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
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
- 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
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
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.
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
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
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
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
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
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
- 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
- `-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