@@ -240,18 +240,7 @@ module Type = struct
240240 then
241241 register_type
242242 (if cps then " cps_closure_0" else " closure_0" )
243- (fun () ->
244- let * fun_ty' = function_type ~cps arity in
245- return
246- { supertype = None
247- ; final = false
248- ; typ =
249- W. Struct
250- [ { mut = false
251- ; typ = Value (Ref { nullable = false ; typ = Type fun_ty' })
252- }
253- ]
254- })
243+ (fun () -> return { supertype = None ; final = false ; typ = W. Struct [] })
255244 else
256245 register_type
257246 (if cps
@@ -287,30 +276,29 @@ module Type = struct
287276 then Printf. sprintf " cps_env_%d_%d" arity env_type_id
288277 else Printf. sprintf " env_%d_%d" arity env_type_id)
289278 (fun () ->
290- let * cl_typ = closure_type ~usage: `Alloc ~cps arity in
291- let * common = closure_common_fields ~cps in
292- let * fun_ty' = function_type ~cps arity in
293- return
294- { supertype = Some cl_typ
295- ; final = true
296- ; typ =
297- W. Struct
298- ((if arity = 1
299- then common
300- else if arity = 0
301- then
302- [ { mut = false
303- ; typ = Value (Ref { nullable = false ; typ = Type fun_ty' })
304- }
305- ]
306- else
307- common
308- @ [ { mut = false
309- ; typ = Value (Ref { nullable = false ; typ = Type fun_ty' })
310- }
311- ])
312- @ make_env_type env_type)
313- })
279+ if arity = 0
280+ then
281+ return
282+ { supertype = None ; final = true ; typ = W. Struct (make_env_type env_type) }
283+ else
284+ let * common = closure_common_fields ~cps in
285+ let * cl_typ = closure_type ~usage: `Alloc ~cps arity in
286+ let * fun_ty' = function_type ~cps arity in
287+ return
288+ { supertype = Some cl_typ
289+ ; final = true
290+ ; typ =
291+ W. Struct
292+ ((if arity = 1
293+ then common
294+ else
295+ common
296+ @ [ { mut = false
297+ ; typ = Value (Ref { nullable = false ; typ = Type fun_ty' })
298+ }
299+ ])
300+ @ make_env_type env_type)
301+ })
314302
315303 let rec_env_type ~function_count ~env_type_id ~env_type =
316304 register_type (Printf. sprintf " rec_env_%d_%d" function_count env_type_id) (fun () ->
@@ -334,28 +322,41 @@ module Type = struct
334322 then Printf. sprintf " cps_closure_rec_%d_%d_%d" arity function_count env_type_id
335323 else Printf. sprintf " closure_rec_%d_%d_%d" arity function_count env_type_id)
336324 (fun () ->
337- let * cl_typ = closure_type ~usage: `Alloc ~cps arity in
338- let * common = closure_common_fields ~cps in
339- let * fun_ty' = function_type ~cps arity in
340325 let * env_ty = rec_env_type ~function_count ~env_type_id ~env_type in
341- return
342- { supertype = Some cl_typ
343- ; final = true
344- ; typ =
345- W. Struct
346- ((if arity = 1
347- then common
348- else
349- common
350- @ [ { mut = false
351- ; typ = Value (Ref { nullable = false ; typ = Type fun_ty' })
352- }
353- ])
354- @ [ { W. mut = false
326+ if arity = 0
327+ then
328+ return
329+ { supertype = None
330+ ; final = true
331+ ; typ =
332+ W. Struct
333+ [ { W. mut = false
355334 ; typ = W. Value (Ref { nullable = false ; typ = Type env_ty })
356335 }
357- ])
358- })
336+ ]
337+ }
338+ else
339+ let * cl_typ = closure_type ~usage: `Alloc ~cps arity in
340+ let * common = closure_common_fields ~cps in
341+ let * fun_ty' = function_type ~cps arity in
342+ return
343+ { supertype = Some cl_typ
344+ ; final = true
345+ ; typ =
346+ W. Struct
347+ ((if arity = 1
348+ then common
349+ else
350+ common
351+ @ [ { mut = false
352+ ; typ = Value (Ref { nullable = false ; typ = Type fun_ty' })
353+ }
354+ ])
355+ @ [ { W. mut = false
356+ ; typ = W. Value (Ref { nullable = false ; typ = Type env_ty })
357+ }
358+ ])
359+ })
359360
360361 let rec curry_type ~cps arity m =
361362 register_type
@@ -800,7 +801,8 @@ module Memory = struct
800801
801802 let env_start arity =
802803 match arity with
803- | 0 | 1 -> 1
804+ | 0 -> 0
805+ | 1 -> 1
804806 | _ -> 2
805807
806808 let load_function_pointer ~cps ~arity ?(skip_cast = false ) closure =
@@ -1053,7 +1055,7 @@ module Closure = struct
10531055 | [ (g, _) ] -> Code.Var. equal f g
10541056 | _ :: r -> is_last_fun r f
10551057
1056- let translate ~context ~closures ~cps f =
1058+ let translate ~context ~closures ~cps ~ need_pointer f =
10571059 let info = Code.Var.Map. find f closures in
10581060 let free_variables = get_free_variables ~context info in
10591061 assert (
@@ -1062,7 +1064,7 @@ module Closure = struct
10621064 ~f: (fun x -> Code.Var.Set. mem x context.globalized_variables)
10631065 free_variables));
10641066 let _, arity = List. find ~f: (fun (f' , _ ) -> Code.Var. equal f f') info.functions in
1065- let arity = if cps then arity - 1 else arity in
1067+ let arity = if need_pointer then if cps then arity - 1 else arity else 0 in
10661068 let * curry_fun = if arity > 1 then need_curry_fun ~cps ~arity else return f in
10671069 if List. is_empty free_variables
10681070 then
@@ -1075,7 +1077,8 @@ module Closure = struct
10751077 (W. StructNew
10761078 ( typ
10771079 , match arity with
1078- | 0 | 1 -> [ W. RefFunc f ]
1080+ | 0 -> []
1081+ | 1 -> [ W. RefFunc f ]
10791082 | _ -> [ RefFunc curry_fun; RefFunc f ] ))
10801083 in
10811084 return (W. GlobalGet name)
@@ -1098,7 +1101,8 @@ module Closure = struct
10981101 (W. StructNew
10991102 ( typ
11001103 , (match arity with
1101- | 0 | 1 -> [ W. RefFunc f ]
1104+ | 0 -> []
1105+ | 1 -> [ W. RefFunc f ]
11021106 | _ -> [ RefFunc curry_fun; RefFunc f ])
11031107 @ l ))
11041108 | (g , _ ) :: _ as functions ->
@@ -1132,9 +1136,10 @@ module Closure = struct
11321136 return
11331137 (W. StructNew
11341138 ( typ
1135- , (if arity = 1
1136- then [ W. RefFunc f ]
1137- else [ RefFunc curry_fun; RefFunc f ])
1139+ , (match arity with
1140+ | 0 -> []
1141+ | 1 -> [ W. RefFunc f ]
1142+ | _ -> [ RefFunc curry_fun; RefFunc f ])
11381143 @ [ env ] ))
11391144 in
11401145 if is_last_fun functions f
@@ -1155,7 +1160,7 @@ module Closure = struct
11551160 (load f)
11561161 else res
11571162
1158- let bind_environment ~context ~closures ~cps f =
1163+ let bind_environment ~context ~closures ~cps ~ need_pointer f =
11591164 let info = Code.Var.Map. find f closures in
11601165 let free_variables = get_free_variables ~context info in
11611166 let free_variable_count = List. length free_variables in
@@ -1167,7 +1172,7 @@ module Closure = struct
11671172 else
11681173 let env_type_id = Option. value ~default: (- 1 ) info.id in
11691174 let _, arity = List. find ~f: (fun (f' , _ ) -> Code.Var. equal f f') info.functions in
1170- let arity = if cps then arity - 1 else arity in
1175+ let arity = if need_pointer then if cps then arity - 1 else arity else 0 in
11711176 let offset = Memory. env_start arity in
11721177 match info.Closure_conversion. functions with
11731178 | [ _ ] ->
0 commit comments