From c2a8008e144bb7f1326ee907b29830f050d830f3 Mon Sep 17 00:00:00 2001 From: Spotandjake Date: Mon, 6 Apr 2026 17:27:20 -0400 Subject: [PATCH] feat!: Upgrade to Binaryen v129 Full Diff: https://github.com/WebAssembly/binaryen/compare/version_128...version_129 API Additions: * Data_segment * Data_segment.get_num_segments * Data_segment.get_segment * Data_segment.get_segment_by_index * Data_segment.get_segment_name * Data_segment.get_segment_byte_offset * Data_segment.get_segment_byte_length * Data_segment.get_segment_passive * Data_segment.get_segment_data * Module.Feature.multibyte API Changes: * Table.add_table -> Now takes an optional `init` expression API Removals: * Memory.get_num_segments -> became Data_segment.get_num_segments * Memory.get_segment_byte_offset -> became Data_segment.get_segment_byte_offset * Memory.get_segment_passive -> became Data_segment.get_segment_passive * Memory.get_segment_data -> became Data_segment.get_segment_data NOTE: This needs the prs for v126, v127 & v128 merged first. This is blocked on libbinaryen v129 releasing --- binaryen.opam | 2 +- esy.lock/index.json | 12 +++---- package.json | 4 +-- src/data_segment.c | 81 +++++++++++++++++++++++++++++++++++++++++++ src/data_segment.js | 49 ++++++++++++++++++++++++++ src/data_segment.ml | 25 +++++++++++++ src/data_segment.mli | 10 ++++++ src/dune | 2 ++ src/memory.c | 41 +--------------------- src/memory.js | 28 +-------------- src/memory.ml | 12 ------- src/memory.mli | 4 --- src/module.c | 10 ++++++ src/module.js | 8 +++++ src/module.ml | 11 ++++++ src/module.mli | 2 ++ src/module_feature.c | 6 ++++ src/module_feature.js | 6 ++++ src/ocaml_helpers.c | 8 +++++ src/ocaml_helpers.h | 4 +++ src/table.c | 15 ++++++-- src/table.js | 18 ++++++++-- src/table.ml | 5 +-- src/table.mli | 3 +- test/test.ml | 43 ++++++++++++++++++++--- 25 files changed, 305 insertions(+), 104 deletions(-) create mode 100644 src/data_segment.c create mode 100644 src/data_segment.js create mode 100644 src/data_segment.ml create mode 100644 src/data_segment.mli diff --git a/binaryen.opam b/binaryen.opam index 7a17c899..e91b4a88 100644 --- a/binaryen.opam +++ b/binaryen.opam @@ -16,6 +16,6 @@ depends: [ "dune" {>= "3.0.0"} "dune-configurator" {>= "3.0.0"} "js_of_ocaml-compiler" {>= "6.4.0" < "7.0.0"} - "libbinaryen" {>= "128.0.0" < "129.0.0"} + "libbinaryen" {>= "129.0.0" < "130.0.0"} ] x-maintenance-intent: ["0.(latest)"] diff --git a/esy.lock/index.json b/esy.lock/index.json index 5bb4b8ae..fb2ae0bc 100644 --- a/esy.lock/index.json +++ b/esy.lock/index.json @@ -1,5 +1,5 @@ { - "checksum": "e0ac1b977a50c857edf45c8c6b5c6a02", + "checksum": "20ec2a11257be87e1aa8fef3d188392e", "root": "@grain/binaryen.ml@link-dev:./package.json", "node": { "ocaml@5.3.0@d41d8cd9": { @@ -1934,14 +1934,14 @@ [ "windows", "x86_64" ] ] }, - "@grain/libbinaryen@128.0.0@d41d8cd9": { - "id": "@grain/libbinaryen@128.0.0@d41d8cd9", + "@grain/libbinaryen@129.0.0@d41d8cd9": { + "id": "@grain/libbinaryen@129.0.0@d41d8cd9", "name": "@grain/libbinaryen", - "version": "128.0.0", + "version": "129.0.0", "source": { "type": "install", "source": [ - "archive:https://registry.npmjs.org/@grain/libbinaryen/-/libbinaryen-128.0.0.tgz#sha1:d2e540a3177f9f6f0f27e6125efdffa5bf670814" + "archive:https://registry.npmjs.org/@grain/libbinaryen/-/libbinaryen-129.0.0.tgz#sha1:6d927815b071a528ee314ad02c3279d86428aec6" ] }, "overrides": [], @@ -1974,7 +1974,7 @@ "ocaml@5.3.0@d41d8cd9", "@opam/dune-configurator@opam:3.24.2@7928eaef", "@opam/dune@opam:3.24.2@dc9091c2", - "@grain/libbinaryen@128.0.0@d41d8cd9" + "@grain/libbinaryen@129.0.0@d41d8cd9" ], "devDependencies": [ "@opam/ocamlformat@opam:0.29.0@966c16ee", diff --git a/package.json b/package.json index 16e6219b..970eab25 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,7 @@ }, "dependencies": { "ocaml": ">= 4.14.0 < 6.0.0", - "@grain/libbinaryen": ">= 128.0.0 < 129.0.0", + "@grain/libbinaryen": ">= 129.0.0 < 130.0.0", "@opam/dune": ">= 3.0.0", "@opam/dune-configurator": ">= 3.0.0" }, @@ -40,4 +40,4 @@ "binaryen", "ocaml" ] -} +} \ No newline at end of file diff --git a/src/data_segment.c b/src/data_segment.c new file mode 100644 index 00000000..825ea931 --- /dev/null +++ b/src/data_segment.c @@ -0,0 +1,81 @@ +#define CAML_NAME_SPACE +#include +#include +#include +#include + +#include "binaryen-c.h" +#include "ocaml_helpers.h" + + +CAMLprim value +caml_binaryen_get_num_memory_segments(value _module) { + CAMLparam1(_module); + BinaryenModuleRef module = BinaryenModuleRef_val(_module); + CAMLreturn(Val_int(BinaryenGetNumMemorySegments(module))); +} + +CAMLprim value caml_binaryen_get_data_segment(value _module, value _name) { + CAMLparam2(_module, _name); + BinaryenModuleRef module = BinaryenModuleRef_val(_module); + char* name = Safe_String_val(_name); + BinaryenDataSegmentRef segment = BinaryenGetDataSegment(module, name); + if (segment == NULL) { + CAMLreturn(Val_none); + } else { + CAMLreturn(caml_alloc_some(alloc_BinaryenDataSegmentRef(segment))); + } +} + +CAMLprim value caml_binaryen_get_data_segment_by_index(value _module, value _index) { + CAMLparam2(_module, _index); + BinaryenModuleRef module = BinaryenModuleRef_val(_module); + int index = Int_val(_index); + BinaryenDataSegmentRef segment = BinaryenGetDataSegmentByIndex(module, index); + CAMLreturn(alloc_BinaryenDataSegmentRef(segment)); +} + +CAMLprim value caml_binaryen_data_segment_get_name(value _module, value _segment) { + CAMLparam2(_module, _segment); + BinaryenDataSegmentRef segment = BinaryenDataSegmentRef_val(_segment); + const char* name = BinaryenDataSegmentGetName(segment); + CAMLreturn(caml_copy_string(name)); +} + +CAMLprim value +caml_binaryen_get_memory_segment_byte_offset(value _module, value _segment) { + CAMLparam2(_module, _segment); + BinaryenModuleRef module = BinaryenModuleRef_val(_module); + BinaryenDataSegmentRef segment = BinaryenDataSegmentRef_val(_segment); + if (BinaryenGetMemorySegmentPassive(segment)) { + CAMLreturn(Val_none); + } else { + int offset = BinaryenGetMemorySegmentByteOffset(module, segment); + CAMLreturn(caml_alloc_some(Val_int(offset))); + } +} + +CAMLprim value +caml_binaryen_get_memory_segment_byte_length(value _segment) { + CAMLparam1(_segment); + BinaryenDataSegmentRef segment = BinaryenDataSegmentRef_val(_segment); + int length = BinaryenGetMemorySegmentByteLength(segment); + CAMLreturn(Val_int(length)); +} + +CAMLprim value +caml_binaryen_get_memory_segment_passive(value _segment) { + CAMLparam1(_segment); + BinaryenDataSegmentRef segment = BinaryenDataSegmentRef_val(_segment); + CAMLreturn(Val_bool(BinaryenGetMemorySegmentPassive(segment))); +} + +CAMLprim value +caml_binaryen_get_memory_segment_data(value _module, value _segment) { + CAMLparam2(_module, _segment); + BinaryenDataSegmentRef segment = BinaryenDataSegmentRef_val(_segment); + size_t size = BinaryenGetMemorySegmentByteLength(segment); + CAMLprim value bytes = caml_alloc_string(size); + BinaryenCopyMemorySegmentData(segment, (char*)Bytes_val(bytes)); + CAMLreturn(bytes); +} diff --git a/src/data_segment.js b/src/data_segment.js new file mode 100644 index 00000000..dd0297a3 --- /dev/null +++ b/src/data_segment.js @@ -0,0 +1,49 @@ + +//Provides: caml_binaryen_get_num_memory_segments +function caml_binaryen_get_num_memory_segments(wasm_mod) { + return wasm_mod.getNumMemorySegments(); +} + +//Provides: caml_binaryen_get_data_segment +//Requires: caml_jsstring_of_string, to_option +function caml_binaryen_get_data_segment(wasm_mod, name) { + return to_option(wasm_mod.getDataSegment(caml_jsstring_of_string(name))); +} + +//Provides: caml_binaryen_get_data_segment_by_index +function caml_binaryen_get_data_segment_by_index(wasm_mod, index) { + return wasm_mod.getDataSegmentByIndex(index); +} + +// Provides: caml_binaryen_data_segment_get_name +// Requires: caml_string_of_jsstring +function caml_binaryen_data_segment_get_name(wasm_mod, segment) { + var info = wasm_mod.getMemorySegmentInfo(segment); + return caml_string_of_jsstring(info.name); +} + +//Provides: caml_binaryen_get_memory_segment_byte_offset +//Requires: to_option +function caml_binaryen_get_memory_segment_byte_offset(wasm_mod, segment) { + var info = wasm_mod.getMemorySegmentInfo(segment); + return to_option(info.offset); +} + +//Provides: caml_binaryen_get_memory_segment_byte_length +//Requires: Binaryen +function caml_binaryen_get_memory_segment_byte_length(segment) { + return Binaryen._BinaryenGetMemorySegmentByteLength(segment); +} + +//Provides: caml_binaryen_get_memory_segment_passive +//Requires: Binaryen +function caml_binaryen_get_memory_segment_passive(segment) { + return Binaryen._BinaryenGetMemorySegmentPassive(segment); +} + +//Provides: caml_binaryen_get_memory_segment_data +//Requires: caml_bytes_of_array +function caml_binaryen_get_memory_segment_data(wasm_mod, segment) { + var info = wasm_mod.getMemorySegmentInfo(segment); + return caml_bytes_of_array(info.data); +} diff --git a/src/data_segment.ml b/src/data_segment.ml new file mode 100644 index 00000000..f064e54e --- /dev/null +++ b/src/data_segment.ml @@ -0,0 +1,25 @@ +type t + +external get_num_segments : Module.t -> int + = "caml_binaryen_get_num_memory_segments" + +external get_segment : Module.t -> string -> t option + = "caml_binaryen_get_data_segment" + +external get_segment_by_index : Module.t -> int -> t + = "caml_binaryen_get_data_segment_by_index" + +external get_segment_name : Module.t -> t -> string + = "caml_binaryen_data_segment_get_name" + +external get_segment_byte_offset : Module.t -> t -> int option + = "caml_binaryen_get_memory_segment_byte_offset" + +external get_segment_byte_length : t -> int + = "caml_binaryen_get_memory_segment_byte_length" + +external get_segment_passive : t -> bool + = "caml_binaryen_get_memory_segment_passive" + +external get_segment_data : Module.t -> t -> bytes + = "caml_binaryen_get_memory_segment_data" diff --git a/src/data_segment.mli b/src/data_segment.mli new file mode 100644 index 00000000..7e536604 --- /dev/null +++ b/src/data_segment.mli @@ -0,0 +1,10 @@ +type t + +val get_num_segments : Module.t -> int +val get_segment : Module.t -> string -> t option +val get_segment_by_index : Module.t -> int -> t +val get_segment_name : Module.t -> t -> string +val get_segment_byte_offset : Module.t -> t -> int option +val get_segment_byte_length : t -> int +val get_segment_passive : t -> bool +val get_segment_data : Module.t -> t -> bytes diff --git a/src/dune b/src/dune index 1815587e..653e2e9a 100644 --- a/src/dune +++ b/src/dune @@ -6,6 +6,7 @@ (language c) (names array_type + data_segment type op literal @@ -30,6 +31,7 @@ (js_of_ocaml (javascript_files array_type.js + data_segment.js type.js op.js literal.js diff --git a/src/memory.c b/src/memory.c index 0feeeabc..74951ff7 100644 --- a/src/memory.c +++ b/src/memory.c @@ -107,43 +107,4 @@ caml_binaryen_memory_is_64(value _module, value _memoryName) { BinaryenModuleRef module = BinaryenModuleRef_val(_module); char* memoryName = Safe_String_val(_memoryName); CAMLreturn(Val_bool(BinaryenMemoryIs64(module, memoryName))); -} - -CAMLprim value -caml_binaryen_get_num_memory_segments(value _module) { - CAMLparam1(_module); - BinaryenModuleRef module = BinaryenModuleRef_val(_module); - CAMLreturn(Val_int(BinaryenGetNumMemorySegments(module))); -} - -CAMLprim value -caml_binaryen_get_memory_segment_byte_offset(value _module, value _name) { - CAMLparam2(_module, _name); - BinaryenModuleRef module = BinaryenModuleRef_val(_module); - char* name = Safe_String_val(_name); - if (BinaryenGetMemorySegmentPassive(module, name)) { - CAMLreturn(Val_none); - } else { - int offset = BinaryenGetMemorySegmentByteOffset(module, name); - CAMLreturn(caml_alloc_some(Val_int(offset))); - } -} - -CAMLprim value -caml_binaryen_get_memory_segment_passive(value _module, value _name) { - CAMLparam2(_module, _name); - BinaryenModuleRef module = BinaryenModuleRef_val(_module); - char* name = Safe_String_val(_name); - CAMLreturn(Val_bool(BinaryenGetMemorySegmentPassive(module, name))); -} - -CAMLprim value -caml_binaryen_get_memory_segment_data(value _module, value _name) { - CAMLparam2(_module, _name); - BinaryenModuleRef module = BinaryenModuleRef_val(_module); - char* name = Safe_String_val(_name); - size_t size = BinaryenGetMemorySegmentByteLength(module, name); - CAMLprim value bytes = caml_alloc_string(size); - BinaryenCopyMemorySegmentData(module, name, (char*)Bytes_val(bytes)); - CAMLreturn(bytes); -} +} \ No newline at end of file diff --git a/src/memory.js b/src/memory.js index 006a9680..ebf8d189 100644 --- a/src/memory.js +++ b/src/memory.js @@ -104,30 +104,4 @@ function caml_binaryen_memory_is_shared(mod, memoryName) { function caml_binaryen_memory_is_64(mod, memoryName) { var memory_info = mod.getMemoryInfo(caml_jsstring_of_string(memoryName)); return caml_js_to_bool(memory_info.is64); -} - -//Provides: caml_binaryen_get_num_memory_segments -function caml_binaryen_get_num_memory_segments(wasm_mod) { - return wasm_mod.getNumMemorySegments(); -} - -//Provides: caml_binaryen_get_memory_segment_byte_offset -//Requires: caml_jsstring_of_string, to_option -function caml_binaryen_get_memory_segment_byte_offset(wasm_mod, name) { - var info = wasm_mod.getMemorySegmentInfo(caml_jsstring_of_string(name)); - return to_option(info.offset); -} - -//Provides: caml_binaryen_get_memory_segment_passive -//Requires: caml_jsstring_of_string -function caml_binaryen_get_memory_segment_passive(wasm_mod, name) { - var info = wasm_mod.getMemorySegmentInfo(caml_jsstring_of_string(name)); - return info.passive; -} - -//Provides: caml_binaryen_get_memory_segment_data -//Requires: caml_bytes_of_array, caml_jsstring_of_string -function caml_binaryen_get_memory_segment_data(wasm_mod, name) { - var info = wasm_mod.getMemorySegmentInfo(caml_jsstring_of_string(name)); - return caml_bytes_of_array(info.data); -} +} \ No newline at end of file diff --git a/src/memory.ml b/src/memory.ml index 5e00286b..a106ab69 100644 --- a/src/memory.ml +++ b/src/memory.ml @@ -67,15 +67,3 @@ external is_shared : Module.t -> string -> bool external is_64 : Module.t -> string -> bool = "caml_binaryen_memory_is_64" let unlimited = -1 - -external get_num_segments : Module.t -> int - = "caml_binaryen_get_num_memory_segments" - -external get_segment_byte_offset : Module.t -> string -> int option - = "caml_binaryen_get_memory_segment_byte_offset" - -external get_segment_passive : Module.t -> string -> bool - = "caml_binaryen_get_memory_segment_passive" - -external get_segment_data : Module.t -> string -> bytes - = "caml_binaryen_get_memory_segment_data" diff --git a/src/memory.mli b/src/memory.mli index 1c99ecc1..1a5ae1c1 100644 --- a/src/memory.mli +++ b/src/memory.mli @@ -19,7 +19,3 @@ val get_max : Module.t -> string -> int val is_shared : Module.t -> string -> bool val is_64 : Module.t -> string -> bool val unlimited : int -val get_num_segments : Module.t -> int -val get_segment_byte_offset : Module.t -> string -> int option -val get_segment_passive : Module.t -> string -> bool -val get_segment_data : Module.t -> string -> bytes diff --git a/src/module.c b/src/module.c index 285419f6..9ccc0080 100644 --- a/src/module.c +++ b/src/module.c @@ -137,6 +137,16 @@ caml_binaryen_module_read(value _bytes) { CAMLreturn(alloc_BinaryenModuleRef(result)); } +CAMLprim value +caml_binaryen_module_read_with_features(value _bytes, value _features) { + CAMLparam2(_bytes, _features); + char* bytes = Safe_String_val(_bytes); + int length = caml_string_length(_bytes); + BinaryenFeatures features = Int_val(_features); + BinaryenModuleRef result = BinaryenModuleReadWithFeatures(bytes, length, features); + CAMLreturn(alloc_BinaryenModuleRef(result)); +} + CAMLprim value caml_binaryen_module_interpret(value _module) { CAMLparam1(_module); diff --git a/src/module.js b/src/module.js index 90d10690..8de9ce30 100644 --- a/src/module.js +++ b/src/module.js @@ -93,6 +93,14 @@ function caml_binaryen_module_read(bytes) { return Binaryen.readBinary(data); } +//Provides: caml_binaryen_module_read_with_features +//Requires: Binaryen +//Requires: caml_uint8_array_of_bytes +function caml_binaryen_module_read_with_features(bytes, features) { + var data = caml_uint8_array_of_bytes(bytes); + return Binaryen.readBinaryWithFeatures(data, features); +} + //Provides: caml_binaryen_module_interpret function caml_binaryen_module_interpret(wasm_mod) { return wasm_mod.interpret(); diff --git a/src/module.ml b/src/module.ml index 534633a6..2ecebfd4 100644 --- a/src/module.ml +++ b/src/module.ml @@ -102,6 +102,10 @@ module Feature = struct let relaxed_atomics = relaxed_atomics () + external multibyte : unit -> t = "caml_binaryen_feature_multibyte" + + let multibyte = multibyte () + external custom_page_sizes : unit -> t = "caml_binaryen_feature_custom_page_sizes" @@ -152,6 +156,13 @@ external write : t -> string option -> bytes * string option external write_text : t -> string = "caml_binaryen_module_write_text" external write_stack_ir : t -> string = "caml_binaryen_module_write_stack_ir" external read : bytes -> t = "caml_binaryen_module_read" + +external read_with_features : bytes -> int -> t + = "caml_binaryen_module_read_with_features" + +let read_with_features buf features = + read_with_features buf (List.fold_left ( lor ) 0 features) + external interpret : t -> unit = "caml_binaryen_module_interpret" external add_debug_info_filename : t -> string -> int diff --git a/src/module.mli b/src/module.mli index a5e76a61..c3b0dca8 100644 --- a/src/module.mli +++ b/src/module.mli @@ -26,6 +26,7 @@ module Feature : sig val bulk_memory_opt : t val call_indirect_overlong : t val relaxed_atomics : t + val multibyte : t val custom_page_sizes : t val all : t end @@ -46,6 +47,7 @@ val write : t -> string option -> bytes * string option val write_text : t -> string val write_stack_ir : t -> string val read : bytes -> t +val read_with_features : bytes -> Feature.t list -> t val interpret : t -> unit val add_debug_info_filename : t -> string -> int val get_debug_info_filename : t -> int -> string diff --git a/src/module_feature.c b/src/module_feature.c index d484bf0e..07d3662b 100644 --- a/src/module_feature.c +++ b/src/module_feature.c @@ -161,6 +161,12 @@ caml_binaryen_feature_relaxed_atomics(value unit) { CAMLreturn(Val_int(BinaryenFeatureRelaxedAtomics())); } +CAMLprim value +caml_binaryen_feature_multibyte(value unit) { + CAMLparam1(unit); + CAMLreturn(Val_int(BinaryenFeatureMultibyte())); +} + CAMLprim value caml_binaryen_feature_custom_page_sizes(value unit) { CAMLparam1(unit); diff --git a/src/module_feature.js b/src/module_feature.js index e8af8909..f6ac7854 100644 --- a/src/module_feature.js +++ b/src/module_feature.js @@ -146,6 +146,12 @@ function caml_binaryen_feature_relaxed_atomics() { return Binaryen.Features.RelaxedAtomics; } +//Provides: caml_binaryen_feature_multibyte +//Requires: Binaryen +function caml_binaryen_feature_multibyte() { + return Binaryen._BinaryenFeatureMultibyte; +} + //Provides: caml_binaryen_feature_custom_page_sizes //Requires: Binaryen function caml_binaryen_feature_custom_page_sizes() { diff --git a/src/ocaml_helpers.c b/src/ocaml_helpers.c index be2568dc..c49432f2 100644 --- a/src/ocaml_helpers.c +++ b/src/ocaml_helpers.c @@ -111,6 +111,14 @@ value alloc_TypeBuilderRef(TypeBuilderRef builder) return v; } +/* Allocating an OCaml custom block to hold the given BinaryenDataSegmentRef */ +value alloc_BinaryenDataSegmentRef(BinaryenDataSegmentRef seg) +{ + value v = caml_alloc_custom(&binaryen_ops, sizeof(BinaryenDataSegmentRef), 0, 1); + BinaryenDataSegmentRef_val(v) = seg; + return v; +} + CAMLprim value array_of_list(value list) { CAMLparam1(list); diff --git a/src/ocaml_helpers.h b/src/ocaml_helpers.h index 5c32738c..c8236cb6 100644 --- a/src/ocaml_helpers.h +++ b/src/ocaml_helpers.h @@ -35,6 +35,7 @@ static struct custom_operations binaryen_ops = { #define BinaryenTableRef_val(v) (*((BinaryenTableRef*) Data_custom_val(v))) #define BinaryenElementSegmentRef_val(v) (*((BinaryenElementSegmentRef*) Data_custom_val(v))) #define TypeBuilderRef_val(v) (*((TypeBuilderRef*) Data_custom_val(v))) +#define BinaryenDataSegmentRef_val(v) (*((BinaryenDataSegmentRef*) Data_custom_val(v))) #define Val_none Val_int(0) #define Some_val(v) Field(v, 0) @@ -83,6 +84,9 @@ value alloc_BinaryenElementSegmentRef(BinaryenElementSegmentRef elem); /* Allocating an OCaml custom block to hold the given TypeBuilderRef */ value alloc_TypeBuilderRef(TypeBuilderRef builder); +/* Allocating an OCaml custom block to hold the given BinaryenDataSegmentRef */ +value alloc_BinaryenDataSegmentRef(BinaryenDataSegmentRef seg); + CAMLprim value array_of_list(value list); diff --git a/src/table.c b/src/table.c index 1d7b095b..07ba05ad 100644 --- a/src/table.c +++ b/src/table.c @@ -8,14 +8,25 @@ #include "ocaml_helpers.h" CAMLprim value -caml_binaryen_add_table(value _module, value _table, value _initial, value _maximum, value _tableType) { +caml_binaryen_add_table(value _module, value _table, value _initial, value _maximum, value _tableType, value _init) { CAMLparam5(_module, _table, _initial, _maximum, _tableType); + CAMLxparam1(_init); BinaryenModuleRef module = BinaryenModuleRef_val(_module); char* table = Safe_String_val(_table); BinaryenIndex initial = Int_val(_initial); BinaryenIndex maximum = Int_val(_maximum); BinaryenType tableType = BinaryenType_val(_tableType); - CAMLreturn(alloc_BinaryenTableRef(BinaryenAddTable(module, table, initial, maximum, tableType))); + BinaryenExpressionRef init; + if (Is_none(_init)) { + init = NULL; + } else { + init = BinaryenExpressionRef_val(Some_val(_init)); + } + CAMLreturn(alloc_BinaryenTableRef(BinaryenAddTable(module, table, initial, maximum, tableType, init))); +} +CAMLprim value +caml_binaryen_add_table__bytecode(value * argv) { + return caml_binaryen_add_table(argv[0], argv[1], argv[2], argv[3], argv[4], argv[5]); } CAMLprim value diff --git a/src/table.js b/src/table.js index 80835c4e..8f80256a 100644 --- a/src/table.js +++ b/src/table.js @@ -1,14 +1,26 @@ //Provides: caml_binaryen_add_table //Requires: caml_jsstring_of_string -function caml_binaryen_add_table(wasm_mod, table, initial, maximum, tableType) { +function caml_binaryen_add_table(wasm_mod, table, initial, maximum, tableType, init) { return wasm_mod.addTable( caml_jsstring_of_string(table), initial, maximum, - tableType + tableType, + init ? init : null + ); +} +//Provides: caml_binaryen_add_table__bytecode +//Requires: caml_binaryen_add_table +function caml_binaryen_add_table__bytecode() { + return caml_binaryen_add_table( + arguments[0], + arguments[1], + arguments[2], + arguments[3], + arguments[4], + arguments[5] ); } - //Provides: caml_binaryen_add_active_element_segment //Requires: caml_jsstring_of_string, caml_list_to_js_array function caml_binaryen_add_active_element_segment( diff --git a/src/table.ml b/src/table.ml index 53109636..b7d83ed5 100644 --- a/src/table.ml +++ b/src/table.ml @@ -1,7 +1,8 @@ type t -external add_table : Module.t -> string -> int -> int -> Type.t -> t - = "caml_binaryen_add_table" +external add_table : + Module.t -> string -> int -> int -> Type.t -> Expression.t option -> t + = "caml_binaryen_add_table__bytecode" "caml_binaryen_add_table" (** Module, name, initial size, maximum size, table type *) external add_active_element_segment : diff --git a/src/table.mli b/src/table.mli index ad3a4a8d..a086abe3 100644 --- a/src/table.mli +++ b/src/table.mli @@ -1,6 +1,7 @@ type t -val add_table : Module.t -> string -> int -> int -> Type.t -> t +val add_table : + Module.t -> string -> int -> int -> Type.t -> Expression.t option -> t val add_active_element_segment : Module.t -> diff --git a/test/test.ml b/test/test.ml index cad22181..2f3f1cb2 100644 --- a/test/test.ml +++ b/test/test.ml @@ -169,7 +169,7 @@ let start = ]) let _ = Export.add_function_export wasm_mod "adder" "adder" -let _ = Table.add_table wasm_mod "table" 1 1 Type.funcref +let _ = Table.add_table wasm_mod "table" 1 1 Type.funcref None let adder_type = let builder = Type_builder.make 1 in @@ -254,13 +254,43 @@ let _ = Memory.set_memory max_memory_wasm_mod 1 2 "memory" [] false false "0" let _ = assert (Memory.has_max max_memory_wasm_mod "0" = true) let _ = assert (Memory.get_max max_memory_wasm_mod "0" = 2) -(* Memory.get_segment_byte_offset Passive *) -let _ = assert (Memory.get_segment_byte_offset wasm_mod "world" = None) +(* Data_segment.get_num_segments *) +let _ = assert (Data_segment.get_num_segments wasm_mod = 2) +(* Data_segment.get_segment *) +let segment_hello = Data_segment.get_segment wasm_mod "hello" +let segment_world = Data_segment.get_segment wasm_mod "world" +let _ = assert (segment_hello <> None) +let _ = assert (segment_world <> None) +let _ = assert (Data_segment.get_segment wasm_mod "nonexistent" = None) +let segment_hello = Option.get segment_hello +let segment_world = Option.get segment_world + +(* Data_segment.get_segment_by_index *) +let _ = + assert ( + Data_segment.get_segment_name wasm_mod + (Data_segment.get_segment_by_index wasm_mod 0) + = "hello") + +(* Data_segment.get_segment_name *) +let _ = assert (Data_segment.get_segment_name wasm_mod segment_hello = "hello") + +(* Data_segment.get_segment_byte_offset *) +let _ = + assert (Data_segment.get_segment_byte_offset wasm_mod segment_world = None) + +(* Data_segment.get_segment_byte_length *) +let _ = assert (Data_segment.get_segment_byte_length segment_hello = 5) + +(* Data_segment.get_segment_passive *) +let _ = assert (Data_segment.get_segment_passive segment_hello = false) + +(* Data_segment.get_segment_data *) let _ = assert ( Bytes.equal - (Memory.get_segment_data wasm_mod "world") + (Data_segment.get_segment_data wasm_mod segment_world) (Bytes.of_string "world")) (* Call_ref *) @@ -518,6 +548,9 @@ let _ = let new_mod = Module.read byts +let new_mod_with_features = + Module.read_with_features byts [ Module.Feature.all ] + let _ = Module.run_passes new_mod [ @@ -567,8 +600,10 @@ let _ = let _ = assert (Module.validate new_mod == 1) let _ = Module.print new_mod let _ = Module.print_stack_ir new_mod +let _ = Module.validate new_mod_with_features (* Dispose the modules 👋 *) let _ = Module.dispose wasm_mod let _ = Module.dispose new_mod +let _ = Module.dispose new_mod_with_features