Start on new allocator
This commit is contained in:
parent
fe864e6b9d
commit
b42ae275b9
@ -360,6 +360,8 @@ def module(inp: ourlang.Module) -> wasm.Module:
|
|||||||
|
|
||||||
result.functions = [
|
result.functions = [
|
||||||
_generate____new_reference___(inp),
|
_generate____new_reference___(inp),
|
||||||
|
_generate_stdlib_alloc___init__(inp),
|
||||||
|
_generate_stdlib_alloc___alloc__(inp),
|
||||||
_generate____access_bytes_index___(inp),
|
_generate____access_bytes_index___(inp),
|
||||||
] + [
|
] + [
|
||||||
function(x)
|
function(x)
|
||||||
@ -392,6 +394,77 @@ def _generate____new_reference___(mod: ourlang.Module) -> wasm.Function:
|
|||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def _generate_stdlib_alloc___init__(mod: ourlang.Module) -> wasm.Function:
|
||||||
|
return wasm.Function(
|
||||||
|
'stdlib.alloc.__init__',
|
||||||
|
'stdlib.alloc.__init__',
|
||||||
|
[],
|
||||||
|
[],
|
||||||
|
wasm.WasmTypeNone(),
|
||||||
|
[
|
||||||
|
wasm.Statement('i32.const', '0x00'),
|
||||||
|
wasm.Statement('i32.load'),
|
||||||
|
wasm.Statement('i32.const', '0xA1C0'),
|
||||||
|
wasm.Statement('i32.eq'),
|
||||||
|
wasm.Statement('if', comment='Already set up'),
|
||||||
|
wasm.Statement('return'),
|
||||||
|
wasm.Statement('end'),
|
||||||
|
|
||||||
|
wasm.Statement('i32.const', '0x04', comment='Reserved'),
|
||||||
|
wasm.Statement('i32.const', '0x000000'),
|
||||||
|
wasm.Statement('i32.store'),
|
||||||
|
|
||||||
|
wasm.Statement('i32.const', '0x08', comment='Address of next free block'),
|
||||||
|
wasm.Statement('i32.const', '0x000000'),
|
||||||
|
wasm.Statement('i32.store'),
|
||||||
|
|
||||||
|
wasm.Statement('i32.const', '0x0C', comment='Reserved'),
|
||||||
|
wasm.Statement('i32.const', '0x000000'),
|
||||||
|
wasm.Statement('i32.store'),
|
||||||
|
|
||||||
|
wasm.Statement('i32.const', '0x00', comment='Done setting up'),
|
||||||
|
wasm.Statement('i32.const', '0xA1C0'),
|
||||||
|
wasm.Statement('i32.store'),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
def _generate_stdlib_alloc___alloc__(mod: ourlang.Module) -> wasm.Function:
|
||||||
|
return wasm.Function(
|
||||||
|
'stdlib.alloc.__alloc__',
|
||||||
|
'stdlib.alloc.__alloc__',
|
||||||
|
[
|
||||||
|
('alloc_size', type_(mod.types['i32']), ),
|
||||||
|
],
|
||||||
|
[
|
||||||
|
('result', type_(mod.types['i32']), ),
|
||||||
|
],
|
||||||
|
type_(mod.types['i32']),
|
||||||
|
[
|
||||||
|
wasm.Statement('i32.const', '0'),
|
||||||
|
wasm.Statement('i32.load'),
|
||||||
|
wasm.Statement('i32.const', '0xA1C0'),
|
||||||
|
wasm.Statement('i32.ne'),
|
||||||
|
wasm.Statement('if', comment='Failed to set up'),
|
||||||
|
wasm.Statement('unreachable'),
|
||||||
|
wasm.Statement('end'),
|
||||||
|
|
||||||
|
# wasm.Statement('local.get', '$alloc_size'),
|
||||||
|
# wasm.Statement('call', '$stdlib.alloc.__find_space__'),
|
||||||
|
wasm.Statement('i32.const', '0x16', comment='STUB'),
|
||||||
|
wasm.Statement('local.set', '$result'),
|
||||||
|
|
||||||
|
# Store block size
|
||||||
|
wasm.Statement('local.get', '$result'),
|
||||||
|
wasm.Statement('local.get', '$alloc_size'),
|
||||||
|
wasm.Statement('i32.store', 'offset=0'),
|
||||||
|
|
||||||
|
# Return address of the allocated bytes
|
||||||
|
wasm.Statement('local.get', '$result'),
|
||||||
|
wasm.Statement('i32.const', '0x04'),
|
||||||
|
wasm.Statement('i32.add'),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
def _generate____access_bytes_index___(mod: ourlang.Module) -> wasm.Function:
|
def _generate____access_bytes_index___(mod: ourlang.Module) -> wasm.Function:
|
||||||
return wasm.Function(
|
return wasm.Function(
|
||||||
'___access_bytes_index___',
|
'___access_bytes_index___',
|
||||||
|
|||||||
106
tests/integration/test_stdlib_alloc.py
Normal file
106
tests/integration/test_stdlib_alloc.py
Normal file
@ -0,0 +1,106 @@
|
|||||||
|
import sys
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
|
||||||
|
import wasm3
|
||||||
|
|
||||||
|
from phasm.compiler import phasm_compile
|
||||||
|
from phasm.parser import phasm_parse
|
||||||
|
|
||||||
|
from .helpers import DASHES, wat2wasm, _dump_memory, _write_numbered_lines
|
||||||
|
|
||||||
|
def setup_interpreter(code_phasm):
|
||||||
|
phasm_module = phasm_parse(code_phasm)
|
||||||
|
wasm_module = phasm_compile(phasm_module)
|
||||||
|
code_wat = wasm_module.to_wat()
|
||||||
|
|
||||||
|
sys.stderr.write(f'{DASHES} Assembly {DASHES}\n')
|
||||||
|
_write_numbered_lines(code_wat)
|
||||||
|
|
||||||
|
code_wasm = wat2wasm(code_wat)
|
||||||
|
|
||||||
|
env = wasm3.Environment()
|
||||||
|
mod = env.parse_module(code_wasm)
|
||||||
|
|
||||||
|
rtime = env.new_runtime(1024 * 1024)
|
||||||
|
rtime.load(mod)
|
||||||
|
|
||||||
|
return rtime
|
||||||
|
|
||||||
|
@pytest.mark.integration_test
|
||||||
|
def test___init__():
|
||||||
|
code_py = """
|
||||||
|
@exported
|
||||||
|
def testEntry() -> u8:
|
||||||
|
return 13
|
||||||
|
"""
|
||||||
|
|
||||||
|
rtime = setup_interpreter(code_py)
|
||||||
|
|
||||||
|
for idx in range(128):
|
||||||
|
rtime.get_memory(0)[idx] = idx
|
||||||
|
|
||||||
|
sys.stderr.write(f'{DASHES} Memory (pre run) {DASHES}\n')
|
||||||
|
_dump_memory(rtime.get_memory(0))
|
||||||
|
|
||||||
|
rtime.find_function('stdlib.alloc.__init__')()
|
||||||
|
|
||||||
|
sys.stderr.write(f'{DASHES} Memory (pre run) {DASHES}\n')
|
||||||
|
_dump_memory(rtime.get_memory(0))
|
||||||
|
|
||||||
|
memory = rtime.get_memory(0).tobytes()
|
||||||
|
|
||||||
|
assert (
|
||||||
|
b'\xC0\xA1\x00\x00'
|
||||||
|
b'\x00\x00\x00\x00'
|
||||||
|
b'\x00\x00\x00\x00'
|
||||||
|
b'\x00\x00\x00\x00'
|
||||||
|
b'\x10\x11\x12\x13' # Untouched because unused
|
||||||
|
) == memory[0:20]
|
||||||
|
|
||||||
|
@pytest.mark.integration_test
|
||||||
|
def test___alloc___no_init():
|
||||||
|
code_py = """
|
||||||
|
@exported
|
||||||
|
def testEntry() -> u8:
|
||||||
|
return 13
|
||||||
|
"""
|
||||||
|
|
||||||
|
rtime = setup_interpreter(code_py)
|
||||||
|
|
||||||
|
for idx in range(128):
|
||||||
|
rtime.get_memory(0)[idx] = idx
|
||||||
|
|
||||||
|
sys.stderr.write(f'{DASHES} Memory (pre run) {DASHES}\n')
|
||||||
|
_dump_memory(rtime.get_memory(0))
|
||||||
|
|
||||||
|
with pytest.raises(RuntimeError, match='unreachable executed'):
|
||||||
|
rtime.find_function('stdlib.alloc.__alloc__')(32)
|
||||||
|
|
||||||
|
@pytest.mark.integration_test
|
||||||
|
def test___alloc___ok():
|
||||||
|
code_py = """
|
||||||
|
@exported
|
||||||
|
def testEntry() -> u8:
|
||||||
|
return 13
|
||||||
|
"""
|
||||||
|
|
||||||
|
rtime = setup_interpreter(code_py)
|
||||||
|
|
||||||
|
for idx in range(128):
|
||||||
|
rtime.get_memory(0)[idx] = idx
|
||||||
|
|
||||||
|
sys.stderr.write(f'{DASHES} Memory (pre run) {DASHES}\n')
|
||||||
|
_dump_memory(rtime.get_memory(0))
|
||||||
|
|
||||||
|
offset = rtime.find_function('stdlib.alloc.__init__')()
|
||||||
|
offset = rtime.find_function('stdlib.alloc.__alloc__')(32)
|
||||||
|
|
||||||
|
sys.stderr.write(f'{DASHES} Memory (pre run) {DASHES}\n')
|
||||||
|
_dump_memory(rtime.get_memory(0))
|
||||||
|
|
||||||
|
memory = rtime.get_memory(0).tobytes()
|
||||||
|
|
||||||
|
assert b'\xC0\xA1\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' == memory[0:12]
|
||||||
|
|
||||||
|
assert 0 == offset
|
||||||
Loading…
x
Reference in New Issue
Block a user