Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reference types #101

Merged
merged 4 commits into from May 9, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
@@ -1,5 +1,6 @@
node_modules/
_esy/
_build/
phated marked this conversation as resolved.
Show resolved Hide resolved
.merlin
META
.vscode/
Expand Down
16 changes: 16 additions & 0 deletions js/op.ml
Expand Up @@ -687,3 +687,19 @@ let narrow_u_vec_i32x4_to_vec_i16x8 : t =
global ##. binaryen ##. Operations ##. NarrowUVecI32x4ToVecI16x8

let swizzle_vec8x16 : t = global ##. binaryen ##. Operations ##. SwizzleVec8x16

let ref_is_null : t = global ##. binaryen ##. Operations ##. RefIsNull

let ref_is_func : t = global ##. binaryen ##. Operations ##. RefIsFunc

let ref_is_data : t = global ##. binaryen ##. Operations ##. RefIsData

let ref_is_i31 : t = global ##. binaryen ##. Operations ##. RefIsI31

let ref_as_non_null : t = global ##. binaryen ##. Operations ##. RefAsNonNull

let ref_as_func : t = global ##. binaryen ##. Operations ##. RefAsFunc

let ref_as_data : t = global ##. binaryen ##. Operations ##. RefAsData

let ref_as_i31 : t = global ##. binaryen ##. Operations ##. RefAsI31
10 changes: 5 additions & 5 deletions src/binaryen_stubs_expressions.c
Expand Up @@ -626,6 +626,11 @@ caml_binaryen_expression_id_ref_is(value unit) {
CAMLreturn(Val_int(BinaryenRefIsId()));
}
CAMLprim value
caml_binaryen_expression_id_ref_as(value unit) {
CAMLparam1(unit);
CAMLreturn(Val_int(BinaryenRefAsId()));
}
CAMLprim value
caml_binaryen_expression_id_ref_func(value unit) {
CAMLparam1(unit);
CAMLreturn(Val_int(BinaryenRefFuncId()));
Expand Down Expand Up @@ -735,11 +740,6 @@ caml_binaryen_expression_id_array_len(value unit) {
CAMLparam1(unit);
CAMLreturn(Val_int(BinaryenArrayLenId()));
}
CAMLprim value
caml_binaryen_expression_id_ref_as(value unit) {
CAMLparam1(unit);
CAMLreturn(Val_int(BinaryenRefAsId()));
}

// Expression operations

Expand Down
56 changes: 56 additions & 0 deletions src/binaryen_stubs_ops.c
Expand Up @@ -2170,3 +2170,59 @@ caml_binaryen_binaryen_swizzle_vec8x16(value unit) {
BinaryenOp op = BinaryenSwizzleVec8x16();
CAMLreturn(alloc_BinaryenOp(op));
}

CAMLprim value
caml_binaryen_binaryen_ref_is_null(value unit) {
CAMLparam1(unit);
BinaryenOp op = BinaryenRefIsNull();
CAMLreturn(alloc_BinaryenOp(op));
}

CAMLprim value
caml_binaryen_binaryen_ref_is_func(value unit) {
CAMLparam1(unit);
BinaryenOp op = BinaryenRefIsFunc();
CAMLreturn(alloc_BinaryenOp(op));
}

CAMLprim value
caml_binaryen_binaryen_ref_is_data(value unit) {
CAMLparam1(unit);
BinaryenOp op = BinaryenRefIsData();
CAMLreturn(alloc_BinaryenOp(op));
}

CAMLprim value
caml_binaryen_binaryen_ref_is_i31(value unit) {
CAMLparam1(unit);
BinaryenOp op = BinaryenRefIsI31();
CAMLreturn(alloc_BinaryenOp(op));
}

CAMLprim value
caml_binaryen_binaryen_ref_as_non_null(value unit) {
CAMLparam1(unit);
BinaryenOp op = BinaryenRefAsNonNull();
CAMLreturn(alloc_BinaryenOp(op));
}

CAMLprim value
caml_binaryen_binaryen_ref_as_func(value unit) {
CAMLparam1(unit);
BinaryenOp op = BinaryenRefAsFunc();
CAMLreturn(alloc_BinaryenOp(op));
}

CAMLprim value
caml_binaryen_binaryen_ref_as_data(value unit) {
CAMLparam1(unit);
BinaryenOp op = BinaryenRefAsData();
CAMLreturn(alloc_BinaryenOp(op));
}

CAMLprim value
caml_binaryen_binaryen_ref_as_i31(value unit) {
CAMLparam1(unit);
BinaryenOp op = BinaryenRefAsI31();
CAMLreturn(alloc_BinaryenOp(op));
}
32 changes: 32 additions & 0 deletions src/op.ml
Expand Up @@ -1306,3 +1306,35 @@ let narrow_u_vec_i32x4_to_vec_i16x8 = narrow_u_vec_i32x4_to_vec_i16x8 ()
external swizzle_vec8x16 : unit -> t = "caml_binaryen_binaryen_swizzle_vec8x16"

let swizzle_vec8x16 = swizzle_vec8x16 ()

external ref_is_null : unit -> t = "caml_binaryen_binaryen_ref_is_null"

let ref_is_null = ref_is_null ()

external ref_is_func : unit -> t = "caml_binaryen_binaryen_ref_is_func"

let ref_is_func = ref_is_func ()

external ref_is_data : unit -> t = "caml_binaryen_binaryen_ref_is_data"

let ref_is_data = ref_is_data ()

external ref_is_i31 : unit -> t = "caml_binaryen_binaryen_ref_is_i31"

let ref_is_i31 = ref_is_i31 ()

external ref_as_non_null : unit -> t = "caml_binaryen_binaryen_ref_as_non_null"

let ref_as_non_null = ref_as_non_null ()

external ref_as_func : unit -> t = "caml_binaryen_binaryen_ref_as_func"

let ref_as_func = ref_as_func ()

external ref_as_data : unit -> t = "caml_binaryen_binaryen_ref_as_data"

let ref_as_data = ref_as_data ()

external ref_as_i31 : unit -> t = "caml_binaryen_binaryen_ref_as_i31"

let ref_as_i31 = ref_as_i31 ()
33 changes: 33 additions & 0 deletions test/test.expected
@@ -1,13 +1,17 @@
(module
(type $i32_i32_=>_i32 (func (param i32 i32) (result i32)))
(type $none_=>_none (func))
(type $externref_=>_i32 (func (param externref) (result i32)))
(type $externref_i32_i32_=>_i32 (func (param externref i32 i32) (result i32)))
(import "future-wasi" "write" (func $write (param externref i32 i32) (result i32)))
(global $max_int64 i64 (i64.const 9223372036854775807))
(global $test_float64_bits f64 (f64.const 1.23))
(memory $0 1)
(table $table 1 1 funcref)
(elem $elem (i32.const 0) $adder)
(export "adder" (func $adder))
(export "memory" (memory $0))
(export "hello" (func $hello))
(start $start)
(func $adder (param $0 i32) (param $1 i32) (result i32)
(block $add (result i32)
Expand Down Expand Up @@ -36,15 +40,26 @@
)
)
)
(func $hello (param $0 externref) (result i32)
(call $write
(local.get $0)
(i32.const 0)
(i32.const 1)
)
)
)
(module
(type $none_=>_none (func))
(type $externref_=>_i32 (func (param externref) (result i32)))
(type $i32_i32_=>_i32 (func (param i32 i32) (result i32)))
(type $externref_i32_i32_=>_i32 (func (param externref i32 i32) (result i32)))
(import "future-wasi" "write" (func $write (param externref i32 i32) (result i32)))
(memory $0 1)
(table $table 1 1 funcref)
(elem $elem (i32.const 0) $adder)
(export "adder" (func $adder))
(export "memory" (memory $0))
(export "hello" (func $hello))
(start $start)
(func $adder (; has Stack IR ;) (param $0 i32) (param $1 i32) (result i32)
(i32.add
Expand All @@ -66,15 +81,26 @@
)
)
)
(func $hello (; has Stack IR ;) (param $0 externref) (result i32)
(call $write
(local.get $0)
(i32.const 0)
(i32.const 1)
)
)
)
(module
(type $none_=>_none (func))
(type $externref_=>_i32 (func (param externref) (result i32)))
(type $i32_i32_=>_i32 (func (param i32 i32) (result i32)))
(type $externref_i32_i32_=>_i32 (func (param externref i32 i32) (result i32)))
(import "future-wasi" "write" (func $fimport$0 (param externref i32 i32) (result i32)))
(memory $0 1)
(table $0 1 1 funcref)
(elem (i32.const 0) $0)
(export "adder" (func $0))
(export "memory" (memory $0))
(export "hello" (func $2))
(start $1)
(func $0 (param $0 i32) (param $1 i32) (result i32)
(i32.add
Expand All @@ -96,4 +122,11 @@
)
)
)
(func $2 (param $0 externref) (result i32)
(call $fimport$0
(local.get $0)
(i32.const 0)
(i32.const 1)
)
)
)
33 changes: 33 additions & 0 deletions test/test.ml
Expand Up @@ -95,20 +95,53 @@ let _ = Function.set_start wasm_mod start

let _ = Memory.set_memory wasm_mod 1 Memory.unlimited "memory" [] false

(* Create an imported "write" function i32 (externref, i32, i32) *)
(* Similar to the example here: https://bytecodealliance.org/articles/reference-types-in-wasmtime *)

let _ =
Import.add_function_import wasm_mod "write" "future-wasi" "write"
(Type.create [| Type.externref; Type.int32; Type.int32 |])
Type.int32

(* Create a function that calls the imported write function *)
let _ =
Function.add_function wasm_mod "hello" Type.externref Type.int32 [||]
(Expression.Call.make wasm_mod "write"
[
Expression.Local_get.make wasm_mod 0 Type.externref;
Expression.Const.make wasm_mod (Literal.int32 0l);
Expression.Const.make wasm_mod (Literal.int32 1l);
]
Type.int32)

let _ = Export.add_function_export wasm_mod "hello" "hello"

(* Finally, we print 3 versions of the module to be checked against test.expected *)

(* 1. Print the the module as-is *)

let _ = Module.print wasm_mod

(* 2. Optimize, then print the module *)

let _ = Module.optimize wasm_mod

let _ = Module.print wasm_mod

(* 3. Copy previous module bytes into new module, validate, and print *)

let byts, _ = Module.write wasm_mod None

let new_mod = Module.read byts

let _ = Module.set_features new_mod [ Module.Feature.all ]

let _ = Module.validate new_mod

let _ = Module.print new_mod

(* Dispose the modules 👋 *)

let _ = Module.dispose wasm_mod

let _ = Module.dispose new_mod
16 changes: 16 additions & 0 deletions virtual/op.mli
Expand Up @@ -615,3 +615,19 @@ val narrow_s_vec_i32x4_to_vec_i16x8 : t
val narrow_u_vec_i32x4_to_vec_i16x8 : t

val swizzle_vec8x16 : t

val ref_is_null : t

val ref_is_func : t

val ref_is_data : t

val ref_is_i31 : t

val ref_as_non_null : t

val ref_as_func : t

val ref_as_data : t

val ref_as_i31 : t