85 lines
3.2 KiB
WebAssembly Text Format
85 lines
3.2 KiB
WebAssembly Text Format
(module
|
|
;; import console.log.
|
|
(func $print (import "guppy" "print") (param i32))
|
|
|
|
;; declare a table with a reference to $halt in it. idk why, but this
|
|
is ;; necessary to use funcrefs lmfao.
|
|
(table 2 funcref)
|
|
(elem (i32.const 0) $halt)
|
|
|
|
;; an array of return continuations.
|
|
(type $cont (func (param i32)))
|
|
(type $cont-stack-type (array (mut (ref null $cont))))
|
|
(global $cont-stack (ref $cont-stack-type)
|
|
(array.new_default $cont-stack-type (i32.const 128)))
|
|
(global $cont-stack-top (mut i32) (i32.const 0))
|
|
|
|
;; a global array on which we pass arguments.
|
|
(type $arg-array-type (array (mut (ref null eq))))
|
|
(global $arg-array (ref $arg-array-type)
|
|
(array.new_default $arg-array-type (i32.const 32)))
|
|
|
|
;; cps'd function. takes the number of scheme arguments as the sole
|
|
;; wasm argument. arguments are read into locals from
|
|
;; $arg-array. does not return, instead popping a continuation from
|
|
;; $cont-stack and tail-calling it.
|
|
(func $add (param $nargs i32)
|
|
(local $x (ref eq))
|
|
(local $y (ref eq))
|
|
(local $return (ref $cont))
|
|
(local.set $x (ref.as_non_null
|
|
(array.get $arg-array-type
|
|
(global.get $arg-array)
|
|
(i32.const 0))))
|
|
(local.set $y (ref.as_non_null
|
|
(array.get $arg-array-type
|
|
(global.get $arg-array)
|
|
(i32.const 1))))
|
|
(array.set $arg-array-type
|
|
(global.get $arg-array)
|
|
(i32.const 0)
|
|
(ref.i31
|
|
(i32.add (i31.get_s (ref.cast (ref i31) (local.get $x)))
|
|
(i31.get_s (ref.cast (ref i31) (local.get $y))))))
|
|
(return_call_ref
|
|
$cont
|
|
(i32.const 1)
|
|
(block (result (ref $cont))
|
|
(ref.as_non_null
|
|
(array.get $cont-stack-type
|
|
(global.get $cont-stack)
|
|
(global.get $cont-stack-top)))
|
|
(global.set $cont-stack-top
|
|
(i32.sub (global.get $cont-stack-top)
|
|
(i32.const 1))))))
|
|
;; for demo purposes, this continuation calls console.log and stops.
|
|
(func $halt (param $nargs i32)
|
|
(call $print
|
|
(i31.get_s
|
|
(ref.cast
|
|
(ref i31)
|
|
(ref.as_non_null
|
|
(array.get $arg-array-type
|
|
(global.get $arg-array)
|
|
(i32.const 0)))))))
|
|
;; entry point }:3
|
|
(func (export "main")
|
|
;; push args
|
|
(array.set $arg-array-type
|
|
(global.get $arg-array)
|
|
(i32.const 0)
|
|
(ref.i31 (i32.const 4)))
|
|
(array.set $arg-array-type
|
|
(global.get $arg-array)
|
|
(i32.const 1)
|
|
(ref.i31 (i32.const 5)))
|
|
;; push return continuation
|
|
(array.set $cont-stack-type
|
|
(global.get $cont-stack)
|
|
(i32.const 0)
|
|
(ref.func $halt))
|
|
;; make call }:)
|
|
(return_call $add
|
|
;; inform $add how many arguments we called it with
|
|
(i32.const 2))))
|