Skip to content

Commit fe531a2

Browse files
authored
Add support for ArrayBuffer and typed arrays to @unboxed (#7788)
* Add support for ArrayBuffer to @unboxed * Add support for typed arrays to @unboxed
1 parent 18ff979 commit fe531a2

File tree

3 files changed

+158
-37
lines changed

3 files changed

+158
-37
lines changed

compiler/ml/ast_untagged_variants.ml

Lines changed: 73 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,44 @@
11
module Instance = struct
2-
type t = Array | Blob | Date | File | Promise | RegExp
2+
type t =
3+
| Array
4+
| ArrayBuffer
5+
| BigInt64Array
6+
| BigUint64Array
7+
| Blob
8+
| DataView
9+
| Date
10+
| File
11+
| Float32Array
12+
| Float64Array
13+
| Int16Array
14+
| Int32Array
15+
| Int8Array
16+
| Promise
17+
| RegExp
18+
| Uint16Array
19+
| Uint32Array
20+
| Uint8Array
21+
| Uint8ClampedArray
322
let to_string = function
423
| Array -> "Array"
24+
| ArrayBuffer -> "ArrayBuffer"
25+
| BigInt64Array -> "BigInt64Array"
26+
| BigUint64Array -> "BigUint64Array"
527
| Blob -> "Blob"
28+
| DataView -> "DataView"
629
| Date -> "Date"
730
| File -> "File"
31+
| Float32Array -> "Float32Array"
32+
| Float64Array -> "Float64Array"
33+
| Int16Array -> "Int16Array"
34+
| Int32Array -> "Int32Array"
35+
| Int8Array -> "Int8Array"
836
| Promise -> "Promise"
937
| RegExp -> "RegExp"
38+
| Uint16Array -> "Uint16Array"
39+
| Uint32Array -> "Uint32Array"
40+
| Uint8Array -> "Uint8Array"
41+
| Uint8ClampedArray -> "Uint8ClampedArray"
1042
end
1143

1244
type untagged_error =
@@ -200,37 +232,54 @@ let type_to_instanceof_backed_obj (t : Types.type_expr) =
200232
| Tconstr (path, _, _) when Path.same path Predef.path_array -> Some Array
201233
| Tconstr (path, _, _) -> (
202234
match Path.name path with
235+
| "Stdlib_ArrayBuffer.t" -> Some ArrayBuffer
236+
| "Stdlib.BigInt64Array.t" -> Some BigInt64Array
237+
| "Stdlib.BigUint64Array.t" -> Some BigUint64Array
238+
| "Stdlib.DataView.t" -> Some DataView
203239
| "Stdlib_Date.t" -> Some Date
240+
| "Stdlib.Float32Array.t" -> Some Float32Array
241+
| "Stdlib.Float64Array.t" -> Some Float64Array
242+
| "Stdlib.Int16Array.t" -> Some Int16Array
243+
| "Stdlib.Int32Array.t" -> Some Int32Array
244+
| "Stdlib.Int8Array.t" -> Some Int8Array
204245
| "Stdlib_RegExp.t" -> Some RegExp
246+
| "Stdlib.Uint16Array.t" -> Some Uint16Array
247+
| "Stdlib.Uint32Array.t" -> Some Uint32Array
248+
| "Stdlib.Uint8Array.t" -> Some Uint8Array
249+
| "Stdlib.Uint8ClampedArray.t" -> Some Uint8ClampedArray
205250
| "Js_file.t" -> Some File
206251
| "Js_blob.t" -> Some Blob
207252
| _ -> None)
208253
| _ -> None
209254

210255
let get_block_type_from_typ ~env (t : Types.type_expr) : block_type option =
211-
let t = !expand_head env t in
212-
match t with
213-
| {desc = Tconstr (path, _, _)} when Path.same path Predef.path_string ->
214-
Some StringType
215-
| {desc = Tconstr (path, _, _)} when Path.same path Predef.path_int ->
216-
Some IntType
217-
| {desc = Tconstr (path, _, _)} when Path.same path Predef.path_float ->
218-
Some FloatType
219-
| {desc = Tconstr (path, _, _)} when Path.same path Predef.path_bigint ->
220-
Some BigintType
221-
| {desc = Tconstr (path, _, _)} when Path.same path Predef.path_bool ->
222-
Some BooleanType
223-
| {desc = Tarrow _} -> Some FunctionType
224-
| {desc = Tconstr (path, _, _)} when Path.same path Predef.path_string ->
225-
Some StringType
226-
| {desc = Tconstr _} as t when type_is_builtin_object t -> Some ObjectType
227-
| {desc = Tconstr _} as t
228-
when type_to_instanceof_backed_obj t |> Option.is_some -> (
229-
match type_to_instanceof_backed_obj t with
230-
| None -> None
231-
| Some instance_type -> Some (InstanceType instance_type))
232-
| {desc = Ttuple _} -> Some (InstanceType Array)
233-
| _ -> None
256+
(* First check the original (unexpanded) type for typed arrays and other instance types *)
257+
match type_to_instanceof_backed_obj t with
258+
| Some instance_type -> Some (InstanceType instance_type)
259+
| None -> (
260+
(* If original type didn't match, expand and try standard checks *)
261+
let expanded_t = !expand_head env t in
262+
match expanded_t with
263+
| {desc = Tconstr (path, _, _)} when Path.same path Predef.path_string ->
264+
Some StringType
265+
| {desc = Tconstr (path, _, _)} when Path.same path Predef.path_int ->
266+
Some IntType
267+
| {desc = Tconstr (path, _, _)} when Path.same path Predef.path_float ->
268+
Some FloatType
269+
| {desc = Tconstr (path, _, _)} when Path.same path Predef.path_bigint ->
270+
Some BigintType
271+
| {desc = Tconstr (path, _, _)} when Path.same path Predef.path_bool ->
272+
Some BooleanType
273+
| {desc = Tarrow _} -> Some FunctionType
274+
| {desc = Tconstr _} as expanded_t when type_is_builtin_object expanded_t ->
275+
Some ObjectType
276+
| {desc = Tconstr _} as expanded_t
277+
when type_to_instanceof_backed_obj expanded_t |> Option.is_some -> (
278+
match type_to_instanceof_backed_obj expanded_t with
279+
| None -> None
280+
| Some instance_type -> Some (InstanceType instance_type))
281+
| {desc = Ttuple _} -> Some (InstanceType Array)
282+
| _ -> None)
234283

235284
let get_block_type ~env (cstr : Types.constructor_declaration) :
236285
block_type option =

tests/tests/src/UntaggedVariants.mjs

Lines changed: 55 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22

33
import * as Js_dict from "rescript/lib/es6/Js_dict.js";
44
import * as Belt_Array from "rescript/lib/es6/Belt_Array.js";
5-
import * as Primitive_array from "rescript/lib/es6/Primitive_array.js";
65
import * as Primitive_option from "rescript/lib/es6/Primitive_option.js";
76

87
function classify(x) {
@@ -289,7 +288,7 @@ let OverlapObject = {
289288

290289
function classify$7(v) {
291290
if (Array.isArray(v)) {
292-
return Primitive_array.get(v, 0);
291+
return v[0];
293292
} else {
294293
return v.x;
295294
}
@@ -303,7 +302,7 @@ function classify$8(v) {
303302
if (typeof v === "object" && !Array.isArray(v)) {
304303
return v.x;
305304
} else {
306-
return Primitive_array.get(v, 0);
305+
return v[0];
307306
}
308307
}
309308

@@ -356,7 +355,7 @@ let OptionUnboxingHeuristic = {
356355

357356
function classify$9(v) {
358357
if (Array.isArray(v)) {
359-
return Primitive_array.get(v, 0);
358+
return v[0];
360359
}
361360
switch (typeof v) {
362361
case "object" :
@@ -522,6 +521,58 @@ async function classifyAll(t) {
522521
console.log(t.size);
523522
return;
524523
}
524+
if (t instanceof ArrayBuffer) {
525+
console.log("ArrayBuffer");
526+
return;
527+
}
528+
if (t instanceof Int8Array) {
529+
console.log("Int8Array");
530+
return;
531+
}
532+
if (t instanceof Int16Array) {
533+
console.log("Int16Array");
534+
return;
535+
}
536+
if (t instanceof Int32Array) {
537+
console.log("Int32Array");
538+
return;
539+
}
540+
if (t instanceof Uint8Array) {
541+
console.log("Uint8Array");
542+
return;
543+
}
544+
if (t instanceof Uint8ClampedArray) {
545+
console.log("Uint8ClampedArray");
546+
return;
547+
}
548+
if (t instanceof Uint16Array) {
549+
console.log("Uint16Array");
550+
return;
551+
}
552+
if (t instanceof Uint32Array) {
553+
console.log("Uint32Array");
554+
return;
555+
}
556+
if (t instanceof Float32Array) {
557+
console.log("Float32Array");
558+
return;
559+
}
560+
if (t instanceof Float64Array) {
561+
console.log("Float64Array");
562+
return;
563+
}
564+
if (t instanceof BigInt64Array) {
565+
console.log("BigInt64Array");
566+
return;
567+
}
568+
if (t instanceof BigUint64Array) {
569+
console.log("BigUint64Array");
570+
return;
571+
}
572+
if (t instanceof DataView) {
573+
console.log("DataView");
574+
return;
575+
}
525576
switch (typeof t) {
526577
case "string" :
527578
console.log(t);
@@ -606,8 +657,6 @@ let RecursiveType = {
606657
}
607658
};
608659

609-
let $$Array;
610-
611660
let i = 42;
612661

613662
let i2 = 42.5;
@@ -622,7 +671,6 @@ let w = {
622671
};
623672

624673
export {
625-
$$Array,
626674
i,
627675
i2,
628676
s,

tests/tests/src/UntaggedVariants.res

Lines changed: 30 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
module Array = Ocaml_Array
2-
31
@unboxed
42
type t = A | I(int) | S(string)
53
@unboxed
@@ -182,7 +180,7 @@ let classify (x : t) : tagged_t =
182180
else if Js_array2.isArray x then
183181
JSONArray (Obj.magic x)
184182
else
185-
JSONObject (Obj.magic x)
183+
JSONObject (Obj.magic x)
186184
*/
187185
}
188186

@@ -249,7 +247,7 @@ module RecordIsObject = {
249247
let classify = v =>
250248
switch v {
251249
| Record({x}) => x
252-
| Array(a) => a[0]
250+
| Array(a) => a->Array.getUnsafe(0)
253251
}
254252
}
255253

@@ -260,7 +258,7 @@ module ArrayAndObject = {
260258
let classify = v =>
261259
switch v {
262260
| Record({x}) => x
263-
| Array(a) => a[0]
261+
| Array(a) => a->Array.getUnsafe(0)
264262
}
265263
}
266264

@@ -303,7 +301,7 @@ module TestFunctionCase = {
303301
let classify = v =>
304302
switch v {
305303
| Record({x}) => x
306-
| Array(a) => a[0]
304+
| Array(a) => a->Array.getUnsafe(0)
307305
| Function(f) => f(3)
308306
}
309307

@@ -402,6 +400,19 @@ module AllInstanceofTypes = {
402400
| RegExp(Stdlib_RegExp.t)
403401
| File(Js.File.t)
404402
| Blob(Js.Blob.t)
403+
| ArrayBuffer(ArrayBuffer.t)
404+
| Int8Array(Int8Array.t)
405+
| Int16Array(Int16Array.t)
406+
| Int32Array(Int32Array.t)
407+
| Uint8Array(Uint8Array.t)
408+
| Uint8ClampedArray(Uint8ClampedArray.t)
409+
| Uint16Array(Uint16Array.t)
410+
| Uint32Array(Uint32Array.t)
411+
| Float32Array(Float32Array.t)
412+
| Float64Array(Float64Array.t)
413+
| BigInt64Array(BigInt64Array.t)
414+
| BigUint64Array(BigUint64Array.t)
415+
| DataView(DataView.t)
405416

406417
let classifyAll = async (t: t) =>
407418
switch t {
@@ -413,6 +424,19 @@ module AllInstanceofTypes = {
413424
| Array(arr) => Js.log(arr->Belt.Array.joinWith("-", x => x))
414425
| File(file) => Js.log(file->fileName)
415426
| Blob(blob) => Js.log(blob->blobSize)
427+
| ArrayBuffer(_) => Js.log("ArrayBuffer")
428+
| Int8Array(_) => Js.log("Int8Array")
429+
| Int16Array(_) => Js.log("Int16Array")
430+
| Int32Array(_) => Js.log("Int32Array")
431+
| Uint8Array(_) => Js.log("Uint8Array")
432+
| Uint8ClampedArray(_) => Js.log("Uint8ClampedArray")
433+
| Uint16Array(_) => Js.log("Uint16Array")
434+
| Uint32Array(_) => Js.log("Uint32Array")
435+
| Float32Array(_) => Js.log("Float32Array")
436+
| Float64Array(_) => Js.log("Float64Array")
437+
| BigInt64Array(_) => Js.log("BigInt64Array")
438+
| BigUint64Array(_) => Js.log("BigUint64Array")
439+
| DataView(_) => Js.log("DataView")
416440
}
417441
}
418442

0 commit comments

Comments
 (0)