]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Further work on 64-bit WASM builds. It now gets through just shy of half of tester1.js.
authorstephan <stephan@noemail.net>
Sat, 20 Sep 2025 15:16:55 +0000 (15:16 +0000)
committerstephan <stephan@noemail.net>
Sat, 20 Sep 2025 15:16:55 +0000 (15:16 +0000)
FossilOrigin-Name: c8deed31365898e1379d577298fc80ef08a5531999d5b54a9f14337febed0260

ext/wasm/api/sqlite3-api-cleanup.js
ext/wasm/api/sqlite3-api-glue.c-pp.js
ext/wasm/api/sqlite3-api-oo1.c-pp.js
ext/wasm/api/sqlite3-api-prologue.js
ext/wasm/common/whwasmutil.js
ext/wasm/tester1.c-pp.js
manifest
manifest.uuid

index 7fb29e6487e43f6f729bfb4c7d40b07ff463bf42..57aa3351234cc5814a951c4ee0c1c322dd7df4f8 100644 (file)
 'use strict';
 if('undefined' !== typeof Module){ // presumably an Emscripten build
   /**
-     Install a suitable default configuration for sqlite3ApiBootstrap().
+     The WASM-environment-specific configuration pieces
+     for sqlite3ApiBootstrap().
   */
   const SABC = Object.assign(
-    Object.create(null), {
+    Object.create(null),
+    globalThis.sqlite3ApiConfig || {},
+    {
       exports: ('undefined'===typeof wasmExports)
         ? Module['asm']/* emscripten <=3.1.43 */
         : wasmExports  /* emscripten >=3.1.44 */,
-      memory: Module.wasmMemory /* gets set if built with -sIMPORTED_MEMORY */
-    },
-    globalThis.sqlite3ApiConfig || {}
+      memory: Module.wasmMemory /* gets set if built with -sIMPORTED_MEMORY */,
+//#if sMEMORY64=1
+      wasmPtrSizeof: 8,
+      wasmPtrIR: 'i64',
+//#elif sMEMORY64=2
+      wasmPtrSizeof: 8/*???*/,
+      wasmPtrIR: 'i64'/*???*/,
+//#else
+      wasmPtrSizeof: 4,
+      wasmPtrIR: 'i32',
+//#endif
+    }
   );
 
   /**
@@ -44,10 +56,11 @@ if('undefined' !== typeof Module){ // presumably an Emscripten build
      able to provide the necessary configuration state.
   */
   //console.warn("globalThis.sqlite3ApiConfig = ",globalThis.sqlite3ApiConfig);
-  globalThis.sqlite3ApiConfig = SABC;
-  let sqlite3;
   try{
-    sqlite3 = globalThis.sqlite3ApiBootstrap();
+    Module.sqlite3 = globalThis.sqlite3ApiBootstrap(SABC)
+      /* Our customized sqlite3InitModule() in extern-post-js.js needs
+         this to be able to pass the sqlite3 object off to the
+         client. */;
   }catch(e){
     console.error("sqlite3ApiBootstrap() error:",e);
     throw e;
@@ -56,8 +69,6 @@ if('undefined' !== typeof Module){ // presumably an Emscripten build
     delete globalThis.sqlite3ApiConfig;
   }
 
-  Module.sqlite3 = sqlite3 /* Needed for customized sqlite3InitModule() to be able to
-                              pass the sqlite3 object off to the client. */;
 }else{
   console.warn("This is not running in an Emscripten module context, so",
                "globalThis.sqlite3ApiBootstrap() is _not_ being called due to lack",
index fa0f1ae49129cf0de83bf28d92d1e25552ce09cb..09f757bdea632f007e08274401a302e9af9d1f24 100644 (file)
@@ -21,13 +21,6 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
   'use strict';
   const toss = (...args)=>{throw new Error(args.join(' '))};
   const capi = sqlite3.capi, wasm = sqlite3.wasm, util = sqlite3.util;
-//#if sMEMORY64=1
-  wasm.pointerIR = 'i64';
-//#elif sMEMORY64=2
-  wasm.pointerIR = 'i64'/*???*/;
-//#else
-  wasm.pointerIR = 'i32';
-//#endif
   globalThis.WhWasmUtilInstaller(wasm);
   delete globalThis.WhWasmUtilInstaller;
 
@@ -1099,7 +1092,6 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
        wasm.uninstallFunction() any WASM function bindings it has
        installed for pDb.
     */
-    const closeArgs = [pDb];
     for(const name of [
       'sqlite3_busy_handler',
       'sqlite3_commit_hook',
@@ -1119,15 +1111,19 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
         /* assume it was built without this API */
         continue;
       }
+      const closeArgs = [pDb];
       closeArgs.length = x.length/*==argument count*/
         || 1 /* Recall that: (A) undefined entries translate to 0 when
                 passed to WASM and (B) Safari wraps wasm.exports.* in
                 nullary functions so x.length is 0 there. */;
+      //console.debug(closeArgs, name,"()", capi[name]);
+      //wasm.xWrap.debug = true;
       try{ capi[name](...closeArgs) }
       catch(e){
         /* This "cannot happen" unless something is well and truly sideways. */
         sqlite3.config.warn("close-time call of",name+"(",closeArgs,") threw:",e);
       }
+      //wasm.xWrap.debug = false;
     }
     const m = __dbCleanupMap(pDb, 0);
     if(!m) return;
@@ -1475,9 +1471,9 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
        Helper for string:flexible conversions which requires a
        byte-length counterpart argument. Passed a value and its
        ostensible length, this function returns [V,N], where V is
-       either v or a transformed copy of v and N is either n (if v is
-       a WASM pointer), -1 (if v is a string or Array), or the byte
-       length of v (if it's a byte array or ArrayBuffer).
+       either v or a transformed copy of v and N is either Number(n)
+       (if v is a WASM pointer), -1 (if v is a string or Array), or
+       the byte length of v (if it's a byte array or ArrayBuffer).
     */
     const __flexiString = (v,n)=>{
       if('string'===typeof v){
@@ -1490,7 +1486,13 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
       }else if(Array.isArray(v)){
         v = v.join("");
         n = -1;
-      }
+      }/*else if( 'bigint'===typeof n ){
+        // tag:64-bit A workaround for when a stray BigInt, possibly
+        // calculated via a pointer range, gets passed in here. This
+        // has been seen to happen in sqlite3_prepare_v3() via
+        // oo1.DB.exec().
+        n = Number(n);
+      }*/
       return [v, n];
     };
 
@@ -1531,13 +1533,14 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
       }
       const [xSql, xSqlLen] = __flexiString(sql, sqlLen);
       switch(typeof xSql){
-          case 'string': return __prepare.basic(pDb, xSql, xSqlLen, prepFlags, ppStmt, null);
-          case 'number': return __prepare.full(pDb, xSql, xSqlLen, prepFlags, ppStmt, pzTail);
-          default:
-            return util.sqlite3__wasm_db_error(
-              pDb, capi.SQLITE_MISUSE,
-              "Invalid SQL argument type for sqlite3_prepare_v2/v3()."
-            );
+        case 'string': return __prepare.basic(pDb, xSql, xSqlLen, prepFlags, ppStmt, null);
+        case (typeof wasm.NullPtr):
+          return __prepare.full(pDb, xSql, xSqlLen, prepFlags, ppStmt, pzTail);
+        default:
+          return util.sqlite3__wasm_db_error(
+            pDb, capi.SQLITE_MISUSE,
+            "Invalid SQL argument type for sqlite3_prepare_v2/v3(). typeof="+(typeof xSql)
+          );
       }
     };
 
index a0fac358faed02f1098f830e25dd283c44be1e9b..4dfd0a933fc5082d0013debec78fdfc2436ed974 100644 (file)
@@ -1051,14 +1051,14 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
         let sqlByteLen = isTA ? arg.sql.byteLength : wasm.jstrlen(arg.sql);
         const ppStmt  = wasm.scopedAlloc(
           /* output (sqlite3_stmt**) arg and pzTail */
-          (2 * wasm.ptrSizeof) + (sqlByteLen + 1/* SQL + NUL */)
+          (2 * wasm.pointerSizeof) + (sqlByteLen + 1/* SQL + NUL */)
         );
-        const pzTail = ppStmt + wasm.ptrSizeof /* final arg to sqlite3_prepare_v2() */;
-        let pSql = pzTail + wasm.ptrSizeof;
-        const pSqlEnd = pSql + sqlByteLen;
+        const pzTail = wasm.ptrAdd(ppStmt, wasm.pointerSizeof) /* final arg to sqlite3_prepare_v2() */;
+        let pSql = wasm.ptrAdd(pzTail, wasm.pointerSizeof);
+        const pSqlEnd = wasm.ptrAdd(pSql, sqlByteLen);
         if(isTA) wasm.heap8().set(arg.sql, pSql);
         else wasm.jstrcpy(arg.sql, wasm.heap8(), pSql, sqlByteLen, false);
-        wasm.poke(pSql + sqlByteLen, 0/*NUL terminator*/);
+        wasm.poke(wasm.ptrAdd(pSql, sqlByteLen), 0/*NUL terminator*/);
         while(pSql && wasm.peek(pSql, 'i8')
               /* Maintenance reminder:^^^ _must_ be 'i8' or else we
                  will very likely cause an endless loop. What that's
@@ -1073,7 +1073,7 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
           ));
           const pStmt = wasm.peekPtr(ppStmt);
           pSql = wasm.peekPtr(pzTail);
-          sqlByteLen = pSqlEnd - pSql;
+          sqlByteLen = Number(wasm.ptrAdd(pSqlEnd,-pSql));
           if(!pStmt) continue;
           if(saveSql) saveSql.push(capi.sqlite3_sql(pStmt).trim());
           stmt = new Stmt(this, pStmt, BindTypes);
@@ -2091,15 +2091,14 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
             const n = capi.sqlite3_column_bytes(this.pointer, ndx),
                   ptr = capi.sqlite3_column_blob(this.pointer, ndx),
                   rc = new Uint8Array(n);
-            //heap = n ? wasm.heap8() : false;
-            if(n) rc.set(wasm.heap8u().slice(ptr, ptr+n), 0);
-            //for(let i = 0; i < n; ++i) rc[i] = heap[ptr + i];
-            if(n && this.db._blobXfer instanceof Array){
-              /* This is an optimization soley for the
-                 Worker-based API. These values will be
-                 transfered to the main thread directly
-                 instead of being copied. */
-              this.db._blobXfer.push(rc.buffer);
+            if(n){
+              rc.set(wasm.heap8u().slice(Number(ptr), Number(ptr)+n), 0);
+              if(this.db._blobXfer instanceof Array){
+                /* This is an optimization soley for the Worker1 API. It
+                   will transfer these to the main thread directly
+                   instead of copying them. */
+                this.db._blobXfer.push(rc.buffer);
+              }
             }
             return rc;
           }
index 733782dd121a63d9798cc663460799603f08e15e..a14f7692d5dc4ccbfaa8e506804e0808f7171dd8 100644 (file)
@@ -150,18 +150,23 @@ globalThis.sqlite3ApiBootstrap = function sqlite3ApiBootstrap(
        it becomes significant with, e.g., sqlite3_deserialize() and
        certain wasm.xWrap.resultAdapter()s.
     */
-    useStdAlloc: false
+    useStdAlloc: false,
+    /*
+      sqlite3-api-cleanup.js sets wasmPtrSizeof and wasmPtrIR
+    */
+    wasmPtrSizeof: 4,
+    wasmPtrIR: 'i32'
   }, apiConfig || {});
 
   Object.assign(config, {
     allocExportName: config.useStdAlloc ? 'malloc' : 'sqlite3_malloc',
     deallocExportName: config.useStdAlloc ? 'free' : 'sqlite3_free',
     reallocExportName: config.useStdAlloc ? 'realloc' : 'sqlite3_realloc'
-  }, config);
+  });
 
   [
     // If any of these config options are functions, replace them with
-    // the result of calling that function...
+    // the result of calling that function. They must not be async.
     'exports', 'memory', 'wasmfsOpfsDir'
   ].forEach((k)=>{
     if('function' === typeof config[k]){
@@ -846,6 +851,10 @@ globalThis.sqlite3ApiBootstrap = function sqlite3ApiBootstrap(
     }
   }/*util*/;
 
+  /**
+     wasm.X properties which are used for configuring the wasm
+     environment via whwashutil.js.
+  */
   Object.assign(wasm, {
     /**
        Emscripten APIs have a deep-seated assumption that all pointers
@@ -853,13 +862,13 @@ globalThis.sqlite3ApiBootstrap = function sqlite3ApiBootstrap(
        the case and will use this constant in places where we might
        otherwise use a hard-coded 4.
     */
-    ptrSizeof: config.wasmPtrSizeof || 4,
+    pointerSizeof: config.wasmPtrSizeof,
     /**
        The WASM IR (Intermediate Representation) value for
        pointer-type values. It MUST refer to a value type of the
-       size described by this.ptrSizeof.
+       size described by this.pointerSizeof.
     */
-    ptrIR: config.wasmPtrIR || "i32",
+    pointerIR: config.wasmPtrIR,
     /**
        True if BigInt support was enabled via (e.g.) the
        Emscripten -sWASM_BIGINT flag, else false. When
@@ -1156,14 +1165,14 @@ globalThis.sqlite3ApiBootstrap = function sqlite3ApiBootstrap(
         WasmAllocError.toss("Invalid size value for allocChunks(",arguments[1],")");
       }
       const mem = wasm.pstack.alloc(n * sz);
-      const rc = [];
-      let i = 0, offset = 0;
+      const rc = [mem];
+      let i = 1, offset = sz;
       for(; i < n; ++i, offset += sz) rc.push(wasm.ptrAdd(mem, offset));
       return rc;
     },
     /**
        A convenience wrapper for allocChunks() which sizes each chunk
-       as either 8 bytes (safePtrSize is truthy) or wasm.ptrSizeof (if
+       as either 8 bytes (safePtrSize is truthy) or wasm.pointerSizeof (if
        safePtrSize is falsy).
 
        How it returns its result differs depending on its first
@@ -1182,8 +1191,8 @@ globalThis.sqlite3ApiBootstrap = function sqlite3ApiBootstrap(
     */
     allocPtr: (n=1,safePtrSize=true)=>{
       return 1===n
-        ? wasm.pstack.alloc(safePtrSize ? 8 : wasm.ptrSizeof)
-        : wasm.pstack.allocChunks(n, safePtrSize ? 8 : wasm.ptrSizeof);
+        ? wasm.pstack.alloc(safePtrSize ? 8 : wasm.pointerSizeof)
+        : wasm.pstack.allocChunks(n, safePtrSize ? 8 : wasm.pointerSizeof);
     },
 
     /**
@@ -1403,7 +1412,7 @@ globalThis.sqlite3ApiBootstrap = function sqlite3ApiBootstrap(
     const scope = wasm.scopedAllocPush();
     let pOut;
     try{
-      const pSize = wasm.scopedAlloc(8/*i64*/ + wasm.ptrSizeof);
+      const pSize = wasm.scopedAlloc(8/*i64*/ + wasm.pointerSizeof);
       const ppOut = pSize + 8;
       /**
          Maintenance reminder, since this cost a full hour of grief
@@ -1853,7 +1862,7 @@ globalThis.sqlite3ApiBootstrap = function sqlite3ApiBootstrap(
          do not.
       */
       tgt.push(capi.sqlite3_value_to_js(
-        wasm.peekPtr(pArgv + (wasm.ptrSizeof * i)),
+        wasm.peekPtr(pArgv + (wasm.pointerSizeof * i)),
         throwIfCannotConvert
       ));
     }
index 155e1f2dee78740a0394d2e5e35508cf27da4e52..6f9edb9b5b38e1139b69f20d58884ca6b57e3380 100644 (file)
 
   https://fossil.wanderinghorse.net/r/jaccwabyt
 
+  More specifically:
+
+  https://fossil.wanderinghorse.net/r/jaccwabyt/file/common/whwasmutil.js
+
   and SQLite:
 
   https://sqlite.org
    utility APIs provided by this code are still usable as replacements
    for their Emscripten counterparts.
 
-   Forewarning: this API explicitly targets only browser
-   environments. If a given non-browser environment has the
-   capabilities needed for a given feature (e.g. TextEncoder), great,
-   but it does not go out of its way to account for them and does not
-   provide compatibility crutches for them.
+   Forewarning: this API explicitly targets only browser environments.
+   If a given non-browser environment has the capabilities needed for
+   a given feature (e.g. TextEncoder), great, but it does not go out
+   of its way to account for them and does not provide compatibility
+   crutches for them.
 
    Intended usage:
 
 
    - `pointerIR`: an IR-format string for the WASM environment's
       pointer size. If set it must be either 'i32' or 'i64'. If not
-      set, it defaults to whatever this code thinks the pointer size
+      set, it gets set to whatever this code thinks the pointer size
       is.  Modifying it after this call has no effect.
-      target.pointerSizeof gets set to either 4 or 8, depending on
-      this option.
-
 
-   This code is developed and maintained in conjunction with the
-   Jaccwabyt project:
+   - `pointerSizeof`: if set, it must be one of 4 or 8 and must
+      correspond to the value of `pointerIR`. If not set, it gets set
+      to whatever this code thinks the pointer size is (4 unless
+      `pointerIR` is 'i64'). If `pointerSizeof` is set but `pointerIR`
+      is not, `pointerIR` gets set appropriately, and vice versa.
 
-   https://fossil.wanderinghorse.net/r/jaccwabyt
+   When building with Emscripten's -sMEMORY64=1, `pointerIR` must be
+   set to 'i64' and/or `pointerSizeof` must be set to 8.
 
-   More specifically:
+   Design notes:
 
-   https://fossil.wanderinghorse.net/r/jaccwabyt/file/common/whwasmutil.js
+   - It should probably take a config object and return the
+     target. The current approach seemed better at the time.
 */
 globalThis.WhWasmUtilInstaller = function(target){
   'use strict';
@@ -187,12 +193,53 @@ globalThis.WhWasmUtilInstaller = function(target){
       all args with a space between each. */
   const toss = (...args)=>{throw new Error(args.join(' '))};
 
-  if(!target.exports){
-    Object.defineProperty(target, 'exports', {
-      enumerable: true, configurable: true,
-      get: ()=>(target.instance && target.instance.exports)
-    });
+  /**
+     Pointers in WASM are currently assumed to be 32-bit, but someday
+     that will certainly change.
+
+     2025-09-19: work has started in getting this library to work with
+     Emscripten's -sMEMORY64=1.
+  */
+  if( target.pointerSizeof && !target.pointerIR ){
+    target.pointerIR = (4===target.pointerSizeof ? 'i32' : 'i64');
+  }
+  const ptrIR = (target.pointerIR ??= 'i32');
+  const ptrSizeof = (target.pointerSizeof ??=
+                     ('i32'===ptrIR ? 4 : ('i64'===ptrIR ? 8 : 0)));
+
+  if( 'i32'!==ptrIR && 'i64'!==ptrIR ){
+    toss("Invalid pointerIR:",ptrIR);
   }
+  if( 8!==ptrSizeof && 4!==ptrSizeof ){
+    toss("Invalid pointerSizeof:",ptrSizeof);
+  }
+
+  /**
+     If target.pointerIR=='i32' then this is equivalent to
+     Number(v) else it's equivalent to BigInt(v||0).
+
+     Why? Because Number(null)===0, but BigInt(null) throws.
+  */
+  const __asPtrType = (4===ptrSizeof)
+        ? Number
+        : (target.bigIntEnabled
+           ? ((v)=>BigInt(v || 0))
+           : toss("Missing BigInt support"));
+
+  target.asPtrType = __asPtrType;
+
+  /**
+     The number 0 as either type Number or BigInt, depending on
+     target.pointerIR.
+  */
+  const __NullPtr = __asPtrType(0);
+
+  target.NullPtr = __NullPtr;
+
+  /**
+     The typeof X value for target.NullPtr
+  */
+  //target.pointerTypeof = typeof __NullPtr;
 
   /*********
     alloc()/dealloc() auto-install...
@@ -223,30 +270,6 @@ globalThis.WhWasmUtilInstaller = function(target){
     }
   }*******/
 
-  /**
-     Pointers in WASM are currently assumed to be 32-bit, but someday
-     that will certainly change.
-  */
-  const ptrIR = target.pointerIR || (target.pointerIR = 'i32');
-  const ptrSizeof = target.pointerSizeof =
-        ('i32'===ptrIR ? 4
-         : ('i64'===ptrIR
-            ? 8 : toss("Unhandled pointerIR:",ptrIR)));
-
-  /**
-     If target.pointerIR=='i32' then this is equivalent to
-     Number(v) else it's equivalent to BigInt(v||0).
-
-     Why? Because Number(null)===0, but BigInt(null) throws.
-  */
-  const __asPtrType = ('i32'==ptrIR)
-        ? Number
-        : (target.bigIntEnabled
-           ? ((v)=>BigInt(v || 0))
-           : toss("Missing BigInt support"));
-
-  target.asPtrType = __asPtrType;
-
   /**
      Expects any number of numeric arguments, each one of either type
      Number or BigInt. It sums them up (from an implicit starting
@@ -267,13 +290,13 @@ globalThis.WhWasmUtilInstaller = function(target){
 
   target.ptrAdd = __ptrAdd;
 
-  /**
-     The number 0 as either type Number or BigInt, depending on
-     target.pointerIR.
-  */
-  const __NullPtr = __asPtrType(0);
 
-  target.NullPtr = __NullPtr;
+  if(!target.exports){
+    Object.defineProperty(target, 'exports', {
+      enumerable: true, configurable: true,
+      get: ()=>(target?.instance?.exports)
+    });
+  }
 
   /** Stores various cached state. */
   const cache = Object.create(null);
@@ -898,12 +921,11 @@ globalThis.WhWasmUtilInstaller = function(target){
   */
   target.isPtr32 = (ptr)=>('number'===typeof ptr && (ptr===(ptr|0)) && ptr>=0);
 
-  /* UNTESTED */
   target.isPtr64 = (ptr)=>{
     if( 'bigint'===typeof ptr ){
       return ptr >= 0;
     }
-    return ('number'===typeof ptr && (ptr===(ptr|0)) && ptr>=0);
+    return ('number'===typeof ptr && ptr>=0 && (ptr===(ptr|0)));
   };
 
   /**
@@ -1034,6 +1056,8 @@ globalThis.WhWasmUtilInstaller = function(target){
     if(!tgt || (!(tgt instanceof Int8Array) && !(tgt instanceof Uint8Array))){
       toss("jstrcpy() target must be an Int8Array or Uint8Array.");
     }
+    maxBytes = Number(maxBytes)/*tag:64bit*/;
+    offset = Number(offset)/*tag:64bit*/;
     if(maxBytes<0) maxBytes = tgt.length - offset;
     if(!(maxBytes>0) || !(offset>=0)) return 0;
     let i = 0, max = jstr.length;
@@ -1498,7 +1522,17 @@ globalThis.WhWasmUtilInstaller = function(target){
     xArg.set('i64', (i)=>BigInt(i || 0));
   }
   const __xArgPtr = __asPtrType;
-  xArg.set('i32', (i)=>(i | 0) )
+  xArg.set(
+    'i32',
+    0
+      ? (i)=>Number(i) | 0
+    /* This Number(i) is unsatisfying but it enables i32-type args which
+       are inadvertently passed a BigInt (which is easy to do) to
+       play along instead of causing an exception about lack of implicit
+       conversions from BigInt to Number. */
+      : (i)=>i|0
+  );
+  xArg
     .set('i16', (i)=>((i | 0) & 0xFFFF))
     .set('i8', (i)=>((i | 0) & 0xFF))
     .set('f32', (i)=>Number(i).valueOf())
@@ -1796,13 +1830,19 @@ globalThis.WhWasmUtilInstaller = function(target){
        exactly the 2nd and 3rd arguments are.
     */
     convertArg(v,argv,argIndex){
-      //FuncPtrAdapter.debugOut("FuncPtrAdapter.convertArg()",this.name,this.signature,this.transient,v);
       let pair = this.singleton;
       if(!pair && this.isContext){
         pair = this.contextMap(this.contextKey(argv,argIndex));
         //FuncPtrAdapter.debugOut(this.name, this.signature, "contextKey() =",this.contextKey(argv,argIndex), pair);
       }
-      if(pair && pair[0]===v){
+      if( 0 ){
+        FuncPtrAdapter.debugOut("FuncPtrAdapter.convertArg()",this.name,
+                                'signature =',this.signature,
+                                'transient ?=',this.transient,
+                                'pair =',pair,
+                                'v =',v);
+      }
+      if(pair && 2===pair.length && pair[0]===v){
         /* We have already handled this function. */
         return pair[1];
       }
@@ -1838,23 +1878,22 @@ globalThis.WhWasmUtilInstaller = function(target){
             }
             catch(e){/*ignored*/}
           }
-          pair[0] = arguments[0]/*the original v*/;
+          pair[0] = arguments[0] || __NullPtr/*the original v*/;
           pair[1] = fp;
         }
         return fp;
       }else if(target.isPtr(v) || null===v || undefined===v){
-        //FuncPtrAdapter.debugOut("FuncPtrAdapter.convertArg()",this.name,this.signature,this.transient,v,pair);
         if(pair && pair[1] && pair[1]!==v){
           /* uninstall stashed mapping and replace stashed mapping with v. */
           if(FuncPtrAdapter.debugFuncInstall){
             FuncPtrAdapter.debugOut("FuncPtrAdapter uninstalling", this,
                                     this.contextKey(argv,argIndex), '@'+pair[1], v);
           }
-          try{ cache.scopedAlloc.pushPtr(pair[1]); }
+          try{cache.scopedAlloc.pushPtr(pair[1]);/*see notes above*/}
           catch(e){/*ignored*/}
-          pair[0] = pair[1] = (v | 0);
+          pair[0] = pair[1] = (v || __NullPtr);
         }
-        return v || 0;
+        return v || __NullPtr;
       }else{
         throw new TypeError("Invalid FuncPtrAdapter argument type. "+
                             "Expecting a function pointer or a "+
@@ -2150,6 +2189,9 @@ globalThis.WhWasmUtilInstaller = function(target){
           https://sqlite.org/forum/forumpost/b549992634b55104
         */
         let i = 0;
+        if( callee.debug ){
+          console.debug("xWrap() preparing: resultType ",resultType, 'xf',xf,"argTypes",argTypes,"args",args);
+        }
         for(; i < args.length; ++i) args[i] = cxw.convertArgNoCheck(
           argTypes[i], args[i], args, i
         );
@@ -2327,28 +2369,26 @@ globalThis.WhWasmUtilInstaller = function(target){
 
    - `uri`: required URI of the WASM file to load.
 
-   - `onload(loadResult,config)`: optional callback. The first
-     argument is the result object from
-     WebAssembly.instantiate[Streaming](). The 2nd is the config
-     object passed to this function. Described in more detail below.
+   - `onload(loadResult)`: optional callback. Its argument is an
+     object described in more detail below.
 
    - `imports`: optional imports object for
-     WebAssembly.instantiate[Streaming](). The default is an empty set
-     of imports. If the module requires any imports, this object
+     WebAssembly.instantiate[Streaming]().  The default is an empty
+     set of imports. If the module requires any imports, this object
      must include them.
 
    - `wasmUtilTarget`: optional object suitable for passing to
      WhWasmUtilInstaller(). If set, it gets passed to that function
-     after the promise resolves. This function sets several properties
-     on it before passing it on to that function (which sets many
-     more):
+     before the returned promise resolves. This function sets several
+     properties on it before passing it on to that function (which
+     sets many more):
 
      - `module`, `instance`: the properties from the
        instantiate[Streaming]() result.
 
      - If `instance.exports.memory` is _not_ set then it requires that
        `config.imports.env.memory` be set (else it throws), and
-       assigns that to `target.memory`.
+       assigns that to `wasmUtilTarget.memory`.
 
      - If `wasmUtilTarget.alloc` is not set and
        `instance.exports.malloc` is, it installs
@@ -2357,14 +2397,15 @@ globalThis.WhWasmUtilInstaller = function(target){
 
    It returns a function which, when called, initiates loading of the
    module and returns a Promise. When that Promise resolves, it calls
-   the `config.onload` callback (if set) and passes it
-   `(loadResult,config)`, where `loadResult` is the result of
-   WebAssembly.instantiate[Streaming](): an object in the form:
+   the `config.onload` callback (if set) and passes it `(loadResult)`,
+   where `loadResult` is derived from the result of
+   WebAssembly.instantiate[Streaming](), an object in the form:
 
    ```
    {
      module: a WebAssembly.Module,
-     instance: a WebAssembly.Instance
+     instance: a WebAssembly.Instance,
+     config: the config arg to this function
    }
    ```
 
@@ -2392,8 +2433,7 @@ globalThis.WhWasmUtilInstaller.yawl = function(config){
            (exported from WASM) or tgt.memory (JS-provided memory
            imported into WASM).
         */
-        tgt.memory = (config.imports && config.imports.env
-                      && config.imports.env.memory)
+        tgt.memory = config?.imports?.env?.memory
           || toss("Missing 'memory' object!");
       }
       if(!tgt.alloc && arg.instance.exports.malloc){
@@ -2405,7 +2445,8 @@ globalThis.WhWasmUtilInstaller.yawl = function(config){
       }
       wui(tgt);
     }
-    if(config.onload) config.onload(arg,config);
+    arg.config = config;
+    if(config.onload) config.onload(arg);
     return arg /* for any then() handler attached to
                   yetAnotherWasmLoader()'s return value */;
   };
index 8497f5bb5c9bead23730dea66a2af76f5895c09f..0576f25ce6f57c600c23b1f24c270045fe485704 100644 (file)
@@ -1084,7 +1084,9 @@ globalThis.sqlite3InitModule = sqlite3InitModule;
       T.assert(P.pointer === stack);
       try {
         const [p1, p2, p3] = P.allocChunks(3,'i32');
-        T.assert(P.pointer == Number(stack)-16/*always rounded to multiple of 8*/)
+        let sPos = wasm.ptrAdd(stack,-16)/*pstack alloc always rounds to multiple of 8*/;
+        T.assert(P.pointer === sPos)
+          .assert(p1 === sPos)
           .assert(p2 == Number(p1) + 4)
           .assert(p3 == Number(p2) + 4);
         T.mustThrowMatching(()=>P.allocChunks(1024, 1024 * 16),
@@ -1096,12 +1098,16 @@ globalThis.sqlite3InitModule = sqlite3InitModule;
       T.assert(P.pointer === stack);
       try {
         let [p1, p2, p3] = P.allocPtr(3,false);
-        let sPos = Number(stack)-16/*always rounded to multiple of 8*/;
-        T.assert(P.pointer == sPos)
-          .assert(p2 == Number(p1) + 4)
-          .assert(p3 == Number(p2) + 4);
+        let sPos = wasm.ptrAdd(stack,
+                               -(4===wasm.pointerSizeof
+                                 ? 16/*pstack alloc always rounds to multiple of 8*/
+                                 : 24));
+        T.assert(P.pointer === p1)
+          .assert(p1 === sPos)
+          .assert(p2 == Number(p1) + wasm.pointerSizeof)
+          .assert(p3 == Number(p2) + wasm.pointerSizeof);
         [p1, p2, p3] = P.allocPtr(3);
-        T.assert(P.pointer == sPos-24/*3 x 8 bytes*/)
+        T.assert(P.pointer === wasm.ptrAdd(sPos, -24)/*3 x 8 bytes*/)
           .assert(p2 == Number(p1) + 8)
           .assert(p3 == Number(p2) + 8);
         p1 = P.allocPtr();
@@ -1119,8 +1125,8 @@ globalThis.sqlite3InitModule = sqlite3InitModule;
       try{
         const n = 520;
         const p = wasm.pstack.alloc(n);
-        T.assert(0===wasm.peek8(p))
-          .assert(0===wasm.peek8(wasm.ptrAdd(p,n,-1)));
+        T.assert(0==wasm.peek8(p))
+          .assert(0==wasm.peek8(wasm.ptrAdd(p,n,-1)));
         T.assert(undefined === capi.sqlite3_randomness(n - 10, p));
         let j, check = 0;
         const heap = wasm.heap8u();
@@ -1275,7 +1281,7 @@ globalThis.sqlite3InitModule = sqlite3InitModule;
         const stack = wasm.pstack.pointer;
         try {
           const ppOut = wasm.pstack.allocPtr();
-          T.assert( 0===wasm.peekPtr(ppOut) );
+          T.assert( 0==wasm.peekPtr(ppOut) );
           let rc = capi.sqlite3_open_v2( ":memory:", ppOut,
                                          capi.SQLITE_OPEN_CREATE
                                          | capi.SQLITE_OPEN_READWRITE,
@@ -1488,6 +1494,7 @@ globalThis.sqlite3InitModule = sqlite3InitModule;
       const db = this.db;
       let list = [];
       this.progressHandlerCount = 0;
+      //wasm.xWrap.debug = true;
       let rc = db.exec({
         sql:['CREATE TABLE t(a,b);',
              // ^^^ using TEMP TABLE breaks the db export test
index 668b96ac78f44451991878ef6716d9b457be9d2b..3f8fd94de1ce0012ef90cea11500b3d3c8f7b847 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Get\sthe\swasm\stests\srunning\sin\sa\s64-bit\sbuild\sup\sthrough\s(but\snot\sincluding)\sthe\soo1\sbits.
-D 2025-09-20T11:09:20.368
+C Further\swork\son\s64-bit\sWASM\sbuilds.\sIt\snow\sgets\sthrough\sjust\sshy\sof\shalf\sof\stester1.js.
+D 2025-09-20T15:16:55.119
 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x
 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
@@ -596,10 +596,10 @@ F ext/wasm/api/extern-pre-js.js cc61c09c7a24a07dbecb4c352453c3985170cec12b4e7e7e
 F ext/wasm/api/post-js-footer.js 365405929f41ca0e6d389ed8a8da3f3c93e11d3ef43a90ae151e37fa9f75bf41
 F ext/wasm/api/post-js-header.js 53740d824e5d9027eb1e6fd59e216abbd2136740ce260ea5f0699ff2acb0a701
 F ext/wasm/api/pre-js.c-pp.js 58f823de197e2c10d76179aa05410a593b7ae03e1ece983bb42ffd818e8857e1
-F ext/wasm/api/sqlite3-api-cleanup.js 3ac1786e461ada63033143be8c3b00b26b939540661f3e839515bb92f2e35359
-F ext/wasm/api/sqlite3-api-glue.c-pp.js c6a4271411caf9b0ff434436766fcd226e22cad484949fc207045d13ba960354
-F ext/wasm/api/sqlite3-api-oo1.c-pp.js dc8573267f0dd49ae314a295c0dbe86de921f6d6beabbb7a447029ca1ea4e1d9
-F ext/wasm/api/sqlite3-api-prologue.js 5812f5acb0eb17ce04cbea554fa33236acfcbe5eaaa6ddc04eb6454141040a98
+F ext/wasm/api/sqlite3-api-cleanup.js 6341cb85c931044647ad4b12654a178c81f5a8fbeccdf4dc4f258e5a390d2241
+F ext/wasm/api/sqlite3-api-glue.c-pp.js 8d399c686b068427b4c9e51d68d9fc1f632ee9c89a1c49d3e2919744d68c622a
+F ext/wasm/api/sqlite3-api-oo1.c-pp.js c40857ef457c1243d40dd92602e362e7431500936b0358263e8caa115436e705
+F ext/wasm/api/sqlite3-api-prologue.js 1f3aa229e225f8f93e6011d64c7ecd1ac2e4a70b94d8f78f493e1a7dbb236e47
 F ext/wasm/api/sqlite3-api-worker1.c-pp.js 760191cd13416e6f5adfd9fcc8a97fed5645c9e0a5fbac213a2d4ce2d79a4334
 F ext/wasm/api/sqlite3-license-version-header.js 0c807a421f0187e778dc1078f10d2994b915123c1223fe752b60afdcd1263f89
 F ext/wasm/api/sqlite3-opfs-async-proxy.js 9654b565b346dc609b75d15337f20acfa7af7d9d558da1afeb9b6d8eaa404966
@@ -618,7 +618,7 @@ F ext/wasm/c-pp.c cca55c5b55ebd8d29916adbedb0e40baa12caa9a2e8429f812683c308f9b0e
 F ext/wasm/common/SqliteTestUtil.js 7adaeffef757d8708418dc9190f72df22367b531831775804b31598b44f6aa51
 F ext/wasm/common/emscripten.css 11bd104b6c0d597c67d40cc8ecc0a60dae2b965151e3b6a37fa5708bac3acd15
 F ext/wasm/common/testing.css e97549bab24126c24e0daabfe2de9bb478fb0a69fdb2ddd0a73a992c091aad6f
-F ext/wasm/common/whwasmutil.js 1475e140bbd48d67e385603ce3e4bef7ca00d8ee3ec896d40cf4f55c7336b0c3
+F ext/wasm/common/whwasmutil.js 1b4b0b38b590221bad5d9d807b1d30127626ddc05f616182f01423ac8fcce089
 F ext/wasm/config.make.in c424ae1cc3c89274520ad312509d36c4daa34a3fce5d0c688e5f8f4365e1049a
 F ext/wasm/demo-123-worker.html a0b58d9caef098a626a1a1db567076fca4245e8d60ba94557ede8684350a81ed
 F ext/wasm/demo-123.html 8c70a412ce386bd3796534257935eb1e3ea5c581e5d5aea0490b8232e570a508
@@ -655,7 +655,7 @@ F ext/wasm/test-opfs-vfs.html 1f2d672f3f3fce810dfd48a8d56914aba22e45c6834e262555
 F ext/wasm/test-opfs-vfs.js 1618670e466f424aa289859fe0ec8ded223e42e9e69b5c851f809baaaca1a00c
 F ext/wasm/tester1-worker.html ebc4b820a128963afce328ecf63ab200bd923309eb939f4110510ab449e9814c
 F ext/wasm/tester1.c-pp.html 1c1bc78b858af2019e663b1a31e76657b73dc24bede28ca92fbe917c3a972af2
-F ext/wasm/tester1.c-pp.js 827de6ae0b069709762afb58c452b769bbab092c6c7c850e5aab9581d82aff45
+F ext/wasm/tester1.c-pp.js 7f32d79407cce016cde0e884e364d5fb04addeb7cb7f43b30169cdd938589634
 F ext/wasm/tests/opfs/concurrency/index.html 657578a6e9ce1e9b8be951549ed93a6a471f4520a99e5b545928668f4285fb5e
 F ext/wasm/tests/opfs/concurrency/test.js d08889a5bb6e61937d0b8cbb78c9efbefbf65ad09f510589c779b7cc6a803a88
 F ext/wasm/tests/opfs/concurrency/worker.js 0a8c1a3e6ebb38aabbee24f122693f1fb29d599948915c76906681bb7da1d3d2
@@ -2175,8 +2175,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350
 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7
 F tool/warnings.sh 1ad0169b022b280bcaaf94a7fa231591be96b514230ab5c98fbf15cd7df842dd
 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
-P 1e3b003ff99d2788d93e179504b711cb78846605774bf472589440d0136f20fa
-R 5e413c78ac49f5649b20125a76a68b9e
+P a5af46174a05e1414370884d1a99827af9286a60eff1c8ae1551e7fad3903f7a
+R 2adec1131b74b3b8137161b75e6957cf
 U stephan
-Z 40da1eb0811159ac3f90712f37f01328
+Z 0d524ac36a249cd8e25e154440f46d24
 # Remove this line to create a well-formed Fossil manifest.
index ffeb3900e4154fe0efd34c095fee43caeb3fe9f6..bf1f9119150a129861de2d3783f0720568de195a 100644 (file)
@@ -1 +1 @@
-a5af46174a05e1414370884d1a99827af9286a60eff1c8ae1551e7fad3903f7a
+c8deed31365898e1379d577298fc80ef08a5531999d5b54a9f14337febed0260