summaryrefslogtreecommitdiff
path: root/stdlib/obj.ml
diff options
context:
space:
mode:
authorXavier Leroy <xavier.leroy@college-de-france.fr>2020-06-08 19:32:17 +0200
committerXavier Leroy <xavier.leroy@college-de-france.fr>2020-06-10 16:29:37 +0200
commitec33006c0a2253a29dfc55c36b66358cd20b188f (patch)
treec308b05b9d6864c9ea4070f1d271f3265e507993 /stdlib/obj.ml
parentd8f3273292bd4f1459b4132322746b9c42925e62 (diff)
downloadocaml-ec33006c0a2253a29dfc55c36b66358cd20b188f.tar.gz
Add type Obj.raw_data and functions Obj.raw_field, Obj.set_raw_field
Some OCaml objects contain data that cannot be safely represented as an OCaml value (type Obj.t). For example, in no-naked-pointers mode, this is the case for code pointers inside closures, and for the "custom operations" pointers inside custom blocks. This PR introduces a type Obj.raw_data (an alias for nativeint) to encapsulate this data, and functions Obj.raw_field / Obj.set_raw_field to read and write the "raw" contents of fields of blocks. Note: just like it is wrong to access code pointers and custom operations using Obj.field / Obj.set_field, it is wrong to access regular fields possibly containing pointers into the OCaml heap using Obj.raw_field / Obj.set_raw_field. The OCaml heap block can be reclaimed or moved after its address was captured by Obj.raw_field. Symmetrically, Obj.set_raw_field on a regular field bypasses the write barrier of the GC.
Diffstat (limited to 'stdlib/obj.ml')
-rw-r--r--stdlib/obj.ml6
1 files changed, 6 insertions, 0 deletions
diff --git a/stdlib/obj.ml b/stdlib/obj.ml
index 32049d72b3..ab13b9b7d4 100644
--- a/stdlib/obj.ml
+++ b/stdlib/obj.ml
@@ -17,6 +17,8 @@
type t
+type raw_data = nativeint
+
external repr : 'a -> t = "%identity"
external obj : t -> 'a = "%identity"
external magic : 'a -> 'b = "%identity"
@@ -34,6 +36,10 @@ external floatarray_set :
let [@inline always] double_field x i = floatarray_get (obj x : floatarray) i
let [@inline always] set_double_field x i v =
floatarray_set (obj x : floatarray) i v
+external raw_field : t -> int -> raw_data = "caml_obj_raw_field"
+external set_raw_field : t -> int -> raw_data -> unit
+ = "caml_obj_set_raw_field"
+
external new_block : int -> int -> t = "caml_obj_block"
external dup : t -> t = "caml_obj_dup"
external truncate : t -> int -> unit = "caml_obj_truncate"