1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-07-30 19:03:16 +03:00

wasm util: remove superfluous function.bind() calls to eliminate a level of call() indirection.

FossilOrigin-Name: 1aab9627983ef0f016b01f78564e79cf815ed14d4b1b6dc04ec627b96f1b2f70
This commit is contained in:
stephan
2022-08-30 09:49:30 +00:00
parent 2f06bf2541
commit 5bb5965710
3 changed files with 68 additions and 69 deletions

View File

@ -326,7 +326,7 @@ self.WhWasmUtilInstaller = function(target){
if(c.HEAP64) return unsigned ? c.HEAP64U : c.HEAP64; if(c.HEAP64) return unsigned ? c.HEAP64U : c.HEAP64;
break; break;
default: default:
if(this.bigIntEnabled){ if(target.bigIntEnabled){
if(n===self['BigUint64Array']) return c.HEAP64U; if(n===self['BigUint64Array']) return c.HEAP64U;
else if(n===self['BigInt64Array']) return c.HEAP64; else if(n===self['BigInt64Array']) return c.HEAP64;
break; break;
@ -334,7 +334,7 @@ self.WhWasmUtilInstaller = function(target){
} }
toss("Invalid heapForSize() size: expecting 8, 16, 32,", toss("Invalid heapForSize() size: expecting 8, 16, 32,",
"or (if BigInt is enabled) 64."); "or (if BigInt is enabled) 64.");
}.bind(target); };
/** /**
Returns the WASM-exported "indirect function table." Returns the WASM-exported "indirect function table."
@ -346,16 +346,16 @@ self.WhWasmUtilInstaller = function(target){
- Use `__indirect_function_table` as the import name for the - Use `__indirect_function_table` as the import name for the
table, which is what LLVM does. table, which is what LLVM does.
*/ */
}.bind(target); };
/** /**
Given a function pointer, returns the WASM function table entry Given a function pointer, returns the WASM function table entry
if found, else returns a falsy value. if found, else returns a falsy value.
*/ */
target.functionEntry = function(fptr){ target.functionEntry = function(fptr){
const ft = this.functionTable(); const ft = target.functionTable();
return fptr < ft.length ? ft.get(fptr) : undefined; return fptr < ft.length ? ft.get(fptr) : undefined;
}.bind(target); };
/** /**
Creates a WASM function which wraps the given JS function and Creates a WASM function which wraps the given JS function and
@ -504,7 +504,7 @@ self.WhWasmUtilInstaller = function(target){
https://github.com/emscripten-core/emscripten/issues/17323 https://github.com/emscripten-core/emscripten/issues/17323
*/ */
target.installFunction = function f(func, sig){ target.installFunction = function f(func, sig){
const ft = this.functionTable(); const ft = target.functionTable();
const oldLen = ft.length; const oldLen = ft.length;
let ptr; let ptr;
while(cache.freeFuncIndexes.length){ while(cache.freeFuncIndexes.length){
@ -532,13 +532,13 @@ self.WhWasmUtilInstaller = function(target){
} }
// It's not a WASM-exported function, so compile one... // It's not a WASM-exported function, so compile one...
try { try {
ft.set(ptr, this.jsFuncToWasm(func, sig)); ft.set(ptr, target.jsFuncToWasm(func, sig));
}catch(e){ }catch(e){
if(ptr===oldLen) cache.freeFuncIndexes.push(oldLen); if(ptr===oldLen) cache.freeFuncIndexes.push(oldLen);
throw e; throw e;
} }
return ptr; return ptr;
}.bind(target); };
/** /**
Requires a pointer value previously returned from Requires a pointer value previously returned from
@ -551,12 +551,12 @@ self.WhWasmUtilInstaller = function(target){
*/ */
target.uninstallFunction = function(ptr){ target.uninstallFunction = function(ptr){
const fi = cache.freeFuncIndexes; const fi = cache.freeFuncIndexes;
const ft = this.functionTable(); const ft = target.functionTable();
fi.push(ptr); fi.push(ptr);
const rc = ft.get(ptr); const rc = ft.get(ptr);
ft.set(ptr, null); ft.set(ptr, null);
return rc; return rc;
}.bind(target); };
/** /**
Given a WASM heap memory address and a data type name in the form Given a WASM heap memory address and a data type name in the form
@ -614,14 +614,14 @@ self.WhWasmUtilInstaller = function(target){
case 'i16': return c.HEAP16[ptr>>1]; case 'i16': return c.HEAP16[ptr>>1];
case 'i32': return c.HEAP32[ptr>>2]; case 'i32': return c.HEAP32[ptr>>2];
case 'i64': case 'i64':
if(this.bigIntEnabled) return BigInt(c.HEAP64[ptr>>3]); if(target.bigIntEnabled) return BigInt(c.HEAP64[ptr>>3]);
break; break;
case 'float': case 'f32': return c.HEAP32F[ptr>>2]; case 'float': case 'f32': return c.HEAP32F[ptr>>2];
case 'double': case 'f64': return Number(c.HEAP64F[ptr>>3]); case 'double': case 'f64': return Number(c.HEAP64F[ptr>>3]);
default: break; default: break;
} }
toss('Invalid type for getMemValue():',type); toss('Invalid type for getMemValue():',type);
}.bind(target); };
/** /**
The counterpart of getMemValue(), this sets a numeric value at The counterpart of getMemValue(), this sets a numeric value at
@ -698,9 +698,9 @@ self.WhWasmUtilInstaller = function(target){
ptr is falsy, `null` is returned. ptr is falsy, `null` is returned.
*/ */
target.cstringToJs = function(ptr){ target.cstringToJs = function(ptr){
const n = this.cstrlen(ptr); const n = target.cstrlen(ptr);
return n ? __utf8Decode(heapWrappers().HEAP8U, ptr, ptr+n) : (null===n ? n : ""); return n ? __utf8Decode(heapWrappers().HEAP8U, ptr, ptr+n) : (null===n ? n : "");
}.bind(target); };
/** /**
Given a JS string, this function returns its UTF-8 length in Given a JS string, this function returns its UTF-8 length in
@ -828,16 +828,16 @@ self.WhWasmUtilInstaller = function(target){
*/ */
target.cstrncpy = function(tgtPtr, srcPtr, n){ target.cstrncpy = function(tgtPtr, srcPtr, n){
if(!tgtPtr || !srcPtr) toss("cstrncpy() does not accept NULL strings."); if(!tgtPtr || !srcPtr) toss("cstrncpy() does not accept NULL strings.");
if(n<0) n = this.cstrlen(strPtr)+1; if(n<0) n = target.cstrlen(strPtr)+1;
else if(!(n>0)) return 0; else if(!(n>0)) return 0;
const heap = this.heap8u(); const heap = target.heap8u();
let i = 0, ch; let i = 0, ch;
for(; i < n && (ch = heap[srcPtr+i]); ++i){ for(; i < n && (ch = heap[srcPtr+i]); ++i){
heap[tgtPtr+i] = ch; heap[tgtPtr+i] = ch;
} }
if(i<n) heap[tgtPtr + i++] = 0; if(i<n) heap[tgtPtr + i++] = 0;
return i; return i;
}.bind(target); };
/** /**
For the given JS string, returns a Uint8Array of its contents For the given JS string, returns a Uint8Array of its contents
@ -882,13 +882,13 @@ self.WhWasmUtilInstaller = function(target){
}; };
const __allocCStr = function(jstr, returnWithLength, allocator, funcName){ const __allocCStr = function(jstr, returnWithLength, allocator, funcName){
__affirmAlloc(this, funcName); __affirmAlloc(target, funcName);
if('string'!==typeof jstr) return null; if('string'!==typeof jstr) return null;
const n = this.jstrlen(jstr), const n = target.jstrlen(jstr),
ptr = allocator(n+1); ptr = allocator(n+1);
this.jstrcpy(jstr, this.heap8u(), ptr, n+1, true); target.jstrcpy(jstr, target.heap8u(), ptr, n+1, true);
return returnWithLength ? [ptr, n] : ptr; return returnWithLength ? [ptr, n] : ptr;
}.bind(target); };
/** /**
Uses target.alloc() to allocate enough memory for jstrlen(jstr)+1 Uses target.alloc() to allocate enough memory for jstrlen(jstr)+1
@ -941,11 +941,11 @@ self.WhWasmUtilInstaller = function(target){
alloc levels are currently active. alloc levels are currently active.
*/ */
target.scopedAllocPush = function(){ target.scopedAllocPush = function(){
__affirmAlloc(this, 'scopedAllocPush'); __affirmAlloc(target, 'scopedAllocPush');
const a = []; const a = [];
cache.scopedAlloc.push(a); cache.scopedAlloc.push(a);
return a; return a;
}.bind(target); };
/** /**
Cleans up all allocations made using scopedAlloc() in the context Cleans up all allocations made using scopedAlloc() in the context
@ -970,15 +970,15 @@ self.WhWasmUtilInstaller = function(target){
trivial code that may be a non-issue. trivial code that may be a non-issue.
*/ */
target.scopedAllocPop = function(state){ target.scopedAllocPop = function(state){
__affirmAlloc(this, 'scopedAllocPop'); __affirmAlloc(target, 'scopedAllocPop');
const n = arguments.length const n = arguments.length
? cache.scopedAlloc.indexOf(state) ? cache.scopedAlloc.indexOf(state)
: cache.scopedAlloc.length-1; : cache.scopedAlloc.length-1;
if(n<0) toss("Invalid state object for scopedAllocPop()."); if(n<0) toss("Invalid state object for scopedAllocPop().");
if(0===arguments.length) state = cache.scopedAlloc[n]; if(0===arguments.length) state = cache.scopedAlloc[n];
cache.scopedAlloc.splice(n,1); cache.scopedAlloc.splice(n,1);
for(let p; (p = state.pop()); ) this.dealloc(p); for(let p; (p = state.pop()); ) target.dealloc(p);
}.bind(target); };
/** /**
Allocates n bytes of memory using this.alloc() and records that Allocates n bytes of memory using this.alloc() and records that
@ -1000,10 +1000,10 @@ self.WhWasmUtilInstaller = function(target){
if(!cache.scopedAlloc.length){ if(!cache.scopedAlloc.length){
toss("No scopedAllocPush() scope is active."); toss("No scopedAllocPush() scope is active.");
} }
const p = this.alloc(n); const p = target.alloc(n);
cache.scopedAlloc[cache.scopedAlloc.length-1].push(p); cache.scopedAlloc[cache.scopedAlloc.length-1].push(p);
return p; return p;
}.bind(target); };
Object.defineProperty(target.scopedAlloc, 'level', { Object.defineProperty(target.scopedAlloc, 'level', {
configurable: false, enumerable: false, configurable: false, enumerable: false,
@ -1030,15 +1030,15 @@ self.WhWasmUtilInstaller = function(target){
result of calling func(). result of calling func().
*/ */
target.scopedAllocCall = function(func){ target.scopedAllocCall = function(func){
this.scopedAllocPush(); target.scopedAllocPush();
try{ return func() } finally{ this.scopedAllocPop() } try{ return func() } finally{ target.scopedAllocPop() }
}.bind(target); };
/** Internal impl for allocPtr() and scopedAllocPtr(). */ /** Internal impl for allocPtr() and scopedAllocPtr(). */
const __allocPtr = function(howMany, method){ const __allocPtr = function(howMany, method){
__affirmAlloc(this, method); __affirmAlloc(target, method);
let m = this[method](howMany * ptrSizeof); let m = target[method](howMany * ptrSizeof);
this.setMemValue(m, 0, ptrIR) target.setMemValue(m, 0, ptrIR)
if(1===howMany){ if(1===howMany){
return m; return m;
} }
@ -1046,10 +1046,10 @@ self.WhWasmUtilInstaller = function(target){
for(let i = 1; i < howMany; ++i){ for(let i = 1; i < howMany; ++i){
m += ptrSizeof; m += ptrSizeof;
a[i] = m; a[i] = m;
this.setMemValue(m, 0, ptrIR); target.setMemValue(m, 0, ptrIR);
} }
return a; return a;
}.bind(target); };
/** /**
Allocates a single chunk of memory capable of holding `howMany` Allocates a single chunk of memory capable of holding `howMany`
@ -1099,7 +1099,7 @@ self.WhWasmUtilInstaller = function(target){
not legal to pass an Array object to a WASM function.) not legal to pass an Array object to a WASM function.)
*/ */
target.xCall = function(fname, ...args){ target.xCall = function(fname, ...args){
const f = this.xGet(fname); const f = target.xGet(fname);
if(!(f instanceof Function)) toss("Exported symbol",fname,"is not a function."); if(!(f instanceof Function)) toss("Exported symbol",fname,"is not a function.");
if(f.length!==args.length) __argcMismatch(fname,f.length) if(f.length!==args.length) __argcMismatch(fname,f.length)
/* This is arguably over-pedantic but we want to help clients keep /* This is arguably over-pedantic but we want to help clients keep
@ -1107,7 +1107,7 @@ self.WhWasmUtilInstaller = function(target){
return (2===arguments.length && Array.isArray(arguments[1])) return (2===arguments.length && Array.isArray(arguments[1]))
? f.apply(null, arguments[1]) ? f.apply(null, arguments[1])
: f.apply(null, args); : f.apply(null, args);
}.bind(target); };
/** /**
State for use with xWrap() State for use with xWrap()
@ -1181,19 +1181,19 @@ self.WhWasmUtilInstaller = function(target){
*/ */
xcv.arg['func-ptr'] = function(v){ xcv.arg['func-ptr'] = function(v){
if(!(v instanceof Function)) return xcv.arg[ptrIR]; if(!(v instanceof Function)) return xcv.arg[ptrIR];
const f = this.jsFuncToWasm(v, WHAT_SIGNATURE); const f = target.jsFuncToWasm(v, WHAT_SIGNATURE);
}.bind(target); };
} }
const __xArgAdapter = const __xArgAdapterCheck =
(t)=>xcv.arg[t] || toss("Argument adapter not found:",t); (t)=>xcv.arg[t] || toss("Argument adapter not found:",t);
const __xResultAdapter = const __xResultAdapterCheck =
(t)=>xcv.result[t] || toss("Result adapter not found:",t); (t)=>xcv.result[t] || toss("Result adapter not found:",t);
cache.xWrap.convertArg = (t,v)=>__xArgAdapter(t)(v); cache.xWrap.convertArg = (t,v)=>__xArgAdapterCheck(t)(v);
cache.xWrap.convertResult = cache.xWrap.convertResult =
(t,v)=>(null===t ? v : (t ? __xResultAdapter(t)(v) : undefined)); (t,v)=>(null===t ? v : (t ? __xResultAdapterCheck(t)(v) : undefined));
/** /**
Creates a wrapper for the WASM-exported function fname. Uses Creates a wrapper for the WASM-exported function fname. Uses
@ -1327,34 +1327,32 @@ self.WhWasmUtilInstaller = function(target){
if(3===arguments.length && Array.isArray(arguments[2])){ if(3===arguments.length && Array.isArray(arguments[2])){
argTypes = arguments[2]; argTypes = arguments[2];
} }
const xf = this.xGet(fname); const xf = target.xGet(fname);
if(argTypes.length!==xf.length) __argcMismatch(fname, xf.length) if(argTypes.length!==xf.length) __argcMismatch(fname, xf.length);
if((null===resultType) && 0===xf.length){ if((null===resultType) && 0===xf.length){
/* Func taking no args with an as-is return. We don't need a wrapper. */ /* Func taking no args with an as-is return. We don't need a wrapper. */
return xf; return xf;
} }
/*Verify the arg type conversions are valid...*/; /*Verify the arg type conversions are valid...*/;
if(undefined!==resultType && null!==resultType) __xResultAdapter(resultType); if(undefined!==resultType && null!==resultType) __xResultAdapterCheck(resultType);
argTypes.forEach(__xArgAdapter) argTypes.forEach(__xArgAdapterCheck);
if(0===xf.length){ if(0===xf.length){
// No args to convert, so we can create a simpler wrapper... // No args to convert, so we can create a simpler wrapper...
return function(){ return (...args)=>(args.length
return (arguments.length ? __argcMismatch(fname, xf.length)
? __argcMismatch(fname, xf.length) : cache.xWrap.convertResult(resultType, xf.call(null)));
: cache.xWrap.convertResult(resultType, xf.call(null)));
};
} }
return function(...args){ return function(...args){
if(args.length!==xf.length) __argcMismatch(fname, xf.length); if(args.length!==xf.length) __argcMismatch(fname, xf.length);
const scope = this.scopedAllocPush(); const scope = target.scopedAllocPush();
try{ try{
const rc = xf.apply(null,args.map((v,i)=>cache.xWrap.convertArg(argTypes[i], v))); const rc = xf.apply(null,args.map((v,i)=>cache.xWrap.convertArg(argTypes[i], v)));
return cache.xWrap.convertResult(resultType, rc); return cache.xWrap.convertResult(resultType, rc);
}finally{ }finally{
this.scopedAllocPop(scope); target.scopedAllocPop(scope);
} }
}.bind(this); };
}.bind(target)/*xWrap()*/; }/*xWrap()*/;
/** Internal impl for xWrap.resultAdapter() and argAdaptor(). */ /** Internal impl for xWrap.resultAdapter() and argAdaptor(). */
const __xAdapter = function(func, argc, typeName, adapter, modeName, xcvPart){ const __xAdapter = function(func, argc, typeName, adapter, modeName, xcvPart){
@ -1458,8 +1456,8 @@ self.WhWasmUtilInstaller = function(target){
*/ */
target.xCallWrapped = function(fname, resultType, argTypes, ...args){ target.xCallWrapped = function(fname, resultType, argTypes, ...args){
if(Array.isArray(arguments[3])) args = arguments[3]; if(Array.isArray(arguments[3])) args = arguments[3];
return this.xWrap(fname, resultType, argTypes||[]).apply(null, args||[]); return target.xWrap(fname, resultType, argTypes||[]).apply(null, args||[]);
}.bind(target); };
return target; return target;
}; };
@ -1539,10 +1537,11 @@ self.WhWasmUtilInstaller.yawl = function(config){
|| toss("Missing 'memory' object!"); || toss("Missing 'memory' object!");
} }
if(!tgt.alloc && arg.instance.exports.malloc){ if(!tgt.alloc && arg.instance.exports.malloc){
const exports = arg.instance.exports;
tgt.alloc = function(n){ tgt.alloc = function(n){
return this(n) || toss("Allocation of",n,"bytes failed."); return exports.malloc(n) || toss("Allocation of",n,"bytes failed.");
}.bind(arg.instance.exports.malloc); };
tgt.dealloc = function(m){this(m)}.bind(arg.instance.exports.free); tgt.dealloc = function(m){exports.free(m)};
} }
wui(tgt); wui(tgt);
} }

View File

@ -1,5 +1,5 @@
C Lots\sof\stweaking\sin\sbatch-runner.js.\sMinor\sinternal\sAPI\supdate\sin\sOO\s#1\sAPI. C wasm\sutil:\sremove\ssuperfluous\sfunction.bind()\scalls\sto\seliminate\sa\slevel\sof\scall()\sindirection.
D 2022-08-29T18:58:38.025 D 2022-08-30T09:49:30.007
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
@ -494,7 +494,7 @@ F ext/wasm/batch-runner.js 84a465acde760de81d0372415cce56737799876395a878c44a7d3
F ext/wasm/common/SqliteTestUtil.js eb96275bed43fdb364b7d65bcded0ca5e22aaacff120d593d1385f852f486247 F ext/wasm/common/SqliteTestUtil.js eb96275bed43fdb364b7d65bcded0ca5e22aaacff120d593d1385f852f486247
F ext/wasm/common/emscripten.css 3d253a6fdb8983a2ac983855bfbdd4b6fa1ff267c28d69513dd6ef1f289ada3f F ext/wasm/common/emscripten.css 3d253a6fdb8983a2ac983855bfbdd4b6fa1ff267c28d69513dd6ef1f289ada3f
F ext/wasm/common/testing.css 572cf1ffae0b6eb7ca63684d3392bf350217a07b90e7a896e4fa850700c989b0 F ext/wasm/common/testing.css 572cf1ffae0b6eb7ca63684d3392bf350217a07b90e7a896e4fa850700c989b0
F ext/wasm/common/whwasmutil.js e1c6779c977c8614053e24311d489dd4872962cb58c27013d4778f0dd7329e9c F ext/wasm/common/whwasmutil.js 3d68a9cd87a2d8f7e6d5a78f3b829a927f2e28422685e029139f6e75d4ed42e4
F ext/wasm/demo-oo1.html 75646855b38405d82781246fd08c852a2b3bee05dd9f0fe10ab655a8cffb79aa F ext/wasm/demo-oo1.html 75646855b38405d82781246fd08c852a2b3bee05dd9f0fe10ab655a8cffb79aa
F ext/wasm/demo-oo1.js aad38cb90b6fa7fd4d1184e759b25056fb4ed45c4957c458896354281259515f F ext/wasm/demo-oo1.js aad38cb90b6fa7fd4d1184e759b25056fb4ed45c4957c458896354281259515f
F ext/wasm/fiddle/emscripten.css 3d253a6fdb8983a2ac983855bfbdd4b6fa1ff267c28d69513dd6ef1f289ada3f F ext/wasm/fiddle/emscripten.css 3d253a6fdb8983a2ac983855bfbdd4b6fa1ff267c28d69513dd6ef1f289ada3f
@ -2012,8 +2012,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 e5b7006f0f57f10a490d7eaeb7df77251a2f684602fed8ff161d8ce60033e7bc P 24b82b9504db3d8e1335c2300b133f897dc1a541026dc24be5b0ffd8be66d977
R ac09921b66efbf8cc7311954674841d9 R c9f285330e60c2a709dc88c6f308d17d
U stephan U stephan
Z 16cfbad53a69907d89a4919845ccdd35 Z 746ec57f2eb86d7d664aa6615f7c7bf3
# Remove this line to create a well-formed Fossil manifest. # Remove this line to create a well-formed Fossil manifest.

View File

@ -1 +1 @@
24b82b9504db3d8e1335c2300b133f897dc1a541026dc24be5b0ffd8be66d977 1aab9627983ef0f016b01f78564e79cf815ed14d4b1b6dc04ec627b96f1b2f70