Beispiel #1
0
def instantiate_eei_module(store,modules,gas):
    # if VERBOSE>1: print("instantiate_eei_module()")
    store["gasLeft"] = gas	#modify store with a gasLeft field, this is not in the Wasm spec
    wasm.alloc_func(store, [["i64"],[]], useGas)
    wasm.alloc_func(store, [[],["i64"]], getGasLeft)
    modules["ethereum"] = {"types": [[["i64"], []],
                                     [[], ["i64"]],
                                     ],
                           "funcaddrs": [0, 1],
                           "tableaddrs": [],
                           "memaddrs": [],
                           "globaladdrs": [],
                           "exports": [{"name": "useGas", "value": ["func", 0]},
                                       {"name": "getGasLeft", "value": ["func", 1]},
                                       ]
                           }
def instantiate_spectest_module(store):
    def spectest__print_i32(store, arg):
        if verbose > 1: print(arg)
        return store, []

    def spectest__print_i64(store, arg):
        if verbose > 1: print(arg)
        return store, []

    def spectest__print_f32(store, arg):
        if verbose > 1: print(arg)
        return store, []

    def spectest__print_f64(store, arg):
        if verbose > 1: print(arg)
        return store, []

    def spectest__print_i32_f32(store, arg):
        if verbose > 1: print(arg)
        return store, []

    def spectest__print_f64_f64(store, arg):
        if verbose > 1: print(arg)
        return store, []

    def spectest__print(store, arg):
        if verbose > 1: print(arg)
        return store, []

    pywebassembly.alloc_func(store, [["i32"], []], spectest__print_i32)
    pywebassembly.alloc_func(store, [["i64"], []], spectest__print_i64)
    pywebassembly.alloc_func(store, [["f32"], []], spectest__print_f32)
    pywebassembly.alloc_func(store, [["f64"], []], spectest__print_f64)
    pywebassembly.alloc_func(store, [["i32", "f32"], []],
                             spectest__print_i32_f32)
    pywebassembly.alloc_func(store, [["f64", "f64"], []],
                             spectest__print_f64_f64)
    pywebassembly.alloc_func(store, [[], []], spectest__print)
    pywebassembly.alloc_mem(store, {
        "min": 1,
        "max": 2
    })  #min:1,max:2 required by import.wast:
    pywebassembly.alloc_global(store, ["const", "i32"],
                               666)  #666 required by import.wast
    pywebassembly.alloc_global(store, ["const", "f32"], 0.0)
    pywebassembly.alloc_global(store, ["const", "f64"], 0.0)
    pywebassembly.alloc_table(store, [{
        "min": 10,
        "max": 20
    }, "anyfunc"])  #max was 30, changed to 20 for import.wast
    moduleinst = {
        "types": [
            [["i32"], []],
            [["i64"], []],
            [["i32"], []],
            [["f64"], []],
            [["i32", "f32"], []],
            [["f64", "f64"], []],
            [[], []],
        ],
        "funcaddrs": [0, 1, 2, 3, 4, 5, 6],
        "tableaddrs": [0],
        "memaddrs": [0],
        "globaladdrs": [0, 1, 2],
        "exports": [{
            "name": "print_i32",
            "value": ["func", 0]
        }, {
            "name": "print_i64",
            "value": ["func", 1]
        }, {
            "name": "print_f32",
            "value": ["func", 2]
        }, {
            "name": "print_f64",
            "value": ["func", 3]
        }, {
            "name": "print_i32_f32",
            "value": ["func", 4]
        }, {
            "name": "print_f64_f64",
            "value": ["func", 5]
        }, {
            "name": "print",
            "value": ["func", 6]
        }, {
            "name": "memory",
            "value": ["mem", 0]
        }, {
            "name": "global_i32",
            "value": ["global", 0]
        }, {
            "name": "global_f32",
            "value": ["global", 1]
        }, {
            "name": "global_f64",
            "value": ["global", 2]
        }, {
            "name": "table",
            "value": ["table", 0]
        }]
    }
    return moduleinst
def instantiate_test_module(store):
    def test__func(store, arg):
        pass

    def test__func_i32(store, arg):
        pass

    def test__func_f32(store, arg):
        pass

    def test__func__i32(store, arg):
        pass

    def test__func__f32(store, arg):
        pass

    def test__func_i32_i32(store, arg):
        pass

    def test__func_i64_i64(store, arg):
        pass

    pywebassembly.alloc_func(store, [[], []], test__func)
    pywebassembly.alloc_func(store, [["i32"], []], test__func_i32)
    pywebassembly.alloc_func(store, [["f32"], []], test__func_f32)
    pywebassembly.alloc_func(store, [[], ["i32"]], test__func__i32)
    pywebassembly.alloc_func(store, [[], ["f32"]], test__func__f32)
    pywebassembly.alloc_func(store, [["i32"], ["i32"]], test__func_i32_i32)
    pywebassembly.alloc_func(store, [["i64"], ["i64"]], test__func_i64_i64)
    pywebassembly.alloc_mem(store, {"min": 1, "max": None})
    pywebassembly.alloc_global(store, ["const", "i32"], 666)
    pywebassembly.alloc_global(store, ["const", "f32"], 0.0)
    pywebassembly.alloc_table(store, [{"min": 10, "max": None}, "anyfunc"])
    moduleinst = {
        "types": [[["i32"], []], [["f32"], []], [[], ["i32"]], [[], ["f32"]],
                  [["i32"], ["i32"]], [["i64"], ["i64"]]],
        "funcaddrs": [0, 1, 2, 3, 4, 5, 6],
        "tableaddrs": [0],
        "memaddrs": [0],
        "globaladdrs": [0, 1],
        "exports": [{
            "name": "func",
            "value": ["func", 0]
        }, {
            "name": "func_i32",
            "value": ["func", 1]
        }, {
            "name": "func_f32",
            "value": ["func", 2]
        }, {
            "name": "func__i32",
            "value": ["func", 3]
        }, {
            "name": "func__f32",
            "value": ["func", 4]
        }, {
            "name": "func__i32_i32",
            "value": ["func", 5]
        }, {
            "name": "func__i64_i64",
            "value": ["func", 6]
        }, {
            "name": "memory-2-inf",
            "value": ["mem", 0]
        }, {
            "name": "global-i32",
            "value": ["global", 0]
        }, {
            "name": "global-f32",
            "value": ["global", 1]
        }, {
            "name": "table-10-inf",
            "value": ["table", 0]
        }]
    }
    return moduleinst
Beispiel #4
0
  def exec_(self, calldata):
    """
      The following function is used to call a given contract.
      This will "spin-up" a new VM, execute the contract, and output the contract's return values and gas used.
    """
    self.calldata = calldata[:]

    # spin-up a VM
    modules = {}		# all moduleinst's indexed by their names, used to call funcs and resolve exports
    registered_modules = {}	# all moduleinst's which can be imported from, indexed by their registered name
    store = wasm.init_store()	# done once and lasts for lifetime of this abstract machine

    # create host module
    def eth2_loadPreStateRoot(store,arg):
      if verbose: print("eth2_loadPreStateRoot")
      offset = arg[0]
      self.module_memory[offset:offset+32] = self.state_root[:]
      return store,[]

    def eth2_blockDataSize(store,arg):
      if verbose: print("eth2_blockDataSize", len(self.calldata))
      return store,[len(self.calldata)]

    def eth2_blockDataCopy(store,arg):
      if verbose: print("eth2_blockDataCopy")
      memory_offset = arg[0]
      calldata_offset = arg[1]
      length = arg[2]
      self.module_memory[memory_offset:memory_offset+length] = self.calldata[calldata_offset:calldata_offset+length]
      return store,[]

    def eth2_savePostStateRoot(store,arg):
      if verbose: print("eth2_savePostStateRoot", arg[0])
      offset = arg[0]
      self.state_root[:] = self.module_memory[offset:offset+32]
      return store,[]

    def eth2_pushNewDeposit(store,arg):
      if verbose: print("eth2_pushNewDeposit")
      offset = arg[0]
      length = arg[1]
      return store,[]

    def eth2_debugPrintMem(store,arg):
      if verbose: print("eth2_debugPrintMem")
      offset = arg[0]
      length = arg[1]
      print(self.module_memory[offset:offset+length])
      return store,[]

    wasm.alloc_func(store, [["i32"],[]], eth2_loadPreStateRoot)
    wasm.alloc_func(store, [[],["i32"]], eth2_blockDataSize)
    wasm.alloc_func(store, [["i32","i32","i32"],[]], eth2_blockDataCopy)
    wasm.alloc_func(store, [["i32"],[]], eth2_savePostStateRoot)
    wasm.alloc_func(store, [["i32","i32"],[]], eth2_pushNewDeposit)
    wasm.alloc_func(store, [["i32","i32"],[]], eth2_debugPrintMem)
    modules["env"] =      {"types":[[["i32"],[]],
                                    [[],["i32"]],
                                    [["i32","i32","i32"],[]],
                                    [["i32","i32"],[]],
                                   ],
                           "funcaddrs":[0,1,2,3,4,5],
                           "tableaddrs":[],
                           "memaddrs":[],
                           "globaladdrs":[],
                           "exports":[{"name":"eth2_loadPreStateRoot","value":["func",0]},
                                      {"name":"eth2_blockDataSize","value":["func",1]},
                                      {"name":"eth2_blockDataCopy","value":["func",2]},
                                      {"name":"eth2_savePostStateRoot","value":["func",3]},
                                      {"name":"eth2_pushNewDeposit","value":["func",4]},
                                      {"name":"eth2_debugPrintMem","value":["func",5]},
                                     ]
                          }

    # register the host module
    registered_modules["env"] = modules["env"]           		#register module "ethereum" to be import-able

    # instantiate module which contains the func to-be-called
    module = wasm.decode_module(self.bytecode)                          #get module as abstract syntax
    externvalstar = []			           	                #populate imports
    for import_ in module["imports"]:
      if import_["module"] not in registered_modules: return None #error
      importmoduleinst = registered_modules[import_["module"]]
      externval = None
      for export in importmoduleinst["exports"]:
        if export["name"] == import_["name"]:
          externval = export["value"]
      if externval == None: return None #error
      if externval[0] != import_["desc"][0]: return None #error
      externvalstar += [externval]
    store,moduleinst,ret = wasm.instantiate_module(store,module,externvalstar)

    # get its memory
    self.module_memory = store["mems"][0]["data"]

    # finally, call the function
    externval = wasm.get_export(moduleinst, "main")	#we want to call function "main"
    funcaddr = externval[1]				#the address of the funcname
    args = []
    store,ret = wasm.invoke_func(store,funcaddr,args)	#finally, invoke the function
    return ret