@@ -117,9 +117,20 @@ let mut_from_env env ptr =
117
117
else Asttypes. Mutable
118
118
| _ -> Asttypes. Mutable
119
119
120
- let get_field env ptr n dbg =
120
+ let get_field env layout ptr n dbg =
121
121
let mut = mut_from_env env ptr in
122
- get_field_gen mut ptr n dbg
122
+ let memory_chunk =
123
+ match layout with
124
+ | Pvalue Pintval | Punboxed_int _ -> Word_int
125
+ | Pvalue _ -> Word_val
126
+ | Punboxed_float -> Double
127
+ | Ptop ->
128
+ Misc. fatal_errorf " get_field with Ptop: %a" Debuginfo. print_compact dbg
129
+ | Pbottom ->
130
+ Misc. fatal_errorf " get_field with Pbottom: %a" Debuginfo. print_compact
131
+ dbg
132
+ in
133
+ get_field_gen_given_memory_chunk memory_chunk mut ptr n dbg
123
134
124
135
type rhs_kind =
125
136
| RHS_block of Lambda .alloc_mode * int
@@ -448,9 +459,19 @@ let rec transl env e =
448
459
| Ugeneric_apply (clos , args , args_layout , result_layout , kind , dbg ) ->
449
460
let clos = transl env clos in
450
461
let args = List. map (transl env) args in
451
- let args_type = List. map machtype_of_layout args_layout in
452
- let return = machtype_of_layout result_layout in
453
- generic_apply (mut_from_env env clos) clos args args_type return kind dbg
462
+ if List. mem Pbottom args_layout then
463
+ (* [machtype_of_layout] will fail on Pbottom, convert it to a sequence
464
+ and remove the call, preserving the execution order. *)
465
+ List. fold_left2 (fun rest arg arg_layout ->
466
+ if arg_layout = Pbottom then
467
+ arg
468
+ else
469
+ Csequence (remove_unit arg, rest)
470
+ ) (Ctuple [] ) args args_layout
471
+ else
472
+ let args_type = List. map machtype_of_layout args_layout in
473
+ let return = machtype_of_layout result_layout in
474
+ generic_apply (mut_from_env env clos) clos args args_type return kind dbg
454
475
| Usend (kind , met , obj , args , args_layout , result_layout , pos , dbg ) ->
455
476
let met = transl env met in
456
477
let obj = transl env obj in
@@ -596,6 +617,7 @@ let rec transl env e =
596
617
| Pandbint _ | Porbint _ | Pxorbint _ | Plslbint _ | Plsrbint _
597
618
| Pasrbint _ | Pbintcomp (_, _) | Pstring_load _ | Pbytes_load _
598
619
| Pbytes_set _ | Pbigstring_load _ | Pbigstring_set _
620
+ | Punbox_float | Pbox_float _ | Punbox_int _ | Pbox_int _
599
621
| Pbbswap _), _)
600
622
->
601
623
fatal_error " Cmmgen.transl:prim"
@@ -731,27 +753,38 @@ and transl_catch (kind : Cmm.value_kind) env nfail ids body handler dbg =
731
753
each argument. *)
732
754
let report args =
733
755
List. iter2
734
- (fun (_id , Pvalue kind , u ) c ->
735
- let strict =
736
- match kind with
737
- | Pfloatval | Pboxedintval _ -> false
738
- | Pintval | Pgenval | Pvariant _ | Parrayval _ -> true
739
- in
740
- u := join_unboxed_number_kind ~strict ! u
741
- (is_unboxed_number_cmm ~strict c)
756
+ (fun (id , (layout : Lambda.layout ), u ) c ->
757
+ match layout with
758
+ | Ptop ->
759
+ Misc. fatal_errorf " Variable %a with layout [Ptop] can't be compiled"
760
+ VP. print id
761
+ | Pbottom ->
762
+ Misc. fatal_errorf
763
+ " Variable %a with layout [Pbottom] can't be compiled"
764
+ VP. print id
765
+ | Punboxed_float | Punboxed_int _ ->
766
+ u := No_unboxing
767
+ | Pvalue kind ->
768
+ let strict =
769
+ match kind with
770
+ | Pfloatval | Pboxedintval _ -> false
771
+ | Pintval | Pgenval | Pvariant _ | Parrayval _ -> true
772
+ in
773
+ u := join_unboxed_number_kind ~strict ! u
774
+ (is_unboxed_number_cmm ~strict c)
742
775
)
743
776
ids args
744
777
in
745
778
let env_body = add_notify_catch nfail report env in
746
779
let body = transl env_body body in
747
780
let new_env, rewrite, ids =
748
781
List. fold_right
749
- (fun (id , _kind , u ) (env , rewrite , ids ) ->
782
+ (fun (id , layout , u ) (env , rewrite , ids ) ->
750
783
match ! u with
751
784
| No_unboxing | Boxed (_ , true ) | No_result ->
752
785
env,
753
786
(fun x -> x) :: rewrite,
754
- (id, Cmm. typ_val ) :: ids
787
+ (id, machtype_of_layout layout ) :: ids
755
788
| Boxed (bn , false ) ->
756
789
let unboxed_id = V. create_local (VP. name id) in
757
790
add_unboxed_id (VP. var id) unboxed_id bn env,
@@ -847,8 +880,8 @@ and transl_prim_1 env p arg dbg =
847
880
Popaque ->
848
881
opaque (transl env arg) dbg
849
882
(* Heap operations *)
850
- | Pfield n ->
851
- get_field env (transl env arg) n dbg
883
+ | Pfield ( n , layout ) ->
884
+ get_field env layout (transl env arg) n dbg
852
885
| Pfloatfield (n ,mode ) ->
853
886
let ptr = transl env arg in
854
887
box_float dbg mode (floatfield n ptr dbg)
@@ -864,7 +897,15 @@ and transl_prim_1 env p arg dbg =
864
897
offsetint n (transl env arg) dbg
865
898
| Poffsetref n ->
866
899
offsetref n (transl env arg) dbg
900
+ | Punbox_int bi ->
901
+ transl_unbox_int dbg env bi arg
902
+ | Pbox_int (bi , m ) ->
903
+ box_int dbg bi m (transl env arg)
867
904
(* Floating-point operations *)
905
+ | Punbox_float ->
906
+ transl_unbox_float dbg env arg
907
+ | Pbox_float m ->
908
+ box_float dbg m (transl env arg)
868
909
| Pfloatofint m ->
869
910
box_float dbg m (Cop (Cfloatofint , [untag_int(transl env arg) dbg], dbg))
870
911
| Pintoffloat ->
@@ -1099,6 +1140,7 @@ and transl_prim_2 env p arg1 arg2 dbg =
1099
1140
| Pnegbint _ | Pbigarrayref (_, _, _, _) | Pbigarrayset (_, _, _, _)
1100
1141
| Pbigarraydim _ | Pbytes_set _ | Pbigstring_set _ | Pbbswap _
1101
1142
| Pprobe_is_enabled _
1143
+ | Punbox_float | Pbox_float _ | Punbox_int _ | Pbox_int _
1102
1144
->
1103
1145
fatal_errorf " Cmmgen.transl_prim_2: %a"
1104
1146
Printclambda_primitives. primitive p
@@ -1159,6 +1201,7 @@ and transl_prim_3 env p arg1 arg2 arg3 dbg =
1159
1201
| Pbigarrayref (_, _, _, _) | Pbigarrayset (_, _, _, _) | Pbigarraydim _
1160
1202
| Pstring_load _ | Pbytes_load _ | Pbigstring_load _ | Pbbswap _
1161
1203
| Pprobe_is_enabled _
1204
+ | Punbox_float | Pbox_float _ | Punbox_int _ | Pbox_int _
1162
1205
->
1163
1206
fatal_errorf " Cmmgen.transl_prim_3: %a"
1164
1207
Printclambda_primitives. primitive p
@@ -1181,7 +1224,7 @@ and transl_unbox_sized size dbg env exp =
1181
1224
| Thirty_two -> transl_unbox_int dbg env Pint32 exp
1182
1225
| Sixty_four -> transl_unbox_int dbg env Pint64 exp
1183
1226
1184
- and transl_let env str (Pvalue kind : Lambda.layout ) id exp transl_body =
1227
+ and transl_let_value env str (kind : Lambda.value_kind ) id exp transl_body =
1185
1228
let dbg = Debuginfo. none in
1186
1229
let cexp = transl env exp in
1187
1230
let unboxing =
@@ -1233,6 +1276,30 @@ and transl_let env str (Pvalue kind : Lambda.layout) id exp transl_body =
1233
1276
| Mutable , bn -> Clet_mut (v, typ_of_boxed_number bn, cexp, body)
1234
1277
end
1235
1278
1279
+ and transl_let env str (layout : Lambda.layout ) id exp transl_body =
1280
+ match layout with
1281
+ | Ptop ->
1282
+ Misc. fatal_errorf " Variable %a with layout [Ptop] can't be compiled"
1283
+ VP. print id
1284
+ | Pbottom ->
1285
+ let cexp = transl env exp in
1286
+ (* N.B. [body] must still be traversed even if [exp] will never return:
1287
+ there may be constant closures inside that need lifting out. *)
1288
+ let _cbody : expression = transl_body env in
1289
+ cexp
1290
+ | Punboxed_float | Punboxed_int _ -> begin
1291
+ let cexp = transl env exp in
1292
+ let cbody = transl_body env in
1293
+ match str with
1294
+ | (Immutable | Immutable_unique ) ->
1295
+ Clet (id, cexp, cbody)
1296
+ | Mutable ->
1297
+ let typ = machtype_of_layout layout in
1298
+ Clet_mut (id, typ, cexp, cbody)
1299
+ end
1300
+ | Pvalue kind ->
1301
+ transl_let_value env str kind id exp transl_body
1302
+
1236
1303
and make_catch (kind : Cmm.value_kind ) ncatch body handler dbg = match body with
1237
1304
| Cexit (nexit ,[] ) when nexit= ncatch -> handler
1238
1305
| _ -> ccatch (ncatch, [] , body, handler, dbg, kind)
0 commit comments