@@ -188,6 +188,13 @@ function assert_return(action, ...expected) {
188188| }
189189
190190
191+ (* Errors & Tracing *)
192+
193+ module Error = Error. Make ()
194+
195+ exception Error = Error. Error
196+
197+
191198(* Context *)
192199
193200module NameMap = Map. Make (struct type t = Ast. name let compare = compare end )
@@ -217,12 +224,26 @@ let bind (mods : modules) x_opt m =
217224let lookup (mods : modules ) x_opt name at =
218225 let exports =
219226 try Map. find (of_var_opt mods x_opt) mods.env with Not_found ->
220- raise ( Eval. Crash (at,
221- if x_opt = None then " no module defined within script"
222- else " unknown module " ^ of_var_opt mods x_opt ^ " within script" ) )
227+ Error. error at
228+ ( if x_opt = None then " no module defined within script"
229+ else " unknown module " ^ of_var_opt mods x_opt ^ " within script" )
223230 in try NameMap. find name exports with Not_found ->
224- raise (Eval. Crash (at, " unknown export \" " ^
225- string_of_name name ^ " \" within module" ))
231+ Error. error at (" unknown export \" " ^
232+ string_of_name name ^ " \" within module" )
233+
234+ let lookup_func (mods : modules ) x_opt name at =
235+ match lookup mods x_opt name at with
236+ | ExternFuncType ft -> ft
237+ | _ ->
238+ Error. error at (" export \" " ^
239+ string_of_name name ^ " \" is not a function" )
240+
241+ let lookup_global (mods : modules ) x_opt name at =
242+ match lookup mods x_opt name at with
243+ | ExternGlobalType gt -> gt
244+ | _ ->
245+ Error. error at (" export \" " ^
246+ string_of_name name ^ " \" is not a global" )
226247
227248
228249(* Wrappers *)
@@ -259,21 +280,34 @@ let abs_mask_of = function
259280 | I32Type | F32Type -> Values. I32 Int32. max_int
260281 | I64Type | F64Type -> Values. I64 Int64. max_int
261282
262- let value v =
263- match v.it with
264- | Values. Num n -> [Const (n @@ v.at) @@ v.at]
265- | Values. Vec s -> [VecConst (s @@ v.at) @@ v.at]
266- | Values. Ref (Values. NullRef t ) -> [RefNull t @@ v.at]
283+ (*
284+ let literal lit =
285+ match lit.it with
286+ | Values.Num n -> [Const (n @@ lit.at) @@ lit.at]
287+ | Values.Vec s -> [VecConst (s @@ lit.at) @@ lit.at]
288+ | Values.Ref (Values.NullRef t) -> [RefNull t @@ lit.at]
267289 | Values.Ref (ExternRef n) ->
268- [Const (Values. I32 n @@ v.at) @@ v.at; Call (externref_idx @@ v.at) @@ v.at]
290+ [ Const (Values.I32 n @@ lit.at) @@ lit.at;
291+ Call (externref_idx @@ lit.at) @@ lit.at;
292+ ]
269293 | Values.Ref _ -> assert false
270-
271- let invoke ft vs at =
272- [ft @@ at], FuncImport (subject_type_idx @@ at) @@ at,
273- List. concat (List. map value vs) @ [Call (subject_idx @@ at) @@ at]
294+ *)
274295
275296let get t at =
276- [] , GlobalImport t @@ at, [GlobalGet (subject_idx @@ at) @@ at]
297+ [] , GlobalImport t @@ at, [] , [GlobalGet (subject_idx @@ at) @@ at]
298+
299+ let invoke ft at =
300+ let FuncType (ts, _) = ft in
301+ [ft @@ at], FuncImport (subject_type_idx @@ at) @@ at,
302+ List. mapi (fun i t ->
303+ { module_name = Utf8. decode " arg" ;
304+ item_name = Utf8. decode (string_of_int i);
305+ idesc = GlobalImport (GlobalType (t, Immutable )) @@ at;
306+ } @@ at
307+ ) ts,
308+ List. concat
309+ (Lib.List32. mapi (fun i _ -> [GlobalGet (i @@ at) @@ at]) ts) @
310+ [Call (subject_idx @@ at) @@ at]
277311
278312let run ts at =
279313 [] , []
@@ -378,7 +412,7 @@ let assert_return ress ts at =
378412 in [] , List. flatten (List. rev_map test ress)
379413
380414let wrap item_name wrap_action wrap_assertion at =
381- let itypes, idesc, action = wrap_action at in
415+ let itypes, idesc, iargs, action = wrap_action at in
382416 let locals, assertion = wrap_assertion at in
383417 let types =
384418 (FuncType ([] , [] ) @@ at) ::
@@ -400,7 +434,8 @@ let wrap item_name wrap_action wrap_assertion at =
400434 {module_name = Utf8. decode " spectest" ; item_name = Utf8. decode " eq_externref" ;
401435 idesc = FuncImport (4l @@ at) @@ at} @@ at;
402436 {module_name = Utf8. decode " spectest" ; item_name = Utf8. decode " eq_funcref" ;
403- idesc = FuncImport (5l @@ at) @@ at} @@ at ]
437+ idesc = FuncImport (5l @@ at) @@ at} @@ at;
438+ ] @ iargs
404439 in
405440 let item =
406441 List. fold_left
@@ -429,10 +464,10 @@ let is_js_value_type = function
429464 | RefType t -> true
430465
431466let is_js_global_type = function
432- | GlobalType (t , mut ) -> is_js_value_type t && mut = Immutable
467+ | GlobalType (t , mut ) -> is_js_value_type t
433468
434469let is_js_func_type = function
435- | FuncType (ins , out ) -> List. for_all is_js_value_type (ins @ out )
470+ | FuncType (ts1 , ts2 ) -> List. for_all is_js_value_type (ts1 @ ts2 )
436471
437472
438473(* Script conversion *)
@@ -473,14 +508,19 @@ let of_num n =
473508 let open Values in
474509 match n with
475510 | I32 i -> I32. to_string_s i
476- | I64 i -> " int64( \" " ^ I64. to_string_s i ^ " \" ) "
511+ | I64 i -> I64. to_string_s i ^ " n "
477512 | F32 z -> of_float (F32. to_float z)
478513 | F64 z -> of_float (F64. to_float z)
479514
480515let of_vec v =
481- let open Values in
482- match v with
483- | V128 v -> " v128(\" " ^ V128. to_string v ^ " \" )"
516+ let at = Source. no_region in
517+ let gtype = GlobalType (VecType (Values. type_of_vec v), Immutable ) in
518+ let ginit = [VecConst (v @@ at) @@ at] @@ at in
519+ let globals = [{gtype; ginit} @@ at] in
520+ let edesc = GlobalExport (0l @@ at) @@ at in
521+ let exports = [{name = Utf8. decode " v128" ; edesc} @@ at] in
522+ let bs = Encode. encode ({empty_module with globals; exports} @@ at) in
523+ " instance(" ^ of_bytes bs ^ " ).exports.v128"
484524
485525let of_ref r =
486526 let open Values in
@@ -489,9 +529,9 @@ let of_ref r =
489529 | ExternRef n -> " externref(" ^ Int32. to_string n ^ " )"
490530 | _ -> assert false
491531
492- let of_value v =
532+ let of_literal lit =
493533 let open Values in
494- match v .it with
534+ match lit .it with
495535 | Num n -> of_num n
496536 | Vec v -> of_vec v
497537 | Ref r -> of_ref r
@@ -529,43 +569,52 @@ let rec of_definition def =
529569 try of_definition (Parse. string_to_module s) with Parse. Syntax _ ->
530570 of_bytes " <malformed quote>"
531571
532- let of_wrapper mods x_opt name wrap_action wrap_assertion at =
572+ let of_arg_import i opd =
573+ " arg" ^ string_of_int i ^ " : " ^ opd
574+
575+ let of_wrapper mods x_opt name wrap_action opds wrap_assertion at =
533576 let x = of_var_opt mods x_opt in
534577 let bs = wrap name wrap_action wrap_assertion at in
535- " call(instance(" ^ of_bytes bs ^ " , " ^
536- " exports(" ^ x ^ " )), " ^ " \" run\" , [])"
578+ let exs = if opds = [] then " exports(" ^ x ^ " )" else
579+ " {...exports(" ^ x ^ " ), " ^
580+ " args: [" ^ String. concat " , " (List. mapi of_arg_import opds) ^ " ]}"
581+ in " call(instance(" ^ of_bytes bs ^ " , " ^ exs ^ " ), \" run\" , [])"
537582
538- let of_action mods act =
583+ let rec of_action mods act =
539584 match act.it with
540- | Invoke (x_opt , name , vs ) ->
585+ | Invoke (x_opt , name , args ) ->
541586 " call(" ^ of_var_opt mods x_opt ^ " , " ^ of_name name ^ " , " ^
542- " [" ^ String. concat " , " (List. map of_value vs) ^ " ])" ,
543- (match lookup mods x_opt name act.at with
544- | ExternFuncType ft when not (is_js_func_type ft) ->
545- let FuncType (_, out) = ft in
546- Some (of_wrapper mods x_opt name (invoke ft vs), out)
547- | _ -> None
548- )
587+ " [" ^ String. concat " , " (List. map (of_arg mods) args) ^ " ].flat())" ,
588+ let FuncType (_, ts2) as ft = lookup_func mods x_opt name act.at in
589+ if is_js_func_type ft then None else
590+ let opds = List. map (of_arg mods) args in
591+ Some (of_wrapper mods x_opt name (invoke ft) opds, ts2)
549592 | Get (x_opt , name ) ->
550593 " get(" ^ of_var_opt mods x_opt ^ " , " ^ of_name name ^ " )" ,
551- (match lookup mods x_opt name act.at with
552- | ExternGlobalType gt when not (is_js_global_type gt) ->
553- let GlobalType (t, _) = gt in
554- Some (of_wrapper mods x_opt name (get gt), [t])
555- | _ -> None
556- )
594+ let GlobalType (t, _) as gt = lookup_global mods x_opt name act.at in
595+ if is_js_global_type gt then None else
596+ Some (of_wrapper mods x_opt name (get gt) [] , [t])
597+
598+ and of_arg mods arg =
599+ match arg.it with
600+ | LiteralArg lit -> of_literal lit
601+ | ActionArg act ->
602+ let act_js, act_wrapper_opt = of_action mods act in
603+ match act_wrapper_opt with
604+ | None -> act_js
605+ | Some (act_wrapper , ts ) -> act_wrapper (run ts) act.at
557606
558607let of_assertion' mods act name args wrapper_opt =
559608 let act_js, act_wrapper_opt = of_action mods act in
560609 let js = name ^ " (() => " ^ act_js ^ String. concat " , " (" " :: args) ^ " )" in
561610 match act_wrapper_opt with
562611 | None -> js ^ " ;"
563- | Some (act_wrapper , out ) ->
612+ | Some (act_wrapper , ts ) ->
564613 let run_name, wrapper =
565614 match wrapper_opt with
566615 | None -> name, run
567616 | Some wrapper -> " run" , wrapper
568- in run_name ^ " (() => " ^ act_wrapper (wrapper out ) act.at ^ " ); // " ^ js
617+ in run_name ^ " (() => " ^ act_wrapper (wrapper ts ) act.at ^ " ); // " ^ js
569618
570619let of_assertion mods ass =
571620 match ass.it with
0 commit comments