Skip to content

Commit

Permalink
feat(compiler): Name globals in wasm output
Browse files Browse the repository at this point in the history
  • Loading branch information
ospencer committed May 14, 2022
1 parent 9b0a798 commit 986eef8
Show file tree
Hide file tree
Showing 5 changed files with 27 additions and 86 deletions.
66 changes: 9 additions & 57 deletions compiler/src/codegen/compcore.re
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,6 @@ type codegen_env = {
stack_size,
/* Allocated closures which need backpatching */
backpatches: ref(list((Expression.t, closure_data))),
imported_funcs: Ident.tbl(Ident.tbl(int32)),
imported_globals: Ident.tbl(Ident.tbl(string)),
required_imports: list(import),
};

Expand Down Expand Up @@ -283,20 +281,9 @@ let init_codegen_env = name => {
stack_size_f64: 0,
},
backpatches: ref([]),
imported_funcs: Ident.empty,
imported_globals: Ident.empty,
required_imports: [],
};

let lookup_ext_global = (env, modname, itemname) =>
Ident.find_same(itemname, Ident.find_same(modname, env.imported_globals));

let var_of_ext_global = (env, modname, itemname) =>
lookup_ext_global(env, modname, itemname);

let lookup_ext_func = (env, modname, itemname) =>
Ident.find_same(itemname, Ident.find_same(modname, env.imported_funcs));

/** Static runtime values */

// Static pointer to the runtime heap
Expand Down Expand Up @@ -3436,8 +3423,8 @@ let compile_imports = (wasm_mod, env, {imports}) => {
let compile_exports = (wasm_mod, env, {imports, exports, globals}) => {
let compile_export = (i, export) => {
switch (export) {
| GlobalExport({ex_global_name, ex_global_index}) =>
let internal_name = Printf.sprintf("global_%ld", ex_global_index);
| GlobalExport({ex_global_name}) =>
let internal_name = Ident.unique_name(ex_global_name);
let exported_name = "GRAIN$EXPORT$" ++ Ident.name(ex_global_name);
ignore @@
Export.add_global_export(wasm_mod, internal_name, exported_name);
Expand Down Expand Up @@ -3483,7 +3470,7 @@ let compile_exports = (wasm_mod, env, {imports, exports, globals}) => {
ignore @@
Export.add_global_export(
wasm_mod,
Printf.sprintf("global_%d", List.length(globals) + 1),
Ident.name(table_size),
Ident.name(table_size),
);
};
Expand Down Expand Up @@ -3511,11 +3498,11 @@ let compile_globals = (wasm_mod, env, {globals} as prog) => {
| Types.StackAllocated(WasmF32) => const_float32(0.)
| Types.StackAllocated(WasmF64) => const_float64(0.);
List.iter(
((i, ty)) =>
((id, ty)) =>
ignore @@
Global.add_global(
wasm_mod,
Printf.sprintf("global_%ld", i),
Ident.unique_name(id),
wasm_type(ty),
true,
Expression.Const.make(wasm_mod, initial_value(ty)),
Expand All @@ -3525,7 +3512,7 @@ let compile_globals = (wasm_mod, env, {globals} as prog) => {
ignore @@
Global.add_global(
wasm_mod,
Printf.sprintf("global_%d", 1 + List.length(globals)),
Ident.name(table_size),
Type.int32,
false,
Expression.Const.make(
Expand Down Expand Up @@ -3638,49 +3625,14 @@ let validate_module = (~name=?, wasm_mod: Module.t) =>
raise(WasmRunnerError(wasm_mod, name, "WARNING: Invalid module"))
};

let prepare = (env, {imports}) => {
let process_import =
(acc_env, idx, {mimp_mod, mimp_name, mimp_type, mimp_kind}) => {
let idx_name = Transl_anf.global_name(idx);
let register = (name, tbl) => {
let tbl =
switch (Ident.find_same_opt(mimp_mod, tbl)) {
| None => Ident.add(mimp_mod, Ident.empty, tbl)
| Some(_) => tbl
};
Ident.add(
mimp_mod,
Ident.add(mimp_name, name, Ident.find_same(mimp_mod, tbl)),
tbl,
);
};

let (imported_funcs, imported_globals) =
switch (mimp_type) {
| MFuncImport(_) => (
register(Int32.of_int(idx), acc_env.imported_funcs),
acc_env.imported_globals,
)
| MGlobalImport(_) => (
acc_env.imported_funcs,
register(idx_name, acc_env.imported_globals),
)
};
{...acc_env, imported_funcs, imported_globals};
};

let prepare = env => {
let required_imports =
if (Env.is_runtime_mode()) {
List.concat([required_global_imports, required_function_imports]);
} else {
runtime_imports;
};
let new_env =
List_utils.fold_lefti(process_import, env, runtime_global_imports);
let new_env =
List_utils.fold_lefti(process_import, new_env, runtime_function_imports);
let new_env = List_utils.fold_lefti(process_import, new_env, imports);
{...new_env, required_imports};
{...env, required_imports};
};

let compile_wasm_module = (~env=?, ~name=?, prog) => {
Expand All @@ -3690,7 +3642,7 @@ let compile_wasm_module = (~env=?, ~name=?, prog) => {
| None => init_codegen_env(name)
| Some(e) => e
};
let env = prepare(env, prog);
let env = prepare(env);
let wasm_mod = Module.create();
if (Config.source_map^) {
ignore @@
Expand Down
2 changes: 0 additions & 2 deletions compiler/src/codegen/compcore.rei
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@ type codegen_env = {
stack_size,
/* Allocated closures which need backpatching */
backpatches: ref(list((Expression.t, closure_data))),
imported_funcs: Ident.tbl(Ident.tbl(int32)),
imported_globals: Ident.tbl(Ident.tbl(string)),
required_imports: list(import),
};

Expand Down
7 changes: 2 additions & 5 deletions compiler/src/codegen/mashtree.re
Original file line number Diff line number Diff line change
Expand Up @@ -466,10 +466,7 @@ type export =
ex_function_name: string,
ex_function_internal_name: string,
})
| GlobalExport({
ex_global_name: Ident.t,
ex_global_index: int32,
});
| GlobalExport({ex_global_name: Ident.t});

[@deriving sexp]
type mash_function = {
Expand Down Expand Up @@ -497,7 +494,7 @@ type mash_program = {
exports: list(export),
main_body: block,
main_body_stack_size: stack_size,
globals: list((int32, Types.allocation_type)),
globals: list((Ident.t, Types.allocation_type)),
function_table_elements: list(string),
signature: Cmi_format.cmi_infos,
type_metadata: list(Types.type_metadata),
Expand Down
36 changes: 15 additions & 21 deletions compiler/src/codegen/transl_anf.re
Original file line number Diff line number Diff line change
Expand Up @@ -90,12 +90,11 @@ let set_global_imports = imports => {
/** Global index (index of global variables) */

let global_table =
ref(Ident.empty: Ident.tbl((bool, int32, Types.allocation_type)));
let global_index = ref(0);
ref(Ident.empty: Ident.tbl((bool, Types.allocation_type)));

let get_globals = () => {
Ident.fold_all(
(_, (_, slot, ty), acc) => [(slot, ty), ...acc],
(id, (_, ty), acc) => [(id, ty), ...acc],
global_table^,
[],
);
Expand All @@ -104,9 +103,9 @@ let get_globals = () => {
let global_exports = () => {
let tbl = global_table^;
Ident.fold_all(
(ex_global_name, (exported, ex_global_index, _), acc) =>
(ex_global_name, (exported, _), acc) =>
if (exported) {
[GlobalExport({ex_global_name, ex_global_index}), ...acc];
[GlobalExport({ex_global_name: ex_global_name}), ...acc];
} else {
acc;
},
Expand All @@ -117,28 +116,23 @@ let global_exports = () => {

let reset_global = () => {
global_table := Ident.empty;
global_index := 0;
};

let next_global = (exported, id, ty: Types.allocation_type) =>
/* RIP Hygiene (this behavior works as expected until we have more metaprogramming constructs) */
let get_global = (exported, id, ty: Types.allocation_type) =>
switch (Ident.find_same_opt(id, global_table^)) {
| Some((_, ret, _)) => Int32.to_int(ret)
| Some(_) => id
| None =>
let ret = global_index^;
global_table :=
Ident.add(id, (exported, Int32.of_int(ret), ty), global_table^);
global_index := ret + 1;
ret;
global_table := Ident.add(id, (exported, ty), global_table^);
id;
};

let global_name = slot => Printf.sprintf("global_%d", slot);
let global_name = id => Ident.unique_name(id);

let find_id = (id, env) =>
try(Ident.find_same(id, env.ce_binds)) {
| Not_found =>
let (_, slot, alloc) = Ident.find_same(id, global_table^);
MGlobalBind(global_name(Int32.to_int(slot)), alloc);
let (_, alloc) = Ident.find_same(id, global_table^);
MGlobalBind(global_name(id), alloc);
};

let worklist_reset = () => Queue.clear(compilation_worklist);
Expand Down Expand Up @@ -761,8 +755,8 @@ let compile_wrapper =
{func_idx, arity: Int32.of_int(arity + 1), variables: []};
};

let next_global = (~exported=false, id, ty) => {
let ret = next_global(exported, id, ty);
let get_global = (~exported=false, id, ty) => {
let ret = get_global(exported, id, ty);
global_name(ret);
};

Expand Down Expand Up @@ -994,7 +988,7 @@ and compile_anf_expr = (env, a) =>
switch (global) {
| Global({exported}) => (
env,
MGlobalBind(next_global(~exported, id, alloc), alloc),
MGlobalBind(get_global(~exported, id, alloc), alloc),
)
| Nonglobal => (
next_env,
Expand Down Expand Up @@ -1206,7 +1200,7 @@ let lift_imports = (env, imports) => {
| WasmFunction(mod_, name) =>
let exported = imp_exported == Global({exported: true});
let glob =
next_global(~exported, imp_use_id, Types.StackAllocated(WasmI32));
get_global(~exported, imp_use_id, Types.StackAllocated(WasmI32));
let new_mod = {
mimp_mod: Ident.create_persistent(mod_),
mimp_name: Ident.create_persistent(name),
Expand Down
2 changes: 1 addition & 1 deletion compiler/src/codegen/transl_anf.rei
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
open Grain_middle_end;

let global_name: int => string;
let global_name: Grain_typed.Ident.t => string;
let transl_anf_program: Anftree.anf_program => Mashtree.mash_program;

0 comments on commit 986eef8

Please sign in to comment.