1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-07-29 08:01:23 +03:00

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
This commit is contained in:
stephan
2022-11-07 13:06:20 +00:00
parent da01757870
commit 690d4c545d
4 changed files with 65 additions and 25 deletions

View File

@ -399,8 +399,22 @@ self.sqlite3ApiBootstrap = function sqlite3ApiBootstrap(
exceptions. exceptions.
*/ */
class WasmAllocError extends Error { 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){ constructor(...args){
if(2===args.length && 'object'===typeof args){
super(...args); super(...args);
}else if(args.length){
super(args.join(' '));
}else{
super("Allocation failed.");
}
this.name = 'WasmAllocError'; this.name = 'WasmAllocError';
} }
}; };
@ -710,21 +724,33 @@ self.sqlite3ApiBootstrap = function sqlite3ApiBootstrap(
API NOT throw and must instead return SQLITE_NOMEM (or API NOT throw and must instead return SQLITE_NOMEM (or
equivalent, depending on the context). 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 client-defined functions propagating exceptions via the C-style
API. Most notably, this applies ot User-defined SQL Functions API. Most notably, this applies to WASM-bound JS functions
(UDFs) registered via sqlite3_create_function_v2(). For that which are created directly by clients and passed on _as WASM
specific case it is recommended that all UDF creation be function pointers_ to functions such as
funneled through a utility function and that a wrapper function sqlite3_create_function_v2(). Such bindings created
be added around the UDF which catches any exception and sets transparently by this API will automatically use wrappers which
the error state to OOM. (The overall complexity of registering catch exceptions and convert them to appropriate error codes.
UDFs essentially requires a helper for doing so!)
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*/, alloc: undefined/*installed later*/,
/** /**
The API's one single point of access to the WASM-side memory The API's one single point of access to the WASM-side memory
deallocator. Works like free(3) (and is likely bound to deallocator. Works like free(3) (and is likely bound to
free()). 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*/ dealloc: undefined/*installed later*/
@ -752,7 +778,9 @@ self.sqlite3ApiBootstrap = function sqlite3ApiBootstrap(
wasm.allocFromTypedArray = function(srcTypedArray){ wasm.allocFromTypedArray = function(srcTypedArray){
affirmBindableTypedArray(srcTypedArray); affirmBindableTypedArray(srcTypedArray);
const pRet = wasm.alloc(srcTypedArray.byteLength || 1); 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; return pRet;
}; };
@ -763,13 +791,13 @@ self.sqlite3ApiBootstrap = function sqlite3ApiBootstrap(
if(!(f instanceof Function)) toss3("Missing required exports[",key,"] function."); if(!(f instanceof Function)) toss3("Missing required exports[",key,"] function.");
} }
wasm.alloc = function(n){ wasm.alloc = function f(n){
const m = wasm.exports[keyAlloc](n); const m = f.impl(n);
if(!m) throw new WasmAllocError("Failed to allocate "+n+" bytes."); if(!m) throw new WasmAllocError("Failed to allocate",n," bytes.");
return m; return m;
}; };
wasm.alloc.impl = wasm.exports[keyAlloc];
wasm.dealloc = (m)=>wasm.exports[keyDealloc](m); wasm.dealloc = wasm.exports[keyDealloc];
/** /**
Reports info about compile-time options using Reports info about compile-time options using

View File

@ -342,8 +342,20 @@
throw new sqlite3.WasmAllocError; throw new sqlite3.WasmAllocError;
}catch(e){ }catch(e){
T.assert(e instanceof Error) T.assert(e instanceof Error)
.assert(e instanceof sqlite3.WasmAllocError); .assert(e instanceof sqlite3.WasmAllocError)
.assert("Allocation failed." === e.message);
} }
try {
throw new sqlite3.WasmAllocError("test",{
cause: 3
});
}catch(e){
T.assert(3 === e.cause)
.assert("test" === e.message);
}
try {throw new sqlite3.WasmAllocError("test","ing",".")}
catch(e){T.assert("test ing ." === e.message)}
try{ throw new sqlite3.SQLite3Error(capi.SQLITE_SCHEMA) } try{ throw new sqlite3.SQLite3Error(capi.SQLITE_SCHEMA) }
catch(e){ T.assert('SQLITE_SCHEMA' === e.message) } catch(e){ T.assert('SQLITE_SCHEMA' === e.message) }
try{ sqlite3.SQLite3Error.toss(capi.SQLITE_CORRUPT,{cause: true}) } try{ sqlite3.SQLite3Error.toss(capi.SQLITE_CORRUPT,{cause: true}) }

View File

@ -1,5 +1,5 @@
C Fix\srequirements\smarks\sso\sthat\sthey\smatch\sdocumentation\scorrections. C Add\ssqlite3.wasm.alloc.impl()\sas\sa\s"public\sback\sdoor"\sinto\sthe\slow-level\snon-throwing\sallocator.\sCorrect\ssqlite3.WasmAllocError\sconstructor\sto\sbehave\slike\sits\susages\sexpect\sit\sto\sand\sadd\stests\sfor\sthat.
D 2022-11-07T12:21:06.865 D 2022-11-07T13:06:20.227
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
@ -502,7 +502,7 @@ F ext/wasm/api/sqlite3-api-cleanup.js ecdc69dbfccfe26146f04799fcfd4a6f5790d46e7e
F ext/wasm/api/sqlite3-api-glue.js 056f44b82c126358a0175e08a892d56fadfce177b0d7a0012502a6acf67ea6d5 F ext/wasm/api/sqlite3-api-glue.js 056f44b82c126358a0175e08a892d56fadfce177b0d7a0012502a6acf67ea6d5
F ext/wasm/api/sqlite3-api-oo1.js e9a83489bbb4838ce0aee46eaaa9350e0e25a5b926b565e4f5ae8e840e4fbaed F ext/wasm/api/sqlite3-api-oo1.js e9a83489bbb4838ce0aee46eaaa9350e0e25a5b926b565e4f5ae8e840e4fbaed
F ext/wasm/api/sqlite3-api-opfs.js cdcbb57acc66f4569ac9e18f9d13d5a3657d8aae195725c6324943da56c1005d F ext/wasm/api/sqlite3-api-opfs.js cdcbb57acc66f4569ac9e18f9d13d5a3657d8aae195725c6324943da56c1005d
F ext/wasm/api/sqlite3-api-prologue.js 80ec5c035b0fd06ae6fbb4fb9de4cada005d044e4bd9bb60cfa7c0f313e927ba F ext/wasm/api/sqlite3-api-prologue.js fd526fa017fa2578673ca18158354515c719e719a5d93f2f6d0e43f39170430e
F ext/wasm/api/sqlite3-api-worker1.js e94ba98e44afccfa482874cd9acb325883ade50ed1f9f9526beb9de1711f182f F ext/wasm/api/sqlite3-api-worker1.js e94ba98e44afccfa482874cd9acb325883ade50ed1f9f9526beb9de1711f182f
F ext/wasm/api/sqlite3-license-version-header.js a661182fc93fc2cf212dfd0b987f8e138a3ac98f850b1112e29b5fbdaecc87c3 F ext/wasm/api/sqlite3-license-version-header.js a661182fc93fc2cf212dfd0b987f8e138a3ac98f850b1112e29b5fbdaecc87c3
F ext/wasm/api/sqlite3-opfs-async-proxy.js ab7d2888ad9b3dd24bb782bd882fcada2a20cb88eb78c8f36e7bfe708857dbd1 F ext/wasm/api/sqlite3-opfs-async-proxy.js ab7d2888ad9b3dd24bb782bd882fcada2a20cb88eb78c8f36e7bfe708857dbd1
@ -549,7 +549,7 @@ F ext/wasm/test-opfs-vfs.html 1f2d672f3f3fce810dfd48a8d56914aba22e45c6834e262555
F ext/wasm/test-opfs-vfs.js 44363db07b2a20e73b0eb1808de4400ca71b703af718d0fa6d962f15e73bf2ac F ext/wasm/test-opfs-vfs.js 44363db07b2a20e73b0eb1808de4400ca71b703af718d0fa6d962f15e73bf2ac
F ext/wasm/tester1-worker.html 51bf39e2b87f974ae3d5bc3086e2fb36d258f3698c54f6e21ba4b3b99636fa27 F ext/wasm/tester1-worker.html 51bf39e2b87f974ae3d5bc3086e2fb36d258f3698c54f6e21ba4b3b99636fa27
F ext/wasm/tester1.html 624ec41cd9f78a1f2b6d7df70aaa7a6394396b1f2455ecbd6de5775c1275b121 F ext/wasm/tester1.html 624ec41cd9f78a1f2b6d7df70aaa7a6394396b1f2455ecbd6de5775c1275b121
F ext/wasm/tester1.js 3a5558201359ff8a1c3051ab24fcc8bed5a4e99ae5e086e5184cbfc915d08724 F ext/wasm/tester1.js bff806de454de115922d78c056f11d523ec7ed9ed3839d4e21433a9f72558b88
F ext/wasm/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd72273503ae7d5 F ext/wasm/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd72273503ae7d5
F ext/wasm/wasmfs.make edfd60691d10fd19ada4c061280fd7fbe4cf5f6bf6b913268e8ebedfccea6ab5 F ext/wasm/wasmfs.make edfd60691d10fd19ada4c061280fd7fbe4cf5f6bf6b913268e8ebedfccea6ab5
F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x
@ -2054,8 +2054,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
P 2c448368913a844bdb5e69f8fa3bad91a2b6612ba3b7f3f650dd07b81db25a77 P 10d6189d23133006b39ea230045a918483721dd48f5558f77e57e23693097d16
R 501b73220d1b13bbd9bfe624235248b2 R dbbc6e5147410c1ff1f5e52d341a107c
U drh U stephan
Z beb5dbfff782217ad4460048cb127dcb Z 38b0ee956ab9968f2c2619fa1c2e4c41
# Remove this line to create a well-formed Fossil manifest. # Remove this line to create a well-formed Fossil manifest.

View File

@ -1 +1 @@
10d6189d23133006b39ea230045a918483721dd48f5558f77e57e23693097d16 cea8bf9a144d842c4755c3130273524926e8c4831d7f21c4e34d4e8c74109c8c