aboutsummaryrefslogtreecommitdiff
path: root/ext/wasm/common/whwasmutil.js
diff options
context:
space:
mode:
authorstephan <stephan@noemail.net>2022-12-09 05:47:42 +0000
committerstephan <stephan@noemail.net>2022-12-09 05:47:42 +0000
commit464c80d4c22d03840c35b7e3748183b361257a9f (patch)
tree24c2ff5681ca5720a8deb405f1c425bc245e964e /ext/wasm/common/whwasmutil.js
parent75f54dba501a5f5d9709956d67db22b29d6ce802 (diff)
downloadsqlite-464c80d4c22d03840c35b7e3748183b361257a9f.tar.gz
sqlite-464c80d4c22d03840c35b7e3748183b361257a9f.zip
Export sqlite3_status() and sqlite3_stmt_status() to wasm. Expand the arg/return semantics of wasm.get/setPtrValue() and get/setMemValue() to simplify handling of multiple pointers.
FossilOrigin-Name: e144fd5c88fa4151429a2fef3daf389588402e158267f0afa0dfd142527d76b9
Diffstat (limited to 'ext/wasm/common/whwasmutil.js')
-rw-r--r--ext/wasm/common/whwasmutil.js109
1 files changed, 71 insertions, 38 deletions
diff --git a/ext/wasm/common/whwasmutil.js b/ext/wasm/common/whwasmutil.js
index 0da1841b6..3f3281876 100644
--- a/ext/wasm/common/whwasmutil.js
+++ b/ext/wasm/common/whwasmutil.js
@@ -599,6 +599,11 @@ self.WhWasmUtilInstaller = function(target){
type triggers an exception if this.bigIntEnabled is
falsy). Throws if given an invalid type.
+ If the first argument is an array, it is treated as an array of
+ addresses and the result is an array of the values from each of
+ those address, using the same 2nd argument for determining the
+ value type to fetch.
+
As a special case, if type ends with a `*`, it is considered to
be a pointer type and is treated as the WASM numeric type
appropriate for the pointer size (`i32`).
@@ -641,23 +646,33 @@ self.WhWasmUtilInstaller = function(target){
See: setMemValue()
*/
- target.getMemValue = function(ptr, type='i8'){
+ target.getMemValue = function f(ptr, type='i8'){
if(type.endsWith('*')) type = ptrIR;
const c = (cache.memory && cache.heapSize === cache.memory.buffer.byteLength)
? cache : heapWrappers();
- switch(type){
- case 'i1':
- case 'i8': return c.HEAP8[ptr>>0];
- case 'i16': return c.HEAP16[ptr>>1];
- case 'i32': return c.HEAP32[ptr>>2];
- case 'i64':
- if(target.bigIntEnabled) return BigInt(c.HEAP64[ptr>>3]);
- break;
- case 'float': case 'f32': return c.HEAP32F[ptr>>2];
- case 'double': case 'f64': return Number(c.HEAP64F[ptr>>3]);
- default: break;
- }
- toss('Invalid type for getMemValue():',type);
+ const list = Array.isArray(ptr) ? [] : undefined;
+ let rc;
+ do{
+ if(list) ptr = arguments[0].shift();
+ switch(type){
+ case 'i1':
+ case 'i8': rc = c.HEAP8[ptr>>0]; break;
+ case 'i16': rc = c.HEAP16[ptr>>1]; break;
+ case 'i32': rc = c.HEAP32[ptr>>2]; break;
+ case 'float': case 'f32': rc = c.HEAP32F[ptr>>2]; break;
+ case 'double': case 'f64': rc = Number(c.HEAP64F[ptr>>3]); break;
+ case 'i64':
+ if(target.bigIntEnabled){
+ rc = BigInt(c.HEAP64[ptr>>3]);
+ break;
+ }
+ /* fallthru */
+ default:
+ toss('Invalid type for getMemValue():',type);
+ }
+ if(list) list.push(rc);
+ }while(list && arguments[0].length);
+ return list || rc;
};
/**
@@ -668,41 +683,59 @@ self.WhWasmUtilInstaller = function(target){
argument ends with `*` then it is treated as a pointer type and
this function behaves as if the 3rd argument were `i32`.
- This function returns itself.
+ If the first argument is an array, it is treated like a list
+ of pointers and the given value is written to each one.
+
+ Returns `this`. (Prior to 2022-12-09 it returns this function.)
ACHTUNG: calling this often, e.g. in a loop, can have a noticably
painful impact on performance. Rather than doing so, use
- heapForSize() to fetch the heap object and assign directly to it.
+ heapForSize() to fetch the heap object and assign directly to it
+ or use the heap's set() method.
*/
- target.setMemValue = function f(ptr, value, type='i8'){
+ target.setMemValue = function(ptr, value, type='i8'){
if (type.endsWith('*')) type = ptrIR;
const c = (cache.memory && cache.heapSize === cache.memory.buffer.byteLength)
? cache : heapWrappers();
- switch (type) {
- case 'i1':
- case 'i8': c.HEAP8[ptr>>0] = value; return f;
- case 'i16': c.HEAP16[ptr>>1] = value; return f;
- case 'i32': c.HEAP32[ptr>>2] = value; return f;
- case 'i64':
- if(c.HEAP64){
- c.HEAP64[ptr>>3] = BigInt(value);
- return f;
- }
- break;
- case 'float': case 'f32': c.HEAP32F[ptr>>2] = value; return f;
- case 'double': case 'f64': c.HEAP64F[ptr>>3] = value; return f;
+ for(const p of (Array.isArray(ptr) ? ptr : [ptr])){
+ switch (type) {
+ case 'i1':
+ case 'i8': c.HEAP8[p>>0] = value; continue;
+ case 'i16': c.HEAP16[p>>1] = value; continue;
+ case 'i32': c.HEAP32[p>>2] = value; continue;
+ case 'float': case 'f32': c.HEAP32F[p>>2] = value; continue;
+ case 'double': case 'f64': c.HEAP64F[p>>3] = value; continue;
+ case 'i64':
+ if(c.HEAP64){
+ c.HEAP64[p>>3] = BigInt(value);
+ continue;
+ }
+ /* fallthru */
+ default:
+ toss('Invalid type for setMemValue(): ' + type);
+ }
}
- toss('Invalid type for setMemValue(): ' + type);
+ return this;
};
+ /**
+ Convenience form of getMemValue() intended for fetching
+ pointer-to-pointer values. If passed a single non-array argument
+ it returns the value of that one pointer address. If passed
+ multiple arguments, or a single array of arguments, it returns an
+ array of their values.
+ */
+ target.getPtrValue = function(...ptr){
+ return target.getMemValue( (1===ptr.length ? ptr[0] : ptr), ptrIR );
+ };
- /** Convenience form of getMemValue() intended for fetching
- pointer-to-pointer values. */
- target.getPtrValue = (ptr)=>target.getMemValue(ptr, ptrIR);
-
- /** Convenience form of setMemValue() intended for setting
- pointer-to-pointer values. */
- target.setPtrValue = (ptr, value)=>target.setMemValue(ptr, value, ptrIR);
+ /**
+ A variant of setMemValue() intended for setting
+ pointer-to-pointer values. Its differences from setMemValue() are
+ that (1) it defaults to a value of 0, (2) it always writes
+ to the pointer-sized heap view, and (3) it returns `this`.
+ */
+ target.setPtrValue = (ptr, value=0)=>target.setMemValue(ptr, value, ptrIR);
/**
Returns true if the given value appears to be legal for use as