aboutsummaryrefslogtreecommitdiff
path: root/ext/wasm/api/sqlite3-api-prologue.js
diff options
context:
space:
mode:
authorstephan <stephan@noemail.net>2022-11-07 13:06:20 +0000
committerstephan <stephan@noemail.net>2022-11-07 13:06:20 +0000
commit690d4c545db74e35d2360cfb7674cbb58d904695 (patch)
tree340ed8c6007a9739175e7afad0f263a3b1aa8f6d /ext/wasm/api/sqlite3-api-prologue.js
parentda01757870dabf3994a80f6f153018cd7c87b154 (diff)
downloadsqlite-690d4c545db74e35d2360cfb7674cbb58d904695.tar.gz
sqlite-690d4c545db74e35d2360cfb7674cbb58d904695.zip
Add sqlite3.wasm.alloc.impl() as a "public back door" into the low-level non-throwing allocator. Correct sqlite3.WasmAllocError constructor to behave like its usages expect it to and add tests for that.
FossilOrigin-Name: cea8bf9a144d842c4755c3130273524926e8c4831d7f21c4e34d4e8c74109c8c
Diffstat (limited to 'ext/wasm/api/sqlite3-api-prologue.js')
-rw-r--r--ext/wasm/api/sqlite3-api-prologue.js58
1 files changed, 43 insertions, 15 deletions
diff --git a/ext/wasm/api/sqlite3-api-prologue.js b/ext/wasm/api/sqlite3-api-prologue.js
index d633064be..fed1c5666 100644
--- a/ext/wasm/api/sqlite3-api-prologue.js
+++ b/ext/wasm/api/sqlite3-api-prologue.js
@@ -399,8 +399,22 @@ self.sqlite3ApiBootstrap = function sqlite3ApiBootstrap(
exceptions.
*/
class WasmAllocError extends Error {
+ /**
+ If called with 2 arguments and the 2nd one is an object, it
+ behaves like the Error constructor, else it concatenates all
+ arguments together with a single space between each to
+ construct an error message string. As a special case, if
+ called with no arguments then it uses a default error
+ message.
+ */
constructor(...args){
- super(...args);
+ if(2===args.length && 'object'===typeof args){
+ super(...args);
+ }else if(args.length){
+ super(args.join(' '));
+ }else{
+ super("Allocation failed.");
+ }
this.name = 'WasmAllocError';
}
};
@@ -710,21 +724,33 @@ self.sqlite3ApiBootstrap = function sqlite3ApiBootstrap(
API NOT throw and must instead return SQLITE_NOMEM (or
equivalent, depending on the context).
- That said, very few cases in the API can result in
+ Very few cases in the sqlite3 JS APIs can result in
client-defined functions propagating exceptions via the C-style
- API. Most notably, this applies ot User-defined SQL Functions
- (UDFs) registered via sqlite3_create_function_v2(). For that
- specific case it is recommended that all UDF creation be
- funneled through a utility function and that a wrapper function
- be added around the UDF which catches any exception and sets
- the error state to OOM. (The overall complexity of registering
- UDFs essentially requires a helper for doing so!)
+ API. Most notably, this applies to WASM-bound JS functions
+ which are created directly by clients and passed on _as WASM
+ function pointers_ to functions such as
+ sqlite3_create_function_v2(). Such bindings created
+ transparently by this API will automatically use wrappers which
+ 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
+ underlying C-level allocator.
+
+ Design note: this function is not named "malloc" primarily
+ because Emscripten uses that name and we wanted to avoid any
+ confusion early on in this code's development, when it still
+ had close ties to Emscripten's glue code.
*/
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()).
+
+ Design note: this function is not named "free" for the same
+ reason that this.alloc() is not called this.malloc().
*/
dealloc: undefined/*installed later*/
@@ -752,7 +778,9 @@ self.sqlite3ApiBootstrap = function sqlite3ApiBootstrap(
wasm.allocFromTypedArray = function(srcTypedArray){
affirmBindableTypedArray(srcTypedArray);
const pRet = wasm.alloc(srcTypedArray.byteLength || 1);
- wasm.heapForSize(srcTypedArray.constructor).set(srcTypedArray.byteLength ? srcTypedArray : [0], pRet);
+ wasm.heapForSize(srcTypedArray.constructor).set(
+ srcTypedArray.byteLength ? srcTypedArray : [0], pRet
+ );
return pRet;
};
@@ -763,13 +791,13 @@ self.sqlite3ApiBootstrap = function sqlite3ApiBootstrap(
if(!(f instanceof Function)) toss3("Missing required exports[",key,"] function.");
}
- wasm.alloc = function(n){
- const m = wasm.exports[keyAlloc](n);
- if(!m) throw new WasmAllocError("Failed to allocate "+n+" bytes.");
+ wasm.alloc = function f(n){
+ const m = f.impl(n);
+ if(!m) throw new WasmAllocError("Failed to allocate",n," bytes.");
return m;
};
-
- wasm.dealloc = (m)=>wasm.exports[keyDealloc](m);
+ wasm.alloc.impl = wasm.exports[keyAlloc];
+ wasm.dealloc = wasm.exports[keyDealloc];
/**
Reports info about compile-time options using