mirror of
https://github.com/sqlite/sqlite.git
synced 2025-07-30 19:03:16 +03:00
Enhance sqlite3.wasm.xWrap.FuncPtrAdapter to be able to handle sqlite3_create_function() and friends and reimplement those bindings to use this feature (this will also simplify certain session API bindings). Interal API changes only with no client-side breakage.
FossilOrigin-Name: 7f9ace1b11a6703031790af9cf08ab25df25850a86e6ca2a7aeaefd8aa395e6d
This commit is contained in:
@ -82,7 +82,7 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
|
|||||||
"sqlite3*",
|
"sqlite3*",
|
||||||
new wasm.xWrap.FuncPtrAdapter({
|
new wasm.xWrap.FuncPtrAdapter({
|
||||||
signature: 'i(pi)',
|
signature: 'i(pi)',
|
||||||
contextKey: (argIndex,argv)=>'sqlite3@'+argv[0]
|
contextKey: (argv,argIndex)=>'sqlite3@'+argv[0]
|
||||||
}),
|
}),
|
||||||
"*"
|
"*"
|
||||||
]],
|
]],
|
||||||
@ -160,7 +160,7 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
|
|||||||
name: 'xProgressHandler',
|
name: 'xProgressHandler',
|
||||||
signature: 'i(p)',
|
signature: 'i(p)',
|
||||||
bindScope: 'context',
|
bindScope: 'context',
|
||||||
contextKey: (argIndex,argv)=>'sqlite3@'+argv[0]
|
contextKey: (argv,argIndex)=>'sqlite3@'+argv[0]
|
||||||
}), "*"
|
}), "*"
|
||||||
]
|
]
|
||||||
],
|
],
|
||||||
@ -200,7 +200,7 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
|
|||||||
new wasm.xWrap.FuncPtrAdapter({
|
new wasm.xWrap.FuncPtrAdapter({
|
||||||
name: 'sqlite3_trace_v2::callback',
|
name: 'sqlite3_trace_v2::callback',
|
||||||
signature: 'i(ippp)',
|
signature: 'i(ippp)',
|
||||||
contextKey: (argIndex, argv)=>'sqlite3@'+argv[0]
|
contextKey: (argv,argIndex)=>'sqlite3@'+argv[0]
|
||||||
}), "*"],
|
}), "*"],
|
||||||
["sqlite3_txn_state", "int", ["sqlite3*","string"]],
|
["sqlite3_txn_state", "int", ["sqlite3*","string"]],
|
||||||
/* Note that sqlite3_uri_...() have very specific requirements for
|
/* Note that sqlite3_uri_...() have very specific requirements for
|
||||||
@ -497,28 +497,24 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
if(1){/* Bindings for sqlite3_create_collation[_v2]() */
|
{/* Bindings for sqlite3_create_collation[_v2]() */
|
||||||
const __collationContextKey = (argIndex,argv)=>{
|
// contextKey() impl for wasm.xWrap.FuncPtrAdapter
|
||||||
|
const contextKey = (argv,argIndex)=>{
|
||||||
return 'argv['+argIndex+']:sqlite3@'+argv[0]+
|
return 'argv['+argIndex+']:sqlite3@'+argv[0]+
|
||||||
':'+wasm.cstrToJs(argv[1]).toLowerCase()
|
':'+wasm.cstrToJs(argv[1]).toLowerCase()
|
||||||
};
|
};
|
||||||
const __ccv2 = wasm.xWrap(
|
const __sqlite3CreateCollationV2 = wasm.xWrap(
|
||||||
'sqlite3_create_collation_v2', 'int',
|
'sqlite3_create_collation_v2', 'int', [
|
||||||
'sqlite3*','string','int','*',
|
'sqlite3*', 'string', 'int', '*',
|
||||||
new wasm.xWrap.FuncPtrAdapter({
|
new wasm.xWrap.FuncPtrAdapter({
|
||||||
/* int(*xCompare)(void*,int,const void*,int,const void*) */
|
/* int(*xCompare)(void*,int,const void*,int,const void*) */
|
||||||
name: 'sqlite3_create_collation_v2::xCompare',
|
name: 'xCompare', signature: 'i(pipip)', contextKey
|
||||||
signature: 'i(pipip)',
|
}),
|
||||||
bindScope: 'context',
|
new wasm.xWrap.FuncPtrAdapter({
|
||||||
contextKey: __collationContextKey
|
/* void(*xDestroy(void*) */
|
||||||
}),
|
name: 'xDestroy', signature: 'v(p)', contextKey
|
||||||
new wasm.xWrap.FuncPtrAdapter({
|
})
|
||||||
/* void(*xDestroy(void*) */
|
]
|
||||||
name: 'sqlite3_create_collation_v2::xDestroy',
|
|
||||||
signature: 'v(p)',
|
|
||||||
bindScope: 'context',
|
|
||||||
contextKey: __collationContextKey
|
|
||||||
})
|
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -552,13 +548,11 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
|
|||||||
}else if( capi.SQLITE_UTF8 !== (eTextRep & 0xf) ){
|
}else if( capi.SQLITE_UTF8 !== (eTextRep & 0xf) ){
|
||||||
return __errEncoding(pDb);
|
return __errEncoding(pDb);
|
||||||
}
|
}
|
||||||
let rc, pfCompare, pfDestroy;
|
try{
|
||||||
try{
|
return __sqlite3CreateCollationV2(pDb, zName, eTextRep, pArg, xCompare, xDestroy);
|
||||||
rc = __ccv2(pDb, zName, eTextRep, pArg, xCompare, xDestroy);
|
|
||||||
}catch(e){
|
}catch(e){
|
||||||
rc = util.sqlite3_wasm_db_error(pDb, e);
|
return util.sqlite3_wasm_db_error(pDb, e);
|
||||||
}
|
}
|
||||||
return rc;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
capi.sqlite3_create_collation = (pDb,zName,eTextRep,pArg,xCompare)=>{
|
capi.sqlite3_create_collation = (pDb,zName,eTextRep,pArg,xCompare)=>{
|
||||||
@ -617,82 +611,91 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
|
|||||||
}/*sqlite3_exec() proxy*/;
|
}/*sqlite3_exec() proxy*/;
|
||||||
|
|
||||||
{/* Special-case handling of sqlite3_create_function_v2()
|
{/* Special-case handling of sqlite3_create_function_v2()
|
||||||
and sqlite3_create_window_function() */
|
and sqlite3_create_window_function(). */
|
||||||
/* Maintenance reminder: FuncPtrAdapter is not expressive enough
|
/**
|
||||||
to be able to perform these mappings. */
|
FuncPtrAdapter for contextKey() for sqlite3_create_function().
|
||||||
const sqlite3CreateFunction = wasm.xWrap(
|
*/
|
||||||
"sqlite3_create_function_v2", "int",
|
const contextKey = function(argv,argIndex){
|
||||||
["sqlite3*", "string"/*funcName*/, "int"/*nArg*/,
|
return (
|
||||||
"int"/*eTextRep*/, "*"/*pApp*/,
|
'sqlite3@'+argv[0]
|
||||||
"*"/*xStep*/,"*"/*xFinal*/, "*"/*xValue*/, "*"/*xDestroy*/]
|
+':'+argIndex
|
||||||
);
|
+':'+wasm.cstrToJs(argv[1]).toLowerCase()
|
||||||
|
)
|
||||||
|
};
|
||||||
|
|
||||||
const sqlite3CreateWindowFunction = wasm.xWrap(
|
/**
|
||||||
"sqlite3_create_window_function", "int",
|
JS proxies for the various sqlite3_create[_window]_function()
|
||||||
["sqlite3*", "string"/*funcName*/, "int"/*nArg*/,
|
callbacks, structured in a form usable by wasm.xWrap.FuncPtrAdapter.
|
||||||
"int"/*eTextRep*/, "*"/*pApp*/,
|
*/
|
||||||
"*"/*xStep*/,"*"/*xFinal*/, "*"/*xValue*/,
|
const __cfProxy = Object.assign(Object.create(null), {
|
||||||
"*"/*xInverse*/, "*"/*xDestroy*/]
|
xInverseAndStep: {
|
||||||
);
|
signature:'v(pip)', contextKey,
|
||||||
|
callProxy: (callback)=>{
|
||||||
const __xFunc = function(callback){
|
return (pCtx, argc, pArgv)=>{
|
||||||
return function(pCtx, argc, pArgv){
|
try{ callback(pCtx, ...capi.sqlite3_values_to_js(argc, pArgv)) }
|
||||||
try{
|
catch(e){ capi.sqlite3_result_error_js(pCtx, e) }
|
||||||
capi.sqlite3_result_js(
|
};
|
||||||
pCtx,
|
|
||||||
callback(pCtx, ...capi.sqlite3_values_to_js(argc, pArgv))
|
|
||||||
);
|
|
||||||
}catch(e){
|
|
||||||
//console.error('xFunc() caught:',e);
|
|
||||||
capi.sqlite3_result_error_js(pCtx, e);
|
|
||||||
}
|
}
|
||||||
};
|
},
|
||||||
};
|
xFinalAndValue: {
|
||||||
|
signature:'v(p)', contextKey,
|
||||||
const __xInverseAndStep = function(callback){
|
callProxy: (callback)=>{
|
||||||
return function(pCtx, argc, pArgv){
|
return (pCtx)=>{
|
||||||
try{ callback(pCtx, ...capi.sqlite3_values_to_js(argc, pArgv)) }
|
try{ capi.sqlite3_result_js(pCtx, callback(pCtx)) }
|
||||||
catch(e){ capi.sqlite3_result_error_js(pCtx, e) }
|
catch(e){ capi.sqlite3_result_error_js(pCtx, e) }
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
|
},
|
||||||
const __xFinalAndValue = function(callback){
|
xFunc: {
|
||||||
return function(pCtx){
|
signature:'v(pip)', contextKey,
|
||||||
try{ capi.sqlite3_result_js(pCtx, callback(pCtx)) }
|
callProxy: (callback)=>{
|
||||||
catch(e){ capi.sqlite3_result_error_js(pCtx, e) }
|
return (pCtx, argc, pArgv)=>{
|
||||||
};
|
try{
|
||||||
};
|
capi.sqlite3_result_js(
|
||||||
|
pCtx,
|
||||||
const __xDestroy = function(callback){
|
callback(pCtx, ...capi.sqlite3_values_to_js(argc, pArgv))
|
||||||
return function(pVoid){
|
);
|
||||||
try{ callback(pVoid) }
|
}catch(e){
|
||||||
catch(e){ console.error("UDF xDestroy method threw:",e) }
|
//console.error('xFunc() caught:',e);
|
||||||
};
|
capi.sqlite3_result_error_js(pCtx, e);
|
||||||
};
|
}
|
||||||
|
};
|
||||||
const __xMap = Object.assign(Object.create(null), {
|
}
|
||||||
xFunc: {sig:'v(pip)', f:__xFunc},
|
},
|
||||||
xStep: {sig:'v(pip)', f:__xInverseAndStep},
|
xDestroy: {
|
||||||
xInverse: {sig:'v(pip)', f:__xInverseAndStep},
|
signature:'v(p)', contextKey,
|
||||||
xFinal: {sig:'v(p)', f:__xFinalAndValue},
|
//Arguable: a well-behaved destructor doesn't require a proxy.
|
||||||
xValue: {sig:'v(p)', f:__xFinalAndValue},
|
callProxy: (callback)=>{
|
||||||
xDestroy: {sig:'v(p)', f:__xDestroy}
|
return (pVoid)=>{
|
||||||
});
|
try{ callback(pVoid) }
|
||||||
|
catch(e){ console.error("UDF xDestroy method threw:",e) }
|
||||||
/* Internal helper for sqlite3_create_function() and friends. */
|
};
|
||||||
const __xWrapFuncs = function(theKeys, theFuncs, tgtUninst){
|
|
||||||
const rc = []
|
|
||||||
for(const k of theKeys){
|
|
||||||
let fArg = theFuncs[k];
|
|
||||||
if('function'===typeof fArg){
|
|
||||||
const w = __xMap[k] || toss3("Internal error in __xWrapFuncs: invalid key:",k);
|
|
||||||
fArg = wasm.installFunction(w.sig, w.f(fArg));
|
|
||||||
tgtUninst.push(fArg);
|
|
||||||
}
|
}
|
||||||
rc.push(fArg);
|
|
||||||
}
|
}
|
||||||
return rc;
|
})/*__cfProxy*/;
|
||||||
};
|
|
||||||
|
const __sqlite3CreateFunction = wasm.xWrap(
|
||||||
|
"sqlite3_create_function_v2", "int", [
|
||||||
|
"sqlite3*", "string"/*funcName*/, "int"/*nArg*/,
|
||||||
|
"int"/*eTextRep*/, "*"/*pApp*/,
|
||||||
|
new wasm.xWrap.FuncPtrAdapter({name: 'xFunc', ...__cfProxy.xFunc}),
|
||||||
|
new wasm.xWrap.FuncPtrAdapter({name: 'xStep', ...__cfProxy.xInverseAndStep}),
|
||||||
|
new wasm.xWrap.FuncPtrAdapter({name: 'xFinal', ...__cfProxy.xFinalAndValue}),
|
||||||
|
new wasm.xWrap.FuncPtrAdapter({name: 'xDestroy', ...__cfProxy.xDestroy})
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
|
const __sqlite3CreateWindowFunction = wasm.xWrap(
|
||||||
|
"sqlite3_create_window_function", "int", [
|
||||||
|
"sqlite3*", "string"/*funcName*/, "int"/*nArg*/,
|
||||||
|
"int"/*eTextRep*/, "*"/*pApp*/,
|
||||||
|
new wasm.xWrap.FuncPtrAdapter({name: 'xStep', ...__cfProxy.xInverseAndStep}),
|
||||||
|
new wasm.xWrap.FuncPtrAdapter({name: 'xFinal', ...__cfProxy.xFinalAndValue}),
|
||||||
|
new wasm.xWrap.FuncPtrAdapter({name: 'xValue', ...__cfProxy.xFinalAndValue}),
|
||||||
|
new wasm.xWrap.FuncPtrAdapter({name: 'xInverse', ...__cfProxy.xInverseAndStep}),
|
||||||
|
new wasm.xWrap.FuncPtrAdapter({name: 'xDestroy', ...__cfProxy.xDestroy})
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
/* Documented in the api object's initializer. */
|
/* Documented in the api object's initializer. */
|
||||||
capi.sqlite3_create_function_v2 = function f(
|
capi.sqlite3_create_function_v2 = function f(
|
||||||
@ -709,26 +712,16 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
|
|||||||
}else if( capi.SQLITE_UTF8 !== (eTextRep & 0xf) ){
|
}else if( capi.SQLITE_UTF8 !== (eTextRep & 0xf) ){
|
||||||
return __errEncoding(pDb);
|
return __errEncoding(pDb);
|
||||||
}
|
}
|
||||||
/* Wrap the callbacks in a WASM-bound functions... */
|
|
||||||
const uninstall = [/*funcs to uninstall on error*/];
|
|
||||||
let rc;
|
|
||||||
try{
|
try{
|
||||||
const funcArgs = __xWrapFuncs(['xFunc','xStep','xFinal','xDestroy'],
|
return __sqlite3CreateFunction(pDb, funcName, nArg, eTextRep,
|
||||||
{xFunc, xStep, xFinal, xDestroy},
|
pApp, xFunc, xStep, xFinal, xDestroy);
|
||||||
uninstall);
|
|
||||||
rc = sqlite3CreateFunction(pDb, funcName, nArg, eTextRep,
|
|
||||||
pApp, ...funcArgs);
|
|
||||||
}catch(e){
|
}catch(e){
|
||||||
console.error("sqlite3_create_function_v2() setup threw:",e);
|
console.error("sqlite3_create_function_v2() setup threw:",e);
|
||||||
for(let v of uninstall){
|
return util.sqlite3_wasm_db_error(pDb, e, "Creation of UDF threw: "+e);
|
||||||
wasm.uninstallFunction(v);
|
|
||||||
}
|
|
||||||
rc = util.sqlite3_wasm_db_error(pDb, capi.SQLITE_ERROR,
|
|
||||||
"Creation of UDF threw: "+e.message);
|
|
||||||
}
|
}
|
||||||
return rc;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* Documented in the api object's initializer. */
|
||||||
capi.sqlite3_create_function = function f(
|
capi.sqlite3_create_function = function f(
|
||||||
pDb, funcName, nArg, eTextRep, pApp,
|
pDb, funcName, nArg, eTextRep, pApp,
|
||||||
xFunc, xStep, xFinal
|
xFunc, xStep, xFinal
|
||||||
@ -744,8 +737,8 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
|
|||||||
pDb, funcName, nArg, eTextRep, pApp,
|
pDb, funcName, nArg, eTextRep, pApp,
|
||||||
xStep, //void (*xStep)(sqlite3_context*,int,sqlite3_value**)
|
xStep, //void (*xStep)(sqlite3_context*,int,sqlite3_value**)
|
||||||
xFinal, //void (*xFinal)(sqlite3_context*)
|
xFinal, //void (*xFinal)(sqlite3_context*)
|
||||||
xValue, //void (*xFinal)(sqlite3_context*)
|
xValue, //void (*xValue)(sqlite3_context*)
|
||||||
xInverse,//void (*xStep)(sqlite3_context*,int,sqlite3_value**)
|
xInverse,//void (*xInverse)(sqlite3_context*,int,sqlite3_value**)
|
||||||
xDestroy //void (*xDestroy)(void*)
|
xDestroy //void (*xDestroy)(void*)
|
||||||
){
|
){
|
||||||
if( f.length!==arguments.length ){
|
if( f.length!==arguments.length ){
|
||||||
@ -755,24 +748,14 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
|
|||||||
}else if( capi.SQLITE_UTF8 !== (eTextRep & 0xf) ){
|
}else if( capi.SQLITE_UTF8 !== (eTextRep & 0xf) ){
|
||||||
return __errEncoding(pDb);
|
return __errEncoding(pDb);
|
||||||
}
|
}
|
||||||
/* Wrap the callbacks in a WASM-bound functions... */
|
|
||||||
const uninstall = [/*funcs to uninstall on error*/];
|
|
||||||
let rc;
|
|
||||||
try{
|
try{
|
||||||
const funcArgs = __xWrapFuncs(['xStep','xFinal','xValue','xInverse','xDestroy'],
|
return __sqlite3CreateWindowFunction(pDb, funcName, nArg, eTextRep,
|
||||||
{xStep, xFinal, xValue, xInverse, xDestroy},
|
pApp, xStep, xFinal, xValue,
|
||||||
uninstall);
|
xInverse, xDestroy);
|
||||||
rc = sqlite3CreateWindowFunction(pDb, funcName, nArg, eTextRep,
|
|
||||||
pApp, ...funcArgs);
|
|
||||||
}catch(e){
|
}catch(e){
|
||||||
console.error("sqlite3_create_window_function() setup threw:",e);
|
console.error("sqlite3_create_window_function() setup threw:",e);
|
||||||
for(let v of uninstall){
|
return util.sqlite3_wasm_db_error(pDb, e, "Creation of UDF threw: "+e);
|
||||||
wasm.uninstallFunction(v);
|
|
||||||
}
|
|
||||||
rc = util.sqlite3_wasm_db_error(pDb, capi.SQLITE_ERROR,
|
|
||||||
"Creation of UDF threw: "+e.message);
|
|
||||||
}
|
}
|
||||||
return rc;
|
|
||||||
};
|
};
|
||||||
/**
|
/**
|
||||||
A _deprecated_ alias for capi.sqlite3_result_js() which
|
A _deprecated_ alias for capi.sqlite3_result_js() which
|
||||||
|
@ -1496,7 +1496,7 @@ self.WhWasmUtilInstaller = function(target){
|
|||||||
types are indeterminate, whereas the LHS values will be
|
types are indeterminate, whereas the LHS values will be
|
||||||
WASM-compatible values by the time this is called.
|
WASM-compatible values by the time this is called.
|
||||||
*/
|
*/
|
||||||
convertArg(v,argIndex,argv){
|
convertArg(v,argv,argIndex){
|
||||||
toss("AbstractArgAdapter must be subclassed.");
|
toss("AbstractArgAdapter must be subclassed.");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -1541,24 +1541,38 @@ self.WhWasmUtilInstaller = function(target){
|
|||||||
context. This mode is the default if bindScope is _not_ set
|
context. This mode is the default if bindScope is _not_ set
|
||||||
but a property named contextKey (described below) is.
|
but a property named contextKey (described below) is.
|
||||||
|
|
||||||
|
- callProxy (function): if set, this must be a function which
|
||||||
|
will act as a proxy for any "converted" JS function. It is
|
||||||
|
passed the being-converted function value and must return
|
||||||
|
either that function or a function which acts on its
|
||||||
|
behalf. The returned function will be the one which gets
|
||||||
|
installed into the WASM function table. The proxy must perform
|
||||||
|
any required argument conversion (noting that it will be called
|
||||||
|
from C code, so will receive C-format arguments) before passing
|
||||||
|
them on to the being-converted function. Whether or not the
|
||||||
|
proxy itself must return a value depends on the context. If it
|
||||||
|
does, it must be a WASM-friendly value, as it will be returning
|
||||||
|
from a call made from native code.
|
||||||
|
|
||||||
- contextKey (function): is only used if bindScope is 'context'
|
- contextKey (function): is only used if bindScope is 'context'
|
||||||
or if bindScope is not set and this function is, in which case
|
or if bindScope is not set and this function is, in which case
|
||||||
'context' is assumed. This function gets passed
|
'context' is assumed. This function gets bound to this object,
|
||||||
(argIndex,argv), where argIndex is the index of _this_ function
|
so its "this" is this object. It gets passed (argv,argIndex),
|
||||||
pointer in its _wrapping_ function's arguments and argv is the
|
where argIndex is the index of _this_ function pointer in its
|
||||||
_current_ still-being-xWrap()-processed args array. All
|
_wrapping_ function's arguments and argv is the _current_
|
||||||
arguments to the left of argIndex will have been processed by
|
still-being-xWrap()-processed args array. All arguments to the
|
||||||
xWrap() by the time this is called. argv[argIndex] will be the
|
left of argIndex will have been processed by xWrap() by the
|
||||||
value the user passed in to the xWrap()'d function for the
|
time this is called. argv[argIndex] will be the value the user
|
||||||
argument this FuncPtrAdapter is mapped to. Arguments to the
|
passed in to the xWrap()'d function for the argument this
|
||||||
right of argv[argIndex] will not yet have been converted before
|
FuncPtrAdapter is mapped to. Arguments to the right of
|
||||||
this is called. The function must return a key which uniquely
|
argv[argIndex] will not yet have been converted before this is
|
||||||
|
called. The function must return a key which uniquely
|
||||||
identifies this function mapping context for _this_
|
identifies this function mapping context for _this_
|
||||||
FuncPtrAdapter instance (other instances are not considered),
|
FuncPtrAdapter instance (other instances are not considered),
|
||||||
taking into account that C functions often take some sort of
|
taking into account that C functions often take some sort of
|
||||||
state object as one or more of their arguments. As an example,
|
state object as one or more of their arguments. As an example,
|
||||||
if the xWrap()'d function takes `(int,T*,functionPtr,X*)` and
|
if the xWrap()'d function takes `(int,T*,functionPtr,X*)` and
|
||||||
this FuncPtrAdapter is the argv[2]nd arg, contextKey(2,argv)
|
this FuncPtrAdapter is the argv[2]nd arg, contextKey(argv,2)
|
||||||
might return 'T@'+argv[1], or even just argv[1]. Note,
|
might return 'T@'+argv[1], or even just argv[1]. Note,
|
||||||
however, that the (X*) argument will not yet have been
|
however, that the (X*) argument will not yet have been
|
||||||
processed by the time this is called and should not be used as
|
processed by the time this is called and should not be used as
|
||||||
@ -1570,7 +1584,7 @@ self.WhWasmUtilInstaller = function(target){
|
|||||||
use their pointers in the key because most C-strings in this
|
use their pointers in the key because most C-strings in this
|
||||||
constellation are transient.
|
constellation are transient.
|
||||||
|
|
||||||
Yes, that ^^^ is a bit awkward, but it's what we have.
|
Yes, that ^^^ is quite awkward, but it's what we have.
|
||||||
|
|
||||||
The constructor only saves the above state for later, and does
|
The constructor only saves the above state for later, and does
|
||||||
not actually bind any functions. Its convertArg() method is
|
not actually bind any functions. Its convertArg() method is
|
||||||
@ -1598,6 +1612,8 @@ self.WhWasmUtilInstaller = function(target){
|
|||||||
if( ('singleton'===this.bindScope) ) this.singleton = [];
|
if( ('singleton'===this.bindScope) ) this.singleton = [];
|
||||||
else this.singleton = undefined;
|
else this.singleton = undefined;
|
||||||
//console.warn("FuncPtrAdapter()",opt,this);
|
//console.warn("FuncPtrAdapter()",opt,this);
|
||||||
|
this.callProxy = (opt.callProxy instanceof Function)
|
||||||
|
? opt.callProxy : undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bindScopes = [
|
static bindScopes = [
|
||||||
@ -1605,7 +1621,7 @@ self.WhWasmUtilInstaller = function(target){
|
|||||||
];
|
];
|
||||||
|
|
||||||
/* Dummy impl. Overwritten per-instance as needed. */
|
/* Dummy impl. Overwritten per-instance as needed. */
|
||||||
contextKey(argIndex,argv){
|
contextKey(argv,argIndex){
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1638,14 +1654,16 @@ self.WhWasmUtilInstaller = function(target){
|
|||||||
See the parent class's convertArg() docs for details on what
|
See the parent class's convertArg() docs for details on what
|
||||||
exactly the 2nd and 3rd arguments are.
|
exactly the 2nd and 3rd arguments are.
|
||||||
*/
|
*/
|
||||||
convertArg(v,argIndex,argv){
|
convertArg(v,argv,argIndex){
|
||||||
//console.warn("FuncPtrAdapter.convertArg()",this.signature,this.transient,v);
|
//console.warn("FuncPtrAdapter.convertArg()",this.signature,this.transient,v);
|
||||||
let pair = this.singleton;
|
let pair = this.singleton;
|
||||||
if(!pair && this.isContext){
|
if(!pair && this.isContext){
|
||||||
pair = this.contextMap(this.contextKey(argIndex, argv));
|
pair = this.contextMap(this.contextKey(argv,argIndex));
|
||||||
}
|
}
|
||||||
if(pair && pair[0]===v) return pair[1];
|
if(pair && pair[0]===v) return pair[1];
|
||||||
if(v instanceof Function){
|
if(v instanceof Function){
|
||||||
|
/* Install a WASM binding and return its pointer. */
|
||||||
|
if(this.callProxy) v = this.callProxy(v);
|
||||||
const fp = __installFunction(v, this.signature, this.isTransient);
|
const fp = __installFunction(v, this.signature, this.isTransient);
|
||||||
if(pair){
|
if(pair){
|
||||||
/* Replace existing stashed mapping */
|
/* Replace existing stashed mapping */
|
||||||
@ -1660,10 +1678,10 @@ self.WhWasmUtilInstaller = function(target){
|
|||||||
}else if(target.isPtr(v) || null===v || undefined===v){
|
}else if(target.isPtr(v) || null===v || undefined===v){
|
||||||
if(pair && pair[1] && pair[1]!==v){
|
if(pair && pair[1] && pair[1]!==v){
|
||||||
/* uninstall stashed mapping and replace stashed mapping with v. */
|
/* uninstall stashed mapping and replace stashed mapping with v. */
|
||||||
//console.warn("FuncPtrAdapter is uninstalling function", this.contextKey(argIndex,argv),v);
|
//console.warn("FuncPtrAdapter is uninstalling function", this.contextKey(argv,argIndex),v);
|
||||||
try{target.uninstallFunction(pair[1])}
|
try{target.uninstallFunction(pair[1])}
|
||||||
catch(e){/*ignored*/}
|
catch(e){/*ignored*/}
|
||||||
pair[0] = pair[1] = (v || 0);
|
pair[0] = pair[1] = (v | 0);
|
||||||
}
|
}
|
||||||
return v || 0;
|
return v || 0;
|
||||||
}else{
|
}else{
|
||||||
@ -1897,17 +1915,20 @@ self.WhWasmUtilInstaller = function(target){
|
|||||||
The public interface of argument adapters is that they take
|
The public interface of argument adapters is that they take
|
||||||
ONE argument and return a (possibly) converted result for
|
ONE argument and return a (possibly) converted result for
|
||||||
it. The passing-on of arguments after the first is an
|
it. The passing-on of arguments after the first is an
|
||||||
internal impl. detail for the sake of AbstractArgAdapter, and
|
internal implementation detail for the sake of
|
||||||
not to be relied on or documented for other cases. The fact
|
AbstractArgAdapter, and not to be relied on or documented
|
||||||
that this is how AbstractArgAdapter.convertArgs() gets its 2nd+
|
for other cases. The fact that this is how
|
||||||
arguments, and how FuncPtrAdapter.contextKey() gets its
|
AbstractArgAdapter.convertArgs() gets its 2nd+ arguments,
|
||||||
args, is also an implementation detail and subject to
|
and how FuncPtrAdapter.contextKey() gets its args, is also
|
||||||
change. i.e. the public interface of 1 argument is stable.
|
an implementation detail and subject to change. i.e. the
|
||||||
The fact that any arguments may be passed in after that one,
|
public interface of 1 argument is stable. The fact that any
|
||||||
and what those arguments are, is _not_ part of the public
|
arguments may be passed in after that one, and what those
|
||||||
interface and is _not_ stable.
|
arguments are, is _not_ part of the public interface and is
|
||||||
|
_not_ stable.
|
||||||
*/
|
*/
|
||||||
for(const i in args) args[i] = cxw.convertArgNoCheck(argTypes[i], args[i], i, args);
|
for(const i in args) args[i] = cxw.convertArgNoCheck(
|
||||||
|
argTypes[i], args[i], args, i
|
||||||
|
);
|
||||||
return cxw.convertResultNoCheck(resultType, xf.apply(null,args));
|
return cxw.convertResultNoCheck(resultType, xf.apply(null,args));
|
||||||
}finally{
|
}finally{
|
||||||
target.scopedAllocPop(scope);
|
target.scopedAllocPop(scope);
|
||||||
|
14
manifest
14
manifest
@ -1,5 +1,5 @@
|
|||||||
C Simplify\sthe\ssignature\sfor\sJS\sfunctions,\sas\sopposed\sto\sfunction\spointers,\spassed\sto\ssqlite3_exec(),\seliminating\sthe\ssuperfluous\sinitial\stwo\sarguments.\sUpdate\srelated\stests\sto\sdemonstrate\sboth\sfunction-passing\sapproaches.
|
C Enhance\ssqlite3.wasm.xWrap.FuncPtrAdapter\sto\sbe\sable\sto\shandle\ssqlite3_create_function()\sand\sfriends\sand\sreimplement\sthose\sbindings\sto\suse\sthis\sfeature\s(this\swill\salso\ssimplify\scertain\ssession\sAPI\sbindings).\sInteral\sAPI\schanges\sonly\swith\sno\sclient-side\sbreakage.
|
||||||
D 2022-12-25T10:22:27.506
|
D 2022-12-25T12:51:53.541
|
||||||
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,7 +503,7 @@ 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 72f1ed1d60db62e18cf752c5871bc7c21cfef9258d9c81e61c830914c3f7da91
|
F ext/wasm/api/sqlite3-api-glue.js 4114cbd92818eda90bffb9cf3f181a4c1eb50521c95a3ea6d4e0bbc552901ffb
|
||||||
F ext/wasm/api/sqlite3-api-oo1.js 5393fb0b325d2fdafada7fdbfb9219af9a865631acb351d5c5196a982b632c8b
|
F ext/wasm/api/sqlite3-api-oo1.js 5393fb0b325d2fdafada7fdbfb9219af9a865631acb351d5c5196a982b632c8b
|
||||||
F ext/wasm/api/sqlite3-api-prologue.js a27762fd1ed2576897026f28a748a69edcdcc53ef79f46cead5e4446dc949763
|
F ext/wasm/api/sqlite3-api-prologue.js a27762fd1ed2576897026f28a748a69edcdcc53ef79f46cead5e4446dc949763
|
||||||
F ext/wasm/api/sqlite3-api-worker1.js e94ba98e44afccfa482874cd9acb325883ade50ed1f9f9526beb9de1711f182f
|
F ext/wasm/api/sqlite3-api-worker1.js e94ba98e44afccfa482874cd9acb325883ade50ed1f9f9526beb9de1711f182f
|
||||||
@ -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 700fb1b702986522d2177fe8247bfbab3040e82cb4f6c35e929c4c85fbd7ffc5
|
F ext/wasm/common/whwasmutil.js 46e1ae432eda14ade6c84318c257917dd86755cb0bfa329d989522e057adff6e
|
||||||
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 ffe2999a91a7dec129a38afb675fe9e539d7c347886bfea85cba55f6367d54d1
|
P e7cc70cdda426863f82ebe1305f4c3053824c5a605b1516b0b7f205f1203178b
|
||||||
R 57b44198d665feb79b35a3b3cc62df00
|
R 942325294903c7f082d03ed59c06bba6
|
||||||
U stephan
|
U stephan
|
||||||
Z fa52e396693ed4ebb322eeecdf80849b
|
Z 9f06406b1eaa13fb27bb0e5cf658bbb6
|
||||||
# Remove this line to create a well-formed Fossil manifest.
|
# Remove this line to create a well-formed Fossil manifest.
|
||||||
|
@ -1 +1 @@
|
|||||||
e7cc70cdda426863f82ebe1305f4c3053824c5a605b1516b0b7f205f1203178b
|
7f9ace1b11a6703031790af9cf08ab25df25850a86e6ca2a7aeaefd8aa395e6d
|
Reference in New Issue
Block a user