@@ -61,7 +61,8 @@ let console_mod = Ident.create_persistent("console");
6161let print_exception_ident = Ident . create_persistent("printException" );
6262let print_exception_closure_ident =
6363 Ident . create_persistent("GRAIN$EXPORT$printException" );
64- let assertion_error_ident =
64+ let assertion_error_ident = Ident . create_persistent("AssertionError" );
65+ let assertion_error_closure_ident =
6566 Ident . create_persistent("GRAIN$EXPORT$AssertionError" );
6667let index_out_of_bounds_ident =
6768 Ident . create_persistent("GRAIN$EXPORT$IndexOutOfBounds" );
@@ -88,7 +89,7 @@ let required_global_imports = [
8889 mimp_type: MGlobalImport (Types . StackAllocated (WasmI32 ), false ),
8990 mimp_kind: MImportWasm ,
9091 mimp_setup: MSetupNone ,
91- mimp_used: false ,
92+ mimp_used: true ,
9293 },
9394 {
9495 mimp_mod: grain_env_mod,
@@ -108,7 +109,7 @@ let required_global_imports = [
108109 },
109110 {
110111 mimp_mod: exception_mod,
111- mimp_name: assertion_error_ident ,
112+ mimp_name: assertion_error_closure_ident ,
112113 mimp_type: MGlobalImport (Types . StackAllocated (WasmI32 ), true ),
113114 mimp_kind: MImportWasm ,
114115 mimp_setup: MSetupNone ,
@@ -183,6 +184,18 @@ let required_function_imports = [
183184 mimp_setup: MSetupNone ,
184185 mimp_used: false ,
185186 },
187+ {
188+ mimp_mod: exception_mod,
189+ mimp_name: assertion_error_ident,
190+ mimp_type:
191+ MFuncImport (
192+ [ Types . StackAllocated (WasmI32 ), Types . StackAllocated (WasmI32 )] ,
193+ [ Types . StackAllocated (WasmI32 )] ,
194+ ),
195+ mimp_kind: MImportWasm ,
196+ mimp_setup: MSetupNone ,
197+ mimp_used: false ,
198+ },
186199] ;
187200
188201let grain_function_imports = [
@@ -296,7 +309,10 @@ let runtime_type_metadata_ptr = () => runtime_heap_ptr^ + 0x08;
296309
297310let reset = () => {
298311 reset_labels() ;
299- List . iter(imp => imp. mimp_used = false , runtime_imports);
312+ List . iter(
313+ imp => imp. mimp_used = imp. mimp_mod == grain_env_mod,
314+ runtime_imports,
315+ );
300316 runtime_heap_ptr :=
301317 (
302318 switch (Grain_utils . Config . memory_base^ ) {
@@ -741,7 +757,7 @@ let compile_bind =
741757 /* Closure bindings need to be calculated */
742758 if (! (action == BindGet )) {
743759 failwith (
744- "Internal error: attempted to emit instruction which would mutate closure contents " ,
760+ "Internal error: attempted to emit instruction which would mutate closure values " ,
745761 );
746762 };
747763 appropriate_incref(
@@ -973,38 +989,31 @@ let compile_imm =
973989 };
974990
975991let call_error_handler = (wasm_mod, env, err, args) => {
976- let err_ident =
992+ let ( err_value_ident , err_func_ident ) =
977993 switch (err) {
978- | Runtime_errors . MatchFailure => match_failure_ident
979- | Runtime_errors . IndexOutOfBounds => index_out_of_bounds_ident
980- | Runtime_errors . AssertionError => assertion_error_ident
994+ | Runtime_errors . MatchFailure => (match_failure_ident, None )
995+ | Runtime_errors . IndexOutOfBounds => (index_out_of_bounds_ident, None )
996+ | Runtime_errors . AssertionError => (
997+ assertion_error_closure_ident,
998+ Some (get_wasm_imported_name(exception_mod, assertion_error_ident)),
999+ )
9811000 };
9821001 let mk_err = () =>
9831002 Expression . Global_get . make(
9841003 wasm_mod,
985- get_wasm_imported_name(exception_mod, err_ident ),
1004+ get_wasm_imported_name(exception_mod, err_value_ident ),
9861005 Type . int32,
9871006 );
9881007 let err =
9891008 switch (args) {
9901009 | [] => mk_err()
9911010 | _ =>
9921011 let compiled_args = args;
993- Expression . Call_indirect . make(
1012+ Expression . Call . make(
9941013 wasm_mod,
995- global_function_table,
996- load(~offset= 8 , wasm_mod, mk_err() ),
1014+ Option . get(err_func_ident),
9971015 [ mk_err() , ... compiled_args] ,
998- Type . create @@
999- Array . map(
1000- wasm_type,
1001- Array . of_list([
1002- Types . StackAllocated (WasmI32 ),
1003- ... List . map(_ => Types . StackAllocated (WasmI32 ), args),
1004- ] ),
1005- ),
1006- Type . create @@
1007- Array . map(wasm_type, Array . of_list([ Types . StackAllocated (WasmI32 )] )),
1016+ Type . int32,
10081017 );
10091018 };
10101019 Expression . Block . make(
@@ -1393,6 +1402,33 @@ let compile_record_op = (wasm_mod, env, rec_imm, op) => {
13931402 };
13941403};
13951404
1405+ let compile_closure_op = (wasm_mod, env, closure_imm, op) => {
1406+ // We skip the incref here as this is akin to using a swap slot (the
1407+ // reference we create here cannot escape, so there isn't a need to add an
1408+ // incref/decref pair). Since it won't live in a local, it wouldn't be
1409+ // cleaned up automatically anyway.
1410+ let closure = () =>
1411+ compile_imm(~skip_incref= true , wasm_mod, env, closure_imm);
1412+ switch (op) {
1413+ | MClosureSetPtr (idx ) =>
1414+ store(
1415+ ~offset= 8 ,
1416+ wasm_mod,
1417+ closure() ,
1418+ Expression . Binary . make(
1419+ wasm_mod,
1420+ Op . add_int32,
1421+ Expression . Global_get . make(
1422+ wasm_mod,
1423+ get_wasm_imported_name(grain_env_mod, reloc_base),
1424+ Type . int32,
1425+ ),
1426+ Expression . Const . make(wasm_mod, wrap_int32(idx)),
1427+ ),
1428+ )
1429+ };
1430+ };
1431+
13961432/** Heap allocations. */
13971433
13981434/** Rounds the given number of words to be aligned correctly */
@@ -1729,6 +1765,22 @@ let allocate_closure =
17291765 );
17301766 patches := List . mapi(patch_var, variables);
17311767 };
1768+ let func_idx =
1769+ switch (func_idx) {
1770+ | Some (idx ) =>
1771+ Expression . Binary . make(
1772+ wasm_mod,
1773+ Op . add_int32,
1774+ Expression . Global_get . make(
1775+ wasm_mod,
1776+ get_wasm_imported_name(grain_env_mod, reloc_base),
1777+ Type . int32,
1778+ ),
1779+ Expression . Const . make(wasm_mod, wrap_int32(idx)),
1780+ )
1781+ // Use as a sentinel
1782+ | None => Expression . Const . make(wasm_mod, wrap_int32(- 1 l))
1783+ };
17321784 let preamble = [
17331785 store(
17341786 ~offset= 0 ,
@@ -1745,21 +1797,7 @@ let allocate_closure =
17451797 get_swap() ,
17461798 Expression . Const . make(wasm_mod, wrap_int32(arity)),
17471799 ),
1748- store(
1749- ~offset= 8 ,
1750- wasm_mod,
1751- get_swap() ,
1752- Expression . Binary . make(
1753- wasm_mod,
1754- Op . add_int32,
1755- Expression . Global_get . make(
1756- wasm_mod,
1757- get_wasm_imported_name(grain_env_mod, reloc_base),
1758- Type . int32,
1759- ),
1760- Expression . Const . make(wasm_mod, wrap_int32(func_idx)),
1761- ),
1762- ),
1800+ store(~offset= 8 , wasm_mod, get_swap() , func_idx),
17631801 store(
17641802 ~offset= 12 ,
17651803 wasm_mod,
@@ -2939,6 +2977,8 @@ and compile_instr = (wasm_mod, env, instr) =>
29392977 | MAdtOp (adt_op , adt ) => compile_adt_op(wasm_mod, env, adt, adt_op)
29402978 | MRecordOp (record_op , record ) =>
29412979 compile_record_op(wasm_mod, env, record, record_op)
2980+ | MClosureOp (closure_op , closure ) =>
2981+ compile_closure_op(wasm_mod, env, closure, closure_op)
29422982 | MPrim0 (p0 ) => compile_prim0(wasm_mod, env, p0)
29432983 | MPrim1 (p1 , arg ) => compile_prim1(wasm_mod, env, p1, arg, instr. instr_loc)
29442984 | MPrim2 (p2 , arg1 , arg2 ) => compile_prim2(wasm_mod, env, p2, arg1, arg2)
@@ -3245,7 +3285,7 @@ let compile_function =
32453285 ~preamble=?,
32463286 wasm_mod,
32473287 env,
3248- {index , id, args, return_type, stack_size, body: body_instrs, func_loc},
3288+ {id, args, return_type, stack_size, body: body_instrs, func_loc},
32493289 ) => {
32503290 sources := [] ;
32513291 let arity = List . length(args);
@@ -3312,8 +3352,8 @@ let compile_function =
33123352 func_ref;
33133353};
33143354
3315- let compute_table_size = (env, {functions }) => {
3316- List . length(functions );
3355+ let compute_table_size = (env, {function_table_elements }) => {
3356+ List . length(function_table_elements );
33173357};
33183358
33193359let compile_imports = (wasm_mod, env, {imports}) => {
@@ -3448,14 +3488,12 @@ let compile_exports = (wasm_mod, env, {imports, exports, globals}) => {
34483488 );
34493489};
34503490
3451- let compile_tables = (wasm_mod, env, {functions}) => {
3452- let function_names =
3453- List . map(({id}) => Ident . unique_name(id), functions);
3491+ let compile_tables = (wasm_mod, env, {function_table_elements}) => {
34543492 Table . add_active_element_segment(
34553493 wasm_mod,
34563494 global_function_table,
34573495 "elem" ,
3458- function_names ,
3496+ function_table_elements ,
34593497 Expression . Global_get . make(
34603498 wasm_mod,
34613499 get_wasm_imported_name(grain_env_mod, reloc_base),
@@ -3555,7 +3593,6 @@ let compile_main = (wasm_mod, env, prog) => {
35553593 wasm_mod,
35563594 env,
35573595 {
3558- index: Int32 . of_int(- 99 ),
35593596 id: Ident . create(grain_main),
35603597 name: Some (grain_main),
35613598 args: [] ,
@@ -3687,11 +3724,11 @@ let compile_wasm_module = (~env=?, ~name=?, prog) => {
36873724 Memory . set_memory(wasm_mod, 0 , Memory . unlimited, "memory" , [] , false );
36883725
36893726 let compile_all = () => {
3727+ ignore @@ compile_globals(wasm_mod, env, prog);
36903728 ignore @@ compile_functions(wasm_mod, env, prog);
3691- ignore @@ compile_tables(wasm_mod, env, prog);
3692- ignore @@ compile_imports(wasm_mod, env, prog);
36933729 ignore @@ compile_exports(wasm_mod, env, prog);
3694- ignore @@ compile_globals(wasm_mod, env, prog);
3730+ ignore @@ compile_imports(wasm_mod, env, prog);
3731+ ignore @@ compile_tables(wasm_mod, env, prog);
36953732 };
36963733
36973734 if (Env . is_runtime_mode() ) {
0 commit comments