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 However, since Forth only requires structured jumps, the compiler can easily be implemented
using the loop and branch instructions available in WebAssembly. 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 ### The Loader

View file

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

View file

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

View file

@ -298,12 +298,12 @@
;; 6.1.0460 ;; 6.1.0460
(func $semicolon (param i32) (func $semicolon (param i32)
(local $bodySize i32) (local $bodySize i32)
(local $nameLength i32)
(call $emitEnd) (call $emitEnd)
(set_local $bodySize (i32.sub (get_global $cp) (i32.const !moduleHeaderBase)))
;; Update code size ;; Update code size
(set_local $bodySize (i32.sub (get_global $cp) (i32.const !moduleHeaderBase)))
(i32.store (i32.store
(i32.const !moduleHeaderCodeSizeBase) (i32.const !moduleHeaderCodeSizeBase)
(call $leb128-4p (call $leb128-4p
@ -322,8 +322,46 @@
(i32.const !moduleHeaderLocalCountBase) (i32.const !moduleHeaderLocalCountBase)
(call $leb128-4p (get_global $localsCount))) (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 ;; 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)) (i32.store (call $body (get_global $latest)) (get_global $nextTableIndex))
(set_global $nextTableIndex (i32.add (get_global $nextTableIndex) (i32.const 1))) (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[1]).to.eql(4);
expect(stack[2]).to.eql(5); 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", () => { describe("VARIABLE", () => {