Skip to content

Commit bc003c7

Browse files
authored
feat: Add bindings for exception handling (try/throw) (#264)
1 parent 0877b1e commit bc003c7

21 files changed

Lines changed: 1186 additions & 31 deletions

src/dune

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
export
1616
global
1717
table
18+
tag
1819
memory
1920
module_feature
2021
module
@@ -37,6 +38,7 @@
3738
export.js
3839
global.js
3940
table.js
41+
tag.js
4042
memory.js
4143
module_feature.js
4244
module.js

src/export.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,16 @@ caml_binaryen_add_global_export(value _module, value _internalName, value _exter
4848
CAMLreturn(alloc_BinaryenExportRef(exp));
4949
}
5050

51+
CAMLprim value
52+
caml_binaryen_add_tag_export(value _module, value _internalName, value _externalName) {
53+
CAMLparam3(_module, _internalName, _externalName);
54+
BinaryenModuleRef module = BinaryenModuleRef_val(_module);
55+
char* internalName = Safe_String_val(_internalName);
56+
char* externalName = Safe_String_val(_externalName);
57+
BinaryenExportRef exp = BinaryenAddTagExport(module, internalName, externalName);
58+
CAMLreturn(alloc_BinaryenExportRef(exp));
59+
}
60+
5161
CAMLprim value
5262
caml_binaryen_get_export(value _module, value _externalName) {
5363
CAMLparam2(_module, _externalName);

src/export.js

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,19 @@ function caml_binaryen_add_global_export(
5050
);
5151
}
5252

53+
//Provides: caml_binaryen_add_tag_export
54+
//Requires: caml_jsstring_of_string
55+
function caml_binaryen_add_tag_export(
56+
wasm_mod,
57+
internal_name,
58+
external_name
59+
) {
60+
return wasm_mod.addTagExport(
61+
caml_jsstring_of_string(internal_name),
62+
caml_jsstring_of_string(external_name)
63+
);
64+
}
65+
5366
//Provides: caml_binaryen_get_export
5467
//Requires: caml_jsstring_of_string
5568
function caml_binaryen_get_export(wasm_mod, external_name) {

src/export.ml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,10 @@ external add_global_export : Module.t -> string -> string -> t
1616
= "caml_binaryen_add_global_export"
1717
(** Module, internal name, external name. *)
1818

19+
external add_tag_export : Module.t -> string -> string -> t
20+
= "caml_binaryen_add_tag_export"
21+
(** Module, internal name, external name. *)
22+
1923
external get_export : Module.t -> string -> t = "caml_binaryen_get_export"
2024

2125
external remove_export : Module.t -> string -> unit

src/export.mli

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ val add_function_export : Module.t -> string -> string -> t
44
val add_table_export : Module.t -> string -> string -> t
55
val add_memory_export : Module.t -> string -> string -> t
66
val add_global_export : Module.t -> string -> string -> t
7+
val add_tag_export : Module.t -> string -> string -> t
78
val get_export : Module.t -> string -> t
89
val remove_export : Module.t -> string -> unit
910
val get_num_exports : Module.t -> int

src/expression.c

Lines changed: 291 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1883,6 +1883,297 @@ caml_binaryen_ref_eq(value _module, value _left, value _right) {
18831883
CAMLreturn(alloc_BinaryenExpressionRef(exp));
18841884
}
18851885

1886+
// Exception handling operations
1887+
CAMLprim value
1888+
caml_binaryen_try(value _module, value _name, value _body, value _catchTags, value _catchBodies, value _delegateTarget) {
1889+
CAMLparam5(_module, _name, _body, _catchTags, _catchBodies);
1890+
CAMLxparam1(_delegateTarget);
1891+
BinaryenModuleRef module = BinaryenModuleRef_val(_module);
1892+
char *name;
1893+
if (Is_none(_name)) {
1894+
name = NULL;
1895+
} else {
1896+
name = Safe_String_val(Some_val(_name));
1897+
}
1898+
BinaryenExpressionRef body = BinaryenExpressionRef_val(_body);
1899+
_catchTags = array_of_list(_catchTags);
1900+
int catchTagsLen = array_length(_catchTags);
1901+
const char* catchTags[catchTagsLen];
1902+
for (int i = 0; i < catchTagsLen; i++) {
1903+
catchTags[i] = Safe_String_val(Field(_catchTags, i));
1904+
}
1905+
_catchBodies = array_of_list(_catchBodies);
1906+
int catchBodiesLen = array_length(_catchBodies);
1907+
BinaryenExpressionRef catchBodies[catchBodiesLen];
1908+
for (int i = 0; i < catchBodiesLen; i++) {
1909+
catchBodies[i] = BinaryenExpressionRef_val(Field(_catchBodies, i));
1910+
}
1911+
char *delegateTarget;
1912+
if (Is_none(_delegateTarget)) {
1913+
delegateTarget = NULL;
1914+
} else {
1915+
delegateTarget = Safe_String_val(Some_val(_delegateTarget));
1916+
}
1917+
BinaryenExpressionRef exp = BinaryenTry(
1918+
module,
1919+
name,
1920+
body,
1921+
catchTags,
1922+
catchTagsLen,
1923+
catchBodies,
1924+
catchBodiesLen,
1925+
delegateTarget
1926+
);
1927+
CAMLreturn(alloc_BinaryenExpressionRef(exp));
1928+
}
1929+
1930+
CAMLprim value caml_binaryen_try__bytecode(value * argv) {
1931+
return caml_binaryen_try(argv[0], argv[1], argv[2], argv[3], argv[4], argv[5]);
1932+
}
1933+
1934+
CAMLprim value
1935+
caml_binaryen_throw(value _module, value _tag, value _operands) {
1936+
CAMLparam3(_module, _tag, _operands);
1937+
BinaryenModuleRef module = BinaryenModuleRef_val(_module);
1938+
char *tag = Safe_String_val(_tag);
1939+
_operands = array_of_list(_operands);
1940+
int operandsLen = array_length(_operands);
1941+
BinaryenExpressionRef operands[operandsLen];
1942+
for (int i = 0; i < operandsLen; i++) {
1943+
operands[i] = BinaryenExpressionRef_val(Field(_operands, i));
1944+
}
1945+
BinaryenExpressionRef exp = BinaryenThrow(module, tag, operands, operandsLen);
1946+
CAMLreturn(alloc_BinaryenExpressionRef(exp));
1947+
}
1948+
1949+
CAMLprim value
1950+
caml_binaryen_try_get_name(value _expr) {
1951+
CAMLparam1(_expr);
1952+
BinaryenExpressionRef expr = BinaryenExpressionRef_val(_expr);
1953+
const char* name = BinaryenTryGetName(expr);
1954+
if (name == NULL) {
1955+
CAMLreturn(Val_none);
1956+
} else {
1957+
CAMLreturn(caml_alloc_some(caml_copy_string(name)));
1958+
}
1959+
}
1960+
1961+
CAMLprim value
1962+
caml_binaryen_try_set_name(value _expr, value _name) {
1963+
CAMLparam2(_expr, _name);
1964+
BinaryenExpressionRef expr = BinaryenExpressionRef_val(_expr);
1965+
const char* name = Safe_String_val(_name);
1966+
BinaryenTrySetName(expr, name);
1967+
CAMLreturn(Val_unit);
1968+
}
1969+
1970+
CAMLprim value
1971+
caml_binaryen_try_get_body(value _expr) {
1972+
CAMLparam1(_expr);
1973+
BinaryenExpressionRef expr = BinaryenExpressionRef_val(_expr);
1974+
BinaryenExpressionRef binaryenRetVal = BinaryenTryGetBody(expr);
1975+
CAMLreturn(alloc_BinaryenExpressionRef(binaryenRetVal));
1976+
}
1977+
1978+
CAMLprim value
1979+
caml_binaryen_try_set_body(value _expr, value _bodyExpr) {
1980+
CAMLparam2(_expr, _bodyExpr);
1981+
BinaryenExpressionRef expr = BinaryenExpressionRef_val(_expr);
1982+
BinaryenExpressionRef bodyExpr = BinaryenExpressionRef_val(_bodyExpr);
1983+
BinaryenTrySetBody(expr, bodyExpr);
1984+
CAMLreturn(Val_unit);
1985+
}
1986+
1987+
CAMLprim value
1988+
caml_binaryen_try_get_num_catch_tags(value _expr) {
1989+
CAMLparam1(_expr);
1990+
BinaryenExpressionRef expr = BinaryenExpressionRef_val(_expr);
1991+
BinaryenIndex binaryenRetVal = BinaryenTryGetNumCatchTags(expr);
1992+
CAMLreturn(Val_int(binaryenRetVal));
1993+
}
1994+
1995+
CAMLprim value
1996+
caml_binaryen_try_get_num_catch_bodies(value _expr) {
1997+
CAMLparam1(_expr);
1998+
BinaryenExpressionRef expr = BinaryenExpressionRef_val(_expr);
1999+
BinaryenIndex binaryenRetVal = BinaryenTryGetNumCatchBodies(expr);
2000+
CAMLreturn(Val_int(binaryenRetVal));
2001+
}
2002+
2003+
CAMLprim value
2004+
caml_binaryen_try_get_catch_tag_at(value _expr, value _index) {
2005+
CAMLparam2(_expr, _index);
2006+
BinaryenExpressionRef expr = BinaryenExpressionRef_val(_expr);
2007+
BinaryenIndex index = Int_val(_index);
2008+
const char* binaryenRetVal = BinaryenTryGetCatchTagAt(expr, index);
2009+
CAMLreturn(caml_copy_string(binaryenRetVal));
2010+
}
2011+
2012+
CAMLprim value
2013+
caml_binaryen_try_set_catch_tag_at(value _expr, value _index, value _catchTag) {
2014+
CAMLparam3(_expr, _index, _catchTag);
2015+
BinaryenExpressionRef expr = BinaryenExpressionRef_val(_expr);
2016+
BinaryenIndex index = Int_val(_index);
2017+
const char* catchTag = Safe_String_val(_catchTag);
2018+
BinaryenTrySetCatchTagAt(expr, index, catchTag);
2019+
CAMLreturn(Val_unit);
2020+
}
2021+
2022+
CAMLprim value
2023+
caml_binaryen_try_append_catch_tag(value _expr, value _catchTag) {
2024+
CAMLparam2(_expr, _catchTag);
2025+
BinaryenExpressionRef expr = BinaryenExpressionRef_val(_expr);
2026+
const char* catchTag = Safe_String_val(_catchTag);
2027+
BinaryenIndex binaryenRetVal = BinaryenTryAppendCatchTag(expr, catchTag);
2028+
CAMLreturn(Val_int(binaryenRetVal));
2029+
}
2030+
2031+
CAMLprim value
2032+
caml_binaryen_try_insert_catch_tag_at(value _expr, value _index, value _catchTag) {
2033+
CAMLparam3(_expr, _index, _catchTag);
2034+
BinaryenExpressionRef expr = BinaryenExpressionRef_val(_expr);
2035+
BinaryenIndex index = Int_val(_index);
2036+
const char* catchTag = Safe_String_val(_catchTag);
2037+
BinaryenTryInsertCatchTagAt(expr, index, catchTag);
2038+
CAMLreturn(Val_unit);
2039+
}
2040+
2041+
CAMLprim value
2042+
caml_binaryen_try_remove_catch_tag_at(value _expr, value _index) {
2043+
CAMLparam2(_expr, _index);
2044+
BinaryenExpressionRef expr = BinaryenExpressionRef_val(_expr);
2045+
BinaryenIndex index = Int_val(_index);
2046+
const char* binaryenRetVal = BinaryenTryRemoveCatchTagAt(expr, index);
2047+
CAMLreturn(caml_copy_string(binaryenRetVal));
2048+
}
2049+
2050+
CAMLprim value
2051+
caml_binaryen_try_get_catch_body_at(value _expr, value _index) {
2052+
CAMLparam2(_expr, _index);
2053+
BinaryenExpressionRef expr = BinaryenExpressionRef_val(_expr);
2054+
BinaryenIndex index = Int_val(_index);
2055+
BinaryenExpressionRef binaryenRetVal = BinaryenTryGetCatchBodyAt(expr, index);
2056+
CAMLreturn(alloc_BinaryenExpressionRef(binaryenRetVal));
2057+
}
2058+
2059+
CAMLprim value
2060+
caml_binaryen_try_set_catch_body_at(value _expr, value _index, value _catchExpr) {
2061+
CAMLparam3(_expr, _index, _catchExpr);
2062+
BinaryenExpressionRef expr = BinaryenExpressionRef_val(_expr);
2063+
BinaryenIndex index = Int_val(_index);
2064+
BinaryenExpressionRef catchExpr = BinaryenExpressionRef_val(_catchExpr);
2065+
BinaryenTrySetCatchBodyAt(expr, index, catchExpr);
2066+
CAMLreturn(Val_unit);
2067+
}
2068+
2069+
CAMLprim value
2070+
caml_binaryen_try_append_catch_body(value _expr, value _catchExpr) {
2071+
CAMLparam2(_expr, _catchExpr);
2072+
BinaryenExpressionRef expr = BinaryenExpressionRef_val(_expr);
2073+
BinaryenExpressionRef catchExpr = BinaryenExpressionRef_val(_catchExpr);
2074+
BinaryenIndex binaryenRetVal = BinaryenTryAppendCatchBody(expr, catchExpr);
2075+
CAMLreturn(Val_int(binaryenRetVal));
2076+
}
2077+
2078+
CAMLprim value
2079+
caml_binaryen_try_insert_catch_body_at(value _expr, value _index, value _catchExpr) {
2080+
CAMLparam3(_expr, _index, _catchExpr);
2081+
BinaryenExpressionRef expr = BinaryenExpressionRef_val(_expr);
2082+
BinaryenIndex index = Int_val(_index);
2083+
BinaryenExpressionRef catchExpr = BinaryenExpressionRef_val(_catchExpr);
2084+
BinaryenTryInsertCatchBodyAt(expr, index, catchExpr);
2085+
CAMLreturn(Val_unit);
2086+
}
2087+
2088+
CAMLprim value
2089+
caml_binaryen_try_remove_catch_body_at(value _expr, value _index) {
2090+
CAMLparam2(_expr, _index);
2091+
BinaryenExpressionRef expr = BinaryenExpressionRef_val(_expr);
2092+
BinaryenIndex index = Int_val(_index);
2093+
BinaryenExpressionRef binaryenRetVal = BinaryenTryRemoveCatchBodyAt(expr, index);
2094+
CAMLreturn(alloc_BinaryenExpressionRef(binaryenRetVal));
2095+
}
2096+
2097+
CAMLprim value
2098+
caml_binaryen_try_has_catch_all(value _expr) {
2099+
CAMLparam1(_expr);
2100+
BinaryenExpressionRef expr = BinaryenExpressionRef_val(_expr);
2101+
bool binaryenRetVal = BinaryenTryHasCatchAll(expr);
2102+
CAMLreturn(Val_bool(binaryenRetVal));
2103+
}
2104+
2105+
CAMLprim value
2106+
caml_binaryen_throw_get_tag(value _expr) {
2107+
CAMLparam1(_expr);
2108+
BinaryenExpressionRef expr = BinaryenExpressionRef_val(_expr);
2109+
const char* binaryenRetVal = BinaryenThrowGetTag(expr);
2110+
CAMLreturn(caml_copy_string(binaryenRetVal));
2111+
}
2112+
2113+
CAMLprim value
2114+
caml_binaryen_throw_set_tag(value _expr, value _tagName) {
2115+
CAMLparam2(_expr, _tagName);
2116+
BinaryenExpressionRef expr = BinaryenExpressionRef_val(_expr);
2117+
const char* tagName = Safe_String_val(_tagName);
2118+
BinaryenThrowSetTag(expr, tagName);
2119+
CAMLreturn(Val_unit);
2120+
}
2121+
2122+
CAMLprim value
2123+
caml_binaryen_throw_get_num_operands(value _expr) {
2124+
CAMLparam1(_expr);
2125+
BinaryenExpressionRef expr = BinaryenExpressionRef_val(_expr);
2126+
BinaryenIndex binaryenRetVal = BinaryenThrowGetNumOperands(expr);
2127+
CAMLreturn(Val_int(binaryenRetVal));
2128+
}
2129+
2130+
CAMLprim value
2131+
caml_binaryen_throw_get_operand_at(value _expr, value _index) {
2132+
CAMLparam2(_expr, _index);
2133+
BinaryenExpressionRef expr = BinaryenExpressionRef_val(_expr);
2134+
BinaryenIndex index = Int_val(_index);
2135+
BinaryenExpressionRef binaryenRetVal = BinaryenThrowGetOperandAt(expr, index);
2136+
CAMLreturn(alloc_BinaryenExpressionRef(binaryenRetVal));
2137+
}
2138+
2139+
CAMLprim value
2140+
caml_binaryen_throw_set_operand_at(value _expr, value _index, value _operandExpr) {
2141+
CAMLparam3(_expr, _index, _operandExpr);
2142+
BinaryenExpressionRef expr = BinaryenExpressionRef_val(_expr);
2143+
BinaryenIndex index = Int_val(_index);
2144+
BinaryenExpressionRef operandExpr = BinaryenExpressionRef_val(_operandExpr);
2145+
BinaryenThrowSetOperandAt(expr, index, operandExpr);
2146+
CAMLreturn(Val_unit);
2147+
}
2148+
2149+
CAMLprim value
2150+
caml_binaryen_throw_append_operand(value _expr, value _operandExpr) {
2151+
CAMLparam2(_expr, _operandExpr);
2152+
BinaryenExpressionRef expr = BinaryenExpressionRef_val(_expr);
2153+
BinaryenExpressionRef operandExpr = BinaryenExpressionRef_val(_operandExpr);
2154+
BinaryenIndex binaryenRetVal = BinaryenThrowAppendOperand(expr, operandExpr);
2155+
CAMLreturn(Val_int(binaryenRetVal));
2156+
}
2157+
2158+
CAMLprim value
2159+
caml_binaryen_throw_insert_operand_at(value _expr, value _index, value _operandExpr) {
2160+
CAMLparam3(_expr, _index, _operandExpr);
2161+
BinaryenExpressionRef expr = BinaryenExpressionRef_val(_expr);
2162+
BinaryenIndex index = Int_val(_index);
2163+
BinaryenExpressionRef operandExpr = BinaryenExpressionRef_val(_operandExpr);
2164+
BinaryenThrowInsertOperandAt(expr, index, operandExpr);
2165+
CAMLreturn(Val_unit);
2166+
}
2167+
2168+
CAMLprim value
2169+
caml_binaryen_throw_remove_operand_at(value _expr, value _index) {
2170+
CAMLparam2(_expr, _index);
2171+
BinaryenExpressionRef expr = BinaryenExpressionRef_val(_expr);
2172+
BinaryenIndex index = Int_val(_index);
2173+
BinaryenExpressionRef binaryenRetVal = BinaryenThrowRemoveOperandAt(expr, index);
2174+
CAMLreturn(alloc_BinaryenExpressionRef(binaryenRetVal));
2175+
}
2176+
18862177
// Table operations
18872178
CAMLprim value
18882179
caml_binaryen_table_get(value _module, value _name, value _index, value _ty) {

0 commit comments

Comments
 (0)