62 Commits
Author SHA1 Message Date
Saúl Ibarra Corretgé 5f2fb55994 Port Bellard's register-based regexp engine
Replace quickjs-ng's stack-based libregexp with Fabrice Bellard's
register-based backtracking engine, which
is faster and guarantees linear bytecode size growth. This also brings the
regexp implementation to full parity with upstream: v flag, regexp modifiers,
duplicate named capture groups, properties of strings, and Script=Unknown.

Includes the following upstream commits from bellard/quickjs:
  7ab2341  faster and simpler implementation of regexp backtracking
  a774007  removed buffer overflows introduced in regexp optimizations
  371c06e  ensure regexp bytecode size grows linearly with the input
  47aac8b  regexp: a set of registers instead of an auxiliary stack
  5907aa6  added missing lre_poll_timeout()
  f113949  removed alloca() in lre_exec(); \s/\S opcodes; optimized \b/\B
  7bd1ae2  \x{N} is a syntax error
  24379bf  added regexp duplicate named groups; fixed reset of captures
  f95b8ba  added regexp modifiers
  d7cdfdc  regexp: added v flag support; CR_OP_SUB + properties of strings
  fc524f7  added missing 'Unknown' unicode Script
2026-06-27 12:43:44 +02:00
Saúl Ibarra CorretgéandBen Noordhuis 440883bda5 Implement explicit resource management
Co-authored-by: Ben Noordhuis <[email protected]>

Closes: https://github.com/quickjs-ng/quickjs/pull/865
2026-05-17 00:33:49 +02:00
Fabrice Bellard 83bd236785 added JSON.parse source text access 2026-03-27 23:09:35 +01:00
Ben Noordhuis 8968855f20 Add checksum field to bjson (#1386)
Helps protect the wire format against data corruption, where corruption
should be understood as bit flips, not adversarial input.

Fixes: https://github.com/quickjs-ng/quickjs/issues/1378
2026-03-06 18:32:46 +01:00
Saúl Ibarra Corretgé cb83fd9d69 Port closure variable type refactoring
Replace is_local/is_arg boolean fields in JSClosureVar with a single
closure_type enum (JSClosureTypeEnum) that supports 8 distinct types:
- JS_CLOSURE_LOCAL: local variable in parent function
- JS_CLOSURE_ARG: argument variable in parent function
- JS_CLOSURE_REF: closure variable reference in parent function
- JS_CLOSURE_GLOBAL_REF: global variable reference
- JS_CLOSURE_GLOBAL_DECL: global variable declaration (eval)
- JS_CLOSURE_GLOBAL: global variable (eval)
- JS_CLOSURE_MODULE_DECL: module variable definition (eval)
- JS_CLOSURE_MODULE_IMPORT: module import definition (eval)

Ref: https://github.com/bellard/quickjs/commit/a6816be
2026-01-29 11:31:41 +01:00
Saúl Ibarra Corretgé 1438b57831 Optimize global variable access
- Made JS_GetGlobalVar and JS_SetGlobalVar inline with fast paths
- Removed OP_check_var and OP_put_var_strict opcodes
- Simplified optimize_scope_make_global_ref to not use strict mode special code
- Simplified bytecode optimizations that referenced removed opcodes
- Updated microbench.js to use normal functions instead of eval
- Regenerated bytecode for updated opcode indices

Note: This removes full compliance with the spec for strict mode variable
assignment so that they are as fast as in non strict mode (V8, SpiderMonkey
and JavaScriptCore do the same).

Ref: https://github.com/bellard/quickjs/commit/2c90110
2026-01-29 11:31:41 +01:00
Saúl Ibarra Corretgé 97d23e51dc Port closure optimizations (#1313)
* Port closure optimizations

Ref: https://github.com/bellard/quickjs/commit/ae7219b1a1b2f409435d00b32c1e10d250e0d064
2026-01-12 10:00:06 +01:00
Saúl Ibarra Corretgé bb7a32d541 Add support for import attributes and JSON modules
Ref: https://github.com/bellard/quickjs/commit/f10ef299a6ab4c36c4162cc5840f128f74ec197c
2026-01-08 01:01:10 +01:00
Ben Noordhuis bbcfcd5bc7 Add Iterator.zipKeyed (#1277) 2026-01-08 00:02:31 +01:00
Ben Noordhuis 210ecb2b27 Add Iterator.zip (#1274) 2026-01-07 23:07:34 +01:00
Ben Noordhuis fa9472db36 Tab-complete keywords in REPL (#1267)
Make it smart enough to complete:

- `wh<TAB>` to `while (`
- `tr<TAB>` to `try {`
- `th<TAB>` to `this` and then `this<TAB>` to `this.`
- etc.

But don't complete object properties that way.

Fixes: https://github.com/quickjs-ng/quickjs/issues/1265
2025-12-07 23:03:12 +01:00
Zephyr Lykos cf0c52c68c repl: respect xdg base dir, default on linux
this will fallback to the old path if not found.
2025-10-14 12:59:23 +02:00
Ben Noordhuis bc7c58db82 Add Iterator.concat (#1158)
Implements https://github.com/tc39/proposal-iterator-sequencing
2025-09-25 17:15:24 +02:00
bptato eb996c584f Add DOMException
Implemented separately from the other errors because it is defined in
terms of WebIDL, where members of an interface are getters on their
prototype.

See the difference between
`JSON.stringify(Object.getOwnPropertyDescriptors(new TypeError()))` vs
`JSON.stringify(Object.getOwnPropertyDescriptors(new DOMException()))`.

Note: the standard doesn't specify where to put "stack".  We follow
existing practice which imitates node instead of browsers.
2025-09-01 09:12:33 +02:00
Ben Noordhuis a9a8ece429 Move builtin-array-fromasync.h to toplevel (#1034)
Putting it in gen/ is inconvenient for downstream users that vendor or
repackage the source files.
2025-04-22 21:16:28 +02:00
Saúl Ibarra Corretgé 8ead934eff Fix standalone executables when not using the full path
Fixes: https://github.com/quickjs-ng/quickjs/issues/1004
2025-04-16 10:21:07 +02:00
Saúl Ibarra Corretgé ad1d1af0bf New BigInt implementation
Manually port the following commits from bellard/quickjs

https://github.com/bellard/quickjs/commit/61e8b9442840bf94a2a9b0b872c8b3a197c1eac3
https://github.com/bellard/quickjs/commit/ee4cd4deaced6b5966b594e257ff1dd10b5d02d4
https://github.com/bellard/quickjs/commit/6de88859e7fdb8c6418e1033e75ca4900e022b51
https://github.com/bellard/quickjs/commit/5a16c0c1eba084742ed328eff75b9e886e63d166
https://github.com/bellard/quickjs/commit/6d6893bfa3d383d4952b67954003800aba1f4be8
https://github.com/bellard/quickjs/commit/131408fa07254ba6c44b1d3804ba43aadd4440a1

Co-authored-by: Fabrice Bellard <[email protected]>

Since libbf is gone, incorporate xsum as the backing for the
Math.sumPrecise implementation.

Changes made to xsum:

- Removed printf debug statements since many contained type errors
- Removed unneeded debug functions
- Added incldue guards
2025-04-02 22:35:25 +02:00
Ben Noordhuis 97e6ef94c5 Simplify Array.fromAsync lazy loading (#982)
Store it as classic JS instead of an ES module that we need to pull
apart first.

Added benefit is that it shrinks the serialized representation by 5%.
2025-03-17 11:32:44 +01:00
Ben Noordhuis bfc9e3cc01 Add Array.fromAsync (#975)
Implement Array.fromAsync as a lazily loaded bytecode function.

Fixes: https://github.com/quickjs-ng/quickjs/issues/962
2025-03-15 22:44:30 +01:00
Ben Noordhuis 4c32c53a3b Record stack trace for non-object exceptions (#805)
Consider this script that throws an uncaught exception:

    function f() {
        throw "fail"
    }
    f()

Running with `qjs --script t.js` used to print merely:

    fail

But now prints:

    fail
        at f (t.js:2:11)
        at f (t.js:4:1)

qjs has been updated but no public API yet because I still need to think
through the corner cases.

Includes a one-line fix for line:column reporting for throw statements.

Refs: https://github.com/quickjs-ng/quickjs/issues/799
2025-01-24 23:47:37 +01:00
Saúl Ibarra Corretgé a7914d1711 Use stdbool rather than custom booleans
Fixes: https://github.com/quickjs-ng/quickjs/issues/817
2025-01-15 14:21:37 +01:00
Saúl Ibarra Corretgé 97ea19dc81 Simplify exiting interpreter with exception
- Avoid keeping the exception object around
- Avoid passing the responsibility of freeing the exeption object to the
  caller
2025-01-08 21:37:49 +01:00
Ben Noordhuis ac4cd17bb5 Track line and column numbers for expressions (#781)
Commit 73cc00e reduced the number of emitted source locations a great
deal but it resulted in at least one observable regression:

    export default async function f() {
         return "abc" + x
    }
    f() // ReferenceError should point to 2:20 but pointed to 1:1

Emit source locations for expressions again. Increases the average
number of source locations by about 15%. Non-scientifically tested
by counting source locations emitted when parsing the test suite
before and after.

No test because we currently cannot easily test stack traces coming
from module imports.

Fixes: https://github.com/quickjs-ng/quickjs/issues/779
2025-01-05 22:20:43 +01:00
Ben Noordhuis 5b609f15af Optimize derived class construction (#753)
We were emitting gobs of inefficient bytecode that created an arguments
array on the stack, then applied it to the parent constructor.

Add a new opcode for initializing a derived class. Speeds up construction
by 500%, although sadly that is not visible in the web-tooling-benchmark,
only in micro-benchmarks.

Fixes: https://github.com/quickjs-ng/quickjs/issues/752
2025-01-05 22:01:37 +01:00
Saúl Ibarra Corretgé e5915821be Throw error when target executable cannot be found (#764) 2024-12-23 21:31:15 +01:00
Saúl Ibarra Corretgé ce03c998c4 Add ability to create standalone binaries with qjs
Ref: https://github.com/quickjs-ng/quickjs/issues/438
Closes: https://github.com/quickjs-ng/quickjs/pull/441
2024-12-03 22:59:11 +01:00
Saúl Ibarra Corretgé f7f70fc579 Fix leak when interpreter exits due to exception
Fixes: https://github.com/quickjs-ng/quickjs/issues/720
2024-11-25 11:07:07 +01:00
Saúl Ibarra Corretgé 9631492534 Fix catching all exceptions from std.evalScript
In case of a syntax error, the function throws syncrnonously.

I'll admit I wondered when Promise.try would be useful... I guess I know
now!

Fixes: https://github.com/quickjs-ng/quickjs/issues/720#issuecomment-2495961142
2024-11-25 10:44:05 +01:00
Saúl Ibarra Corretgé 284510f781 Make Iterator.from spec compliant
Create a proper wrapper around the inner iterator and proxy the calls to
next / return.
2024-11-15 13:35:25 +01:00
Saúl Ibarra Corretgé c41ee4f15f Implement Iterator.prototype.drop
Includes the scaffold for other iterator helper methods that require an
Iterator Helper object.
2024-11-11 22:25:24 +01:00
Ben Noordhuis 73cc00e57e Improve line:column tracking (#660)
Emit source locations manually for more precise tracking. Don't infer
them from emitted bytecode opcodes because that leads to inaccurate
and sometimes surprising results.

Speeds up code generation (although infinitesimally) as a bonus.

Fixes: https://github.com/quickjs-ng/quickjs/issues/236
2024-11-07 22:03:00 +01:00
Ben Noordhuis 37fe427d59 Add resizable ArrayBuffers (#646)
This commit implements resizable ArrayBuffers - RABs for short - and
extends typed arrays (TAs) to support fixed-length and length-tracking
modes.

SharedArrayBuffers (SABs) also support the maxByteLength option now but
I cheated and allocate all memory upfront because atomically resizing
memory allocations is hard and this commit is already big and complex.

The lion's share is updating all the TA prototype methods to deal with
RABs resizing underneath them. Method arguments can be arbitrary objects
with arbitrary .valueOf methods and arbitrary side effects, like...
resizing the RAB we're currently operating on.

Fixes: https://github.com/quickjs-ng/quickjs/issues/477
2024-11-05 21:55:42 +01:00
Saúl Ibarra Corretgé cc11a829e8 Prefix stdlib modules with "qjs:"
Fixes: https://github.com/quickjs-ng/quickjs/issues/616
2024-10-24 22:24:03 +02:00
Ben Noordhuis 8cd59bf7c4 Improve JS_DetectModule (#610)
It's still not infallible (I don't think it can ever be, the whole
premise is wrong) but hopefully it's a little less fallible now.

Fixes: https://github.com/quickjs-ng/quickjs/issues/606
2024-10-20 12:42:21 +02:00
Saúl Ibarra Corretgé d0df61d04a Support the NO_COLOR env variable in the REPL 2024-09-27 19:53:11 +02:00
Saúl Ibarra Corretgé 06175d1e0c Simplify eval_and_print code in REPL
We always use async eval.

Also clean up some console.log usage since we use std.puts all across.
2024-09-26 20:07:24 +02:00
Saúl Ibarra Corretgé b1dc19c4f7 Add Ctrl-W support for REPL 2024-09-26 09:55:18 +02:00
Saúl Ibarra Corretgé 946d653c58 Fix clearing screen in REPL with Ctrl-L 2024-09-25 21:14:49 +02:00
Ben Noordhuis aefdee7b9a Add Iterator (#548) 2024-09-24 22:07:29 +02:00
Saúl Ibarra Corretgé 3a96b9cb6f Support private brand checks
Fixes: https://github.com/quickjs-ng/quickjs/issues/541
Ref: https://github.com/bellard/quickjs/commit/3ab1c2b3148d1c70181607002aac23ecdd2ad482
2024-09-24 18:37:02 +02:00
Saúl Ibarra Corretgé c25aad7b49 Add ability to (de)serialize symbols
Fixes: https://github.com/quickjs-ng/quickjs/issues/481
2024-09-24 10:01:08 +02:00
Saúl Ibarra Corretgé 5f5170796e regexp: fixed the zero advance logic in quantifiers
Ref: https://github.com/bellard/quickjs/commit/10fc744ae4dfe59b685f5643b71530891cf0be3b
2024-09-14 22:00:48 +02:00
zeromake 902cc2cf0e Add native module support on Windows 2024-09-10 22:47:40 +02:00
Ben Noordhuis 8e81a88a18 Add Set.prototype.union (#499) 2024-09-06 09:24:21 +02:00
Ben Noordhuis 9bc41a8a00 Add Float16Array (#491) 2024-09-03 20:32:17 +02:00
Ben Noordhuis 3a58376485 Support (de)serializing Map and Set objects (#483)
Fixes: https://github.com/quickjs-ng/quickjs/issues/482
2024-08-19 12:20:42 +02:00
Ben Noordhuis 5a50ce3b08 Export bjson module (#478)
I find it convenient to have access to JS_ReadObject and JS_WriteObject
from JS land. That's precisely the functionality that tests/bjson.c
provides, ergo, move it into quickjs-libc.c
2024-08-11 11:04:08 +02:00
Tom Lienard d3da56b630 Sync TLA implementation with upstream
Fixes: https://github.com/quickjs-ng/quickjs/issues/339
2024-06-07 15:46:44 +02:00
Charlie Gordon f227746c6e Add util.inspect emulation in REPL (#387)
- output values with controlable depth and detail
- add `.hidden` and `.depth` directives
- remove `eval_mode`
- add `use_strict` and `.strict` meta command
- add missing closures on global objects
- save and load command history to/from `~/.qjs_history`
- use USEPROFILE variable on Windows in addition to HOME
- use the same style names as util.inspect
2024-04-21 08:46:17 +02:00
Charlie Gordon f326a7a195 Add strip option in qjsc to reduce object size (#388)
- `-s` strips the source code
- `-ss` strips source and line/column numbers information
- `qjsc repl.js` generates an object size of **105726** bytes
- `qjsc -s repl.js` generates an object size of **20853** bytes
- `qjsc -ss repl.js` generates an object size of only **16147** bytes
- compile repl.js with `-ss`
- bump byte code version to 12
2024-04-19 08:41:12 +02:00