Skip to content

Commit

Permalink
Let the runtime maintain imports
Browse files Browse the repository at this point in the history
  • Loading branch information
mohanson committed Nov 2, 2024
1 parent eaef3b5 commit 5f212c8
Show file tree
Hide file tree
Showing 8 changed files with 33 additions and 32 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import pywasm
pywasm.log.lvl = 1

runtime = pywasm.core.Runtime()
m = runtime.instance_from_file('./examples/fib.wasm', {})
m = runtime.instance_from_file('./examples/fib.wasm')
r = runtime.invocate(m, 'fib', [10])
print(f'fib(10) = {r[0]}')
```
Expand Down
2 changes: 1 addition & 1 deletion examples/add.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@
pywasm.log.lvl = 1

runtime = pywasm.core.Runtime()
m = runtime.instance_from_file('./examples/add.wasm', {})
m = runtime.instance_from_file('./examples/add.wasm')
r = runtime.invocate(m, 'add', [4, 5])
print(f'4 + 5 = {r[0]}')
6 changes: 3 additions & 3 deletions examples/env.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,11 @@ def fib_wasm(_: pywasm.core.ModuleInst, args: typing.List[int]) -> typing.List[i


runtime = pywasm.core.Runtime()
imports = {'env': {}}
imports['env']['fib'] = runtime.allocate_func_host(
runtime.imports['env'] = {}
runtime.imports['env']['fib'] = runtime.allocate_func_host(
pywasm.core.FuncType([pywasm.core.ValType.i32()], [pywasm.core.ValType.i32()]),
fib_wasm,
)
m = runtime.instance_from_file('./examples/env.wasm', imports)
m = runtime.instance_from_file('./examples/env.wasm')
r = runtime.invocate(m, 'get', [10])
print(f'fib(10) = {r[0]}')
2 changes: 1 addition & 1 deletion examples/fib.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@
pywasm.log.lvl = 1

runtime = pywasm.core.Runtime()
m = runtime.instance_from_file('./examples/fib.wasm', {})
m = runtime.instance_from_file('./examples/fib.wasm')
r = runtime.invocate(m, 'fib', [10])
print(f'fib(10) = {r[0]}')
2 changes: 1 addition & 1 deletion examples/str.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
pywasm.log.lvl = 1

runtime = pywasm.core.Runtime()
mod = runtime.instance_from_file('./examples/str.wasm', {})
mod = runtime.instance_from_file('./examples/str.wasm')
ptr = runtime.invocate(mod, 'get', [])[0]
mem = runtime.exported_memory(mod, 'memory')
print(mem.data[ptr:ptr+12].decode())
2 changes: 1 addition & 1 deletion examples/sum.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@
pywasm.log.lvl = 1

runtime = pywasm.core.Runtime()
m = runtime.instance_from_file('./examples/sum.wasm', {})
m = runtime.instance_from_file('./examples/sum.wasm')
r = runtime.invocate(m, 'sum', [100])
print(f'1 + 2 + ... + 99 = {r[0]}')
9 changes: 5 additions & 4 deletions pywasm/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -2535,6 +2535,7 @@ class Runtime:

def __init__(self) -> typing.Self:
self.machine = Machine()
self.imports: typing.Dict[str, typing.Dict[str, Extern]] = {}

def allocate_func_host(self, type: FuncType, func: typing.Callable) -> Extern:
return Extern(0x00, self.machine.store.allocate_func_host(FuncHost(type, func)))
Expand All @@ -2560,15 +2561,15 @@ def exported_global(self, module: ModuleInst, name: str) -> GlobalInst:
addr = inst.data
return self.machine.store.glob[addr]

def instance(self, module: ModuleDesc, imps: typing.Dict[str, typing.Any]) -> ModuleInst:
def instance(self, module: ModuleDesc) -> ModuleInst:
extern: typing.List[Extern] = []
for e in module.imps:
extern.append(imps[e.module][e.name])
extern.append(self.imports[e.module][e.name])
return self.machine.instance(module, extern)

def instance_from_file(self, path: str, imps: typing.Dict[str, typing.Any]) -> ModuleInst:
def instance_from_file(self, path: str) -> ModuleInst:
with open(path, 'rb') as f:
return self.instance(ModuleDesc.from_reader(f), imps)
return self.instance(ModuleDesc.from_reader(f))

def invocate(self, module: ModuleInst, func: str, args: typing.List[int | float]) -> typing.List[int | float]:
addr = [e for e in module.exps if e.name == func][0].data.data
Expand Down
40 changes: 20 additions & 20 deletions test/test_spec.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,47 +72,47 @@ def vale(a: pywasm.ValInst, b: pywasm.ValInst) -> bool:

def impi(runtime: pywasm.core.Runtime) -> typing.Dict[str, typing.Dict[str, pywasm.core.Extern]]:
# See https://github.com/WebAssembly/spec/blob/w3c-1.0/interpreter/host/spectest.ml
imps = {'spectest': {}}
imps['spectest']['global_i32'] = runtime.allocate_global(
runtime.imports['spectest'] = {}
runtime.imports['spectest']['global_i32'] = runtime.allocate_global(
pywasm.core.GlobalType(pywasm.core.ValType.i32(), 0), pywasm.core.ValInst.from_i32(666)
)
imps['spectest']['global_i64'] = runtime.allocate_global(
runtime.imports['spectest']['global_i64'] = runtime.allocate_global(
pywasm.core.GlobalType(pywasm.core.ValType.i64(), 0), pywasm.core.ValInst.from_i64(666)
)
imps['spectest']['global_f32'] = runtime.allocate_global(
runtime.imports['spectest']['global_f32'] = runtime.allocate_global(
pywasm.core.GlobalType(pywasm.core.ValType.f32(), 0), pywasm.core.ValInst.from_f32(666.6)
)
imps['spectest']['global_f64'] = runtime.allocate_global(
runtime.imports['spectest']['global_f64'] = runtime.allocate_global(
pywasm.core.GlobalType(pywasm.core.ValType.f64(), 0), pywasm.core.ValInst.from_f64(666.6)
)
imps['spectest']['table'] = runtime.allocate_table(
runtime.imports['spectest']['table'] = runtime.allocate_table(
pywasm.core.TableType(pywasm.core.ValType.ref_func(), pywasm.core.Limits(10, 20))
)
imps['spectest']['memory'] = runtime.allocate_memory(
runtime.imports['spectest']['memory'] = runtime.allocate_memory(
pywasm.core.MemType(pywasm.core.Limits(1, 2))
)
imps['spectest']['print'] = runtime.allocate_func_host(
runtime.imports['spectest']['print'] = runtime.allocate_func_host(
pywasm.core.FuncType([], []), lambda m, a: []
)
imps['spectest']['print_i32'] = runtime.allocate_func_host(
runtime.imports['spectest']['print_i32'] = runtime.allocate_func_host(
pywasm.core.FuncType([pywasm.core.ValType.i32()], []), lambda m, a: []
)
imps['spectest']['print_i64'] = runtime.allocate_func_host(
runtime.imports['spectest']['print_i64'] = runtime.allocate_func_host(
pywasm.core.FuncType([pywasm.core.ValType.i64()], []), lambda m, a: []
)
imps['spectest']['print_f32'] = runtime.allocate_func_host(
runtime.imports['spectest']['print_f32'] = runtime.allocate_func_host(
pywasm.core.FuncType([pywasm.core.ValType.f32()], []), lambda m, a: []
)
imps['spectest']['print_f64'] = runtime.allocate_func_host(
runtime.imports['spectest']['print_f64'] = runtime.allocate_func_host(
pywasm.core.FuncType([pywasm.core.ValType.f64()], []), lambda m, a: []
)
imps['spectest']['print_i32_f32'] = runtime.allocate_func_host(
runtime.imports['spectest']['print_i32_f32'] = runtime.allocate_func_host(
pywasm.core.FuncType([pywasm.core.ValType.i32(), pywasm.core.ValType.f32()], []), lambda m, a: []
)
imps['spectest']['print_f64_f64'] = runtime.allocate_func_host(
runtime.imports['spectest']['print_f64_f64'] = runtime.allocate_func_host(
pywasm.core.FuncType([pywasm.core.ValType.f64(), pywasm.core.ValType.f64()], []), lambda m, a: []
)
return imps
return runtime.imports


for name in sorted(glob.glob('res/spectest/*.json')):
Expand All @@ -121,10 +121,10 @@ def impi(runtime: pywasm.core.Runtime) -> typing.Dict[str, typing.Dict[str, pywa
with open(name) as f:
suit = json.load(f)['commands']
runtime = pywasm.Runtime()
imports = impi(runtime)
cmodule: pywasm.ModuleInst
lmodule: pywasm.ModuleInst
mmodule = {}
impi(runtime)
for elem in suit:
print(elem)
match elem['type']:
Expand Down Expand Up @@ -175,21 +175,21 @@ def impi(runtime: pywasm.core.Runtime) -> typing.Dict[str, typing.Dict[str, pywa
assert 1
case 'assert_uninstantiable':
try:
lmodule = runtime.instance_from_file(f'res/spectest/{elem['filename']}', imports)
lmodule = runtime.instance_from_file(f'res/spectest/{elem['filename']}')
except Exception as e:
runtime.machine.stack.frame.clear()
runtime.machine.stack.label.clear()
runtime.machine.stack.value.clear()
case 'assert_unlinkable':
assert 1
case 'module':
lmodule = runtime.instance_from_file(f'res/spectest/{elem['filename']}', imports)
lmodule = runtime.instance_from_file(f'res/spectest/{elem['filename']}')
if 'name' in elem:
mmodule[elem['name']] = lmodule
case 'register':
mmodule[elem['as']] = lmodule
imports[elem['as']] = {}
runtime.imports[elem['as']] = {}
for e in lmodule.exps:
imports[elem['as']][e.name] = e.data
runtime.imports[elem['as']][e.name] = e.data
case _:
assert 0

0 comments on commit 5f212c8

Please sign in to comment.