Basic getting works now.

This commit is contained in:
Jacques Wagener 2019-09-11 16:03:44 +02:00
parent 6678882031
commit 55cf1b34fb
No known key found for this signature in database
GPG Key ID: C294D1025DA0E923
5 changed files with 94 additions and 50 deletions

View File

@ -56,3 +56,6 @@ contract("MapStorage"):
# tx = contract_.functions.set_name(b"key", b"value").buildTransaction({'from': acct.address, 'nonce': w3.eth.getTransactionCount(acct.address)})
# signed = acct.signTransaction(tx)
# tx_hash = w3.eth.sendRawTransaction(signed.rawTransaction)
# receipt = w3.eth.waitForTransactionReceipt(tx_hash)

View File

@ -5,8 +5,8 @@ contract("Registry"):
names: StorageTable[bytes32, bytes32]
proc set_name*(k: bytes32, v: bytes32) {.self,msg.} =
proc set_name*(k: bytes32, v: bytes32) {.self.} =
self.names[k] = v
# proc get_name(k: bytes32) {.self.} =
# self.names[k]
proc get_name*(k: bytes32): bytes32 {.self.} =
self.names[k]

View File

@ -55,14 +55,14 @@ proc is_log_statement(node: NimNode, global_ctx: GlobalContext): bool =
)
proc has_self_assignment(node: NimNode, global_ctx: GlobalContext): bool =
proc has_self_assignment(node: NimNode): bool =
if node.kind == nnkAsgn:
if is_dot_variable(node[0]) and node[0][0].strVal == "self":
return true
return false
proc has_self_storage_table(node: NimNode, global_ctx: GlobalContext): bool =
proc has_self_storage_table_set(node: NimNode): bool =
if node.kind == nnkAsgn and node[0].kind == nnkBracketExpr:
if is_dot_variable(node[0][0]) and node[0][0][0].strVal == "self":
echo treeRepr(node)
@ -70,14 +70,22 @@ proc has_self_storage_table(node: NimNode, global_ctx: GlobalContext): bool =
return false
proc has_self_storage_table_get(node: NimNode): bool =
if node.kind == nnkBracketExpr and is_dot_variable(node[0]):
return true
return false
proc is_keyword(node: NimNode, global_ctx: GlobalContext): (bool, string) =
if is_message_sender(node):
return (true, "msg.sender")
if is_message_value(node):
return (true, "msg.value")
elif has_self_storage_table(node, global_ctx):
return (true, "set_table_self."& strVal(node[0][0][1]))
elif has_self_assignment(node, global_ctx):
elif has_self_storage_table_set(node):
return (true, "set_table_self." & strVal(node[0][0][1]))
elif has_self_storage_table_get(node):
return (true, "get_table_self." & strVal(node[0][1]))
elif has_self_assignment(node):
return (true, "set_self." & strVal(node[0][1]))
elif has_self(node, global_ctx):
return (true, "self." & strVal(node[1]))
@ -90,8 +98,14 @@ proc is_keyword(node: NimNode, global_ctx: GlobalContext): (bool, string) =
proc find_builtin_keywords(func_body: NimNode, used_keywords: var seq[string], global_ctx: GlobalContext) =
for child in func_body:
let (is_kw, kw_key_name) = is_keyword(child, global_ctx)
var setter_kw = false
for proposed_setter_kw in @["set_" & kw_key_name, "set_table_" & kw_key_name]:
var
setter_kw = false
setter_exemption_list = @[
"set_" & kw_key_name,
"set_table_" & kw_key_name,
"get_table_" & kw_key_name,
]
for proposed_setter_kw in setter_exemption_list:
if proposed_setter_kw in used_keywords:
setter_kw = true
if is_kw and not setter_kw:
@ -141,7 +155,11 @@ proc generate_defines(keywords: seq[string], global_ctx: GlobalContext): (NimNod
tmp_vars[kw] = new_proc_name
stmts.add(new_proc)
elif kw.startsWith("set_table_self."):
var (new_proc, new_proc_name) = generate_storage_table_func(kw, global_ctx)
var (new_proc, new_proc_name) = generate_storage_table_set_func(kw, global_ctx)
tmp_vars[kw] = new_proc_name
stmts.add(new_proc)
elif kw.startsWith("get_table_self."):
var (new_proc, new_proc_name) = generate_storage_table_get_func(kw, global_ctx)
tmp_vars[kw] = new_proc_name
stmts.add(new_proc)
elif kw.startsWith("self."):
@ -153,7 +171,7 @@ proc generate_defines(keywords: seq[string], global_ctx: GlobalContext): (NimNod
proc check_keyword_defines(keywords_used: seq[string], local_ctx: LocalContext) =
for keyword in keywords_used:
var base = keyword.replace("set_", "").replace("table_", "")
var base = keyword.replace("set_", "").replace("get_", "").replace("table_", "")
if "." in base:
base = base.split(".")[0]
if not (base in local_ctx.sig.pragma_base_keywords):
@ -167,13 +185,12 @@ proc get_keyword_defines*(proc_def: NimNode, global_ctx: GlobalContext, local_ct
var
keywords_used: seq[string]
find_builtin_keywords(proc_def, keywords_used, global_ctx)
echo keywords_used
echo "%^%^%^%^%^"
keywords_used = deduplicate(keywords_used)
check_keyword_defines(keywords_used, local_ctx)
let (global_define_stmts, global_keyword_map) = generate_defines(keywords_used, global_ctx)
return (global_define_stmts, global_keyword_map)
proc get_next_storage_node(kw_key_name: string, global_keyword_map: Table[string, string], current_node: NimNode): NimNode =
if kw_key_name.startsWith("self."):
return nnkCall.newTree(
@ -184,6 +201,14 @@ proc get_next_storage_node(kw_key_name: string, global_keyword_map: Table[string
newIdentNode(global_keyword_map[kw_key_name]),
current_node[1]
)
elif kw_key_name.startsWith("get_table_self."):
var call_func = nnkCall.newTree(
newIdentNode(global_keyword_map[kw_key_name]),
)
echo treeRepr(current_node)
for param in current_node[1..current_node.len - 1]: # key params
call_func.add(param)
return call_func
elif kw_key_name.startsWith("set_table_self."):
var call_func = nnkCall.newTree(
newIdentNode(global_keyword_map[kw_key_name]),
@ -191,10 +216,8 @@ proc get_next_storage_node(kw_key_name: string, global_keyword_map: Table[string
for param in current_node[0][1..current_node.len - 1]: # key params
call_func.add(param)
call_func.add(current_node[1]) # val param
echo treeRepr(call_func)
return call_func
else:
raise newException(ParserError, "Unknown global self keyword")

View File

@ -238,22 +238,21 @@ template get_util_functions() {.dirty.} =
if Uint128.fromBytesBE(b) > 0.stuint(128):
revert(nil, 0)
proc exit_message(s: string) =
proc exitMessage(s: string) =
revert(cstring(s), s.len.int32)
proc concat[I1, I2: static[int]; T](a: array[I1, T], b: array[I2, T]): array[I1 + I2, T] =
result[0..a.high] = a
result[a.len..result.high] = b
proc setTableValue[N](table_id: int32, key: array[N, byte], value: var bytes32) =
proc getHashedKey[N](table_id: int32, key: array[N, byte]): bytes32 =
type CombinedKey {.packed.} = object
table_id: int32
key: array[N, byte]
var
sha256_address: array[20, byte]
hashed_key {.noinit.}: bytes32
combined_key: CombinedKey
hashed_key: bytes32
sha256_address: array[20, byte]
sha256_address[19] = 2'u8
combined_key.table_id = table_id
@ -267,14 +266,25 @@ template get_util_functions() {.dirty.} =
sizeof(combined_key).int32, # dataLength
)
if res == 1: # call failed
exit_message("Could not call sha256 in setTableValue")
exitMessage("Could not call sha256 in setTableValue")
# raise newException(Exception, "Could not call sha256 in setTableValue")
if getReturnDataSize() != 32.int32:
exit_message("Could not call sha256, Incorrect return size")
exitMessage("Could not call sha256, Incorrect return size")
returnDataCopy(addr hashed_key, 0.int32, 32.int32)
hashed_key # return
proc setTableValue[N](table_id: int32, key: array[N, byte], value: var bytes32) =
var hashed_key = getHashedKey(table_id, key)
storageStore(hashed_key, addr value)
proc getTableValue[N](table_id: int32, key: array[N, byte], ): bytes32 =
var
value: bytes32
hashed_key: bytes32 = getHashedKey(table_id, key)
storageLoad(hashed_key, addr value)
value # return
proc get_getter_func(var_struct: VariableType): NimNode =
let

View File

@ -6,9 +6,9 @@ import tables
import ./types
proc generate_storage_get_func*(storage_keword: string, global_ctx: GlobalContext): (NimNode, string) =
proc generate_storage_get_func*(storage_keyword: string, global_ctx: GlobalContext): (NimNode, string) =
var
global_var_name = storage_keword.split(".")[1]
global_var_name = storage_keyword.split(".")[1]
new_proc_name = fmt"get_{global_var_name}_from_storage"
var_info = global_ctx.global_variables[global_var_name]
slot_number = var_info.slot
@ -61,27 +61,6 @@ proc generate_storage_get_func*(storage_keword: string, global_ctx: GlobalContex
return tmp
""")
return (new_proc, new_proc_name)
# elif var_info.var_type == "StorageTable":
# var
# key_param_arr: seq[string]
# value_type = var_info.key_types[^1]
# table_id = var_info.slot
# key_count = 0
# for x in var_info.key_types[0..^1]:
# key_param_arr.add(
# fmt"key{key_count}:" & x
# )
# inc(key_count)
# var new_proc = parseStmt(fmt"""
# proc {new_proc_name}({key_param_arr.join(",")}): {value_type} =
# var
# tmp {{.noinit.}}: bytes32
# pos = {$slot_number}.stuint(32).toByteArrayBE
# storageLoad(pos, addr tmp)
# return tmp
# """)
# return (new_proc, new_proc_name)
else:
raise newException(ParserError, var_info.var_type & " storage is not supported at the moment.")
@ -136,12 +115,12 @@ proc generate_storage_set_func*(storage_keyword: string, global_ctx: GlobalConte
raise newException(ParserError, var_info.var_type & " storage is not supported at the moment.")
proc generate_storage_table_func*(storage_keyword: string, global_ctx: GlobalContext): (NimNode, string) =
proc generate_storage_table_set_func*(storage_keyword: string, global_ctx: GlobalContext): (NimNode, string) =
var
key_param_arr: seq[string]
global_var_name = storage_keyword.split(".")[1]
var_info = global_ctx.global_variables[global_var_name]
new_proc_name = fmt"set_{global_var_name}_in_storage"
new_proc_name = fmt"set_{global_var_name}_in_storage_table"
value_type = var_info.key_types[^1]
table_id = var_info.slot
key_count = 0
@ -159,8 +138,37 @@ proc generate_storage_table_func*(storage_keyword: string, global_ctx: GlobalCon
raise newException(ParserError, "Only one key storage is supported at the moment.")
var new_proc = parseStmt(fmt"""
proc {new_proc_name}({key_param_arr.join(",")}, val: {var_info.key_types[^1]}) =
proc {new_proc_name}({key_param_arr.join(",")}, val: {value_type}) =
var tmp_val = val
setTableValue({table_id}.int32, {combined_key}, tmp_val)
""")
return (new_proc, new_proc_name)
proc generate_storage_table_get_func*(storage_keyword: string, global_ctx: GlobalContext): (NimNode, string) =
var
key_param_arr: seq[string]
global_var_name = storage_keyword.split(".")[1]
new_proc_name = fmt"get_{global_var_name}_in_storage_table"
var_info = global_ctx.global_variables[global_var_name]
value_type = var_info.key_types[^1]
table_id = var_info.slot
key_count = 0
combined_key = ""
for x in var_info.key_types[0..^2]:
key_param_arr.add(
fmt"key{key_count}: " & x
)
inc(key_count)
if key_param_arr.len == 1:
combined_key = "key0"
else:
raise newException(ParserError, "Only one key storage is supported at the moment.")
var new_proc = parseStmt(fmt"""
proc {new_proc_name}({key_param_arr.join(",")}): {value_type} =
getTableValue({table_id}.int32, {combined_key})
""")
return (new_proc, new_proc_name)