]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Internal refactoring of how sqlite3.wasm.xWrap() handles JS-to-C function pointer...
authorstephan <stephan@noemail.net>
Thu, 15 Dec 2022 02:28:55 +0000 (02:28 +0000)
committerstephan <stephan@noemail.net>
Thu, 15 Dec 2022 02:28:55 +0000 (02:28 +0000)
FossilOrigin-Name: 10cfe3fae6f680d3ecc3b0afbbf628ce91e34e3757b19dd27c231f0daf44232a

ext/wasm/api/sqlite3-api-glue.js
ext/wasm/common/whwasmutil.js
manifest
manifest.uuid

index 972b4a2e08ba229645227fd23e9dd4c42a3c0666..5488f26c944e150f201e28e41695c460dce65e11 100644 (file)
@@ -138,7 +138,7 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
        the range of supported argument types. */
     [ 
       "sqlite3_progress_handler", undefined, [
-        "sqlite3*", "int", wasm.xWrap.FuncPtrAdapter({
+        "sqlite3*", "int", new wasm.xWrap.FuncPtrAdapter({
           name: 'xProgressHandler',
           signature: 'i(p)',
           bindScope: 'context',
@@ -180,7 +180,7 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
      "**", "**", "*", "*", "*"],
     ["sqlite3_total_changes", "int", "sqlite3*"],
     ["sqlite3_trace_v2", "int", "sqlite3*", "int",
-     wasm.xWrap.FuncPtrAdapter({
+     new wasm.xWrap.FuncPtrAdapter({
        name: 'sqlite3_trace_v2::callback',
        signature: 'i(ippp)',
        contextKey: (argIndex, argv)=>'sqlite3@'+argv[0]
@@ -469,14 +469,14 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
       'sqlite3*','string','int','*',
       new wasm.xWrap.FuncPtrAdapter({
         /* int(*xCompare)(void*,int,const void*,int,const void*) */
-        name: 'xCompare',
+        name: 'sqlite3_create_collation_v2::xCompare',
         signature: 'i(pipip)',
         bindScope: 'context',
         contextKey: __collationContextKey
       }),
       new wasm.xWrap.FuncPtrAdapter({
         /* void(*xDestroy(void*) */
-        name: 'xDestroy',
+        name: 'sqlite3_create_collation_v2::xDestroy',
         signature: 'v(p)',
         bindScope: 'context',
         contextKey: __collationContextKey
index a662d5a1ed687e510608b98d7becabc68ed4d0c8..82d10dff119264a7ae325bbcd7f39e939dce0935 100644 (file)
@@ -1473,8 +1473,40 @@ self.WhWasmUtilInstaller = function(target){
   }
 
   /**
-     EXPERIMENTAL! DO NOT USE IN CLIENT CODE!
+     Internal-use-only base class for FuncPtrAdapter and potentially
+     additional stateful argument adapter classes.
+
+     Note that its main interface (convertArg()) is strictly
+     internal, not to be exposed to client code, as it may still
+     need re-shaping. Only the constructors of concrete subclasses
+     should be exposed to clients, and those in such a way that
+     does not hinder internal redesign of the convertArg()
+     interface.
+  */
+  const AbstractArgAdapter = class {
+    constructor(opt){
+      this.name = opt.name;
+    }
+    /**
+       Gets called via xWrap() to "convert" v to whatever type
+       this specific class supports.
 
+       argIndex is the argv index of _this_ argument in the
+       being-xWrap()'d call. argv is the current argument list
+       undergoing xWrap() argument conversion. argv entries to the
+       left of argIndex will have already undergone transformation and
+       those to the right will not have (they will have the values the
+       client-level code passed in, awaiting conversion). The RHS
+       indexes must never be relied upon for anything because their
+       types are indeterminate, whereas the LHS values will be
+       WASM-compatible values by the time this is called.
+    */
+    convertArg(v,argIndex,argv){
+      toss("AbstractArgAdapter must be subclassed.");
+    }
+  };
+
+  /**
      An attempt at adding function pointer conversion support to
      xWrap(). This type is recognized by xWrap() as a proxy for
      converting a JS function to a C-side function, either
@@ -1482,7 +1514,7 @@ self.WhWasmUtilInstaller = function(target){
      or semi-contextual, where it may keep track of a single binding
      for a given context and uninstall the binding if it's replaced.
 
-     Requires an options object with these properties:
+     The constructor requires an options object with these properties:
 
      - name (optional): string describing the function binding. This
        is solely for debugging and error-reporting purposes. If not
@@ -1514,17 +1546,18 @@ self.WhWasmUtilInstaller = function(target){
          context. This mode is the default if bindScope is _not_ set
          but a property named contextKey (described below) is.
 
-     - contextKey (function): is only used if bindScope is not set or
-       is 'context'. This function gets passed (argIndex,argv), where
-       argIndex is the index of _this_ function pointer in its
-       _wrapping_ function's arguments and argv is the _current_
-       still-being-xWrap()-processed args array. All arguments to the
-       left of argIndex will have been processed by xWrap() by the
-       time this is called. argv[argIndex] will be the value the user
-       passed in to the xWrap()'d function for the argument this
-       FuncPtrAdapter is mapped to. Arguments to the right of
-       argv[argIndex] will not yet have been converted before this is
-       called. The function must return a key which uniquely
+     - contextKey (function): is only used if bindScope is 'context'
+       or if bindScope is not set and this function is, in which case
+       'context' is assumed. This function gets passed
+       (argIndex,argv), where argIndex is the index of _this_ function
+       pointer in its _wrapping_ function's arguments and argv is the
+       _current_ still-being-xWrap()-processed args array. All
+       arguments to the left of argIndex will have been processed by
+       xWrap() by the time this is called. argv[argIndex] will be the
+       value the user passed in to the xWrap()'d function for the
+       argument this FuncPtrAdapter is mapped to. Arguments to the
+       right of 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_
        FuncPtrAdapter instance (other instances are not considered),
        taking into account that C functions often take some sort of
@@ -1547,74 +1580,65 @@ self.WhWasmUtilInstaller = function(target){
      The constructor only saves the above state for later, and does
      not actually bind any functions. Its convertArg() method is
      called via xWrap() to perform any bindings.
-
-     If this is called like a function, instead of a constructor,
-     it behaves as if it were called like a constructor.
   */
-  xArg.FuncPtrAdapter = function ctor(opt) {
-    if(!(this instanceof xArg.FuncPtrAdapter)){
-      return new xArg.FuncPtrAdapter(opt);
-    }
-    this.signature = opt.signature;
-    if(!opt.bindScope && (opt.contextKey instanceof Function)){
-      opt.bindScope = 'context';
-    }else if(ctor.bindScopes.indexOf(opt.bindScope)<0){
-      toss("Invalid options.bindScope ("+opt.bindMod+") for FuncPtrAdapter. "+
-           "Expecting one of: ("+ctor.bindScopes.join(', ')+')');
+  xArg.FuncPtrAdapter = class FuncPtrAdapter extends AbstractArgAdapter {
+    constructor(opt) {
+      super(opt);
+      this.signature = opt.signature;
+      if(!opt.bindScope && (opt.contextKey instanceof Function)){
+        opt.bindScope = 'context';
+      }else if(FuncPtrAdapter.bindScopes.indexOf(opt.bindScope)<0){
+        toss("Invalid options.bindScope ("+opt.bindMod+") for FuncPtrAdapter. "+
+             "Expecting one of: ("+FuncPtrAdapter.bindScopes.join(', ')+')');
+      }
+      this.bindScope = opt.bindScope;
+      if(opt.contextKey) this.contextKey = opt.contextKey /*else inherit one*/;
+      this.isTransient = 'transient'===this.bindScope;
+      this.isContext = 'context'===this.bindScope;
+      if( ('singleton'===this.bindScope) ) this.singleton = [];
+      else this.singleton = undefined;
+      //console.warn("FuncPtrAdapter()",opt,this);
     }
-    this.bindScope = opt.bindScope;
-    this.name = opt.name || '';
-    if(opt.contextKey) this.contextKey = opt.contextKey /*else inherit one*/;
-    this.isTransient = 'transient'===this.bindScope;
-    this.isContext = 'context'===this.bindScope;
-    if( ('singleton'===this.bindScope) ) this.singleton = [];
-    else this.singleton = undefined;
-    //console.warn("FuncPtrAdapter()",opt,this);
-  };
-  xArg.FuncPtrAdapter.bindScopes = [
-    'transient', 'context', 'singleton'
-  ];
-  xArg.FuncPtrAdapter.prototype = {
+
+    static bindScopes = [
+      'transient', 'context', 'singleton'
+    ];
+
     /* Dummy impl. Overwritten per-instance as needed. */
-    contextKey: function(argIndex,argv){
+    contextKey(argIndex,argv){
       return this;
-    },
+    }
+
     /* Returns this objects mapping for the given context key, in the
        form of an an array, creating the mapping if needed. The key
        may be anything suitable for use in a Map. */
-    contextMap: function(key){
+    contextMap(key){
       const cm = (this.__cmap || (this.__cmap = new Map));
       let rc = cm.get(key);
       if(undefined===rc) cm.set(key, (rc = []));
       return rc;
-    },
+    }
+
     /**
        Gets called via xWrap() to "convert" v to a WASM-bound function
        pointer. If v is one of (a pointer, null, undefined) then
        (v||0) is returned and any earlier function installed by this
-       mapping _might_, depending on how it's bound, be
-       uninstalled. If v is not one of those types, it must be a
-       Function, for which it creates (if needed) a WASM function
-       binding and returns the WASM pointer to that binding. If this
-       instance is not in 'transient' mode, it will remember the
-       binding for at least the next call, to avoid recreating the
-       function binding unnecessarily.
+       mapping _might_, depending on how it's bound, be uninstalled.
+       If v is not one of those types, it must be a Function, for
+       which it creates (if needed) a WASM function binding and
+       returns the WASM pointer to that binding. If this instance is
+       not in 'transient' mode, it will remember the binding for at
+       least the next call, to avoid recreating the function binding
+       unnecessarily.
 
        If it's passed a pointer(ish) value for v, it does _not_
        perform any function binding, so this object's bindMode is
        irrelevant for such cases.
 
-       argIndex is the argv index of _this_ argument in the
-       being-xWrap()'d call. argv is the current argument list
-       undergoing xWrap() argument conversion. argv entries to the
-       left of argIndex will have already undergone transformation and
-       those to the right will not have (they will have the values the
-       client-level code passed in, awaiting conversion). The RHS
-       indexes must never be relied upon for anything because their
-       types are indeterminate, whereas the LHS values will be
-       WASM-compatible values by the time this is called.
+       See the parent class's convertArg() docs for details on what
+       exactly the 2nd and 3rd arguments are.
     */
-    convertArg: function(v,argIndex,argv){
+    convertArg(v,argIndex,argv){
       //console.warn("FuncPtrAdapter.convertArg()",this.signature,this.transient,v);
       let pair = this.singleton;
       if(!pair && this.isContext){
@@ -1650,7 +1674,7 @@ self.WhWasmUtilInstaller = function(target){
                             this.signature+".");
       }
     }/*convertArg()*/
-  }/*FuncPtrAdapter.prototype*/;
+  }/*FuncPtrAdapter*/;
 
   const __xArgAdapterCheck =
         (t)=>xArg.get(t) || toss("Argument adapter not found:",t);
@@ -1823,7 +1847,7 @@ self.WhWasmUtilInstaller = function(target){
     /*Verify the arg type conversions are valid...*/;
     if(undefined!==resultType && null!==resultType) __xResultAdapterCheck(resultType);
     for(const t of argTypes){
-      if(t instanceof xArg.FuncPtrAdapter) xArg.set(t, (...args)=>t.convertArg(...args));
+      if(t instanceof AbstractArgAdapter) xArg.set(t, (...args)=>t.convertArg(...args));
       else __xArgAdapterCheck(t);
     }
     const cxw = cache.xWrap;
@@ -1842,9 +1866,9 @@ self.WhWasmUtilInstaller = function(target){
           The public interface of argument adapters is that they take
           ONE argument and return a (possibly) converted result for
           it. The passing-on of arguments after the first is an
-          internal impl. detail for the sake of FuncPtrAdapter, and
+          internal impl. detail for the sake of AbstractArgAdapter, and
           not to be relied on or documented for other cases. The fact
-          that this is how FuncPtrAdapter.convertArgs() gets its 2nd+
+          that this is how AbstractArgAdapter.convertArgs() gets its 2nd+
           arguments, and how FuncPtrAdapter.contextKey() gets its
           args, is also an implementation detail and subject to
           change. i.e. the public interface of 1 argument is stable.
index f082e7072465f468861b798cc2623299fdaf7eb5..be0d20aa97fcc62fc87fae0f613490c7b9ffb147 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Remove\san\sunnecessary/obsolete\sEmscripten-specific\sexport.
-D 2022-12-15T02:26:13.244
+C Internal\srefactoring\sof\show\ssqlite3.wasm.xWrap()\shandles\sJS-to-C\sfunction\spointer\sconversions,\sto\senable\ssimilar\sconversions\sto\sbe\sadded\smore\seasily.
+D 2022-12-15T02:28:55.691
 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
 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/pre-js.c-pp.js b88499dc303c21fc3f55f2c364a0f814f587b60a95784303881169f9e91c1d5f
 F ext/wasm/api/sqlite3-api-cleanup.js 680d5ccfff54459db136a49b2199d9f879c8405d9c99af1dda0cc5e7c29056f4
-F ext/wasm/api/sqlite3-api-glue.js a8010bf3fa184886d1e9e76b0d0d1e290b5fa25130510644a59e91a18f779ef4
+F ext/wasm/api/sqlite3-api-glue.js 2e1087b870290a3a613d59ed626bde1f6da7c9c211cd36e41df1ee8b2932b508
 F ext/wasm/api/sqlite3-api-oo1.js c0c4ccc269cccee657ffd03f094da7e270e1367b7928926b3730d543555a12a6
 F ext/wasm/api/sqlite3-api-prologue.js 86eb4488f2be85e68c23ebcfad0834c24b6075e1645c67890cc4163c462efac1
 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/emscripten.css 11bd104b6c0d597c67d40cc8ecc0a60dae2b965151e3b6a37fa5708bac3acd15
 F ext/wasm/common/testing.css 0ff15602a3ab2bad8aef2c3bd120c7ee3fd1c2054ad2ace7e214187ae68d926f
-F ext/wasm/common/whwasmutil.js 8bec2460dfb515986faf854c011b7ae4f2cc1b2a128d9afa74ca57ee6057bdaa
+F ext/wasm/common/whwasmutil.js e8934d24518f99a8995e2da5a4f308d36c13bea90d36a0396585e2debba94d57
 F ext/wasm/demo-123-worker.html a0b58d9caef098a626a1a1db567076fca4245e8d60ba94557ede8684350a81ed
 F ext/wasm/demo-123.html 8c70a412ce386bd3796534257935eb1e3ea5c581e5d5aea0490b8232e570a508
 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.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
 F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
-P c1d5261b222bbf94c20e558089f3d2eae6a88b6d739225ee4f7d0338e0e59994
-R 918e16f92d23cc300804b300dc026e25
+P fa278022afd6dd6e499d26f74a8359f3e9973e1680772059ce331b64e77ec582
+R e784d3c7094c47f7ba465262d6340c12
 U stephan
-Z e5f6c496f6861a48778111a469988478
+Z 0c197c6d7ed7bd2414c2cff61c07cad7
 # Remove this line to create a well-formed Fossil manifest.
index a6b0edf399a5a9344369c657a1811f07a703ed18..8b8fca451a7ebf2027a1d3f11fd30b34f34b15c6 100644 (file)
@@ -1 +1 @@
-fa278022afd6dd6e499d26f74a8359f3e9973e1680772059ce331b64e77ec582
\ No newline at end of file
+10cfe3fae6f680d3ecc3b0afbbf628ce91e34e3757b19dd27c231f0daf44232a
\ No newline at end of file