Need help with Jack to WebAssembly code generator

classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

Need help with Jack to WebAssembly code generator

Sunner
Hello,

I've been trying to write a Jack to WebAssembly compiler, since WASM also is a stack based language like the Jack VM and this would allow Jack programs to be run inside a browser. Basic expression evaluation and assigning variables works like a charm. Blocks such as while and if pose a challenge though that I don't know how to tackle. In Jack, these blocks allow you to return from the function at any time, in WASM however, it seems that you cannot do that so easily. Take for instance the following Jack code:


class Math {
	/** Returns the absolute value of x. */
	function int abs(int x) {
		if (x < 0) {
			return -x;
		} else {
			return x;
		}
	}
}

Using my compiler, I get the following WASM out:


(module $Math
	(func $abs
		(export "abs")
		(param $p_x i32)
		(result i32)
		;; if (x < 0)
		(block $ELSE0
			(block $IF0
				(br_if $IF0
					(i32.eqz 
						(i32.lt_s 
							(local.get $p_x)
							(i32.const 0)
						)
					)
				)
			)
			;; return -x;
			(return 
				(i32.sub 
					(i32.const 0)
					(local.get $p_x)
				)
			)
			(br $ELSE0)
			;; return x;
			(return 
				(local.get $p_x)
			)
		)
	)
)

When trying to compile this in NodeJS, I get the following error: CompileError: WebAssembly.instantiate(): Compiling function #0:"abs" failed: expected 1 elements on the stack for fallthru to @1, found 0 @+59

Anyone here with a bit more experience in compiler construction and/or WASM know how to solve this? I've tried to find answers on google, but to no avail.

Reply | Threaded
Open this post in threaded view
|

Re: Need help with Jack to WebAssembly code generator

Lozminda
That looks like a great idea and thanks for introducing me to Wasm. However you'll notice the previous sentence indicates of how much help I can be !

Good luck, Lozminda

Reply | Threaded
Open this post in threaded view
|

Re: Need help with Jack to WebAssembly code generator

Lozminda
Hi again.

Have just been reading the Wasm wiki page, it looks like (and I might be way off the mark here) that Wasm does "returns" in a very similar fashion to N2T (Nand to Tetris) VM machine i.e. a call to a label that's been generated in a look up table. (labels corresponding to points in the asm code). Chapters 7 & 8 of the N2T book (sorry I'm a bit rusty haven't looked at those chapters for a few months).

I'm sure more knowledgeable minds will correct me if I'm wrong.

Apologies if I'm heading in the wrong direction with this...

Reply | Threaded
Open this post in threaded view
|

Re: Need help with Jack to WebAssembly code generator

Sunner
It seems that it is a bit more complicated than that:
From what I could gather, control flow (if, while, etc.) in WASM works through "blocks", that can each return values as well (but not through the return instruction, they return the value on top of the stack), so when I try to return a value from within a block, it complains. When I rewrite my Math.abs function so that I declare a local result variable and return that at the end, it compiles successfully and works as expected. However, this requires to rewrite every code so that blocks don't return and I would like that every valid Jack program works :P

Also, you cannot jump to any label, you can only jump to the end of the current block. This looks like a deliberate choice by the WASM designers, but technically that should not be an issue, since Jack doesn't have gotos anyway.

Thanks for taking interest in my little project by the way ;)
Reply | Threaded
Open this post in threaded view
|

Re: Need help with Jack to WebAssembly code generator

ivant
I think in this case you may find more help with the WASM community, because your question requires knowledge in WASM rather than Jack or N2T.

But please keep on posting here of your findings and progress! It is a nice project and would be cool to see the demos directly in your browser.