diff --git a/Makefile b/Makefile index 09bbb51..8f4d045 100644 --- a/Makefile +++ b/Makefile @@ -3,7 +3,7 @@ WABT_DIR := /home/johan/Sources/github.com/WebAssembly/wabt WAT2WASM := $(WABT_DIR)/bin/wat2wasm WASM2C := $(WABT_DIR)/bin/wasm2c -%.wat: %.py phasm/*.py venv/.done +%.wat: %.py $(shell find phasm -name '*.py') venv/.done venv/bin/python -m phasm $< $@ %.wat.html: %.wat diff --git a/TODO.md b/TODO.md index 048c4ca..2775e07 100644 --- a/TODO.md +++ b/TODO.md @@ -1,6 +1,5 @@ # TODO -- Rename ourlang.Struct to OurTypeStruct - - Maybe rename this to a types module? -- Fix naming in Suite() calls +- Implement foldl for bytes - Replace ___new_reference___ by stdlib.alloc.__alloc__ +- Implement a trace() builtin for debugging diff --git a/examples/buffer.html b/examples/buffer.html index d0b14ca..e5d7c19 100644 --- a/examples/buffer.html +++ b/examples/buffer.html @@ -30,22 +30,20 @@ WebAssembly.instantiateStreaming(fetch('buffer.wasm'), importObject) // Allocate room within the memory of the WebAssembly class let size = 8; - // TODO: Use bytes constructor - let offset = app.instance.exports.___new_reference___(size); - new Uint32Array(app.instance.exports.memory.buffer, offset, 1)[0] = size; + stdlib_alloc___init__ = app.instance.exports['stdlib.alloc.__init__'] + stdlib_alloc___init__() + + stdlib_types___alloc_bytes__ = app.instance.exports['stdlib.types.__alloc_bytes__'] + + let offset = stdlib_types___alloc_bytes__(size) var i8arr = new Uint8Array(app.instance.exports.memory.buffer, offset + 4, size); //Fill it - let sum = 0; for (var i = 0; i < size; i++) { i8arr[i] = i + 5; - sum += i8arr[i]; let from_wasm = app.instance.exports.index(offset, i); log('i8arr[' + i + '] = ' + from_wasm); } - - log('expected result = ' + sum); - log('actual result = ' + app.instance.exports.sum(offset)); }); diff --git a/examples/buffer.py b/examples/buffer.py index 74eb023..96944fd 100644 --- a/examples/buffer.py +++ b/examples/buffer.py @@ -1,7 +1,3 @@ -@exported -def sum() -> i32: # TODO: Should be [i32] -> i32 - return 0 # TODO: Implement me - @exported def index(inp: bytes, idx: i32) -> i32: return inp[idx] diff --git a/phasm/compiler.py b/phasm/compiler.py index 6c9ce98..eb02672 100644 --- a/phasm/compiler.py +++ b/phasm/compiler.py @@ -6,9 +6,9 @@ from typing import Generator from . import ourlang from . import typing from . import wasm -from . import wasmeasy from .stdlib import alloc as stdlib_alloc +from .stdlib import types as stdlib_types from .wasmeasy import i32, i64 Statements = Generator[wasm.Statement, None, None] @@ -380,6 +380,7 @@ def module(inp: ourlang.Module) -> wasm.Module: stdlib_alloc.__init__, stdlib_alloc.__find_free_block__, stdlib_alloc.__alloc__, + stdlib_types.__alloc_bytes__, _generate____access_bytes_index___(inp), ] + [ function(x) diff --git a/phasm/stdlib/types.py b/phasm/stdlib/types.py new file mode 100644 index 0000000..f815ead --- /dev/null +++ b/phasm/stdlib/types.py @@ -0,0 +1,32 @@ +""" +stdlib: Standard types that are not wasm primitives +""" +from phasm.wasmgenerator import Generator, VarType_i32 as i32, func_wrapper + +from phasm.stdlib import alloc + +@func_wrapper() +def __alloc_bytes__(g: Generator, length: i32) -> i32: + """ + Allocates room for a bytes instance, but does not write + anything to the allocated memory + """ + result = i32('result') + + # Allocate the length of the byte string, as well + # as 4 bytes for a length header + g.local.get(length) + g.i32.const(4) + g.i32.add() + g.call(alloc.__alloc__) + + # Store the address in a variable so we can use it up + # for writing the length header + g.local.tee(result) + g.local.get(length) + g.i32.store() + + # Get the address back from the variable as return + g.local.get(result) + + return i32('return') # To satisfy mypy