aboutsummaryrefslogtreecommitdiff
path: root/kernel/vm.ml
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/vm.ml')
-rw-r--r--kernel/vm.ml32
1 files changed, 25 insertions, 7 deletions
diff --git a/kernel/vm.ml b/kernel/vm.ml
index 2cc1efe431..65d84e882d 100644
--- a/kernel/vm.ml
+++ b/kernel/vm.ml
@@ -79,7 +79,7 @@ type vprod
type vfun
type vfix
type vcofix
-type vblock
+type vblock
type arguments
type vm_env
@@ -161,7 +161,7 @@ type whd =
| Vfix of vfix * arguments option
| Vcofix of vcofix * to_up * arguments option
| Vconstr_const of int
- | Vconstr_block of vblock
+ | Vconstr_block of int * vblock
| Vatom_stk of atom * stack
(*************************************************)
@@ -224,7 +224,13 @@ let whd_val : values -> whd =
| 2 -> Vfix(Obj.obj (Obj.field o 1), Some (Obj.obj o))
| 3 -> Vatom_stk(Aid(RelKey(int_tcode (fun_code o) 1)), [])
| _ -> Errors.anomaly ~label:"Vm.whd " (Pp.str "kind_of_closure does not work"))
- else Vconstr_block(Obj.obj o)
+ else
+ if tag = max_tag then
+ let tag = Obj.obj (Obj.field o 0) + max_tag in
+ let block = Obj.obj (Obj.field o 1) in
+ Vconstr_block(tag, block)
+ else
+ Vconstr_block(tag, Obj.obj o)
@@ -518,10 +524,22 @@ let type_of_switch sw =
let branch_arg k (tag,arity) =
if Int.equal arity 0 then ((Obj.magic tag):values)
else
- let b = Obj.new_block tag arity in
- for i = 0 to arity - 1 do
- Obj.set_field b i (Obj.repr (val_of_rel (k+i)))
- done;
+ let init b =
+ for i = 0 to arity - 1 do
+ Obj.set_field b i (Obj.repr (val_of_rel (k+i)))
+ done in
+ let b =
+ if tag < max_tag then
+ let b = Obj.new_block tag arity in
+ init b;
+ b
+ else
+ let b0 = Obj.new_block 0 arity in
+ init b0;
+ let b = Obj.new_block max_tag 2 in
+ Obj.set_field b 0 (Obj.repr (tag - max_tag));
+ Obj.set_field b 1 (Obj.repr b0);
+ b in
val_of_obj b
let apply_switch sw arg =