@@ -9,8 +9,6 @@ open Mashtree;
99
1010type compilation_env = {
1111 ce_binds: Ident . tbl (Mashtree . binding ),
12- /* Useful due to us needing a second pass over exports (for mutual recursion) */
13- ce_exported_globals: Ident . tbl (int32 ),
1412 ce_stack_idx_ptr: int ,
1513 ce_stack_idx_i32: int ,
1614 ce_stack_idx_i64: int ,
@@ -21,7 +19,6 @@ type compilation_env = {
2119
2220let initial_compilation_env = {
2321 ce_binds: Ident . empty,
24- ce_exported_globals: Ident . empty,
2522 ce_stack_idx_ptr: 0 ,
2623 ce_stack_idx_i32: 0 ,
2724 ce_stack_idx_i64: 0 ,
@@ -63,6 +60,16 @@ let next_lift = () => {
6360 ret;
6461};
6562
63+ /** Imports which are always in scope */
64+ let global_imports = ref (Ident . Set . empty);
65+
66+ let set_global_imports = imports => {
67+ global_imports :=
68+ Ident . Set . of_list(
69+ Ident . fold_all((id, _, acc) => [ id, ... acc] , imports, [] ),
70+ );
71+ };
72+
6673/** Global index (index of global variables) */
6774
6875let global_table =
@@ -100,8 +107,14 @@ let next_global = (exported, id, ty: Types.allocation_type) =>
100107 ret;
101108 };
102109
103- let find_id = (id, env) => Ident . find_same(id, env. ce_binds);
104- let find_global = (id, env) => Ident . find_same(id, env. ce_exported_globals);
110+ let global_name = slot => Printf . sprintf("global_% d " , slot);
111+
112+ let find_id = (id, env) =>
113+ try (Ident . find_same(id, env. ce_binds)) {
114+ | Not_found =>
115+ let (_ , slot , alloc ) = Ident . find_same(id, global_table^ );
116+ MGlobalBind (global_name(Int32 . to_int(slot)), alloc);
117+ };
105118
106119let worklist_reset = () => Queue . clear(compilation_worklist);
107120let worklist_enqueue = elt => Queue . add(elt, compilation_worklist);
@@ -544,17 +557,23 @@ let compile_lambda =
544557 register_function(id);
545558 let (body , return_type ) = body;
546559 let used_var_set = Anf_utils . anf_free_vars(body);
547- let free_var_set =
548- Ident . Set . diff(used_var_set) @@
549- Ident . Set . of_list(List . map(((arg, _)) => arg, args));
560+ let arg_vars = List . map(((arg, _)) => arg, args);
561+ let global_vars =
562+ Ident . fold_all((id, _, acc) => [ id, ... acc] , global_table^, [] );
563+ let accessible_var_set =
564+ Ident . Set . union(
565+ global_imports^,
566+ Ident . Set . of_list(arg_vars @ global_vars),
567+ );
568+ let free_var_set = Ident . Set . diff(used_var_set, accessible_var_set);
550569 let free_vars = Ident . Set . elements(free_var_set);
551570 /* Bind all non-arguments in the function body to
552571 their respective closure slots */
553572 let free_binds =
554573 List_utils . fold_lefti(
555574 (acc, closure_idx, var) =>
556575 Ident . add(var, MClosureBind (Int32 . of_int(closure_idx)), acc),
557- Ident . empty ,
576+ env . ce_binds ,
558577 free_vars,
559578 );
560579 let closure_arg = (Ident . create("$self" ), Types . HeapAllocated );
@@ -579,7 +598,6 @@ let compile_lambda =
579598 ) =
580599 Anf_utils . anf_count_vars(body);
581600 let lam_env = {
582- ... env,
583601 ce_binds: arg_binds,
584602 ce_stack_idx_ptr: 0 ,
585603 ce_stack_idx_i32: 0 ,
@@ -650,7 +668,6 @@ let compile_wrapper = (id, env, func_name, args, rets): Mashtree.closure_data =>
650668 let idx = next_lift() ;
651669 let arity = List . length(args);
652670 let lam_env = {
653- ... env,
654671 ce_binds: Ident . empty,
655672 ce_stack_idx_ptr: 0 ,
656673 ce_stack_idx_i32: 0 ,
@@ -687,7 +704,7 @@ let compile_wrapper = (id, env, func_name, args, rets): Mashtree.closure_data =>
687704
688705let next_global = (~exported= false , id, ty) => {
689706 let ret = next_global(exported, id, ty);
690- Printf . sprintf( "global_ % d " , ret);
707+ global_name( ret);
691708};
692709
693710let rec compile_comp = (~id=?, env, c) => {
@@ -882,44 +899,39 @@ and compile_anf_expr = (env, a) =>
882899 let rec get_locs = (env, binds) => {
883900 switch (binds) {
884901 | [ (id , {comp_allocation_type}), ... rest ] =>
885- let (alloc , gc , stack_idx , next_env ) =
902+ let (alloc , stack_idx , next_env ) =
886903 switch (comp_allocation_type) {
887904 | HeapAllocated => (
888905 Types . HeapAllocated ,
889- true ,
890906 env. ce_stack_idx_ptr,
891907 {... env, ce_stack_idx_ptr: env. ce_stack_idx_ptr + 1 },
892908 )
893909 | StackAllocated (WasmI32 ) => (
894910 Types . StackAllocated (WasmI32 ),
895- false ,
896911 env. ce_stack_idx_i32,
897912 {... env, ce_stack_idx_i32: env. ce_stack_idx_i32 + 1 },
898913 )
899914 | StackAllocated (WasmI64 ) => (
900915 Types . StackAllocated (WasmI64 ),
901- false ,
902916 env. ce_stack_idx_i64,
903917 {... env, ce_stack_idx_i64: env. ce_stack_idx_i64 + 1 },
904918 )
905919 | StackAllocated (WasmF32 ) => (
906920 Types . StackAllocated (WasmF32 ),
907- false ,
908921 env. ce_stack_idx_f32,
909922 {... env, ce_stack_idx_f32: env. ce_stack_idx_f32 + 1 },
910923 )
911924 | StackAllocated (WasmF64 ) => (
912925 Types . StackAllocated (WasmF64 ),
913- false ,
914926 env. ce_stack_idx_f64,
915927 {... env, ce_stack_idx_f64: env. ce_stack_idx_f64 + 1 },
916928 )
917929 };
918930 let (env , loc ) =
919931 switch (global) {
920- | Global => (
932+ | Global ({exported}) => (
921933 env,
922- MGlobalBind (next_global(~exported= true , id, alloc), alloc, gc ),
934+ MGlobalBind (next_global(~exported, id, alloc), alloc),
923935 )
924936 | Nonglobal => (
925937 next_env,
@@ -1022,10 +1034,9 @@ let lift_imports = (env, imports) => {
10221034 | GrainValue (mod_ , name ) =>
10231035 let mimp_mod = Ident . create_persistent(mod_);
10241036 let mimp_name = Ident . create_persistent(name);
1025- let ( alloc , gc ) =
1037+ let alloc =
10261038 switch (imp_shape) {
1027- | GlobalShape (HeapAllocated as alloc ) => (alloc, true )
1028- | GlobalShape (alloc ) => (alloc, false )
1039+ | GlobalShape (alloc ) => alloc
10291040 | FunctionShape (_ ) =>
10301041 failwith ("internal: GrainValue had FunctionShape" )
10311042 };
@@ -1051,7 +1062,6 @@ let lift_imports = (env, imports) => {
10511062 Ident . name(mimp_name),
10521063 ),
10531064 alloc,
1054- gc,
10551065 ),
10561066 env. ce_binds,
10571067 ),
@@ -1060,10 +1070,9 @@ let lift_imports = (env, imports) => {
10601070 | WasmValue (mod_ , name ) =>
10611071 let mimp_mod = Ident . create_persistent(mod_);
10621072 let mimp_name = Ident . create_persistent(name);
1063- let ( alloc , gc ) =
1073+ let alloc =
10641074 switch (imp_shape) {
1065- | GlobalShape (HeapAllocated as alloc ) => (alloc, true )
1066- | GlobalShape (alloc ) => (alloc, false )
1075+ | GlobalShape (alloc ) => alloc
10671076 | FunctionShape (_ ) =>
10681077 failwith ("internal: WasmValue had FunctionShape" )
10691078 };
@@ -1089,7 +1098,6 @@ let lift_imports = (env, imports) => {
10891098 Ident . name(mimp_name),
10901099 ),
10911100 alloc,
1092- gc,
10931101 ),
10941102 env. ce_binds,
10951103 ),
@@ -1098,7 +1106,7 @@ let lift_imports = (env, imports) => {
10981106 | WasmFunction (mod_ , name ) =>
10991107 let glob =
11001108 next_global(
1101- ~exported= imp_exported == Global ,
1109+ ~exported= imp_exported == Global ({exported : true }) ,
11021110 imp_use_id,
11031111 Types . StackAllocated (WasmI32 ),
11041112 );
@@ -1129,11 +1137,7 @@ let lift_imports = (env, imports) => {
11291137 instr_desc:
11301138 MStore ([
11311139 (
1132- MGlobalBind (
1133- glob,
1134- Types . StackAllocated (WasmI32 ),
1135- true ,
1136- ),
1140+ MGlobalBind (glob, Types . HeapAllocated ),
11371141 {
11381142 instr_desc:
11391143 MAllocate (
@@ -1163,7 +1167,7 @@ let lift_imports = (env, imports) => {
11631167 ce_binds:
11641168 Ident . add(
11651169 imp_use_id,
1166- MGlobalBind (glob, Types . StackAllocated ( WasmI32 ) , true ),
1170+ MGlobalBind (glob, HeapAllocated ),
11671171 env. ce_binds,
11681172 ),
11691173 },
@@ -1188,6 +1192,9 @@ let transl_anf_program =
11881192
11891193 let (imports , setups , env ) =
11901194 lift_imports(initial_compilation_env, anf_prog. imports);
1195+
1196+ set_global_imports(env. ce_binds);
1197+
11911198 let (
11921199 stack_size_ptr ,
11931200 stack_size_i32 ,
0 commit comments