mirror of
https://github.com/sqlite/sqlite.git
synced 2025-07-29 08:01:23 +03:00
Refactor the sqlite3_value-to-JS conversion from an internal detail to sqlite3.capi.sqlite3_value_to_js() for use with routines like sqlite3_module::xFilter().
FossilOrigin-Name: f6dbf280f99809a80c99337e4c22a86dea7a35ae41ae9a69144c4502385a0a1f
This commit is contained in:
@ -372,49 +372,19 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
|
||||
}/*__udfSetResult()*/;
|
||||
|
||||
const __udfConvertArgs = function(argc, pArgv){
|
||||
let i, pVal, valType, arg;
|
||||
let i;
|
||||
const tgt = [];
|
||||
for(i = 0; i < argc; ++i){
|
||||
pVal = wasm.peekPtr(pArgv + (wasm.ptrSizeof * i));
|
||||
/**
|
||||
Curiously: despite ostensibly requiring 8-byte
|
||||
alignment, the pArgv array is parcelled into chunks of
|
||||
4 bytes (1 pointer each). The values those point to
|
||||
have 8-byte alignment but the individual argv entries
|
||||
do not.
|
||||
*/
|
||||
valType = capi.sqlite3_value_type(pVal);
|
||||
switch(valType){
|
||||
case capi.SQLITE_INTEGER:
|
||||
if(wasm.bigIntEnabled){
|
||||
arg = capi.sqlite3_value_int64(pVal);
|
||||
if(util.bigIntFitsDouble(arg)) arg = Number(arg);
|
||||
}
|
||||
else arg = capi.sqlite3_value_double(pVal)/*yes, double, for larger integers*/;
|
||||
break;
|
||||
case capi.SQLITE_FLOAT:
|
||||
arg = capi.sqlite3_value_double(pVal);
|
||||
break;
|
||||
case capi.SQLITE_TEXT:
|
||||
arg = capi.sqlite3_value_text(pVal);
|
||||
break;
|
||||
case capi.SQLITE_BLOB:{
|
||||
const n = capi.sqlite3_value_bytes(pVal);
|
||||
const pBlob = capi.sqlite3_value_blob(pVal);
|
||||
if(n && !pBlob) sqlite3.WasmAllocError.toss(
|
||||
"Cannot allocate memory for blob argument of",n,"byte(s)"
|
||||
);
|
||||
arg = n ? wasm.heap8u().slice(pBlob, pBlob + Number(n)) : null;
|
||||
break;
|
||||
}
|
||||
case capi.SQLITE_NULL:
|
||||
arg = null; break;
|
||||
default:
|
||||
toss3("Unhandled sqlite3_value_type()",valType,
|
||||
"is possibly indicative of incorrect",
|
||||
"pointer size assumption.");
|
||||
}
|
||||
tgt.push(arg);
|
||||
*/
|
||||
tgt.push(capi.sqlite3_value_to_js(
|
||||
wasm.peekPtr(pArgv + (wasm.ptrSizeof * i))
|
||||
));
|
||||
}
|
||||
return tgt;
|
||||
}/*__udfConvertArgs()*/;
|
||||
|
@ -1658,6 +1658,48 @@ self.sqlite3ApiBootstrap = function sqlite3ApiBootstrap(
|
||||
}
|
||||
}.bind(Object.create(null));
|
||||
|
||||
/**
|
||||
Given a (sqlite3_value*), this function attempts to convert it
|
||||
to an equivalent JS value with as much fidelity as feasible and
|
||||
return it. Throws if it cannot determine any sensible
|
||||
conversion, but that would be indicative of a serious error.
|
||||
*/
|
||||
capi.sqlite3_value_to_js = function(pVal){
|
||||
let arg;
|
||||
const valType = capi.sqlite3_value_type(pVal);
|
||||
switch(valType){
|
||||
case capi.SQLITE_INTEGER:
|
||||
if(wasm.bigIntEnabled){
|
||||
arg = capi.sqlite3_value_int64(pVal);
|
||||
if(util.bigIntFitsDouble(arg)) arg = Number(arg);
|
||||
}
|
||||
else arg = capi.sqlite3_value_double(pVal)/*yes, double, for larger integers*/;
|
||||
break;
|
||||
case capi.SQLITE_FLOAT:
|
||||
arg = capi.sqlite3_value_double(pVal);
|
||||
break;
|
||||
case capi.SQLITE_TEXT:
|
||||
arg = capi.sqlite3_value_text(pVal);
|
||||
break;
|
||||
case capi.SQLITE_BLOB:{
|
||||
const n = capi.sqlite3_value_bytes(pVal);
|
||||
const pBlob = capi.sqlite3_value_blob(pVal);
|
||||
if(n && !pBlob) sqlite3.WasmAllocError.toss(
|
||||
"Cannot allocate memory for blob argument of",n,"byte(s)"
|
||||
);
|
||||
arg = n ? wasm.heap8u().slice(pBlob, pBlob + Number(n)) : null;
|
||||
break;
|
||||
}
|
||||
case capi.SQLITE_NULL:
|
||||
arg = null; break;
|
||||
default:
|
||||
toss3("Unhandled sqlite3_value_type()",valType,
|
||||
"is possibly indicative of incorrect",
|
||||
"pointer size assumption.");
|
||||
}
|
||||
return arg;
|
||||
};
|
||||
|
||||
/* The remainder of the API will be set up in later steps. */
|
||||
const sqlite3 = {
|
||||
WasmAllocError: WasmAllocError,
|
||||
|
@ -316,13 +316,11 @@ self.WhWasmUtilInstaller = function(target){
|
||||
|
||||
Throws if passed an invalid n.
|
||||
|
||||
Pedantic side note: the name "heap" is a bit of a misnomer. In an
|
||||
Emscripten environment, the memory managed via the stack
|
||||
allocation API is in the same Memory object as the heap (which
|
||||
makes sense because otherwise arbitrary pointer X would be
|
||||
ambiguous: is it in the heap or the stack?).
|
||||
Pedantic side note: the name "heap" is a bit of a misnomer. In a
|
||||
WASM environment, the stack and heap memory are all accessed via
|
||||
the same view(s) of the memory.
|
||||
*/
|
||||
target.heapForSize = function(n,unsigned = false){
|
||||
target.heapForSize = function(n,unsigned = true){
|
||||
let ctor;
|
||||
const c = (cache.memory && cache.heapSize === cache.memory.buffer.byteLength)
|
||||
? cache : heapWrappers();
|
||||
|
@ -212,8 +212,8 @@
|
||||
const renderFunc = function(name){
|
||||
let lbl = name+'()';
|
||||
const e = eLi(lbl, eFuncs);;
|
||||
if(name.startsWith('sqlite3_js')
|
||||
|| name.startsWith('sqlite3_wasm')){
|
||||
if(name.indexOf('_js')>0
|
||||
|| name.indexOf('_wasm')>0){
|
||||
e.classList.add('func-wasm');
|
||||
}
|
||||
};
|
||||
|
Reference in New Issue
Block a user