Locals support in wasm. You can now have multiple objects [skip-ci]

This commit is contained in:
Johan B.W. de Vries 2022-03-05 11:42:01 +01:00
parent b468ffa780
commit efe24fb4b5
3 changed files with 48 additions and 6 deletions

View File

@ -35,9 +35,19 @@ class Visitor:
[
('alloc_size', 'i32'),
],
[
('result', 'i32'),
],
'i32',
[
wasm.Statement('i32.const', '4', comment='Stub')
wasm.Statement('i32.const', '0'),
wasm.Statement('i32.const', '0'),
wasm.Statement('i32.load'),
wasm.Statement('local.tee', '$result', comment='Address for this call'),
wasm.Statement('local.get', '$alloc_size'),
wasm.Statement('i32.add'),
wasm.Statement('i32.store', comment='Address for the next call'),
wasm.Statement('local.get', '$result'),
]
))
@ -141,7 +151,11 @@ class Visitor:
else:
params.append((arg.arg, _parse_annotation(arg.annotation), ))
return wasm.Function(node.name, exported, params, result, [])
locals_ = [
('___new_reference___addr', 'i32'), # For the ___new_reference__ method
]
return wasm.Function(node.name, exported, params, locals_, result, [])
def parse_FunctionDef_body(
self,

View File

@ -61,12 +61,14 @@ class Function:
name: str,
exported: bool,
params: Iterable[Param],
locals_: Iterable[Param],
result: Optional[str],
statements: Iterable[Statement],
) -> None:
self.name = name
self.exported = exported
self.params = [*params]
self.locals = [*locals_]
self.result = result
self.statements = [*statements]
@ -77,12 +79,13 @@ class Function:
header = ('(export "{}")' if self.exported else '${}').format(self.name)
for nam, typ in self.params:
header += ' (param ${} {})'.format(nam, typ)
header += f' (param ${nam} {typ})'
if self.result:
header += ' (result {})'.format(self.result)
header += f' (result {self.result})'
header += ' (local $___new_reference___addr i32)'
for nam, typ in self.locals:
header += f' (local ${nam} {typ})'
return '(func {}\n {}\n )'.format(
header,

View File

@ -252,7 +252,7 @@ def testEntry() -> i32:
assert [] == result.log_int32_list
@pytest.mark.integration_test
def test_struct():
def test_struct_1():
code_py = """
class Rectangle:
@ -272,3 +272,28 @@ def helper(shape: Rectangle) -> i32:
assert 252 == result.returned_value
assert [] == result.log_int32_list
@pytest.mark.integration_test
def test_struct_2():
code_py = """
class Rectangle:
height: i32
width: i32
border: i32 # = 5
@exported
def testEntry() -> i32:
return helper(Rectangle(100, 150, 2), Rectangle(200, 90, 3))
def helper(shape1: Rectangle, shape2: Rectangle) -> i32:
return (
shape1.height + shape1.width + shape1.border
+ shape2.height + shape2.width + shape2.border
)
"""
result = Suite(code_py, 'test_call').run_code()
assert 545 == result.returned_value
assert [] == result.log_int32_list