fetch ("mandelbrot.wasm").then (
	response => response.arrayBuffer ().then (
		arrayBuffer => WebAssembly.instantiate (arrayBuffer, importObject).then (
		response => {
			// Utiliser response.instance
		},
		error => { console.log (error.message) }
)));

var importObject = {
	someImports: {
		memory: new WebAssembly.Memory ({ initial: Math.ceil (WIDTH * HEIGHT * 4 / 65536) })
	}
}

 (func                    ;; Empiler (A)
	(local $i i32)
	(block                ;; Empiler (B)
		br 0            ;; Sauter en (B)
		i32.const 7
		set_local $i
		;; (B)
	)
	;; (A)
)

 (func                    ;; Empiler (A)
	(local $i i32)
	(loop                ;; Empiler (B)
		;; (B)
		br 0            ;; Sauter en (B)
		i32.const 7
		set_local $i
	)
	;; (A)
)

 (func                                                        ;; Empiler (A)
	(local $i i32)
	(set_local $i (i32.const 10))
	(loop                                                    ;; Empiler (B)
		;; (B)
		(set_local $i (i32.sub (get_local $i) (i32.const 1)))
		(br_if 0 (i32.ne (get_local $i) (i32.const 0)))        ;; Sauter en (B)
	)
	;; (A)
)

 (func                                                ;; Empiler (A)
	(local $i i32)
	(local $j i32)
	(set_local $i (i32.const 5))
	(set_local $j (i32.const 10))
	(block                                            ;; Empiler (B)
		(loop                                        ;; Empiler (C)
			;; (C)
			(set_local $i (i32.sub (get_local $i) (i32.const 1)))
			(set_local $j (i32.sub (get_local $j) (i32.const 1)))
			(br_if 1 (i32.eqz (get_local $i)))        ;; Sauter en (C)
			(br_if 1 (i32.eqz (get_local $j)))        ;; Sauter en (C)
			br 0                                    ;; Sauter en (B)
		)
		;; (B)
	)
	;; (A)
)

 

(func                                            ;; Empiler (A)
	(local $i i32)
	(local $j i32)
	(set_local $i (i32.const 5))
	(set_local $j (i32.const 10))
	(loop                                        ;; Empiler (B)
		;; (B)
		(set_local $i (i32.sub (get_local $i) (i32.const 1)))
		(set_local $j (i32.sub (get_local $j) (i32.const 1)))
		(br_if 1 (i32.eqz (get_local $i)))        ;; Sauter en (A)
		(br_if 1 (i32.eqz (get_local $j)))        ;; Sauter en (A)
		br 0                                    ;; Sauter en (B)
	)
	nop                                            ;; Jamais exécutée
	;; (A)
)

 (module
	(memory (import "imports" "memory") 1)
	(func (export "mandelbrot")
		(param $width i32)
		(param $height i32)
		(param $minX f64)
		(param $maxX f64)
		(param $minY f64)
		(param $maxY f64)
		(param $maxN i32)
		;; ...
	)
)

 (func $mandelbrot (export "mandelbrot")
	(param $width i32)
	(param $height i32)
	(param $minX f64)
	(param $maxX f64)
	(param $minY f64)
	(param $maxY f64)
	(param $maxN i32)
	(local $i i32)
	(local $j i32)
	(local $dx f64)
	(local $dy f64)
	(local $x f64)
	(local $y f64)
	(local $a f64)
	(local $b f64)
	(local $c f64)
	(local $n i32)
	(local $index i32)
	(set_local $dx (f64.div (f64.sub (get_local $maxX) (get_local $minX)) (f64.convert_u/i32 (get_local $width))))
	(set_local $dy (f64.div (f64.sub (get_local $maxY) (get_local $minY)) (f64.convert_u/i32 (get_local $height))))
	(set_local $j (get_local $height))
	(set_local $y (get_local $minY))
	(set_local $index (i32.const 0))
	(loop
		(set_local $i (get_local $width))
		(set_local $x (get_local $minX))
		(loop    
			(set_local $a (f64.const 0.0))
			(set_local $b (f64.const 0.0))
			(set_local $n (get_local $maxN))
			(block
				(loop
					;; $c = $a (just push it)
					get_local $a
					;; Set $a = $a * $a - $b * $b + $x
					(f64.mul (get_local $a) (get_local $a))
					(f64.sub (f64.mul (get_local $b) (get_local $b)))
					(set_local $a (f64.add (get_local $x)))
					;; Set $b = 2 * $c * $b + y
					(f64.mul (f64.const 2.0))        ;; This pops $a
					(f64.mul (get_local $b))
					(set_local $b (f64.add (get_local $y)))
					;; Set $n -= 1
					(set_local $n (i32.sub (get_local $n) (i32.const 1)))
					;; Break if $a * $a + $b * $b >= 4.0
					(f64.add (f64.mul (get_local $a) (get_local $a)) (f64.mul (get_local $b) (get_local $b)))
					(br_if 1 (f64.ge (f64.const 4.0)))
					;; Break if $n == 0, else loop
					(br_if 1 (i32.eqz (get_local $n)))
					br 0
				)
			)
			;; Store (0xFF000000 | (($n * 255 / ($maxN - 1)) & 0xFF)) at index $index
			get_local $index
			(i32.trunc_u/f64 (f64.div (f64.convert_u/i32 (i32.mul (get_local $n) (i32.const 255))) (f64.convert_u/i32 (i32.sub (get_local $maxN) (i32.const 1)))))
			(i32.or (i32.const 0xFF000000))
			i32.store
			;; Same thing with S-expressions :
			;;(i32.store
			;;    (get_local $index)
			;;    (i32.or
			;;        (i32.const 0xFF000000)
			;;        (i32.trunc_u/f64 (f64.div (f64.convert_u/i32 (i32.mul (get_local $n) (i32.const 255))) (f64.convert_u/i32 (i32.sub (get_local $maxN) (i32.const 1)))))
			;;    )
			;;)
			;; Set $index += 4
			(set_local $index (i32.add (get_local $index) (i32.const 4)))
			
			;; Set $x += $dx
			(set_local $x (f64.add (get_local $x) (get_local $dx)))
			;; Loop if $i -- != 0, else exit
			(set_local $i (i32.sub (get_local $i) (i32.const 1)))
			(br_if 0 (i32.ne (get_local $i) (i32.const 0)))
		)
		;; Set $y += $dy
		(set_local $y (f64.add (get_local $y) (get_local $dy)))
		;; Loop if $j -- != 0, else exit
		(set_local $j (i32.sub (get_local $j) (i32.const 1)))
		(br_if 0 (i32.ne (get_local $j) (i32.const 0)))
	)
)

var width = 11, height = 11;
var importObject = {
	imports: {
		memory: new WebAssembly.Memory ({ initial: Math.ceil (width * height * 4 / 65536) })
	}
};
const wasmInstance = new WebAssembly.Instance (wasmModule, importObject);
wasmInstance.exports.mandelbrot (width, height, -2.1, 1.1, -1.4, 1.4, 20);
var i, j, pixels;
pixels = new Uint32Array (importObject.imports.memory.buffer);
for (j = 0; j != height; j ++) {
	for (i = 0; i != width  ; i++)
		console.log (`(${i}, ${j}) = ${pixels[i + j * width].toString (16)}`);
}