def instantiate_wasm_invoke_func(filename,funcname,args):
  file_ = open(filename, 'rb')
  if not file_: return "error, could not open "+filename
  bytestar = memoryview(file_.read())
  if not bytestar: return "error, could not read "+filename
  module = wasm.decode_module(bytestar)	#get module as abstract syntax
  #print("module",module)
  if not module: return "error, could not decode "+filename
  store = wasm.init_store()		#do this once for each VM instance
  externvalstar = []			#imports, hopefully none
  store,moduleinst,ret = wasm.instantiate_module(store,module,externvalstar)
  if moduleinst == "error": return "error, module could not be instantiated"
  #print("moduleinst",moduleinst)
  externval = wasm.get_export(moduleinst, funcname)
  if not externval or externval[0]!="func": return "error, "+funcname+" is not a function export of the module"
  #print("externval",externval)
  funcaddr = externval[1]
  valstar = [["i32.const",int(arg)] for arg in args]
  #print("valstar",valstar)
  store,ret = wasm.invoke_func(store,funcaddr,valstar)
  if ret=="trap": return "error, invokation resulted in a trap"
  #print("ret",ret)
  if type(ret)==list and len(ret)>0:
    ret = ret[0]
  return ret
def instantiate_wasm_invoke_start(filename):
  file_ = open(filename, 'rb')
  if not file_: return "error, could not open "+filename
  bytestar = memoryview(file_.read())
  if not bytestar: return "error, could not read "+filename
  module = wasm.decode_module(bytestar)	#get module as abstract syntax
  #print("module",module)
  if not module: return "error, could not decode "+filename
  store = wasm.init_store()		#do this once for each VM instance
  externvalstar = []			#imports, hopefully none
  store,moduleinst,ret = wasm.instantiate_module(store,module,externvalstar)
  if moduleinst == "error": return "error, module could not be instantiated"
  return ret
Ejemplo n.º 3
0
def run_test_file(jsonfilename):
    d = None
    with open(jsonfilename) as f:
        d = json.load(f)
    if d == None: return -1
    #print(d)
    #print(json.dumps(d,indent=2))
    if "source_filename" not in d:
        print("this may not be a valid wabt test file")
        return -1
    if verbose > -1: print("\nrunning tests in " + d["source_filename"])
    tests = d["commands"]
    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 = pywebassembly.init_store(
    )  #done once and lasts for lifetime of this abstract machine
    instantiate_spectest_module(
        store, modules,
        registered_modules)  #module "spectest" is imported from by many tests
    registered_modules["spectest"] = modules[
        "spectest"]  #register module "spectest" to be import-able
    moduleinst = None
    num_tests_passed = 0
    num_tests_tried = 0
    for idx, test in enumerate(tests):  #iterate over tests in this file
        if verbose > 1: print("\ntest #", idx, test["type"])
        num_tests_tried += 1
        if test["type"] == "module":  #module
            store, moduleinst = test_opcode_module(test, store, modules,
                                                   registered_modules)
            if moduleinst: num_tests_passed += 1
        elif test["type"] == "register":  #register
            test_opcode_register(test, store, modules, registered_modules,
                                 moduleinst)
            num_tests_passed += 1
        elif test["type"] == "action":  #action
            test_opcode_action(test, store, modules, registered_modules,
                               moduleinst)
            num_tests_passed += 1
        elif test["type"][:7] == "assert_":  #assertion
            ret = test_opcode_assertion(test, store, modules,
                                        registered_modules, moduleinst)
            if test["type"] not in {"assert_return", "assert_trap"}:
                num_tests_tried -= 1  #hack to only count assert_... that are implemented
            if ret == "success": num_tests_passed += 1
    if verbose > -1:
        print(
            "Passed", num_tests_passed, "out of", num_tests_tried, "tests"
        )  #"(actually, there are ",len(tests),"total tests, some test opcodes not implemented yet)")
Ejemplo n.º 4
0
Archivo: juno.py Proyecto: lrettig/juno
def juno_execute(state, msg, tx_context, computation):
    logger = logging.getLogger('juno')

    code = computation.code
    gas = msg.gas
    args = msg.data

    if not has_wasm_preamble(code):
        raise Exception("Invalid code")

    logger.debug('juno_execute')
    # if VERBOSE>1: print("call_contract(",moduleid,funcname,arg,gas,")")
    # spin-up a VM instance with eei module
    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
    instantiate_eei_module(store,modules,gas)	#instantiate the EEI module "ethereum"
    registered_modules["ethereum"] = modules["ethereum"] 		#register module "ethereum" to be import-able
    # instantiate module which contains the func to-be-called
    # module_as_bytes = trinity.get_module_as_bytes(moduleid)	#TODO: need API to get module bytes
    module = wasm.decode_module(code)		#get module as abstract syntax
    externvalstar = []					#populate imports
    for import_ in module["imports"]:
        if import_["module"] not in registered_modules:
            logger.error('module not in registered_modules')
            return -1, -1
        importmoduleinst = registered_modules[import_["module"]]
        externval = None
        for export in importmoduleinst["exports"]:
            if export["name"] == import_["name"]:
                externval = export["value"]
        if externval == None:
            logger.error('Missing import')
            return None #error
        if externval[0] != import_["desc"][0]:
            logger.error('Bad imported function signature')
            return None #error
        externvalstar += [externval]
    store,moduleinst,ret = wasm.instantiate_module(store,module,externvalstar)
    # finally, call the function
    externval = wasm.get_export(moduleinst, "main")	#we want to call function "main"
    funcaddr = externval[1]				#the address of the funcname
    store,ret = wasm.invoke_func(store,funcaddr,args)	#finally, invoke the function
    print("Initial gas was ", gas, ", gas left is ", store["gasLeft"])
    computation.consume_gas(gas - store["gasLeft"], "juno")
    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
"""

import sys
sys.path.append('..')
import pywebassembly as wasm

#set up VM for multiple modules
store = wasm.init_store()  #do this once for each VM instance
modules = {
}  #all moduleinst's indexed by their names, used to call funcs and resolve exports

#instantiate first module
file_ = open('mod1.wasm', 'rb')
bytecode = memoryview(
    file_.read())  #can also use bytearray or bytes instead of memoryview
module = wasm.decode_module(bytecode)  #get module as abstract syntax
externvalstar = []  #imports, none for fibonacci.wasm
store, moduleinst, ret = wasm.instantiate_module(store, module, externvalstar)

#register this module instance so it can be imported from
modules["mod1"] = moduleinst

#instantiate second module
Ejemplo n.º 6
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