1 (***********************************************************************)
5 (* Xavier Leroy, projet Cristal, INRIA Rocquencourt *)
7 (* Copyright 1996 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 (* portions lifted from Extlib *)
13 (* Copyright (C) 2003 Brian Hurt *)
14 (* Copyright (C) 2003 Nicolas Cannasse *)
15 (***********************************************************************)
19 (* Operations on internal representations of values *)
23 external repr
: 'a
-> t
= "%identity"
24 external obj
: t
-> 'a
= "%identity"
25 external magic
: 'a
-> 'b
= "%identity"
26 external is_block
: t
-> bool = "caml_obj_is_block"
27 external is_int
: t
-> bool = "%obj_is_int"
28 external tag
: t
-> int = "caml_obj_tag"
29 external set_tag
: t
-> int -> unit = "caml_obj_set_tag"
30 external size
: t
-> int = "%obj_size"
31 external field
: t
-> int -> t
= "%obj_field"
32 external set_field
: t
-> int -> t
-> unit = "%obj_set_field"
33 external new_block
: int -> int -> t
= "caml_obj_block"
34 external dup
: t
-> t
= "caml_obj_dup"
35 external truncate
: t
-> int -> unit = "caml_obj_truncate"
37 let marshal (obj
: t
) =
38 Marshal.to_string obj
[]
39 let unmarshal str pos
=
40 (Marshal.from_string str pos
, pos
+ Marshal.total_size str pos
)
50 let abstract_tag = 251
53 let double_array_tag = 254
55 let final_tag = custom_tag
59 let out_of_heap_tag = 1001
63 string_of_int
(magic r
: int)
65 let rec get_fields acc
= function
67 | n
-> let n = n-1 in get_fields (field r
n :: acc
) n
73 let s = size r
and t
= tag r
in
74 t
= 0 && s = 2 && is_list (field r
1) (* h :: t *)
80 let h = field r
0 and t
= get_list (field r
1) in
84 (* XXX In future, print the address of value 'r'. Not possible in
85 * pure OCaml at the moment.
89 let s = size r
and t
= tag r
in
90 (* From the tag, determine the type of block. *)
93 let fields = get_list r
in
94 "[" ^
String.concat
"; " (List.map
dump fields) ^
"]"
96 let fields = get_fields [] s in
97 "(" ^
String.concat
", " (List.map
dump fields) ^
")"
98 | x
when x
= lazy_tag ->
99 (* Note that [lazy_tag .. forward_tag] are < no_scan_tag. Not
100 * clear if very large constructed values could have the same
103 | x
when x
= closure_tag ->
105 | x
when x
= object_tag ->
106 let fields = get_fields [] s in
107 let clasz, id
, slots
=
109 | h::h'
::t
-> h, h'
, t
112 (* No information on decoding the class (first field). So just print
113 * out the ID and the slots. *)
114 "Object #" ^
dump id ^
" (" ^
String.concat
", " (List.map
dump slots
) ^
")"
115 | x
when x
= infix_tag ->
117 | x
when x
= forward_tag ->
119 | x
when x
< no_scan_tag ->
120 let fields = get_fields [] s in
121 "Tag" ^ string_of_int t ^
122 " (" ^
String.concat
", " (List.map
dump fields) ^
")"
123 | x
when x
= string_tag ->
124 "\"" ^
String.escaped
(magic r
: string) ^
"\""
125 | x
when x
= double_tag ->
126 string_of_float
(magic r
: float)
127 | x
when x
= abstract_tag ->
129 | x
when x
= custom_tag ->
131 | x
when x
= final_tag ->
134 failwith
("Std.dump: impossible tag (" ^ string_of_int t ^
")")
136 let dump v
= dump (repr v
)
138 let print v
= print_endline
(dump v
)
140 let __unique_counter = ref 0
143 incr
__unique_counter;