@@ -153,36 +153,6 @@ let load =
153153 );
154154};
155155
156- let is_grain_env = str => grain_env_name == str;
157-
158- let get_exported_names = (~function_names=?, ~global_names=?, wasm_mod) => {
159- let num_exports = Export . get_num_exports(wasm_mod);
160- let exported_names : Hashtbl . t (string , string ) = Hashtbl . create(10 );
161- for (i in 0 to num_exports - 1 ) {
162- let export = Export . get_export_by_index(wasm_mod, i);
163- let export_kind = Export . export_get_kind(export);
164- let exported_name = Export . get_name(export);
165- let internal_name = Export . get_value(export);
166-
167- if (export_kind == Export . external_function) {
168- let new_internal_name =
169- switch (function_names) {
170- | Some (function_names ) => Hashtbl . find(function_names, internal_name)
171- | None => internal_name
172- };
173- Hashtbl . add(exported_names, exported_name, new_internal_name);
174- } else if (export_kind == Export . external_global) {
175- let new_internal_name =
176- switch (global_names) {
177- | Some (global_names ) => Hashtbl . find(global_names, internal_name)
178- | None => internal_name
179- };
180- Hashtbl . add(exported_names, exported_name, new_internal_name);
181- };
182- };
183- exported_names;
184- };
185-
186156let type_of_repr = repr => {
187157 Types . (
188158 switch (repr) {
@@ -195,152 +165,147 @@ let type_of_repr = repr => {
195165};
196166
197167let write_universal_exports =
198- (wasm_mod, {Cmi_format . cmi_sign}, exported_names) => {
199- Types . (
200- Type_utils . (
201- List . iter(
202- item => {
203- switch (item) {
204- | TSigValue (
205- id ,
206- {
207- val_repr: ReprFunction (args , rets , direct ),
208- val_fullpath: path ,
209- },
210- ) =>
211- let name = Ident . name(id);
212- let exported_name = "GRAIN$EXPORT$" ++ name;
213- let internal_global_name =
214- Hashtbl . find(exported_names, exported_name);
215- let get_closure = () =>
216- Expression . Global_get . make(
168+ (wasm_mod, {Cmi_format . cmi_sign}, exports, resolve) => {
169+ open Types ;
170+ open Type_utils ;
171+ let export_map = Hashtbl . create(128 );
172+ List . iter(
173+ e => {
174+ switch (e) {
175+ | WasmGlobalExport ({ex_global_name, ex_global_internal_name}) =>
176+ Hashtbl . add(
177+ export_map,
178+ ex_global_name,
179+ resolve(ex_global_internal_name),
180+ )
181+ // All functions have an associated global
182+ | WasmFunctionExport (_ ) => ()
183+ }
184+ },
185+ exports,
186+ );
187+ List . iter(
188+ item => {
189+ switch (item) {
190+ | TSigValue (id , {val_repr: ReprFunction (args , rets , direct )}) =>
191+ let name = Ident . name(id);
192+ let internal_name = Hashtbl . find(export_map, name);
193+ let get_closure = () =>
194+ Expression . Global_get . make(wasm_mod, internal_name, Type . int32);
195+ let arguments =
196+ List . mapi(
197+ (i, arg) =>
198+ Expression . Local_get . make(wasm_mod, i, type_of_repr(arg)),
199+ args,
200+ );
201+ let arguments = [ get_closure() , ... arguments] ;
202+ let call_result_types =
203+ Type . create(
204+ Array . of_list(
205+ List . map(type_of_repr, rets == [] ? [ WasmI32 ] : rets),
206+ ),
207+ );
208+ let function_call =
209+ switch (direct) {
210+ | Direct ({name}) =>
211+ Expression . Call . make(
212+ wasm_mod,
213+ internal_name,
214+ arguments,
215+ call_result_types,
216+ )
217+ | Indirect =>
218+ let call_arg_types =
219+ Type . create(
220+ Array . of_list(List . map(type_of_repr, [ WasmI32 , ... args] )),
221+ );
222+ let func_ptr =
223+ Expression . Load . make(
217224 wasm_mod,
218- internal_global_name,
225+ 4 ,
226+ 8 ,
227+ 2 ,
219228 Type . int32,
229+ get_closure() ,
230+ grain_memory,
220231 );
221- let arguments =
222- List . mapi(
223- (i, arg) =>
224- Expression . Local_get . make(wasm_mod, i, type_of_repr(arg)),
225- args,
226- );
227- let arguments = [ get_closure() , ... arguments] ;
228- let call_result_types =
229- Type . create(
230- Array . of_list(
231- List . map(type_of_repr, rets == [] ? [ WasmI32 ] : rets),
232+ Expression . Call_indirect . make(
233+ wasm_mod,
234+ grain_global_function_table,
235+ func_ptr,
236+ arguments,
237+ call_arg_types,
238+ call_result_types,
239+ );
240+ | Unknown => failwith ("Impossible: Unknown function call type" )
241+ };
242+ let function_body =
243+ switch (rets) {
244+ | [] => Expression . Drop . make(wasm_mod, function_call)
245+ | _ => function_call
246+ };
247+ let function_body =
248+ Expression . Block . make(
249+ wasm_mod,
250+ "closure_incref" ,
251+ [
252+ Expression . If . make(
253+ wasm_mod,
254+ Expression . Binary . make(
255+ wasm_mod,
256+ Op . ne_int32,
257+ get_closure() ,
258+ Expression . Const . make(wasm_mod, Literal . int32(0 l)),
232259 ),
233- );
234- let function_call =
235- switch (direct) {
236- | Direct ({name}) =>
237- Expression . Call . make(
260+ store(
238261 wasm_mod,
239- Hashtbl . find(exported_names, name),
240- arguments,
241- call_result_types,
242- )
243- | Indirect =>
244- let call_arg_types =
245- Type . create(
246- Array . of_list(
247- List . map(type_of_repr, [ WasmI32 , ... args] ),
248- ),
249- );
250- let func_ptr =
251- Expression . Load . make(
262+ Expression . Binary . make(
252263 wasm_mod,
253- 4 ,
254- 8 ,
255- 2 ,
256- Type . int32,
264+ Op . sub_int32,
257265 get_closure() ,
258- grain_memory,
259- );
260- Expression . Call_indirect . make(
261- wasm_mod,
262- grain_global_function_table,
263- func_ptr,
264- arguments,
265- call_arg_types,
266- call_result_types,
267- );
268- | Unknown => failwith ("Impossible: Unknown function call type" )
269- };
270- let function_body =
271- switch (rets) {
272- | [] => Expression . Drop . make(wasm_mod, function_call)
273- | _ => function_call
274- };
275- let function_body =
276- Expression . Block . make(
277- wasm_mod,
278- "closure_incref" ,
279- [
280- Expression . If . make(
266+ Expression . Const . make(wasm_mod, Literal . int32(8 l)),
267+ ),
268+ Expression . Binary . make(
281269 wasm_mod,
282- Expression . Binary . make(
283- wasm_mod,
284- Op . ne_int32,
285- get_closure() ,
286- Expression . Const . make(wasm_mod, Literal . int32(0 l)),
287- ),
288- store(
270+ Op . add_int32,
271+ load(
289272 wasm_mod,
290273 Expression . Binary . make(
291274 wasm_mod,
292275 Op . sub_int32,
293276 get_closure() ,
294277 Expression . Const . make(wasm_mod, Literal . int32(8 l)),
295278 ),
296- Expression . Binary . make(
297- wasm_mod,
298- Op . add_int32,
299- load(
300- wasm_mod,
301- Expression . Binary . make(
302- wasm_mod,
303- Op . sub_int32,
304- get_closure() ,
305- Expression . Const . make(
306- wasm_mod,
307- Literal . int32(8 l),
308- ),
309- ),
310- ),
311- Expression . Const . make(wasm_mod, Literal . int32(1 l)),
312- ),
313279 ),
314- Expression . Null . make() ,
280+ Expression . Const . make(wasm_mod , Literal . int32( 1 l) ),
315281 ),
316- function_body,
317- ] ,
318- );
319- let arg_types =
320- Type . create(Array . of_list(List . map(type_of_repr, args)));
321- let result_types =
322- Type . create(Array . of_list(List . map(type_of_repr, rets)));
323- ignore @@
324- Function . add_function(
325- wasm_mod,
326- name,
327- arg_types,
328- result_types,
329- [||] ,
282+ ),
283+ Expression . Null . make() ,
284+ ),
330285 function_body,
331- );
332- // Remove existing Grain export (if any)
333- Export . remove_export(wasm_mod, name);
334- ignore @@ Export . add_function_export(wasm_mod, name, name);
335- | TSigValue (_ )
336- | TSigType (_ )
337- | TSigTypeExt (_ )
338- | TSigModule (_ )
339- | TSigModType (_ ) => ()
340- }
341- },
342- cmi_sign,
343- )
344- )
286+ ] ,
287+ );
288+ let arg_types =
289+ Type . create(Array . of_list(List . map(type_of_repr, args)));
290+ let result_types =
291+ Type . create(Array . of_list(List . map(type_of_repr, rets)));
292+ ignore @@
293+ Function . add_function(
294+ wasm_mod,
295+ name,
296+ arg_types,
297+ result_types,
298+ [||] ,
299+ function_body,
300+ );
301+ ignore @@ Export . add_function_export(wasm_mod, name, name);
302+ | TSigValue (_ )
303+ | TSigType (_ )
304+ | TSigTypeExt (_ )
305+ | TSigModule (_ )
306+ | TSigModType (_ ) => ()
307+ }
308+ },
309+ cmi_sign,
345310 );
346311};
0 commit comments