1
0
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:
stephan
2022-10-03 08:21:06 +00:00
parent 510a9d1c64
commit ef9cd12ec4
8 changed files with 76 additions and 65 deletions

View File

@ -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*/;

View File

@ -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,

View File

@ -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

View File

@ -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);

View File

@ -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+'.');

View File

@ -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!)