Add name section support.

Resolves #2
This commit is contained in:
Remko Tronçon 2018-05-31 21:11:04 +02:00
parent fed7aa5389
commit 76b1975ff6
5 changed files with 52 additions and 10 deletions

View file

@ -83,6 +83,11 @@ As WebAssembly doesn't support unstructured jumps, control flow words (`IF/ELSE/
However, since Forth only requires structured jumps, the compiler can easily be implemented
using the loop and branch instructions available in WebAssembly.
Finally, the compiler adds minimal debug information about the compiled word in
the [name section](https://github.com/WebAssembly/design/blob/master/BinaryEncoding.md#name-section), making it easier for doing some debugging in the browser.
![Debugger view of a compiled word](https://el-tramo.be/blog/waforth/debugger.png "Debugger view of a compiled word")
### The Loader

View file

@ -60,12 +60,7 @@ class WAForth {
if (index >= table.length) {
table.grow(table.length); // Double size
}
// console.log(
// "Load",
// index,
// new Uint8Array(data),
// arrayToBase64(data)
// );
// console.log("Load", index, new Uint8Array(data), arrayToBase64(data));
var module = new WebAssembly.Module(data);
new WebAssembly.Instance(module, {
env: { table, tableBase: index, memory, tos: -1 }

View file

@ -1,6 +1,6 @@
;; Template for defining 'word' modules
;; Used to 'reverse engineer' the binary code to emit from the compiler
(module
(module $quadruple
(import "env" "table" (table 4 anyfunc))
(import "env" "tableBase" (global $tableBase i32))
(import "env" "memory" (memory 1))

View file

@ -298,12 +298,12 @@
;; 6.1.0460
(func $semicolon (param i32)
(local $bodySize i32)
(local $nameLength i32)
(call $emitEnd)
(set_local $bodySize (i32.sub (get_global $cp) (i32.const !moduleHeaderBase)))
;; Update code size
(set_local $bodySize (i32.sub (get_global $cp) (i32.const !moduleHeaderBase)))
(i32.store
(i32.const !moduleHeaderCodeSizeBase)
(call $leb128-4p
@ -322,8 +322,46 @@
(i32.const !moduleHeaderLocalCountBase)
(call $leb128-4p (get_global $localsCount)))
;; Write a name section
(set_local $nameLength (i32.and (i32.load8_u (i32.add (get_global $latest) (i32.const 4)))
(i32.const !lengthMask)))
(i32.store8 (get_global $cp) (i32.const 0))
(i32.store8 (i32.add (get_global $cp) (i32.const 1))
(i32.add (i32.const 13) (i32.mul (i32.const 2)
(get_local $nameLength))))
(i32.store8 (i32.add (get_global $cp) (i32.const 2)) (i32.const 0x04))
(i32.store8 (i32.add (get_global $cp) (i32.const 3)) (i32.const 0x6e))
(i32.store8 (i32.add (get_global $cp) (i32.const 4)) (i32.const 0x61))
(i32.store8 (i32.add (get_global $cp) (i32.const 5)) (i32.const 0x6d))
(i32.store8 (i32.add (get_global $cp) (i32.const 6)) (i32.const 0x65))
(set_global $cp (i32.add (get_global $cp) (i32.const 7)))
(i32.store8 (get_global $cp) (i32.const 0x00))
(i32.store8 (i32.add (get_global $cp) (i32.const 1))
(i32.add (i32.const 1) (get_local $nameLength)))
(i32.store8 (i32.add (get_global $cp) (i32.const 2)) (get_local $nameLength))
(set_global $cp (i32.add (get_global $cp) (i32.const 3)))
(call $memcpy (get_global $cp)
(i32.add (get_global $latest) (i32.const 5))
(get_local $nameLength))
(set_global $cp (i32.add (get_global $cp) (get_local $nameLength)))
(i32.store8 (get_global $cp) (i32.const 0x01))
(i32.store8 (i32.add (get_global $cp) (i32.const 1))
(i32.add (i32.const 3) (get_local $nameLength)))
(i32.store8 (i32.add (get_global $cp) (i32.const 2)) (i32.const 0x01))
(i32.store8 (i32.add (get_global $cp) (i32.const 3)) (i32.const 0x00))
(i32.store8 (i32.add (get_global $cp) (i32.const 4)) (get_local $nameLength))
(set_global $cp (i32.add (get_global $cp) (i32.const 5)))
(call $memcpy (get_global $cp)
(i32.add (get_global $latest) (i32.const 5))
(get_local $nameLength))
(set_global $cp (i32.add (get_global $cp) (get_local $nameLength)))
;; Load the code and store the index
(call $shell_load (i32.const !moduleHeaderBase) (get_local $bodySize) (get_global $nextTableIndex))
(call $shell_load (i32.const !moduleHeaderBase)
(i32.sub (get_global $cp) (i32.const !moduleHeaderBase))
(get_global $nextTableIndex))
(i32.store (call $body (get_global $latest)) (get_global $nextTableIndex))
(set_global $nextTableIndex (i32.add (get_global $nextTableIndex) (i32.const 1)))

View file

@ -1012,6 +1012,10 @@ describe("WAForth", () => {
expect(stack[1]).to.eql(4);
expect(stack[2]).to.eql(5);
});
it("should compile a name with an illegal WASM character", () => {
run(': F" 3 0 DO 2 LOOP ;');
});
});
describe("VARIABLE", () => {