SQLite

Check-in [65ff3200c6]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Remove the JS-side SQLITE_WASM_DEALLOC sanity check which triggers the problem mentioned in [688c5c13d156] and [ae0196d86ee8], for reasons covered in the code comments, per discussion in forum post e5b20e1feb.
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 65ff3200c6009a1649fc108d7ce36f5c014185ba46bbf98471ec86eaeb572656
User & Date: stephan 2023-01-04 03:14:06.615
Context
2023-01-04
11:57
Elaborate on the open-in-read-only fallback behavior of the SQLITE_OPEN_READWRITE flag, per user request. Unrelated trailing EOL whitespace cleanups. (check-in: 1003144fc1 user: stephan tags: trunk)
03:14
Remove the JS-side SQLITE_WASM_DEALLOC sanity check which triggers the problem mentioned in [688c5c13d156] and [ae0196d86ee8], for reasons covered in the code comments, per discussion in forum post e5b20e1feb. (check-in: 65ff3200c6 user: stephan tags: trunk)
2023-01-03
19:27
Small performance increase in the symbol hash table. (check-in: a19597b4fd user: drh tags: trunk)
Changes
Unified Diff Ignore Whitespace Patch
Changes to ext/wasm/api/sqlite3-api-glue.js.
22
23
24
25
26
27
28



29
30
31
32
33
34
35
36
37




38
39

40
41
42
43
44
45
46
  const toss3 = sqlite3.SQLite3Error.toss;
  const capi = sqlite3.capi, wasm = sqlite3.wasm, util = sqlite3.util;
  self.WhWasmUtilInstaller(wasm);
  delete self.WhWasmUtilInstaller;

  if(0){
    /**



       This block inexplicably fails on Safari, per report at
       https://sqlite.org/forum/forumpost/e5b20e1feb. In its place,
       we instead add an unsightly snippet to
       sqlite3_wasm_enum_json() which emits the SQLITE_WASM_DEALLOC
       pointer as an integer.

        "The problem" with that approach is that in order to honor
        sqlite3.config.deallocExportName, we have to have the
        following loop (or something equivalent). Because we cannot




        (for Safari) do so, we are currently implicitly hard-coded to
        using sqlite3.config.deallocExportName==='sqlite3_free'.

    */
    /**
       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







>
>
>
|
|
<
<
<

|
|
|
>
>
>
>
|
<
>







22
23
24
25
26
27
28
29
30
31
32
33



34
35
36
37
38
39
40
41
42

43
44
45
46
47
48
49
50
  const toss3 = sqlite3.SQLite3Error.toss;
  const capi = sqlite3.capi, wasm = sqlite3.wasm, util = sqlite3.util;
  self.WhWasmUtilInstaller(wasm);
  delete self.WhWasmUtilInstaller;

  if(0){
    /**
       Please keep this block around as a maintenance reminder
       that we cannot rely on this type of check.

       This block fails on Safari, per a report at
       https://sqlite.org/forum/forumpost/e5b20e1feb.




       It turns out that what Safari serves from the indirect function
       table (e.g. wasm.functionEntry(X)) is anonymous functions which
       wrap the WASM functions, rather than returning the WASM
       functions themselves. That means comparison of such functions
       is useless for determining whether or not we have a specific
       function from wasm.exports. i.e. if function X is indirection
       function table entry N then wasm.exports.X is not equal to
       wasm.functionEntry(N) in Safari, despite being so in the other

       browsers.
    */
    /**
       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
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
    for(const t of defineGroups){
      for(const e of Object.entries(wasm.ctype[t])){
        // ^^^ [k,v] there triggers a buggy code transformation via
        // one of the Emscripten-driven optimizers.
        capi[e[0]] = e[1];
      }
    }
    /*  Exporting SQLITE_WASM_DEALLOC via the wasm.ctype entries fails
        in Safari. One final thing to try: */
    capi.SQLITE_WASM_DEALLOC = wasm.exports.sqlite3_wasm_ptr_to_sqlite3_free();
    if(wasm.exports[sqlite3.config.deallocExportName]
       !== wasm.functionEntry(capi.SQLITE_WASM_DEALLOC)){
      toss("Internal error: sqlite3.wasm.exports["+
           sqlite3.config.deallocExportName+"]",
           "is not the same pointer as SQLITE_WASM_DEALLOC.",
           "These must match in order to accommodate allocator-related",
           "API guarantees.");
    }
    const __rcMap = Object.create(null);
    for(const t of ['resultCodes']){
      for(const e of Object.entries(wasm.ctype[t])){
        __rcMap[e[1]] = e[0];
      }
    }







<
<
<
<
|
|
<
|
<
<







809
810
811
812
813
814
815




816
817

818


819
820
821
822
823
824
825
    for(const t of defineGroups){
      for(const e of Object.entries(wasm.ctype[t])){
        // ^^^ [k,v] there triggers a buggy code transformation via
        // one of the Emscripten-driven optimizers.
        capi[e[0]] = e[1];
      }
    }




    if(!wasm.functionEntry(capi.SQLITE_WASM_DEALLOC)){
      toss("Internal error: cannot resolve exported function",

           "entry SQLITE_WASM_DEALLOC (=="+capi.SQLITE_WASM_DEALLOC+").");


    }
    const __rcMap = Object.create(null);
    for(const t of ['resultCodes']){
      for(const e of Object.entries(wasm.ctype[t])){
        __rcMap[e[1]] = e[0];
      }
    }
Changes to ext/wasm/api/sqlite3-wasm.c.
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
    DefInt(SQLITE_RECURSIVE);
  } _DefGroup;

  DefGroup(blobFinalizers) {
    /* SQLITE_STATIC/TRANSIENT need to be handled explicitly as
    ** integers to avoid casting-related warnings. */
    out("\"SQLITE_STATIC\":0, \"SQLITE_TRANSIENT\":-1");
#if 0
    /* This approach to exporting SQLITE_WASM_DEALLOC as a pointer to
       sqlite3_free fails in Safari. */
    outf(",\"SQLITE_WASM_DEALLOC\": %lld",
         (sqlite3_int64)(sqlite3_free));
#endif
  } _DefGroup;

  DefGroup(changeset){
    DefInt(SQLITE_CHANGESETSTART_INVERT);
    DefInt(SQLITE_CHANGESETAPPLY_NOSAVEPOINT);
    DefInt(SQLITE_CHANGESETAPPLY_INVERT);








<
<
<


<







460
461
462
463
464
465
466



467
468

469
470
471
472
473
474
475
    DefInt(SQLITE_RECURSIVE);
  } _DefGroup;

  DefGroup(blobFinalizers) {
    /* SQLITE_STATIC/TRANSIENT need to be handled explicitly as
    ** integers to avoid casting-related warnings. */
    out("\"SQLITE_STATIC\":0, \"SQLITE_TRANSIENT\":-1");



    outf(",\"SQLITE_WASM_DEALLOC\": %lld",
         (sqlite3_int64)(sqlite3_free));

  } _DefGroup;

  DefGroup(changeset){
    DefInt(SQLITE_CHANGESETSTART_INVERT);
    DefInt(SQLITE_CHANGESETAPPLY_NOSAVEPOINT);
    DefInt(SQLITE_CHANGESETAPPLY_INVERT);

1593
1594
1595
1596
1597
1598
1599



1600
1601
1602
1603
1604
1605
1606
** a single i64 argument.
*/
SQLITE_WASM_KEEP
int sqlite3_wasm_config_j(int op, sqlite3_int64 arg){
  return sqlite3_config(op, arg);
}




/*
** This function is NOT part of the sqlite3 public API. It is strictly
** for use by the sqlite project's own JS/WASM bindings.
**
** Returns a pointer to sqlite3_free(). In compliant browsers the
** return value, when passed to sqlite3.wasm.exports.functionEntry(),
** must resolve to the same function as







>
>
>







1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
** a single i64 argument.
*/
SQLITE_WASM_KEEP
int sqlite3_wasm_config_j(int op, sqlite3_int64 arg){
  return sqlite3_config(op, arg);
}

#if 0
// Pending removal after verification of a workaround discussed in the
// forum post linked to below.
/*
** This function is NOT part of the sqlite3 public API. It is strictly
** for use by the sqlite project's own JS/WASM bindings.
**
** Returns a pointer to sqlite3_free(). In compliant browsers the
** return value, when passed to sqlite3.wasm.exports.functionEntry(),
** must resolve to the same function as
1618
1619
1620
1621
1622
1623
1624

1625
1626
1627
1628
1629
1630
1631
** Safari-specific quirk covered at
** https://sqlite.org/forum/info/e5b20e1feb37a19a.
**/
SQLITE_WASM_KEEP
void * sqlite3_wasm_ptr_to_sqlite3_free(void){
  return (void*)sqlite3_free;
}


#if defined(__EMSCRIPTEN__) && defined(SQLITE_ENABLE_WASMFS)
#include <emscripten/wasmfs.h>

/*
** This function is NOT part of the sqlite3 public API. It is strictly
** for use by the sqlite project's own JS/WASM bindings, specifically







>







1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
** Safari-specific quirk covered at
** https://sqlite.org/forum/info/e5b20e1feb37a19a.
**/
SQLITE_WASM_KEEP
void * sqlite3_wasm_ptr_to_sqlite3_free(void){
  return (void*)sqlite3_free;
}
#endif

#if defined(__EMSCRIPTEN__) && defined(SQLITE_ENABLE_WASMFS)
#include <emscripten/wasmfs.h>

/*
** This function is NOT part of the sqlite3 public API. It is strictly
** for use by the sqlite project's own JS/WASM bindings, specifically