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

feat!: Support passive memory segments #158

Merged
merged 2 commits into from
Jun 12, 2022
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
101 changes: 101 additions & 0 deletions src/binaryen_stubs_expressions.c
Original file line number Diff line number Diff line change
Expand Up @@ -354,6 +354,27 @@ caml_binaryen_unreachable(value _module) {
CAMLreturn(alloc_BinaryenExpressionRef(exp));
}

CAMLprim value
caml_binaryen_memory_init(value _module, value _segment, value _dest, value _offset, value _size) {
CAMLparam5(_module, _segment, _dest, _offset, _size);
BinaryenModuleRef module = BinaryenModuleRef_val(_module);
uint32_t segment = Int_val(_segment);
BinaryenExpressionRef dest = BinaryenExpressionRef_val(_dest);
BinaryenExpressionRef offset = BinaryenExpressionRef_val(_offset);
BinaryenExpressionRef size = BinaryenExpressionRef_val(_size);
BinaryenExpressionRef exp = BinaryenMemoryInit(module, segment, dest, offset, size);
CAMLreturn(alloc_BinaryenExpressionRef(exp));
}

CAMLprim value
caml_binaryen_data_drop(value _module, value _segment) {
CAMLparam2(_module, _segment);
BinaryenModuleRef module = BinaryenModuleRef_val(_module);
uint32_t segment = Int_val(_segment);
BinaryenExpressionRef exp = BinaryenDataDrop(module, segment);
CAMLreturn(alloc_BinaryenExpressionRef(exp));
}

CAMLprim value
caml_binaryen_memory_copy(value _module, value _dest, value _source, value _size) {
CAMLparam4(_module, _dest, _source, _size);
Expand Down Expand Up @@ -1551,6 +1572,86 @@ caml_binaryen_return_set_value(value _exp, value _value) {
CAMLreturn(Val_unit);
}

CAMLprim value
caml_binaryen_memory_init_get_segment(value _exp) {
CAMLparam1(_exp);
BinaryenExpressionRef exp = BinaryenExpressionRef_val(_exp);
CAMLreturn(Val_int(BinaryenMemoryInitGetSegment(exp)));
}

CAMLprim value
caml_binaryen_memory_init_set_segment(value _exp, value _value) {
CAMLparam2(_exp, _value);
BinaryenExpressionRef exp = BinaryenExpressionRef_val(_exp);
uint32_t val = Int_val(_value);
BinaryenMemoryInitSetSegment(exp, val);
CAMLreturn(Val_unit);
}

CAMLprim value
caml_binaryen_memory_init_get_dest(value _exp) {
CAMLparam1(_exp);
BinaryenExpressionRef exp = BinaryenExpressionRef_val(_exp);
CAMLreturn(alloc_BinaryenExpressionRef(BinaryenMemoryInitGetDest(exp)));
}

CAMLprim value
caml_binaryen_memory_init_set_dest(value _exp, value _value) {
CAMLparam2(_exp, _value);
BinaryenExpressionRef exp = BinaryenExpressionRef_val(_exp);
BinaryenExpressionRef val = BinaryenExpressionRef_val(_value);
BinaryenMemoryInitSetDest(exp, val);
CAMLreturn(Val_unit);
}

CAMLprim value
caml_binaryen_memory_init_get_offset(value _exp) {
CAMLparam1(_exp);
BinaryenExpressionRef exp = BinaryenExpressionRef_val(_exp);
CAMLreturn(alloc_BinaryenExpressionRef(BinaryenMemoryInitGetOffset(exp)));
}

CAMLprim value
caml_binaryen_memory_init_set_offset(value _exp, value _value) {
CAMLparam2(_exp, _value);
BinaryenExpressionRef exp = BinaryenExpressionRef_val(_exp);
BinaryenExpressionRef val = BinaryenExpressionRef_val(_value);
BinaryenMemoryInitSetOffset(exp, val);
CAMLreturn(Val_unit);
}

CAMLprim value
caml_binaryen_memory_init_get_size(value _exp) {
CAMLparam1(_exp);
BinaryenExpressionRef exp = BinaryenExpressionRef_val(_exp);
CAMLreturn(alloc_BinaryenExpressionRef(BinaryenMemoryInitGetSize(exp)));
}

CAMLprim value
caml_binaryen_memory_init_set_size(value _exp, value _value) {
CAMLparam2(_exp, _value);
BinaryenExpressionRef exp = BinaryenExpressionRef_val(_exp);
BinaryenExpressionRef val = BinaryenExpressionRef_val(_value);
BinaryenMemoryInitSetSize(exp, val);
CAMLreturn(Val_unit);
}

CAMLprim value
caml_binaryen_data_drop_get_segment(value _exp) {
CAMLparam1(_exp);
BinaryenExpressionRef exp = BinaryenExpressionRef_val(_exp);
CAMLreturn(Val_int(BinaryenDataDropGetSegment(exp)));
}

CAMLprim value
caml_binaryen_data_drop_set_segment(value _exp, value _value) {
CAMLparam2(_exp, _value);
BinaryenExpressionRef exp = BinaryenExpressionRef_val(_exp);
uint32_t val = Int_val(_value);
BinaryenDataDropSetSegment(exp, val);
CAMLreturn(Val_unit);
}

CAMLprim value
caml_binaryen_memory_copy_get_dest(value _exp) {
CAMLparam1(_exp);
Expand Down
70 changes: 70 additions & 0 deletions src/binaryen_stubs_expressions.js
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,16 @@ function caml_binaryen_unreachable(wasm_mod) {
return wasm_mod.unreachable();
}

//Provides: caml_binaryen_memory_init
function caml_binaryen_memory_init(wasm_mod, segment, dest, offset, size) {
return wasm_mod.memory.init(segment, dest, offset, size);
}

//Provides: caml_binaryen_data_drop
function caml_binaryen_data_drop(wasm_mod, segment) {
return wasm_mod.data.drop(segment);
}

//Provides: caml_binaryen_memory_copy
function caml_binaryen_memory_copy(wasm_mod, dest, source, size) {
return wasm_mod.memory.copy(dest, source, size);
Expand Down Expand Up @@ -1284,6 +1294,66 @@ function caml_binaryen_return_set_value(exp, value) {
return binaryen.Return.setValue(exp, value);
}

//Provides: caml_binaryen_memory_init_get_segment
//Requires: binaryen
function caml_binaryen_memory_init_get_segment(exp) {
return binaryen.MemoryInit.getSegment(exp);
}

//Provides: caml_binaryen_memory_init_set_segment
//Requires: binaryen
function caml_binaryen_memory_init_set_segment(exp, value) {
return binaryen.MemoryInit.setSegment(exp, value);
}

//Provides: caml_binaryen_memory_init_get_dest
//Requires: binaryen
function caml_binaryen_memory_init_get_dest(exp) {
return binaryen.MemoryInit.getDest(exp);
}

//Provides: caml_binaryen_memory_init_set_dest
//Requires: binaryen
function caml_binaryen_memory_init_set_dest(exp, value) {
return binaryen.MemoryInit.setDest(exp, value);
}

//Provides: caml_binaryen_memory_init_get_offset
//Requires: binaryen
function caml_binaryen_memory_init_get_offset(exp) {
return binaryen.MemoryInit.getOffset(exp);
}

//Provides: caml_binaryen_memory_init_set_offset
//Requires: binaryen
function caml_binaryen_memory_init_set_offset(exp, value) {
return binaryen.MemoryInit.setOffset(exp, value);
}

//Provides: caml_binaryen_memory_init_get_size
//Requires: binaryen
function caml_binaryen_memory_init_get_size(exp) {
return binaryen.MemoryInit.getSize(exp);
}

//Provides: caml_binaryen_memory_init_set_size
//Requires: binaryen
function caml_binaryen_memory_init_set_size(exp, value) {
return binaryen.MemoryInit.setSize(exp, value);
}

//Provides: caml_binaryen_data_drop_get_segment
//Requires: binaryen
function caml_binaryen_data_drop_get_segment(exp) {
return binaryen.DataDrop.getSegment(exp);
}

//Provides: caml_binaryen_data_drop_set_segment
//Requires: binaryen
function caml_binaryen_data_drop_set_segment(exp, value) {
return binaryen.DataDrop.setSegment(exp, value);
}

//Provides: caml_binaryen_memory_copy_get_dest
//Requires: binaryen
function caml_binaryen_memory_copy_get_dest(exp) {
Expand Down
2 changes: 1 addition & 1 deletion src/binaryen_stubs_memory.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ function caml_binaryen_set_memory(wasm_mod, initial, maximum, exportName, segmen
var segs = caml_list_to_js_array(segments).map(function (segment, idx) {
return {
data: caml_convert_bytes_to_array(segment),
passive: segmentPassives[idx + 1], // OCaml Lists are offset by 1
passive: caml_js_from_bool(segmentPassives[idx + 1]), // OCaml Lists are offset by 1
offset: segmentOffsets[idx + 1] // OCaml Lists are offset by 1
}
});
Expand Down
27 changes: 27 additions & 0 deletions src/expression.ml
Original file line number Diff line number Diff line change
Expand Up @@ -707,6 +707,33 @@ module Memory_grow = struct
external set_delta : t -> t -> unit = "caml_binaryen_memory_grow_set_delta"
end

module Memory_init = struct
external make : Module.t -> int -> t -> t -> t = "caml_binaryen_memory_init"
(** Module, segment, destination, offset, size. *)

external get_segment : t -> int = "caml_binaryen_memory_init_get_segment"

external set_segment : t -> int -> unit
= "caml_binaryen_memory_init_set_segment"

external get_dest : t -> t = "caml_binaryen_memory_init_get_dest"
external set_dest : t -> t -> unit = "caml_binaryen_memory_init_set_dest"
external get_offset : t -> t = "caml_binaryen_memory_init_get_offset"
external set_offset : t -> t -> unit = "caml_binaryen_memory_init_set_offset"
external get_size : t -> t = "caml_binaryen_memory_init_get_size"
external set_size : t -> t -> unit = "caml_binaryen_memory_init_set_size"
end

module Data_drop = struct
external make : Module.t -> int -> t = "caml_binaryen_data_drop"
(** Module, segment. *)

external get_segment : t -> int = "caml_binaryen_data_drop_get_segment"

external set_segment : t -> int -> unit
= "caml_binaryen_data_drop_set_segment"
end

module Memory_copy = struct
external make : Module.t -> t -> t -> t -> t = "caml_binaryen_memory_copy"
(** Module, destination, source, size. *)
Expand Down
18 changes: 18 additions & 0 deletions src/expression.mli
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,24 @@ module Memory_grow : sig
val set_delta : t -> t -> unit
end

module Memory_init : sig
val make : Module.t -> int -> t -> t -> t
val get_segment : t -> int
val set_segment : t -> int -> unit
val get_dest : t -> t
val set_dest : t -> t -> unit
val get_offset : t -> t
val set_offset : t -> t -> unit
val get_size : t -> t
val set_size : t -> t -> unit
end

module Data_drop : sig
val make : Module.t -> int -> t
val get_segment : t -> int
val set_segment : t -> int -> unit
end

module Memory_copy : sig
val make : Module.t -> t -> t -> t -> t
val get_dest : t -> t
Expand Down
27 changes: 15 additions & 12 deletions src/memory.ml
Original file line number Diff line number Diff line change
Expand Up @@ -3,31 +3,34 @@ external set_memory :
int ->
int ->
string ->
string list ->
bytes list ->
bool list ->
Expression.t list ->
int list ->
bool ->
unit = "caml_binaryen_set_memory__bytecode" "caml_binaryen_set_memory"

type segment = {
data : string;
passive : bool;
offset : Expression.t;
size : int;
}
type segment = { data : bytes; kind : segment_kind; size : int }
and segment_kind = Passive | Active of { offset : Expression.t }

(** Module, initial size, maximum size, export name, segments, shared. *)
let set_memory wasm_mod initial maximum export_name (segments : segment list)
shared =
let split_segments segments =
List.fold_right
(fun { data; passive; offset; size }
(fun { data; kind; size }
(segment_data, segment_passive, segment_offsets, segment_sizes) ->
( data :: segment_data,
passive :: segment_passive,
offset :: segment_offsets,
size :: segment_sizes ))
match kind with
| Active { offset } ->
( data :: segment_data,
false :: segment_passive,
offset :: segment_offsets,
size :: segment_sizes )
| Passive ->
( data :: segment_data,
true :: segment_passive,
Expression.Null.make () :: segment_offsets,
size :: segment_sizes ))
segments ([], [], [], [])
in
let segment_data, segment_passive, segment_offsets, segment_sizes =
Expand Down
8 changes: 2 additions & 6 deletions src/memory.mli
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
type segment = {
data : string;
passive : bool;
offset : Expression.t;
size : int;
}
type segment = { data : bytes; kind : segment_kind; size : int }
and segment_kind = Passive | Active of { offset : Expression.t }

val set_memory :
Module.t -> int -> int -> string -> segment list -> bool -> unit
Expand Down
1 change: 1 addition & 0 deletions test/test.expected
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
(global $test_float64_bits f64 (f64.const 1.23))
(memory $0 1)
(data (i32.const 0) "hello")
(data "world")
(table $table 1 1 funcref)
(elem $elem (i32.const 0) $adder)
(export "adder" (func $adder))
Expand Down
23 changes: 17 additions & 6 deletions test/test.ml
Original file line number Diff line number Diff line change
Expand Up @@ -123,13 +123,24 @@ let _ =
let _ = Function.set_start wasm_mod start

let segment : Binaryen.Memory.segment =
let data = "hello" in
let passive = false in
let offset = Expression.Const.make wasm_mod (Literal.int32 0l) in
let size = String.length data in
{ data; passive; offset; size }
let data = Bytes.of_string "hello" in
let kind =
Binaryen.Memory.Active
{ offset = Expression.Const.make wasm_mod (Literal.int32 0l) }
in
let size = Bytes.length data in
{ data; kind; size }

let passive_segment : Binaryen.Memory.segment =
let data = Bytes.of_string "world" in
let kind = Binaryen.Memory.Passive in
let size = Bytes.length data in
{ data; kind; size }

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

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