Ask coding questions

← Back to all posts
Simple multiplication table code fails to run loop
xxpertHacker (476)

(If you don't want to or don't know how to help me, could you upvote this so that it gets seen by more people?)

I was setting up a very simple program in Wasm, using wat2wasm, because Repl's Wasm Repls are not stable, nor are they properly maintained.

The program would contain two loops, one nested in another, that would increment two variables $i and $j by one, until $i is greater than 12.
With each iteration then would output the value of $i, $j, and the result of them multiplied together.

To start, I needed a host language; JavaScript is the most common one, and it has native support for Wasm, since Wasm is the fourth language of the Web, and has finally been adopted as a WC3 standard.

I set up a simple import allowing access to console.log:

"use strict";

WebAssembly.instantiate(
	wasmModule, {
		console: {
			start: console.log.bind(null, "Times tables!"),
			table: console.log.bind(null,"%i Times tables:"),
			assign: console.log.bind(null, "%i × %i = %i")
		}
	}
).catch(console.log);

Here I had put console.log's optional format string parameter to use, allowing me to format my output in these three specific formats.

I would start off by calling start, then call table with every iteration of the outer loop, and then call assign in every iteration of the inner loop, in order to build of the "body" of the table.

My Wat was as follows:

(import "console" "start" (func $console::log::start (param)))
(import "console" "table" (func $console::log::table (param i32)))
(import "console" "assign" (func $console::log::assign (param i32 i32 i32)))

(start $_start)

(func $_start
	(local $i i32)
	(local $j i32)
	(call $console::log::start) ;; "Times tables!"

	(local.set $i
		(i32.const 1)
	) ;; i = 1
	(loop ;; this loop doesn't run at all
		(br_if 1
			(i32.le_s
				(local.get $i)
				(i32.const 12)
			) ;; i <= 12
		) ;; br
		(call $console::log::table
			(local.get $i)
		) ;; "%i Times tables:"

		(local.set $j
			(i32.const 1)
		) ;; j = 1
		(loop
			(br_if 2
				(i32.le_s
					(local.get $j)
					(i32.const 12)
				) ;; j <= 12
			) ;; br
			(call $console::log::assign
				(local.get $i)
				(local.get $j)
				(i32.mul
					(local.get $i)
					(local.get $j)
				)
			) ;; "%i × %i = %i"

			(local.set $j
				(i32.add
					(local.get $j)
					(i32.const 1)
				)
			) ;; ++j
		) ;; nested loop end

		(local.set $i
			(i32.add
				(local.get $i)
				(i32.const 1)
			)
		) ;; ++i
	) ;; outer loop end
)

It seems that my first loop, line #14, doesn't execute at all, yet I checked the value of the br_if, and it's 1, I tried negating it, and it only iterated once, instead of all 12 times.
I made sure to check that $i was properly being updated too.

Is anyone willing to help me that knows knows what I'm doing wrong?


Update

I attached a Repl to show the code in execution on Repl.

equivalent.mjs shows the equivalent JavaScript that the Wasm maps to.

Commentshotnewtop
firefish (743)

My question is why do you use wasm

xxpertHacker (476)

@firefish Because I was bored, and it was a pretty simple idea, so I was thinking that it could be easy to complete. But it turns out that I was wrong.

xxpertHacker (476)

@firefish Should I have used normal Asm?

firefish (743)

@xxpertHacker Hm.... try normal assembler then

firefish (743)

@xxpertHacker Yep, AT&T though, NASM is a joke

xxpertHacker (476)

@firefish tbh Wasm seems easier than both, because it's so high-level (in comparison to most native ASMs). I was literally about to go setup NASM on Repl and do it there instead, but if you suggest AT&T, guess I'll go check it out.

firefish (743)

@xxpertHacker It's easy to do AT&T assembler, just use gcc.

xxpertHacker (476)

@firefish Yeah but, I've gotta go learn their syntax. :)
Also, if I mess up with AT&T, I'm going to try asking on Repl again and get no responses, right?

firefish (743)

@xxpertHacker Ask me instead... If you want to know AT%T Assembly is also known as GAS, or GNU Assembler

xxpertHacker (476)

@firefish I've heard of all three but I did not know they were the same.