Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
emscripten-core
GitHub Repository: emscripten-core/emscripten
Path: blob/main/src/polyfill/bigint64array.js
4150 views
1
#if !POLYFILL
2
#error "this file should never be included unless POLYFILL is set"
3
#endif
4
5
if (typeof globalThis.BigInt64Array === "undefined") {
6
// BigInt64Array polyfill for Safari versions between v14.0 and v15.0.
7
// All browsers other than Safari added BigInt and BigInt64Array at the same
8
// time, but Safari introduced BigInt in v14.0 and introduced BigInt64Array in
9
// v15.0
10
11
function partsToBigIntSigned(lower, upper) {
12
return BigInt(lower) | (BigInt(upper + 2 * (upper & 0x80000000)) << 32n);
13
}
14
15
function partsToBigIntUnsigned(lower, upper) {
16
return BigInt(lower) | (BigInt(upper) << 32n);
17
}
18
19
function bigIntToParts(value) {
20
var lower = Number(BigInt(value) & BigInt(0xffffffff)) | 0;
21
var upper = Number(BigInt(value) >> 32n) | 0;
22
return [lower, upper];
23
}
24
25
function createBigIntArrayShim(partsToBigInt) {
26
function createBigInt64Array(array) {
27
if (typeof array === "number") {
28
array = new Uint32Array(2 * array);
29
}
30
var orig_array;
31
if (!ArrayBuffer.isView(array)) {
32
if (array.constructor?.name === "ArrayBuffer") {
33
array = new Uint32Array(array);
34
} else {
35
orig_array = array;
36
array = new Uint32Array(array.length * 2);
37
}
38
}
39
var proxy = new Proxy(
40
{
41
slice(min, max) {
42
max ??= array.length;
43
var new_buf = array.slice(min * 2, max * 2);
44
return createBigInt64Array(new_buf);
45
},
46
subarray(min, max) {
47
var new_buf = array.subarray(min * 2, max * 2);
48
return createBigInt64Array(new_buf);
49
},
50
[Symbol.iterator]: function* () {
51
for (var i = 0; i < array.length / 2; i++) {
52
yield partsToBigInt(array[2 * i], array[2 * i + 1]);
53
}
54
},
55
BYTES_PER_ELEMENT: 2 * array.BYTES_PER_ELEMENT,
56
buffer: array.buffer,
57
byteLength: array.byteLength,
58
byteOffset: array.byteOffset,
59
length: array.length / 2,
60
copyWithin: function (target, start, end) {
61
array.copyWithin(target * 2, start * 2, end * 2);
62
return proxy;
63
},
64
set(source, targetOffset) {
65
targetOffset ??= 0;
66
if (2 * (source.length + targetOffset) > array.length) {
67
// This is the Chrome error message
68
// Firefox: "invalid or out-of-range index"
69
throw new RangeError("offset is out of bounds");
70
}
71
for (var i = 0; i < source.length; i++) {
72
var value = source[i];
73
var pair = bigIntToParts(value);
74
array.set(pair, 2 * (targetOffset + i));
75
}
76
},
77
},
78
{
79
get(target, idx, receiver) {
80
if (typeof idx !== "string" || !/^\d+$/.test(idx)) {
81
return Reflect.get(target, idx, receiver);
82
}
83
var lower = array[idx * 2];
84
var upper = array[idx * 2 + 1];
85
return partsToBigInt(lower, upper);
86
},
87
set(target, idx, value, receiver) {
88
if (typeof idx !== "string" || !/^\d+$/.test(idx)) {
89
return Reflect.set(target, idx, value, receiver);
90
}
91
if (typeof value !== "bigint") {
92
// Chrome error message, Firefox has no "a" in front if "BigInt".
93
throw new TypeError(`Cannot convert ${value} to a BigInt`);
94
}
95
var pair = bigIntToParts(value);
96
array.set(pair, 2 * idx);
97
return true;
98
},
99
}
100
);
101
if (orig_array) {
102
proxy.set(orig_array);
103
}
104
return proxy;
105
}
106
return createBigInt64Array;
107
}
108
109
globalThis.BigUint64Array = createBigIntArrayShim(partsToBigIntUnsigned);
110
globalThis.BigInt64Array = createBigIntArrayShim(partsToBigIntSigned);
111
}
112
113