Rename wasm.xWrap.resultAdapter() X:free entries to X:dealloc for consistency with wasm.dealloc(). Add an undocumented feature to replace wasm.alloc/dealloc/realloc() with the C-standard allocators (after an allocator misuse led down a several-hour rabbit hole trying to discover a mis-free() violation). Related test updates.
FossilOrigin-Name: d9807656f8a7c2a893d3f68ee5592f44826b8e999ae66f7d9000674b5c1b0207
This commit is contained in:
parent
54ac04c831
commit
09c27a59db
@ -93,3 +93,4 @@ _sqlite3_vfs_register
|
||||
_sqlite3_vfs_unregister
|
||||
_malloc
|
||||
_free
|
||||
_realloc
|
||||
|
@ -112,12 +112,23 @@ self.sqlite3ApiBootstrap = function sqlite3ApiBootstrap(
|
||||
}
|
||||
return !!self.BigInt64Array;
|
||||
})(),
|
||||
allocExportName: 'sqlite3_malloc',
|
||||
deallocExportName: 'sqlite3_free',
|
||||
reallocExportName: 'sqlite3_realloc',
|
||||
wasmfsOpfsDir: '/opfs'
|
||||
wasmfsOpfsDir: '/opfs',
|
||||
/**
|
||||
useStdAlloc is just for testing an allocator discrepancy. The
|
||||
docs guarantee that this is false in the canonical builds. For
|
||||
99% of purposes it doesn't matter which allocators we use, but
|
||||
it becomes significant with, e.g., sqlite3_deserialize()
|
||||
and certain wasm.xWrap.resultAdapter()s.
|
||||
*/
|
||||
useStdAlloc: false
|
||||
}, apiConfig || {});
|
||||
|
||||
Object.assign(config, {
|
||||
allocExportName: config.useStdAlloc ? 'malloc' : 'sqlite3_malloc',
|
||||
deallocExportName: config.useStdAlloc ? 'free' : 'sqlite3_free',
|
||||
reallocExportName: config.useStdAlloc ? 'realloc' : 'sqlite3_realloc'
|
||||
}, config);
|
||||
|
||||
[
|
||||
// If any of these config options are functions, replace them with
|
||||
// the result of calling that function...
|
||||
@ -768,15 +779,12 @@ self.sqlite3ApiBootstrap = function sqlite3ApiBootstrap(
|
||||
}
|
||||
|
||||
wasm.alloc = function f(n){
|
||||
const m = f.impl(n);
|
||||
if(!m) throw new WasmAllocError("Failed to allocate",n," bytes.");
|
||||
return m;
|
||||
return f.impl(n) || WasmAllocError.toss("Failed to allocate",n," bytes.");
|
||||
};
|
||||
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;
|
||||
return n ? (m2 || WasmAllocError.toss("Failed to reallocate",n," bytes.")) : 0;
|
||||
};
|
||||
wasm.realloc.impl = wasm.exports[keyRealloc];
|
||||
wasm.dealloc = wasm.exports[keyDealloc];
|
||||
|
@ -1204,7 +1204,7 @@ void sqlite3_wasm_test_stack_overflow(int recurse){
|
||||
/* For testing the 'string-free' whwasmutil.xWrap() conversion. */
|
||||
SQLITE_WASM_KEEP
|
||||
char * sqlite3_wasm_test_str_hello(int fail){
|
||||
char * s = fail ? 0 : (char *)malloc(6);
|
||||
char * s = fail ? 0 : (char *)sqlite3_malloc(6);
|
||||
if(s){
|
||||
memcpy(s, "hello", 5);
|
||||
s[5] = 0;
|
||||
|
@ -1267,7 +1267,7 @@ self.WhWasmUtilInstaller = function(target){
|
||||
- If v is a string, scopeAlloc() a new C-string from it and return
|
||||
that temp string's pointer.
|
||||
|
||||
- Else return the value from the arg adaptor defined for ptrIR.
|
||||
- Else return the value from the arg adapter defined for ptrIR.
|
||||
|
||||
TODO? Permit an Int8Array/Uint8Array and convert it to a string?
|
||||
Would that be too much magic concentrated in one place, ready to
|
||||
@ -1279,12 +1279,12 @@ self.WhWasmUtilInstaller = function(target){
|
||||
return v ? xcv.arg[ptrIR](v) : null;
|
||||
};
|
||||
xcv.result.string = xcv.result.utf8 = (i)=>target.cstringToJs(i);
|
||||
xcv.result['string:free'] = xcv.result['utf8:free'] = (i)=>{
|
||||
xcv.result['string:dealloc'] = xcv.result['utf8:dealloc'] = (i)=>{
|
||||
try { return i ? target.cstringToJs(i) : null }
|
||||
finally{ target.dealloc(i) }
|
||||
};
|
||||
xcv.result.json = (i)=>JSON.parse(target.cstringToJs(i));
|
||||
xcv.result['json:free'] = (i)=>{
|
||||
xcv.result['json:dealloc'] = (i)=>{
|
||||
try{ return i ? JSON.parse(target.cstringToJs(i)) : null }
|
||||
finally{ target.dealloc(i) }
|
||||
}
|
||||
@ -1383,7 +1383,7 @@ self.WhWasmUtilInstaller = function(target){
|
||||
true.
|
||||
|
||||
- `f32` (`float`), `f64` (`double`) (args and results): pass
|
||||
their argument to Number(). i.e. the adaptor does not currently
|
||||
their argument to Number(). i.e. the adapter does not currently
|
||||
distinguish between the two types of floating-point numbers.
|
||||
|
||||
- `number` (results): converts the result to a JS Number using
|
||||
@ -1411,7 +1411,7 @@ self.WhWasmUtilInstaller = function(target){
|
||||
const C-string, encoded as UTF-8, copies it to a JS string,
|
||||
and returns that JS string.
|
||||
|
||||
- `string:free` or `utf8:free) (results): treats the result value
|
||||
- `string:dealloc` or `utf8:dealloc) (results): treats the result value
|
||||
as a non-const UTF-8 C-string, ownership of which has just been
|
||||
transfered to the caller. It copies the C-string to a JS
|
||||
string, frees the C-string, and returns the JS string. If such
|
||||
@ -1422,7 +1422,7 @@ self.WhWasmUtilInstaller = function(target){
|
||||
required. For example:
|
||||
|
||||
```js
|
||||
target.xWrap.resultAdaptor('string:my_free',(i)=>{
|
||||
target.xWrap.resultAdapter('string:my_free',(i)=>{
|
||||
try { return i ? target.cstringToJs(i) : null }
|
||||
finally{ target.exports.my_free(i) }
|
||||
};
|
||||
@ -1432,9 +1432,9 @@ self.WhWasmUtilInstaller = function(target){
|
||||
returns the result of passing the converted-to-JS string to
|
||||
JSON.parse(). Returns `null` if the C-string is a NULL pointer.
|
||||
|
||||
- `json:free` (results): works exactly like `string:free` but
|
||||
- `json:dealloc` (results): works exactly like `string:dealloc` but
|
||||
returns the same thing as the `json` adapter. Note the
|
||||
warning in `string:free` regarding maching allocators and
|
||||
warning in `string:dealloc` regarding maching allocators and
|
||||
deallocators.
|
||||
|
||||
The type names for results and arguments are validated when
|
||||
@ -1545,7 +1545,7 @@ self.WhWasmUtilInstaller = function(target){
|
||||
*/
|
||||
target.xWrap.resultAdapter = function f(typeName, adapter){
|
||||
return __xAdapter(f, arguments.length, typeName, adapter,
|
||||
'resultAdaptor()', xcv.result);
|
||||
'resultAdapter()', xcv.result);
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -344,9 +344,20 @@ self.sqlite3InitModule = sqlite3InitModule;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
T.g('Basic sanity checks')
|
||||
.t("JS wasm-side allocator === sqlite3_malloc()", function(sqlite3){
|
||||
T.assert(wasm.alloc.impl === wasm.exports.sqlite3_malloc)
|
||||
.assert(wasm.dealloc === wasm.exports.sqlite3_free);
|
||||
.t({
|
||||
name: "JS wasm-side allocator",
|
||||
test: function(sqlite3){
|
||||
if(sqlite3.config.useStdAlloc){
|
||||
warn("Using system allocator. This violates the docs.");
|
||||
T.assert(wasm.alloc.impl === wasm.exports.malloc)
|
||||
.assert(wasm.dealloc === wasm.exports.free)
|
||||
.assert(wasm.realloc.impl === wasm.exports.realloc);
|
||||
}else{
|
||||
T.assert(wasm.alloc.impl === wasm.exports.sqlite3_malloc)
|
||||
.assert(wasm.dealloc === wasm.exports.sqlite3_free)
|
||||
.assert(wasm.realloc.impl === wasm.exports.sqlite3_realloc);
|
||||
}
|
||||
}
|
||||
})
|
||||
.t('Namespace object checks', function(sqlite3){
|
||||
const wasmCtypes = wasm.ctype;
|
||||
@ -434,12 +445,14 @@ self.sqlite3InitModule = sqlite3InitModule;
|
||||
|
||||
// Check allocation limits and allocator's responses...
|
||||
T.assert('number' === typeof sqlite3.capi.SQLITE_MAX_ALLOCATION_SIZE);
|
||||
const tooMuch = sqlite3.capi.SQLITE_MAX_ALLOCATION_SIZE + 1,
|
||||
isAllocErr = (e)=>e instanceof sqlite3.WasmAllocError;
|
||||
T.mustThrowMatching(()=>w.alloc(tooMuch), isAllocErr)
|
||||
.assert(0 === w.alloc.impl(tooMuch))
|
||||
.mustThrowMatching(()=>w.realloc(0, tooMuch), isAllocErr)
|
||||
.assert(0 === w.realloc.impl(0, tooMuch));
|
||||
if(!sqlite3.config.useStdAlloc){
|
||||
const tooMuch = sqlite3.capi.SQLITE_MAX_ALLOCATION_SIZE + 1,
|
||||
isAllocErr = (e)=>e instanceof sqlite3.WasmAllocError;
|
||||
T.mustThrowMatching(()=>w.alloc(tooMuch), isAllocErr)
|
||||
.assert(0 === w.alloc.impl(tooMuch))
|
||||
.mustThrowMatching(()=>w.realloc(0, tooMuch), isAllocErr)
|
||||
.assert(0 === w.realloc.impl(0, tooMuch));
|
||||
}
|
||||
|
||||
// Check allocFromTypedArray()...
|
||||
const byteList = [11,22,33]
|
||||
@ -553,11 +566,12 @@ self.sqlite3InitModule = sqlite3InitModule;
|
||||
|
||||
//log("allocCString()...");
|
||||
{
|
||||
const cstr = w.allocCString("hällo, world");
|
||||
const n = w.cstrlen(cstr);
|
||||
T.assert(13 === n)
|
||||
const jstr = "hällo, world!";
|
||||
const [cstr, n] = w.allocCString(jstr, true);
|
||||
T.assert(14 === n)
|
||||
.assert(0===w.getMemValue(cstr+n))
|
||||
.assert(chr('d')===w.getMemValue(cstr+n-1));
|
||||
.assert(chr('!')===w.getMemValue(cstr+n-1));
|
||||
w.dealloc(cstr);
|
||||
}
|
||||
|
||||
//log("scopedAlloc() and friends...");
|
||||
@ -639,11 +653,13 @@ self.sqlite3InitModule = sqlite3InitModule;
|
||||
rc = w.xCallWrapped('sqlite3_wasm_enum_json','utf8');
|
||||
T.assert('string'===typeof rc).assert(rc.length>300);
|
||||
if(haveWasmCTests()){
|
||||
fw = w.xWrap('sqlite3_wasm_test_str_hello', 'utf8:free',['i32']);
|
||||
rc = fw(0);
|
||||
T.assert('hello'===rc);
|
||||
rc = fw(1);
|
||||
T.assert(null===rc);
|
||||
if(!sqlite3.config.useStdAlloc){
|
||||
fw = w.xWrap('sqlite3_wasm_test_str_hello', 'utf8:dealloc',['i32']);
|
||||
rc = fw(0);
|
||||
T.assert('hello'===rc);
|
||||
rc = fw(1);
|
||||
T.assert(null===rc);
|
||||
}
|
||||
|
||||
if(w.bigIntEnabled){
|
||||
w.xWrap.resultAdapter('thrice', (v)=>3n*BigInt(v));
|
||||
|
20
manifest
20
manifest
@ -1,5 +1,5 @@
|
||||
C Doc\stypo\sfix\sfor\sSQLITE_MAX_ALLOCATION_SIZE\sin\smalloc.c.\sNo\scode\schanges.
|
||||
D 2022-12-03T13:05:33.513
|
||||
C Rename\swasm.xWrap.resultAdapter()\sX:free\sentries\sto\sX:dealloc\sfor\sconsistency\swith\swasm.dealloc().\sAdd\san\sundocumented\sfeature\sto\sreplace\swasm.alloc/dealloc/realloc()\swith\sthe\sC-standard\sallocators\s(after\san\sallocator\smisuse\sled\sdown\sa\sseveral-hour\srabbit\shole\strying\sto\sdiscover\sa\smis-free()\sviolation).\sRelated\stest\supdates.
|
||||
D 2022-12-03T13:10:58.483
|
||||
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
|
||||
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
|
||||
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
|
||||
@ -494,7 +494,7 @@ F ext/wasm/EXPORTED_FUNCTIONS.fiddle.in 27450c8b8c70875a260aca55435ec927068b34ce
|
||||
F ext/wasm/GNUmakefile bfa47f169468ca9db031105b0e336db29a88e93c3abd217d0bbb2b8731fa5413
|
||||
F ext/wasm/README-dist.txt 2d670b426fc7c613b90a7d2f2b05b433088fe65181abead970980f0a4a75ea20
|
||||
F ext/wasm/README.md ef39861aa21632fdbca0bdd469f78f0096f6449a720f3f39642594af503030e9
|
||||
F ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-api b4d68c97d14944b48d55e06aa44f544a6f56a7fa2bcb6f9e030936a5b2a9479a
|
||||
F ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-api eeb1300945c3871e46904e026a04a41d6fc458fcaa74ccee4e719ebb8ccb3087
|
||||
F ext/wasm/api/EXPORTED_RUNTIME_METHODS.sqlite3-api 1ec3c73e7d66e95529c3c64ac3de2470b0e9e7fbf7a5b41261c367cf4f1b7287
|
||||
F ext/wasm/api/README.md 20a256f4aaae80035d2bb1c9e3e0a125570313a8d137d427471d7be10edde87a
|
||||
F ext/wasm/api/extern-post-js.c-pp.js 8923f76c3d2213159e12d641dc750523ead5c848185dc4996fae5cc12397f88d
|
||||
@ -505,14 +505,14 @@ F ext/wasm/api/pre-js.c-pp.js b88499dc303c21fc3f55f2c364a0f814f587b60a9578430388
|
||||
F ext/wasm/api/sqlite3-api-cleanup.js 680d5ccfff54459db136a49b2199d9f879c8405d9c99af1dda0cc5e7c29056f4
|
||||
F ext/wasm/api/sqlite3-api-glue.js 6fe39964605fda3b699f69365eed565b5172d29cab2c49bc057a43f9a93f9f36
|
||||
F ext/wasm/api/sqlite3-api-oo1.js 91a7d7b9203fb0f031e6ba380a644a7f871e1798b388de399c01ed4087bac9e0
|
||||
F ext/wasm/api/sqlite3-api-prologue.js 3d9550021269fd97636595ea2d2a1ec3ce00866f0a5d3b5fab94d4583afdafe0
|
||||
F ext/wasm/api/sqlite3-api-prologue.js b06eb09246deb56612b4905eb2ec4bcc8b10f0472fa661cd54c5d6cd1888d8b9
|
||||
F ext/wasm/api/sqlite3-api-worker1.js e94ba98e44afccfa482874cd9acb325883ade50ed1f9f9526beb9de1711f182f
|
||||
F ext/wasm/api/sqlite3-license-version-header.js a661182fc93fc2cf212dfd0b987f8e138a3ac98f850b1112e29b5fbdaecc87c3
|
||||
F ext/wasm/api/sqlite3-opfs-async-proxy.js f79dd8d98ef3e0b55c10bb2bee7a3840fa967318e1f577c156aafc34664271d1
|
||||
F ext/wasm/api/sqlite3-vfs-helper.js 4ad4faf02e1524bf0296be8452c00b5708dce6faf649468d0377e26a0b299263
|
||||
F ext/wasm/api/sqlite3-vfs-opfs.c-pp.js 29d6487a26b2fb6a471cde52c37ffee7c27ed6a91914b308c247e0706f454ffb
|
||||
F ext/wasm/api/sqlite3-wasi.h 25356084cfe0d40458a902afb465df8c21fc4152c1d0a59b563a3fba59a068f9
|
||||
F ext/wasm/api/sqlite3-wasm.c 69c2c1bf555dd25596137bf282d721657d5c49243061e0cb420375203107adcd
|
||||
F ext/wasm/api/sqlite3-wasm.c b0babf8435f31d21f28454fb81433aa538c68b23d0a4a251f0666fdec4e71f59
|
||||
F ext/wasm/api/sqlite3-worker1-promiser.js 0c7a9826dbf82a5ed4e4f7bf7816e825a52aff253afbf3350431f5773faf0e4b
|
||||
F ext/wasm/api/sqlite3-worker1.js 1e54ea3d540161bcfb2100368a2fc0cad871a207b8336afee1c445715851ec54
|
||||
F ext/wasm/batch-runner.html 4deeed44fe41496dc6898d9fb17938ea3291f40f4bfb977e29d0cef96fbbe4c8
|
||||
@ -521,7 +521,7 @@ F ext/wasm/c-pp.c 92285f7bce67ed7b7020b40fde8ed0982c442b63dc33df9dfd4b658d4a6c07
|
||||
F ext/wasm/common/SqliteTestUtil.js d8bf97ecb0705a2299765c8fc9e11b1a5ac7f10988bbf375a6558b7ca287067b
|
||||
F ext/wasm/common/emscripten.css 3d253a6fdb8983a2ac983855bfbdd4b6fa1ff267c28d69513dd6ef1f289ada3f
|
||||
F ext/wasm/common/testing.css 35889709547d89a6109ff83b25c11bbc91d8dd43aab8722e428655ca98880a06
|
||||
F ext/wasm/common/whwasmutil.js dbe625a22bf0962cde1f958f2be604d27d2f97ee1b4e6ee0f19c6480aa36aeed
|
||||
F ext/wasm/common/whwasmutil.js c1bc5715cd96728929cc31d788b16152ccbd6b2e111d2e88fbc9725247e67b4f
|
||||
F ext/wasm/demo-123-worker.html a0b58d9caef098a626a1a1db567076fca4245e8d60ba94557ede8684350a81ed
|
||||
F ext/wasm/demo-123.html 8c70a412ce386bd3796534257935eb1e3ea5c581e5d5aea0490b8232e570a508
|
||||
F ext/wasm/demo-123.js ebae30756585bca655b4ab2553ec9236a87c23ad24fc8652115dcedb06d28df6
|
||||
@ -555,7 +555,7 @@ F ext/wasm/test-opfs-vfs.html 1f2d672f3f3fce810dfd48a8d56914aba22e45c6834e262555
|
||||
F ext/wasm/test-opfs-vfs.js 44363db07b2a20e73b0eb1808de4400ca71b703af718d0fa6d962f15e73bf2ac
|
||||
F ext/wasm/tester1-worker.html 29b1d87f7d51f70d61645719fee657f3787fe939bb695f27034c75404e8f1e6f
|
||||
F ext/wasm/tester1.c-pp.html 74aa9b31c75f12490653f814b53c3dd39f40cd3f70d6a53a716f4e8587107399
|
||||
F ext/wasm/tester1.c-pp.js d25cea43933bf86590aab63038a6a0b6e7002ffba7e85d8df2720b7a69f85690
|
||||
F ext/wasm/tester1.c-pp.js 956acfd5675e61fa7c52a19e5b16603da61e753e309abe91284e3b1d39598840
|
||||
F ext/wasm/tests/opfs/concurrency/index.html 86d8ac435074d1e7007b91105f4897f368c165e8cecb6a9aa3d81f5cf5dcbe70
|
||||
F ext/wasm/tests/opfs/concurrency/test.js a98016113eaf71e81ddbf71655aa29b0fed9a8b79a3cdd3620d1658eb1cc9a5d
|
||||
F ext/wasm/tests/opfs/concurrency/worker.js 0a8c1a3e6ebb38aabbee24f122693f1fb29d599948915c76906681bb7da1d3d2
|
||||
@ -2065,8 +2065,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
|
||||
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
|
||||
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
|
||||
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
|
||||
P f1da32410ca7b808b3bef5f5a59766e7281e9e6ea343c8b979599bf1fc1060f5
|
||||
R ecd21c0eba1077a6366f5dd7664db4b8
|
||||
P ed1ed21221b048ac5a5275cdfc4d9b2a406acdc7d4b648c3b61bcc822d88d955
|
||||
R 04802c5e85209b72659bc288df2e94a1
|
||||
U stephan
|
||||
Z d0c7ece3afa4de468292a6daac64615d
|
||||
Z 23bb6930a31350fa896c81241f2934b6
|
||||
# Remove this line to create a well-formed Fossil manifest.
|
||||
|
@ -1 +1 @@
|
||||
ed1ed21221b048ac5a5275cdfc4d9b2a406acdc7d4b648c3b61bcc822d88d955
|
||||
d9807656f8a7c2a893d3f68ee5592f44826b8e999ae66f7d9000674b5c1b0207
|
Loading…
x
Reference in New Issue
Block a user