summaryrefslogtreecommitdiffstats
path: root/stdlib
diff options
context:
space:
mode:
Diffstat (limited to 'stdlib')
-rw-r--r--stdlib/.depend6
-rwxr-xr-xstdlib/Makefile.shared5
-rw-r--r--stdlib/StdlibModules1
-rw-r--r--stdlib/camlinternalLazy.ml64
-rw-r--r--stdlib/camlinternalLazy.mli25
-rw-r--r--stdlib/lazy.ml40
-rw-r--r--stdlib/lazy.mli3
-rw-r--r--stdlib/stdlib.mllib1
8 files changed, 105 insertions, 40 deletions
diff --git a/stdlib/.depend b/stdlib/.depend
index fc51ab117..a45db17de 100644
--- a/stdlib/.depend
+++ b/stdlib/.depend
@@ -1,3 +1,4 @@
+camlinternalLazy.cmi: obj.cmi
camlinternalMod.cmi: obj.cmi
camlinternalOO.cmi: obj.cmi
format.cmi: buffer.cmi
@@ -18,6 +19,7 @@ buffer.cmo: sys.cmi string.cmi buffer.cmi
buffer.cmx: sys.cmx string.cmx buffer.cmi
callback.cmo: obj.cmi callback.cmi
callback.cmx: obj.cmx callback.cmi
+camlinternalLazy.cmo: camlinternalLazy.cmi
camlinternalMod.cmo: obj.cmi camlinternalOO.cmi array.cmi camlinternalMod.cmi
camlinternalMod.cmx: obj.cmx camlinternalOO.cmx array.cmx camlinternalMod.cmi
camlinternalOO.cmo: sys.cmi string.cmi obj.cmi map.cmi list.cmi char.cmi \
@@ -46,8 +48,8 @@ int32.cmo: pervasives.cmi int32.cmi
int32.cmx: pervasives.cmx int32.cmi
int64.cmo: pervasives.cmi int64.cmi
int64.cmx: pervasives.cmx int64.cmi
-lazy.cmo: obj.cmi lazy.cmi
-lazy.cmx: obj.cmx lazy.cmi
+lazy.cmo: obj.cmi camlinternalLazy.cmi lazy.cmi
+lazy.cmx: obj.cmx camlinternalLazy.cmx lazy.cmi
lexing.cmo: sys.cmi string.cmi array.cmi lexing.cmi
lexing.cmx: sys.cmx string.cmx array.cmx lexing.cmi
list.cmo: list.cmi
diff --git a/stdlib/Makefile.shared b/stdlib/Makefile.shared
index 02a986238..2440f1b9a 100755
--- a/stdlib/Makefile.shared
+++ b/stdlib/Makefile.shared
@@ -28,8 +28,9 @@ OTHERS=array.cmo list.cmo char.cmo string.cmo sys.cmo \
hashtbl.cmo sort.cmo marshal.cmo obj.cmo \
int32.cmo int64.cmo nativeint.cmo \
lexing.cmo parsing.cmo \
- set.cmo map.cmo stack.cmo queue.cmo lazy.cmo stream.cmo buffer.cmo \
- printf.cmo format.cmo scanf.cmo \
+ set.cmo map.cmo stack.cmo queue.cmo \
+ camlinternalLazy.cmo lazy.cmo stream.cmo \
+ buffer.cmo printf.cmo format.cmo scanf.cmo \
arg.cmo printexc.cmo gc.cmo \
digest.cmo random.cmo callback.cmo \
camlinternalOO.cmo oo.cmo camlinternalMod.cmo \
diff --git a/stdlib/StdlibModules b/stdlib/StdlibModules
index f9fec2d96..4f689f8c4 100644
--- a/stdlib/StdlibModules
+++ b/stdlib/StdlibModules
@@ -8,6 +8,7 @@ STDLIB_MODULES=\
arrayLabels \
buffer \
callback \
+ camlinternalLazy \
camlinternalMod \
camlinternalOO \
char \
diff --git a/stdlib/camlinternalLazy.ml b/stdlib/camlinternalLazy.ml
new file mode 100644
index 000000000..46cf42788
--- /dev/null
+++ b/stdlib/camlinternalLazy.ml
@@ -0,0 +1,64 @@
+(***********************************************************************)
+(* *)
+(* Objective Caml *)
+(* *)
+(* Damien Doligez, projet Para, INRIA Rocquencourt *)
+(* *)
+(* Copyright 1997 Institut National de Recherche en Informatique et *)
+(* en Automatique. All rights reserved. This file is distributed *)
+(* under the terms of the GNU Library General Public License, with *)
+(* the special exception on linking described in file ../LICENSE. *)
+(* *)
+(***********************************************************************)
+
+(* $Id$ *)
+
+(* Internals of forcing lazy values. *)
+
+exception Undefined;;
+
+let raise_undefined = Obj.repr (fun () -> raise Undefined);;
+
+(* Assume [blk] is a block with tag lazy *)
+let force_lazy_block (blk : 'arg lazy_t) =
+ let closure = (Obj.obj (Obj.field (Obj.repr blk) 0) : unit -> 'arg) in
+ Obj.set_field (Obj.repr blk) 0 raise_undefined;
+ try
+ let result = closure () in
+ Obj.set_field (Obj.repr blk) 0 (Obj.repr result); (* do set_field BEFORE set_tag *)
+ Obj.set_tag (Obj.repr blk) Obj.forward_tag;
+ result
+ with e ->
+ Obj.set_field (Obj.repr blk) 0 (Obj.repr (fun () -> raise e));
+ raise e
+;;
+
+(* Assume [blk] is a block with tag lazy *)
+let force_val_lazy_block (blk : 'arg lazy_t) =
+ let closure = (Obj.obj (Obj.field (Obj.repr blk) 0) : unit -> 'arg) in
+ Obj.set_field (Obj.repr blk) 0 raise_undefined;
+ let result = closure () in
+ Obj.set_field (Obj.repr blk) 0 (Obj.repr result); (* do set_field BEFORE set_tag *)
+ Obj.set_tag (Obj.repr blk) (Obj.forward_tag);
+ result
+;;
+
+(* [force] is not used, since [Lazy.force] is declared as a primitive
+ whose code inlines the tag tests of its argument. This function is
+ here for the sake of completeness, and for debugging purpose. *)
+
+let force (lzv : 'arg lazy_t) =
+ let x = Obj.repr lzv in
+ let t = Obj.tag x in
+ if t = Obj.forward_tag then (Obj.obj (Obj.field x 0) : 'arg) else
+ if t <> Obj.lazy_tag then (Obj.obj x : 'arg)
+ else force_lazy_block lzv
+;;
+
+let force_val (lzv : 'arg lazy_t) =
+ let x = Obj.repr lzv in
+ let t = Obj.tag x in
+ if t = Obj.forward_tag then (Obj.obj (Obj.field x 0) : 'arg) else
+ if t <> Obj.lazy_tag then (Obj.obj x : 'arg)
+ else force_val_lazy_block lzv
+;;
diff --git a/stdlib/camlinternalLazy.mli b/stdlib/camlinternalLazy.mli
new file mode 100644
index 000000000..37b707d4f
--- /dev/null
+++ b/stdlib/camlinternalLazy.mli
@@ -0,0 +1,25 @@
+(***********************************************************************)
+(* *)
+(* Objective Caml *)
+(* *)
+(* Damien Doligez, projet Para, INRIA Rocquencourt *)
+(* *)
+(* Copyright 1997 Institut National de Recherche en Informatique et *)
+(* en Automatique. All rights reserved. This file is distributed *)
+(* under the terms of the GNU Library General Public License, with *)
+(* the special exception on linking described in file ../LICENSE. *)
+(* *)
+(***********************************************************************)
+
+(* $Id$ *)
+
+(* Internals of forcing lazy values *)
+
+exception Undefined;;
+
+val force_lazy_block : 'a lazy_t -> 'a ;;
+
+val force_val_lazy_block : 'a lazy_t -> 'a ;;
+
+val force : 'a lazy_t -> 'a ;;
+val force_val : 'a lazy_t -> 'a ;;
diff --git a/stdlib/lazy.ml b/stdlib/lazy.ml
index 70acccd10..b1a9cbbda 100644
--- a/stdlib/lazy.ml
+++ b/stdlib/lazy.ml
@@ -46,46 +46,16 @@
*)
type 'a t = 'a lazy_t;;
-exception Undefined;;
-let raise_undefined = Obj.repr (fun () -> raise Undefined);;
+exception Undefined = CamlinternalLazy.Undefined;;
-external follow_forward : Obj.t -> 'a = "caml_lazy_follow_forward";;
external make_forward : 'a -> 'a lazy_t = "caml_lazy_make_forward";;
-let force (l : 'arg t) =
- let x = Obj.repr l in
- let t = Obj.tag x in
- if t = Obj.forward_tag then (follow_forward x : 'arg)
- else if t <> Obj.lazy_tag then (Obj.obj x : 'arg)
- else begin
- let closure = (Obj.obj (Obj.field x 0) : unit -> 'arg) in
- Obj.set_field x 0 raise_undefined;
- try
- let result = closure () in
- Obj.set_field x 0 (Obj.repr result); (* do set_field BEFORE set_tag *)
- Obj.set_tag x Obj.forward_tag;
- result
- with e ->
- Obj.set_field x 0 (Obj.repr (fun () -> raise e));
- raise e
- end
-;;
+external force : 'a t -> 'a = "%lazy_force";;
-let force_val (l : 'arg t) =
- let x = Obj.repr l in
- let t = Obj.tag x in
- if t = Obj.forward_tag then (follow_forward x : 'arg)
- else if t <> Obj.lazy_tag then (Obj.obj x : 'arg)
- else begin
- let closure = (Obj.obj (Obj.field x 0) : unit -> 'arg) in
- Obj.set_field x 0 raise_undefined;
- let result = closure () in
- Obj.set_field x 0 (Obj.repr result); (* do set_field BEFORE set_tag *)
- Obj.set_tag x (Obj.forward_tag);
- result
- end
-;;
+(* let force = force;; *)
+
+let force_val = CamlinternalLazy.force_val;;
let lazy_from_fun (f : unit -> 'arg) =
let x = Obj.new_block Obj.lazy_tag 1 in
diff --git a/stdlib/lazy.mli b/stdlib/lazy.mli
index afdb1e6d1..f0255c224 100644
--- a/stdlib/lazy.mli
+++ b/stdlib/lazy.mli
@@ -39,7 +39,8 @@ type 'a t = 'a lazy_t;;
exception Undefined;;
-val force : 'a t -> 'a;;
+external force : 'a t -> 'a = "%lazy_force";;
+(* val force : 'a t -> 'a ;; *)
(** [force x] forces the suspension [x] and returns its result.
If [x] has already been forced, [Lazy.force x] returns the
same value again without recomputing it. If it raised an exception,
diff --git a/stdlib/stdlib.mllib b/stdlib/stdlib.mllib
index b3c6924f5..9f835c6fa 100644
--- a/stdlib/stdlib.mllib
+++ b/stdlib/stdlib.mllib
@@ -8,6 +8,7 @@ Array
ArrayLabels
Buffer
Callback
+CamlinternalLazy
CamlinternalMod
CamlinternalOO
Char