🏡 index : cold-air-networks/mirror-jetstream.git

// Copyright 2024 the V8 project authors. All rights reserved.
// Copyright 2025 Apple Inc. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// First, some polyfills for missing browser APIs in JavaScript shells.
// Since the generated JavaScript code of SQLite immediately uses some of them,
// we need to load and run this code before the generated `speedtest1.js` in the
// JetStream driver.

// Empty `URLSearchParams` has just the same interface as a `Map`.
globalThis.URLSearchParams = Map;

// Now, some configuration options for when we initialize SQLite.

// Use JetStream functions instead of `console.log` and friends.
globalThis.sqlite3ApiConfig = {
  log: print,
  debug: print,
  warn: print,
  error: print,
};

// Make sure we never initialize OPFS by removing one of it's APIs (see
// `installOpfsVfs` in the generated JavaScript code of sqlite).
// We never want to use it anyway (see VFS config below) and this way we don't
// waste cycles on the browser runner to initialize it.
delete globalThis.FileSystemHandle;

class Benchmark {
  sqlite3Module;

  async init() {
    Module.wasmBinary = await JetStream.getBinary(JetStream.preload.wasmBinary);
  }

  async runIteration() {
    if (!this.sqlite3Module) {
      // Defined in the generated SQLite JavaScript code.
      // Different in details but seemingly related/inspired by Emscripten code.
      this.sqlite3Module = await sqlite3InitModule(Module);
    }

    // The following is simplified from inline JavaScript in `speedtest1.html`.
    
    // Configure the VFS to use.
    // Don't use OPFS, WASMFS (which is on top of OPFS), or kvvfs, since they
    // all use persistent browser storage (localStorage or OPFS), which is not
    // available in JavaScript shells.
    // Also don't use memfs, since that crashes with a NULL function pointer.
    // Instead, make the default VFS explicit.
    const capi = this.sqlite3Module.capi
    print("Available SQLite VFS:", capi.sqlite3_js_vfs_list());
    const vfs = "unix";
    print("Using VFS:", vfs);
    const pVfs = capi.sqlite3_vfs_find(vfs);
    if (!pVfs) {
      throw new Error("Unknown VFS:", vfs);
    }

    // These arguments should match the upstream browser runner in 
    // `speedtest1.html`, except for the --size parameter.
    let argv = [
      "speedtest1",
      "--singlethread",
      //"--nomutex",
      //"--nosync",
      //"--memdb", // note that memdb trumps the filename arg
      "--nomemstat",
      "--big-transactions" /*important for tests 410 and 510!*/,
      "--size", "2", // To speedup, default is 100 (and takes about 4s).
      "--vfs", vfs, // See VFS comment above.
    ];

    print("Calling main with argv:", argv);
    const wasm = this.sqlite3Module.wasm;
    wasm.scopedAllocPush();  // Required for `scopedAllocMainArgv()`.
    wasm.xCall("wasm_main", argv.length, wasm.scopedAllocMainArgv(argv));
    wasm.scopedAllocPop();
  }
}