1
(***********************************************************************)
5
(* Damien Doligez, projet Para, INRIA Rocquencourt *)
7
(* Copyright 1997 Institut National de Recherche en Informatique et *)
8
(* en Automatique. All rights reserved. This file is distributed *)
9
(* under the terms of the GNU Library General Public License, with *)
10
(* the special exception on linking described in file ../LICENSE. *)
12
(***********************************************************************)
14
(* $Id: camlinternalLazy.ml,v 1.1 2008/08/01 16:57:10 mauny Exp $ *)
16
(* Internals of forcing lazy values. *)
20
let raise_undefined = Obj.repr (fun () -> raise Undefined);;
22
(* Assume [blk] is a block with tag lazy *)
23
let force_lazy_block (blk : 'arg lazy_t) =
24
let closure = (Obj.obj (Obj.field (Obj.repr blk) 0) : unit -> 'arg) in
25
Obj.set_field (Obj.repr blk) 0 raise_undefined;
27
let result = closure () in
28
Obj.set_field (Obj.repr blk) 0 (Obj.repr result); (* do set_field BEFORE set_tag *)
29
Obj.set_tag (Obj.repr blk) Obj.forward_tag;
32
Obj.set_field (Obj.repr blk) 0 (Obj.repr (fun () -> raise e));
36
(* Assume [blk] is a block with tag lazy *)
37
let force_val_lazy_block (blk : 'arg lazy_t) =
38
let closure = (Obj.obj (Obj.field (Obj.repr blk) 0) : unit -> 'arg) in
39
Obj.set_field (Obj.repr blk) 0 raise_undefined;
40
let result = closure () in
41
Obj.set_field (Obj.repr blk) 0 (Obj.repr result); (* do set_field BEFORE set_tag *)
42
Obj.set_tag (Obj.repr blk) (Obj.forward_tag);
46
(* [force] is not used, since [Lazy.force] is declared as a primitive
47
whose code inlines the tag tests of its argument. This function is
48
here for the sake of completeness, and for debugging purpose. *)
50
let force (lzv : 'arg lazy_t) =
51
let x = Obj.repr lzv in
53
if t = Obj.forward_tag then (Obj.obj (Obj.field x 0) : 'arg) else
54
if t <> Obj.lazy_tag then (Obj.obj x : 'arg)
55
else force_lazy_block lzv
58
let force_val (lzv : 'arg lazy_t) =
59
let x = Obj.repr lzv in
61
if t = Obj.forward_tag then (Obj.obj (Obj.field x 0) : 'arg) else
62
if t <> Obj.lazy_tag then (Obj.obj x : 'arg)
63
else force_val_lazy_block lzv