mirror of
https://github.com/sqlite/sqlite.git
synced 2025-07-29 08:01:23 +03:00
Reimplement JS's sqlite3_bind_text/blob() with hand-written bindings to permit more flexible inputs. Add automated JS-to-C function conversion to sqlite3_busy_handler(). sqlite3.wasm.xWrap()'s '*' argument conversion no longer treats JS strings as C-strings: those conversions require explicit opt-in via the 'string' converter (or equivalent).
FossilOrigin-Name: 96ba44946b3e88b6aa305c4363cbbfeab0d9120b3d8c4d2587d68b9293ea7cc6
This commit is contained in:
@ -42,10 +42,8 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
|
|||||||
wasm.bindingSignatures = [
|
wasm.bindingSignatures = [
|
||||||
// Please keep these sorted by function name!
|
// Please keep these sorted by function name!
|
||||||
["sqlite3_aggregate_context","void*", "sqlite3_context*", "int"],
|
["sqlite3_aggregate_context","void*", "sqlite3_context*", "int"],
|
||||||
["sqlite3_bind_blob","int", "sqlite3_stmt*", "int", "*", "int", "*"
|
/* sqlite3_bind_blob() and sqlite3_bind_text() have hand-written
|
||||||
/* TODO: we should arguably write a custom wrapper which knows
|
bindings to permit more flexible inputs. */
|
||||||
how to handle Blob, TypedArrays, and JS strings. */
|
|
||||||
],
|
|
||||||
["sqlite3_bind_double","int", "sqlite3_stmt*", "int", "f64"],
|
["sqlite3_bind_double","int", "sqlite3_stmt*", "int", "f64"],
|
||||||
["sqlite3_bind_int","int", "sqlite3_stmt*", "int", "int"],
|
["sqlite3_bind_int","int", "sqlite3_stmt*", "int", "int"],
|
||||||
["sqlite3_bind_null",undefined, "sqlite3_stmt*", "int"],
|
["sqlite3_bind_null",undefined, "sqlite3_stmt*", "int"],
|
||||||
@ -53,16 +51,14 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
|
|||||||
["sqlite3_bind_parameter_index","int", "sqlite3_stmt*", "string"],
|
["sqlite3_bind_parameter_index","int", "sqlite3_stmt*", "string"],
|
||||||
["sqlite3_bind_pointer", "int",
|
["sqlite3_bind_pointer", "int",
|
||||||
"sqlite3_stmt*", "int", "*", "string:static", "*"],
|
"sqlite3_stmt*", "int", "*", "string:static", "*"],
|
||||||
["sqlite3_bind_text","int", "sqlite3_stmt*", "int", "string", "int", "*"
|
["sqlite3_busy_handler","int", [
|
||||||
/* We should arguably create a hand-written binding of
|
"sqlite3*",
|
||||||
bind_text() which does more flexible text conversion, along
|
new wasm.xWrap.FuncPtrAdapter({
|
||||||
the lines of sqlite3_prepare_v3(). The slightly problematic
|
signature: 'i(pi)',
|
||||||
part is the final argument (text destructor). */
|
contextKey: (argIndex,argv)=>'sqlite3@'+argv[0]
|
||||||
],
|
}),
|
||||||
//["sqlite3_busy_handler","int", "sqlite3*", "*", "*"],
|
"*"
|
||||||
// ^^^^ TODO: custom binding which auto-converts JS function arg
|
]],
|
||||||
// to a WASM function, noting that calling it multiple times
|
|
||||||
// would introduce a leak.
|
|
||||||
["sqlite3_busy_timeout","int", "sqlite3*", "int"],
|
["sqlite3_busy_timeout","int", "sqlite3*", "int"],
|
||||||
["sqlite3_close_v2", "int", "sqlite3*"],
|
["sqlite3_close_v2", "int", "sqlite3*"],
|
||||||
["sqlite3_changes", "int", "sqlite3*"],
|
["sqlite3_changes", "int", "sqlite3*"],
|
||||||
@ -779,6 +775,7 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
|
|||||||
|
|
||||||
if(1){/* Special-case handling of sqlite3_prepare_v2() and
|
if(1){/* Special-case handling of sqlite3_prepare_v2() and
|
||||||
sqlite3_prepare_v3() */
|
sqlite3_prepare_v3() */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Helper for string:flexible conversions which require a
|
Helper for string:flexible conversions which require a
|
||||||
byte-length counterpart argument. Passed a value and its
|
byte-length counterpart argument. Passed a value and its
|
||||||
@ -802,32 +799,33 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
|
|||||||
/**
|
/**
|
||||||
Scope-local holder of the two impls of sqlite3_prepare_v2/v3().
|
Scope-local holder of the two impls of sqlite3_prepare_v2/v3().
|
||||||
*/
|
*/
|
||||||
const __prepare = Object.create(null);
|
const __prepare = {
|
||||||
/**
|
/**
|
||||||
This binding expects a JS string as its 2nd argument and
|
This binding expects a JS string as its 2nd argument and
|
||||||
null as its final argument. In order to compile multiple
|
null as its final argument. In order to compile multiple
|
||||||
statements from a single string, the "full" impl (see
|
statements from a single string, the "full" impl (see
|
||||||
below) must be used.
|
below) must be used.
|
||||||
*/
|
*/
|
||||||
__prepare.basic = wasm.xWrap('sqlite3_prepare_v3',
|
basic: wasm.xWrap('sqlite3_prepare_v3',
|
||||||
"int", ["sqlite3*", "string",
|
"int", ["sqlite3*", "string",
|
||||||
"int"/*ignored for this impl!*/,
|
"int"/*ignored for this impl!*/,
|
||||||
"int", "**",
|
"int", "**",
|
||||||
"**"/*MUST be 0 or null or undefined!*/]);
|
"**"/*MUST be 0 or null or undefined!*/]),
|
||||||
/**
|
/**
|
||||||
Impl which requires that the 2nd argument be a pointer
|
Impl which requires that the 2nd argument be a pointer
|
||||||
to the SQL string, instead of being converted to a
|
to the SQL string, instead of being converted to a
|
||||||
string. This variant is necessary for cases where we
|
string. This variant is necessary for cases where we
|
||||||
require a non-NULL value for the final argument
|
require a non-NULL value for the final argument
|
||||||
(exec()'ing multiple statements from one input
|
(exec()'ing multiple statements from one input
|
||||||
string). For simpler cases, where only the first
|
string). For simpler cases, where only the first
|
||||||
statement in the SQL string is required, the wrapper
|
statement in the SQL string is required, the wrapper
|
||||||
named sqlite3_prepare_v2() is sufficient and easier to
|
named sqlite3_prepare_v2() is sufficient and easier to
|
||||||
use because it doesn't require dealing with pointers.
|
use because it doesn't require dealing with pointers.
|
||||||
*/
|
*/
|
||||||
__prepare.full = wasm.xWrap('sqlite3_prepare_v3',
|
full: wasm.xWrap('sqlite3_prepare_v3',
|
||||||
"int", ["sqlite3*", "*", "int", "int",
|
"int", ["sqlite3*", "*", "int", "int",
|
||||||
"**", "**"]);
|
"**", "**"])
|
||||||
|
};
|
||||||
|
|
||||||
/* Documented in the capi object's initializer. */
|
/* Documented in the capi object's initializer. */
|
||||||
capi.sqlite3_prepare_v3 = function f(pDb, sql, sqlLen, prepFlags, ppStmt, pzTail){
|
capi.sqlite3_prepare_v3 = function f(pDb, sql, sqlLen, prepFlags, ppStmt, pzTail){
|
||||||
@ -852,7 +850,80 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
|
|||||||
? capi.sqlite3_prepare_v3(pDb, sql, sqlLen, 0, ppStmt, pzTail)
|
? capi.sqlite3_prepare_v3(pDb, sql, sqlLen, 0, ppStmt, pzTail)
|
||||||
: __dbArgcMismatch(pDb,"sqlite3_prepare_v2",f.length);
|
: __dbArgcMismatch(pDb,"sqlite3_prepare_v2",f.length);
|
||||||
};
|
};
|
||||||
}/*sqlite3_prepare_v2/v3()*/;
|
|
||||||
|
}/*sqlite3_prepare_v2/v3()*/
|
||||||
|
|
||||||
|
{/*sqlite3_bind_text/blob()*/
|
||||||
|
const __bindText = wasm.xWrap("sqlite3_bind_text", "int", [
|
||||||
|
"sqlite3_stmt*", "int", "string", "int", "*"
|
||||||
|
]);
|
||||||
|
const __bindBlob = wasm.xWrap("sqlite3_bind_blob", "int", [
|
||||||
|
"sqlite3_stmt*", "int", "*", "int", "*"
|
||||||
|
]);
|
||||||
|
|
||||||
|
/** Documented in the capi object's initializer. */
|
||||||
|
capi.sqlite3_bind_text = function f(pStmt, iCol, text, nText, xDestroy){
|
||||||
|
if(f.length!==arguments.length){
|
||||||
|
return __dbArgcMismatch(capi.sqlite3_db_handle(pStmt),
|
||||||
|
"sqlite3_bind_text", f.length);
|
||||||
|
}else if(wasm.isPtr(text) || null===text){
|
||||||
|
return __bindText(pStmt, iCol, text, nText, xDestroy);
|
||||||
|
}else if(text instanceof ArrayBuffer){
|
||||||
|
text = new Uint8Array(text);
|
||||||
|
}else if(Array.isArray(pMem)){
|
||||||
|
text = pMem.join('');
|
||||||
|
}
|
||||||
|
let p, n;
|
||||||
|
try {
|
||||||
|
if(util.isSQLableTypedArray(text)){
|
||||||
|
p = wasm.allocFromTypedArray(text);
|
||||||
|
n = text.byteLength;
|
||||||
|
}else if('string'===typeof text){
|
||||||
|
[p, n] = wasm.allocCString(text);
|
||||||
|
}else{
|
||||||
|
return util.sqlite3_wasm_db_error(
|
||||||
|
capi.sqlite3_db_handle(pStmt), capi.SQLITE_MISUSE,
|
||||||
|
"Invalid 3rd argument type for sqlite3_bind_text()."
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return __bindText(pStmt, iCol, p, n, capi.SQLITE_TRANSIENT);
|
||||||
|
}finally{
|
||||||
|
wasm.dealloc(p);
|
||||||
|
}
|
||||||
|
}/*sqlite3_bind_text()*/;
|
||||||
|
|
||||||
|
/** Documented in the capi object's initializer. */
|
||||||
|
capi.sqlite3_bind_blob = function f(pStmt, iCol, pMem, nMem, xDestroy){
|
||||||
|
if(f.length!==arguments.length){
|
||||||
|
return __dbArgcMismatch(capi.sqlite3_db_handle(pStmt),
|
||||||
|
"sqlite3_bind_blob", f.length);
|
||||||
|
}else if(wasm.isPtr(pMem) || null===pMem){
|
||||||
|
return __bindBlob(pStmt, iCol, pMem, nMem, xDestroy);
|
||||||
|
}else if(pMem instanceof ArrayBuffer){
|
||||||
|
pMem = new Uint8Array(pMem);
|
||||||
|
}else if(Array.isArray(pMem)){
|
||||||
|
pMem = pMem.join('');
|
||||||
|
}
|
||||||
|
let p, n;
|
||||||
|
try{
|
||||||
|
if(util.isBindableTypedArray(pMem)){
|
||||||
|
p = wasm.allocFromTypedArray(pMem);
|
||||||
|
n = nMem>=0 ? nMem : pMem.byteLength;
|
||||||
|
}else if('string'===typeof pMem){
|
||||||
|
[p, n] = wasm.allocCString(pMem);
|
||||||
|
}else{
|
||||||
|
return util.sqlite3_wasm_db_error(
|
||||||
|
capi.sqlite3_db_handle(pStmt), capi.SQLITE_MISUSE,
|
||||||
|
"Invalid 3rd argument type for sqlite3_bind_blob()."
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return __bindBlob(pStmt, iCol, p, n, capi.SQLITE_TRANSIENT);
|
||||||
|
}finally{
|
||||||
|
wasm.dealloc(p);
|
||||||
|
}
|
||||||
|
}/*sqlite3_bind_blob()*/;
|
||||||
|
|
||||||
|
}/*sqlite3_bind_text/blob()*/
|
||||||
|
|
||||||
{/* sqlite3_set_authorizer() */
|
{/* sqlite3_set_authorizer() */
|
||||||
const __ssa = wasm.xWrap("sqlite3_set_authorizer", 'int', [
|
const __ssa = wasm.xWrap("sqlite3_set_authorizer", 'int', [
|
||||||
|
@ -1332,8 +1332,7 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
|
|||||||
}else if(!util.isBindableTypedArray(val)){
|
}else if(!util.isBindableTypedArray(val)){
|
||||||
toss3("Binding a value as a blob requires",
|
toss3("Binding a value as a blob requires",
|
||||||
"that it be a string, Uint8Array, or Int8Array.");
|
"that it be a string, Uint8Array, or Int8Array.");
|
||||||
}else if(1){
|
}else{
|
||||||
/* _Hypothetically_ more efficient than the impl in the 'else' block. */
|
|
||||||
const stack = wasm.scopedAllocPush();
|
const stack = wasm.scopedAllocPush();
|
||||||
try{
|
try{
|
||||||
const pBlob = wasm.scopedAlloc(val.byteLength || 1);
|
const pBlob = wasm.scopedAlloc(val.byteLength || 1);
|
||||||
@ -1343,14 +1342,6 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
|
|||||||
}finally{
|
}finally{
|
||||||
wasm.scopedAllocPop(stack);
|
wasm.scopedAllocPop(stack);
|
||||||
}
|
}
|
||||||
}else{
|
|
||||||
const pBlob = wasm.allocFromTypedArray(val);
|
|
||||||
try{
|
|
||||||
rc = capi.sqlite3_bind_blob(stmt.pointer, ndx, pBlob, val.byteLength,
|
|
||||||
capi.SQLITE_TRANSIENT);
|
|
||||||
}finally{
|
|
||||||
wasm.dealloc(pBlob);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -417,6 +417,92 @@ self.sqlite3ApiBootstrap = function sqlite3ApiBootstrap(
|
|||||||
};
|
};
|
||||||
|
|
||||||
Object.assign(capi, {
|
Object.assign(capi, {
|
||||||
|
/**
|
||||||
|
sqlite3_bind_blob() works exactly like its C counterpart unless
|
||||||
|
its 3rd argument is one of:
|
||||||
|
|
||||||
|
- JS string: the 3rd argument is converted to a C string, the
|
||||||
|
4th argument is ignored, and the C-string's length is used
|
||||||
|
in its place.
|
||||||
|
|
||||||
|
- Array: converted to a string as defined for "flexible
|
||||||
|
strings" and then it's treated as a JS string.
|
||||||
|
|
||||||
|
- Int8Array or Uint8Array: wasm.allocFromTypedArray() is used to
|
||||||
|
conver the memory to the WASM heap. If the 4th argument is
|
||||||
|
0 or greater, it is used as-is, otherwise the array's byteLength
|
||||||
|
value is used. This is an exception to the C API's undefined
|
||||||
|
behavior for a negative 4th argument, but results are undefined
|
||||||
|
if the given 4th argument value is greater than the byteLength
|
||||||
|
of the input array.
|
||||||
|
|
||||||
|
- If it's an ArrayBuffer, it gets wrapped in a Uint8Array and
|
||||||
|
treated as that type.
|
||||||
|
|
||||||
|
In all of those cases, the final argument (text destructor) is
|
||||||
|
ignored and capi.SQLITE_TRANSIENT is assumed.
|
||||||
|
|
||||||
|
A 3rd argument of `null` is treated as if it were a WASM pointer
|
||||||
|
of 0.
|
||||||
|
|
||||||
|
If the 3rd argument is neither a WASM pointer nor one of the
|
||||||
|
above-described types, capi.SQLITE_MISUSE is returned.
|
||||||
|
|
||||||
|
The first argument may be either an `sqlite3_stmt*` WASM
|
||||||
|
pointer or an sqlite3.oo1.Stmt instance.
|
||||||
|
|
||||||
|
For consistency with the C API, it requires the same number of
|
||||||
|
arguments. It returns capi.SQLITE_MISUSE if passed any other
|
||||||
|
argument count.
|
||||||
|
*/
|
||||||
|
sqlite3_bind_blob: undefined/*installed later*/,
|
||||||
|
|
||||||
|
/**
|
||||||
|
sqlite3_bind_text() works exactly like its C counterpart unless
|
||||||
|
its 3rd argument is one of:
|
||||||
|
|
||||||
|
- JS string: the 3rd argument is converted to a C string, the
|
||||||
|
4th argument is ignored, and the C-string's length is used
|
||||||
|
in its place.
|
||||||
|
|
||||||
|
- Array: converted to a string as defined for "flexible
|
||||||
|
strings". The 4th argument is ignored and a value of -1
|
||||||
|
is assumed.
|
||||||
|
|
||||||
|
- Int8Array or Uint8Array: is assumed to contain UTF-8 text, is
|
||||||
|
converted to a string. The 4th argument is ignored, replaced
|
||||||
|
by the array's byteLength value.
|
||||||
|
|
||||||
|
- If it's an ArrayBuffer, it gets wrapped in a Uint8Array and
|
||||||
|
treated as that type.
|
||||||
|
|
||||||
|
In each of those cases, the final argument (text destructor) is
|
||||||
|
ignored and capi.SQLITE_TRANSIENT is assumed.
|
||||||
|
|
||||||
|
A 3rd argument of `null` is treated as if it were a WASM pointer
|
||||||
|
of 0.
|
||||||
|
|
||||||
|
If the 3rd argument is neither a WASM pointer nor one of the
|
||||||
|
above-described types, capi.SQLITE_MISUSE is returned.
|
||||||
|
|
||||||
|
The first argument may be either an `sqlite3_stmt*` WASM
|
||||||
|
pointer or an sqlite3.oo1.Stmt instance.
|
||||||
|
|
||||||
|
For consistency with the C API, it requires the same number of
|
||||||
|
arguments. It returns capi.SQLITE_MISUSE if passed any other
|
||||||
|
argument count.
|
||||||
|
|
||||||
|
If client code needs to bind partial strings, it needs to
|
||||||
|
either parcel the string up before passing it in here or it
|
||||||
|
must pass in a WASM pointer for the 3rd argument and a valid
|
||||||
|
4th-argument value, taking care not to pass a value which
|
||||||
|
truncates a multi-byte UTF-8 character. When passing
|
||||||
|
WASM-format strings, it is important that the final argument be
|
||||||
|
valid or unexpected content can result can result, or even a
|
||||||
|
crash if the application reads past the WASM heap bounds.
|
||||||
|
*/
|
||||||
|
sqlite3_bind_text: undefined/*installed later*/,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
sqlite3_create_function_v2() differs from its native
|
sqlite3_create_function_v2() differs from its native
|
||||||
counterpart only in the following ways:
|
counterpart only in the following ways:
|
||||||
@ -525,18 +611,18 @@ self.sqlite3ApiBootstrap = function sqlite3ApiBootstrap(
|
|||||||
WASM build is compiled with emcc's `-sALLOW_TABLE_GROWTH`
|
WASM build is compiled with emcc's `-sALLOW_TABLE_GROWTH`
|
||||||
flag.
|
flag.
|
||||||
*/
|
*/
|
||||||
sqlite3_create_function_v2: function(
|
sqlite3_create_function_v2: (
|
||||||
pDb, funcName, nArg, eTextRep, pApp,
|
pDb, funcName, nArg, eTextRep, pApp,
|
||||||
xFunc, xStep, xFinal, xDestroy
|
xFunc, xStep, xFinal, xDestroy
|
||||||
){/*installed later*/},
|
)=>{/*installed later*/},
|
||||||
/**
|
/**
|
||||||
Equivalent to passing the same arguments to
|
Equivalent to passing the same arguments to
|
||||||
sqlite3_create_function_v2(), with 0 as the final argument.
|
sqlite3_create_function_v2(), with 0 as the final argument.
|
||||||
*/
|
*/
|
||||||
sqlite3_create_function:function(
|
sqlite3_create_function: (
|
||||||
pDb, funcName, nArg, eTextRep, pApp,
|
pDb, funcName, nArg, eTextRep, pApp,
|
||||||
xFunc, xStep, xFinal
|
xFunc, xStep, xFinal
|
||||||
){/*installed later*/},
|
)=>{/*installed later*/},
|
||||||
/**
|
/**
|
||||||
The sqlite3_create_window_function() JS wrapper differs from
|
The sqlite3_create_window_function() JS wrapper differs from
|
||||||
its native implementation in the exact same way that
|
its native implementation in the exact same way that
|
||||||
@ -544,10 +630,10 @@ self.sqlite3ApiBootstrap = function sqlite3ApiBootstrap(
|
|||||||
xInverse(), is treated identically to xStep() by the wrapping
|
xInverse(), is treated identically to xStep() by the wrapping
|
||||||
layer.
|
layer.
|
||||||
*/
|
*/
|
||||||
sqlite3_create_window_function: function(
|
sqlite3_create_window_function: (
|
||||||
pDb, funcName, nArg, eTextRep, pApp,
|
pDb, funcName, nArg, eTextRep, pApp,
|
||||||
xStep, xFinal, xValue, xInverse, xDestroy
|
xStep, xFinal, xValue, xInverse, xDestroy
|
||||||
){/*installed later*/},
|
)=>{/*installed later*/},
|
||||||
/**
|
/**
|
||||||
The sqlite3_prepare_v3() binding handles two different uses
|
The sqlite3_prepare_v3() binding handles two different uses
|
||||||
with differing JS/WASM semantics:
|
with differing JS/WASM semantics:
|
||||||
@ -669,7 +755,7 @@ self.sqlite3ApiBootstrap = function sqlite3ApiBootstrap(
|
|||||||
toss3,
|
toss3,
|
||||||
typedArrayPart
|
typedArrayPart
|
||||||
};
|
};
|
||||||
|
|
||||||
Object.assign(wasm, {
|
Object.assign(wasm, {
|
||||||
/**
|
/**
|
||||||
Emscripten APIs have a deep-seated assumption that all pointers
|
Emscripten APIs have a deep-seated assumption that all pointers
|
||||||
|
@ -1406,7 +1406,8 @@ self.WhWasmUtilInstaller = function(target){
|
|||||||
.set('int', xArg.get('i32'))
|
.set('int', xArg.get('i32'))
|
||||||
.set('null', (i)=>i)
|
.set('null', (i)=>i)
|
||||||
.set(null, xArg.get('null'))
|
.set(null, xArg.get('null'))
|
||||||
.set('**', __xArgPtr);
|
.set('**', __xArgPtr)
|
||||||
|
.set('*', __xArgPtr);
|
||||||
xResult.set('*', __xArgPtr)
|
xResult.set('*', __xArgPtr)
|
||||||
.set('pointer', __xArgPtr)
|
.set('pointer', __xArgPtr)
|
||||||
.set('number', (v)=>Number(v))
|
.set('number', (v)=>Number(v))
|
||||||
@ -1448,23 +1449,23 @@ self.WhWasmUtilInstaller = function(target){
|
|||||||
if('string'===typeof v) return target.scopedAllocCString(v);
|
if('string'===typeof v) return target.scopedAllocCString(v);
|
||||||
return v ? __xArgPtr(v) : null;
|
return v ? __xArgPtr(v) : null;
|
||||||
};
|
};
|
||||||
xArg.set('string', __xArgString);
|
xArg.set('string', __xArgString)
|
||||||
xArg.set('utf8', __xArgString);
|
.set('utf8', __xArgString)
|
||||||
xArg.set('pointer', __xArgString);
|
.set('pointer', __xArgString);
|
||||||
xArg.set('*', __xArgString);
|
//xArg.set('*', __xArgString);
|
||||||
|
|
||||||
xResult.set('string', (i)=>target.cstrToJs(i));
|
xResult.set('string', (i)=>target.cstrToJs(i))
|
||||||
xResult.set('utf8', xResult.get('string'));
|
.set('utf8', xResult.get('string'))
|
||||||
xResult.set('string:dealloc', (i)=>{
|
.set('string:dealloc', (i)=>{
|
||||||
try { return i ? target.cstrToJs(i) : null }
|
try { return i ? target.cstrToJs(i) : null }
|
||||||
finally{ target.dealloc(i) }
|
finally{ target.dealloc(i) }
|
||||||
});
|
})
|
||||||
xResult.set('utf8:dealloc', xResult.get('string:dealloc'));
|
.set('utf8:dealloc', xResult.get('string:dealloc'))
|
||||||
xResult.set('json', (i)=>JSON.parse(target.cstrToJs(i)));
|
.set('json', (i)=>JSON.parse(target.cstrToJs(i)))
|
||||||
xResult.set('json:dealloc', (i)=>{
|
.set('json:dealloc', (i)=>{
|
||||||
try{ return i ? JSON.parse(target.cstrToJs(i)) : null }
|
try{ return i ? JSON.parse(target.cstrToJs(i)) : null }
|
||||||
finally{ target.dealloc(i) }
|
finally{ target.dealloc(i) }
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Internal-use-only base class for FuncPtrAdapter and potentially
|
Internal-use-only base class for FuncPtrAdapter and potentially
|
||||||
@ -1748,10 +1749,13 @@ self.WhWasmUtilInstaller = function(target){
|
|||||||
- `N*` (args): a type name in the form `N*`, where N is a numeric
|
- `N*` (args): a type name in the form `N*`, where N is a numeric
|
||||||
type name, is treated the same as WASM pointer.
|
type name, is treated the same as WASM pointer.
|
||||||
|
|
||||||
- `*` and `pointer` (args): have multple semantics. They
|
- `*` and `pointer` (args): are assumed to be WASM pointer values
|
||||||
behave exactly as described below for `string` args.
|
and are returned coerced to an appropriately-sized pointer
|
||||||
|
value (i32 or i64). Non-numeric values will coerce to 0 and
|
||||||
|
out-of-range values will have undefined results (just as with
|
||||||
|
any pointer misuse).
|
||||||
|
|
||||||
- `*` and `pointer` (results): are aliases for the current
|
- `*` and `pointer` (results): aliases for the current
|
||||||
WASM pointer numeric type.
|
WASM pointer numeric type.
|
||||||
|
|
||||||
- `**` (args): is simply a descriptive alias for the WASM pointer
|
- `**` (args): is simply a descriptive alias for the WASM pointer
|
||||||
|
18
manifest
18
manifest
@ -1,5 +1,5 @@
|
|||||||
C Internal\sJS\scleanups.\sCorrect\spart\sof\s[ac136925a645]\sto\saccount\sfor\sthe\seTextRep\sflag\sbeing\sable\sto\shold\sflags\sother\sthan\sthe\sencoding.
|
C Reimplement\sJS's\ssqlite3_bind_text/blob()\swith\shand-written\sbindings\sto\spermit\smore\sflexible\sinputs.\sAdd\sautomated\sJS-to-C\sfunction\sconversion\sto\ssqlite3_busy_handler().\ssqlite3.wasm.xWrap()'s\s'*'\sargument\sconversion\sno\slonger\streats\sJS\sstrings\sas\sC-strings:\sthose\sconversions\srequire\sexplicit\sopt-in\svia\sthe\s'string'\sconverter\s(or\sequivalent).
|
||||||
D 2022-12-23T21:10:49.493
|
D 2022-12-23T23:46:33.608
|
||||||
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
|
||||||
@ -503,9 +503,9 @@ F ext/wasm/api/post-js-footer.js cd0a8ec768501d9bd45d325ab0442037fb0e33d1f3b4f08
|
|||||||
F ext/wasm/api/post-js-header.js 47b6b281f39ad59fa6e8b658308cd98ea292c286a68407b35ff3ed9cfd281a62
|
F ext/wasm/api/post-js-header.js 47b6b281f39ad59fa6e8b658308cd98ea292c286a68407b35ff3ed9cfd281a62
|
||||||
F ext/wasm/api/pre-js.c-pp.js b88499dc303c21fc3f55f2c364a0f814f587b60a95784303881169f9e91c1d5f
|
F ext/wasm/api/pre-js.c-pp.js b88499dc303c21fc3f55f2c364a0f814f587b60a95784303881169f9e91c1d5f
|
||||||
F ext/wasm/api/sqlite3-api-cleanup.js 680d5ccfff54459db136a49b2199d9f879c8405d9c99af1dda0cc5e7c29056f4
|
F ext/wasm/api/sqlite3-api-cleanup.js 680d5ccfff54459db136a49b2199d9f879c8405d9c99af1dda0cc5e7c29056f4
|
||||||
F ext/wasm/api/sqlite3-api-glue.js f50211dc11f1debf972cdaea87cb4df9772022828072e7100cf5025d1dca2a78
|
F ext/wasm/api/sqlite3-api-glue.js f0651048a2601bf79f7f39c2c855f6417e65548417f5019ac9ac2ffb2463f2b9
|
||||||
F ext/wasm/api/sqlite3-api-oo1.js 4cce9671e8a31ac9b76bd8559e7827ccc2b121734e460fa9c7d243735a771ec8
|
F ext/wasm/api/sqlite3-api-oo1.js c2a3e310f993a632b6c5da0c49b0635863a73df60c4f9fc0a30648f25e4ec32a
|
||||||
F ext/wasm/api/sqlite3-api-prologue.js 789639d256e3134563c5c9be25ade28b40e06e783885d26cccc01cd1ed4b820d
|
F ext/wasm/api/sqlite3-api-prologue.js 683956ea6ab5e0132db48bb693a6bb9dd92f36c8c0902af36572e9b29006ac6d
|
||||||
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 7795b84b66a7a8dedc791340709b310bb497c3c72a80bef364fa2a58e2ddae3f
|
F ext/wasm/api/sqlite3-opfs-async-proxy.js 7795b84b66a7a8dedc791340709b310bb497c3c72a80bef364fa2a58e2ddae3f
|
||||||
@ -521,7 +521,7 @@ F ext/wasm/c-pp.c 92285f7bce67ed7b7020b40fde8ed0982c442b63dc33df9dfd4b658d4a6c07
|
|||||||
F ext/wasm/common/SqliteTestUtil.js d8bf97ecb0705a2299765c8fc9e11b1a5ac7f10988bbf375a6558b7ca287067b
|
F ext/wasm/common/SqliteTestUtil.js d8bf97ecb0705a2299765c8fc9e11b1a5ac7f10988bbf375a6558b7ca287067b
|
||||||
F ext/wasm/common/emscripten.css 11bd104b6c0d597c67d40cc8ecc0a60dae2b965151e3b6a37fa5708bac3acd15
|
F ext/wasm/common/emscripten.css 11bd104b6c0d597c67d40cc8ecc0a60dae2b965151e3b6a37fa5708bac3acd15
|
||||||
F ext/wasm/common/testing.css 0ff15602a3ab2bad8aef2c3bd120c7ee3fd1c2054ad2ace7e214187ae68d926f
|
F ext/wasm/common/testing.css 0ff15602a3ab2bad8aef2c3bd120c7ee3fd1c2054ad2ace7e214187ae68d926f
|
||||||
F ext/wasm/common/whwasmutil.js 97807770ec452fdcaa48509c5decd3a2c1e3001164a62a3223a347f66967533e
|
F ext/wasm/common/whwasmutil.js 700fb1b702986522d2177fe8247bfbab3040e82cb4f6c35e929c4c85fbd7ffc5
|
||||||
F ext/wasm/demo-123-worker.html a0b58d9caef098a626a1a1db567076fca4245e8d60ba94557ede8684350a81ed
|
F ext/wasm/demo-123-worker.html a0b58d9caef098a626a1a1db567076fca4245e8d60ba94557ede8684350a81ed
|
||||||
F ext/wasm/demo-123.html 8c70a412ce386bd3796534257935eb1e3ea5c581e5d5aea0490b8232e570a508
|
F ext/wasm/demo-123.html 8c70a412ce386bd3796534257935eb1e3ea5c581e5d5aea0490b8232e570a508
|
||||||
F ext/wasm/demo-123.js ebae30756585bca655b4ab2553ec9236a87c23ad24fc8652115dcedb06d28df6
|
F ext/wasm/demo-123.js ebae30756585bca655b4ab2553ec9236a87c23ad24fc8652115dcedb06d28df6
|
||||||
@ -2067,8 +2067,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 deffe6fb211410fa1a1fbca824a52b4e09b54d4b4f4a4e12d71c9e4b7e8606fb
|
P 1dfc03ab1e0269807beef27bf884ab9ead7553d4a5f6ed213f812d7fa052045f
|
||||||
R 537077e8e7a576993086a957d5c52d05
|
R 0557f08bf576b7be78ec588d2742348d
|
||||||
U stephan
|
U stephan
|
||||||
Z 379d99233453fc912eb71dcbaf16b8ce
|
Z 4e12d5aedea06f895991428eb871a6d7
|
||||||
# Remove this line to create a well-formed Fossil manifest.
|
# Remove this line to create a well-formed Fossil manifest.
|
||||||
|
@ -1 +1 @@
|
|||||||
1dfc03ab1e0269807beef27bf884ab9ead7553d4a5f6ed213f812d7fa052045f
|
96ba44946b3e88b6aa305c4363cbbfeab0d9120b3d8c4d2587d68b9293ea7cc6
|
Reference in New Issue
Block a user