aboutsummaryrefslogtreecommitdiff
path: root/ext/wasm/api/sqlite3-api-prologue.js
diff options
context:
space:
mode:
authorstephan <stephan@noemail.net>2022-12-03 11:16:55 +0000
committerstephan <stephan@noemail.net>2022-12-03 11:16:55 +0000
commit85ef4e434415ac8e674f4f92480a38cd7c3a135e (patch)
treef42d3728596de78bd548b6fc5552f63af06ea89e /ext/wasm/api/sqlite3-api-prologue.js
parent2564ca7d15328a8519248be22829702348253d8e (diff)
downloadsqlite-85ef4e434415ac8e674f4f92480a38cd7c3a135e.tar.gz
sqlite-85ef4e434415ac8e674f4f92480a38cd7c3a135e.zip
JavaScript: add sqlite3.wasm.realloc(), sqlite3.capi.SQLITE_MAX_ALLOCATION_SIZE, and related tests.
FossilOrigin-Name: eeb84ba5de1152ef0f42105b8b285fdee9f5ad58281e60a4e0c8b1d6de1dead8
Diffstat (limited to 'ext/wasm/api/sqlite3-api-prologue.js')
-rw-r--r--ext/wasm/api/sqlite3-api-prologue.js92
1 files changed, 64 insertions, 28 deletions
diff --git a/ext/wasm/api/sqlite3-api-prologue.js b/ext/wasm/api/sqlite3-api-prologue.js
index a99065663..b6ff94dfe 100644
--- a/ext/wasm/api/sqlite3-api-prologue.js
+++ b/ext/wasm/api/sqlite3-api-prologue.js
@@ -75,6 +75,10 @@
the `free(3)`-compatible routine for the WASM
environment. Defaults to `"sqlite3_free"`.
+ - `reallocExportName`: the name of the function, in `exports`, of
+ the `realloc(3)`-compatible routine for the WASM
+ environment. Defaults to `"sqlite3_realloc"`.
+
- `wasmfsOpfsDir`[^1]: if the environment supports persistent
storage using OPFS-over-WASMFS , this directory names the "mount
point" for that directory. It must be prefixed by `/` and may
@@ -110,6 +114,7 @@ self.sqlite3ApiBootstrap = function sqlite3ApiBootstrap(
})(),
allocExportName: 'sqlite3_malloc',
deallocExportName: 'sqlite3_free',
+ reallocExportName: 'sqlite3_realloc',
wasmfsOpfsDir: '/opfs'
}, apiConfig || {});
@@ -284,12 +289,14 @@ self.sqlite3ApiBootstrap = function sqlite3ApiBootstrap(
};
/**
- Returns true if v appears to be one of our bind()-able
- TypedArray types: Uint8Array or Int8Array. Support for
- TypedArrays with element sizes >1 is TODO.
+ Returns true if v appears to be one of our bind()-able TypedArray
+ types: Uint8Array or Int8Array. Support for TypedArrays with
+ element sizes >1 is a potential TODO just waiting on a use case
+ to justify them.
*/
const isBindableTypedArray = (v)=>{
- return v && v.constructor && (1===v.constructor.BYTES_PER_ELEMENT);
+ return v && (v instanceof Uint8Array || v instanceof Int8Array);
+ //v && v.constructor && (1===v.constructor.BYTES_PER_ELEMENT);
};
/**
@@ -302,7 +309,8 @@ self.sqlite3ApiBootstrap = function sqlite3ApiBootstrap(
isSQLableTypedArray() list.
*/
const isSQLableTypedArray = (v)=>{
- return v && v.constructor && (1===v.constructor.BYTES_PER_ELEMENT);
+ return v && (v instanceof Uint8Array || v instanceof Int8Array);
+ //v && v.constructor && (1===v.constructor.BYTES_PER_ELEMENT);
};
/** Returns true if isBindableTypedArray(v) does, else throws with a message
@@ -664,12 +672,12 @@ self.sqlite3ApiBootstrap = function sqlite3ApiBootstrap(
"or config.memory (imported)."),
/**
- The API's one single point of access to the WASM-side memory
- allocator. Works like malloc(3) (and is likely bound to
- malloc()) but throws an WasmAllocError if allocation fails. It is
- important that any code which might pass through the sqlite3 C
- API NOT throw and must instead return SQLITE_NOMEM (or
- equivalent, depending on the context).
+ The API's primary point of access to the WASM-side memory
+ allocator. Works like sqlite3_malloc() but throws a
+ WasmAllocError if allocation fails. It is important that any
+ code which might pass through the sqlite3 C API NOT throw and
+ must instead return SQLITE_NOMEM (or equivalent, depending on
+ the context).
Very few cases in the sqlite3 JS APIs can result in
client-defined functions propagating exceptions via the C-style
@@ -681,7 +689,7 @@ self.sqlite3ApiBootstrap = function sqlite3ApiBootstrap(
catch exceptions and convert them to appropriate error codes.
For cases where non-throwing allocation is required, use
- sqlite3.wasm.alloc.impl(), which is direct binding of the
+ this.alloc.impl(), which is direct binding of the
underlying C-level allocator.
Design note: this function is not named "malloc" primarily
@@ -692,9 +700,27 @@ self.sqlite3ApiBootstrap = function sqlite3ApiBootstrap(
alloc: undefined/*installed later*/,
/**
- The API's one single point of access to the WASM-side memory
- deallocator. Works like free(3) (and is likely bound to
- free()).
+ Rarely necessary in JS code, this routine works like
+ sqlite3_realloc(M,N), where M is either NULL or a pointer
+ obtained from this function or this.alloc() and N is the number
+ of bytes to reallocate the block to. Returns a pointer to the
+ reallocated block or 0 if allocation fails.
+
+ If M is NULL and N is positive, this behaves like
+ this.alloc(N). If N is 0, it behaves like this.dealloc().
+ Results are undefined if N is negative (sqlite3_realloc()
+ treats that as 0, but if this code is built with a different
+ allocator it may misbehave with negative values).
+
+ Like this.alloc.impl(), this.realloc.impl() is a direct binding
+ to the underlying realloc() implementation which does not throw
+ exceptions, instead returning 0 on allocation error.
+ */
+ realloc: undefined/*installed later*/,
+
+ /**
+ The API's primary point of access to the WASM-side memory
+ deallocator. Works like sqlite3_free().
Design note: this function is not named "free" for the same
reason that this.alloc() is not called this.malloc().
@@ -731,20 +757,30 @@ self.sqlite3ApiBootstrap = function sqlite3ApiBootstrap(
return pRet;
};
- const keyAlloc = config.allocExportName,
- keyDealloc = config.deallocExportName;
- for(const key of [keyAlloc, keyDealloc]){
- const f = wasm.exports[key];
- if(!(f instanceof Function)) toss3("Missing required exports[",key,"] function.");
- }
+ {
+ // Set up allocators...
+ const keyAlloc = config.allocExportName,
+ keyDealloc = config.deallocExportName,
+ keyRealloc = config.reallocExportName;
+ for(const key of [keyAlloc, keyDealloc, keyRealloc]){
+ const f = wasm.exports[key];
+ if(!(f instanceof Function)) toss3("Missing required exports[",key,"] function.");
+ }
- wasm.alloc = function f(n){
- const m = f.impl(n);
- if(!m) throw new WasmAllocError("Failed to allocate",n," bytes.");
- return m;
- };
- wasm.alloc.impl = wasm.exports[keyAlloc];
- wasm.dealloc = wasm.exports[keyDealloc];
+ wasm.alloc = function f(n){
+ const m = f.impl(n);
+ if(!m) throw new WasmAllocError("Failed to allocate",n," bytes.");
+ return m;
+ };
+ wasm.alloc.impl = wasm.exports[keyAlloc];
+ wasm.realloc = function f(m,n){
+ const m2 = f.impl(m,n);
+ if(n && !m2) throw new WasmAllocError("Failed to reallocate",n," bytes.");
+ return n ? m2 : 0;
+ };
+ wasm.realloc.impl = wasm.exports[keyRealloc];
+ wasm.dealloc = wasm.exports[keyDealloc];
+ }
/**
Reports info about compile-time options using