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
示例#2
0
def instantiate_module_from_wasm_file(test,filename,store,registered_modules):
  if verbose>2: print("instantiate_module_from_wasm_file(",filename,")")
  if filename[-5:]!=".wasm":
    if verbose>1: print("we don't yet support .wast or .wat text format files")
    return store,None
  moduleinst = None
  with open(filename, 'rb') as f:
    #memoryview doesn't make copy, bytearray may require copy
    wasmbytes = memoryview(f.read())
    module = wasm.decode_module(wasmbytes)
    #module = pywebassembly.decode_module(wasmbytes)
    #print("module",module)
    if module=="malformed": return None,"malformed"
    #validate
    ret = wasm.validate_module(module)
    #print("OKOK")
    #print(module)
    #ret = pywebassembly.validate_module(module)
    #print("valid:",ret)
    if type(ret)==str and ret[:14]=="error: invalid":
      #print(ret)
      #print(test["text"])
      #if ret=="error: invalid: pop_opd":
      #  #print(test["text"])
      #  if test["text"] != "type mismatch":
      #    print("#######################################################")
      #    print(test["text"])
      #    print(ret)
      #if ret=="pop_opd2" and test["text"]!="type mismatch":
      #  print("#######################################################")
      return None,"invalid"
    #if test["type"]=="assert_invalid" and ret!="error: invalid": #TODO remove this
    #  print("INVALID MISSED !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!",test)
    #  return None,"invalid"
    #imports preparation
    externvalstar = []
    #print("module",filename,module)
    for import_ in module["imports"]:
      if import_["module"] not in registered_modules: return store,"unlinkable"	#error: module name doesn't exist
      importmoduleinst = registered_modules[import_["module"]]
      externval = None
      #print("importmoduleinst",importmoduleinst)
      #for key in importmoduleinst:
      #  print(key,importmoduleinst[key])
      for export in importmoduleinst["exports"]:
        if export["name"] == import_["name"]:
          externval = export["value"]
      if externval == None: return store,"unlinkable"	#error: export name doesn't exist
      if externval[0] != import_["desc"][0]: return store,"unlinkable"	#error: import type (func, table, mem, globa) doesn't match
      externvalstar += [externval]
    #print("store",store)
    #print("module",module)
    #print("externvalstar",externvalstar)
    store,moduleinst,ret = wasm.instantiate_module(store,module,externvalstar)
    #print("moduleinst",moduleinst)
    #print(store["mems"][0]["data"])
    if moduleinst=="error":
      #print("instantiate_module_from_wasm_file",moduleinst,ret)
      return store,ret #ret is the actual error, eg "unlinkable"
  return store,moduleinst
示例#3
0
def instantiate_module_from_wasm_file(filename, store, registered_modules):
    if verbose > 2: print("instantiate_module_from_wasm_file(", filename, ")")
    if filename[-5:] != ".wasm":
        if verbose > 1:
            print("we don't yet support .wast or .wat text format files")
        return store, None
    moduleinst = None
    with open(filename, 'rb') as f:
        #memoryview doesn't make copy, bytearray may require copy
        wasmbytes = memoryview(f.read())
        module = pywebassembly.decode_module(wasmbytes)
        #imports preparation
        externvalstar = []
        for import_ in module["imports"]:
            if import_["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: return -1, -1
            if externval[0] != import_["desc"][0]: return -1, -1
            externvalstar += [externval]
        #print("store",store)
        #print("module",module)
        #print("externvalstar",externvalstar)
        store, moduleinst = pywebassembly.instantiate_module(
            store, module, externvalstar)
        #print("moduleinst",moduleinst)
        #print(store["mems"][0]["data"])
        if moduleinst == "error":
            return store, None
    return store, moduleinst
示例#4
0
def parse_wasm_and_clean_up(filename):
    #print("reading ",filename)
    with open(filename, 'rb') as f:
        bytecode = memoryview(f.read())
        mod = wasm.decode_module(bytecode)
        export_only_main_and_memory(mod)
        import_only_ethereum_eei(mod)
        fout = open(filename.rsplit('.', 1)[0] + "_ewasmified.wasm", 'wb')
        bytecode_out = wasm.encode_module(mod)
        fout.write(bytecode_out)
        fout.close()
示例#5
0
def parse_wasm_and_inject_and_generate(filename):
    with open(filename, 'rb') as f:
        bytecode = memoryview(f.read())
        mod = wasm.decode_module(bytecode)
        inject_metering_calls_to_each_function(mod)
        #must inject above metering calls before injecting helper functions
        inject_helper_functions(mod)
        #print_sections(mod)
        fout = open(filename.split('.')[0] + "_metered.wasm", 'wb')
        bytecode_out = wasm.encode_module(mod)
        fout.write(bytecode_out)
        fout.close()
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
示例#7
0
文件: juno.py 项目: 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")
示例#8
0
def instantiate_module_from_wasm_file(test, filename, store,
                                      registered_modules):
    if verbose > 2: print("instantiate_module_from_wasm_file(", filename, ")")
    if filename[-5:] != ".wasm":
        if verbose > 1:
            print("we don't yet support .wast or .wat text format files")
        return store, None
    moduleinst = None
    with open(filename, 'rb') as f:
        #memoryview doesn't make copy, bytearray may require copy
        wasmbytes = memoryview(f.read())
        module = wasm.decode_module(wasmbytes)
        if module == "malformed": return None, "malformed"
        #validate
        ret = wasm.validate_module(module)
        if type(ret) == str and ret[:14] == "error: invalid":
            return None, "invalid"
        #imports preparation
        externvalstar = []
        #print("module",filename,module)
        for import_ in module["imports"]:
            if import_["module"] not in registered_modules:
                return store, "unlinkable"  #error: module name doesn't exist
            importmoduleinst = registered_modules[import_["module"]]
            externval = None
            for export in importmoduleinst["exports"]:
                if export["name"] == import_["name"]:
                    externval = export["value"]
            if externval == None:
                return store, "unlinkable"  #error: export name doesn't exist
            if externval[0] != import_["desc"][0]:
                return store, "unlinkable"  #error: import type (func, table, mem, globa) doesn't match
            externvalstar += [externval]
        store, moduleinst, ret = wasm.instantiate_module(
            store, module, externvalstar)
        if moduleinst == "error":
            return store, ret  #ret is the actual error, eg "unlinkable"
    return store, moduleinst
"""

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
file_ = open('mod2.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
for import_ in module[
        "imports"]:  #for each import, look for it's matching export
    importmoduleinst = modules[import_["module"]]
示例#10
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