Skip to content

Commit c59631b

Browse files
committed
Add BigInt64Array shim for Safari 14
1 parent 719b7c6 commit c59631b

File tree

1 file changed

+93
-2
lines changed

1 file changed

+93
-2
lines changed

src/preamble.js

+93-2
Original file line numberDiff line numberDiff line change
@@ -295,8 +295,99 @@ function updateGlobalBufferAndViews(buf) {
295295
Module['HEAPF32'] = HEAPF32 = new Float32Array(buf);
296296
Module['HEAPF64'] = HEAPF64 = new Float64Array(buf);
297297
#if WASM_BIGINT
298-
Module['HEAP64'] = HEAP64 = new BigInt64Array(buf);
299-
Module['HEAPU64'] = HEAPU64 = new BigUint64Array(buf);
298+
if(typeof BigInt64Array !== "undefined"){
299+
Module['HEAP64'] = HEAP64 = new BigInt64Array(buf);
300+
Module['HEAPU64'] = HEAPU64 = new BigUint64Array(buf);
301+
} else {
302+
function partsToBigIntSigned(lower, upper){
303+
return BigInt(lower) | (BigInt(upper + 2 * (upper & 0x80000000)) << BigInt(32));
304+
}
305+
306+
function partsToBigIntUnsigned(lower, upper){
307+
return BigInt(lower) | (BigInt(upper) << BigInt(32));
308+
}
309+
310+
function bigIntToParts(value){
311+
var lower = Number((value) & BigInt(0xffffffff)) | 0;
312+
var upper = (Number((value) >> BigInt(32)) | 0);
313+
return [lower, upper];
314+
}
315+
316+
function createBigIntArrayShim(partsToBigInt){
317+
function createBigInt64Array(buf){
318+
var array;
319+
if(ArrayBuffer.isView(buf)){
320+
array = buf;
321+
} else {
322+
array = new Uint32Array(buf);
323+
}
324+
325+
let proxy = new Proxy({
326+
slice : function(min, max){
327+
var new_buf = array.slice(min * 2, max *2);
328+
return createBigInt64Array(new_buf);
329+
},
330+
subarray : function(min, max){
331+
var new_buf = array.subarray(min * 2, max *2);
332+
return createBigInt64Array(new_buf);
333+
},
334+
[Symbol.iterator] : function*(){
335+
for(var i = 0; i < (array.length)/2; i++){
336+
yield partsToBigInt(array[2*i], array[2*i+1]);
337+
}
338+
},
339+
buffer : array.buffer,
340+
byteLength : array.byteLength,
341+
offset : array.byteOffset / 2,
342+
copyWithin : function(target, start, end){
343+
array.copyWithin(target*2, start * 2, end*2);
344+
return proxy;
345+
},
346+
set : function(source, targetOffset){
347+
if(2*(source.length + targetOffset) > array.length){
348+
// This is the Chrome error message
349+
// Firefox: "invalid or out-of-range index"
350+
throw new RangeError("offset is out of bounds");
351+
}
352+
for(var i = 0; i < array.length; i++){
353+
var value = source[i];
354+
var pair = bigIntToParts(BigInt(value));
355+
array.set(pair, 2*(targetOffset + i));
356+
}
357+
}
358+
}, {
359+
get : function(target, idx, receiver){
360+
if(!/^\d+$/.test(idx)){
361+
return Reflect.get(target, idx, receiver);
362+
}
363+
var lower = array[idx * 2];
364+
var upper = array[idx * 2 + 1];
365+
return partsToBigInt(lower, upper);
366+
},
367+
set: function(target, idx, value, receiver) {
368+
if(!/^\d+$/.test(idx)){
369+
return Reflect.set(target, idx, value, receiver);
370+
}
371+
if(typeof value !== "bigint"){
372+
// Chrome error message, Firefox has no "a".
373+
throw new TypeError(`Cannot convert ${value} to a BigInt`);
374+
}
375+
var pair = bigIntToParts(value);
376+
array.set(pair, 2*idx);
377+
}
378+
});
379+
return proxy;
380+
}
381+
return createBigInt64Array;
382+
}
383+
384+
var createBigUint64Array = createBigIntArrayShim(partsToBigIntUnsigned);
385+
var createBigInt64Array = createBigIntArrayShim(partsToBigIntSigned);
386+
387+
Module['HEAP64'] = HEAP64 = createBigInt64Array(HEAP);
388+
Module['HEAPU64'] = HEAPU64 = createBigUint64Array(HEAP);
389+
}
390+
300391
#endif
301392
}
302393

0 commit comments

Comments
 (0)