From 6448aeb4ae00a07c98b0386fc1a82f6b653ac2c0 Mon Sep 17 00:00:00 2001 From: Oscar Spencer Date: Sun, 24 Jan 2021 18:21:47 -0500 Subject: [PATCH] feat: Allow signed narrow-width loads (#62) --- js/expression.ml | 3 ++- src/binaryen_stubs_expressions.c | 11 ++++++----- src/expression.ml | 6 ++++-- test/test.expected | 12 ++++++++++-- test/test.ml | 13 ++++++++----- virtual/expression.mli | 2 +- 6 files changed, 31 insertions(+), 16 deletions(-) diff --git a/js/expression.ml b/js/expression.ml index da4f4a8e..8270bd8b 100644 --- a/js/expression.ml +++ b/js/expression.ml @@ -83,11 +83,12 @@ let global_set wasm_mod name value = let scope = get wasm_mod "global" in meth_call scope "set" [| inject (string name); inject value |] -let load wasm_mod byts offset align typ ptr = +let load wasm_mod byts ?(signed=false) offset align typ ptr = meth_call global##.binaryen "_BinaryenLoad" [| inject wasm_mod; inject byts; + inject signed; inject offset; inject align; inject typ; diff --git a/src/binaryen_stubs_expressions.c b/src/binaryen_stubs_expressions.c index 453cdc44..b17e362b 100644 --- a/src/binaryen_stubs_expressions.c +++ b/src/binaryen_stubs_expressions.c @@ -204,21 +204,22 @@ caml_binaryen_global_set(value _module, value _name, value _val) { } CAMLprim value -caml_binaryen_load(value _module, value _bytes, value _offset, value _align, value _ty, value _ptr) { - CAMLparam5(_module, _bytes, _offset, _align, _ty); - CAMLxparam1(_ptr); +caml_binaryen_load(value _module, value _bytes, value _signed_, value _offset, value _align, value _ty, value _ptr) { + CAMLparam5(_module, _bytes, _signed_, _offset, _align); + CAMLxparam2(_ty, _ptr); BinaryenModuleRef module = BinaryenModuleRef_val(_module); int bytes = Int_val(_bytes); + int8_t signed_ = Bool_val(_signed_); int offset = Int_val(_offset); int align = Int_val(_align); BinaryenType ty = BinaryenType_val(_ty); BinaryenExpressionRef ptr = BinaryenExpressionRef_val(_ptr); - BinaryenExpressionRef exp = BinaryenLoad(module, bytes, 0, offset, align, ty, ptr); + BinaryenExpressionRef exp = BinaryenLoad(module, bytes, signed_, offset, align, ty, ptr); CAMLreturn(alloc_BinaryenExpressionRef(exp)); } CAMLprim value caml_binaryen_load__bytecode(value * argv) { - return caml_binaryen_load(argv[0], argv[1], argv[2], argv[3], argv[4], argv[5]); + return caml_binaryen_load(argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6]); } CAMLprim value diff --git a/src/expression.ml b/src/expression.ml index 2673b2bc..1de90f4f 100644 --- a/src/expression.ml +++ b/src/expression.ml @@ -51,9 +51,11 @@ external global_get : Module.t -> string -> Type.t -> t external global_set : Module.t -> string -> t -> t = "caml_binaryen_global_set" (** Module, name, value. *) -external load : Module.t -> int -> int -> int -> Type.t -> t -> t +external load : Module.t -> int -> bool -> int -> int -> Type.t -> t -> t = "caml_binaryen_load__bytecode" "caml_binaryen_load" -(** Module, num_bytes, offset, align, type, ptr. *) +let load wasm_mod bytes ?(signed=false) offset align ty ptr = + load wasm_mod bytes signed offset align ty ptr +(** Module, num_bytes, ?signed, offset, align, type, ptr. *) external store : Module.t -> int -> int -> int -> t -> t -> Type.t -> t = "caml_binaryen_store__bytecode" "caml_binaryen_store" diff --git a/test/test.expected b/test/test.expected index 75455ea7..e8e88d8f 100644 --- a/test/test.expected +++ b/test/test.expected @@ -1,11 +1,15 @@ (module (type $i32_i32_=>_i32 (func (param i32 i32) (result i32))) + (memory $0 1) + (export "memory" (memory $0)) (func $adder (param $0 i32) (param $1 i32) (result i32) (block $add (result i32) (i32.add (select (local.get $0) - (local.get $1) + (i32.load8_s + (local.get $1) + ) (i32.const 1) ) (local.get $1) @@ -15,11 +19,15 @@ ) (module (type $i32_i32_=>_i32 (func (param i32 i32) (result i32))) + (memory $0 1) + (export "memory" (memory $0)) (func $0 (param $0 i32) (param $1 i32) (result i32) (i32.add (select (local.get $0) - (local.get $1) + (i32.load8_s + (local.get $1) + ) (i32.const 1) ) (local.get $1) diff --git a/test/test.ml b/test/test.ml index a2eb73df..27ebf85e 100644 --- a/test/test.ml +++ b/test/test.ml @@ -7,18 +7,21 @@ let params = Type.create [| Type.int32; Type.int32 |] let results = Type.int32 -(* Get arguments 0 and 1, add them *) -let x = Expression.local_get wasm_mod 0 Type.int32 +let x () = Expression.local_get wasm_mod 0 Type.int32 -let y = Expression.local_get wasm_mod 1 Type.int32 +let y () = Expression.local_get wasm_mod 1 Type.int32 -let select = Expression.select wasm_mod (Expression.const wasm_mod (Literal.int32 1l)) x y +let load = Expression.load wasm_mod 1 ~signed:true 0 0 Type.int32 (y ()) -let add = Expression.block wasm_mod ~return_type:Type.int32 "add" [Expression.binary wasm_mod Op.add_int32 select y] +let select = Expression.select wasm_mod (Expression.const wasm_mod (Literal.int32 1l)) (x ()) load + +let add = Expression.block wasm_mod ~return_type:Type.int32 "add" [Expression.binary wasm_mod Op.add_int32 select (y ())] (* Create the add function *) let adder = Function.add_function wasm_mod "adder" params results [||] add +let _ = Memory.set_memory wasm_mod 1 Memory.unlimited "memory" [] false + let _ = Module.print wasm_mod let byts, _ = Module.write wasm_mod None diff --git a/virtual/expression.mli b/virtual/expression.mli index 72220554..8f3d512c 100644 --- a/virtual/expression.mli +++ b/virtual/expression.mli @@ -28,7 +28,7 @@ val global_get : Module.t -> string -> Type.t -> t val global_set : Module.t -> string -> t -> t -val load : Module.t -> int -> int -> int -> Type.t -> t -> t +val load : Module.t -> int -> ?signed:bool -> int -> int -> Type.t -> t -> t val store : Module.t -> int -> int -> int -> t -> t -> Type.t -> t