Skip to content

LuciNyan/slowjs

 
 

Repository files navigation

SlowJS

SlowJS - QuickJS is quick but I can make it slow!

Learning the awesome QuickJS by extending it with below functionalities:

  • Divide the 5.4W LoC file quickjs.c into multiple small files, which makes the code easy to browser and navigate
  • A debugger which supports inline breakpoints and includes web interfaces which is easy to integrate with the Debug Adapter Protocol
  • Dump the GC managed objects and view the results in the Chrome inspector

Debugger

The debugger can be tasted by following steps:

  1. Build our SlowJS:
cmake -S . --preset=default
cmake --build --preset=qjs

the location of the built stuff is ./build/qjs/qjs

  1. Make up a file tmp_test.js to test:
function add(a, b) {
  const c = a + b;
  return c;
}

function sub(a, b) {
  const c = a - b;
  return c;
}

function doSth(a, b) {
  return add(a, b) + sub(a, b);
}

print(doSth(1, 2));
  1. Start the debugger:
./build/qjs/qjs --debug 8097
  1. Connect to the debugger:
nc 0.0.0.0 8097

We use nc to communicate with the debugger server, then we can paste come commands to perform debug

  1. Call the debugger to launch a new session:
{ "type": "launch", "data": { "file": "./tmp_test.js" } }

Paste above json into the nc REPL and press ENTER

  1. Set breakpoints:
{ "type": "setBreakpoint", "data": { "file": "./tmp_test.js", "line": 3, "col": 0 } }
{ "type": "setBreakpoint", "data": { "file": "./tmp_test.js", "line": 8, "col": 0 } }
  1. Star to run our test script:
{ "type": "run" }
  1. Now the debugger is paused at the first breakpoint, we can list the stack frames:
{ "type": "listStackframes" }

the output looks like:

{
  "type": "listStackframes",
  "data": [
    {
      "name": "add",
      "file": "./tmp_test.js",
      "line": 1
    },
    {
      "name": "doSth",
      "file": "./tmp_test.js",
      "line": 11
    },
    {
      "name": "<eval>",
      "file": "./tmp_test.js",
      "line": 1
    }
  ]
}
  1. We can resume the debugger by issuing below command:
{ "type": "continue" }
  1. Now the debugger is paused at the second breakpoint, we can print the variable in the topmost stack frame:
{ "type": "dumpStackframe", "data": { "i": 0 }  }

the output looks like:

{
  "type": "dumpStackframe",
  "data": {
    "args": [
      {
        "name": "a",
        "value": 1
      },
      {
        "name": "b",
        "value": 2
      }
    ],
    "vars": [
      {
        "name": "c",
        "value": -1
      }
    ],
    "closure_vars": [],
    "name": "sub",
    "file": "./tmp_test.js",
    "line": 6
  }
}
  1. We can use the continue command resume the debugger again:
{ "type": "continue" }
  1. Now the test script is done and the debugger server prints the final results:
client closed, stopping sess thread...
new sess thread is running...
2

Development

It's better to glance over the available options before you perform the actual build:

cmake -B build -LH
  • -B stands for the building directory
  • -L stands for listing all the options
  • -H stands for printing the help messages along with the options

above command will print the available options and their help messages, use them like this:

cmake -B build -S . -G Ninja -D QJS_DUMP_BYTECODE=1
  • -S stands for the source directory
  • -D stands for specifying an options in a key=value pattern

then choose one of below sections to run in project root directory

Debug build

cmake -S . --preset=default
cmake --build --preset=qjs

Release build

cmake -S . --preset=default -D CMAKE_BUILD_TYPE=Release
cmake --build --preset=qjs

Tests

cmake -S . --preset=default
cmake --build --preset=run-tests

Microbench

cmake -S . --preset=default -D CMAKE_BUILD_TYPE=Release
cmake --build --preset=run-microbench

Test262

cmake -S . --preset=default -D CMAKE_BUILD_TYPE=Release
cmake --build --preset=run-test262

# Result: 302/75790 errors, 1396 excluded, 7712 skipped, 302 new

Presets

You can also choose the presets listed in CMakePresets.json to run:

# Use a config preset
cmake -S . --preset=default

# Use a build preset
cmake --build --preset=run-tests

About

Learning the awesome QuickJS

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • C 92.5%
  • JavaScript 7.2%
  • Other 0.3%