@@ -25,6 +25,8 @@ type expression = Wasm_ast.expression Code_generation.t
2525module Type = struct
2626 let value = W. Ref { nullable = false ; typ = Eq }
2727
28+ let closure = W. Ref { nullable = false ; typ = Struct }
29+
2830 let block_type =
2931 register_type " block" (fun () ->
3032 return
@@ -203,7 +205,8 @@ module Type = struct
203205 let primitive_type n =
204206 { W. params = List. init ~len: n ~f: (fun _ -> value); result = [ value ] }
205207
206- let func_type n = primitive_type (n + 1 )
208+ let func_type n =
209+ { W. params = List. init ~len: n ~f: (fun _ -> value) @ [ closure ]; result = [ value ] }
207210
208211 let function_type ~cps n =
209212 let n = if cps then n + 1 else n in
@@ -327,7 +330,7 @@ module Type = struct
327330 (List. init
328331 ~f: (fun i ->
329332 { W. mut = i < function_count
330- ; typ = W. Value (Ref { nullable = false ; typ = Eq })
333+ ; typ = W. Value (Ref { nullable = false ; typ = Struct })
331334 })
332335 ~len: function_count
333336 @ make_env_type env_type)
@@ -441,6 +444,8 @@ module Value = struct
441444 let * t = Type. block_type in
442445 array_placeholder t
443446
447+ let dummy_closure = empty_struct
448+
444449 let as_block e =
445450 let * t = Type. block_type in
446451 let * e = e in
@@ -825,6 +830,15 @@ module Memory = struct
825830 | 0 | 1 -> 1
826831 | _ -> 2
827832
833+ let cast_closure ~cps ~arity closure =
834+ let arity = if cps then arity - 1 else arity in
835+ let * ty = Type. closure_type ~usage: `Access ~cps arity in
836+ wasm_cast ty closure
837+
838+ let cast_generic_closure closure =
839+ let * e = closure in
840+ return (W. RefCast ({ nullable = false ; typ = Struct }, e))
841+
828842 let load_function_pointer ~cps ~arity ?(skip_cast = false ) closure =
829843 let arity = if cps then arity - 1 else arity in
830844 let * ty = Type. closure_type ~usage: `Access ~cps arity in
@@ -1096,7 +1110,7 @@ module Closure = struct
10961110 if List. is_empty free_variables
10971111 then
10981112 if no_code_pointer
1099- then Value. unit
1113+ then Value. dummy_closure
11001114 else
11011115 let * typ = Type. closure_type ~usage: `Alloc ~cps arity in
11021116 let name = Code.Var. fork f in
@@ -1151,12 +1165,11 @@ module Closure = struct
11511165 tee
11521166 ~typ: (W. Ref { nullable = false ; typ = Type env_typ })
11531167 env
1154- (return
1168+ (let * dummy_closure = Value. dummy_closure in
1169+ return
11551170 (W. StructNew
11561171 ( env_typ
1157- , List. init ~len: function_count ~f: (fun _ ->
1158- W. RefI31 (W. Const (I32 0l )))
1159- @ l )))
1172+ , List. init ~len: function_count ~f: (fun _ -> dummy_closure) @ l )))
11601173 else
11611174 let * env = get_closure_env g in
11621175 let * () = set_closure_env f env in
@@ -1208,7 +1221,7 @@ module Closure = struct
12081221 if List. is_empty free_variables
12091222 then
12101223 (* The closures are all constants and the environment is empty. *)
1211- let * _ = add_var (Code.Var. fresh () ) in
1224+ let * _ = add_var ~typ: Type. closure (Code.Var. fresh () ) in
12121225 return ()
12131226 else
12141227 let env_type_id = Option. value ~default: (- 1 ) info.id in
@@ -1220,7 +1233,7 @@ module Closure = struct
12201233 let * typ =
12211234 Type. env_type ~cps ~arity ~no_code_pointer ~env_type_id ~env_type: []
12221235 in
1223- let * _ = add_var f in
1236+ let * _ = add_var ~typ: Type. closure f in
12241237 let env = Code.Var. fresh_n " env" in
12251238 let * () =
12261239 store
@@ -1247,7 +1260,7 @@ module Closure = struct
12471260 ~env_type_id
12481261 ~env_type: []
12491262 in
1250- let * _ = add_var f in
1263+ let * _ = add_var ~typ: Type. closure f in
12511264 let env = Code.Var. fresh_n " env" in
12521265 let * env_typ = Type. rec_env_type ~function_count ~env_type_id ~env_type: [] in
12531266 let * () =
0 commit comments