Skip to content

Commit

Permalink
feat(compiler): Call known functions across module boundaries
Browse files Browse the repository at this point in the history
  • Loading branch information
ospencer committed Mar 22, 2022
1 parent fc61950 commit 07af6d5
Show file tree
Hide file tree
Showing 9 changed files with 329 additions and 195 deletions.
94 changes: 63 additions & 31 deletions compiler/src/codegen/comp_utils.re
Original file line number Diff line number Diff line change
Expand Up @@ -92,23 +92,32 @@ let grain_env_name = "_grainEnv";

let is_grain_env = str => grain_env_name == str;

let get_exported_names = (~local_names=?, wasm_mod) => {
let get_exported_names = (~local_functions=?, ~local_globals=?, wasm_mod) => {
let num_exports = Export.get_num_exports(wasm_mod);
let exported_names: Hashtbl.t(string, string) = Hashtbl.create(10);
for (i in 0 to num_exports - 1) {
let export = Export.get_export_by_index(wasm_mod, i);
let export_kind = Export.export_get_kind(export);
if (export_kind == Export.external_function
|| export_kind == Export.external_global) {
let exported_name = Export.get_name(export);
let internal_name = Export.get_value(export);
let exported_name = Export.get_name(export);
let internal_name = Export.get_value(export);

if (export_kind == Export.external_function) {
let new_internal_name =
switch (local_functions) {
| Some(local_functions) =>
Hashtbl.find(local_functions, internal_name)
| None => internal_name
};
Hashtbl.add(exported_names, exported_name, new_internal_name);
} else if (export_kind == Export.external_global) {
let new_internal_name =
switch (local_names) {
| Some(local_names) => Hashtbl.find(local_names, internal_name)
switch (local_globals) {
| Some(local_globals) => Hashtbl.find(local_globals, internal_name)
| None => internal_name
};
Hashtbl.add(exported_names, exported_name, new_internal_name);
};
();
};
exported_names;
};
Expand All @@ -133,47 +142,70 @@ let write_universal_exports =
List.iter(
item => {
switch (item) {
| TSigValue(id, {val_repr: ReprFunction(args, rets)}) =>
| TSigValue(
id,
{
val_repr: ReprFunction(args, rets, direct),
val_fullpath: path,
},
) =>
let name = Ident.name(id);
let exported_name = "GRAIN$EXPORT$" ++ name;
let internal_name = Hashtbl.find(exported_names, exported_name);
let internal_global_name =
Hashtbl.find(exported_names, exported_name);
let get_closure = () =>
Expression.Global_get.make(wasm_mod, internal_name, Type.int32);
Expression.Global_get.make(
wasm_mod,
internal_global_name,
Type.int32,
);
let arguments =
List.mapi(
(i, arg) =>
Expression.Local_get.make(wasm_mod, i, type_of_repr(arg)),
args,
);
let arguments = [get_closure(), ...arguments];
let call_arg_types =
Type.create(
Array.of_list(List.map(type_of_repr, [WasmI32, ...args])),
);
let call_result_types =
Type.create(
Array.of_list(
List.map(type_of_repr, rets == [] ? [WasmI32] : rets),
),
);
let func_ptr =
Expression.Load.make(
wasm_mod,
4,
8,
2,
Type.int32,
get_closure(),
);
let function_call =
Expression.Call_indirect.make(
wasm_mod,
global_function_table,
func_ptr,
arguments,
call_arg_types,
call_result_types,
);
switch (direct) {
| Direct(name) =>
Expression.Call.make(
wasm_mod,
Hashtbl.find(exported_names, name),
arguments,
call_result_types,
)
| _ =>
let call_arg_types =
Type.create(
Array.of_list(
List.map(type_of_repr, [WasmI32, ...args]),
),
);
let func_ptr =
Expression.Load.make(
wasm_mod,
4,
8,
2,
Type.int32,
get_closure(),
);
Expression.Call_indirect.make(
wasm_mod,
global_function_table,
func_ptr,
arguments,
call_arg_types,
call_result_types,
);
};
let function_body =
switch (rets) {
| [] => Expression.Drop.make(wasm_mod, function_call)
Expand Down
14 changes: 7 additions & 7 deletions compiler/src/codegen/compcore.re
Original file line number Diff line number Diff line change
Expand Up @@ -315,9 +315,8 @@ let get_wasm_imported_name = (~runtime_import=true, mod_, name) => {
Printf.sprintf("wimport_%s_%s", Ident.name(mod_), Ident.name(name));
};

let get_grain_imported_name = (mod_, name) => {
let get_grain_imported_name = (mod_, name) =>
Printf.sprintf("gimport_%s_%s", Ident.name(mod_), Ident.name(name));
};

let call_exception_printer = (wasm_mod, env, args) => {
let args = [
Expand Down Expand Up @@ -3314,14 +3313,15 @@ let compile_imports = (wasm_mod, env, {imports}) => {
| MImportWasm => Ident.name(name)
| MImportGrain => "GRAIN$MODULE$" ++ Ident.name(name);

let compile_import_name = name =>
fun
| MImportWasm => Ident.name(name)
| MImportGrain => "GRAIN$EXPORT$" ++ Ident.name(name);
let compile_import_name = (name, kind, ty) =>
switch (kind, ty) {
| (MImportGrain, MGlobalImport(_)) => "GRAIN$EXPORT$" ++ Ident.name(name)
| _ => Ident.name(name)
};

let compile_import = ({mimp_mod, mimp_name, mimp_type, mimp_kind}) => {
let module_name = compile_module_name(mimp_mod, mimp_kind);
let item_name = compile_import_name(mimp_name, mimp_kind);
let item_name = compile_import_name(mimp_name, mimp_kind, mimp_type);
let internal_name =
switch (mimp_kind) {
| MImportGrain => get_grain_imported_name(mimp_mod, mimp_name)
Expand Down
Loading

0 comments on commit 07af6d5

Please sign in to comment.