mirror of https://github.com/pyodide/pyodide.git
Enable Wasm BigInt (#2643)
This enables WASM_BIGINT while maintaining (hypothetical) Safari 14 support by shimming BigInt64Array and BigUint64Array if they are missing. I think the last time we tried to enable WASM_BIGINT was before #2019 so our chances are significantly better this time. This will fix dynamic linking bugs and yields a minor reduction in code size.
This commit is contained in:
parent
0aafb5dd12
commit
95b1194945
|
@ -90,6 +90,7 @@ export LDFLAGS_BASE=\
|
|||
-std=c++14 \
|
||||
-s LZ4=1 \
|
||||
-L $(CPYTHONROOT)/installs/python-$(PYVERSION)/lib/ \
|
||||
-s WASM_BIGINT \
|
||||
$(EXTRA_LDFLAGS)
|
||||
|
||||
export CXXFLAGS_BASE=
|
||||
|
|
|
@ -113,6 +113,9 @@ substitutions:
|
|||
Python rather than the host Python.
|
||||
{pr}`2516`
|
||||
|
||||
- {{ Enhancement }} Pyodide now builds with `-sWASM_BIGINT`..
|
||||
{pr}`2643`
|
||||
|
||||
### REPL
|
||||
|
||||
- {{ Enhancement }} Add a spinner while the REPL is loading
|
||||
|
|
|
@ -65,8 +65,8 @@ Pyodide,
|
|||
|
||||
| Browser | Minimal supported version | Release date |
|
||||
| ------- | ------------------------- | ----------------- |
|
||||
| Safari | 13.1 | 19 September 2019 |
|
||||
| Edge | 80 | 26 Feb 2020 |
|
||||
| Safari | 14.0 | 15 September 2020 |
|
||||
| Edge | 80 | 26 February 2020 |
|
||||
|
||||
Other browsers with WebAssembly support might also work however they are not
|
||||
officially supported.
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
From e83a295f8e1b8c48d4748d1811a4b22840f25e14 Mon Sep 17 00:00:00 2001
|
||||
From: Hood <hood@mit.edu>
|
||||
Date: Thu, 24 Jun 2021 04:08:02 -0700
|
||||
Subject: [PATCH 1/7] Throw away errors in minify_wasm_js
|
||||
Subject: [PATCH 1/6] Throw away errors in minify_wasm_js
|
||||
|
||||
---
|
||||
emcc.py | 13 ++++++++-----
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
From 40956dee436737d9dd40e0b57c6e2ebd26569920 Mon Sep 17 00:00:00 2001
|
||||
From: Hood <hood@mit.edu>
|
||||
Date: Wed, 8 Sep 2021 17:49:15 -0700
|
||||
Subject: [PATCH 2/7] Fix dup
|
||||
Subject: [PATCH 2/6] Fix dup
|
||||
|
||||
This fixes two problems with the `dup` system calls:
|
||||
1. `dup` expects that every file descriptor has a corresponding file (so pipes and (https://github.com/emscripten-core/emscripten/issues/14640)
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
From 73b89ee1b5a57c65824baf91b547be32b69decbd Mon Sep 17 00:00:00 2001
|
||||
From: Hood Chatham <roberthoodchatham@gmail.com>
|
||||
Date: Tue, 15 Feb 2022 23:27:03 -0500
|
||||
Subject: [PATCH 3/7] Fix side module exception handling
|
||||
Subject: [PATCH 3/6] Fix side module exception handling
|
||||
|
||||
See https://github.com/emscripten-core/emscripten/pull/16309
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
From 8de43377d0e72a4c5794f8494a06d81a9609090f Mon Sep 17 00:00:00 2001
|
||||
From: Hood Chatham <roberthoodchatham@gmail.com>
|
||||
Date: Wed, 2 Mar 2022 13:44:14 -0800
|
||||
Subject: [PATCH 4/7] Fix lookupPath when applied to a symlink loop
|
||||
Subject: [PATCH 4/6] Fix lookupPath when applied to a symlink loop
|
||||
|
||||
The following code leads to an infinite loop in lookupPath:
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
From 6aca63c041033835d08a99fb54b3327a36652ff8 Mon Sep 17 00:00:00 2001
|
||||
From 8eed4062c1a0bd6aa7859938240f8761e6e72114 Mon Sep 17 00:00:00 2001
|
||||
From: Hood Chatham <roberthoodchatham@gmail.com>
|
||||
Date: Wed, 18 May 2022 21:49:17 -0700
|
||||
Subject: [PATCH 7/7] Indicate Emscripten version in uname
|
||||
Subject: [PATCH 5/6] Indicate Emscripten version in uname
|
||||
|
||||
This patch has been upstreamed:
|
||||
https://github.com/emscripten-core/emscripten/pull/17026
|
|
@ -0,0 +1,139 @@
|
|||
From 4462c2871933db0adc4b46a24f77b942caff969c Mon Sep 17 00:00:00 2001
|
||||
From: Hood Chatham <roberthoodchatham@gmail.com>
|
||||
Date: Sun, 29 May 2022 18:17:29 -0700
|
||||
Subject: [PATCH 6/6] Add BigInt64Array shim for Safari 14
|
||||
|
||||
---
|
||||
src/parseTools.js | 2 +-
|
||||
src/polyfill/bigint64array.js | 87 +++++++++++++++++++++++++++++++++++
|
||||
src/preamble.js | 5 +-
|
||||
3 files changed, 92 insertions(+), 2 deletions(-)
|
||||
create mode 100644 src/polyfill/bigint64array.js
|
||||
|
||||
diff --git a/src/parseTools.js b/src/parseTools.js
|
||||
index 92490fe71..8a183c610 100644
|
||||
--- a/src/parseTools.js
|
||||
+++ b/src/parseTools.js
|
||||
@@ -94,7 +94,7 @@ function preprocess(text, filenameHint) {
|
||||
showStack.push(truthy ? SHOW : IGNORE);
|
||||
} else if (first === '#include') {
|
||||
if (showCurrentLine()) {
|
||||
- let filename = line.substr(line.indexOf(' ') + 1);
|
||||
+ let filename = trimmed.substr(trimmed.indexOf(' ') + 1);
|
||||
if (filename.startsWith('"')) {
|
||||
filename = filename.substr(1, filename.length - 2);
|
||||
}
|
||||
diff --git a/src/polyfill/bigint64array.js b/src/polyfill/bigint64array.js
|
||||
new file mode 100644
|
||||
index 000000000..126c2b51f
|
||||
--- /dev/null
|
||||
+++ b/src/polyfill/bigint64array.js
|
||||
@@ -0,0 +1,87 @@
|
||||
+if (typeof BigInt64Array === "undefined") {
|
||||
+ // BigInt64Array polyfill for Safari versions between v14.0 and v15.0.
|
||||
+ // All browsers other than Safari added BigInt and BigInt64Array at the same
|
||||
+ // time, but Safari introduced BigInt in v14.0 and introduced BigInt64Array in
|
||||
+ // v15.0
|
||||
+
|
||||
+ function partsToBigIntSigned(lower, upper) {
|
||||
+ return BigInt(lower) | (BigInt(upper + 2 * (upper & 0x80000000)) << BigInt(32));
|
||||
+ }
|
||||
+
|
||||
+ function partsToBigIntUnsigned(lower, upper) {
|
||||
+ return BigInt(lower) | (BigInt(upper) << BigInt(32));
|
||||
+ }
|
||||
+
|
||||
+ function bigIntToParts(value) {
|
||||
+ var lower = Number(BigInt(value) & BigInt(0xffffffff)) | 0;
|
||||
+ var upper = (Number(BigInt(value) >> BigInt(32)) | 0);
|
||||
+ return [lower, upper];
|
||||
+ }
|
||||
+
|
||||
+ function createBigIntArrayShim(partsToBigInt) {
|
||||
+ function createBigInt64Array(array) {
|
||||
+ if(!ArrayBuffer.isView(array)){
|
||||
+ array = new Uint32Array(array);
|
||||
+ }
|
||||
+ let proxy = new Proxy({
|
||||
+ slice: function(min, max) {
|
||||
+ var new_buf = array.slice(min * 2, max *2);
|
||||
+ return createBigInt64Array(new_buf);
|
||||
+ },
|
||||
+ subarray: function(min, max) {
|
||||
+ var new_buf = array.subarray(min * 2, max *2);
|
||||
+ return createBigInt64Array(new_buf);
|
||||
+ },
|
||||
+ [Symbol.iterator]: function*() {
|
||||
+ for (var i = 0; i < (array.length)/2; i++) {
|
||||
+ yield partsToBigInt(array[2*i], array[2*i+1]);
|
||||
+ }
|
||||
+ },
|
||||
+ buffer : array.buffer,
|
||||
+ byteLength : array.byteLength,
|
||||
+ offset : array.byteOffset / 2,
|
||||
+ copyWithin: function(target, start, end) {
|
||||
+ array.copyWithin(target*2, start * 2, end*2);
|
||||
+ return proxy;
|
||||
+ },
|
||||
+ set: function(source, targetOffset) {
|
||||
+ if(2*(source.length + targetOffset) > array.length) {
|
||||
+ // This is the Chrome error message
|
||||
+ // Firefox: "invalid or out-of-range index"
|
||||
+ throw new RangeError("offset is out of bounds");
|
||||
+ }
|
||||
+ for (var i = 0; i < array.length; i++) {
|
||||
+ var value = source[i];
|
||||
+ var pair = bigIntToParts(BigInt(value));
|
||||
+ array.set(pair, 2*(targetOffset + i));
|
||||
+ }
|
||||
+ }
|
||||
+ }, {
|
||||
+ get: function(target, idx, receiver) {
|
||||
+ if (typeof idx !== "string" || !/^\d+$/.test(idx)) {
|
||||
+ return Reflect.get(target, idx, receiver);
|
||||
+ }
|
||||
+ var lower = array[idx * 2];
|
||||
+ var upper = array[idx * 2 + 1];
|
||||
+ return partsToBigInt(lower, upper);
|
||||
+ },
|
||||
+ set: function(target, idx, value, receiver) {
|
||||
+ if (typeof idx !== "string" || !/^\d+$/.test(idx)) {
|
||||
+ return Reflect.set(target, idx, value, receiver);
|
||||
+ }
|
||||
+ if (typeof value !== "bigint") {
|
||||
+ // Chrome error message, Firefox has no "a" in front if "BigInt".
|
||||
+ throw new TypeError(`Cannot convert ${value} to a BigInt`);
|
||||
+ }
|
||||
+ var pair = bigIntToParts(value);
|
||||
+ array.set(pair, 2*idx);
|
||||
+ }
|
||||
+ });
|
||||
+ return proxy;
|
||||
+ }
|
||||
+ return createBigInt64Array;
|
||||
+ }
|
||||
+
|
||||
+ var BigUint64Array = createBigIntArrayShim(partsToBigIntUnsigned);
|
||||
+ var BigInt64Array = createBigIntArrayShim(partsToBigIntSigned);
|
||||
+}
|
||||
diff --git a/src/preamble.js b/src/preamble.js
|
||||
index 1094dd7dc..6afca739b 100644
|
||||
--- a/src/preamble.js
|
||||
+++ b/src/preamble.js
|
||||
@@ -285,9 +285,12 @@ function updateGlobalBufferAndViews(buf) {
|
||||
Module['HEAPF32'] = HEAPF32 = new Float32Array(buf);
|
||||
Module['HEAPF64'] = HEAPF64 = new Float64Array(buf);
|
||||
#if WASM_BIGINT
|
||||
+#if MIN_SAFARI_VERSION < 150000
|
||||
+ #include "polyfill/bigint64array.js"
|
||||
+#endif // MIN_SAFARI_VERSION < 15000
|
||||
Module['HEAP64'] = HEAP64 = new BigInt64Array(buf);
|
||||
Module['HEAPU64'] = HEAPU64 = new BigUint64Array(buf);
|
||||
-#endif
|
||||
+#endif // WASM_BIGINT
|
||||
}
|
||||
|
||||
var TOTAL_STACK = {{{ TOTAL_STACK }}};
|
||||
--
|
||||
2.25.1
|
||||
|
|
@ -34,7 +34,7 @@
|
|||
(BigInt(lower) | (BigInt(upper) << BigInt(32)))
|
||||
|
||||
#define IBIGINT_FROM_PAIR(lower, upper) \
|
||||
(BigInt(lower) | (BigInt(upper - 2 * (upper & 0x80000000)) << BigInt(32)))
|
||||
(BigInt(lower) | (BigInt(upper + 2 * (upper & 0x80000000)) << BigInt(32)))
|
||||
|
||||
#define LOAD_U64(addr, offset) \
|
||||
UBIGINT_FROM_PAIR(DEREF_U32(addr, offset * 2), \
|
||||
|
|
Loading…
Reference in New Issue