]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Replace JS-side use of SQLITE_TRANSIENT with the new SQLITE_WASM_DEALLOC, reducing...
authorstephan <stephan@noemail.net>
Sat, 24 Dec 2022 15:28:45 +0000 (15:28 +0000)
committerstephan <stephan@noemail.net>
Sat, 24 Dec 2022 15:28:45 +0000 (15:28 +0000)
FossilOrigin-Name: ffe2999a91a7dec129a38afb675fe9e539d7c347886bfea85cba55f6367d54d1

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

index dd80963f3e68e0a9172b2b7f39756faf269e93c5..7b5fa11816a7e9471b23f4596c92d7367178b272 100644 (file)
@@ -24,6 +24,33 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
   self.WhWasmUtilInstaller(wasm);
   delete self.WhWasmUtilInstaller;
 
+  {
+    /**
+       Find a mapping for SQLITE_WASM_DEALLOC, which the API
+       guarantees is a WASM pointer to the same underlying function as
+       wasm.dealloc() (noting that wasm.dealloc() is permitted to be a
+       JS wrapper around the WASM function). There is unfortunately no
+       O(1) algorithm for finding this pointer: we have to walk the
+       WASM indirect function table to find it. However, experience
+       indicates that that particular function is always very close to
+       the front of the table (it's been entry #3 in all relevant
+       tests).
+    */
+    const dealloc = wasm.exports[sqlite3.config.deallocExportName];
+    const nFunc = wasm.functionTable().length;
+    let i;
+    for(i = 0; i < nFunc; ++i){
+      const e = wasm.functionEntry(i);
+      if(dealloc === e){
+        capi.SQLITE_WASM_DEALLOC = i;
+        break;
+      }
+    }
+    if(dealloc !== wasm.functionEntry(capi.SQLITE_WASM_DEALLOC)){
+      toss("Internal error: cannot find function pointer for SQLITE_WASM_DEALLOC.");
+    }
+  }
+
   /**
      Signatures for the WASM-exported C-side functions. Each entry
      is an array with 2+ elements:
@@ -874,7 +901,7 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
         text = pMem.join('');
       }
       let p, n;
-      try {
+      try{
         if(util.isSQLableTypedArray(text)){
           p = wasm.allocFromTypedArray(text);
           n = text.byteLength;
@@ -886,9 +913,12 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
             "Invalid 3rd argument type for sqlite3_bind_text()."
           );
         }
-        return __bindText(pStmt, iCol, p, n, capi.SQLITE_TRANSIENT);
-      }finally{
+        return __bindText(pStmt, iCol, p, n, capi.SQLITE_WASM_DEALLOC);
+      }catch(e){
         wasm.dealloc(p);
+        return util.sqlite3_wasm_db_error(
+          capi.sqlite3_db_handle(pStmt), e
+        );
       }
     }/*sqlite3_bind_text()*/;
 
@@ -917,9 +947,12 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
             "Invalid 3rd argument type for sqlite3_bind_blob()."
           );
         }
-        return __bindBlob(pStmt, iCol, p, n, capi.SQLITE_TRANSIENT);
-      }finally{
+        return __bindBlob(pStmt, iCol, p, n, capi.SQLITE_WASM_DEALLOC);
+      }catch(e){
         wasm.dealloc(p);
+        return util.sqlite3_wasm_db_error(
+          capi.sqlite3_db_handle(pStmt), e
+        );
       }
     }/*sqlite3_bind_blob()*/;
 
index e3c90271b187ae89fbe6ee74397dcbe0d48c9075..16f5f00b1523e166de951e9ba900008a437e5a00 100644 (file)
@@ -1285,7 +1285,7 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
      success.
   */
   const bindOne = function f(stmt,ndx,bindType,val){
-    affirmUnlocked(stmt, 'bind()');
+    affirmUnlocked(affirmStmtOpen(stmt), 'bind()');
     if(!f._){
       f._tooBigInt = (v)=>toss3(
         "BigInt value is too big to store without precision loss:", v
@@ -1295,14 +1295,9 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
          so we have no range checking. */
       f._ = {
         string: function(stmt, ndx, val, asBlob){
-          const stack = wasm.scopedAllocPush();
-          try{
-            const [pStr, n] = wasm.scopedAllocCString(val, true);
-            const f = asBlob ? capi.sqlite3_bind_blob : capi.sqlite3_bind_text;
-            return f(stmt.pointer, ndx, pStr, n, capi.SQLITE_TRANSIENT);
-          }finally{
-            wasm.scopedAllocPop(stack);
-          }
+          const [pStr, n] = wasm.allocCString(val, true);
+          const f = asBlob ? capi.sqlite3_bind_blob : capi.sqlite3_bind_text;
+          return f(stmt.pointer, ndx, pStr, n, capi.SQLITE_WASM_DEALLOC);
         }
       };
     }/* static init */
@@ -1354,15 +1349,10 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
             toss3("Binding a value as a blob requires",
                   "that it be a string, Uint8Array, Int8Array, or ArrayBuffer.");
           }
-          const stack = wasm.scopedAllocPush();
-          try{
-            const pBlob = wasm.scopedAlloc(val.byteLength || 1);
-            wasm.heap8().set(val.byteLength ? val : [0], pBlob)
-            rc = capi.sqlite3_bind_blob(stmt.pointer, ndx, pBlob, val.byteLength,
-                                        capi.SQLITE_TRANSIENT);
-          }finally{
-            wasm.scopedAllocPop(stack);
-          }
+          const pBlob = wasm.alloc(val.byteLength || 1);
+          wasm.heap8().set(val.byteLength ? val : [0], pBlob)
+          rc = capi.sqlite3_bind_blob(stmt.pointer, ndx, pBlob, val.byteLength,
+                                      capi.SQLITE_WASM_DEALLOC);
           break;
         }
         default:
index c3533a4767f0cd62cb5e3f9cc461b18e0658f5c4..faa2dbbbf40d00c6da87249279ad3f03b8ad52dd 100644 (file)
@@ -321,14 +321,17 @@ self.sqlite3ApiBootstrap = function sqlite3ApiBootstrap(
   };
 
   /**
-     Returns true if v appears to be one of our bind()-able TypedArray
-     types: Uint8Array or Int8Array. Support for TypedArrays with
-     element sizes >1 is a potential TODO just waiting on a use case
-     to justify them.
+     Returns v if v appears to be one of our bind()-able TypedArray
+     types: Uint8Array or Int8Array or ArrayBuffer. Support for
+     TypedArrays with element sizes >1 is a potential TODO just
+     waiting on a use case to justify them. Until then, their `buffer`
+     property can be used to pass them as an ArrayBuffer. If it's not
+     a bindable array type, a falsy value is returned.
   */
   const isBindableTypedArray = (v)=>{
-    return v && (v instanceof Uint8Array || v instanceof Int8Array);
-    //v && v.constructor && (1===v.constructor.BYTES_PER_ELEMENT);
+    return v && (v instanceof Uint8Array
+                 || v instanceof Int8Array
+                 || v instanceof ArrayBuffer);
   };
 
   /**
@@ -341,8 +344,9 @@ self.sqlite3ApiBootstrap = function sqlite3ApiBootstrap(
      isSQLableTypedArray() list.
   */
   const isSQLableTypedArray = (v)=>{
-    return v && (v instanceof Uint8Array || v instanceof Int8Array);
-    //v && v.constructor && (1===v.constructor.BYTES_PER_ELEMENT);
+    return v && (v instanceof Uint8Array
+                 || v instanceof Int8Array
+                 || v instanceof ArrayBuffer);
   };
 
   /** Returns true if isBindableTypedArray(v) does, else throws with a message
@@ -439,8 +443,8 @@ self.sqlite3ApiBootstrap = function sqlite3ApiBootstrap(
        - If it's an ArrayBuffer, it gets wrapped in a Uint8Array and
          treated as that type.
 
-       In all of those cases, the final argument (text destructor) is
-       ignored and capi.SQLITE_TRANSIENT is assumed.
+       In all of those cases, the final argument (destructor) is
+       ignored and capi.SQLITE_WASM_DEALLOC is assumed.
 
        A 3rd argument of `null` is treated as if it were a WASM pointer
        of 0.
@@ -477,7 +481,7 @@ self.sqlite3ApiBootstrap = function sqlite3ApiBootstrap(
          treated as that type.
 
        In each of those cases, the final argument (text destructor) is
-       ignored and capi.SQLITE_TRANSIENT is assumed.
+       ignored and capi.SQLITE_WASM_DEALLOC is assumed.
 
        A 3rd argument of `null` is treated as if it were a WASM pointer
        of 0.
@@ -1645,7 +1649,7 @@ self.sqlite3ApiBootstrap = function sqlite3ApiBootstrap(
       capi.sqlite3_result_error(pCtx, ''+e, -1);
     }
   };
-  
+
   /**
      This function passes its 2nd argument to one of the
      sqlite3_result_xyz() routines, depending on the type of that
@@ -1661,7 +1665,7 @@ self.sqlite3ApiBootstrap = function sqlite3ApiBootstrap(
      - `bigint`: similar to `number` but will trigger an error if the
        value is too big to store in an int64.
      - `string`: `sqlite3_result_text()`
-     - Uint8Array or Int8Array: `sqlite3_result_blob()`
+     - Uint8Array or Int8Array or ArrayBuffer: `sqlite3_result_blob()`
      - `undefined`: is a no-op provided to simplify certain use cases.
 
      Anything else triggers `sqlite3_result_error()` with a
@@ -1712,9 +1716,11 @@ self.sqlite3ApiBootstrap = function sqlite3ApiBootstrap(
             f(pCtx, val);
             break;
           }
-          case 'string':
-            capi.sqlite3_result_text(pCtx, val, -1, capi.SQLITE_TRANSIENT);
+          case 'string': {
+            const [p, n] = wasm.allocCString(val,true);
+            capi.sqlite3_result_text(pCtx, p, n, capi.SQLITE_WASM_DEALLOC);
             break;
+          }
           case 'object':
             if(null===val/*yes, typeof null === 'object'*/) {
               capi.sqlite3_result_null(pCtx);
@@ -1723,7 +1729,7 @@ self.sqlite3ApiBootstrap = function sqlite3ApiBootstrap(
               const pBlob = wasm.allocFromTypedArray(val);
               capi.sqlite3_result_blob(
                 pCtx, pBlob, val.byteLength,
-                wasm.exports[sqlite3.config.deallocExportName]
+                capi.SQLITE_WASM_DEALLOC
               );
               break;
             }
index ed3b96dea176fa65c621e90b4eb094cf1df01f8b..f2bf5fef1eecc674abc1c93c53ace7bbe4d1f255 100644 (file)
@@ -1621,6 +1621,11 @@ int sqlite3_wasm_test_intptr(int * p){
   return *p = *p * 2;
 }
 
+SQLITE_WASM_KEEP
+void * sqlite3_wasm_test_voidptr(void * p){
+  return p;
+}
+
 SQLITE_WASM_KEEP
 int64_t sqlite3_wasm_test_int64_max(void){
   return (int64_t)0x7fffffffffffffff;
index a87532e18be84379073e19428b706771d8542eba..ae745a28deb1497baf14c2585c9a124ceb61b84b 100644 (file)
@@ -1987,7 +1987,6 @@ self.sqlite3InitModule = sqlite3InitModule;
       name: 'virtual table #1: eponymous w/ manual exception handling',
       predicate: ()=>!!capi.sqlite3_index_info,
       test: function(sqlite3){
-        warn("The vtab/module JS bindings are experimental and subject to change.");
         const VT = sqlite3.vtab;
         const tmplCols = Object.assign(Object.create(null),{
           A: 0, B: 1
@@ -2185,7 +2184,6 @@ self.sqlite3InitModule = sqlite3InitModule;
       name: 'virtual table #2: non-eponymous w/ automated exception wrapping',
       predicate: ()=>!!capi.sqlite3_index_info,
       test: function(sqlite3){
-        warn("The vtab/module JS bindings are experimental and subject to change.");
         const VT = sqlite3.vtab;
         const tmplCols = Object.assign(Object.create(null),{
           A: 0, B: 1
index 713880bc5c59e78604619f14d66df463bb2c405b..85eda685fcd40eb7f6baef5ed469833cdd447149 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Extend\soo1.Stmt.bind()\sto\saccept\sArrayBuffer\sinstances\sto\sbind\sas\sblobs.
-D 2022-12-24T14:16:02.217
+C Replace\sJS-side\suse\sof\sSQLITE_TRANSIENT\swith\sthe\snew\sSQLITE_WASM_DEALLOC,\sreducing\sthe\samount\sallocation/copying\srequired\sby\ssqlite3_bind_blob/text()\sand\ssqlite3_result_blob/text().\sRemove\sthe\s'experimental'\slog\smessage\sfrom\sthe\svirtual\stable\stests.
+D 2022-12-24T15:28:45.647
 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
 F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
@@ -503,16 +503,16 @@ F ext/wasm/api/post-js-footer.js cd0a8ec768501d9bd45d325ab0442037fb0e33d1f3b4f08
 F ext/wasm/api/post-js-header.js 47b6b281f39ad59fa6e8b658308cd98ea292c286a68407b35ff3ed9cfd281a62
 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-glue.js f0651048a2601bf79f7f39c2c855f6417e65548417f5019ac9ac2ffb2463f2b9
-F ext/wasm/api/sqlite3-api-oo1.js 1312eaf2776c957e41a6fd63c31e7487502bf71745805c41f72429e0925802a5
-F ext/wasm/api/sqlite3-api-prologue.js 683956ea6ab5e0132db48bb693a6bb9dd92f36c8c0902af36572e9b29006ac6d
+F ext/wasm/api/sqlite3-api-glue.js ba532798e577497da9221bf9ac7d286619eec4d16736c927f1d10f3c8d21ada3
+F ext/wasm/api/sqlite3-api-oo1.js 5393fb0b325d2fdafada7fdbfb9219af9a865631acb351d5c5196a982b632c8b
+F ext/wasm/api/sqlite3-api-prologue.js b0302c61abf21966c8cf9788453fea29c790633f7a14a92e05e6db994b590d11
 F ext/wasm/api/sqlite3-api-worker1.js e94ba98e44afccfa482874cd9acb325883ade50ed1f9f9526beb9de1711f182f
 F ext/wasm/api/sqlite3-license-version-header.js a661182fc93fc2cf212dfd0b987f8e138a3ac98f850b1112e29b5fbdaecc87c3
 F ext/wasm/api/sqlite3-opfs-async-proxy.js 7795b84b66a7a8dedc791340709b310bb497c3c72a80bef364fa2a58e2ddae3f
 F ext/wasm/api/sqlite3-v-helper.js 6f6c3e390a72e08b0a5b16a0d567d7af3c04d172831853a29d72a6f1dd40ff24
 F ext/wasm/api/sqlite3-vfs-opfs.c-pp.js 66daf6fb6843bea615fe193109e1542efbeca24f560ee9da63375a910bb48115
 F ext/wasm/api/sqlite3-wasi.h 25356084cfe0d40458a902afb465df8c21fc4152c1d0a59b563a3fba59a068f9
-F ext/wasm/api/sqlite3-wasm.c b114bb85cdf8be7b2939ddcc2bbc2f30c190c44b993c34a77b017c978345efb1
+F ext/wasm/api/sqlite3-wasm.c 313489816e1733a10ece74a92cbea65d3ee241eb07d98088e96258cc211c9719
 F ext/wasm/api/sqlite3-worker1-promiser.js 0c7a9826dbf82a5ed4e4f7bf7816e825a52aff253afbf3350431f5773faf0e4b
 F ext/wasm/api/sqlite3-worker1.js 1e54ea3d540161bcfb2100368a2fc0cad871a207b8336afee1c445715851ec54
 F ext/wasm/batch-runner.html 4deeed44fe41496dc6898d9fb17938ea3291f40f4bfb977e29d0cef96fbbe4c8
@@ -555,7 +555,7 @@ F ext/wasm/test-opfs-vfs.html 1f2d672f3f3fce810dfd48a8d56914aba22e45c6834e262555
 F ext/wasm/test-opfs-vfs.js f09266873e1a34d9bdb6d3981ec8c9e382f31f215c9fd2f9016d2394b8ae9b7b
 F ext/wasm/tester1-worker.html d43f3c131d88f10d00aff3e328fed13c858d674ea2ff1ff90225506137f85aa9
 F ext/wasm/tester1.c-pp.html d34bef3d48e5cbc1c7c06882ad240fec49bf88f5f65696cc2c72c416933aa406
-F ext/wasm/tester1.c-pp.js 145c493221727eb40194280bb2852da49f857e850d8394c31b7bd4caeb5d7bed
+F ext/wasm/tester1.c-pp.js dec750b65ec33ff267b35370ab746899859beb0a7c695cb9b087663d5b144512
 F ext/wasm/tests/opfs/concurrency/index.html 86d8ac435074d1e7007b91105f4897f368c165e8cecb6a9aa3d81f5cf5dcbe70
 F ext/wasm/tests/opfs/concurrency/test.js a98016113eaf71e81ddbf71655aa29b0fed9a8b79a3cdd3620d1658eb1cc9a5d
 F ext/wasm/tests/opfs/concurrency/worker.js 0a8c1a3e6ebb38aabbee24f122693f1fb29d599948915c76906681bb7da1d3d2
@@ -2067,8 +2067,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
 F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
 F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
-P 6a37874db04f3b4842994ad17fc74cb6222f8ea0fa1315a23aff1ffa69bcd12a
-R b07f6a4d9e30a3f649f5decc82bdf7ef
+P f76bd30137fbff981625ffcb28cddd5e8651803dfc3f2d8d7801ead33496311d
+R 244f04d134cc6151e3968d82d6c44161
 U stephan
-Z 934cef85bd1b053ac09da3261d128afb
+Z 5d490510463cd36c1f126d30ea32761d
 # Remove this line to create a well-formed Fossil manifest.
index bc46d13f051f005a17efec3004408176ca08e3b0..cf1529c72ffdd9e7aa224ea1e09f4ca6a67c4ac7 100644 (file)
@@ -1 +1 @@
-f76bd30137fbff981625ffcb28cddd5e8651803dfc3f2d8d7801ead33496311d
\ No newline at end of file
+ffe2999a91a7dec129a38afb675fe9e539d7c347886bfea85cba55f6367d54d1
\ No newline at end of file