mirror of
https://github.com/sqlite/sqlite.git
synced 2025-07-29 08:01:23 +03:00
More fleshing out of sqlite3.capi.wasm.pstack.
FossilOrigin-Name: eb5726677a727a958df11f1fba078d30c7c0ba2a9bdb158e8641b35b5f971af3
This commit is contained in:
@ -55,10 +55,11 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
|
|||||||
|
|
||||||
if(1){// WhWasmUtil.xWrap() bindings...
|
if(1){// WhWasmUtil.xWrap() bindings...
|
||||||
/**
|
/**
|
||||||
Add some descriptive xWrap() aliases for '*' intended to
|
Add some descriptive xWrap() aliases for '*' intended to (A)
|
||||||
(A) initially improve readability/correctness of capi.signatures
|
initially improve readability/correctness of capi.signatures
|
||||||
and (B) eventually perhaps provide some sort of type-safety
|
and (B) eventually perhaps provide automatic conversion from
|
||||||
in their conversions.
|
higher-level representations, e.g. capi.sqlite3_vfs to
|
||||||
|
`sqlite3_vfs*` via capi.sqlite3_vfs.pointer.
|
||||||
*/
|
*/
|
||||||
const aPtr = wasm.xWrap.argAdapter('*');
|
const aPtr = wasm.xWrap.argAdapter('*');
|
||||||
wasm.xWrap.argAdapter('sqlite3*', aPtr)('sqlite3_stmt*', aPtr);
|
wasm.xWrap.argAdapter('sqlite3*', aPtr)('sqlite3_stmt*', aPtr);
|
||||||
@ -248,6 +249,56 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
|
|||||||
};
|
};
|
||||||
}/*sqlite3_prepare_v2/v3()*/;
|
}/*sqlite3_prepare_v2/v3()*/;
|
||||||
|
|
||||||
|
if(1){// Extend wasm.pstack, now that the wasm utils are installed
|
||||||
|
/**
|
||||||
|
Allocates n chunks, each sz bytes, as a single memory block and
|
||||||
|
returns the addresses as an array of n element, each holding
|
||||||
|
the address of one chunk.
|
||||||
|
|
||||||
|
Throws a WasmAllocError if allocation fails.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
```
|
||||||
|
const [p1, p2, p3] = wasm.pstack.allocChunks(3,4);
|
||||||
|
```
|
||||||
|
*/
|
||||||
|
wasm.pstack.allocChunks = (n,sz)=>{
|
||||||
|
const mem = wasm.pstack.alloc(n * sz);
|
||||||
|
const rc = [];
|
||||||
|
let i = 0, offset = 0;
|
||||||
|
for(; i < n; offset = (sz * ++i)){
|
||||||
|
rc.push(mem + offset);
|
||||||
|
}
|
||||||
|
return rc;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
A convenience wrapper for allocChunks() which sizes each chunks
|
||||||
|
as either 8 bytes (safePtrSize is truthy) or wasm.ptrSizeof (if
|
||||||
|
safePtrSize is truthy).
|
||||||
|
|
||||||
|
How it returns its result differs depending on its first
|
||||||
|
argument: if it's 1, it returns a single pointer value. If it's
|
||||||
|
more than 1, it returns the same as allocChunks().
|
||||||
|
|
||||||
|
When one of the pointers refers to a 64-bit value, e.g. a
|
||||||
|
double or int64, and that value must be written or fetch,
|
||||||
|
e.g. using wasm.setMemValue() or wasm.getMemValue(), it is
|
||||||
|
important that the pointer in question be aligned to an 8-byte
|
||||||
|
boundary or else it will not be fetched or written properly and
|
||||||
|
will corrupt or read neighboring memory.
|
||||||
|
|
||||||
|
However, when all pointers involved are "small", it is safe to
|
||||||
|
pass a falsy value to save to memory.
|
||||||
|
*/
|
||||||
|
wasm.pstack.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 filler*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Install JS<->C struct bindings for the non-opaque struct types we
|
Install JS<->C struct bindings for the non-opaque struct types we
|
||||||
need... */
|
need... */
|
||||||
|
@ -18,7 +18,7 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
|
|||||||
const toss = (...args)=>{throw new Error(args.join(' '))};
|
const toss = (...args)=>{throw new Error(args.join(' '))};
|
||||||
const toss3 = (...args)=>{throw new sqlite3.SQLite3Error(...args)};
|
const toss3 = (...args)=>{throw new sqlite3.SQLite3Error(...args)};
|
||||||
|
|
||||||
const capi = sqlite3.capi, util = capi.util;
|
const capi = sqlite3.capi, wasm = capi.wasm, util = capi.util;
|
||||||
/* What follows is colloquially known as "OO API #1". It is a
|
/* What follows is colloquially known as "OO API #1". It is a
|
||||||
binding of the sqlite3 API which is designed to be run within
|
binding of the sqlite3 API which is designed to be run within
|
||||||
the same thread (main or worker) as the one in which the
|
the same thread (main or worker) as the one in which the
|
||||||
@ -33,7 +33,7 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
|
|||||||
accessor and store their real values in this map. Keys = DB/Stmt
|
accessor and store their real values in this map. Keys = DB/Stmt
|
||||||
objects, values = pointer values. This also unifies how those are
|
objects, values = pointer values. This also unifies how those are
|
||||||
accessed, for potential use downstream via custom
|
accessed, for potential use downstream via custom
|
||||||
capi.wasm.xWrap() function signatures which know how to extract
|
wasm.xWrap() function signatures which know how to extract
|
||||||
it.
|
it.
|
||||||
*/
|
*/
|
||||||
const __ptrMap = new WeakMap();
|
const __ptrMap = new WeakMap();
|
||||||
@ -72,7 +72,7 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
|
|||||||
being-construct DB object as its "this". See the DB constructor
|
being-construct DB object as its "this". See the DB constructor
|
||||||
for the argument docs. This is split into a separate function
|
for the argument docs. This is split into a separate function
|
||||||
in order to enable simple creation of special-case DB constructors,
|
in order to enable simple creation of special-case DB constructors,
|
||||||
e.g. a hypothetical LocalStorageDB or OpfsDB.
|
e.g. JsStorageDB and OpfsDB.
|
||||||
|
|
||||||
Expects to be passed a configuration object with the following
|
Expects to be passed a configuration object with the following
|
||||||
properties:
|
properties:
|
||||||
@ -123,7 +123,7 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
|
|||||||
console.error("Invalid DB ctor args",opt,arguments);
|
console.error("Invalid DB ctor args",opt,arguments);
|
||||||
toss3("Invalid arguments for DB constructor.");
|
toss3("Invalid arguments for DB constructor.");
|
||||||
}
|
}
|
||||||
let fnJs = ('number'===typeof fn) ? capi.wasm.cstringToJs(fn) : fn;
|
let fnJs = ('number'===typeof fn) ? wasm.cstringToJs(fn) : fn;
|
||||||
const vfsCheck = ctor._name2vfs[fnJs];
|
const vfsCheck = ctor._name2vfs[fnJs];
|
||||||
if(vfsCheck){
|
if(vfsCheck){
|
||||||
vfsName = vfsCheck.vfs;
|
vfsName = vfsCheck.vfs;
|
||||||
@ -136,20 +136,20 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
|
|||||||
if( flagsStr.indexOf('w')>=0 ) oflags |= capi.SQLITE_OPEN_READWRITE;
|
if( flagsStr.indexOf('w')>=0 ) oflags |= capi.SQLITE_OPEN_READWRITE;
|
||||||
if( 0===oflags ) oflags |= capi.SQLITE_OPEN_READONLY;
|
if( 0===oflags ) oflags |= capi.SQLITE_OPEN_READONLY;
|
||||||
oflags |= capi.SQLITE_OPEN_EXRESCODE;
|
oflags |= capi.SQLITE_OPEN_EXRESCODE;
|
||||||
const stack = capi.wasm.scopedAllocPush();
|
const scope = wasm.scopedAllocPush();
|
||||||
try {
|
try {
|
||||||
const ppDb = capi.wasm.scopedAllocPtr() /* output (sqlite3**) arg */;
|
const ppDb = wasm.allocPtr() /* output (sqlite3**) arg */;
|
||||||
const pVfsName = vfsName ? (
|
const pVfsName = vfsName ? (
|
||||||
('number'===typeof vfsName ? vfsName : capi.wasm.scopedAllocCString(vfsName))
|
('number'===typeof vfsName ? vfsName : wasm.scopedAllocCString(vfsName))
|
||||||
): 0;
|
): 0;
|
||||||
const rc = capi.sqlite3_open_v2(fn, ppDb, oflags, pVfsName);
|
const rc = capi.sqlite3_open_v2(fn, ppDb, oflags, pVfsName);
|
||||||
ptr = capi.wasm.getPtrValue(ppDb);
|
ptr = wasm.getPtrValue(ppDb);
|
||||||
checkSqlite3Rc(ptr, rc);
|
checkSqlite3Rc(ptr, rc);
|
||||||
}catch( e ){
|
}catch( e ){
|
||||||
if( ptr ) capi.sqlite3_close_v2(ptr);
|
if( ptr ) capi.sqlite3_close_v2(ptr);
|
||||||
throw e;
|
throw e;
|
||||||
}finally{
|
}finally{
|
||||||
capi.wasm.scopedAllocPop(stack);
|
wasm.scopedAllocPop(scope);
|
||||||
}
|
}
|
||||||
this.filename = fnJs;
|
this.filename = fnJs;
|
||||||
__ptrMap.set(this, ptr);
|
__ptrMap.set(this, ptr);
|
||||||
@ -265,7 +265,7 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
|
|||||||
blob: 5
|
blob: 5
|
||||||
};
|
};
|
||||||
BindTypes['undefined'] == BindTypes.null;
|
BindTypes['undefined'] == BindTypes.null;
|
||||||
if(capi.wasm.bigIntEnabled){
|
if(wasm.bigIntEnabled){
|
||||||
BindTypes.bigint = BindTypes.number;
|
BindTypes.bigint = BindTypes.number;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -454,7 +454,7 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
|
|||||||
if(s && s.pointer) s.finalize();
|
if(s && s.pointer) s.finalize();
|
||||||
});
|
});
|
||||||
Object.values(__udfMap.get(this)).forEach(
|
Object.values(__udfMap.get(this)).forEach(
|
||||||
capi.wasm.uninstallFunction.bind(capi.wasm)
|
wasm.uninstallFunction.bind(capi.wasm)
|
||||||
);
|
);
|
||||||
__ptrMap.delete(this);
|
__ptrMap.delete(this);
|
||||||
__stmtMap.delete(this);
|
__stmtMap.delete(this);
|
||||||
@ -539,15 +539,15 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
|
|||||||
*/
|
*/
|
||||||
prepare: function(sql){
|
prepare: function(sql){
|
||||||
affirmDbOpen(this);
|
affirmDbOpen(this);
|
||||||
const stack = capi.wasm.pstack.pointer;
|
const stack = wasm.pstack.pointer;
|
||||||
let ppStmt, pStmt;
|
let ppStmt, pStmt;
|
||||||
try{
|
try{
|
||||||
ppStmt = capi.wasm.pstack.alloc(8)/* output (sqlite3_stmt**) arg */;
|
ppStmt = wasm.pstack.alloc(8)/* output (sqlite3_stmt**) arg */;
|
||||||
DB.checkRc(this, capi.sqlite3_prepare_v2(this.pointer, sql, -1, ppStmt, null));
|
DB.checkRc(this, capi.sqlite3_prepare_v2(this.pointer, sql, -1, ppStmt, null));
|
||||||
pStmt = capi.wasm.getPtrValue(ppStmt);
|
pStmt = wasm.getPtrValue(ppStmt);
|
||||||
}
|
}
|
||||||
finally {
|
finally {
|
||||||
capi.wasm.pstack.restore(stack);
|
wasm.pstack.restore(stack);
|
||||||
}
|
}
|
||||||
if(!pStmt) toss3("Cannot prepare empty SQL.");
|
if(!pStmt) toss3("Cannot prepare empty SQL.");
|
||||||
const stmt = new Stmt(this, pStmt, BindTypes);
|
const stmt = new Stmt(this, pStmt, BindTypes);
|
||||||
@ -846,7 +846,7 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
|
|||||||
let i, pVal, valType, arg;
|
let i, pVal, valType, arg;
|
||||||
const tgt = [];
|
const tgt = [];
|
||||||
for(i = 0; i < argc; ++i){
|
for(i = 0; i < argc; ++i){
|
||||||
pVal = capi.wasm.getPtrValue(pArgv + (capi.wasm.ptrSizeof * i));
|
pVal = wasm.getPtrValue(pArgv + (wasm.ptrSizeof * i));
|
||||||
/**
|
/**
|
||||||
Curiously: despite ostensibly requiring 8-byte
|
Curiously: despite ostensibly requiring 8-byte
|
||||||
alignment, the pArgv array is parcelled into chunks of
|
alignment, the pArgv array is parcelled into chunks of
|
||||||
@ -868,7 +868,7 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
|
|||||||
const pBlob = capi.sqlite3_value_blob(pVal);
|
const pBlob = capi.sqlite3_value_blob(pVal);
|
||||||
arg = new Uint8Array(n);
|
arg = new Uint8Array(n);
|
||||||
let i;
|
let i;
|
||||||
const heap = n ? capi.wasm.heap8() : false;
|
const heap = n ? wasm.heap8() : false;
|
||||||
for(i = 0; i < n; ++i) arg[i] = heap[pBlob+i];
|
for(i = 0; i < n; ++i) arg[i] = heap[pBlob+i];
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -902,10 +902,10 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
|
|||||||
capi.sqlite3_result_null(pCx);
|
capi.sqlite3_result_null(pCx);
|
||||||
break;
|
break;
|
||||||
}else if(util.isBindableTypedArray(val)){
|
}else if(util.isBindableTypedArray(val)){
|
||||||
const pBlob = capi.wasm.allocFromTypedArray(val);
|
const pBlob = wasm.allocFromTypedArray(val);
|
||||||
capi.sqlite3_result_blob(pCx, pBlob, val.byteLength,
|
capi.sqlite3_result_blob(pCx, pBlob, val.byteLength,
|
||||||
capi.SQLITE_TRANSIENT);
|
capi.SQLITE_TRANSIENT);
|
||||||
capi.wasm.dealloc(pBlob);
|
wasm.dealloc(pBlob);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// else fall through
|
// else fall through
|
||||||
@ -925,7 +925,7 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
const pUdf = capi.wasm.installFunction(wrapper, "v(iii)");
|
const pUdf = wasm.installFunction(wrapper, "v(iii)");
|
||||||
let fFlags = 0 /*flags for sqlite3_create_function_v2()*/;
|
let fFlags = 0 /*flags for sqlite3_create_function_v2()*/;
|
||||||
if(getOwnOption(opt, 'deterministic')) fFlags |= capi.SQLITE_DETERMINISTIC;
|
if(getOwnOption(opt, 'deterministic')) fFlags |= capi.SQLITE_DETERMINISTIC;
|
||||||
if(getOwnOption(opt, 'directOnly')) fFlags |= capi.SQLITE_DIRECTONLY;
|
if(getOwnOption(opt, 'directOnly')) fFlags |= capi.SQLITE_DIRECTONLY;
|
||||||
@ -938,12 +938,12 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
|
|||||||
capi.SQLITE_UTF8 | fFlags, null/*pApp*/, pUdf,
|
capi.SQLITE_UTF8 | fFlags, null/*pApp*/, pUdf,
|
||||||
null/*xStep*/, null/*xFinal*/, null/*xDestroy*/));
|
null/*xStep*/, null/*xFinal*/, null/*xDestroy*/));
|
||||||
}catch(e){
|
}catch(e){
|
||||||
capi.wasm.uninstallFunction(pUdf);
|
wasm.uninstallFunction(pUdf);
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
const udfMap = __udfMap.get(this);
|
const udfMap = __udfMap.get(this);
|
||||||
if(udfMap[name]){
|
if(udfMap[name]){
|
||||||
try{capi.wasm.uninstallFunction(udfMap[name])}
|
try{wasm.uninstallFunction(udfMap[name])}
|
||||||
catch(e){/*ignore*/}
|
catch(e){/*ignore*/}
|
||||||
}
|
}
|
||||||
udfMap[name] = pUdf;
|
udfMap[name] = pUdf;
|
||||||
@ -1049,7 +1049,7 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
|
|||||||
case BindTypes.string:
|
case BindTypes.string:
|
||||||
return t;
|
return t;
|
||||||
case BindTypes.bigint:
|
case BindTypes.bigint:
|
||||||
if(capi.wasm.bigIntEnabled) return t;
|
if(wasm.bigIntEnabled) return t;
|
||||||
/* else fall through */
|
/* else fall through */
|
||||||
default:
|
default:
|
||||||
//console.log("isSupportedBindType",t,v);
|
//console.log("isSupportedBindType",t,v);
|
||||||
@ -1109,7 +1109,7 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
|
|||||||
const bindOne = function f(stmt,ndx,bindType,val){
|
const bindOne = function f(stmt,ndx,bindType,val){
|
||||||
affirmUnlocked(stmt, 'bind()');
|
affirmUnlocked(stmt, 'bind()');
|
||||||
if(!f._){
|
if(!f._){
|
||||||
if(capi.wasm.bigIntEnabled){
|
if(wasm.bigIntEnabled){
|
||||||
f._maxInt = BigInt("0x7fffffffffffffff");
|
f._maxInt = BigInt("0x7fffffffffffffff");
|
||||||
f._minInt = ~f._maxInt;
|
f._minInt = ~f._maxInt;
|
||||||
}
|
}
|
||||||
@ -1120,25 +1120,25 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
|
|||||||
string: function(stmt, ndx, val, asBlob){
|
string: function(stmt, ndx, val, asBlob){
|
||||||
if(1){
|
if(1){
|
||||||
/* _Hypothetically_ more efficient than the impl in the 'else' block. */
|
/* _Hypothetically_ more efficient than the impl in the 'else' block. */
|
||||||
const stack = capi.wasm.scopedAllocPush();
|
const stack = wasm.scopedAllocPush();
|
||||||
try{
|
try{
|
||||||
const n = capi.wasm.jstrlen(val);
|
const n = wasm.jstrlen(val);
|
||||||
const pStr = capi.wasm.scopedAlloc(n);
|
const pStr = wasm.scopedAlloc(n);
|
||||||
capi.wasm.jstrcpy(val, capi.wasm.heap8u(), pStr, n, false);
|
wasm.jstrcpy(val, wasm.heap8u(), pStr, n, false);
|
||||||
const f = asBlob ? capi.sqlite3_bind_blob : capi.sqlite3_bind_text;
|
const f = asBlob ? capi.sqlite3_bind_blob : capi.sqlite3_bind_text;
|
||||||
return f(stmt.pointer, ndx, pStr, n, capi.SQLITE_TRANSIENT);
|
return f(stmt.pointer, ndx, pStr, n, capi.SQLITE_TRANSIENT);
|
||||||
}finally{
|
}finally{
|
||||||
capi.wasm.scopedAllocPop(stack);
|
wasm.scopedAllocPop(stack);
|
||||||
}
|
}
|
||||||
}else{
|
}else{
|
||||||
const bytes = capi.wasm.jstrToUintArray(val,false);
|
const bytes = wasm.jstrToUintArray(val,false);
|
||||||
const pStr = capi.wasm.alloc(bytes.length || 1);
|
const pStr = wasm.alloc(bytes.length || 1);
|
||||||
capi.wasm.heap8u().set(bytes.length ? bytes : [0], pStr);
|
wasm.heap8u().set(bytes.length ? bytes : [0], pStr);
|
||||||
try{
|
try{
|
||||||
const f = asBlob ? capi.sqlite3_bind_blob : capi.sqlite3_bind_text;
|
const f = asBlob ? capi.sqlite3_bind_blob : capi.sqlite3_bind_text;
|
||||||
return f(stmt.pointer, ndx, pStr, bytes.length, capi.SQLITE_TRANSIENT);
|
return f(stmt.pointer, ndx, pStr, bytes.length, capi.SQLITE_TRANSIENT);
|
||||||
}finally{
|
}finally{
|
||||||
capi.wasm.dealloc(pStr);
|
wasm.dealloc(pStr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1160,7 +1160,7 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
|
|||||||
else if('bigint'===typeof val){
|
else if('bigint'===typeof val){
|
||||||
if(val<f._minInt || val>f._maxInt){
|
if(val<f._minInt || val>f._maxInt){
|
||||||
toss3("BigInt value is out of range for storing as int64: "+val);
|
toss3("BigInt value is out of range for storing as int64: "+val);
|
||||||
}else if(capi.wasm.bigIntEnabled){
|
}else if(wasm.bigIntEnabled){
|
||||||
m = capi.sqlite3_bind_int64;
|
m = capi.sqlite3_bind_int64;
|
||||||
}else if(val >= Number.MIN_SAFE_INTEGER && val <= Number.MAX_SAFE_INTEGER){
|
}else if(val >= Number.MIN_SAFE_INTEGER && val <= Number.MAX_SAFE_INTEGER){
|
||||||
val = Number(val);
|
val = Number(val);
|
||||||
@ -1170,7 +1170,7 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
|
|||||||
}
|
}
|
||||||
}else{ // !int32, !bigint
|
}else{ // !int32, !bigint
|
||||||
val = Number(val);
|
val = Number(val);
|
||||||
if(capi.wasm.bigIntEnabled && Number.isInteger(val)){
|
if(wasm.bigIntEnabled && Number.isInteger(val)){
|
||||||
m = capi.sqlite3_bind_int64;
|
m = capi.sqlite3_bind_int64;
|
||||||
}else{
|
}else{
|
||||||
m = capi.sqlite3_bind_double;
|
m = capi.sqlite3_bind_double;
|
||||||
@ -1190,22 +1190,22 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
|
|||||||
"that it be a string, Uint8Array, or Int8Array.");
|
"that it be a string, Uint8Array, or Int8Array.");
|
||||||
}else if(1){
|
}else if(1){
|
||||||
/* _Hypothetically_ more efficient than the impl in the 'else' block. */
|
/* _Hypothetically_ more efficient than the impl in the 'else' block. */
|
||||||
const stack = capi.wasm.scopedAllocPush();
|
const stack = wasm.scopedAllocPush();
|
||||||
try{
|
try{
|
||||||
const pBlob = capi.wasm.scopedAlloc(val.byteLength || 1);
|
const pBlob = wasm.scopedAlloc(val.byteLength || 1);
|
||||||
capi.wasm.heap8().set(val.byteLength ? val : [0], pBlob)
|
wasm.heap8().set(val.byteLength ? val : [0], pBlob)
|
||||||
rc = capi.sqlite3_bind_blob(stmt.pointer, ndx, pBlob, val.byteLength,
|
rc = capi.sqlite3_bind_blob(stmt.pointer, ndx, pBlob, val.byteLength,
|
||||||
capi.SQLITE_TRANSIENT);
|
capi.SQLITE_TRANSIENT);
|
||||||
}finally{
|
}finally{
|
||||||
capi.wasm.scopedAllocPop(stack);
|
wasm.scopedAllocPop(stack);
|
||||||
}
|
}
|
||||||
}else{
|
}else{
|
||||||
const pBlob = capi.wasm.allocFromTypedArray(val);
|
const pBlob = wasm.allocFromTypedArray(val);
|
||||||
try{
|
try{
|
||||||
rc = capi.sqlite3_bind_blob(stmt.pointer, ndx, pBlob, val.byteLength,
|
rc = capi.sqlite3_bind_blob(stmt.pointer, ndx, pBlob, val.byteLength,
|
||||||
capi.SQLITE_TRANSIENT);
|
capi.SQLITE_TRANSIENT);
|
||||||
}finally{
|
}finally{
|
||||||
capi.wasm.dealloc(pBlob);
|
wasm.dealloc(pBlob);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -1518,7 +1518,7 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
|
|||||||
: asType){
|
: asType){
|
||||||
case capi.SQLITE_NULL: return null;
|
case capi.SQLITE_NULL: return null;
|
||||||
case capi.SQLITE_INTEGER:{
|
case capi.SQLITE_INTEGER:{
|
||||||
if(capi.wasm.bigIntEnabled){
|
if(wasm.bigIntEnabled){
|
||||||
const rc = capi.sqlite3_column_int64(this.pointer, ndx);
|
const rc = capi.sqlite3_column_int64(this.pointer, ndx);
|
||||||
if(rc>=Number.MIN_SAFE_INTEGER && rc<=Number.MAX_SAFE_INTEGER){
|
if(rc>=Number.MIN_SAFE_INTEGER && rc<=Number.MAX_SAFE_INTEGER){
|
||||||
/* Coerce "normal" number ranges to normal number values,
|
/* Coerce "normal" number ranges to normal number values,
|
||||||
@ -1549,8 +1549,8 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
|
|||||||
const n = capi.sqlite3_column_bytes(this.pointer, ndx),
|
const n = capi.sqlite3_column_bytes(this.pointer, ndx),
|
||||||
ptr = capi.sqlite3_column_blob(this.pointer, ndx),
|
ptr = capi.sqlite3_column_blob(this.pointer, ndx),
|
||||||
rc = new Uint8Array(n);
|
rc = new Uint8Array(n);
|
||||||
//heap = n ? capi.wasm.heap8() : false;
|
//heap = n ? wasm.heap8() : false;
|
||||||
if(n) rc.set(capi.wasm.heap8u().slice(ptr, ptr+n), 0);
|
if(n) rc.set(wasm.heap8u().slice(ptr, ptr+n), 0);
|
||||||
//for(let i = 0; i < n; ++i) rc[i] = heap[ptr + i];
|
//for(let i = 0; i < n; ++i) rc[i] = heap[ptr + i];
|
||||||
if(n && this.db._blobXfer instanceof Array){
|
if(n && this.db._blobXfer instanceof Array){
|
||||||
/* This is an optimization soley for the
|
/* This is an optimization soley for the
|
||||||
|
@ -265,6 +265,9 @@ self.sqlite3ApiBootstrap = function sqlite3ApiBootstrap(
|
|||||||
this.name = 'WasmAllocError';
|
this.name = 'WasmAllocError';
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
WasmAllocError.toss = (...args)=>{
|
||||||
|
throw new WasmAllocError(args.join(' '));
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
The main sqlite3 binding API gets installed into this object,
|
The main sqlite3 binding API gets installed into this object,
|
||||||
@ -733,6 +736,9 @@ self.sqlite3ApiBootstrap = function sqlite3ApiBootstrap(
|
|||||||
Functions which are intended solely for API-internal use by the
|
Functions which are intended solely for API-internal use by the
|
||||||
WASM components, not client code. These get installed into
|
WASM components, not client code. These get installed into
|
||||||
capi.wasm.
|
capi.wasm.
|
||||||
|
|
||||||
|
TODO: get rid of sqlite3_wasm_vfs_unlink(). It is ill-conceived
|
||||||
|
and only rarely actually useful.
|
||||||
*/
|
*/
|
||||||
capi.wasm.bindingSignatures.wasm = [
|
capi.wasm.bindingSignatures.wasm = [
|
||||||
["sqlite3_wasm_vfs_unlink", "int", "string"]
|
["sqlite3_wasm_vfs_unlink", "int", "string"]
|
||||||
@ -781,15 +787,21 @@ self.sqlite3ApiBootstrap = function sqlite3ApiBootstrap(
|
|||||||
Attempts to allocate the given number of bytes from the
|
Attempts to allocate the given number of bytes from the
|
||||||
pstack. On success, it zeroes out a block of memory of the
|
pstack. On success, it zeroes out a block of memory of the
|
||||||
given size, adjusts the pstack pointer, and returns a pointer
|
given size, adjusts the pstack pointer, and returns a pointer
|
||||||
to the memory. On error, returns 0. The memory must eventually
|
to the memory. On error, returns throws a WasmAllocError. The
|
||||||
be released using restore().
|
memory must eventually be released using restore().
|
||||||
|
|
||||||
This method always adjusts the given value to be a multiple
|
This method always adjusts the given value to be a multiple
|
||||||
of 8 bytes because failing to do so can lead to incorrect
|
of 8 bytes because failing to do so can lead to incorrect
|
||||||
results when reading and writing 64-bit values from/to the WASM
|
results when reading and writing 64-bit values from/to the WASM
|
||||||
heap.
|
heap.
|
||||||
*/
|
*/
|
||||||
alloc: capi.wasm.exports.sqlite3_wasm_pstack_alloc
|
alloc: (n)=>{
|
||||||
|
return capi.wasm.exports.sqlite3_wasm_pstack_alloc(n)
|
||||||
|
|| WasmAllocError.toss("Could not allocate",n,
|
||||||
|
"bytes from the pstack.");
|
||||||
|
}
|
||||||
|
// More methods get added after the capi.wasm object is populated
|
||||||
|
// by WhWasmUtilInstaller.
|
||||||
});
|
});
|
||||||
/**
|
/**
|
||||||
sqlite3.capi.wasm.pstack.pointer resolves to the current pstack
|
sqlite3.capi.wasm.pstack.pointer resolves to the current pstack
|
||||||
@ -828,7 +840,9 @@ self.sqlite3ApiBootstrap = function sqlite3ApiBootstrap(
|
|||||||
this.name = 'SQLite3Error';
|
this.name = 'SQLite3Error';
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
SQLite3Error.toss = (...args)=>{
|
||||||
|
throw new SQLite3Error(args.join(' '));
|
||||||
|
};
|
||||||
|
|
||||||
/** State for sqlite3_wasmfs_opfs_dir(). */
|
/** State for sqlite3_wasmfs_opfs_dir(). */
|
||||||
let __persistentDir = undefined;
|
let __persistentDir = undefined;
|
||||||
|
@ -59,6 +59,10 @@
|
|||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include "sqlite3.c" /* yes, .c instead of .h. */
|
#include "sqlite3.c" /* yes, .c instead of .h. */
|
||||||
|
|
||||||
|
#if defined(__EMSCRIPTEN__)
|
||||||
|
# include <emscripten/console.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** WASM_KEEP is identical to EMSCRIPTEN_KEEPALIVE but is not
|
** WASM_KEEP is identical to EMSCRIPTEN_KEEPALIVE but is not
|
||||||
** Emscripten-specific. It explicitly marks functions for export into
|
** Emscripten-specific. It explicitly marks functions for export into
|
||||||
@ -667,6 +671,9 @@ WASM_KEEP
|
|||||||
int sqlite3_wasm_vfs_unlink(const char * zName){
|
int sqlite3_wasm_vfs_unlink(const char * zName){
|
||||||
int rc = SQLITE_MISUSE /* ??? */;
|
int rc = SQLITE_MISUSE /* ??? */;
|
||||||
sqlite3_vfs * const pVfs = sqlite3_vfs_find(0);
|
sqlite3_vfs * const pVfs = sqlite3_vfs_find(0);
|
||||||
|
#if defined(__EMSCRIPTEN__)
|
||||||
|
emscripten_console_warn("sqlite3_wasm_vfs_unlink() will be removed.");
|
||||||
|
#endif
|
||||||
if( zName && pVfs && pVfs->xDelete ){
|
if( zName && pVfs && pVfs->xDelete ){
|
||||||
rc = pVfs->xDelete(pVfs, zName, 1);
|
rc = pVfs->xDelete(pVfs, zName, 1);
|
||||||
}
|
}
|
||||||
@ -750,9 +757,7 @@ int sqlite3_wasm_db_serialize( sqlite3* pDb, unsigned char **pOut, sqlite3_int64
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#if defined(__EMSCRIPTEN__)
|
#if defined(__EMSCRIPTEN__) && defined(SQLITE_WASM_WASMFS)
|
||||||
#include <emscripten/console.h>
|
|
||||||
#if defined(SQLITE_WASM_WASMFS)
|
|
||||||
#include <emscripten/wasmfs.h>
|
#include <emscripten/wasmfs.h>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -809,6 +814,5 @@ int sqlite3_wasm_init_wasmfs(const char *zUnused){
|
|||||||
return SQLITE_NOTFOUND;
|
return SQLITE_NOTFOUND;
|
||||||
}
|
}
|
||||||
#endif /* __EMSCRIPTEN__ && SQLITE_WASM_WASMFS */
|
#endif /* __EMSCRIPTEN__ && SQLITE_WASM_WASMFS */
|
||||||
#endif
|
|
||||||
|
|
||||||
#undef WASM_KEEP
|
#undef WASM_KEEP
|
||||||
|
@ -1091,28 +1091,36 @@ self.WhWasmUtilInstaller = function(target){
|
|||||||
};
|
};
|
||||||
|
|
||||||
/** Internal impl for allocPtr() and scopedAllocPtr(). */
|
/** Internal impl for allocPtr() and scopedAllocPtr(). */
|
||||||
const __allocPtr = function(howMany, method){
|
const __allocPtr = function(howMany, safePtrSize, method){
|
||||||
__affirmAlloc(target, method);
|
__affirmAlloc(target, method);
|
||||||
let m = target[method](howMany * ptrSizeof);
|
const pIr = safePtrSize ? 'i64' : ptrIR;
|
||||||
target.setMemValue(m, 0, ptrIR)
|
let m = target[method](howMany * (safePtrSize ? 8 : ptrSizeof));
|
||||||
|
target.setMemValue(m, 0, pIr)
|
||||||
if(1===howMany){
|
if(1===howMany){
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
const a = [m];
|
const a = [m];
|
||||||
for(let i = 1; i < howMany; ++i){
|
for(let i = 1; i < howMany; ++i){
|
||||||
m += ptrSizeof;
|
m += (safePtrSize ? 8 : ptrSizeof);
|
||||||
a[i] = m;
|
a[i] = m;
|
||||||
target.setMemValue(m, 0, ptrIR);
|
target.setMemValue(m, 0, pIr);
|
||||||
}
|
}
|
||||||
return a;
|
return a;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Allocates a single chunk of memory capable of holding `howMany`
|
Allocates one or more pointers as a single chunk of memory and
|
||||||
pointers and zeroes them out. If `howMany` is 1 then the memory
|
zeroes them out.
|
||||||
chunk is returned directly, else an array of pointer addresses is
|
|
||||||
returned, which can optionally be used with "destructuring
|
The first argument is the number of pointers to allocate. The
|
||||||
assignment" like this:
|
second specifies whether they should use a "safe" pointer size (8
|
||||||
|
bytes) or whether they may use the default pointer size
|
||||||
|
(typically 4 but also possibly 8).
|
||||||
|
|
||||||
|
How the result is returned depends on its first argument: if
|
||||||
|
passed 1, it returns the allocated memory address. If passed more
|
||||||
|
than one then an array of pointer addresses is returned, which
|
||||||
|
can optionally be used with "destructuring assignment" like this:
|
||||||
|
|
||||||
```
|
```
|
||||||
const [p1, p2, p3] = allocPtr(3);
|
const [p1, p2, p3] = allocPtr(3);
|
||||||
@ -1121,14 +1129,27 @@ self.WhWasmUtilInstaller = function(target){
|
|||||||
ACHTUNG: when freeing the memory, pass only the _first_ result
|
ACHTUNG: when freeing the memory, pass only the _first_ result
|
||||||
value to dealloc(). The others are part of the same memory chunk
|
value to dealloc(). The others are part of the same memory chunk
|
||||||
and must not be freed separately.
|
and must not be freed separately.
|
||||||
|
|
||||||
|
The reason for the 2nd argument is..
|
||||||
|
|
||||||
|
When one of the pointers will refer to a 64-bit value, e.g. a
|
||||||
|
double or int64, an that value must be written or fetch,
|
||||||
|
e.g. using setMemValue() or getMemValue(), it is important that
|
||||||
|
the pointer in question be aligned to an 8-byte boundary or else
|
||||||
|
it will not be fetched or written properly and will corrupt or
|
||||||
|
read neighboring memory. It i only safe to pass false when the
|
||||||
|
client code is certain that it will only get/fetch 4-byte values
|
||||||
|
(or smaller).
|
||||||
*/
|
*/
|
||||||
target.allocPtr = (howMany=1)=>__allocPtr(howMany, 'alloc');
|
target.allocPtr =
|
||||||
|
(howMany=1, safePtrSize=true)=>__allocPtr(howMany, safePtrSize, 'alloc');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Identical to allocPtr() except that it allocates using scopedAlloc()
|
Identical to allocPtr() except that it allocates using scopedAlloc()
|
||||||
instead of alloc().
|
instead of alloc().
|
||||||
*/
|
*/
|
||||||
target.scopedAllocPtr = (howMany=1)=>__allocPtr(howMany, 'scopedAlloc');
|
target.scopedAllocPtr =
|
||||||
|
(howMany=1, safePtrSize=true)=>__allocPtr(howMany, safePtrSize, 'scopedAlloc');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
If target.exports[name] exists, it is returned, else an
|
If target.exports[name] exists, it is returned, else an
|
||||||
|
@ -1030,31 +1030,60 @@
|
|||||||
*/
|
*/
|
||||||
const testPstack = function(db,sqlite3){
|
const testPstack = function(db,sqlite3){
|
||||||
const w = sqlite3.capi.wasm, P = w.pstack;
|
const w = sqlite3.capi.wasm, P = w.pstack;
|
||||||
|
const isAllocErr = (e)=>e instanceof sqlite3.WasmAllocError;
|
||||||
const stack = P.pointer;
|
const stack = P.pointer;
|
||||||
T.assert(0===stack % 8 /* must be 8-byte aligned */);
|
T.assert(0===stack % 8 /* must be 8-byte aligned */);
|
||||||
try{
|
try{
|
||||||
const quota = P.remaining;
|
const quota = P.remaining;
|
||||||
log("pstack quota",quota);
|
log("pstack quota",quota);
|
||||||
T.assert(quota >= 4096)
|
T.assert(quota >= 4096)
|
||||||
.assert(0 === P.alloc(0))
|
.mustThrowMatching(()=>P.alloc(0), isAllocErr)
|
||||||
.assert(0 === P.alloc(-1));
|
.mustThrowMatching(()=>P.alloc(-1), isAllocErr);
|
||||||
let p1 = P.alloc(12);
|
let p1 = P.alloc(12);
|
||||||
T.assert(p1 === stack - 16/*8-byte aligned*/)
|
T.assert(p1 === stack - 16/*8-byte aligned*/)
|
||||||
.assert(P.pointer === p1);
|
.assert(P.pointer === p1);
|
||||||
let p2 = P.alloc(7);
|
let p2 = P.alloc(7);
|
||||||
T.assert(p2 === p1-8/*8-byte aligned, stack grows downwards*/)
|
T.assert(p2 === p1-8/*8-byte aligned, stack grows downwards*/)
|
||||||
.assert(0 === P.alloc(quota))
|
.mustThrowMatching(()=>P.alloc(quota), isAllocErr)
|
||||||
.assert(24 === stack - p2)
|
.assert(24 === stack - p2)
|
||||||
.assert(P.pointer === p2);
|
.assert(P.pointer === p2);
|
||||||
let n = quota - (stack - p2);
|
let n = quota - (stack - p2);
|
||||||
let p3 = P.alloc(n);
|
let p3 = P.alloc(n);
|
||||||
T.assert(p3 === stack-quota)
|
T.assert(p3 === stack-quota)
|
||||||
.assert(0 === P.alloc(1));
|
.mustThrowMatching(()=>P.alloc(1), isAllocErr);
|
||||||
}finally{
|
}finally{
|
||||||
P.restore(stack);
|
P.restore(stack);
|
||||||
T.assert(P.pointer === stack);
|
|
||||||
}
|
}
|
||||||
}/*testPstack()*/;
|
|
||||||
|
T.assert(P.pointer === stack);
|
||||||
|
try {
|
||||||
|
const [p1, p2, p3] = P.allocChunks(3,4);
|
||||||
|
T.assert(P.pointer === stack-16/*always rounded to multiple of 8*/)
|
||||||
|
.assert(p2 === p1 + 4)
|
||||||
|
.assert(p3 === p2 + 4);
|
||||||
|
T.mustThrowMatching(()=>P.allocChunks(1024, 1024 * 16),
|
||||||
|
(e)=>e instanceof sqlite3.WasmAllocError)
|
||||||
|
}finally{
|
||||||
|
P.restore(stack);
|
||||||
|
}
|
||||||
|
|
||||||
|
T.assert(P.pointer === stack);
|
||||||
|
try {
|
||||||
|
let [p1, p2, p3] = P.allocPtr(3,false);
|
||||||
|
let sPos = stack-16/*always rounded to multiple of 8*/;
|
||||||
|
T.assert(P.pointer === sPos)
|
||||||
|
.assert(p2 === p1 + 4)
|
||||||
|
.assert(p3 === p2 + 4);
|
||||||
|
[p1, p2, p3] = P.allocPtr(3);
|
||||||
|
T.assert(P.pointer === sPos-24/*3 x 8 bytes*/)
|
||||||
|
.assert(p2 === p1 + 8)
|
||||||
|
.assert(p3 === p2 + 8);
|
||||||
|
p1 = P.allocPtr();
|
||||||
|
T.assert('number'===typeof p1);
|
||||||
|
}finally{
|
||||||
|
P.restore(stack);
|
||||||
|
}
|
||||||
|
}/*testPstack()*/;
|
||||||
|
|
||||||
const clearKvvfs = function(){
|
const clearKvvfs = function(){
|
||||||
const sz = sqlite3.capi.sqlite3_web_kvvfs_size();
|
const sz = sqlite3.capi.sqlite3_web_kvvfs_size();
|
||||||
|
22
manifest
22
manifest
@ -1,5 +1,5 @@
|
|||||||
C Document\sthe\sroles\sof\sthe\snew\s(this\spast\sweek)\sJS\sfiles\sadded\sto\sthe\sbuild\sprocess.
|
C More\sfleshing\sout\sof\ssqlite3.capi.wasm.pstack.
|
||||||
D 2022-10-02T01:48:14.286
|
D 2022-10-02T03:11:13.806
|
||||||
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
|
||||||
@ -485,19 +485,19 @@ F ext/wasm/api/post-js-footer.js b64319261d920211b8700004d08b956a6c285f3b0bba814
|
|||||||
F ext/wasm/api/post-js-header.js 2e5c886398013ba2af88028ecbced1e4b22dc96a86467f1ecc5ba9e64ef90a8b
|
F ext/wasm/api/post-js-header.js 2e5c886398013ba2af88028ecbced1e4b22dc96a86467f1ecc5ba9e64ef90a8b
|
||||||
F ext/wasm/api/pre-js.js 2db711eb637991b383fc6b5c0f3df65ec48a7201e5730e304beba8de2d3f9b0b
|
F ext/wasm/api/pre-js.js 2db711eb637991b383fc6b5c0f3df65ec48a7201e5730e304beba8de2d3f9b0b
|
||||||
F ext/wasm/api/sqlite3-api-cleanup.js 5d22d1d3818ecacb23bfa223d5970cd0617d8cdbb48c8bc4bbd463f05b021a99
|
F ext/wasm/api/sqlite3-api-cleanup.js 5d22d1d3818ecacb23bfa223d5970cd0617d8cdbb48c8bc4bbd463f05b021a99
|
||||||
F ext/wasm/api/sqlite3-api-glue.js b15a51b88aaa472d36bf82d5123dbfdafe8ddf6ca75fba934510e4a20bbe4adb
|
F ext/wasm/api/sqlite3-api-glue.js 474a5e0bf8016e22aefee44ca45408f08f4159c0b782295ac1d86c4556e91d9a
|
||||||
F ext/wasm/api/sqlite3-api-oo1.js 7667d320f6b9fb5252050a2f9c0b1769e11b84dbc0763b999baf65b451b14369
|
F ext/wasm/api/sqlite3-api-oo1.js 066e67f3033e1b300140d431557c468f5cd0a4c17253f156e05b8a2e2c802da7
|
||||||
F ext/wasm/api/sqlite3-api-opfs.js 1b097808b7b081b0f0700cf97d49ef19760e401706168edff9cd45cf9169f541
|
F ext/wasm/api/sqlite3-api-opfs.js 1b097808b7b081b0f0700cf97d49ef19760e401706168edff9cd45cf9169f541
|
||||||
F ext/wasm/api/sqlite3-api-prologue.js a93bd69969eb8b8f9c4cb34e5d86dcbbe5adbeeea39c1cce57194256c5f28434
|
F ext/wasm/api/sqlite3-api-prologue.js 9b0c5150f0129b3dc558fec0bfc9c8bf7ebda402b58965bcf98b2ed117b55239
|
||||||
F ext/wasm/api/sqlite3-api-worker1.js 7f4f46cb6b512a48572d7567233896e6a9c46570c44bdc3d13419730c7c221c8
|
F ext/wasm/api/sqlite3-api-worker1.js 7f4f46cb6b512a48572d7567233896e6a9c46570c44bdc3d13419730c7c221c8
|
||||||
F ext/wasm/api/sqlite3-wasi.h 25356084cfe0d40458a902afb465df8c21fc4152c1d0a59b563a3fba59a068f9
|
F ext/wasm/api/sqlite3-wasi.h 25356084cfe0d40458a902afb465df8c21fc4152c1d0a59b563a3fba59a068f9
|
||||||
F ext/wasm/api/sqlite3-wasm.c d72aecf0e50a4403402095ef4e8d6a814fdc2256589944c1dc974c70d2f65b7e
|
F ext/wasm/api/sqlite3-wasm.c 2a0f9e4bf1b141a787918951360601128d6a0a190a31a8e5cfe237c99fa640c6
|
||||||
F ext/wasm/batch-runner.html c363032aba7a525920f61f8be112a29459f73f07e46f0ba3b7730081a617826e
|
F ext/wasm/batch-runner.html c363032aba7a525920f61f8be112a29459f73f07e46f0ba3b7730081a617826e
|
||||||
F ext/wasm/batch-runner.js ce92650a6681586c89bef26ceae96674a55ca5a9727815202ca62e1a00ff5015
|
F ext/wasm/batch-runner.js ce92650a6681586c89bef26ceae96674a55ca5a9727815202ca62e1a00ff5015
|
||||||
F ext/wasm/common/SqliteTestUtil.js 647bf014bd30bdd870a7e9001e251d12fc1c9ec9ce176a1004b838a4b33c5c05
|
F ext/wasm/common/SqliteTestUtil.js 647bf014bd30bdd870a7e9001e251d12fc1c9ec9ce176a1004b838a4b33c5c05
|
||||||
F ext/wasm/common/emscripten.css 3d253a6fdb8983a2ac983855bfbdd4b6fa1ff267c28d69513dd6ef1f289ada3f
|
F ext/wasm/common/emscripten.css 3d253a6fdb8983a2ac983855bfbdd4b6fa1ff267c28d69513dd6ef1f289ada3f
|
||||||
F ext/wasm/common/testing.css 3a5143699c2b73a85b962271e1a9b3241b30d90e30d895e4f55665e648572962
|
F ext/wasm/common/testing.css 3a5143699c2b73a85b962271e1a9b3241b30d90e30d895e4f55665e648572962
|
||||||
F ext/wasm/common/whwasmutil.js d2557d6ef1ebaaf3c9a0cea2231fd398b0d8ca8129b51580af1c92f8d04335e0
|
F ext/wasm/common/whwasmutil.js cdb33775fdc55c9b1cbb617d22d24b4a29dc9c1389b827a5b14886a291480d70
|
||||||
F ext/wasm/demo-123-worker.html e419b66495d209b5211ec64903b4cfb3ca7df20d652b41fcd28bf018a773234f
|
F ext/wasm/demo-123-worker.html e419b66495d209b5211ec64903b4cfb3ca7df20d652b41fcd28bf018a773234f
|
||||||
F ext/wasm/demo-123.html aa281d33b7eefa755f3122b7b5a18f39a42dc5fb69c8879171bf14b4c37c4ec4
|
F ext/wasm/demo-123.html aa281d33b7eefa755f3122b7b5a18f39a42dc5fb69c8879171bf14b4c37c4ec4
|
||||||
F ext/wasm/demo-123.js 536579fd587974c2511c5bf82034b253d4fdeceabb726927ad7599ef6b7578e8
|
F ext/wasm/demo-123.js 536579fd587974c2511c5bf82034b253d4fdeceabb726927ad7599ef6b7578e8
|
||||||
@ -530,7 +530,7 @@ F ext/wasm/test-opfs-vfs.js a59ff9210b17d46b0c6fbf6a0ba60143c033327865f2e556e14f
|
|||||||
F ext/wasm/testing-worker1-promiser.html 6eaec6e04a56cf24cf4fa8ef49d78ce8905dde1354235c9125dca6885f7ce893
|
F ext/wasm/testing-worker1-promiser.html 6eaec6e04a56cf24cf4fa8ef49d78ce8905dde1354235c9125dca6885f7ce893
|
||||||
F ext/wasm/testing-worker1-promiser.js bd788e33c1807e0a6dda9c9a9d784bd3350ca49c9dd8ae2cc8719b506b6e013e
|
F ext/wasm/testing-worker1-promiser.js bd788e33c1807e0a6dda9c9a9d784bd3350ca49c9dd8ae2cc8719b506b6e013e
|
||||||
F ext/wasm/testing1.html 50575755e43232dbe4c2f97c9086b3118eb91ec2ee1fae931e6d7669fb17fcae
|
F ext/wasm/testing1.html 50575755e43232dbe4c2f97c9086b3118eb91ec2ee1fae931e6d7669fb17fcae
|
||||||
F ext/wasm/testing1.js 51ef1ced0669f804787ce96f19dcf64367550a7923a998514be56076326988d7
|
F ext/wasm/testing1.js bdea170b16189028c1f63023c620df52ddf31ed416bad56d729c60031b1e27ae
|
||||||
F ext/wasm/testing2.html a66951c38137ff1d687df79466351f3c734fa9c6d9cce71d3cf97c291b2167e3
|
F ext/wasm/testing2.html a66951c38137ff1d687df79466351f3c734fa9c6d9cce71d3cf97c291b2167e3
|
||||||
F ext/wasm/testing2.js 88f40ef3cd8201bdadd120a711c36bbf0ce56cc0eab1d5e7debb71fed7822494
|
F ext/wasm/testing2.js 88f40ef3cd8201bdadd120a711c36bbf0ce56cc0eab1d5e7debb71fed7822494
|
||||||
F ext/wasm/wasmfs.make 3cce1820006196de140f90f2da4b4ea657083fb5bfee7d125be43f7a85748c8f
|
F ext/wasm/wasmfs.make 3cce1820006196de140f90f2da4b4ea657083fb5bfee7d125be43f7a85748c8f
|
||||||
@ -2029,8 +2029,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 f9db664f756f3707afcb5dce87f6d946625848f27ea84337af68de72d4ad6c6b
|
P 8b3bc7313aff551e5ee0b7aeb927095cf19b9b96abbdd922066c130656b8aa7d
|
||||||
R 8201c0f212d8f73dc23b363b8bdcd606
|
R a0d2cb1d1b18288fcfda68347c547fdd
|
||||||
U stephan
|
U stephan
|
||||||
Z 7616e552f06f17aa339add7ed573ed79
|
Z 5fc153c99e29258d724616b67e70d32b
|
||||||
# Remove this line to create a well-formed Fossil manifest.
|
# Remove this line to create a well-formed Fossil manifest.
|
||||||
|
@ -1 +1 @@
|
|||||||
8b3bc7313aff551e5ee0b7aeb927095cf19b9b96abbdd922066c130656b8aa7d
|
eb5726677a727a958df11f1fba078d30c7c0ba2a9bdb158e8641b35b5f971af3
|
Reference in New Issue
Block a user