Skip to content

Commit 107cd28

Browse files
authored
Port runtime of #1420 (local immutable array) (#2084)
1 parent 9c66789 commit 107cd28

File tree

1 file changed

+116
-8
lines changed

1 file changed

+116
-8
lines changed

ocaml/runtime/array.c

Lines changed: 116 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,22 @@ CAMLprim value caml_floatarray_get(value array, value index)
7373
return res;
7474
}
7575

76+
/* [ floatarray -> int -> local_ float ] */
77+
CAMLprim value caml_floatarray_get_local(value array, value index)
78+
{
79+
intnat idx = Long_val(index);
80+
double d;
81+
value res;
82+
83+
CAMLassert (Tag_val(array) == Double_array_tag);
84+
if (idx < 0 || idx >= Wosize_val(array) / Double_wosize)
85+
caml_array_bound_error();
86+
d = Double_flat_field(array, idx);
87+
res = caml_alloc_local(Double_wosize, Double_tag);
88+
Store_double_val(res, d);
89+
return res;
90+
}
91+
7692
/* [ 'a array -> int -> 'a ] */
7793
CAMLprim value caml_array_get(value array, value index)
7894
{
@@ -85,6 +101,18 @@ CAMLprim value caml_array_get(value array, value index)
85101
return caml_array_get_addr(array, index);
86102
}
87103

104+
/* [ local_ 'a array -> int -> local_ 'a ] */
105+
CAMLprim value caml_array_get_local(value array, value index)
106+
{
107+
#ifdef FLAT_FLOAT_ARRAY
108+
if (Tag_val(array) == Double_array_tag)
109+
return caml_floatarray_get_local(array, index);
110+
#else
111+
CAMLassert (Tag_val(array) != Double_array_tag);
112+
#endif
113+
return caml_array_get_addr(array, index);
114+
}
115+
88116
/* [ 'a array -> int -> 'a -> unit ] where 'a != float */
89117
CAMLprim value caml_array_set_addr(value array, value index, value newval)
90118
{
@@ -94,7 +122,20 @@ CAMLprim value caml_array_set_addr(value array, value index, value newval)
94122
return Val_unit;
95123
}
96124

97-
/* [ floatarray -> int -> float -> unit ] */
125+
/* [ local_ 'a array -> int -> local_ 'a -> unit ] where 'a != float
126+
127+
Must be used carefully, as it can violate the "no forward pointers"
128+
restriction on the local stack. */
129+
CAMLprim value caml_array_set_addr_local(value array, value index, value newval)
130+
{
131+
intnat idx = Long_val(index);
132+
if (idx < 0 || idx >= Wosize_val(array)) caml_array_bound_error();
133+
caml_modify_local(array, idx, newval);
134+
return Val_unit;
135+
}
136+
137+
/* [ floatarray -> int -> float -> unit ]
138+
[ local_ floatarray -> int -> local_ float -> unit ] */
98139
CAMLprim value caml_floatarray_set(value array, value index, value newval)
99140
{
100141
intnat idx = Long_val(index);
@@ -118,6 +159,22 @@ CAMLprim value caml_array_set(value array, value index, value newval)
118159
return caml_array_set_addr(array, index, newval);
119160
}
120161

162+
/* [ local_ 'a array -> int -> local_ 'a -> unit ]
163+
164+
Must be used carefully, as it can violate the "no forward pointers"
165+
restriction on the local stack if the array contains pointers (vs. [int]s or
166+
unboxed floats). */
167+
CAMLprim value caml_array_set_local(value array, value index, value newval)
168+
{
169+
#ifdef FLAT_FLOAT_ARRAY
170+
if (Tag_val(array) == Double_array_tag)
171+
return caml_floatarray_set(array, index, newval);
172+
#else
173+
CAMLassert (Tag_val(array) != Double_array_tag);
174+
#endif
175+
return caml_array_set_addr_local(array, index, newval);
176+
}
177+
121178
/* [ floatarray -> int -> float ] */
122179
CAMLprim value caml_floatarray_unsafe_get(value array, value index)
123180
{
@@ -132,6 +189,20 @@ CAMLprim value caml_floatarray_unsafe_get(value array, value index)
132189
return res;
133190
}
134191

192+
/* [ floatarray -> int -> local_ float ] */
193+
CAMLprim value caml_floatarray_unsafe_get_local(value array, value index)
194+
{
195+
intnat idx = Long_val(index);
196+
double d;
197+
value res;
198+
199+
CAMLassert (Tag_val(array) == Double_array_tag);
200+
d = Double_flat_field(array, idx);
201+
res = caml_alloc_local(Double_wosize, Double_tag);
202+
Store_double_val(res, d);
203+
return res;
204+
}
205+
135206
/* [ 'a array -> int -> 'a ] */
136207
CAMLprim value caml_array_unsafe_get(value array, value index)
137208
{
@@ -144,6 +215,18 @@ CAMLprim value caml_array_unsafe_get(value array, value index)
144215
return Field(array, Long_val(index));
145216
}
146217

218+
/* [ local_ 'a array -> int -> local_ 'a ] */
219+
CAMLprim value caml_array_unsafe_get_local(value array, value index)
220+
{
221+
#ifdef FLAT_FLOAT_ARRAY
222+
if (Tag_val(array) == Double_array_tag)
223+
return caml_floatarray_unsafe_get_local(array, index);
224+
#else
225+
CAMLassert (Tag_val(array) != Double_array_tag);
226+
#endif
227+
return Field(array, Long_val(index));
228+
}
229+
147230
/* [ 'a array -> int -> 'a -> unit ] where 'a != float */
148231
static value caml_array_unsafe_set_addr(value array, value index,value newval)
149232
{
@@ -152,7 +235,20 @@ static value caml_array_unsafe_set_addr(value array, value index,value newval)
152235
return Val_unit;
153236
}
154237

155-
/* [ floatarray -> int -> float -> unit ] */
238+
/* [ local_ 'a array -> int -> local_ 'a -> unit ] where 'a != float
239+
240+
Must be used carefully, as it can violate the "no forward pointers"
241+
restriction on the local stack. */
242+
static value caml_array_unsafe_set_addr_local(value array, value index,
243+
value newval)
244+
{
245+
intnat idx = Long_val(index);
246+
caml_modify_local(array, idx, newval);
247+
return Val_unit;
248+
}
249+
250+
/* [ floatarray -> int -> float -> unit ]
251+
[ local_ floatarray -> int -> local_ float -> unit ] */
156252
/* [MM]: [caml_array_unsafe_set_addr] has a fence for enforcing the OCaml
157253
memory model through its use of [caml_modify].
158254
[MM] [TODO]: [caml_floatarray_unsafe_set] will also need a similar fence in
@@ -177,6 +273,23 @@ CAMLprim value caml_array_unsafe_set(value array, value index, value newval)
177273
return caml_array_unsafe_set_addr(array, index, newval);
178274
}
179275

276+
/* [ local_ 'a array -> int -> local_ 'a -> unit ]
277+
278+
Must be used carefully, as it can violate the "no forward pointers"
279+
restriction on the local stack if the array contains pointers (vs. [int]s or
280+
unboxed floats). */
281+
CAMLprim value caml_array_unsafe_set_local(value array, value index,
282+
value newval)
283+
{
284+
#ifdef FLAT_FLOAT_ARRAY
285+
if (Tag_val(array) == Double_array_tag)
286+
return caml_floatarray_unsafe_set(array, index, newval);
287+
#else
288+
CAMLassert (Tag_val(array) != Double_array_tag);
289+
#endif
290+
return caml_array_unsafe_set_addr_local(array, index, newval);
291+
}
292+
180293
/* [len] is a [value] representing number of floats. */
181294
/* [ int -> floatarray ] */
182295
CAMLprim value caml_floatarray_create(value len)
@@ -658,17 +771,12 @@ CAMLprim value caml_array_fill(value array,
658771
return Val_unit;
659772
}
660773

661-
/* Linker compatibility with stdlib externals
662-
CR ocaml 5 runtime: implement iarrays */
663-
664774
CAMLprim value caml_iarray_of_array(value a)
665775
{
666776
return a;
667777
}
668778

669-
extern value caml_obj_dup(value);
670-
671779
CAMLprim value caml_array_of_iarray(value a)
672780
{
673-
return caml_obj_dup(a);
781+
return a;
674782
}

0 commit comments

Comments
 (0)