@@ -25,6 +25,8 @@ type expression = Wasm_ast.expression Code_generation.t
25
25
module Type = struct
26
26
let value = W. Ref { nullable = false ; typ = Eq }
27
27
28
+ let closure = W. Ref { nullable = false ; typ = Struct }
29
+
28
30
let block_type =
29
31
register_type " block" (fun () ->
30
32
return
@@ -203,7 +205,8 @@ module Type = struct
203
205
let primitive_type n =
204
206
{ W. params = List. init ~len: n ~f: (fun _ -> value); result = [ value ] }
205
207
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 ] }
207
210
208
211
let function_type ~cps n =
209
212
let n = if cps then n + 1 else n in
@@ -327,7 +330,7 @@ module Type = struct
327
330
(List. init
328
331
~f: (fun i ->
329
332
{ W. mut = i < function_count
330
- ; typ = W. Value (Ref { nullable = false ; typ = Eq })
333
+ ; typ = W. Value (Ref { nullable = false ; typ = Struct })
331
334
})
332
335
~len: function_count
333
336
@ make_env_type env_type)
@@ -441,6 +444,8 @@ module Value = struct
441
444
let * t = Type. block_type in
442
445
array_placeholder t
443
446
447
+ let dummy_closure = empty_struct
448
+
444
449
let as_block e =
445
450
let * t = Type. block_type in
446
451
let * e = e in
@@ -825,6 +830,15 @@ module Memory = struct
825
830
| 0 | 1 -> 1
826
831
| _ -> 2
827
832
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
+
828
842
let load_function_pointer ~cps ~arity ?(skip_cast = false ) closure =
829
843
let arity = if cps then arity - 1 else arity in
830
844
let * ty = Type. closure_type ~usage: `Access ~cps arity in
@@ -1096,7 +1110,7 @@ module Closure = struct
1096
1110
if List. is_empty free_variables
1097
1111
then
1098
1112
if no_code_pointer
1099
- then Value. unit
1113
+ then Value. dummy_closure
1100
1114
else
1101
1115
let * typ = Type. closure_type ~usage: `Alloc ~cps arity in
1102
1116
let name = Code.Var. fork f in
@@ -1151,12 +1165,11 @@ module Closure = struct
1151
1165
tee
1152
1166
~typ: (W. Ref { nullable = false ; typ = Type env_typ })
1153
1167
env
1154
- (return
1168
+ (let * dummy_closure = Value. dummy_closure in
1169
+ return
1155
1170
(W. StructNew
1156
1171
( 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 )))
1160
1173
else
1161
1174
let * env = get_closure_env g in
1162
1175
let * () = set_closure_env f env in
@@ -1208,7 +1221,7 @@ module Closure = struct
1208
1221
if List. is_empty free_variables
1209
1222
then
1210
1223
(* 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
1212
1225
return ()
1213
1226
else
1214
1227
let env_type_id = Option. value ~default: (- 1 ) info.id in
@@ -1220,7 +1233,7 @@ module Closure = struct
1220
1233
let * typ =
1221
1234
Type. env_type ~cps ~arity ~no_code_pointer ~env_type_id ~env_type: []
1222
1235
in
1223
- let * _ = add_var f in
1236
+ let * _ = add_var ~typ: Type. closure f in
1224
1237
let env = Code.Var. fresh_n " env" in
1225
1238
let * () =
1226
1239
store
@@ -1247,7 +1260,7 @@ module Closure = struct
1247
1260
~env_type_id
1248
1261
~env_type: []
1249
1262
in
1250
- let * _ = add_var f in
1263
+ let * _ = add_var ~typ: Type. closure f in
1251
1264
let env = Code.Var. fresh_n " env" in
1252
1265
let * env_typ = Type. rec_env_type ~function_count ~env_type_id ~env_type: [] in
1253
1266
let * () =
0 commit comments