Skip to content

Commit 643d969

Browse files
rhashimotosimolus3shoestringrgrantcoxdependabot[bot]
authored
Merge upstream wa-sqlite 1.0.9 (#9)
* Fix resetting isHandleRequested * Bump package version. * Fix hello demo import paths. * Permit JS booleans to be bound to queries, as integer 0/1 values (rhashimoto#272) * Permit boolean values to be bound to statements, as 0/1 * Add test for boolean binding * Using a single TextEncoder for all string conversions * Export HEAP* module members for recent EMSDK changes. * Bump tar-fs from 3.0.8 to 3.0.9 Bumps [tar-fs](https://github.com/mafintosh/tar-fs) from 3.0.8 to 3.0.9. - [Commits](mafintosh/tar-fs@v3.0.8...v3.0.9) --- updated-dependencies: - dependency-name: tar-fs dependency-version: 3.0.9 dependency-type: indirect ... Signed-off-by: dependabot[bot] <[email protected]> * Update SQLite to 3.50.1. * Bump package version. * Update issue templates * Replace Facade Proxy with handwritten proxy. (rhashimoto#285) * Replace Proxy with handwritten proxy for jRead/jWrite buffers. * Replace Proxy with handwritten proxy for VFS return data. --------- Co-authored-by: Roy Hashimoto <[email protected]> * Use non-CAPTCHA SQLite download URL. (rhashimoto#289) * Use non-CAPTCHA SQLite download URL. * Use consistent Makefile variable bracing. --------- Co-authored-by: Roy Hashimoto <[email protected]> * Fix WebLocksMixin state initialization. (rhashimoto#293) * Fix WebLocksMixin state initialization. * Don't fetch state in WebLocksMixin file control unnecessarily. * Minor fixes. --------- Co-authored-by: Roy Hashimoto <[email protected]> * Bump package version. --------- Signed-off-by: dependabot[bot] <[email protected]> Co-authored-by: Simon Binder <[email protected]> Co-authored-by: Roy Hashimoto <[email protected]> Co-authored-by: Grant Cox <[email protected]> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
1 parent 1ffca81 commit 643d969

16 files changed

+292
-86
lines changed
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
---
2+
name: " Do not post anything other than a bug report"
3+
about: Issues are only for possible bugs in project code.
4+
title: ''
5+
labels: ''
6+
assignees: ''
7+
8+
---
9+
10+

Makefile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# dependencies
2-
SQLITE_VERSION = version-3.47.0
3-
SQLITE_TARBALL_URL = https://www.sqlite.org/src/tarball/sqlite.tar.gz?r=${SQLITE_VERSION}
2+
SQLITE_VERSION = version-3.50.1
3+
SQLITE_TARBALL_URL = https://www.sqlite.org/src/tarball/$(SQLITE_VERSION)/sqlite.tar.gz
44

55
EXTENSION_FUNCTIONS = extension-functions.c
66
EXTENSION_FUNCTIONS_URL = https://www.sqlite.org/contrib/download/extension-functions.c?get=25

demo/hello/hello.js

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@
44
// to use. Note that an asynchronous VFS requires an asynchronous build
55
// (Asyncify or JSPI). As of 2024-05-26, JSPI is only available behind
66
// a flag on Chromium browsers.
7-
// import SQLiteESMFactory from '../dist/wa-sqlite.mjs';
7+
// import SQLiteESMFactory from '../../dist/wa-sqlite.mjs';
88
import SQLiteESMFactory from '../../dist/wa-sqlite-async.mjs';
9-
// import SQLiteESMFactory from '../dist/wa-sqlite-jspi.mjs';
9+
// import SQLiteESMFactory from '../../dist/wa-sqlite-jspi.mjs';
1010

1111
// Uncomment one of the following imports to choose a VFS. Note that an
1212
// asynchronous VFS requires an asynchronous build, and an VFS using
@@ -19,11 +19,11 @@ import SQLiteESMFactory from '../../dist/wa-sqlite-async.mjs';
1919
// clear the appropriate storage for things to work.
2020
import { IDBBatchAtomicVFS as MyVFS } from '../../src/examples/IDBBatchAtomicVFS.js';
2121
// import { IDBMirrorVFS as MyVFS } from '../../src/examples/IDBMirrorVFS.js';
22-
// import { AccessHandlePoolVFS as MyVFS } from '../src/examples/AccessHandlePoolVFS.js';
23-
// import { OPFSAdaptiveVFS as MyVFS } from '../src/examples/OPFSAdaptiveVFS.js';
22+
// import { AccessHandlePoolVFS as MyVFS } from '../../src/examples/AccessHandlePoolVFS.js';
23+
// import { OPFSAdaptiveVFS as MyVFS } from '../../src/examples/OPFSAdaptiveVFS.js';
2424
// import { OPFSAnyContextVFS as MyVFS } from '../../src/examples/OPFSAnyContextVFS.js';
25-
// import { OPFSCoopSyncVFS as MyVFS } from '../src/examples/OPFSCoopSyncVFS.js';
26-
// import { OPFSPermutedVFS as MyVFS } from '../src/examples/OPFSPermutedVFS.js';
25+
// import { OPFSCoopSyncVFS as MyVFS } from '../../src/examples/OPFSCoopSyncVFS.js';
26+
// import { OPFSPermutedVFS as MyVFS } from '../../src/examples/OPFSPermutedVFS.js';
2727

2828
import * as SQLite from '../../src/sqlite-api.js';
2929

dist/wa-sqlite-async.wasm

7.1 KB
Binary file not shown.

dist/wa-sqlite-jspi.wasm

3.96 KB
Binary file not shown.

dist/wa-sqlite.wasm

3.96 KB
Binary file not shown.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "wa-sqlite",
3-
"version": "1.0.6",
3+
"version": "1.0.9",
44
"type": "module",
55
"main": "src/sqlite-api.js",
66
"types": "src/types/index.d.ts",

src/FacadeVFS.js

Lines changed: 219 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -405,64 +405,30 @@ export class FacadeVFS extends VFS.Base {
405405

406406
/**
407407
* Wrapped DataView for pointer arguments.
408-
* Pointers to a single value are passed using DataView. A Proxy
409-
* wrapper prevents use of incorrect type or endianness.
408+
* Pointers to a single value are passed using a DataView-like class.
409+
* This wrapper class prevents use of incorrect type or endianness, and
410+
* reacquires the underlying buffer when the WebAssembly memory is resized.
410411
* @param {'Int32'|'BigInt64'} type
411412
* @param {number} byteOffset
412413
* @returns {DataView}
413414
*/
414415
#makeTypedDataView(type, byteOffset) {
415-
const byteLength = type === 'Int32' ? 4 : 8;
416-
const getter = `get${type}`;
417-
const setter = `set${type}`;
418-
const makeDataView = () => new DataView(
419-
this._module.HEAPU8.buffer,
420-
this._module.HEAPU8.byteOffset + byteOffset,
421-
byteLength);
422-
let dataView = makeDataView();
423-
return new Proxy(dataView, {
424-
get(_, prop) {
425-
if (dataView.buffer.byteLength === 0) {
426-
// WebAssembly memory resize detached the buffer.
427-
dataView = makeDataView();
428-
}
429-
if (prop === getter) {
430-
return function(byteOffset, littleEndian) {
431-
if (!littleEndian) throw new Error('must be little endian');
432-
return dataView[prop](byteOffset, littleEndian);
433-
}
434-
}
435-
if (prop === setter) {
436-
return function(byteOffset, value, littleEndian) {
437-
if (!littleEndian) throw new Error('must be little endian');
438-
return dataView[prop](byteOffset, value, littleEndian);
439-
}
440-
}
441-
if (typeof prop === 'string' && (prop.match(/^(get)|(set)/))) {
442-
throw new Error('invalid type');
443-
}
444-
const result = dataView[prop];
445-
return typeof result === 'function' ? result.bind(dataView) : result;
446-
}
447-
});
416+
// @ts-ignore
417+
return new DataViewProxy(this._module, byteOffset, type);
448418
}
449419

450420
/**
421+
* Wrapped Uint8Array for buffer arguments.
422+
* Memory blocks are passed as a Uint8Array-like class. This wrapper
423+
* class reacquires the underlying buffer when the WebAssembly memory
424+
* is resized.
451425
* @param {number} byteOffset
452426
* @param {number} byteLength
427+
* @returns {Uint8Array}
453428
*/
454429
#makeDataArray(byteOffset, byteLength) {
455-
let target = this._module.HEAPU8.subarray(byteOffset, byteOffset + byteLength);
456-
return new Proxy(target, {
457-
get: (_, prop, receiver) => {
458-
if (target.buffer.byteLength === 0) {
459-
// WebAssembly memory resize detached the buffer.
460-
target = this._module.HEAPU8.subarray(byteOffset, byteOffset + byteLength);
461-
}
462-
const result = target[prop];
463-
return typeof result === 'function' ? result.bind(target) : result;
464-
}
465-
});
430+
// @ts-ignore
431+
return new Uint8ArrayProxy(this._module, byteOffset, byteLength);
466432
}
467433

468434
#decodeFilename(zName, flags) {
@@ -506,3 +472,210 @@ export class FacadeVFS extends VFS.Base {
506472
function delegalize(lo32, hi32) {
507473
return (hi32 * 0x100000000) + lo32 + (lo32 < 0 ? 2**32 : 0);
508474
}
475+
476+
// This class provides a Uint8Array-like interface for a WebAssembly memory
477+
// buffer. It is used to access memory blocks passed as arguments to
478+
// xRead, xWrite, etc. The class reacquires the underlying buffer when the
479+
// WebAssembly memory is resized, which can happen when the memory is
480+
// detached and resized by the WebAssembly module.
481+
//
482+
// Note that although this class implements the same methods as Uint8Array,
483+
// it is not a real Uint8Array and passing it to functions that expect
484+
// a Uint8Array may not work. Use subarray() to get a real Uint8Array
485+
// if needed.
486+
class Uint8ArrayProxy {
487+
#module;
488+
489+
#_array = new Uint8Array()
490+
get #array() {
491+
if (this.#_array.buffer.byteLength === 0) {
492+
// WebAssembly memory resize detached the buffer so re-create the
493+
// array with the new buffer.
494+
this.#_array = this.#module.HEAPU8.subarray(
495+
this.byteOffset,
496+
this.byteOffset + this.byteLength);
497+
}
498+
return this.#_array;
499+
}
500+
501+
/**
502+
* @param {*} module
503+
* @param {number} byteOffset
504+
* @param {number} byteLength
505+
*/
506+
constructor(module, byteOffset, byteLength) {
507+
this.#module = module;
508+
this.byteOffset = byteOffset;
509+
this.length = this.byteLength = byteLength;
510+
}
511+
512+
get buffer() {
513+
return this.#array.buffer;
514+
}
515+
516+
at(index) {
517+
return this.#array.at(index);
518+
}
519+
copyWithin(target, start, end) {
520+
this.#array.copyWithin(target, start, end);
521+
}
522+
entries() {
523+
return this.#array.entries();
524+
}
525+
every(predicate) {
526+
return this.#array.every(predicate);
527+
}
528+
fill(value, start, end) {
529+
this.#array.fill(value, start, end);
530+
}
531+
filter(predicate) {
532+
return this.#array.filter(predicate);
533+
}
534+
find(predicate) {
535+
return this.#array.find(predicate);
536+
}
537+
findIndex(predicate) {
538+
return this.#array.findIndex(predicate);
539+
}
540+
findLast(predicate) {
541+
return this.#array.findLast(predicate);
542+
}
543+
findLastIndex(predicate) {
544+
return this.#array.findLastIndex(predicate);
545+
}
546+
forEach(callback) {
547+
this.#array.forEach(callback);
548+
}
549+
includes(value, start) {
550+
return this.#array.includes(value, start);
551+
}
552+
indexOf(value, start) {
553+
return this.#array.indexOf(value, start);
554+
}
555+
join(separator) {
556+
return this.#array.join(separator);
557+
}
558+
keys() {
559+
return this.#array.keys();
560+
}
561+
lastIndexOf(value, start) {
562+
return this.#array.lastIndexOf(value, start);
563+
}
564+
map(callback) {
565+
return this.#array.map(callback);
566+
}
567+
reduce(callback, initialValue) {
568+
return this.#array.reduce(callback, initialValue);
569+
}
570+
reduceRight(callback, initialValue) {
571+
return this.#array.reduceRight(callback, initialValue);
572+
}
573+
reverse() {
574+
this.#array.reverse();
575+
}
576+
set(array, offset) {
577+
this.#array.set(array, offset);
578+
}
579+
slice(start, end) {
580+
return this.#array.slice(start, end);
581+
}
582+
some(predicate) {
583+
return this.#array.some(predicate);
584+
}
585+
sort(compareFn) {
586+
this.#array.sort(compareFn);
587+
}
588+
subarray(begin, end) {
589+
return this.#array.subarray(begin, end);
590+
}
591+
toLocaleString(locales, options) {
592+
// @ts-ignore
593+
return this.#array.toLocaleString(locales, options);
594+
}
595+
toReversed() {
596+
return this.#array.toReversed();
597+
}
598+
toSorted(compareFn) {
599+
return this.#array.toSorted(compareFn);
600+
}
601+
toString() {
602+
return this.#array.toString();
603+
}
604+
values() {
605+
return this.#array.values();
606+
}
607+
with(index, value) {
608+
return this.#array.with(index, value);
609+
}
610+
[Symbol.iterator]() {
611+
return this.#array[Symbol.iterator]();
612+
}
613+
}
614+
615+
// This class provides a DataView-like interface for a WebAssembly memory
616+
// buffer, restricted to either Int32 or BigInt64 types. It also reacquires
617+
// the underlying buffer when the WebAssembly memory is resized, which can
618+
// happen when the memory is detached and resized by the WebAssembly module.
619+
class DataViewProxy {
620+
#module;
621+
#type;
622+
623+
#_view = new DataView(new ArrayBuffer(0));
624+
get #view() {
625+
if (this.#_view.buffer.byteLength === 0) {
626+
// WebAssembly memory resize detached the buffer so re-create the
627+
// view with the new buffer.
628+
this.#_view = new DataView(
629+
this.#module.HEAPU8.buffer,
630+
this.#module.HEAPU8.byteOffset + this.byteOffset);
631+
}
632+
return this.#_view;
633+
}
634+
635+
/**
636+
* @param {*} module
637+
* @param {number} byteOffset
638+
* @param {'Int32'|'BigInt64'} type
639+
*/
640+
constructor(module, byteOffset, type) {
641+
this.#module = module;
642+
this.byteOffset = byteOffset;
643+
this.#type = type;
644+
}
645+
646+
get buffer() {
647+
return this.#view.buffer;
648+
}
649+
get byteLength() {
650+
return this.#type === 'Int32' ? 4 : 8;
651+
}
652+
653+
getInt32(byteOffset, littleEndian) {
654+
if (this.#type !== 'Int32') {
655+
throw new Error('invalid type');
656+
}
657+
if (!littleEndian) throw new Error('must be little endian');
658+
return this.#view.getInt32(byteOffset, littleEndian);
659+
}
660+
setInt32(byteOffset, value, littleEndian) {
661+
if (this.#type !== 'Int32') {
662+
throw new Error('invalid type');
663+
}
664+
if (!littleEndian) throw new Error('must be little endian');
665+
this.#view.setInt32(byteOffset, value, littleEndian);
666+
}
667+
getBigInt64(byteOffset, littleEndian) {
668+
if (this.#type !== 'BigInt64') {
669+
throw new Error('invalid type');
670+
}
671+
if (!littleEndian) throw new Error('must be little endian');
672+
return this.#view.getBigInt64(byteOffset, littleEndian);
673+
}
674+
setBigInt64(byteOffset, value, littleEndian) {
675+
if (this.#type !== 'BigInt64') {
676+
throw new Error('invalid type');
677+
}
678+
if (!littleEndian) throw new Error('must be little endian');
679+
this.#view.setBigInt64(byteOffset, value, littleEndian);
680+
}
681+
}

0 commit comments

Comments
 (0)