'use strict';
if('undefined' !== typeof Module){ // presumably an Emscripten build
/**
- Install a suitable default configuration for sqlite3ApiBootstrap().
+ The WASM-environment-specific configuration pieces
+ for sqlite3ApiBootstrap().
*/
const SABC = Object.assign(
- Object.create(null), {
+ Object.create(null),
+ globalThis.sqlite3ApiConfig || {},
+ {
exports: ('undefined'===typeof wasmExports)
? Module['asm']/* emscripten <=3.1.43 */
: wasmExports /* emscripten >=3.1.44 */,
- memory: Module.wasmMemory /* gets set if built with -sIMPORTED_MEMORY */
- },
- globalThis.sqlite3ApiConfig || {}
+ memory: Module.wasmMemory /* gets set if built with -sIMPORTED_MEMORY */,
+//#if sMEMORY64=1
+ wasmPtrSizeof: 8,
+ wasmPtrIR: 'i64',
+//#elif sMEMORY64=2
+ wasmPtrSizeof: 8/*???*/,
+ wasmPtrIR: 'i64'/*???*/,
+//#else
+ wasmPtrSizeof: 4,
+ wasmPtrIR: 'i32',
+//#endif
+ }
);
/**
able to provide the necessary configuration state.
*/
//console.warn("globalThis.sqlite3ApiConfig = ",globalThis.sqlite3ApiConfig);
- globalThis.sqlite3ApiConfig = SABC;
- let sqlite3;
try{
- sqlite3 = globalThis.sqlite3ApiBootstrap();
+ Module.sqlite3 = globalThis.sqlite3ApiBootstrap(SABC)
+ /* Our customized sqlite3InitModule() in extern-post-js.js needs
+ this to be able to pass the sqlite3 object off to the
+ client. */;
}catch(e){
console.error("sqlite3ApiBootstrap() error:",e);
throw e;
delete globalThis.sqlite3ApiConfig;
}
- Module.sqlite3 = sqlite3 /* Needed for customized sqlite3InitModule() to be able to
- pass the sqlite3 object off to the client. */;
}else{
console.warn("This is not running in an Emscripten module context, so",
"globalThis.sqlite3ApiBootstrap() is _not_ being called due to lack",
'use strict';
const toss = (...args)=>{throw new Error(args.join(' '))};
const capi = sqlite3.capi, wasm = sqlite3.wasm, util = sqlite3.util;
-//#if sMEMORY64=1
- wasm.pointerIR = 'i64';
-//#elif sMEMORY64=2
- wasm.pointerIR = 'i64'/*???*/;
-//#else
- wasm.pointerIR = 'i32';
-//#endif
globalThis.WhWasmUtilInstaller(wasm);
delete globalThis.WhWasmUtilInstaller;
wasm.uninstallFunction() any WASM function bindings it has
installed for pDb.
*/
- const closeArgs = [pDb];
for(const name of [
'sqlite3_busy_handler',
'sqlite3_commit_hook',
/* assume it was built without this API */
continue;
}
+ const closeArgs = [pDb];
closeArgs.length = x.length/*==argument count*/
|| 1 /* Recall that: (A) undefined entries translate to 0 when
passed to WASM and (B) Safari wraps wasm.exports.* in
nullary functions so x.length is 0 there. */;
+ //console.debug(closeArgs, name,"()", capi[name]);
+ //wasm.xWrap.debug = true;
try{ capi[name](...closeArgs) }
catch(e){
/* This "cannot happen" unless something is well and truly sideways. */
sqlite3.config.warn("close-time call of",name+"(",closeArgs,") threw:",e);
}
+ //wasm.xWrap.debug = false;
}
const m = __dbCleanupMap(pDb, 0);
if(!m) return;
Helper for string:flexible conversions which requires a
byte-length counterpart argument. Passed a value and its
ostensible length, this function returns [V,N], where V is
- either v or a transformed copy of v and N is either n (if v is
- a WASM pointer), -1 (if v is a string or Array), or the byte
- length of v (if it's a byte array or ArrayBuffer).
+ either v or a transformed copy of v and N is either Number(n)
+ (if v is a WASM pointer), -1 (if v is a string or Array), or
+ the byte length of v (if it's a byte array or ArrayBuffer).
*/
const __flexiString = (v,n)=>{
if('string'===typeof v){
}else if(Array.isArray(v)){
v = v.join("");
n = -1;
- }
+ }/*else if( 'bigint'===typeof n ){
+ // tag:64-bit A workaround for when a stray BigInt, possibly
+ // calculated via a pointer range, gets passed in here. This
+ // has been seen to happen in sqlite3_prepare_v3() via
+ // oo1.DB.exec().
+ n = Number(n);
+ }*/
return [v, n];
};
}
const [xSql, xSqlLen] = __flexiString(sql, sqlLen);
switch(typeof xSql){
- case 'string': return __prepare.basic(pDb, xSql, xSqlLen, prepFlags, ppStmt, null);
- case 'number': return __prepare.full(pDb, xSql, xSqlLen, prepFlags, ppStmt, pzTail);
- default:
- return util.sqlite3__wasm_db_error(
- pDb, capi.SQLITE_MISUSE,
- "Invalid SQL argument type for sqlite3_prepare_v2/v3()."
- );
+ case 'string': return __prepare.basic(pDb, xSql, xSqlLen, prepFlags, ppStmt, null);
+ case (typeof wasm.NullPtr):
+ return __prepare.full(pDb, xSql, xSqlLen, prepFlags, ppStmt, pzTail);
+ default:
+ return util.sqlite3__wasm_db_error(
+ pDb, capi.SQLITE_MISUSE,
+ "Invalid SQL argument type for sqlite3_prepare_v2/v3(). typeof="+(typeof xSql)
+ );
}
};
let sqlByteLen = isTA ? arg.sql.byteLength : wasm.jstrlen(arg.sql);
const ppStmt = wasm.scopedAlloc(
/* output (sqlite3_stmt**) arg and pzTail */
- (2 * wasm.ptrSizeof) + (sqlByteLen + 1/* SQL + NUL */)
+ (2 * wasm.pointerSizeof) + (sqlByteLen + 1/* SQL + NUL */)
);
- const pzTail = ppStmt + wasm.ptrSizeof /* final arg to sqlite3_prepare_v2() */;
- let pSql = pzTail + wasm.ptrSizeof;
- const pSqlEnd = pSql + sqlByteLen;
+ const pzTail = wasm.ptrAdd(ppStmt, wasm.pointerSizeof) /* final arg to sqlite3_prepare_v2() */;
+ let pSql = wasm.ptrAdd(pzTail, wasm.pointerSizeof);
+ const pSqlEnd = wasm.ptrAdd(pSql, sqlByteLen);
if(isTA) wasm.heap8().set(arg.sql, pSql);
else wasm.jstrcpy(arg.sql, wasm.heap8(), pSql, sqlByteLen, false);
- wasm.poke(pSql + sqlByteLen, 0/*NUL terminator*/);
+ wasm.poke(wasm.ptrAdd(pSql, sqlByteLen), 0/*NUL terminator*/);
while(pSql && wasm.peek(pSql, 'i8')
/* Maintenance reminder:^^^ _must_ be 'i8' or else we
will very likely cause an endless loop. What that's
));
const pStmt = wasm.peekPtr(ppStmt);
pSql = wasm.peekPtr(pzTail);
- sqlByteLen = pSqlEnd - pSql;
+ sqlByteLen = Number(wasm.ptrAdd(pSqlEnd,-pSql));
if(!pStmt) continue;
if(saveSql) saveSql.push(capi.sqlite3_sql(pStmt).trim());
stmt = new Stmt(this, pStmt, BindTypes);
const n = capi.sqlite3_column_bytes(this.pointer, ndx),
ptr = capi.sqlite3_column_blob(this.pointer, ndx),
rc = new Uint8Array(n);
- //heap = n ? wasm.heap8() : false;
- if(n) rc.set(wasm.heap8u().slice(ptr, ptr+n), 0);
- //for(let i = 0; i < n; ++i) rc[i] = heap[ptr + i];
- if(n && this.db._blobXfer instanceof Array){
- /* This is an optimization soley for the
- Worker-based API. These values will be
- transfered to the main thread directly
- instead of being copied. */
- this.db._blobXfer.push(rc.buffer);
+ if(n){
+ rc.set(wasm.heap8u().slice(Number(ptr), Number(ptr)+n), 0);
+ if(this.db._blobXfer instanceof Array){
+ /* This is an optimization soley for the Worker1 API. It
+ will transfer these to the main thread directly
+ instead of copying them. */
+ this.db._blobXfer.push(rc.buffer);
+ }
}
return rc;
}
it becomes significant with, e.g., sqlite3_deserialize() and
certain wasm.xWrap.resultAdapter()s.
*/
- useStdAlloc: false
+ useStdAlloc: false,
+ /*
+ sqlite3-api-cleanup.js sets wasmPtrSizeof and wasmPtrIR
+ */
+ wasmPtrSizeof: 4,
+ wasmPtrIR: 'i32'
}, 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...
+ // the result of calling that function. They must not be async.
'exports', 'memory', 'wasmfsOpfsDir'
].forEach((k)=>{
if('function' === typeof config[k]){
}
}/*util*/;
+ /**
+ wasm.X properties which are used for configuring the wasm
+ environment via whwashutil.js.
+ */
Object.assign(wasm, {
/**
Emscripten APIs have a deep-seated assumption that all pointers
the case and will use this constant in places where we might
otherwise use a hard-coded 4.
*/
- ptrSizeof: config.wasmPtrSizeof || 4,
+ pointerSizeof: config.wasmPtrSizeof,
/**
The WASM IR (Intermediate Representation) value for
pointer-type values. It MUST refer to a value type of the
- size described by this.ptrSizeof.
+ size described by this.pointerSizeof.
*/
- ptrIR: config.wasmPtrIR || "i32",
+ pointerIR: config.wasmPtrIR,
/**
True if BigInt support was enabled via (e.g.) the
Emscripten -sWASM_BIGINT flag, else false. When
WasmAllocError.toss("Invalid size value for allocChunks(",arguments[1],")");
}
const mem = wasm.pstack.alloc(n * sz);
- const rc = [];
- let i = 0, offset = 0;
+ const rc = [mem];
+ let i = 1, offset = sz;
for(; i < n; ++i, offset += sz) rc.push(wasm.ptrAdd(mem, offset));
return rc;
},
/**
A convenience wrapper for allocChunks() which sizes each chunk
- as either 8 bytes (safePtrSize is truthy) or wasm.ptrSizeof (if
+ as either 8 bytes (safePtrSize is truthy) or wasm.pointerSizeof (if
safePtrSize is falsy).
How it returns its result differs depending on its first
*/
allocPtr: (n=1,safePtrSize=true)=>{
return 1===n
- ? wasm.pstack.alloc(safePtrSize ? 8 : wasm.ptrSizeof)
- : wasm.pstack.allocChunks(n, safePtrSize ? 8 : wasm.ptrSizeof);
+ ? wasm.pstack.alloc(safePtrSize ? 8 : wasm.pointerSizeof)
+ : wasm.pstack.allocChunks(n, safePtrSize ? 8 : wasm.pointerSizeof);
},
/**
const scope = wasm.scopedAllocPush();
let pOut;
try{
- const pSize = wasm.scopedAlloc(8/*i64*/ + wasm.ptrSizeof);
+ const pSize = wasm.scopedAlloc(8/*i64*/ + wasm.pointerSizeof);
const ppOut = pSize + 8;
/**
Maintenance reminder, since this cost a full hour of grief
do not.
*/
tgt.push(capi.sqlite3_value_to_js(
- wasm.peekPtr(pArgv + (wasm.ptrSizeof * i)),
+ wasm.peekPtr(pArgv + (wasm.pointerSizeof * i)),
throwIfCannotConvert
));
}
https://fossil.wanderinghorse.net/r/jaccwabyt
+ More specifically:
+
+ https://fossil.wanderinghorse.net/r/jaccwabyt/file/common/whwasmutil.js
+
and SQLite:
https://sqlite.org
utility APIs provided by this code are still usable as replacements
for their Emscripten counterparts.
- Forewarning: this API explicitly targets only browser
- environments. If a given non-browser environment has the
- capabilities needed for a given feature (e.g. TextEncoder), great,
- but it does not go out of its way to account for them and does not
- provide compatibility crutches for them.
+ Forewarning: this API explicitly targets only browser environments.
+ If a given non-browser environment has the capabilities needed for
+ a given feature (e.g. TextEncoder), great, but it does not go out
+ of its way to account for them and does not provide compatibility
+ crutches for them.
Intended usage:
- `pointerIR`: an IR-format string for the WASM environment's
pointer size. If set it must be either 'i32' or 'i64'. If not
- set, it defaults to whatever this code thinks the pointer size
+ set, it gets set to whatever this code thinks the pointer size
is. Modifying it after this call has no effect.
- target.pointerSizeof gets set to either 4 or 8, depending on
- this option.
-
- This code is developed and maintained in conjunction with the
- Jaccwabyt project:
+ - `pointerSizeof`: if set, it must be one of 4 or 8 and must
+ correspond to the value of `pointerIR`. If not set, it gets set
+ to whatever this code thinks the pointer size is (4 unless
+ `pointerIR` is 'i64'). If `pointerSizeof` is set but `pointerIR`
+ is not, `pointerIR` gets set appropriately, and vice versa.
- https://fossil.wanderinghorse.net/r/jaccwabyt
+ When building with Emscripten's -sMEMORY64=1, `pointerIR` must be
+ set to 'i64' and/or `pointerSizeof` must be set to 8.
- More specifically:
+ Design notes:
- https://fossil.wanderinghorse.net/r/jaccwabyt/file/common/whwasmutil.js
+ - It should probably take a config object and return the
+ target. The current approach seemed better at the time.
*/
globalThis.WhWasmUtilInstaller = function(target){
'use strict';
all args with a space between each. */
const toss = (...args)=>{throw new Error(args.join(' '))};
- if(!target.exports){
- Object.defineProperty(target, 'exports', {
- enumerable: true, configurable: true,
- get: ()=>(target.instance && target.instance.exports)
- });
+ /**
+ Pointers in WASM are currently assumed to be 32-bit, but someday
+ that will certainly change.
+
+ 2025-09-19: work has started in getting this library to work with
+ Emscripten's -sMEMORY64=1.
+ */
+ if( target.pointerSizeof && !target.pointerIR ){
+ target.pointerIR = (4===target.pointerSizeof ? 'i32' : 'i64');
+ }
+ const ptrIR = (target.pointerIR ??= 'i32');
+ const ptrSizeof = (target.pointerSizeof ??=
+ ('i32'===ptrIR ? 4 : ('i64'===ptrIR ? 8 : 0)));
+
+ if( 'i32'!==ptrIR && 'i64'!==ptrIR ){
+ toss("Invalid pointerIR:",ptrIR);
}
+ if( 8!==ptrSizeof && 4!==ptrSizeof ){
+ toss("Invalid pointerSizeof:",ptrSizeof);
+ }
+
+ /**
+ If target.pointerIR=='i32' then this is equivalent to
+ Number(v) else it's equivalent to BigInt(v||0).
+
+ Why? Because Number(null)===0, but BigInt(null) throws.
+ */
+ const __asPtrType = (4===ptrSizeof)
+ ? Number
+ : (target.bigIntEnabled
+ ? ((v)=>BigInt(v || 0))
+ : toss("Missing BigInt support"));
+
+ target.asPtrType = __asPtrType;
+
+ /**
+ The number 0 as either type Number or BigInt, depending on
+ target.pointerIR.
+ */
+ const __NullPtr = __asPtrType(0);
+
+ target.NullPtr = __NullPtr;
+
+ /**
+ The typeof X value for target.NullPtr
+ */
+ //target.pointerTypeof = typeof __NullPtr;
/*********
alloc()/dealloc() auto-install...
}
}*******/
- /**
- Pointers in WASM are currently assumed to be 32-bit, but someday
- that will certainly change.
- */
- const ptrIR = target.pointerIR || (target.pointerIR = 'i32');
- const ptrSizeof = target.pointerSizeof =
- ('i32'===ptrIR ? 4
- : ('i64'===ptrIR
- ? 8 : toss("Unhandled pointerIR:",ptrIR)));
-
- /**
- If target.pointerIR=='i32' then this is equivalent to
- Number(v) else it's equivalent to BigInt(v||0).
-
- Why? Because Number(null)===0, but BigInt(null) throws.
- */
- const __asPtrType = ('i32'==ptrIR)
- ? Number
- : (target.bigIntEnabled
- ? ((v)=>BigInt(v || 0))
- : toss("Missing BigInt support"));
-
- target.asPtrType = __asPtrType;
-
/**
Expects any number of numeric arguments, each one of either type
Number or BigInt. It sums them up (from an implicit starting
target.ptrAdd = __ptrAdd;
- /**
- The number 0 as either type Number or BigInt, depending on
- target.pointerIR.
- */
- const __NullPtr = __asPtrType(0);
- target.NullPtr = __NullPtr;
+ if(!target.exports){
+ Object.defineProperty(target, 'exports', {
+ enumerable: true, configurable: true,
+ get: ()=>(target?.instance?.exports)
+ });
+ }
/** Stores various cached state. */
const cache = Object.create(null);
*/
target.isPtr32 = (ptr)=>('number'===typeof ptr && (ptr===(ptr|0)) && ptr>=0);
- /* UNTESTED */
target.isPtr64 = (ptr)=>{
if( 'bigint'===typeof ptr ){
return ptr >= 0;
}
- return ('number'===typeof ptr && (ptr===(ptr|0)) && ptr>=0);
+ return ('number'===typeof ptr && ptr>=0 && (ptr===(ptr|0)));
};
/**
if(!tgt || (!(tgt instanceof Int8Array) && !(tgt instanceof Uint8Array))){
toss("jstrcpy() target must be an Int8Array or Uint8Array.");
}
+ maxBytes = Number(maxBytes)/*tag:64bit*/;
+ offset = Number(offset)/*tag:64bit*/;
if(maxBytes<0) maxBytes = tgt.length - offset;
if(!(maxBytes>0) || !(offset>=0)) return 0;
let i = 0, max = jstr.length;
xArg.set('i64', (i)=>BigInt(i || 0));
}
const __xArgPtr = __asPtrType;
- xArg.set('i32', (i)=>(i | 0) )
+ xArg.set(
+ 'i32',
+ 0
+ ? (i)=>Number(i) | 0
+ /* This Number(i) is unsatisfying but it enables i32-type args which
+ are inadvertently passed a BigInt (which is easy to do) to
+ play along instead of causing an exception about lack of implicit
+ conversions from BigInt to Number. */
+ : (i)=>i|0
+ );
+ xArg
.set('i16', (i)=>((i | 0) & 0xFFFF))
.set('i8', (i)=>((i | 0) & 0xFF))
.set('f32', (i)=>Number(i).valueOf())
exactly the 2nd and 3rd arguments are.
*/
convertArg(v,argv,argIndex){
- //FuncPtrAdapter.debugOut("FuncPtrAdapter.convertArg()",this.name,this.signature,this.transient,v);
let pair = this.singleton;
if(!pair && this.isContext){
pair = this.contextMap(this.contextKey(argv,argIndex));
//FuncPtrAdapter.debugOut(this.name, this.signature, "contextKey() =",this.contextKey(argv,argIndex), pair);
}
- if(pair && pair[0]===v){
+ if( 0 ){
+ FuncPtrAdapter.debugOut("FuncPtrAdapter.convertArg()",this.name,
+ 'signature =',this.signature,
+ 'transient ?=',this.transient,
+ 'pair =',pair,
+ 'v =',v);
+ }
+ if(pair && 2===pair.length && pair[0]===v){
/* We have already handled this function. */
return pair[1];
}
}
catch(e){/*ignored*/}
}
- pair[0] = arguments[0]/*the original v*/;
+ pair[0] = arguments[0] || __NullPtr/*the original v*/;
pair[1] = fp;
}
return fp;
}else if(target.isPtr(v) || null===v || undefined===v){
- //FuncPtrAdapter.debugOut("FuncPtrAdapter.convertArg()",this.name,this.signature,this.transient,v,pair);
if(pair && pair[1] && pair[1]!==v){
/* uninstall stashed mapping and replace stashed mapping with v. */
if(FuncPtrAdapter.debugFuncInstall){
FuncPtrAdapter.debugOut("FuncPtrAdapter uninstalling", this,
this.contextKey(argv,argIndex), '@'+pair[1], v);
}
- try{ cache.scopedAlloc.pushPtr(pair[1]); }
+ try{cache.scopedAlloc.pushPtr(pair[1]);/*see notes above*/}
catch(e){/*ignored*/}
- pair[0] = pair[1] = (v | 0);
+ pair[0] = pair[1] = (v || __NullPtr);
}
- return v || 0;
+ return v || __NullPtr;
}else{
throw new TypeError("Invalid FuncPtrAdapter argument type. "+
"Expecting a function pointer or a "+
https://sqlite.org/forum/forumpost/b549992634b55104
*/
let i = 0;
+ if( callee.debug ){
+ console.debug("xWrap() preparing: resultType ",resultType, 'xf',xf,"argTypes",argTypes,"args",args);
+ }
for(; i < args.length; ++i) args[i] = cxw.convertArgNoCheck(
argTypes[i], args[i], args, i
);
- `uri`: required URI of the WASM file to load.
- - `onload(loadResult,config)`: optional callback. The first
- argument is the result object from
- WebAssembly.instantiate[Streaming](). The 2nd is the config
- object passed to this function. Described in more detail below.
+ - `onload(loadResult)`: optional callback. Its argument is an
+ object described in more detail below.
- `imports`: optional imports object for
- WebAssembly.instantiate[Streaming](). The default is an empty set
- of imports. If the module requires any imports, this object
+ WebAssembly.instantiate[Streaming](). The default is an empty
+ set of imports. If the module requires any imports, this object
must include them.
- `wasmUtilTarget`: optional object suitable for passing to
WhWasmUtilInstaller(). If set, it gets passed to that function
- after the promise resolves. This function sets several properties
- on it before passing it on to that function (which sets many
- more):
+ before the returned promise resolves. This function sets several
+ properties on it before passing it on to that function (which
+ sets many more):
- `module`, `instance`: the properties from the
instantiate[Streaming]() result.
- If `instance.exports.memory` is _not_ set then it requires that
`config.imports.env.memory` be set (else it throws), and
- assigns that to `target.memory`.
+ assigns that to `wasmUtilTarget.memory`.
- If `wasmUtilTarget.alloc` is not set and
`instance.exports.malloc` is, it installs
It returns a function which, when called, initiates loading of the
module and returns a Promise. When that Promise resolves, it calls
- the `config.onload` callback (if set) and passes it
- `(loadResult,config)`, where `loadResult` is the result of
- WebAssembly.instantiate[Streaming](): an object in the form:
+ the `config.onload` callback (if set) and passes it `(loadResult)`,
+ where `loadResult` is derived from the result of
+ WebAssembly.instantiate[Streaming](), an object in the form:
```
{
module: a WebAssembly.Module,
- instance: a WebAssembly.Instance
+ instance: a WebAssembly.Instance,
+ config: the config arg to this function
}
```
(exported from WASM) or tgt.memory (JS-provided memory
imported into WASM).
*/
- tgt.memory = (config.imports && config.imports.env
- && config.imports.env.memory)
+ tgt.memory = config?.imports?.env?.memory
|| toss("Missing 'memory' object!");
}
if(!tgt.alloc && arg.instance.exports.malloc){
}
wui(tgt);
}
- if(config.onload) config.onload(arg,config);
+ arg.config = config;
+ if(config.onload) config.onload(arg);
return arg /* for any then() handler attached to
yetAnotherWasmLoader()'s return value */;
};
T.assert(P.pointer === stack);
try {
const [p1, p2, p3] = P.allocChunks(3,'i32');
- T.assert(P.pointer == Number(stack)-16/*always rounded to multiple of 8*/)
+ let sPos = wasm.ptrAdd(stack,-16)/*pstack alloc always rounds to multiple of 8*/;
+ T.assert(P.pointer === sPos)
+ .assert(p1 === sPos)
.assert(p2 == Number(p1) + 4)
.assert(p3 == Number(p2) + 4);
T.mustThrowMatching(()=>P.allocChunks(1024, 1024 * 16),
T.assert(P.pointer === stack);
try {
let [p1, p2, p3] = P.allocPtr(3,false);
- let sPos = Number(stack)-16/*always rounded to multiple of 8*/;
- T.assert(P.pointer == sPos)
- .assert(p2 == Number(p1) + 4)
- .assert(p3 == Number(p2) + 4);
+ let sPos = wasm.ptrAdd(stack,
+ -(4===wasm.pointerSizeof
+ ? 16/*pstack alloc always rounds to multiple of 8*/
+ : 24));
+ T.assert(P.pointer === p1)
+ .assert(p1 === sPos)
+ .assert(p2 == Number(p1) + wasm.pointerSizeof)
+ .assert(p3 == Number(p2) + wasm.pointerSizeof);
[p1, p2, p3] = P.allocPtr(3);
- T.assert(P.pointer == sPos-24/*3 x 8 bytes*/)
+ T.assert(P.pointer === wasm.ptrAdd(sPos, -24)/*3 x 8 bytes*/)
.assert(p2 == Number(p1) + 8)
.assert(p3 == Number(p2) + 8);
p1 = P.allocPtr();
try{
const n = 520;
const p = wasm.pstack.alloc(n);
- T.assert(0===wasm.peek8(p))
- .assert(0===wasm.peek8(wasm.ptrAdd(p,n,-1)));
+ T.assert(0==wasm.peek8(p))
+ .assert(0==wasm.peek8(wasm.ptrAdd(p,n,-1)));
T.assert(undefined === capi.sqlite3_randomness(n - 10, p));
let j, check = 0;
const heap = wasm.heap8u();
const stack = wasm.pstack.pointer;
try {
const ppOut = wasm.pstack.allocPtr();
- T.assert( 0===wasm.peekPtr(ppOut) );
+ T.assert( 0==wasm.peekPtr(ppOut) );
let rc = capi.sqlite3_open_v2( ":memory:", ppOut,
capi.SQLITE_OPEN_CREATE
| capi.SQLITE_OPEN_READWRITE,
const db = this.db;
let list = [];
this.progressHandlerCount = 0;
+ //wasm.xWrap.debug = true;
let rc = db.exec({
sql:['CREATE TABLE t(a,b);',
// ^^^ using TEMP TABLE breaks the db export test
-C Get\sthe\swasm\stests\srunning\sin\sa\s64-bit\sbuild\sup\sthrough\s(but\snot\sincluding)\sthe\soo1\sbits.
-D 2025-09-20T11:09:20.368
+C Further\swork\son\s64-bit\sWASM\sbuilds.\sIt\snow\sgets\sthrough\sjust\sshy\sof\shalf\sof\stester1.js.
+D 2025-09-20T15:16:55.119
F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
F ext/wasm/api/post-js-footer.js 365405929f41ca0e6d389ed8a8da3f3c93e11d3ef43a90ae151e37fa9f75bf41
F ext/wasm/api/post-js-header.js 53740d824e5d9027eb1e6fd59e216abbd2136740ce260ea5f0699ff2acb0a701
F ext/wasm/api/pre-js.c-pp.js 58f823de197e2c10d76179aa05410a593b7ae03e1ece983bb42ffd818e8857e1
-F ext/wasm/api/sqlite3-api-cleanup.js 3ac1786e461ada63033143be8c3b00b26b939540661f3e839515bb92f2e35359
-F ext/wasm/api/sqlite3-api-glue.c-pp.js c6a4271411caf9b0ff434436766fcd226e22cad484949fc207045d13ba960354
-F ext/wasm/api/sqlite3-api-oo1.c-pp.js dc8573267f0dd49ae314a295c0dbe86de921f6d6beabbb7a447029ca1ea4e1d9
-F ext/wasm/api/sqlite3-api-prologue.js 5812f5acb0eb17ce04cbea554fa33236acfcbe5eaaa6ddc04eb6454141040a98
+F ext/wasm/api/sqlite3-api-cleanup.js 6341cb85c931044647ad4b12654a178c81f5a8fbeccdf4dc4f258e5a390d2241
+F ext/wasm/api/sqlite3-api-glue.c-pp.js 8d399c686b068427b4c9e51d68d9fc1f632ee9c89a1c49d3e2919744d68c622a
+F ext/wasm/api/sqlite3-api-oo1.c-pp.js c40857ef457c1243d40dd92602e362e7431500936b0358263e8caa115436e705
+F ext/wasm/api/sqlite3-api-prologue.js 1f3aa229e225f8f93e6011d64c7ecd1ac2e4a70b94d8f78f493e1a7dbb236e47
F ext/wasm/api/sqlite3-api-worker1.c-pp.js 760191cd13416e6f5adfd9fcc8a97fed5645c9e0a5fbac213a2d4ce2d79a4334
F ext/wasm/api/sqlite3-license-version-header.js 0c807a421f0187e778dc1078f10d2994b915123c1223fe752b60afdcd1263f89
F ext/wasm/api/sqlite3-opfs-async-proxy.js 9654b565b346dc609b75d15337f20acfa7af7d9d558da1afeb9b6d8eaa404966
F ext/wasm/common/SqliteTestUtil.js 7adaeffef757d8708418dc9190f72df22367b531831775804b31598b44f6aa51
F ext/wasm/common/emscripten.css 11bd104b6c0d597c67d40cc8ecc0a60dae2b965151e3b6a37fa5708bac3acd15
F ext/wasm/common/testing.css e97549bab24126c24e0daabfe2de9bb478fb0a69fdb2ddd0a73a992c091aad6f
-F ext/wasm/common/whwasmutil.js 1475e140bbd48d67e385603ce3e4bef7ca00d8ee3ec896d40cf4f55c7336b0c3
+F ext/wasm/common/whwasmutil.js 1b4b0b38b590221bad5d9d807b1d30127626ddc05f616182f01423ac8fcce089
F ext/wasm/config.make.in c424ae1cc3c89274520ad312509d36c4daa34a3fce5d0c688e5f8f4365e1049a
F ext/wasm/demo-123-worker.html a0b58d9caef098a626a1a1db567076fca4245e8d60ba94557ede8684350a81ed
F ext/wasm/demo-123.html 8c70a412ce386bd3796534257935eb1e3ea5c581e5d5aea0490b8232e570a508
F ext/wasm/test-opfs-vfs.js 1618670e466f424aa289859fe0ec8ded223e42e9e69b5c851f809baaaca1a00c
F ext/wasm/tester1-worker.html ebc4b820a128963afce328ecf63ab200bd923309eb939f4110510ab449e9814c
F ext/wasm/tester1.c-pp.html 1c1bc78b858af2019e663b1a31e76657b73dc24bede28ca92fbe917c3a972af2
-F ext/wasm/tester1.c-pp.js 827de6ae0b069709762afb58c452b769bbab092c6c7c850e5aab9581d82aff45
+F ext/wasm/tester1.c-pp.js 7f32d79407cce016cde0e884e364d5fb04addeb7cb7f43b30169cdd938589634
F ext/wasm/tests/opfs/concurrency/index.html 657578a6e9ce1e9b8be951549ed93a6a471f4520a99e5b545928668f4285fb5e
F ext/wasm/tests/opfs/concurrency/test.js d08889a5bb6e61937d0b8cbb78c9efbefbf65ad09f510589c779b7cc6a803a88
F ext/wasm/tests/opfs/concurrency/worker.js 0a8c1a3e6ebb38aabbee24f122693f1fb29d599948915c76906681bb7da1d3d2
F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7
F tool/warnings.sh 1ad0169b022b280bcaaf94a7fa231591be96b514230ab5c98fbf15cd7df842dd
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
-P 1e3b003ff99d2788d93e179504b711cb78846605774bf472589440d0136f20fa
-R 5e413c78ac49f5649b20125a76a68b9e
+P a5af46174a05e1414370884d1a99827af9286a60eff1c8ae1551e7fad3903f7a
+R 2adec1131b74b3b8137161b75e6957cf
U stephan
-Z 40da1eb0811159ac3f90712f37f01328
+Z 0d524ac36a249cd8e25e154440f46d24
# Remove this line to create a well-formed Fossil manifest.
-a5af46174a05e1414370884d1a99827af9286a60eff1c8ae1551e7fad3903f7a
+c8deed31365898e1379d577298fc80ef08a5531999d5b54a9f14337febed0260