From 46d659a936ba4321d01b9a431293deeea1805444 Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Fri, 25 Jun 2021 11:25:17 +0100 Subject: [PATCH] Update sql.js (to SQLite 3.35.0) and wasm_exec.js (to Go 1.16.5) --- package.json | 2 +- src/vector/wasm_exec.js | 111 ++++++++++++++++++++++++++-------------- yarn.lock | 6 +-- 3 files changed, 77 insertions(+), 42 deletions(-) diff --git a/package.json b/package.json index 24d7b1d745..29d20b887d 100644 --- a/package.json +++ b/package.json @@ -77,7 +77,7 @@ "react": "^16.9.0", "react-dom": "^16.9.0", "sanitize-html": "^1.19.1", - "sql.js": "github:Kegsay/sql.js#d55d2069673d0a62ffe729a8a6c96b1328ae396c", + "sql.js": "github:neilalexander/sql.js#b9b375ed34e2ad5eef04f528cfb45d7277c142b9", "ua-parser-js": "^0.7.19", "url": "^0.11.0" }, diff --git a/src/vector/wasm_exec.js b/src/vector/wasm_exec.js index fd3f0272c3..82041e6bb9 100644 --- a/src/vector/wasm_exec.js +++ b/src/vector/wasm_exec.js @@ -11,6 +11,7 @@ // - Node.js // - Electron // - Parcel + // - Webpack if (typeof global !== "undefined") { // global already exists @@ -27,7 +28,10 @@ } if (!global.fs && global.require) { -// global.fs = require("fs"); + const fs = require("fs"); + if (typeof fs === "object" && fs !== null && Object.keys(fs).length !== 0) { + global.fs = fs; + } } const enosys = () => { @@ -98,7 +102,7 @@ } } - if (!global.crypto) { + if (!global.crypto && global.require) { const nodeCrypto = require("crypto"); global.crypto = { getRandomValues(b) { @@ -106,6 +110,9 @@ }, }; } + if (!global.crypto) { + throw new Error("global.crypto is not available, polyfill required (getRandomValues only)"); + } if (!global.performance) { global.performance = { @@ -116,13 +123,19 @@ }; } - if (!global.TextEncoder) { + if (!global.TextEncoder && global.require) { global.TextEncoder = require("util").TextEncoder; } + if (!global.TextEncoder) { + throw new Error("global.TextEncoder is not available, polyfill required"); + } - if (!global.TextDecoder) { + if (!global.TextDecoder && global.require) { global.TextDecoder = require("util").TextDecoder; } + if (!global.TextDecoder) { + throw new Error("global.TextDecoder is not available, polyfill required"); + } // End of polyfills for common API. @@ -172,37 +185,19 @@ const storeValue = (addr, v) => { const nanHead = 0x7FF80000; - if (typeof v === "number") { + if (typeof v === "number" && v !== 0) { if (isNaN(v)) { this.mem.setUint32(addr + 4, nanHead, true); this.mem.setUint32(addr, 0, true); return; } - if (v === 0) { - this.mem.setUint32(addr + 4, nanHead, true); - this.mem.setUint32(addr, 1, true); - return; - } this.mem.setFloat64(addr, v, true); return; } - switch (v) { - case undefined: - this.mem.setFloat64(addr, 0, true); - return; - case null: - this.mem.setUint32(addr + 4, nanHead, true); - this.mem.setUint32(addr, 2, true); - return; - case true: - this.mem.setUint32(addr + 4, nanHead, true); - this.mem.setUint32(addr, 3, true); - return; - case false: - this.mem.setUint32(addr + 4, nanHead, true); - this.mem.setUint32(addr, 4, true); - return; + if (v === undefined) { + this.mem.setFloat64(addr, 0, true); + return; } let id = this._ids.get(v); @@ -216,8 +211,13 @@ this._ids.set(v, id); } this._goRefCounts[id]++; - let typeFlag = 1; + let typeFlag = 0; switch (typeof v) { + case "object": + if (v !== null) { + typeFlag = 1; + } + break; case "string": typeFlag = 2; break; @@ -264,6 +264,7 @@ // func wasmExit(code int32) "runtime.wasmExit": (sp) => { + sp >>>= 0; const code = this.mem.getInt32(sp + 8, true); this.exited = true; delete this._inst; @@ -276,6 +277,7 @@ // func wasmWrite(fd uintptr, p unsafe.Pointer, n int32) "runtime.wasmWrite": (sp) => { + sp >>>= 0; const fd = getInt64(sp + 8); const p = getInt64(sp + 16); const n = this.mem.getInt32(sp + 24, true); @@ -284,16 +286,19 @@ // func resetMemoryDataView() "runtime.resetMemoryDataView": (sp) => { + sp >>>= 0; this.mem = new DataView(this._inst.exports.mem.buffer); }, // func nanotime1() int64 "runtime.nanotime1": (sp) => { + sp >>>= 0; setInt64(sp + 8, (timeOrigin + performance.now()) * 1000000); }, // func walltime1() (sec int64, nsec int32) "runtime.walltime1": (sp) => { + sp >>>= 0; const msec = (new Date).getTime(); setInt64(sp + 8, msec / 1000); this.mem.setInt32(sp + 16, (msec % 1000) * 1000000, true); @@ -301,6 +306,7 @@ // func scheduleTimeoutEvent(delay int64) int32 "runtime.scheduleTimeoutEvent": (sp) => { + sp >>>= 0; const id = this._nextCallbackTimeoutID; this._nextCallbackTimeoutID++; this._scheduledTimeouts.set(id, setTimeout( @@ -320,6 +326,7 @@ // func clearTimeoutEvent(id int32) "runtime.clearTimeoutEvent": (sp) => { + sp >>>= 0; const id = this.mem.getInt32(sp + 8, true); clearTimeout(this._scheduledTimeouts.get(id)); this._scheduledTimeouts.delete(id); @@ -327,11 +334,13 @@ // func getRandomData(r []byte) "runtime.getRandomData": (sp) => { + sp >>>= 0; crypto.getRandomValues(loadSlice(sp + 8)); }, // func finalizeRef(v ref) "syscall/js.finalizeRef": (sp) => { + sp >>>= 0; const id = this.mem.getUint32(sp + 8, true); this._goRefCounts[id]--; if (this._goRefCounts[id] === 0) { @@ -344,44 +353,51 @@ // func stringVal(value string) ref "syscall/js.stringVal": (sp) => { + sp >>>= 0; storeValue(sp + 24, loadString(sp + 8)); }, // func valueGet(v ref, p string) ref "syscall/js.valueGet": (sp) => { + sp >>>= 0; const result = Reflect.get(loadValue(sp + 8), loadString(sp + 16)); - sp = this._inst.exports.getsp(); // see comment above + sp = this._inst.exports.getsp() >>> 0; // see comment above storeValue(sp + 32, result); }, // func valueSet(v ref, p string, x ref) "syscall/js.valueSet": (sp) => { + sp >>>= 0; Reflect.set(loadValue(sp + 8), loadString(sp + 16), loadValue(sp + 32)); }, // func valueDelete(v ref, p string) "syscall/js.valueDelete": (sp) => { + sp >>>= 0; Reflect.deleteProperty(loadValue(sp + 8), loadString(sp + 16)); }, // func valueIndex(v ref, i int) ref "syscall/js.valueIndex": (sp) => { + sp >>>= 0; storeValue(sp + 24, Reflect.get(loadValue(sp + 8), getInt64(sp + 16))); }, // valueSetIndex(v ref, i int, x ref) "syscall/js.valueSetIndex": (sp) => { + sp >>>= 0; Reflect.set(loadValue(sp + 8), getInt64(sp + 16), loadValue(sp + 24)); }, // func valueCall(v ref, m string, args []ref) (ref, bool) "syscall/js.valueCall": (sp) => { + sp >>>= 0; try { const v = loadValue(sp + 8); const m = Reflect.get(v, loadString(sp + 16)); const args = loadSliceOfValues(sp + 32); const result = Reflect.apply(m, v, args); - sp = this._inst.exports.getsp(); // see comment above + sp = this._inst.exports.getsp() >>> 0; // see comment above storeValue(sp + 56, result); this.mem.setUint8(sp + 64, 1); } catch (err) { @@ -392,11 +408,12 @@ // func valueInvoke(v ref, args []ref) (ref, bool) "syscall/js.valueInvoke": (sp) => { + sp >>>= 0; try { const v = loadValue(sp + 8); const args = loadSliceOfValues(sp + 16); const result = Reflect.apply(v, undefined, args); - sp = this._inst.exports.getsp(); // see comment above + sp = this._inst.exports.getsp() >>> 0; // see comment above storeValue(sp + 40, result); this.mem.setUint8(sp + 48, 1); } catch (err) { @@ -407,11 +424,12 @@ // func valueNew(v ref, args []ref) (ref, bool) "syscall/js.valueNew": (sp) => { + sp >>>= 0; try { const v = loadValue(sp + 8); const args = loadSliceOfValues(sp + 16); const result = Reflect.construct(v, args); - sp = this._inst.exports.getsp(); // see comment above + sp = this._inst.exports.getsp() >>> 0; // see comment above storeValue(sp + 40, result); this.mem.setUint8(sp + 48, 1); } catch (err) { @@ -422,11 +440,13 @@ // func valueLength(v ref) int "syscall/js.valueLength": (sp) => { + sp >>>= 0; setInt64(sp + 16, parseInt(loadValue(sp + 8).length)); }, // valuePrepareString(v ref) (ref, int) "syscall/js.valuePrepareString": (sp) => { + sp >>>= 0; const str = encoder.encode(String(loadValue(sp + 8))); storeValue(sp + 16, str); setInt64(sp + 24, str.length); @@ -434,20 +454,23 @@ // valueLoadString(v ref, b []byte) "syscall/js.valueLoadString": (sp) => { + sp >>>= 0; const str = loadValue(sp + 8); loadSlice(sp + 16).set(str); }, // func valueInstanceOf(v ref, t ref) bool "syscall/js.valueInstanceOf": (sp) => { - this.mem.setUint8(sp + 24, loadValue(sp + 8) instanceof loadValue(sp + 16)); + sp >>>= 0; + this.mem.setUint8(sp + 24, (loadValue(sp + 8) instanceof loadValue(sp + 16)) ? 1 : 0); }, // func copyBytesToGo(dst []byte, src ref) (int, bool) "syscall/js.copyBytesToGo": (sp) => { + sp >>>= 0; const dst = loadSlice(sp + 8); const src = loadValue(sp + 32); - if (!(src instanceof Uint8Array)) { + if (!(src instanceof Uint8Array || src instanceof Uint8ClampedArray)) { this.mem.setUint8(sp + 48, 0); return; } @@ -459,9 +482,10 @@ // func copyBytesToJS(dst ref, src []byte) (int, bool) "syscall/js.copyBytesToJS": (sp) => { + sp >>>= 0; const dst = loadValue(sp + 8); const src = loadSlice(sp + 16); - if (!(dst instanceof Uint8Array)) { + if (!(dst instanceof Uint8Array || dst instanceof Uint8ClampedArray)) { this.mem.setUint8(sp + 48, 0); return; } @@ -479,6 +503,9 @@ } async run(instance) { + if (!(instance instanceof WebAssembly.Instance)) { + throw new Error("Go.run: WebAssembly.Instance expected"); + } this._inst = instance; this.mem = new DataView(this._inst.exports.mem.buffer); this._values = [ // JS values that Go currently has references to, indexed by reference id @@ -490,10 +517,17 @@ global, this, ]; - this._goRefCounts = []; // number of references that Go has to a JS value, indexed by reference id - this._ids = new Map(); // mapping from JS values to reference ids - this._idPool = []; // unused ids that have been garbage collected - this.exited = false; // whether the Go program has exited + this._goRefCounts = new Array(this._values.length).fill(Infinity); // number of references that Go has to a JS value, indexed by reference id + this._ids = new Map([ // mapping from JS values to reference ids + [0, 1], + [null, 2], + [true, 3], + [false, 4], + [global, 5], + [this, 6], + ]); + this._idPool = []; // unused ids that have been garbage collected + this.exited = false; // whether the Go program has exited // Pass command line arguments and environment variables to WebAssembly by writing them to the linear memory. let offset = 4096; @@ -559,6 +593,7 @@ } if ( + typeof module !== "undefined" && global.require && global.require.main === module && global.process && diff --git a/yarn.lock b/yarn.lock index fa7455e6f4..6e3239b8ed 100644 --- a/yarn.lock +++ b/yarn.lock @@ -11207,9 +11207,9 @@ sprintf-js@~1.0.2: resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw= -"sql.js@github:Kegsay/sql.js#d55d2069673d0a62ffe729a8a6c96b1328ae396c": - version "1.2.2" - resolved "https://codeload.github.com/Kegsay/sql.js/tar.gz/d55d2069673d0a62ffe729a8a6c96b1328ae396c" +"sql.js@github:neilalexander/sql.js#b9b375ed34e2ad5eef04f528cfb45d7277c142b9": + version "1.5.0" + resolved "https://codeload.github.com/neilalexander/sql.js/tar.gz/b9b375ed34e2ad5eef04f528cfb45d7277c142b9" srcset@^2.0.1: version "2.0.1"