mirror of
https://github.com/sqlite/sqlite.git
synced 2025-07-30 19:03:16 +03:00
Minor JS API tweaks prompted by documenting them.
FossilOrigin-Name: a82e6faaa642b09d241232c4daa67134d4dfa24bf3ca3725740346ca5269b381
This commit is contained in:
@ -50,7 +50,7 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
|
||||
'flexible-string'-type arguments */
|
||||
const xString = wasm.xWrap.argAdapter('string');
|
||||
wasm.xWrap.argAdapter(
|
||||
'flexible-string', (v)=>xString(util.arrayToString(v))
|
||||
'flexible-string', (v)=>xString(util.flexibleString(v))
|
||||
);
|
||||
}
|
||||
|
||||
@ -216,8 +216,8 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
|
||||
"*"/*xInverse*/, "*"/*xDestroy*/]
|
||||
);
|
||||
|
||||
const __setUdfResult = function(pCtx, val){
|
||||
//console.warn("setUdfResult",typeof val, val);
|
||||
const __udfSetResult = function(pCtx, val){
|
||||
//console.warn("udfSetResult",typeof val, val);
|
||||
switch(typeof val) {
|
||||
case 'boolean':
|
||||
capi.sqlite3_result_int(pCtx, val ? 1 : 0);
|
||||
@ -259,9 +259,9 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
|
||||
default:
|
||||
toss3("Don't not how to handle this UDF result value:",(typeof val), val);
|
||||
};
|
||||
}/*__setUdfResult()*/;
|
||||
}/*__udfSetResult()*/;
|
||||
|
||||
const __convertUdfArgs = function(argc, pArgv){
|
||||
const __udfConvertArgs = function(argc, pArgv){
|
||||
let i, pVal, valType, arg;
|
||||
const tgt = [];
|
||||
for(i = 0; i < argc; ++i){
|
||||
@ -307,9 +307,9 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
|
||||
tgt.push(arg);
|
||||
}
|
||||
return tgt;
|
||||
}/*__convertUdfArgs()*/;
|
||||
}/*__udfConvertArgs()*/;
|
||||
|
||||
const __setUdfError = (pCtx, e)=>{
|
||||
const __udfSetError = (pCtx, e)=>{
|
||||
if(e instanceof sqlite3.WasmAllocError){
|
||||
capi.sqlite3_result_error_nomem(pCtx);
|
||||
}else{
|
||||
@ -319,25 +319,25 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
|
||||
|
||||
const __xFunc = function(callback){
|
||||
return function(pCtx, argc, pArgv){
|
||||
try{ __setUdfResult(pCtx, callback(pCtx, ...__convertUdfArgs(argc, pArgv))) }
|
||||
try{ __udfSetResult(pCtx, callback(pCtx, ...__udfConvertArgs(argc, pArgv))) }
|
||||
catch(e){
|
||||
//console.error('xFunc() caught:',e);
|
||||
__setUdfError(pCtx, e);
|
||||
__udfSetError(pCtx, e);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
const __xInverseAndStep = function(callback){
|
||||
return function(pCtx, argc, pArgv){
|
||||
try{ callback(pCtx, ...__convertUdfArgs(argc, pArgv)) }
|
||||
catch(e){ __setUdfError(pCtx, e) }
|
||||
try{ callback(pCtx, ...__udfConvertArgs(argc, pArgv)) }
|
||||
catch(e){ __udfSetError(pCtx, e) }
|
||||
};
|
||||
};
|
||||
|
||||
const __xFinalAndValue = function(callback){
|
||||
return function(pCtx){
|
||||
try{ __setUdfResult(pCtx, callback(pCtx)) }
|
||||
catch(e){ __setUdfError(pCtx, e) }
|
||||
try{ __udfSetResult(pCtx, callback(pCtx)) }
|
||||
catch(e){ __udfSetError(pCtx, e) }
|
||||
};
|
||||
};
|
||||
|
||||
@ -446,7 +446,7 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
|
||||
};
|
||||
/**
|
||||
A helper for UDFs implemented in JS and bound to WASM by the
|
||||
client. Given a JS value, setUdfResult(pCtx,X) calls one of the
|
||||
client. Given a JS value, udfSetResult(pCtx,X) calls one of the
|
||||
sqlite3_result_xyz(pCtx,...) routines, depending on X's data
|
||||
type:
|
||||
|
||||
@ -458,9 +458,9 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
|
||||
|
||||
Anything else triggers sqlite3_result_error().
|
||||
*/
|
||||
capi.sqlite3_create_function_v2.setUdfResult =
|
||||
capi.sqlite3_create_function.setUdfResult =
|
||||
capi.sqlite3_create_window_function.setUdfResult = __setUdfResult;
|
||||
capi.sqlite3_create_function_v2.udfSetResult =
|
||||
capi.sqlite3_create_function.udfSetResult =
|
||||
capi.sqlite3_create_window_function.udfSetResult = __udfSetResult;
|
||||
|
||||
/**
|
||||
A helper for UDFs implemented in JS and bound to WASM by the
|
||||
@ -480,9 +480,9 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
|
||||
The conversion will throw only on allocation error or an internal
|
||||
error.
|
||||
*/
|
||||
capi.sqlite3_create_function_v2.convertUdfArgs =
|
||||
capi.sqlite3_create_function.convertUdfArgs =
|
||||
capi.sqlite3_create_window_function.convertUdfArgs = __convertUdfArgs;
|
||||
capi.sqlite3_create_function_v2.udfConvertArgs =
|
||||
capi.sqlite3_create_function.udfConvertArgs =
|
||||
capi.sqlite3_create_window_function.udfConvertArgs = __udfConvertArgs;
|
||||
|
||||
/**
|
||||
A helper for UDFs implemented in JS and bound to WASM by the
|
||||
@ -492,9 +492,9 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
|
||||
depending on whether the 2nd argument is a
|
||||
sqlite3.WasmAllocError object or not.
|
||||
*/
|
||||
capi.sqlite3_create_function_v2.setUdfError =
|
||||
capi.sqlite3_create_function.setUdfError =
|
||||
capi.sqlite3_create_window_function.setUdfError = __setUdfError;
|
||||
capi.sqlite3_create_function_v2.udfSetError =
|
||||
capi.sqlite3_create_function.udfSetError =
|
||||
capi.sqlite3_create_window_function.udfSetError = __udfSetError;
|
||||
|
||||
}/*sqlite3_create_function_v2() and sqlite3_create_window_function() proxies*/;
|
||||
|
||||
|
@ -260,10 +260,10 @@ self.sqlite3ApiBootstrap = function sqlite3ApiBootstrap(
|
||||
|
||||
/**
|
||||
If v is-a Array, its join('') result is returned. If
|
||||
isSQLableTypedArray(v) then typedArrayToString(v) is
|
||||
isSQLableTypedArray(v) is true then typedArrayToString(v) is
|
||||
returned. Else v is returned as-is.
|
||||
*/
|
||||
const arrayToString = function(v){
|
||||
const flexibleString = function(v){
|
||||
if(isSQLableTypedArray(v)) return typedArrayToString(v);
|
||||
else if(Array.isArray(v)) return v.join('');
|
||||
return v;
|
||||
@ -516,7 +516,7 @@ self.sqlite3ApiBootstrap = function sqlite3ApiBootstrap(
|
||||
removed.
|
||||
*/
|
||||
util:{
|
||||
affirmBindableTypedArray, arrayToString,
|
||||
affirmBindableTypedArray, flexibleString,
|
||||
bigIntFits32, bigIntFits64, bigIntFitsDouble,
|
||||
isBindableTypedArray,
|
||||
isInt32, isSQLableTypedArray, isTypedArray,
|
||||
|
@ -615,9 +615,9 @@ const char * sqlite3_wasm_enum_json(void){
|
||||
StructBinder {
|
||||
M(iVersion,"i");
|
||||
M(xClose,"i(p)");
|
||||
M(xRead,"i(ppij)");
|
||||
M(xWrite,"i(ppij)");
|
||||
M(xTruncate,"i(pj)");
|
||||
M(xRead,"i(ppiI)");
|
||||
M(xWrite,"i(ppiI)");
|
||||
M(xTruncate,"i(pI)");
|
||||
M(xSync,"i(pi)");
|
||||
M(xFileSize,"i(pp)");
|
||||
M(xLock,"i(pi)");
|
||||
@ -630,8 +630,8 @@ const char * sqlite3_wasm_enum_json(void){
|
||||
M(xShmLock,"i(piii)");
|
||||
M(xShmBarrier,"v(p)");
|
||||
M(xShmUnmap,"i(pi)");
|
||||
M(xFetch,"i(pjip)");
|
||||
M(xUnfetch,"i(pjp)");
|
||||
M(xFetch,"i(pIip)");
|
||||
M(xUnfetch,"i(pIp)");
|
||||
} _StructBinder;
|
||||
#undef CurrentStruct
|
||||
|
||||
|
@ -377,17 +377,19 @@ self.WhWasmUtilInstaller = function(target){
|
||||
|
||||
- Emscripten: `x...`, where the first x is a letter representing
|
||||
the result type and subsequent letters represent the argument
|
||||
types. See below.
|
||||
types. Functions with no arguments have only a single
|
||||
letter. See below.
|
||||
|
||||
- Jaccwabyt: `x(...)` where `x` is the letter representing the
|
||||
result type and letters in the parens (if any) represent the
|
||||
argument types. See below.
|
||||
argument types. Functions with no arguments use `x()`. See
|
||||
below.
|
||||
|
||||
Supported letters:
|
||||
|
||||
- `i` = int32
|
||||
- `p` = int32 ("pointer")
|
||||
- `j` = int64
|
||||
- `j` or `I` = int64
|
||||
- `f` = float32
|
||||
- `d` = float64
|
||||
- `v` = void, only legal for use as the result type
|
||||
@ -402,6 +404,9 @@ self.WhWasmUtilInstaller = function(target){
|
||||
|
||||
Sidebar: this code is developed together with Jaccwabyt, thus the
|
||||
support for its signature format.
|
||||
|
||||
The arguments may be supplied in either order: (func,sig) or
|
||||
(sig,func).
|
||||
*/
|
||||
target.jsFuncToWasm = function f(func, sig){
|
||||
/** Attribution: adapted up from Emscripten-generated glue code,
|
||||
@ -410,9 +415,14 @@ self.WhWasmUtilInstaller = function(target){
|
||||
if(!f._){/*static init...*/
|
||||
f._ = {
|
||||
// Map of signature letters to type IR values
|
||||
sigTypes: Object.create(null),
|
||||
sigTypes: Object.assign(Object.create(null),{
|
||||
i: 'i32', p: 'i32', P: 'i32', s: 'i32',
|
||||
j: 'i64', I: 'i64', f: 'f32', d: 'f64'
|
||||
}),
|
||||
// Map of type IR values to WASM type code values
|
||||
typeCodes: Object.create(null),
|
||||
typeCodes: Object.assign(Object.create(null),{
|
||||
f64: 0x7c, f32: 0x7d, i64: 0x7e, i32: 0x7f
|
||||
}),
|
||||
/** Encodes n, which must be <2^14 (16384), into target array
|
||||
tgt, as a little-endian value, using the given method
|
||||
('push' or 'unshift'). */
|
||||
@ -452,11 +462,12 @@ self.WhWasmUtilInstaller = function(target){
|
||||
invalid. */
|
||||
pushSigType: (dest, letter)=>dest.push(f._.typeCodes[f._.letterType(letter)])
|
||||
};
|
||||
f._.sigTypes.i = f._.sigTypes.p = f._.sigTypes.P = f._.sigTypes.s = 'i32';
|
||||
f._.sigTypes.j = 'i64'; f._.sigTypes.f = 'f32'; f._.sigTypes.d = 'f64';
|
||||
f._.typeCodes['i32'] = 0x7f; f._.typeCodes['i64'] = 0x7e;
|
||||
f._.typeCodes['f32'] = 0x7d; f._.typeCodes['f64'] = 0x7c;
|
||||
}/*static init*/
|
||||
if('string'===typeof func){
|
||||
const x = sig;
|
||||
sig = func;
|
||||
func = x;
|
||||
}
|
||||
const sigParams = f._.sigParams(sig);
|
||||
const wasmCode = [0x01/*count: 1*/, 0x60/*function*/];
|
||||
f._.uleb128Encode(wasmCode, 'push', sigParams.length);
|
||||
|
@ -123,7 +123,7 @@ self.Jaccwabyt = function StructBinderFactory(config){
|
||||
switch(sigLetter(s)){
|
||||
case 'i': return 'i32';
|
||||
case 'p': case 'P': case 's': return ptrIR;
|
||||
case 'j': return 'i64';
|
||||
case 'j': case 'I': return 'i64';
|
||||
case 'f': return 'float';
|
||||
case 'd': return 'double';
|
||||
}
|
||||
@ -135,7 +135,7 @@ self.Jaccwabyt = function StructBinderFactory(config){
|
||||
switch(sigLetter(s)){
|
||||
case 'i': return 4;
|
||||
case 'p': case 'P': case 's': return ptrSizeof;
|
||||
case 'j': return 8;
|
||||
case 'j': case 'I': return 8;
|
||||
case 'f': return 4 /* C-side floats, not JS-side */;
|
||||
case 'd': return 8;
|
||||
}
|
||||
@ -168,7 +168,7 @@ self.Jaccwabyt = function StructBinderFactory(config){
|
||||
break;
|
||||
}
|
||||
case 'i': return 'getInt32';
|
||||
case 'j': return affirmBigIntArray() && 'getBigInt64';
|
||||
case 'j': case 'I': return affirmBigIntArray() && 'getBigInt64';
|
||||
case 'f': return 'getFloat32';
|
||||
case 'd': return 'getFloat64';
|
||||
}
|
||||
@ -186,7 +186,7 @@ self.Jaccwabyt = function StructBinderFactory(config){
|
||||
break;
|
||||
}
|
||||
case 'i': return 'setInt32';
|
||||
case 'j': return affirmBigIntArray() && 'setBigInt64';
|
||||
case 'j': case 'I': return affirmBigIntArray() && 'setBigInt64';
|
||||
case 'f': return 'setFloat32';
|
||||
case 'd': return 'setFloat64';
|
||||
}
|
||||
@ -200,7 +200,7 @@ self.Jaccwabyt = function StructBinderFactory(config){
|
||||
const sigDVSetWrapper = function(s){
|
||||
switch(sigLetter(s)) {
|
||||
case 'i': case 'f': case 'd': return Number;
|
||||
case 'j': return affirmBigIntArray() && BigInt;
|
||||
case 'j': case 'I': return affirmBigIntArray() && BigInt;
|
||||
case 'p': case 'P': case 's':
|
||||
switch(ptrSizeof){
|
||||
case 4: return Number;
|
||||
@ -361,7 +361,7 @@ self.Jaccwabyt = function StructBinderFactory(config){
|
||||
framework's native format or in Emscripten format.
|
||||
*/
|
||||
const __memberSignature = function f(obj,memberName,emscriptenFormat=false){
|
||||
if(!f._) f._ = (x)=>x.replace(/[^vipPsjrd]/g,'').replace(/[pPs]/g,'i');
|
||||
if(!f._) f._ = (x)=>x.replace(/[^viIpPsjrd]/g,'').replace(/[pPs]/g,'i');
|
||||
const m = __lookupMember(obj.structInfo, memberName, true);
|
||||
return emscriptenFormat ? f._(m.signature) : m.signature;
|
||||
};
|
||||
@ -571,7 +571,7 @@ self.Jaccwabyt = function StructBinderFactory(config){
|
||||
direct reuse in each accessor function. */
|
||||
f._ = {getters: {}, setters: {}, sw:{}};
|
||||
const a = ['i','p','P','s','f','d','v()'];
|
||||
if(bigIntEnabled) a.push('j');
|
||||
if(bigIntEnabled) a.push('j','I');
|
||||
a.forEach(function(v){
|
||||
//const ir = sigIR(v);
|
||||
f._.getters[v] = sigDVGetter(v) /* DataView[MethodName] values for GETTERS */;
|
||||
@ -579,8 +579,8 @@ self.Jaccwabyt = function StructBinderFactory(config){
|
||||
f._.sw[v] = sigDVSetWrapper(v) /* BigInt or Number ctor to wrap around values
|
||||
for conversion */;
|
||||
});
|
||||
const rxSig1 = /^[ipPsjfd]$/,
|
||||
rxSig2 = /^[vipPsjfd]\([ipPsjfd]*\)$/;
|
||||
const rxSig1 = /^[iIpPsjfd]$/,
|
||||
rxSig2 = /^[viIpPsjfd]\([iIpPsjfd]*\)$/;
|
||||
f.sigCheck = function(obj, name, key,sig){
|
||||
if(Object.prototype.hasOwnProperty.call(obj, key)){
|
||||
toss(obj.structName,'already has a property named',key+'.');
|
||||
|
@ -275,10 +275,10 @@ supported letters are:
|
||||
|
||||
- **`v`** = `void` (only used as return type for function pointer members)
|
||||
- **`i`** = `int32` (4 bytes)
|
||||
- **`j`** = `int64` (8 bytes) is only really usable if this code is built
|
||||
with BigInt support (e.g. using the Emscripten `-sWASM_BIGINT` build
|
||||
flag). Without that, this API may throw when encountering the `j`
|
||||
signature entry.
|
||||
- **`j`** or **`I`** = `int64` (8 bytes) is only really usable if this
|
||||
code is built with BigInt support (e.g. using the Emscripten
|
||||
`-sWASM_BIGINT` build flag). Without that, this API may throw when
|
||||
encountering this signature entry.
|
||||
- **`f`** = `float` (4 bytes)
|
||||
- **`d`** = `double` (8 bytes)
|
||||
- **`p`** = `int32` (but see below!)
|
||||
|
Reference in New Issue
Block a user