From f39c456c819c8304bdb955ff7d26cf3a6fc3cf22 Mon Sep 17 00:00:00 2001 From: Spotandjake <40705786+spotandjake@users.noreply.github.com> Date: Wed, 10 Dec 2025 17:30:48 -0500 Subject: [PATCH 1/7] chore: Use js api over `_Binaryen` api for types (#262) This just fixes some small todo's by using the js api where possible --- src/type.js | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/src/type.js b/src/type.js index 23350368..2b258218 100644 --- a/src/type.js +++ b/src/type.js @@ -67,7 +67,7 @@ function caml_binaryen_type_structref() { //Provides: caml_binaryen_type_arrayref //Requires: Binaryen function caml_binaryen_type_arrayref() { - // TODO: Binaryen v111 didn't expose this directly + // TODO: Binaryen v125 doesn't expose this directly return Binaryen._BinaryenTypeArrayref(); } @@ -80,22 +80,19 @@ function caml_binaryen_type_stringref() { //Provides: caml_binaryen_type_nullref //Requires: Binaryen function caml_binaryen_type_nullref() { - // TODO: Binaryen v111 didn't expose this directly - return Binaryen._BinaryenTypeNullref(); + return Binaryen.nullref; } //Provides: caml_binaryen_type_null_externref //Requires: Binaryen function caml_binaryen_type_null_externref() { - // TODO: Binaryen v111 didn't expose this directly - return Binaryen._BinaryenTypeNullExternref(); + return Binaryen.nullexternref; } //Provides: caml_binaryen_type_null_funcref //Requires: Binaryen function caml_binaryen_type_null_funcref() { - // TODO: Binaryen v111 didn't expose this directly - return Binaryen._BinaryenTypeNullFuncref(); + return Binaryen.nullfuncref; } //Provides: caml_binaryen_type_unreachable From 229214bbac9ca53c7eacfda935584ad35da91b6a Mon Sep 17 00:00:00 2001 From: Oscar Spencer Date: Sun, 16 Feb 2025 21:57:29 -0600 Subject: [PATCH 2/7] feat!: Implement GC instructions --- src/dune | 2 + src/expression.c | 268 +++++++++++++++++++++++++++++++++++++++++++ src/expression.js | 194 +++++++++++++++++++++++++++++++ src/expression.ml | 86 ++++++++++++++ src/expression.mli | 60 ++++++++++ src/ocaml_helpers.c | 9 ++ src/ocaml_helpers.h | 5 + src/type.ml | 5 +- src/type.mli | 2 +- src/type_builder.c | 176 ++++++++++++++++++++++++++++ src/type_builder.js | 116 +++++++++++++++++++ src/type_builder.ml | 65 +++++++++++ src/type_builder.mli | 27 +++++ test/test.expected | 197 ++++++++++++++++++++++++++++--- test/test.ml | 89 +++++++++++++- 15 files changed, 1280 insertions(+), 21 deletions(-) create mode 100644 src/type_builder.c create mode 100644 src/type_builder.js create mode 100644 src/type_builder.ml create mode 100644 src/type_builder.mli diff --git a/src/dune b/src/dune index a5bcd431..966c1928 100644 --- a/src/dune +++ b/src/dune @@ -23,6 +23,7 @@ heap_type signature_type struct_type + type_builder ocaml_helpers) (flags :standard -O2 -Wall -Wextra)) (js_of_ocaml @@ -44,4 +45,5 @@ packed_type.js heap_type.js signature_type.js + type_builder.js struct_type.js))) diff --git a/src/expression.c b/src/expression.c index f20c5a9e..737a0124 100644 --- a/src/expression.c +++ b/src/expression.c @@ -124,6 +124,23 @@ caml_binaryen_call_indirect__bytecode(value * argv) { return caml_binaryen_call_indirect(argv[0], argv[1], argv[2], argv[3], argv[4], argv[5]); } +CAMLprim value +caml_binaryen_call_ref(value _module, value _target, value _params, value _ty, value _is_return) { + CAMLparam5(_module, _target, _params, _ty, _is_return); + BinaryenModuleRef module = BinaryenModuleRef_val(_module); + BinaryenExpressionRef target = BinaryenExpressionRef_val(_target); + _params = array_of_list(_params); + int paramsLen = array_length(_params); + BinaryenExpressionRef params[paramsLen]; + for (int i = 0; i < paramsLen; i++) { + params[i] = BinaryenExpressionRef_val(Field(_params, i)); + } + BinaryenType ty = BinaryenType_val(_ty); + bool is_return = Bool_val(_is_return); + BinaryenExpressionRef exp = BinaryenCallRef(module, target, params, paramsLen, ty, is_return); + CAMLreturn(alloc_BinaryenExpressionRef(exp)); +} + CAMLprim value caml_binaryen_return_call(value _module, value _name, value _params, value _retty) { CAMLparam4(_module, _name, _params, _retty); @@ -459,6 +476,38 @@ caml_binaryen_i31_get(value _module, value _val, value _signed) { CAMLreturn(alloc_BinaryenExpressionRef(exp)); } +CAMLprim value +caml_binaryen_ref_test(value _module, value _ref, value _castType) { + CAMLparam3(_module, _ref, _castType); + BinaryenModuleRef module = BinaryenModuleRef_val(_module); + BinaryenExpressionRef ref = BinaryenExpressionRef_val(_ref); + BinaryenType castType = BinaryenType_val(_castType); + BinaryenExpressionRef exp = BinaryenRefTest(module, ref, castType); + CAMLreturn(alloc_BinaryenExpressionRef(exp)); +} + +CAMLprim value +caml_binaryen_ref_cast(value _module, value _ref, value _castType) { + CAMLparam3(_module, _ref, _castType); + BinaryenModuleRef module = BinaryenModuleRef_val(_module); + BinaryenExpressionRef ref = BinaryenExpressionRef_val(_ref); + BinaryenType castType = BinaryenType_val(_castType); + BinaryenExpressionRef exp = BinaryenRefCast(module, ref, castType); + CAMLreturn(alloc_BinaryenExpressionRef(exp)); +} + +CAMLprim value +caml_binaryen_br_on(value _module, value _op, value _name, value _ref, value _castType) { + CAMLparam5(_module, _op, _name, _ref, _castType); + BinaryenModuleRef module = BinaryenModuleRef_val(_module); + BinaryenOp op = BinaryenOp_val(_op); + char* name = Safe_String_val(_name); + BinaryenExpressionRef ref = BinaryenExpressionRef_val(_ref); + BinaryenType castType = BinaryenType_val(_castType); + BinaryenExpressionRef exp = BinaryenBrOn(module, op, name, ref, castType); + CAMLreturn(alloc_BinaryenExpressionRef(exp)); +} + CAMLprim value caml_binaryen_expression_id_invalid(value unit) { CAMLparam1(unit); @@ -1328,6 +1377,90 @@ caml_binaryen_call_indirect_set_return(value _exp, value _isReturn) { CAMLreturn(Val_unit); } +CAMLprim value +caml_binaryen_call_ref_get_target(value _exp) { + CAMLparam1(_exp); + BinaryenExpressionRef exp = BinaryenExpressionRef_val(_exp); + BinaryenExpressionRef target = BinaryenCallRefGetTarget(exp); + CAMLreturn(alloc_BinaryenExpressionRef(target)); +} + +CAMLprim value +caml_binaryen_call_ref_set_target(value _exp, value _target) { + CAMLparam2(_exp, _target); + BinaryenExpressionRef exp = BinaryenExpressionRef_val(_exp); + BinaryenExpressionRef target = BinaryenExpressionRef_val(_target); + BinaryenCallRefSetTarget(exp, target); + CAMLreturn(Val_unit); +} + +CAMLprim value +caml_binaryen_call_ref_get_num_operands(value _exp) { + CAMLparam1(_exp); + BinaryenExpressionRef exp = BinaryenExpressionRef_val(_exp); + CAMLreturn(Val_int(BinaryenCallRefGetNumOperands(exp))); +} + +CAMLprim value +caml_binaryen_call_ref_get_operand_at(value _exp, value _index) { + CAMLparam2(_exp, _index); + BinaryenExpressionRef exp = BinaryenExpressionRef_val(_exp); + BinaryenIndex index = Int_val(_index); + CAMLreturn(alloc_BinaryenExpressionRef(BinaryenCallRefGetOperandAt(exp, index))); +} + +CAMLprim value +caml_binaryen_call_ref_set_operand_at(value _exp, value _index, value _operand) { + CAMLparam3(_exp, _index, _operand); + BinaryenExpressionRef exp = BinaryenExpressionRef_val(_exp); + BinaryenIndex index = Int_val(_index); + BinaryenExpressionRef operand = BinaryenExpressionRef_val(_operand); + BinaryenCallRefSetOperandAt(exp, index, operand); + CAMLreturn(Val_unit); +} + +CAMLprim value +caml_binaryen_call_ref_append_operand(value _exp, value _operand) { + CAMLparam2(_exp, _operand); + BinaryenExpressionRef exp = BinaryenExpressionRef_val(_exp); + BinaryenExpressionRef operand = BinaryenExpressionRef_val(_operand); + CAMLreturn(Val_int(BinaryenCallRefAppendOperand(exp, operand))); +} + +CAMLprim value +caml_binaryen_call_ref_insert_operand_at(value _exp, value _index, value _operand) { + CAMLparam3(_exp, _index, _operand); + BinaryenExpressionRef exp = BinaryenExpressionRef_val(_exp); + BinaryenIndex index = Int_val(_index); + BinaryenExpressionRef operand = BinaryenExpressionRef_val(_operand); + BinaryenCallRefInsertOperandAt(exp, index, operand); + CAMLreturn(Val_unit); +} + +CAMLprim value +caml_binaryen_call_ref_remove_operand_at(value _exp, value _index) { + CAMLparam2(_exp, _index); + BinaryenExpressionRef exp = BinaryenExpressionRef_val(_exp); + BinaryenIndex index = Int_val(_index); + CAMLreturn(alloc_BinaryenExpressionRef(BinaryenCallRefRemoveOperandAt(exp, index))); +} + +CAMLprim value +caml_binaryen_call_ref_is_return(value _exp) { + CAMLparam1(_exp); + BinaryenExpressionRef exp = BinaryenExpressionRef_val(_exp); + CAMLreturn(Val_bool(BinaryenCallRefIsReturn(exp))); +} + +CAMLprim value +caml_binaryen_call_ref_set_return(value _exp, value _isReturn) { + CAMLparam2(_exp, _isReturn); + BinaryenExpressionRef exp = BinaryenExpressionRef_val(_exp); + int isReturn = Bool_val(_isReturn); + BinaryenCallRefSetReturn(exp, isReturn); + CAMLreturn(Val_unit); +} + CAMLprim value caml_binaryen_local_set_get_value(value _exp) { CAMLparam1(_exp); @@ -1883,6 +2016,141 @@ caml_binaryen_ref_eq(value _module, value _left, value _right) { CAMLreturn(alloc_BinaryenExpressionRef(exp)); } +// Struct operations + +CAMLprim value +caml_binaryen_struct_new(value _module, value _operands, value _type) { + CAMLparam3(_module, _operands, _type); + BinaryenModuleRef module = BinaryenModuleRef_val(_module); + BinaryenHeapType type = BinaryenHeapType_val(_type); + if (Is_some(_operands)) { + _operands = array_of_list(Some_val(_operands)); + int operandsLen = array_length(_operands); + BinaryenExpressionRef operands[operandsLen]; + for (int i = 0; i < operandsLen; i++) { + operands[i] = BinaryenExpressionRef_val(Field(_operands, i)); + } + BinaryenExpressionRef exp = BinaryenStructNew(module, operands, operandsLen, type); + CAMLreturn(alloc_BinaryenExpressionRef(exp)); + } else { + BinaryenExpressionRef exp = BinaryenStructNew(module, NULL, 0, type); + CAMLreturn(alloc_BinaryenExpressionRef(exp)); + } +} + +CAMLprim value +caml_binaryen_struct_get(value _module, value _index, value _ref, value _type, value _signed) { + CAMLparam5(_module, _index, _ref, _type, _signed); + BinaryenModuleRef module = BinaryenModuleRef_val(_module); + BinaryenIndex index = Int_val(_index); + BinaryenExpressionRef ref = BinaryenExpressionRef_val(_ref); + BinaryenType type = BinaryenType_val(_type); + bool signed_ = Bool_val(_signed); + BinaryenExpressionRef exp = BinaryenStructGet(module, index, ref, type, signed_); + CAMLreturn(alloc_BinaryenExpressionRef(exp)); +} + +CAMLprim value +caml_binaryen_struct_set(value _module, value _index, value _ref, value _value) { + CAMLparam4(_module, _index, _ref, _value); + BinaryenModuleRef module = BinaryenModuleRef_val(_module); + BinaryenIndex index = Int_val(_index); + BinaryenExpressionRef ref = BinaryenExpressionRef_val(_ref); + BinaryenExpressionRef value_ = BinaryenExpressionRef_val(_value); + BinaryenExpressionRef exp = BinaryenStructSet(module, index, ref, value_); + CAMLreturn(alloc_BinaryenExpressionRef(exp)); +} + +// Array operations + +CAMLprim value +caml_binaryen_array_new(value _module, value _type, value _size, value _init) { + CAMLparam4(_module, _type, _size, _init); + BinaryenModuleRef module = BinaryenModuleRef_val(_module); + BinaryenHeapType type = BinaryenHeapType_val(_type); + BinaryenExpressionRef size = BinaryenExpressionRef_val(_size); + BinaryenExpressionRef init = BinaryenExpressionRef_val(_init); + BinaryenExpressionRef exp = BinaryenArrayNew(module, type, size, init); + CAMLreturn(alloc_BinaryenExpressionRef(exp)); +} + +CAMLprim value +caml_binaryen_array_new_data(value _module, value _type, value _name, value _offset, value _size) { + CAMLparam5(_module, _type, _name, _offset, _size); + BinaryenModuleRef module = BinaryenModuleRef_val(_module); + BinaryenHeapType type = BinaryenHeapType_val(_type); + char* name = Safe_String_val(_name); + BinaryenExpressionRef offset = BinaryenExpressionRef_val(_offset); + BinaryenExpressionRef size = BinaryenExpressionRef_val(_size); + BinaryenExpressionRef exp = BinaryenArrayNewData(module, type, name, offset, size); + CAMLreturn(alloc_BinaryenExpressionRef(exp)); +} + +CAMLprim value +caml_binaryen_array_new_fixed(value _module, value _type, value _values) { + CAMLparam3(_module, _type, _values); + BinaryenModuleRef module = BinaryenModuleRef_val(_module); + BinaryenHeapType type = BinaryenHeapType_val(_type); + _values = array_of_list(_values); + int valuesLen = array_length(_values); + BinaryenExpressionRef values[valuesLen]; + for (int i = 0; i < valuesLen; i++) { + values[i] = BinaryenExpressionRef_val(Field(_values, i)); + } + BinaryenExpressionRef exp = BinaryenArrayNewFixed(module, type, values, valuesLen); + CAMLreturn(alloc_BinaryenExpressionRef(exp)); +} + +CAMLprim value +caml_binaryen_array_get(value _module, value _ref, value _index, value _type, value _signed) { + CAMLparam5(_module, _ref, _index, _type, _signed); + BinaryenModuleRef module = BinaryenModuleRef_val(_module); + BinaryenExpressionRef ref = BinaryenExpressionRef_val(_ref); + BinaryenExpressionRef index = BinaryenExpressionRef_val(_index); + BinaryenType type = BinaryenType_val(_type); + bool signed_ = Bool_val(_signed); + BinaryenExpressionRef exp = BinaryenArrayGet(module, ref, index, type, signed_); + CAMLreturn(alloc_BinaryenExpressionRef(exp)); +} + +CAMLprim value +caml_binaryen_array_set(value _module, value _ref, value _index, value _value) { + CAMLparam4(_module, _ref, _index, _value); + BinaryenModuleRef module = BinaryenModuleRef_val(_module); + BinaryenExpressionRef ref = BinaryenExpressionRef_val(_ref); + BinaryenExpressionRef index = BinaryenExpressionRef_val(_index); + BinaryenExpressionRef value_ = BinaryenExpressionRef_val(_value); + BinaryenExpressionRef exp = BinaryenArraySet(module, ref, index, value_); + CAMLreturn(alloc_BinaryenExpressionRef(exp)); +} + +CAMLprim value +caml_binaryen_array_len(value _module, value _ref) { + CAMLparam2(_module, _ref); + BinaryenModuleRef module = BinaryenModuleRef_val(_module); + BinaryenExpressionRef ref = BinaryenExpressionRef_val(_ref); + BinaryenExpressionRef exp = BinaryenArrayLen(module, ref); + CAMLreturn(alloc_BinaryenExpressionRef(exp)); +} + +CAMLprim value +caml_binaryen_array_copy(value _module, value _destRef, value _destIndex, value _srcRef, value _srcIndex, value _length) { + CAMLparam5(_module, _destRef, _destIndex, _srcRef, _srcIndex); + CAMLxparam1(_length); + BinaryenModuleRef module = BinaryenModuleRef_val(_module); + BinaryenExpressionRef destRef = BinaryenExpressionRef_val(_destRef); + BinaryenExpressionRef destIndex = BinaryenExpressionRef_val(_destIndex); + BinaryenExpressionRef srcRef = BinaryenExpressionRef_val(_srcRef); + BinaryenExpressionRef srcIndex = BinaryenExpressionRef_val(_srcIndex); + BinaryenExpressionRef length = BinaryenExpressionRef_val(_length); + BinaryenExpressionRef exp = BinaryenArrayCopy(module, destRef, destIndex, srcRef, srcIndex, length); + CAMLreturn(alloc_BinaryenExpressionRef(exp)); +} +CAMLprim value +caml_binaryen_array_copy__bytecode(value * argv) { + return caml_binaryen_array_copy(argv[0], argv[1], argv[2], argv[3], argv[4], argv[5]); +} + // Table operations CAMLprim value caml_binaryen_table_get(value _module, value _name, value _index, value _ty) { diff --git a/src/expression.js b/src/expression.js index 13b16cf5..8fb33be1 100644 --- a/src/expression.js +++ b/src/expression.js @@ -101,6 +101,18 @@ function caml_binaryen_call_indirect__bytecode() { ); } +//Provides: caml_binaryen_call_ref +//Requires: caml_jsstring_of_string +//Requires: caml_list_to_js_array, caml_js_from_bool +function caml_binaryen_call_ref(wasm_mod, target, params, typ, is_return) { + return wasm_mod.call_ref( + target, + caml_list_to_js_array(params), + typ, + caml_js_from_bool(is_return) + ); +} + //Provides: caml_binaryen_return_call //Requires: caml_jsstring_of_string //Requires: caml_list_to_js_array @@ -547,6 +559,32 @@ function caml_binaryen_ref_i31(wasm_mod, typ) { return wasm_mod.ref.i31(typ); } +//Provides: caml_binaryen_ref_test +function caml_binaryen_ref_test(wasm_mod, ref, typ) { + return wasm_mod.ref.test(ref, typ); +} + +//Provides: caml_binaryen_ref_cast +function caml_binaryen_ref_cast(wasm_mod, ref, typ) { + return wasm_mod.ref.cast(ref, typ); +} + +//Provides: caml_binaryen_br_on +//Requires: caml_jsstring_of_string +//Requires: Binaryen +function caml_binaryen_br_on(wasm_mod, op, name, ref, typ) { + switch (op) { + case Binaryen.BrOnNull: + return wasm_mod.br_on.null(caml_jsstring_of_string(name), ref, typ); + case Binaryen.BrOnNonNull: + return wasm_mod.br_on.non_null(caml_jsstring_of_string(name), ref, typ); + case Binaryen.BrOnCast: + return wasm_mod.br_on.cast(caml_jsstring_of_string(name), ref, typ); + case Binaryen.BrOnCastFail: + return wasm_mod.br_on.cast_fail(caml_jsstring_of_string(name), ref, typ); + } +} + //Provides: caml_binaryen_i31_get function caml_binaryen_i31_get(wasm_mod, typ, signed) { if (signed) { @@ -1296,6 +1334,68 @@ function caml_binaryen_call_indirect_set_return(exp, isReturn) { return Binaryen.CallIndirect.setReturn(exp, caml_js_from_bool(isReturn)); } +//Provides: caml_binaryen_call_ref_get_target +//Requires: Binaryen +function caml_binaryen_call_ref_get_target(exp) { + return Binaryen.CallRef.getTarget(exp); +} + +//Provides: caml_binaryen_call_ref_set_target +//Requires: Binaryen +function caml_binaryen_call_ref_set_target(exp, target) { + return Binaryen.CallRef.setTarget(exp, target); +} + +//Provides: caml_binaryen_call_ref_get_num_operands +//Requires: Binaryen +function caml_binaryen_call_ref_get_num_operands(exp) { + return Binaryen.CallRef.getNumOperands(exp); +} + +//Provides: caml_binaryen_call_ref_get_operand_at +//Requires: Binaryen +function caml_binaryen_call_ref_get_operand_at(exp, index) { + return Binaryen.CallRef.getOperandAt(exp, index); +} + +//Provides: caml_binaryen_call_ref_set_operand_at +//Requires: Binaryen +function caml_binaryen_call_ref_set_operand_at(exp, index, operand) { + return Binaryen.CallRef.setOperandAt(exp, index, operand); +} + +//Provides: caml_binaryen_call_ref_append_operand +//Requires: Binaryen +function caml_binaryen_call_ref_append_operand(exp, operand) { + return Binaryen.CallRef.appendOperand(exp, operand); +} + +//Provides: caml_binaryen_call_ref_insert_operand_at +//Requires: Binaryen +function caml_binaryen_call_ref_insert_operand_at(exp, index, operand) { + return Binaryen.CallRef.insertOperandAt(exp, index, operand); +} + +//Provides: caml_binaryen_call_ref_remove_operand_at +//Requires: Binaryen +function caml_binaryen_call_ref_remove_operand_at(exp, index) { + return Binaryen.CallRef.removeOperandAt(exp, index); +} + +//Provides: caml_binaryen_call_ref_is_return +//Requires: Binaryen +//Requires: caml_js_to_bool +function caml_binaryen_call_ref_is_return(exp) { + return caml_js_to_bool(Binaryen.CallRef.isReturn(exp)); +} + +//Provides: caml_binaryen_call_ref_set_return +//Requires: Binaryen +//Requires: caml_js_from_bool +function caml_binaryen_call_ref_set_return(exp, isReturn) { + return Binaryen.CallRef.setReturn(exp, caml_js_from_bool(isReturn)); +} + //Provides: caml_binaryen_local_set_get_value //Requires: Binaryen function caml_binaryen_local_set_get_value(exp) { @@ -1707,6 +1807,100 @@ function caml_binaryen_ref_eq(wasm_mod, left, right) { return wasm_mod.ref.func(left, right); } +// Struct operations + +//Provides: caml_binaryen_struct_new +//Requires: caml_list_to_js_array +function caml_binaryen_struct_new(wasm_mod, operands, type) { + return wasm_mod.struct.new( + operands ? caml_list_to_js_array(operands[1]) : null, + type + ); +} + +//Provides: caml_binaryen_struct_get +//Requires: caml_js_from_bool +function caml_binaryen_struct_get(wasm_mod, index, ref, type, signed) { + if (caml_js_from_bool(signed)) { + return wasm_mod.struct.get_s(index, ref, type); + } else { + return wasm_mod.struct.get_u(index, ref, type); + } +} + +//Provides: caml_binaryen_struct_set +function caml_binaryen_struct_set(wasm_mod, index, ref, value) { + return wasm_mod.struct.set(index, ref, value); +} + +// Array operations + +//Provides: caml_binaryen_array_new +function caml_binaryen_array_new(wasm_mod, type, size, init) { + return wasm_mod.array.new(type, size, init); +} + +//Provides: caml_binaryen_array_new_data +//Requires: caml_jsstring_of_string +function caml_binaryen_array_new_data(wasm_mod, type, name, offset, size) { + return wasm_mod.array.new_data( + type, + caml_jsstring_of_string(name), + offset, + size + ); +} + +//Provides: caml_binaryen_array_new_fixed +//Requires: caml_list_to_js_array +function caml_binaryen_array_new_fixed(wasm_mod, type, values) { + return wasm_mod.array.new_fixed(type, caml_list_to_js_array(values)); +} + +//Provides: caml_binaryen_array_get +//Requires: caml_js_from_bool +function caml_binaryen_array_get(wasm_mod, ref, index, type, signed) { + if (caml_js_from_bool(signed)) { + return wasm_mod.array.get_s(ref, index, type); + } else { + return wasm_mod.array.get_u(ref, index, type); + } +} + +//Provides: caml_binaryen_array_set +function caml_binaryen_array_set(wasm_mod, ref, index, value) { + return wasm_mod.array.set(ref, index, value); +} + +//Provides: caml_binaryen_array_len +function caml_binaryen_array_len(wasm_mod, ref) { + return wasm_mod.array.len(ref); +} + +//Provides: caml_binaryen_array_copy +function caml_binaryen_array_copy( + wasm_mod, + destRef, + destIndex, + srcRef, + srcIndex, + length +) { + return wasm_mod.array.copy(destRef, destIndex, srcRef, srcIndex, length); +} +//Provides: caml_binaryen_array_copy__bytecode +//Requires: caml_binaryen_array_copy +function caml_binaryen_array_copy__bytecode() { + return caml_binaryen_array_copy( + arguments[0], + arguments[1], + arguments[2], + arguments[3], + arguments[4], + arguments[5] + ); +} + // Table operations //Provides: caml_binaryen_table_get diff --git a/src/expression.ml b/src/expression.ml index 1824b6db..423f16f2 100644 --- a/src/expression.ml +++ b/src/expression.ml @@ -583,6 +583,39 @@ module Call_indirect = struct = "caml_binaryen_call_indirect_set_return" end +module Call_ref = struct + external make : Module.t -> t -> t list -> Type.t -> bool -> t + = "caml_binaryen_call_ref" + (** Module, function value, params, type, is return. *) + + let make_return mod_ target params typ = make mod_ target params typ true + let make mod_ target params typ = make mod_ target params typ false + + external get_target : t -> t = "caml_binaryen_call_ref_get_target" + external set_target : t -> t -> unit = "caml_binaryen_call_ref_set_target" + + external get_num_operands : t -> int + = "caml_binaryen_call_ref_get_num_operands" + + external get_operand_at : t -> int -> t + = "caml_binaryen_call_ref_get_operand_at" + + external set_operand_at : t -> int -> t -> unit + = "caml_binaryen_call_ref_set_operand_at" + + external append_operand : t -> t -> int + = "caml_binaryen_call_ref_append_operand" + + external insert_operand_at : t -> int -> t -> unit + = "caml_binaryen_call_ref_insert_operand_at" + + external remove_operand_at : t -> int -> t + = "caml_binaryen_call_ref_remove_operand_at" + + external is_return : t -> bool = "caml_binaryen_call_ref_is_return" + external set_return : t -> bool -> unit = "caml_binaryen_call_ref_set_return" +end + module Local_get = struct external make : Module.t -> int -> Type.t -> t = "caml_binaryen_local_get" (** Module, slot, type. *) @@ -830,6 +863,59 @@ module Ref = struct external eq : Module.t -> t -> t -> t = "caml_binaryen_ref_eq" (** Module, left, right *) + + external test : Module.t -> t -> Type.t -> t = "caml_binaryen_ref_test" + (** Module, value, type *) + + external cast : Module.t -> t -> Type.t -> t = "caml_binaryen_ref_cast" + (** Module, value, type *) +end + +module BrOn = struct + external make : Module.t -> Op.t -> string -> t -> Type.t -> t + = "caml_binaryen_br_on" + (** Module, op, label, value, type *) +end + +module Struct = struct + external new_ : Module.t -> t list option -> Heap_type.t -> t + = "caml_binaryen_struct_new" + (** Mdoule, operands, type *) + + external get : Module.t -> int -> t -> Type.t -> bool -> t + = "caml_binaryen_struct_get" + (** Module, index, struct, type, signed *) + + external set : Module.t -> int -> t -> t -> t = "caml_binaryen_struct_set" + (** Module, index, struct, value *) +end + +module Array = struct + external new_ : Module.t -> Heap_type.t -> t -> t -> t + = "caml_binaryen_array_new" + (** Module, type, size, init *) + + external new_data : Module.t -> Heap_type.t -> string -> t -> t -> t + = "caml_binaryen_array_new_data" + (** Module, type, data name, offset, size *) + + external new_fixed : Module.t -> Heap_type.t -> t list -> t + = "caml_binaryen_array_new_fixed" + (** Module, type, values *) + + external get : Module.t -> t -> t -> Type.t -> bool -> t + = "caml_binaryen_array_get" + (** Module, array, index, type, signed *) + + external set : Module.t -> t -> t -> t -> t = "caml_binaryen_array_set" + (** Module, array, index, value *) + + external len : Module.t -> t -> t = "caml_binaryen_array_len" + (** Module, array *) + + external copy : Module.t -> t -> t -> t -> t -> t -> t + = "caml_binaryen_array_copy__bytecode" "caml_binaryen_array_copy" + (** Module, dest, dest index, src, src index, length *) end module Table = struct diff --git a/src/expression.mli b/src/expression.mli index 9abd7beb..60370583 100644 --- a/src/expression.mli +++ b/src/expression.mli @@ -161,6 +161,21 @@ module Call_indirect : sig val set_return : t -> bool -> unit end +module Call_ref : sig + val make : Module.t -> t -> t list -> Type.t -> t + val make_return : Module.t -> t -> t list -> Type.t -> t + val get_target : t -> t + val set_target : t -> t -> unit + val get_num_operands : t -> int + val get_operand_at : t -> int -> t + val set_operand_at : t -> int -> t -> unit + val append_operand : t -> t -> int + val insert_operand_at : t -> int -> t -> unit + val remove_operand_at : t -> int -> t + val is_return : t -> bool + val set_return : t -> bool -> unit +end + module Local_get : sig val make : Module.t -> int -> Type.t -> t end @@ -348,6 +363,51 @@ module Ref : sig val eq : Module.t -> t -> t -> t (** Module, left, right *) + + val test : Module.t -> t -> Type.t -> t + (** Module, value, type *) + + val cast : Module.t -> t -> Type.t -> t + (** Module, value, type *) +end + +module BrOn : sig + val make : Module.t -> Op.t -> string -> t -> Type.t -> t + (** Module, op, label, value, type *) +end + +module Struct : sig + val new_ : Module.t -> t list option -> Heap_type.t -> t + (** Mdoule, operands, type *) + + val get : Module.t -> int -> t -> Type.t -> bool -> t + (** Module, index, struct, type, signed *) + + val set : Module.t -> int -> t -> t -> t + (** Module, index, struct, value *) +end + +module Array : sig + val new_ : Module.t -> Heap_type.t -> t -> t -> t + (** Module, type, size, init *) + + val new_data : Module.t -> Heap_type.t -> string -> t -> t -> t + (** Module, type, data name, offset, size *) + + val new_fixed : Module.t -> Heap_type.t -> t list -> t + (** Module, type, values *) + + val get : Module.t -> t -> t -> Type.t -> bool -> t + (** Module, array, index, type, signed *) + + val set : Module.t -> t -> t -> t -> t + (** Module, array, index, value *) + + val len : Module.t -> t -> t + (** Module, array *) + + val copy : Module.t -> t -> t -> t -> t -> t -> t + (** Module, dest, dest index, src, src index, length *) end module Table : sig diff --git a/src/ocaml_helpers.c b/src/ocaml_helpers.c index 78a17230..bb3e374b 100644 --- a/src/ocaml_helpers.c +++ b/src/ocaml_helpers.c @@ -3,6 +3,7 @@ #include #include #include +#include #include "ocaml_helpers.h" @@ -94,6 +95,14 @@ value alloc_BinaryenElementSegmentRef(BinaryenElementSegmentRef elem) return v; } +/* Allocating an OCaml custom block to hold the given TypeBuilderRef */ +value alloc_TypeBuilderRef(TypeBuilderRef builder) +{ + value v = caml_alloc_custom(&binaryen_ops, sizeof(TypeBuilderRef), 0, 1); + TypeBuilderRef_val(v) = builder; + return v; +} + CAMLprim value array_of_list(value list) { CAMLparam1(list); diff --git a/src/ocaml_helpers.h b/src/ocaml_helpers.h index 3e926eaf..cde38d7f 100644 --- a/src/ocaml_helpers.h +++ b/src/ocaml_helpers.h @@ -23,6 +23,7 @@ static struct custom_operations binaryen_ops = { #define BinaryenModuleRef_val(v) (*((BinaryenModuleRef*) Data_custom_val(v))) #define BinaryenType_val(v) (*((BinaryenType*) Data_custom_val(v))) +#define BinaryenPackedType_val(v) Int_val(v) #define BinaryenHeapType_val(v) (*((BinaryenHeapType*) Data_custom_val(v))) #define BinaryenExpressionRef_val(v) (*((BinaryenExpressionRef*) Data_custom_val(v))) #define BinaryenOp_val(v) (*((BinaryenOp*) Data_custom_val(v))) @@ -32,6 +33,7 @@ static struct custom_operations binaryen_ops = { #define BinaryenExportRef_val(v) (*((BinaryenExportRef*) Data_custom_val(v))) #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 Val_none Val_int(0) #define Some_val(v) Field(v, 0) @@ -74,6 +76,9 @@ value alloc_BinaryenTableRef(BinaryenTableRef table); /* Allocating an OCaml custom block to hold the given BinaryenElementSegmentRef */ value alloc_BinaryenElementSegmentRef(BinaryenElementSegmentRef elem); +/* Allocating an OCaml custom block to hold the given TypeBuilderRef */ +value alloc_TypeBuilderRef(TypeBuilderRef builder); + CAMLprim value array_of_list(value list); diff --git a/src/type.ml b/src/type.ml index 119be8cc..8090acb6 100644 --- a/src/type.ml +++ b/src/type.ml @@ -75,5 +75,8 @@ let auto = auto () external create : t array -> t = "caml_binaryen_type_create" external expand : t -> t array = "caml_binaryen_type_expand" external is_nullable : t -> bool = "caml_binaryen_type_is_nullable" -external from_heap_type : Heap_type.t -> t = "caml_binaryen_type_from_heap_type" + +external from_heap_type : Heap_type.t -> bool -> t + = "caml_binaryen_type_from_heap_type" + external get_heap_type : t -> Heap_type.t = "caml_binaryen_type_get_heap_type" diff --git a/src/type.mli b/src/type.mli index 874ddb37..868ac579 100644 --- a/src/type.mli +++ b/src/type.mli @@ -21,5 +21,5 @@ val auto : t val create : t array -> t val expand : t -> t array val is_nullable : t -> bool -val from_heap_type : Heap_type.t -> t +val from_heap_type : Heap_type.t -> bool -> t val get_heap_type : t -> Heap_type.t diff --git a/src/type_builder.c b/src/type_builder.c new file mode 100644 index 00000000..c1680ba6 --- /dev/null +++ b/src/type_builder.c @@ -0,0 +1,176 @@ +#define CAML_NAME_SPACE +#include +#include +#include +#include + +#include "binaryen-c.h" +#include "ocaml_helpers.h" + +CAMLprim value +caml_type_builder_create(value _size) { + CAMLparam1(_size); + BinaryenIndex size = Int_val(_size); + CAMLreturn(alloc_TypeBuilderRef(TypeBuilderCreate(size))); +} + +CAMLprim value +caml_type_builder_grow(value _builder, value _count) { + CAMLparam2(_builder, _count); + TypeBuilderRef builder = TypeBuilderRef_val(_builder); + BinaryenIndex count = Int_val(_count); + TypeBuilderGrow(builder, count); + CAMLreturn(Val_unit); +} + +CAMLprim value +caml_type_builder_get_size(value _builder) { + CAMLparam1(_builder); + TypeBuilderRef builder = TypeBuilderRef_val(_builder); + CAMLreturn(Val_int(TypeBuilderGetSize(builder))); +} + +CAMLprim value +caml_type_builder_set_signature_type(value _builder, value _index, value _paramTypes, value _resultTypes) { + CAMLparam4(_builder, _index, _paramTypes, _resultTypes); + TypeBuilderRef builder = TypeBuilderRef_val(_builder); + BinaryenIndex index = Int_val(_index); + BinaryenType paramTypes = BinaryenType_val(_paramTypes); + BinaryenType resultTypes = BinaryenType_val(_resultTypes); + TypeBuilderSetSignatureType(builder, index, paramTypes, resultTypes); + CAMLreturn(Val_unit); +} + +CAMLprim value +caml_type_builder_set_struct_type(value _builder, value _index, value _fieldTypes, value _fieldPackedTypes, value _fieldMutables, value _numFields) { + CAMLparam5(_builder, _index, _fieldTypes, _fieldPackedTypes, _fieldMutables); + CAMLxparam1(_numFields); + TypeBuilderRef builder = TypeBuilderRef_val(_builder); + BinaryenIndex index = Int_val(_index); + _fieldTypes = array_of_list(_fieldTypes); + int fieldTypesLen = array_length(_fieldTypes); + BinaryenType fieldTypes[fieldTypesLen]; + for (int i = 0; i < fieldTypesLen; i++) { + fieldTypes[i] = BinaryenType_val(Field(_fieldTypes, i)); + } + _fieldPackedTypes = array_of_list(_fieldPackedTypes); + int fieldPackedTypesLen = array_length(_fieldPackedTypes); + BinaryenPackedType fieldPackedTypes[fieldPackedTypesLen]; + for (int i = 0; i < fieldPackedTypesLen; i++) { + fieldPackedTypes[i] = BinaryenPackedType_val(Field(_fieldPackedTypes, i)); + } + _fieldMutables = array_of_list(_fieldMutables); + int fieldMutablesLen = array_length(_fieldMutables); + bool fieldMutables[fieldMutablesLen]; + for (int i = 0; i < fieldMutablesLen; i++) { + fieldMutables[i] = Bool_val(Field(_fieldMutables, i)); + } + int numFields = Int_val(_numFields); + TypeBuilderSetStructType(builder, index, fieldTypes, fieldPackedTypes, fieldMutables, numFields); + CAMLreturn(Val_unit); +} +CAMLprim value +caml_type_builder_set_struct_type__bytecode(value * argv) { + return caml_type_builder_set_struct_type(argv[0], argv[1], argv[2], argv[3], argv[4], argv[5]); +} + +CAMLprim value +caml_type_builder_set_array_type(value _builder, value _index, value _elementType, value _elementPackedType, value _elementMutable) { + CAMLparam5(_builder, _index, _elementType, _elementPackedType, _elementMutable); + TypeBuilderRef builder = TypeBuilderRef_val(_builder); + BinaryenIndex index = Int_val(_index); + BinaryenType elementType = BinaryenType_val(_elementType); + BinaryenPackedType elementPackedType = BinaryenPackedType_val(_elementPackedType); + bool elementMutable = Bool_val(_elementMutable); + TypeBuilderSetArrayType(builder, index, elementType, elementPackedType, elementMutable); + CAMLreturn(Val_unit); +} + +CAMLprim value +caml_type_builder_get_temp_heap_type(value _builder, value _index) { + CAMLparam2(_builder, _index); + TypeBuilderRef builder = TypeBuilderRef_val(_builder); + BinaryenIndex index = Int_val(_index); + CAMLreturn(alloc_BinaryenHeapType(TypeBuilderGetTempHeapType(builder, index))); +} + +CAMLprim value +caml_type_builder_get_temp_tuple_type(value _builder, value _types, value _numTypes) { + CAMLparam3(_builder, _types, _numTypes); + TypeBuilderRef builder = TypeBuilderRef_val(_builder); + _types = array_of_list(_types); + int typesLen = array_length(_types); + BinaryenType types[typesLen]; + for (int i = 0; i < typesLen; i++) { + types[i] = BinaryenType_val(Field(_types, i)); + } + int numTypes = Int_val(_numTypes); + CAMLreturn(alloc_BinaryenType(TypeBuilderGetTempTupleType(builder, types, numTypes))); +} + +CAMLprim value +caml_type_builder_get_temp_ref_type(value _builder, value _heapType, value _nullable) { + CAMLparam3(_builder, _heapType, _nullable); + TypeBuilderRef builder = TypeBuilderRef_val(_builder); + BinaryenHeapType heapType = BinaryenHeapType_val(_heapType); + bool nullable = Bool_val(_nullable); + CAMLreturn(alloc_BinaryenType(TypeBuilderGetTempRefType(builder, heapType, nullable))); +} + +CAMLprim value +caml_type_builder_set_sub_type(value _builder, value _index, value _superType) { + CAMLparam3(_builder, _index, _superType); + TypeBuilderRef builder = TypeBuilderRef_val(_builder); + BinaryenIndex index = Int_val(_index); + BinaryenHeapType superType = BinaryenHeapType_val(_superType); + TypeBuilderSetSubType(builder, index, superType); + CAMLreturn(Val_unit); +} + +CAMLprim value +caml_type_builder_set_open(value _builder, value _index) { + CAMLparam2(_builder, _index); + TypeBuilderRef builder = TypeBuilderRef_val(_builder); + BinaryenIndex index = Int_val(_index); + TypeBuilderSetOpen(builder, index); + CAMLreturn(Val_unit); +} + +CAMLprim value +caml_type_builder_create_rec_group(value _builder, value _index, value _length) { + CAMLparam3(_builder, _index, _length); + TypeBuilderRef builder = TypeBuilderRef_val(_builder); + BinaryenIndex index = Int_val(_index); + BinaryenIndex length = Int_val(_length); + TypeBuilderCreateRecGroup(builder, index, length); + CAMLreturn(Val_unit); +} + +CAMLprim value +caml_conv_heap_type(BinaryenHeapType heapType) { + return alloc_BinaryenHeapType(heapType); +} + +CAMLprim value +caml_type_builder_build_and_dispose(value _builder) { + CAMLparam1(_builder); + TypeBuilderRef builder = TypeBuilderRef_val(_builder); + BinaryenIndex size = TypeBuilderGetSize(builder); + BinaryenHeapType heapTypes[size + 1]; + heapTypes[size] = (BinaryenHeapType) NULL; + BinaryenIndex errorIndex; + TypeBuilderErrorReason errorReason; + bool success = TypeBuilderBuildAndDispose(builder, heapTypes, &errorIndex, &errorReason); + if (success) { + value ok = caml_alloc_small(1, 0); + Field(ok, 0) = caml_alloc_array((void*)caml_conv_heap_type, (char const **)heapTypes); + CAMLreturn(ok); + } else { + value error = caml_alloc_small(1, 1); + value tuple = caml_alloc_small(2, 0); + Field(tuple, 0) = Val_int(errorIndex); + Field(tuple, 1) = Val_int(errorReason); + Field(error, 0) = tuple; + CAMLreturn(error); + } +} diff --git a/src/type_builder.js b/src/type_builder.js new file mode 100644 index 00000000..b8082e32 --- /dev/null +++ b/src/type_builder.js @@ -0,0 +1,116 @@ +//Provides: caml_type_builder_create +//Requires: Binaryen +function caml_type_builder_create(size) { + return new Binaryen.TypeBuilder(size); +} + +//Provides: caml_type_builder_grow +function caml_type_builder_grow(builder, count) { + builder.grow(count); +} + +//Provides: caml_type_builder_get_size +function caml_type_builder_get_size(builder) { + return builder.getSize(); +} + +//Provides: caml_type_builder_set_signature_type +function caml_type_builder_set_signature_type( + builder, + index, + paramTypes, + resultTypes +) { + builder.setSignatureType(index, paramTypes, resultTypes); +} + +//Provides: caml_type_builder_set_struct_type +//Requires: caml_list_to_js_array +//Requires: caml_js_from_bool +function caml_type_builder_set_struct_type( + builder, + index, + fieldTypes, + fieldPackedTypes, + fieldMutables, + numFields +) { + var types = caml_list_to_js_array(fieldTypes); + var packedTypes = caml_list_to_js_array(fieldPackedTypes); + var mutables = caml_list_to_js_array(fieldMutables); + var fields = types.map(function (type, idx) { + return { + type, + packedType: packedTypes[idx], + mutable: caml_js_from_bool(mutables[idx]), + }; + }); + builder.setStructType(index, fields); +} +//Provides: caml_type_builder_set_struct_type__bytecode +//Requires: caml_type_builder_set_struct_type +function caml_type_builder_set_struct_type__bytecode() { + return caml_type_builder_set_struct_type( + arguments[0], + arguments[1], + arguments[2], + arguments[3], + arguments[4], + arguments[5] + ); +} + +//Provides: caml_type_builder_set_array_type +function caml_type_builder_set_array_type( + builder, + index, + elementType, + elementPackedType, + elementMutable +) { + builder.setArrayType(index, elementType, elementPackedType, elementMutable); +} + +//Provides: caml_type_builder_get_temp_heap_type +function caml_type_builder_get_temp_heap_type(builder, index) { + return builder.getTempHeapType(index); +} + +//Provides: caml_type_builder_get_temp_tuple_type +//Requires: caml_list_to_js_array +function caml_type_builder_get_temp_tuple_type(builder, types, numTypes) { + var tupleTypes = caml_list_to_js_array(types); + return builder.getTempTupleType(tupleTypes); +} + +//Provides: caml_type_builder_get_temp_ref_type +//Requires: caml_js_from_bool +function caml_type_builder_get_temp_ref_type(builder, heapType, nullable) { + return builder.getTempRefType(heapType, caml_js_from_bool(nullable)); +} + +//Provides: caml_type_builder_set_sub_type +function caml_type_builder_set_sub_type(builder, index, superType) { + builder.setSubType(index, superType); +} + +//Provides: caml_type_builder_set_open +function caml_type_builder_set_open(builder, index) { + builder.setOpen(index); +} + +//Provides: caml_type_builder_create_rec_group +function caml_type_builder_create_rec_group(builder, index, length) { + builder.createRecGroup(index, length); +} + +//Provides: caml_type_builder_build_and_dispose +//Requires: caml_js_to_array +function caml_type_builder_build_and_dispose(builder) { + try { + var types = builder.buildAndDispose(); + return [0, caml_js_to_array(types)]; + } catch (e) { + return [1, [0, e.index, e.reason]]; + } +} diff --git a/src/type_builder.ml b/src/type_builder.ml new file mode 100644 index 00000000..0d72d937 --- /dev/null +++ b/src/type_builder.ml @@ -0,0 +1,65 @@ +type t + +type struct_field = { + type_ : Type.t; + packed_type : Packed_type.t; + mutable_ : bool; +} + +type error = + | SelfSupertype of int + | InvalidSupertype of int + | ForwardSupertypeReference of int + | ForwardChildReference of int + +external make : int -> t = "caml_type_builder_create" +external grow : t -> int -> unit = "caml_type_builder_grow" +external size : t -> int = "caml_type_builder_grow" + +external set_signature_type : t -> int -> Type.t -> Type.t -> unit + = "caml_type_builder_set_signature_type" + +external set_struct_type : + t -> int -> Type.t list -> Packed_type.t list -> bool list -> int -> unit + = "caml_type_builder_set_struct_type__bytecode" "caml_type_builder_set_struct_type" + +let set_struct_type builder index fields = + let split_fields fields = + List.fold_right + (fun { type_; packed_type; mutable_ } (types, packed_types, mutables) -> + (type_ :: types, packed_type :: packed_types, mutable_ :: mutables)) + fields ([], [], []) + in + let types, packed_types, mutables = split_fields fields in + set_struct_type builder index types packed_types mutables (List.length types) + +external set_array_type : t -> int -> Type.t -> Packed_type.t -> bool -> unit + = "caml_type_builder_set_array_type" + +external get_temp_heap_type : t -> int -> Heap_type.t + = "caml_type_builder_get_temp_heap_type" + +external get_temp_tuple_type : t -> Type.t list -> Type.t + = "caml_type_builder_get_temp_tuple_type" + +external get_temp_ref_type : t -> Heap_type.t -> bool -> Type.t + = "caml_type_builder_get_temp_ref_type" + +external set_sub_type : t -> int -> Type.t -> unit + = "caml_type_builder_set_sub_type" + +external set_open : t -> int -> unit = "caml_type_builder_set_open" + +external create_rec_group : t -> int -> int -> unit + = "caml_type_builder_create_rec_group" + +external build_and_dispose : t -> (Type.t array, int * int) result + = "caml_type_builder_build_and_dispose" + +let build_and_dispose builder = + match build_and_dispose builder with + | Ok types -> Ok (Array.to_list types) + | Error (idx, 0) -> Error (SelfSupertype idx) + | Error (idx, 1) -> Error (InvalidSupertype idx) + | Error (idx, 2) -> Error (ForwardSupertypeReference idx) + | Error (idx, _) -> Error (ForwardChildReference idx) diff --git a/src/type_builder.mli b/src/type_builder.mli new file mode 100644 index 00000000..260458db --- /dev/null +++ b/src/type_builder.mli @@ -0,0 +1,27 @@ +type t + +type struct_field = { + type_ : Type.t; + packed_type : Packed_type.t; + mutable_ : bool; +} + +type error = + | SelfSupertype of int + | InvalidSupertype of int + | ForwardSupertypeReference of int + | ForwardChildReference of int + +val make : int -> t +val grow : t -> int -> unit +val size : t -> int +val set_signature_type : t -> int -> Type.t -> Type.t -> unit +val set_struct_type : t -> int -> struct_field list -> unit +val set_array_type : t -> int -> Type.t -> Packed_type.t -> bool -> unit +val get_temp_heap_type : t -> int -> Heap_type.t +val get_temp_tuple_type : t -> Type.t list -> Type.t +val get_temp_ref_type : t -> Heap_type.t -> bool -> Type.t +val set_sub_type : t -> int -> Type.t -> unit +val set_open : t -> int -> unit +val create_rec_group : t -> int -> int -> unit +val build_and_dispose : t -> (Type.t list, error) result diff --git a/test/test.expected b/test/test.expected index 8e1c7db2..206ecb4d 100644 --- a/test/test.expected +++ b/test/test.expected @@ -7,11 +7,15 @@ (i32.const 0) ) (module - (type $0 (func (param i32 i32) (result i32))) - (type $1 (func)) - (type $2 (func (param anyref i32 i32) (result i32))) - (type $3 (func (param anyref) (result i32))) - (import "future-wasi" "write" (func $write (type $2) (param anyref i32 i32) (result i32))) + (type $0 (struct (field i31ref) (field (ref null $0)))) + (type $1 (array (mut i8))) + (type $2 (func (param i32 i32) (result i32))) + (type $3 (func (result (ref $1) (ref $0)))) + (type $4 (func)) + (type $5 (func (param anyref i32 i32) (result i32))) + (type $6 (func (param anyref) (result i32))) + (type $7 (func (param anyref) (result anyref anyref))) + (import "future-wasi" "write" (func $write (type $5) (param anyref i32 i32) (result i32))) (global $max_int64 i64 (i64.const 9223372036854775807)) (global $max_int64_mut (mut i64) (i64.const 9223372036854775807)) (global $test_float64_bits f64 (f64.const 1.23)) @@ -23,8 +27,9 @@ (export "adder" (func $adder)) (export "memory" (memory $0)) (export "hello" (func $hello)) + (export "gc" (func $gc)) (start $start) - (func $adder (type $0) (param $0 i32) (param $1 i32) (result i32) + (func $adder (type $2) (param $0 i32) (param $1 i32) (result i32) (block $add (result i32) (if (i32.const 0) @@ -44,7 +49,7 @@ ) ) ) - (func $start (type $1) + (func $start (type $4) (block $start (memory.init $world (i32.const 2048) @@ -52,7 +57,7 @@ (i32.const 5) ) (drop - (call_indirect $table (type $0) + (call_indirect $table (type $2) (i32.const 3) (i32.const 5) (i32.const 0) @@ -60,20 +65,68 @@ ) ) ) - (func $hello (type $3) (param $0 anyref) (result i32) + (func $hello (type $6) (param $0 anyref) (result i32) (call $write (local.get $0) (i32.const 0) (i32.const 1) ) ) + (func $gc (type $7) (param $0 anyref) (result anyref anyref) + (local $1 (ref $1)) + (local $2 (ref $0)) + (block $gc_block (type $3) (result (ref $1) (ref $0)) + (local.set $1 + (array.new_fixed $1 2 + (i32.const 0) + (i32.const 255) + ) + ) + (array.set $1 + (local.get $1) + (i32.const 1) + (i32.const 42) + ) + (local.set $2 + (struct.new $0 + (ref.cast i31ref + (local.get $0) + ) + (struct.new $0 + (ref.i31 + (i32.const 1) + ) + (struct.new $0 + (ref.i31 + (i32.const 2) + ) + (struct.new $0 + (ref.i31 + (i32.const 3) + ) + (ref.null none) + ) + ) + ) + ) + ) + (tuple.make 2 + (local.get $1) + (local.get $2) + ) + ) + ) ) (module - (type $0 (func (param i32 i32) (result i32))) - (type $1 (func)) - (type $2 (func (param anyref i32 i32) (result i32))) - (type $3 (func (param anyref) (result i32))) - (import "future-wasi" "write" (func $write (type $2) (param anyref i32 i32) (result i32))) + (type $0 (struct (field i31ref) (field (ref null $0)))) + (type $1 (array (mut i8))) + (type $2 (func (result (ref $1) (ref $0)))) + (type $3 (func (param i32 i32) (result i32))) + (type $4 (func)) + (type $5 (func (param anyref i32 i32) (result i32))) + (type $6 (func (param anyref) (result i32))) + (type $7 (func (param anyref) (result anyref anyref))) + (import "future-wasi" "write" (func $write (type $5) (param anyref i32 i32) (result i32))) (memory $0 1) (data $hello (i32.const 0) "hello") (data $world "world") @@ -82,8 +135,9 @@ (export "adder" (func $adder)) (export "memory" (memory $0)) (export "hello" (func $hello)) + (export "gc" (func $gc)) (start $start) - (func $adder (type $0) (param $0 i32) (param $1 i32) (result i32) + (func $adder (type $3) (param $0 i32) (param $1 i32) (result i32) (i32.add (select (local.get $0) @@ -95,7 +149,7 @@ (local.get $1) ) ) - (func $start (type $1) + (func $start (type $4) (memory.init $world (i32.const 2048) (i32.const 0) @@ -108,19 +162,60 @@ ) ) ) - (func $hello (type $3) (param $0 anyref) (result i32) + (func $hello (type $6) (param $0 anyref) (result i32) (call $write (local.get $0) (i32.const 0) (i32.const 1) ) ) + (func $gc (type $7) (param $0 anyref) (result anyref anyref) + (local $1 (ref $1)) + (array.set $1 + (local.tee $1 + (array.new_fixed $1 2 + (i32.const 0) + (i32.const 255) + ) + ) + (i32.const 1) + (i32.const 42) + ) + (tuple.make 2 + (local.get $1) + (struct.new $0 + (ref.cast i31ref + (local.get $0) + ) + (struct.new $0 + (ref.i31 + (i32.const 1) + ) + (struct.new $0 + (ref.i31 + (i32.const 2) + ) + (struct.new $0 + (ref.i31 + (i32.const 3) + ) + (ref.null none) + ) + ) + ) + ) + ) + ) ) (module + (type $type_6 (struct (field i31ref) (field (ref null $type_6)))) + (type $type_5 (array (mut i8))) + (type $type_7 (func (result anyref anyref))) (type $type (func (param anyref i32 i32) (result i32))) (type $type_1 (func (param i32 i32) (result i32))) (type $type_2 (func)) (type $type_3 (func (param anyref) (result i32))) + (type $type_4 (func (param anyref) (result anyref anyref))) (import "future-wasi" "write" (func $fimport$0 (type $type) (param anyref i32 i32) (result i32))) (memory $0 1) (data $0 (i32.const 0) "hello") @@ -130,6 +225,7 @@ (export "adder" (func $0)) (export "memory" (memory $0)) (export "hello" (func $2)) + (export "gc" (func $3)) (start $1) (func $0 (type $type_1) (param $0 i32) (param $1 i32) (result i32) (i32.add @@ -163,12 +259,53 @@ (i32.const 1) ) ) + (func $3 (type $type_4) (param $0 anyref) (result anyref anyref) + (local $1 (ref $type_5)) + (array.set $type_5 + (local.tee $1 + (array.new_fixed $type_5 2 + (i32.const 0) + (i32.const 255) + ) + ) + (i32.const 1) + (i32.const 42) + ) + (tuple.make 2 + (local.get $1) + (struct.new $type_6 + (ref.cast i31ref + (local.get $0) + ) + (struct.new $type_6 + (ref.i31 + (i32.const 1) + ) + (struct.new $type_6 + (ref.i31 + (i32.const 2) + ) + (struct.new $type_6 + (ref.i31 + (i32.const 3) + ) + (ref.null none) + ) + ) + ) + ) + ) + ) ) (module + (type $type_6 (struct (field i31ref) (field (ref null $type_6)))) + (type $type_5 (array (mut i8))) + (type $type_7 (func (result anyref anyref))) (type $type (func (param anyref i32 i32) (result i32))) (type $type_1 (func (param i32 i32) (result i32))) (type $type_2 (func)) (type $type_3 (func (param anyref) (result i32))) + (type $type_4 (func (param anyref) (result anyref anyref))) (import "future-wasi" "write" (func $fimport$0 (type $type) (param anyref i32 i32) (result i32))) (memory $0 1) (data $0 (i32.const 0) "hello") @@ -178,6 +315,7 @@ (export "adder" (func $0)) (export "memory" (memory $0)) (export "hello" (func $2)) + (export "gc" (func $3)) (start $1) (func $0 (type $type_1) (param $0 i32) (param $1 i32) (result i32) local.get $0 @@ -204,4 +342,29 @@ i32.const 1 call $fimport$0 ) + (func $3 (type $type_4) (param $0 anyref) (result anyref anyref) + (local $1 (ref $type_5)) + i32.const 0 + i32.const 255 + array.new_fixed $type_5 2 + local.tee $1 + i32.const 1 + i32.const 42 + array.set $type_5 + local.get $1 + local.get $0 + ref.cast i31ref + i32.const 1 + ref.i31 + i32.const 2 + ref.i31 + i32.const 3 + ref.i31 + ref.null none + struct.new $type_6 + struct.new $type_6 + struct.new $type_6 + struct.new $type_6 + tuple.make 2 + ) ) diff --git a/test/test.ml b/test/test.ml index a5ef4e90..2559233d 100644 --- a/test/test.ml +++ b/test/test.ml @@ -254,6 +254,19 @@ let _ = (Memory.get_segment_data wasm_mod "world") (Bytes.of_string "world")) +(* Call_ref *) +let thunk_type = + let builder = Type_builder.make 1 in + Type_builder.set_signature_type builder 0 Type.none Type.none; + match Type_builder.build_and_dispose builder with + | Ok [ ty ] -> ty + | _ -> failwith "failed to build type" + +let _ = + Expression.Call_ref.make wasm_mod + (Expression.Ref.func wasm_mod "start" thunk_type) + [] Type.none + (* Create an imported "write" function i32 (externref, i32, i32) *) (* Similar to the example here: https://bytecodealliance.org/articles/reference-types-in-wasmtime *) @@ -274,7 +287,79 @@ let _ = Type.int32) let _ = Export.add_function_export wasm_mod "hello" "hello" -let _ = Module.validate wasm_mod + +(* Create a function that does gc *) +let _ = + let array_u8_type = + let builder = Type_builder.make 1 in + Type_builder.set_array_type builder 0 Type.int32 Packed_type.int8 true; + match Type_builder.build_and_dispose builder with + | Ok [ ty ] -> ty + | _ -> failwith "failed to make array type" + in + let list_type = + let builder = Type_builder.make 1 in + let temp_heap_type = Type_builder.get_temp_heap_type builder 0 in + let temp_ref_type = + Type_builder.get_temp_ref_type builder temp_heap_type true + in + Type_builder.set_struct_type builder 0 + [ + Type_builder. + { + type_ = Type.i31ref; + packed_type = Packed_type.not_packed; + mutable_ = false; + }; + Type_builder. + { + type_ = temp_ref_type; + packed_type = Packed_type.not_packed; + mutable_ = false; + }; + ]; + match Type_builder.build_and_dispose builder with + | Ok [ ty ] -> ty + | _ -> failwith "failed to make list type" + in + let i32 v = Expression.Const.make wasm_mod (Literal.int32 v) in + let i31 v = Expression.I31.make wasm_mod (i32 v) in + let cons first rest = + Expression.Struct.new_ wasm_mod + (Some [ first; rest ]) + (Type.get_heap_type list_type) + in + let empty () = + Expression.Ref.null wasm_mod + (Type.from_heap_type (Type.get_heap_type list_type) true) + in + Function.add_function wasm_mod "gc" Type.anyref + (Type.create [| Type.anyref; Type.anyref |]) + [| array_u8_type; list_type |] + (Expression.Block.make wasm_mod "gc_block" + [ + Expression.Local_set.make wasm_mod 1 + (Expression.Array.new_fixed wasm_mod + (Type.get_heap_type array_u8_type) + [ i32 0l; i32 255l ]); + Expression.Array.set wasm_mod + (Expression.Local_get.make wasm_mod 1 array_u8_type) + (i32 1l) (i32 42l); + Expression.Local_set.make wasm_mod 2 + (cons + (Expression.Ref.cast wasm_mod + (Expression.Local_get.make wasm_mod 0 Type.anyref) + Type.i31ref) + (cons (i31 1l) (cons (i31 2l) (cons (i31 3l) (empty ()))))); + Expression.Tuple_make.make wasm_mod + [ + Expression.Local_get.make wasm_mod 1 array_u8_type; + Expression.Local_get.make wasm_mod 2 list_type; + ]; + ]) + +let _ = Export.add_function_export wasm_mod "gc" "gc" +let _ = assert (Module.validate wasm_mod == 1) (* Shouldn't actually do anything since we aren't doing function renames *) let _ = Module.update_maps wasm_mod @@ -348,7 +433,7 @@ let _ = Module.Feature.all; ] -let _ = Module.validate new_mod +let _ = assert (Module.validate new_mod == 1) let _ = Module.print new_mod let _ = Module.print_stack_ir new_mod From d89bf1f62dd535a13d56b0d1c3f4ce486086ec0a Mon Sep 17 00:00:00 2001 From: Spotandjake Date: Fri, 5 Dec 2025 10:49:06 -0500 Subject: [PATCH 3/7] feat: Implement additional gc instructions --- src/expression.c | 24 ++++++++++++++++++++++++ src/expression.js | 36 ++++++++++++++++++++++-------------- src/expression.ml | 8 ++++++++ src/expression.mli | 6 ++++++ src/type_builder.ml | 8 +++++--- src/type_builder.mli | 5 +++-- test/test.expected | 8 ++++---- test/test.ml | 24 +++++++++++++----------- 8 files changed, 85 insertions(+), 34 deletions(-) diff --git a/src/expression.c b/src/expression.c index 737a0124..e6dfa4f2 100644 --- a/src/expression.c +++ b/src/expression.c @@ -2086,6 +2086,18 @@ caml_binaryen_array_new_data(value _module, value _type, value _name, value _off CAMLreturn(alloc_BinaryenExpressionRef(exp)); } +CAMLprim value +caml_binaryen_array_new_elem(value _module, value _type, value _seg, value _offset, value _size) { + CAMLparam5(_module, _type, _seg, _offset, _size); + BinaryenModuleRef module = BinaryenModuleRef_val(_module); + BinaryenHeapType type = BinaryenHeapType_val(_type); + char* seg = Safe_String_val(_seg); + BinaryenExpressionRef offset = BinaryenExpressionRef_val(_offset); + BinaryenExpressionRef size = BinaryenExpressionRef_val(_size); + BinaryenExpressionRef exp = BinaryenArrayNewElem(module, type, seg, offset, size); + CAMLreturn(alloc_BinaryenExpressionRef(exp)); +} + CAMLprim value caml_binaryen_array_new_fixed(value _module, value _type, value _values) { CAMLparam3(_module, _type, _values); @@ -2151,6 +2163,18 @@ caml_binaryen_array_copy__bytecode(value * argv) { return caml_binaryen_array_copy(argv[0], argv[1], argv[2], argv[3], argv[4], argv[5]); } +CAMLprim value +caml_binaryen_array_fill(value _module, value _ref, value _index, value _value, value _size) { + CAMLparam5(_module, _ref, _index, _value, _size); + BinaryenModuleRef module = BinaryenModuleRef_val(_module); + BinaryenExpressionRef ref = BinaryenExpressionRef_val(_ref); + BinaryenExpressionRef index = BinaryenExpressionRef_val(_index); + BinaryenExpressionRef val = BinaryenExpressionRef_val(_value); + BinaryenExpressionRef size = BinaryenExpressionRef_val(_size); + BinaryenExpressionRef exp = BinaryenArrayFill(module, ref, index, val, size); + CAMLreturn(alloc_BinaryenExpressionRef(exp)); +} + // Table operations CAMLprim value caml_binaryen_table_get(value _module, value _name, value _index, value _ty) { diff --git a/src/expression.js b/src/expression.js index 8fb33be1..d9116f29 100644 --- a/src/expression.js +++ b/src/expression.js @@ -575,13 +575,13 @@ function caml_binaryen_ref_cast(wasm_mod, ref, typ) { function caml_binaryen_br_on(wasm_mod, op, name, ref, typ) { switch (op) { case Binaryen.BrOnNull: - return wasm_mod.br_on.null(caml_jsstring_of_string(name), ref, typ); + return wasm_mod.br_on_null(caml_jsstring_of_string(name), ref); case Binaryen.BrOnNonNull: - return wasm_mod.br_on.non_null(caml_jsstring_of_string(name), ref, typ); + return wasm_mod.br_on_non_null(caml_jsstring_of_string(name), ref); case Binaryen.BrOnCast: - return wasm_mod.br_on.cast(caml_jsstring_of_string(name), ref, typ); + return wasm_mod.br_on_cast(caml_jsstring_of_string(name), ref, typ); case Binaryen.BrOnCastFail: - return wasm_mod.br_on.cast_fail(caml_jsstring_of_string(name), ref, typ); + return wasm_mod.br_on_cast_fail(caml_jsstring_of_string(name), ref, typ); } } @@ -1821,11 +1821,7 @@ function caml_binaryen_struct_new(wasm_mod, operands, type) { //Provides: caml_binaryen_struct_get //Requires: caml_js_from_bool function caml_binaryen_struct_get(wasm_mod, index, ref, type, signed) { - if (caml_js_from_bool(signed)) { - return wasm_mod.struct.get_s(index, ref, type); - } else { - return wasm_mod.struct.get_u(index, ref, type); - } + return wasm_mod.struct.get(index, ref, type, caml_js_from_bool(signed)); } //Provides: caml_binaryen_struct_set @@ -1851,6 +1847,17 @@ function caml_binaryen_array_new_data(wasm_mod, type, name, offset, size) { ); } +//Provides: caml_binaryen_array_new_elem +//Requires: caml_jsstring_of_string +function caml_binaryen_array_new_elem(wasm_mod, type, name, offset, size) { + return wasm_mod.array.new_elem( + type, + caml_jsstring_of_string(name), + offset, + size + ); +} + //Provides: caml_binaryen_array_new_fixed //Requires: caml_list_to_js_array function caml_binaryen_array_new_fixed(wasm_mod, type, values) { @@ -1860,11 +1867,7 @@ function caml_binaryen_array_new_fixed(wasm_mod, type, values) { //Provides: caml_binaryen_array_get //Requires: caml_js_from_bool function caml_binaryen_array_get(wasm_mod, ref, index, type, signed) { - if (caml_js_from_bool(signed)) { - return wasm_mod.array.get_s(ref, index, type); - } else { - return wasm_mod.array.get_u(ref, index, type); - } + return wasm_mod.array.get(ref, index, type, caml_js_from_bool(signed)); } //Provides: caml_binaryen_array_set @@ -1877,6 +1880,11 @@ function caml_binaryen_array_len(wasm_mod, ref) { return wasm_mod.array.len(ref); } +//Provides: caml_binaryen_array_fill +function caml_binaryen_array_fill(wasm_mod, ref, index, value, size) { + return wasm_mod.array.fill(ref, index, value, size); +} + //Provides: caml_binaryen_array_copy function caml_binaryen_array_copy( wasm_mod, diff --git a/src/expression.ml b/src/expression.ml index 423f16f2..0b02a43c 100644 --- a/src/expression.ml +++ b/src/expression.ml @@ -899,6 +899,10 @@ module Array = struct = "caml_binaryen_array_new_data" (** Module, type, data name, offset, size *) + external new_elem : Module.t -> Heap_type.t -> string -> t -> t -> t + = "caml_binaryen_array_new_elem" + (** Module, type, seg, offset, size *) + external new_fixed : Module.t -> Heap_type.t -> t list -> t = "caml_binaryen_array_new_fixed" (** Module, type, values *) @@ -913,6 +917,10 @@ module Array = struct external len : Module.t -> t -> t = "caml_binaryen_array_len" (** Module, array *) + external fill : Module.t -> Heap_type.t -> t -> t -> t -> t + = "caml_binaryen_array_fill" + (** Module, type, seg, offset, size *) + external copy : Module.t -> t -> t -> t -> t -> t -> t = "caml_binaryen_array_copy__bytecode" "caml_binaryen_array_copy" (** Module, dest, dest index, src, src index, length *) diff --git a/src/expression.mli b/src/expression.mli index 60370583..76d3a284 100644 --- a/src/expression.mli +++ b/src/expression.mli @@ -394,6 +394,9 @@ module Array : sig val new_data : Module.t -> Heap_type.t -> string -> t -> t -> t (** Module, type, data name, offset, size *) + val new_elem : Module.t -> Heap_type.t -> string -> t -> t -> t + (** Module, type, seg, offset, size *) + val new_fixed : Module.t -> Heap_type.t -> t list -> t (** Module, type, values *) @@ -406,6 +409,9 @@ module Array : sig val len : Module.t -> t -> t (** Module, array *) + val fill : Module.t -> Heap_type.t -> t -> t -> t -> t + (** Module, type, seg, offset, size *) + val copy : Module.t -> t -> t -> t -> t -> t -> t (** Module, dest, dest index, src, src index, length *) end diff --git a/src/type_builder.ml b/src/type_builder.ml index 0d72d937..28f33b03 100644 --- a/src/type_builder.ml +++ b/src/type_builder.ml @@ -6,6 +6,7 @@ type struct_field = { mutable_ : bool; } +(* Source: https://github.com/WebAssembly/binaryen/blob/64ba23996a10e229d46e41eb37736a55af87f79a/src/binaryen-c.h#L3618 *) type error = | SelfSupertype of int | InvalidSupertype of int @@ -21,7 +22,8 @@ external set_signature_type : t -> int -> Type.t -> Type.t -> unit external set_struct_type : t -> int -> Type.t list -> Packed_type.t list -> bool list -> int -> unit - = "caml_type_builder_set_struct_type__bytecode" "caml_type_builder_set_struct_type" + = "caml_type_builder_set_struct_type__bytecode" + "caml_type_builder_set_struct_type" let set_struct_type builder index fields = let split_fields fields = @@ -45,7 +47,7 @@ external get_temp_tuple_type : t -> Type.t list -> Type.t external get_temp_ref_type : t -> Heap_type.t -> bool -> Type.t = "caml_type_builder_get_temp_ref_type" -external set_sub_type : t -> int -> Type.t -> unit +external set_sub_type : t -> int -> Heap_type.t -> unit = "caml_type_builder_set_sub_type" external set_open : t -> int -> unit = "caml_type_builder_set_open" @@ -53,7 +55,7 @@ external set_open : t -> int -> unit = "caml_type_builder_set_open" external create_rec_group : t -> int -> int -> unit = "caml_type_builder_create_rec_group" -external build_and_dispose : t -> (Type.t array, int * int) result +external build_and_dispose : t -> (Heap_type.t array, int * int) result = "caml_type_builder_build_and_dispose" let build_and_dispose builder = diff --git a/src/type_builder.mli b/src/type_builder.mli index 260458db..f76dfbb1 100644 --- a/src/type_builder.mli +++ b/src/type_builder.mli @@ -6,6 +6,7 @@ type struct_field = { mutable_ : bool; } +(* Source: https://github.com/WebAssembly/binaryen/blob/64ba23996a10e229d46e41eb37736a55af87f79a/src/binaryen-c.h#L3618 *) type error = | SelfSupertype of int | InvalidSupertype of int @@ -21,7 +22,7 @@ val set_array_type : t -> int -> Type.t -> Packed_type.t -> bool -> unit val get_temp_heap_type : t -> int -> Heap_type.t val get_temp_tuple_type : t -> Type.t list -> Type.t val get_temp_ref_type : t -> Heap_type.t -> bool -> Type.t -val set_sub_type : t -> int -> Type.t -> unit +val set_sub_type : t -> int -> Heap_type.t -> unit val set_open : t -> int -> unit val create_rec_group : t -> int -> int -> unit -val build_and_dispose : t -> (Type.t list, error) result +val build_and_dispose : t -> (Heap_type.t list, error) result diff --git a/test/test.expected b/test/test.expected index 206ecb4d..e20db52c 100644 --- a/test/test.expected +++ b/test/test.expected @@ -120,7 +120,7 @@ (module (type $0 (struct (field i31ref) (field (ref null $0)))) (type $1 (array (mut i8))) - (type $2 (func (result (ref $1) (ref $0)))) + (type $2 (func (result (ref (exact $1)) (ref (exact $0))))) (type $3 (func (param i32 i32) (result i32))) (type $4 (func)) (type $5 (func (param anyref i32 i32) (result i32))) @@ -170,7 +170,7 @@ ) ) (func $gc (type $7) (param $0 anyref) (result anyref anyref) - (local $1 (ref $1)) + (local $1 (ref (exact $1))) (array.set $1 (local.tee $1 (array.new_fixed $1 2 @@ -260,7 +260,7 @@ ) ) (func $3 (type $type_4) (param $0 anyref) (result anyref anyref) - (local $1 (ref $type_5)) + (local $1 (ref (exact $type_5))) (array.set $type_5 (local.tee $1 (array.new_fixed $type_5 2 @@ -343,7 +343,7 @@ call $fimport$0 ) (func $3 (type $type_4) (param $0 anyref) (result anyref anyref) - (local $1 (ref $type_5)) + (local $1 (ref (exact $type_5))) i32.const 0 i32.const 255 array.new_fixed $type_5 2 diff --git a/test/test.ml b/test/test.ml index 2559233d..6a0546b7 100644 --- a/test/test.ml +++ b/test/test.ml @@ -325,25 +325,25 @@ let _ = let i32 v = Expression.Const.make wasm_mod (Literal.int32 v) in let i31 v = Expression.I31.make wasm_mod (i32 v) in let cons first rest = - Expression.Struct.new_ wasm_mod - (Some [ first; rest ]) - (Type.get_heap_type list_type) + Expression.Struct.new_ wasm_mod (Some [ first; rest ]) list_type in let empty () = - Expression.Ref.null wasm_mod - (Type.from_heap_type (Type.get_heap_type list_type) true) + Expression.Ref.null wasm_mod (Type.from_heap_type list_type true) in Function.add_function wasm_mod "gc" Type.anyref (Type.create [| Type.anyref; Type.anyref |]) - [| array_u8_type; list_type |] + [| + Type.from_heap_type array_u8_type false; + Type.from_heap_type list_type false; + |] (Expression.Block.make wasm_mod "gc_block" [ Expression.Local_set.make wasm_mod 1 - (Expression.Array.new_fixed wasm_mod - (Type.get_heap_type array_u8_type) + (Expression.Array.new_fixed wasm_mod array_u8_type [ i32 0l; i32 255l ]); Expression.Array.set wasm_mod - (Expression.Local_get.make wasm_mod 1 array_u8_type) + (Expression.Local_get.make wasm_mod 1 + (Type.from_heap_type array_u8_type false)) (i32 1l) (i32 42l); Expression.Local_set.make wasm_mod 2 (cons @@ -353,8 +353,10 @@ let _ = (cons (i31 1l) (cons (i31 2l) (cons (i31 3l) (empty ()))))); Expression.Tuple_make.make wasm_mod [ - Expression.Local_get.make wasm_mod 1 array_u8_type; - Expression.Local_get.make wasm_mod 2 list_type; + Expression.Local_get.make wasm_mod 1 + (Type.from_heap_type array_u8_type false); + Expression.Local_get.make wasm_mod 2 + (Type.from_heap_type list_type false); ]; ]) From cf67e0fea1ed87ea55882873c33f5fe735710335 Mon Sep 17 00:00:00 2001 From: Spotandjake Date: Fri, 5 Dec 2025 16:00:57 -0500 Subject: [PATCH 4/7] chore: Re-enable funcref test --- test/test.ml | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/test/test.ml b/test/test.ml index 6a0546b7..4cc5d1b0 100644 --- a/test/test.ml +++ b/test/test.ml @@ -171,13 +171,19 @@ let start = let _ = Export.add_function_export wasm_mod "adder" "adder" let _ = Table.add_table wasm_mod "table" 1 1 Type.funcref -(* TODO(#240): Re-enable after type-builder api is merged *) -(* let funcref_expr1 = Expression.Ref.func wasm_mod "adder" (Heap_type.func ()) +let adder_type = + let builder = Type_builder.make 1 in + Type_builder.set_signature_type builder 0 Type.none Type.none; + match Type_builder.build_and_dispose builder with + | Ok [ ty ] -> ty + | _ -> failwith "failed to build type" + +let funcref_expr1 = Expression.Ref.func wasm_mod "adder" adder_type let _ = Expression.Table.set wasm_mod "table" (Expression.Const.make wasm_mod (Literal.int32 0l)) - funcref_expr1 *) + funcref_expr1 let funcref_expr2 = Expression.Table.get wasm_mod "table" From ad2abd8101de56ae0e8784b643cf72e16cdbb93f Mon Sep 17 00:00:00 2001 From: Spotandjake Date: Fri, 5 Dec 2025 16:16:41 -0500 Subject: [PATCH 5/7] feat: Implement `Array.init_data` and `Array.init_elem` --- src/expression.c | 38 ++++++++++++++++++++++++++++++++++++++ src/expression.js | 13 +++++++++++++ src/expression.ml | 8 ++++++++ src/expression.mli | 6 ++++++ 4 files changed, 65 insertions(+) diff --git a/src/expression.c b/src/expression.c index e6dfa4f2..008a26d6 100644 --- a/src/expression.c +++ b/src/expression.c @@ -2175,6 +2175,44 @@ caml_binaryen_array_fill(value _module, value _ref, value _index, value _value, CAMLreturn(alloc_BinaryenExpressionRef(exp)); } +CAMLprim value +caml_binaryen_array_init_data(value _module, value _name, value _ref, value _index, value _offset, value _size) { + CAMLparam5(_module, _name, _ref, _index, _offset); + CAMLxparam1(_size); + BinaryenModuleRef module = BinaryenModuleRef_val(_module); + char* name = Safe_String_val(_name); + BinaryenExpressionRef ref = BinaryenExpressionRef_val(_ref); + BinaryenExpressionRef index = BinaryenExpressionRef_val(_index); + BinaryenExpressionRef offset = BinaryenExpressionRef_val(_offset); + BinaryenExpressionRef size = BinaryenExpressionRef_val(_size); + BinaryenExpressionRef exp = BinaryenArrayInitData(module, name, ref, index, offset, size); + CAMLreturn(alloc_BinaryenExpressionRef(exp)); +} + +CAMLprim value +caml_binaryen_array_init_data__bytecode(value * argv) { + return caml_binaryen_array_init_data(argv[0], argv[1], argv[2], argv[3], argv[4], argv[5]); +} + +CAMLprim value +caml_binaryen_array_init_elem(value _module, value _seg, value _ref, value _index, value _offset, value _size) { + CAMLparam5(_module, _seg, _ref, _index, _offset); + CAMLxparam1(_size); + BinaryenModuleRef module = BinaryenModuleRef_val(_module); + char* seg = Safe_String_val(_seg); + BinaryenExpressionRef ref = BinaryenExpressionRef_val(_ref); + BinaryenExpressionRef index = BinaryenExpressionRef_val(_index); + BinaryenExpressionRef offset = BinaryenExpressionRef_val(_offset); + BinaryenExpressionRef size = BinaryenExpressionRef_val(_size); + BinaryenExpressionRef exp = BinaryenArrayInitElem(module, seg, ref, index, offset, size); + CAMLreturn(alloc_BinaryenExpressionRef(exp)); +} + +CAMLprim value +caml_binaryen_array_init_elem__bytecode(value * argv) { + return caml_binaryen_array_init_elem(argv[0], argv[1], argv[2], argv[3], argv[4], argv[5]); +} + // Table operations CAMLprim value caml_binaryen_table_get(value _module, value _name, value _index, value _ty) { diff --git a/src/expression.js b/src/expression.js index d9116f29..fba5be26 100644 --- a/src/expression.js +++ b/src/expression.js @@ -1896,6 +1896,19 @@ function caml_binaryen_array_copy( ) { return wasm_mod.array.copy(destRef, destIndex, srcRef, srcIndex, length); } + +//Provides: caml_binaryen_array_init_data +//Requires: caml_jsstring_of_string +function caml_binaryen_array_init_data(name, ref, index, offset, size) { + return wasm_mod.array.init_data(caml_jsstring_of_string(name), ref, index, offset, size); +} + +//Provides: caml_binaryen_array_init_elem +//Requires: caml_jsstring_of_string +function caml_binaryen_array_init_elem(name, ref, index, offset, size) { + return wasm_mod.array.init_elem(caml_jsstring_of_string(name), ref, index, offset, size); +} + //Provides: caml_binaryen_array_copy__bytecode //Requires: caml_binaryen_array_copy function caml_binaryen_array_copy__bytecode() { diff --git a/src/expression.ml b/src/expression.ml index 0b02a43c..559939b5 100644 --- a/src/expression.ml +++ b/src/expression.ml @@ -924,6 +924,14 @@ module Array = struct external copy : Module.t -> t -> t -> t -> t -> t -> t = "caml_binaryen_array_copy__bytecode" "caml_binaryen_array_copy" (** Module, dest, dest index, src, src index, length *) + + external init_data : Module.t -> string -> t -> t -> t -> t -> t + = "caml_binaryen_array_init_data__bytecode" "caml_binaryen_array_init_data" + (** Module, name, ref, index, offset, size *) + + external init_elem : Module.t -> string -> t -> t -> t -> t -> t + = "caml_binaryen_array_init_elem__bytecode" "caml_binaryen_array_init_elem" + (** Module, seg, ref, index, offset, size *) end module Table = struct diff --git a/src/expression.mli b/src/expression.mli index 76d3a284..60b6a15f 100644 --- a/src/expression.mli +++ b/src/expression.mli @@ -414,6 +414,12 @@ module Array : sig val copy : Module.t -> t -> t -> t -> t -> t -> t (** Module, dest, dest index, src, src index, length *) + + val init_data : Module.t -> string -> t -> t -> t -> t -> t + (** Module, name, ref, index, offset, size *) + + val init_elem : Module.t -> string -> t -> t -> t -> t -> t + (** Module, seg, ref, index, offset, size *) end module Table : sig From 12f6d7eb959f07d26019bd94b016a5b7aeacdc9b Mon Sep 17 00:00:00 2001 From: Spotandjake Date: Sat, 13 Dec 2025 12:19:22 -0500 Subject: [PATCH 6/7] feat: Update `CallRef` bindings for `v126` --- src/expression.js | 19 +++++++++++++------ test/test.ml | 2 +- 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/src/expression.js b/src/expression.js index fba5be26..b88943d6 100644 --- a/src/expression.js +++ b/src/expression.js @@ -105,12 +105,19 @@ function caml_binaryen_call_indirect__bytecode() { //Requires: caml_jsstring_of_string //Requires: caml_list_to_js_array, caml_js_from_bool function caml_binaryen_call_ref(wasm_mod, target, params, typ, is_return) { - return wasm_mod.call_ref( - target, - caml_list_to_js_array(params), - typ, - caml_js_from_bool(is_return) - ); + if (caml_js_from_bool(is_return)) { + return wasm_mod.return_call_ref( + target, + caml_list_to_js_array(params), + typ + ); + } else { + return wasm_mod.call_ref( + target, + caml_list_to_js_array(params), + typ + ); + } } //Provides: caml_binaryen_return_call diff --git a/test/test.ml b/test/test.ml index 4cc5d1b0..a6b89f6e 100644 --- a/test/test.ml +++ b/test/test.ml @@ -173,7 +173,7 @@ let _ = Table.add_table wasm_mod "table" 1 1 Type.funcref let adder_type = let builder = Type_builder.make 1 in - Type_builder.set_signature_type builder 0 Type.none Type.none; + Type_builder.set_signature_type builder 0 (params ()) results; match Type_builder.build_and_dispose builder with | Ok [ ty ] -> ty | _ -> failwith "failed to build type" From bf67f1131f1c19553df77ad513213156bc5db9e2 Mon Sep 17 00:00:00 2001 From: Spotandjake Date: Sat, 13 Dec 2025 12:46:44 -0500 Subject: [PATCH 7/7] chore: Use preview `v126` libbinaryen --- esy.lock/index.json | 94 +++++++++---------- esy.lock/opam/base.v0.17.3/opam | 6 +- .../opam/ocaml_intrinsics_kernel.v0.17.1/opam | 2 + esy.lock/opam/ocamlfind.1.9.8/opam | 2 +- .../opam/ppx_yojson_conv_lib.v0.17.0/opam | 2 + esy.lock/opam/sexplib0.v0.17.0/opam | 2 + esy.lock/opam/stdio.v0.17.0/opam | 4 +- package.json | 3 +- 8 files changed, 63 insertions(+), 52 deletions(-) diff --git a/esy.lock/index.json b/esy.lock/index.json index 637fbaaf..072d60b3 100644 --- a/esy.lock/index.json +++ b/esy.lock/index.json @@ -1,5 +1,5 @@ { - "checksum": "43b607828957b76c0263dc0b329d0237", + "checksum": "fbb4f4567dbe5512b5e9d459824bf7d6", "root": "@grain/binaryen.ml@link-dev:./package.json", "node": { "ocaml@5.3.0@d41d8cd9": { @@ -103,7 +103,7 @@ "overrides": [], "dependencies": [ "ocaml@5.3.0@d41d8cd9", "@opam/topkg@opam:1.1.1@2377d2f8", - "@opam/ocamlfind@opam:1.9.8@ee910ff5", + "@opam/ocamlfind@opam:1.9.8@4b291364", "@opam/ocamlbuild@opam:0.16.1@b3fc8209", "@opam/cmdliner@opam:1.3.0@8e6dd99f", "@esy-ocaml/substs@0.0.1@d41d8cd9" @@ -136,7 +136,7 @@ "dependencies": [ "ocaml@5.3.0@d41d8cd9", "@opam/uutf@opam:1.0.4@ba7fbef7", "@opam/uucp@opam:17.0.0@843de755", "@opam/topkg@opam:1.1.1@2377d2f8", - "@opam/ocamlfind@opam:1.9.8@ee910ff5", + "@opam/ocamlfind@opam:1.9.8@4b291364", "@opam/ocamlbuild@opam:0.16.1@b3fc8209", "@opam/cmdliner@opam:1.3.0@8e6dd99f", "@esy-ocaml/substs@0.0.1@d41d8cd9" @@ -170,7 +170,7 @@ "overrides": [], "dependencies": [ "ocaml@5.3.0@d41d8cd9", "@opam/topkg@opam:1.1.1@2377d2f8", - "@opam/ocamlfind@opam:1.9.8@ee910ff5", + "@opam/ocamlfind@opam:1.9.8@4b291364", "@opam/ocamlbuild@opam:0.16.1@b3fc8209", "@opam/cmdliner@opam:1.3.0@8e6dd99f", "@esy-ocaml/substs@0.0.1@d41d8cd9" @@ -201,7 +201,7 @@ }, "overrides": [], "dependencies": [ - "ocaml@5.3.0@d41d8cd9", "@opam/ocamlfind@opam:1.9.8@ee910ff5", + "ocaml@5.3.0@d41d8cd9", "@opam/ocamlfind@opam:1.9.8@4b291364", "@opam/ocamlbuild@opam:0.16.1@b3fc8209", "@esy-ocaml/substs@0.0.1@d41d8cd9" ], @@ -285,8 +285,8 @@ [ "windows", "x86_64" ] ] }, - "@opam/stdio@opam:v0.17.0@def6a62f": { - "id": "@opam/stdio@opam:v0.17.0@def6a62f", + "@opam/stdio@opam:v0.17.0@80c625cc": { + "id": "@opam/stdio@opam:v0.17.0@80c625cc", "name": "@opam/stdio", "version": "opam:v0.17.0", "source": { @@ -304,12 +304,12 @@ "overrides": [], "dependencies": [ "ocaml@5.3.0@d41d8cd9", "@opam/dune@opam:3.20.2@8daef28d", - "@opam/base@opam:v0.17.3@78923773", + "@opam/base@opam:v0.17.3@4f79f92d", "@esy-ocaml/substs@0.0.1@d41d8cd9" ], "devDependencies": [ "ocaml@5.3.0@d41d8cd9", "@opam/dune@opam:3.20.2@8daef28d", - "@opam/base@opam:v0.17.3@78923773" + "@opam/base@opam:v0.17.3@4f79f92d" ], "available": [ [ "darwin", "x86_64" ], @@ -349,8 +349,8 @@ [ "windows", "x86_64" ] ] }, - "@opam/sexplib0@opam:v0.17.0@75dcb697": { - "id": "@opam/sexplib0@opam:v0.17.0@75dcb697", + "@opam/sexplib0@opam:v0.17.0@db8af2c0": { + "id": "@opam/sexplib0@opam:v0.17.0@db8af2c0", "name": "@opam/sexplib0", "version": "opam:v0.17.0", "source": { @@ -500,14 +500,14 @@ "overrides": [], "dependencies": [ "ocaml@5.3.0@d41d8cd9", "@opam/stdlib-shims@opam:0.3.0@72c7bc98", - "@opam/sexplib0@opam:v0.17.0@75dcb697", + "@opam/sexplib0@opam:v0.17.0@db8af2c0", "@opam/ppx_derivers@opam:1.2.1@d78727cd", "@opam/ocaml-compiler-libs@opam:v0.17.0@6bdcfede", "@opam/dune@opam:3.20.2@8daef28d", "@esy-ocaml/substs@0.0.1@d41d8cd9" ], "devDependencies": [ "ocaml@5.3.0@d41d8cd9", "@opam/stdlib-shims@opam:0.3.0@72c7bc98", - "@opam/sexplib0@opam:v0.17.0@75dcb697", + "@opam/sexplib0@opam:v0.17.0@db8af2c0", "@opam/ppx_derivers@opam:1.2.1@d78727cd", "@opam/ocaml-compiler-libs@opam:v0.17.0@6bdcfede", "@opam/dune@opam:3.20.2@8daef28d" @@ -519,8 +519,8 @@ [ "windows", "x86_64" ] ] }, - "@opam/ppx_yojson_conv_lib@opam:v0.17.0@2b444c0e": { - "id": "@opam/ppx_yojson_conv_lib@opam:v0.17.0@2b444c0e", + "@opam/ppx_yojson_conv_lib@opam:v0.17.0@e7e988bb": { + "id": "@opam/ppx_yojson_conv_lib@opam:v0.17.0@e7e988bb", "name": "@opam/ppx_yojson_conv_lib", "version": "opam:v0.17.0", "source": { @@ -662,14 +662,14 @@ }, "overrides": [], "dependencies": [ - "ocaml@5.3.0@d41d8cd9", "@opam/ocamlfind@opam:1.9.8@ee910ff5", + "ocaml@5.3.0@d41d8cd9", "@opam/ocamlfind@opam:1.9.8@4b291364", "@opam/dune@opam:3.20.2@8daef28d", "@opam/cmdliner@opam:1.3.0@8e6dd99f", "@opam/base-bytes@opam:base@785dbd33", "@esy-ocaml/substs@0.0.1@d41d8cd9" ], "devDependencies": [ - "ocaml@5.3.0@d41d8cd9", "@opam/ocamlfind@opam:1.9.8@ee910ff5", + "ocaml@5.3.0@d41d8cd9", "@opam/ocamlfind@opam:1.9.8@4b291364", "@opam/dune@opam:3.20.2@8daef28d", "@opam/cmdliner@opam:1.3.0@8e6dd99f", "@opam/base-bytes@opam:base@785dbd33" @@ -733,7 +733,7 @@ "dependencies": [ "ocaml@5.3.0@d41d8cd9", "@opam/uutf@opam:1.0.4@ba7fbef7", "@opam/uuseg@opam:17.0.0@52f3d276", - "@opam/stdio@opam:v0.17.0@def6a62f", + "@opam/stdio@opam:v0.17.0@80c625cc", "@opam/ocp-indent@opam:1.7.0@3e255333", "@opam/ocaml-version@opam:4.0.3@371c2527", "@opam/menhirSdk@opam:20250912@f434747d", @@ -746,14 +746,14 @@ "@opam/dune@opam:3.20.2@8daef28d", "@opam/csexp@opam:1.5.2@46614bf4", "@opam/cmdliner@opam:1.3.0@8e6dd99f", "@opam/camlp-streams@opam:5.0.1@8e96208c", - "@opam/base@opam:v0.17.3@78923773", + "@opam/base@opam:v0.17.3@4f79f92d", "@opam/astring@opam:0.8.5@9975798d", "@esy-ocaml/substs@0.0.1@d41d8cd9" ], "devDependencies": [ "ocaml@5.3.0@d41d8cd9", "@opam/uutf@opam:1.0.4@ba7fbef7", "@opam/uuseg@opam:17.0.0@52f3d276", - "@opam/stdio@opam:v0.17.0@def6a62f", + "@opam/stdio@opam:v0.17.0@80c625cc", "@opam/ocp-indent@opam:1.7.0@3e255333", "@opam/ocaml-version@opam:4.0.3@371c2527", "@opam/menhirSdk@opam:20250912@f434747d", @@ -766,7 +766,7 @@ "@opam/dune@opam:3.20.2@8daef28d", "@opam/csexp@opam:1.5.2@46614bf4", "@opam/cmdliner@opam:1.3.0@8e6dd99f", "@opam/camlp-streams@opam:5.0.1@8e96208c", - "@opam/base@opam:v0.17.3@78923773", + "@opam/base@opam:v0.17.3@4f79f92d", "@opam/astring@opam:0.8.5@9975798d" ], "available": [ @@ -813,8 +813,8 @@ [ "windows", "x86_64" ] ] }, - "@opam/ocamlfind@opam:1.9.8@ee910ff5": { - "id": "@opam/ocamlfind@opam:1.9.8@ee910ff5", + "@opam/ocamlfind@opam:1.9.8@4b291364": { + "id": "@opam/ocamlfind@opam:1.9.8@4b291364", "name": "@opam/ocamlfind", "version": "opam:1.9.8", "source": { @@ -905,8 +905,8 @@ [ "windows", "x86_64" ] ] }, - "@opam/ocaml_intrinsics_kernel@opam:v0.17.1@122c1c73": { - "id": "@opam/ocaml_intrinsics_kernel@opam:v0.17.1@122c1c73", + "@opam/ocaml_intrinsics_kernel@opam:v0.17.1@ec48e72b": { + "id": "@opam/ocaml_intrinsics_kernel@opam:v0.17.1@ec48e72b", "name": "@opam/ocaml_intrinsics_kernel", "version": "opam:v0.17.1", "source": { @@ -989,7 +989,7 @@ "@opam/xdg@opam:3.20.2@ade9ef81", "@opam/stdune@opam:3.20.2@c89dc074", "@opam/spawn@opam:v0.17.0@d0f69739", "@opam/re@opam:1.14.0@62aa9f42", - "@opam/ppx_yojson_conv_lib@opam:v0.17.0@2b444c0e", + "@opam/ppx_yojson_conv_lib@opam:v0.17.0@e7e988bb", "@opam/pp@opam:2.0.0@2177bbde", "@opam/ordering@opam:3.20.2@6865c105", "@opam/ocamlformat-rpc-lib@opam:0.28.1@4c691df7", @@ -1003,7 +1003,7 @@ "@opam/dune@opam:3.20.2@8daef28d", "@opam/csexp@opam:1.5.2@46614bf4", "@opam/chrome-trace@opam:3.20.2@0904f6e5", "@opam/camlp-streams@opam:5.0.1@8e96208c", - "@opam/base@opam:v0.17.3@78923773", + "@opam/base@opam:v0.17.3@4f79f92d", "@opam/astring@opam:0.8.5@9975798d", "@esy-ocaml/substs@0.0.1@d41d8cd9" ], @@ -1012,7 +1012,7 @@ "@opam/xdg@opam:3.20.2@ade9ef81", "@opam/stdune@opam:3.20.2@c89dc074", "@opam/spawn@opam:v0.17.0@d0f69739", "@opam/re@opam:1.14.0@62aa9f42", - "@opam/ppx_yojson_conv_lib@opam:v0.17.0@2b444c0e", + "@opam/ppx_yojson_conv_lib@opam:v0.17.0@e7e988bb", "@opam/pp@opam:2.0.0@2177bbde", "@opam/ordering@opam:3.20.2@6865c105", "@opam/ocamlformat-rpc-lib@opam:0.28.1@4c691df7", @@ -1026,7 +1026,7 @@ "@opam/dune@opam:3.20.2@8daef28d", "@opam/csexp@opam:1.5.2@46614bf4", "@opam/chrome-trace@opam:3.20.2@0904f6e5", "@opam/camlp-streams@opam:5.0.1@8e96208c", - "@opam/base@opam:v0.17.3@78923773", + "@opam/base@opam:v0.17.3@4f79f92d", "@opam/astring@opam:0.8.5@9975798d" ], "available": [ @@ -1248,14 +1248,14 @@ "dependencies": [ "ocaml@5.3.0@d41d8cd9", "@opam/yojson@opam:3.0.0@b2c9a6c1", "@opam/uutf@opam:1.0.4@ba7fbef7", - "@opam/ppx_yojson_conv_lib@opam:v0.17.0@2b444c0e", + "@opam/ppx_yojson_conv_lib@opam:v0.17.0@e7e988bb", "@opam/jsonrpc@opam:1.23.1@f2566740", "@opam/dune@opam:3.20.2@8daef28d", "@esy-ocaml/substs@0.0.1@d41d8cd9" ], "devDependencies": [ "ocaml@5.3.0@d41d8cd9", "@opam/yojson@opam:3.0.0@b2c9a6c1", "@opam/uutf@opam:1.0.4@ba7fbef7", - "@opam/ppx_yojson_conv_lib@opam:v0.17.0@2b444c0e", + "@opam/ppx_yojson_conv_lib@opam:v0.17.0@e7e988bb", "@opam/jsonrpc@opam:1.23.1@f2566740", "@opam/dune@opam:3.20.2@8daef28d" ], @@ -1319,7 +1319,7 @@ "ocaml@5.3.0@d41d8cd9", "@opam/yojson@opam:3.0.0@b2c9a6c1", "@opam/sedlex@opam:3.7@7fb2caab", "@opam/ppxlib@opam:0.37.0@42a12c9c", - "@opam/ocamlfind@opam:1.9.8@ee910ff5", + "@opam/ocamlfind@opam:1.9.8@4b291364", "@opam/menhirSdk@opam:20250912@f434747d", "@opam/menhirLib@opam:20250912@7bcb2f61", "@opam/menhir@opam:20250912@0ed10637", @@ -1395,7 +1395,7 @@ "overrides": [], "dependencies": [ "ocaml@5.3.0@d41d8cd9", "@opam/topkg@opam:1.1.1@2377d2f8", - "@opam/ocamlfind@opam:1.9.8@ee910ff5", + "@opam/ocamlfind@opam:1.9.8@4b291364", "@opam/ocamlbuild@opam:0.16.1@b3fc8209", "@opam/astring@opam:0.8.5@9975798d", "@esy-ocaml/substs@0.0.1@d41d8cd9" @@ -1880,11 +1880,11 @@ }, "overrides": [], "dependencies": [ - "ocaml@5.3.0@d41d8cd9", "@opam/ocamlfind@opam:1.9.8@ee910ff5", + "ocaml@5.3.0@d41d8cd9", "@opam/ocamlfind@opam:1.9.8@4b291364", "@esy-ocaml/substs@0.0.1@d41d8cd9" ], "devDependencies": [ - "ocaml@5.3.0@d41d8cd9", "@opam/ocamlfind@opam:1.9.8@ee910ff5" + "ocaml@5.3.0@d41d8cd9", "@opam/ocamlfind@opam:1.9.8@4b291364" ], "available": [ [ "darwin", "x86_64" ], @@ -1893,8 +1893,8 @@ [ "windows", "x86_64" ] ] }, - "@opam/base@opam:v0.17.3@78923773": { - "id": "@opam/base@opam:v0.17.3@78923773", + "@opam/base@opam:v0.17.3@4f79f92d": { + "id": "@opam/base@opam:v0.17.3@4f79f92d", "name": "@opam/base", "version": "opam:v0.17.3", "source": { @@ -1911,14 +1911,14 @@ }, "overrides": [], "dependencies": [ - "ocaml@5.3.0@d41d8cd9", "@opam/sexplib0@opam:v0.17.0@75dcb697", - "@opam/ocaml_intrinsics_kernel@opam:v0.17.1@122c1c73", + "ocaml@5.3.0@d41d8cd9", "@opam/sexplib0@opam:v0.17.0@db8af2c0", + "@opam/ocaml_intrinsics_kernel@opam:v0.17.1@ec48e72b", "@opam/dune-configurator@opam:3.20.2@7eb6ff01", "@opam/dune@opam:3.20.2@8daef28d", "@esy-ocaml/substs@0.0.1@d41d8cd9" ], "devDependencies": [ - "ocaml@5.3.0@d41d8cd9", "@opam/sexplib0@opam:v0.17.0@75dcb697", - "@opam/ocaml_intrinsics_kernel@opam:v0.17.1@122c1c73", + "ocaml@5.3.0@d41d8cd9", "@opam/sexplib0@opam:v0.17.0@db8af2c0", + "@opam/ocaml_intrinsics_kernel@opam:v0.17.1@ec48e72b", "@opam/dune-configurator@opam:3.20.2@7eb6ff01", "@opam/dune@opam:3.20.2@8daef28d" ], @@ -1948,7 +1948,7 @@ "overrides": [], "dependencies": [ "ocaml@5.3.0@d41d8cd9", "@opam/topkg@opam:1.1.1@2377d2f8", - "@opam/ocamlfind@opam:1.9.8@ee910ff5", + "@opam/ocamlfind@opam:1.9.8@4b291364", "@opam/ocamlbuild@opam:0.16.1@b3fc8209", "@esy-ocaml/substs@0.0.1@d41d8cd9" ], @@ -1960,14 +1960,14 @@ [ "windows", "x86_64" ] ] }, - "@grain/libbinaryen@124.0.1@d41d8cd9": { - "id": "@grain/libbinaryen@124.0.1@d41d8cd9", + "@grain/libbinaryen@git:https://github.com/spotandjake/libbinaryen.git#d4f1fe1c8be38a62cb179705ae8aa9900b2739e3@d41d8cd9": { + "id": "@grain/libbinaryen@git:https://github.com/spotandjake/libbinaryen.git#d4f1fe1c8be38a62cb179705ae8aa9900b2739e3@d41d8cd9", "name": "@grain/libbinaryen", - "version": "124.0.1", + "version": "git:https://github.com/spotandjake/libbinaryen.git#d4f1fe1c8be38a62cb179705ae8aa9900b2739e3", "source": { "type": "install", "source": [ - "archive:https://registry.npmjs.org/@grain/libbinaryen/-/libbinaryen-124.0.1.tgz#sha1:7b29acc4a62ab5a849c6e01c3d8e90c78efd05f2" + "git:https://github.com/spotandjake/libbinaryen.git#d4f1fe1c8be38a62cb179705ae8aa9900b2739e3" ] }, "overrides": [], @@ -1999,7 +1999,7 @@ "ocaml@5.3.0@d41d8cd9", "@opam/dune-configurator@opam:3.20.2@7eb6ff01", "@opam/dune@opam:3.20.2@8daef28d", - "@grain/libbinaryen@124.0.1@d41d8cd9" + "@grain/libbinaryen@git:https://github.com/spotandjake/libbinaryen.git#d4f1fe1c8be38a62cb179705ae8aa9900b2739e3@d41d8cd9" ], "devDependencies": [ "@opam/ocamlformat@opam:0.27.0@c40d4612", diff --git a/esy.lock/opam/base.v0.17.3/opam b/esy.lock/opam/base.v0.17.3/opam index 76d5609f..39abf898 100644 --- a/esy.lock/opam/base.v0.17.3/opam +++ b/esy.lock/opam/base.v0.17.3/opam @@ -11,8 +11,8 @@ build: [ ] depends: [ "ocaml" {>= "5.1.0"} - "ocaml_intrinsics_kernel" {>= "v0.17.0" & < "v0.18.0"} - "sexplib0" {>= "v0.17.0" & < "v0.18.0"} + "ocaml_intrinsics_kernel" {>= "v0.17.0" & < "v0.18~"} + "sexplib0" {>= "v0.17.0" & < "v0.18~"} "dune" {>= "3.11.0"} "dune-configurator" ] @@ -39,3 +39,5 @@ url { "sha512=628610caff7e124631870fa1e29661caac28bdfdb18750ee43b868037da3d65d6dd9023b4be7c4c52405679efb5e865a6632d95606a22b28a36636a6bf706ef3" ] } +x-maintenance-intent: ["(latest)"] + diff --git a/esy.lock/opam/ocaml_intrinsics_kernel.v0.17.1/opam b/esy.lock/opam/ocaml_intrinsics_kernel.v0.17.1/opam index 44be9138..f167d96b 100644 --- a/esy.lock/opam/ocaml_intrinsics_kernel.v0.17.1/opam +++ b/esy.lock/opam/ocaml_intrinsics_kernel.v0.17.1/opam @@ -28,3 +28,5 @@ url { "sha512=21e596d6407a620866cee7cab47ef1a9446d6a733b4994e809ea5566d5fa956682a5c6a6190ffb0ed48458abd658301944ed10c4389d91ecb8df677a5f87f2ab" ] } +x-maintenance-intent: ["(latest)"] + diff --git a/esy.lock/opam/ocamlfind.1.9.8/opam b/esy.lock/opam/ocamlfind.1.9.8/opam index d9fe3931..8fb38dc5 100644 --- a/esy.lock/opam/ocamlfind.1.9.8/opam +++ b/esy.lock/opam/ocamlfind.1.9.8/opam @@ -12,7 +12,7 @@ license: "MIT" homepage: "http://projects.camlcity.org/projects/findlib.html" bug-reports: "https://github.com/ocaml/ocamlfind/issues" depends: [ - "ocaml" {>= "3.08.0"} + "ocaml" {>= "3.08.0" & (os != "cygwin" & os-distribution != "msys2" | < "5.0")} ] depopts: ["graphics"] build: [ diff --git a/esy.lock/opam/ppx_yojson_conv_lib.v0.17.0/opam b/esy.lock/opam/ppx_yojson_conv_lib.v0.17.0/opam index d58fda4f..44492a50 100644 --- a/esy.lock/opam/ppx_yojson_conv_lib.v0.17.0/opam +++ b/esy.lock/opam/ppx_yojson_conv_lib.v0.17.0/opam @@ -23,3 +23,5 @@ url { src: "https://github.com/janestreet/ppx_yojson_conv_lib/archive/refs/tags/v0.17.0.tar.gz" checksum: "sha256=f6e6ee92408c53c5ecd8bb5ae93811aa4cf71f8dc144d5943be8fc2c7697b199" } +x-maintenance-intent: ["(latest)"] + diff --git a/esy.lock/opam/sexplib0.v0.17.0/opam b/esy.lock/opam/sexplib0.v0.17.0/opam index 7cd4cf8f..78a325db 100644 --- a/esy.lock/opam/sexplib0.v0.17.0/opam +++ b/esy.lock/opam/sexplib0.v0.17.0/opam @@ -29,3 +29,5 @@ url { "sha512=ad387e40789fe70a11473db7e85fe017b801592624414e9030730b2e92ea08f98095fb6e9236430f33c801605ebee0a2a6284e0f618a26a7da4599d4fd9d395d" ] } +x-maintenance-intent: ["(latest)"] + diff --git a/esy.lock/opam/stdio.v0.17.0/opam b/esy.lock/opam/stdio.v0.17.0/opam index 6939fc7d..150104a2 100644 --- a/esy.lock/opam/stdio.v0.17.0/opam +++ b/esy.lock/opam/stdio.v0.17.0/opam @@ -11,7 +11,7 @@ build: [ ] depends: [ "ocaml" {>= "5.1.0"} - "base" {>= "v0.17" & < "v0.18"} + "base" {>= "v0.17" & < "v0.18~"} "dune" {>= "3.11.0"} ] available: arch != "x86_32" @@ -26,3 +26,5 @@ url { src: "https://github.com/janestreet/stdio/archive/refs/tags/v0.17.0.tar.gz" checksum: "sha256=e7cb473d4bffcf419f307c658cf2599fab03a2b4fe655bfd0be699f8f7af176e" } +x-maintenance-intent: ["(latest)"] + diff --git a/package.json b/package.json index b0727de4..b6adac5c 100644 --- a/package.json +++ b/package.json @@ -16,7 +16,8 @@ "@opam/ocaml-lsp-server": ">= 1.9.1 < 2.0.0" }, "resolutions": { - "@opam/ocp-indent": "1.7.0" + "@opam/ocp-indent": "1.7.0", + "@grain/libbinaryen": "git+https://github.com/spotandjake/libbinaryen.git#d4f1fe1c8be38a62cb179705ae8aa9900b2739e3" }, "esy": { "build": "dune build -p binaryen"