Skip to content

Commit

Permalink
feat: Allow signed narrow-width loads (#62)
Browse files Browse the repository at this point in the history
  • Loading branch information
ospencer committed Jan 24, 2021
1 parent 2732de5 commit 6448aeb
Show file tree
Hide file tree
Showing 6 changed files with 31 additions and 16 deletions.
3 changes: 2 additions & 1 deletion js/expression.ml
Expand Up @@ -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;
Expand Down
11 changes: 6 additions & 5 deletions src/binaryen_stubs_expressions.c
Expand Up @@ -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
Expand Down
6 changes: 4 additions & 2 deletions src/expression.ml
Expand Up @@ -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"
Expand Down
12 changes: 10 additions & 2 deletions 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)
Expand All @@ -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)
Expand Down
13 changes: 8 additions & 5 deletions test/test.ml
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion virtual/expression.mli
Expand Up @@ -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

Expand Down

0 comments on commit 6448aeb

Please sign in to comment.