* Remove redundant `num_bindings` field from `CodeBlock`
* Remove redundant num_bindings parameter from push_function_inherits
* Remove redundant num_bindings operand from environment opcodes
* Make pop_compile_environment() return an index
* Move boolean `CodeBlock` flags to bitflags
* Fix ci
* Add doc
* Make update operations reuse the last found binding locator
* Rename opcode
* Reword opcode comments
* Change capacity of `bindings_stack`
* Use the callframe stack to store the current binding
* Fix typo
* Reuse locators on assignment deletions
* Fix binding bug
* Remove leftover comment
We have currently some bugs related to binding assignments on arithmetic operations (`+=`, `++`, `?=`, etc.), but fixing those was getting a bit complex with our current bindings APIs.
This PR refactors our binding handling APIs to be a bit easier to use.
This should hopefully fix more async/futures issues related to resuming execution in the future, since we can leverage generator logic to handle this for us.
It changes the following:
- Refactors `GeneratorContext` to handle context preparation.
- Reuses the functionality of `GeneratorContext` in `Await`.
- Removes `EarlyReturnType` in favour of a single `r#await` bool flag in `CallFrame`.
This Pull Request fixes#2317 and #1835, finally giving our engine proper realms 🥳.
It changes the following:
- Extracts the compile environment stack from `Realm` and into `Vm`.
- Adjusts the bytecompiler to accommodate this change.
- Adjusts `call/construct_internal` to accommodate this change. This also coincidentally fixed#2317, which I'm pretty happy about.
- Adjusts several APIs (`NativeJob`, `Realm`) and builtins (`eval`, initializers) to accommodate this change.
- Adjusts `JsNativeError`s to hold a reference to the Realm from which they were created. This only affects errors created within calls to function objects. Native calls don't need to set the realm because it's inherited by the next outer active function object. TLDR: `JsError` API stays the same, we just set the origin Realm of errors in `JsObject::call/construct_internal`.
This Pull Request fixes test [`assert-throws-same-realm.js`](eb44f67274/test/harness/assert-throws-same-realm.js).
It changes the following:
- Handles global variables through the global object, instead of the `context`.
- Adds an `active_function` field to the vm, which is used as the `NewTarget` when certain builtins aren't called with `new`.
- Adds a `realm_intrinsics` field to `Function`.
This Pull Request changes the following:
- Implement `with` statement parsing, ast node, compilation and excution.
- Implement object environments that are used in the `with` statement excution.
The implementation of object environments can probably be optimized further by using more compile-time information about when object environments can exist. Maybe there could also be a separate environment stack for object environments to reduce the filtering and iteration that is needed with the current implementation.
This does not fix all tests in the `test/language/statements/with` suite yet. But for most failing tests that I have looked at we are missing other features / have bugs elsewhere.
As a note for the review:
The functions in the `impl Context` block in `boa_engine/src/environments/runtime.rs` are mostly copied / moved from the existing functions. The only change there should be the addition of the object environment logic. They had to be moved to `Context` because of borrow semantics.
This PR migrates our entire test suite to our new testing API.
It changes the following:
- Migrates tests to new test API.
- Cleans up the API to be a bit more descriptive and maintainable.
- Prettifies our test failure display to show the failed scripts.
- Splits our massive `tests.rs` file into smaller sub-suites.
Example output of a failing test:
![image](https://user-images.githubusercontent.com/38230983/221502567-9e219371-b4ab-49d0-b42b-94a9b1a9c002.png)
This PR changes the following:
- Modifies `EphemeronBox` to be more akin to `GcBox`, with its own header, roots and markers. This also makes it more similar to [Racket's](https://docs.racket-lang.org/reference/ephemerons.html) implementation.
- Removes `EPHEMERON_QUEUE`.
- Ephemerons are now tracked on a special `weak_start` linked list, instead of `strong_start` which is where all other GC boxes live.
- Documents all unsafe blocks.
- Documents our current garbage collection algorithm. I hope this'll clarify a bit what exactly are we doing on every garbage collection.
- Renames/removes some functions.
Per the [Standard Library development guide](https://std-dev-guide.rust-lang.org/code-considerations/performance/inline.html):
> You can add `#[inline]`:
>
> - To public, small, non-generic functions.
>
> You shouldn't need `#[inline]`:
> - On methods that have any generics in scope.
> - On methods on traits that don't have a default implementation.
>
> `#[inline]` can always be introduced later, so if you're in doubt they can just be removed.
This PR follows this guideline to reduce the number of `#[inline]` annotations in our code, removing the annotation in:
- Non-public functions
- Generic functions
- Medium and big functions.
Hopefully this shouldn't impact our perf at all, but let's wait to see the benchmark results.
<!---
Thank you for contributing to Boa! Please fill out the template below, and remove or add any
information as you feel necessary.
--->
Submitting this as a draft for feedback/second opinions. This draft contains some changes to the documentation.
Quick Overview:
- Potential `Boa` header for Boa's crates added to `boa_engine`.
- Changes the wording to a lot of module headers (See `builtins` module and `object/builtins` module).
- Updating built-in wrapper's code examples to use `?` operator.
- Adds the doc logo URL to a few crates that didn't have it.
The main idea of this draft is to move away from the "This module implements" wording as it feels a bit duplicative when listed under the Modules section (mainly focusing around changes in `boa_engine` to start).
While working on this, I had a question about whether we should be using JavaScript or ECMAScript in the Boa's documentation. We do seem to currently use both, and this draft uses JavaScript heavily in the wording.
This Pull Request restructures the lint deny/warn/allow lists in `boa_engine`. It adds a lot of documentation to pup functions. There are still a few clippy lints that are not fixed, mainly regarding casting of number types. Fixing those lints effectiveley would in some cases probably require bigger refactors.
This should probably wait for #2449 to be merged, because that PR already fixes that lints regarding the `Date` built-in.
<!---
Thank you for contributing to Boa! Please fill out the template below, and remove or add any
information as you feel necessary.
--->
Not sure if anyone else may be working on something more substantial/in-depth, but I thought I'd post this. 😄
The basic rundown is that this is more of an untested (and in some ways naïve) draft than anything else. It builds rather heavily on `rust-gc`, and tries to keep plenty of the core aspects so as to not break anything too much, and also to minimize overarching changes were it to actually be merged at some point.
This implementation does add ~~a generational divide (although a little unoptimized) to the heap,~~ a GcAlloc/Collector struct with methods, and an ephemeron implementation that allows for the WeakPair and WeakGc pointers.
This Pull Request fixes#1805.
It changes the following:
- Implement async arrow function parsing and execution.
- Handle special case when a function expressions binding identifier need to be bound in the function body.
- Implement special silent ignored assignment for the above case.
- Fix issue with getting the correct promise capability for function returns.
- Complete function object `toString` todo.
I will fix the two failing assignmenttargettype tests in a follow up PR.
This should hopefully improve our compilation times, both from a clean build and from an incremental compilation snapshot.
Next would be the parser, but it imports `Context`, so it'll require a bit more work.
The number of file changes is obviously big, but almost nothing was changed, I just moved everything to another crate and readjusted the imports of the `parser` module. (Though, I did have to change some details, because there were some functions on the ast that returned `ParseError`s, and the tests had to be moved to the parser)
This Pull Request implements `delete` for variable references:
```Javascript
x = 5;
console.log(x) // 5;
delete x;
console.log(x) // ReferenceError
```
It changes the following:
- Implements delete for references.
- Fixes tests related to deletions of function definitions inside `eval`.
- Implements an op to throw an error on super property deletion.
This puts us at a conformance of 97.98% for the `test/language/expressions/delete` suite. The last 2 failing tests are related to `with` statements ([11.4.1-4.a-5.js](b5d3192914/test/language/expressions/delete/11.4.1-4.a-5.js (L1)) and [11.4.1-4.a-6.js](b5d3192914/test/language/expressions/delete/11.4.1-4.a-6.js (L18))).
This Pull Request allows collisions of var declarations with already existing lexical bindings if the `eval` call is strict or occurs within strict code. In short, it allows:
```Javascript
{
let x;
{
eval('"use strict"; var x;');
}
}
```
and
```Javascript
"use strict";
{
let x;
{
eval('var x;');
}
}
```
This is valid since in strict code all `eval` calls get their own function environment, making it impossible to declare a new var in the outer function environment. This change also skips poisoning environments on strict code, because `eval` cannot add new declarations for the current environment in that situation.
This is an experiment that tries to migrate the codebase from eager `Error` objects to lazy ones.
In short words, this redefines `JsResult = Result<JsValue, JsError>`, where `JsError` is a brand new type that stores only the essential part of an error type, and only transforms those errors to `JsObject`s on demand (when having to pass them as arguments to functions or store them inside async/generators).
This change is pretty big, because it unblocks a LOT of code from having to take a `&mut Context` on each call. It also paves the road for possibly making `JsError` a proper variant of `JsValue`, which can be a pretty big optimization for try/catch.
A downside of this is that it exposes some brand new error types to our public API. However, we can now implement `Error` on `JsError`, making our `JsResult` type a bit more inline with Rust's best practices.
~Will mark this as draft, since it's missing some documentation and a lot of examples, but~ it's pretty much feature complete. As always, any comments about the design are very much appreciated!
Note: Since there are a lot of changes which are essentially just rewriting `context.throw` to `JsNativeError::%type%`, I'll leave an "index" of the most important changes here:
- [boa_engine/src/error.rs](https://github.com/boa-dev/boa/pull/2283/files#diff-f15f2715655440626eefda5c46193d29856f4949ad37380c129a8debc6b82f26)
- [boa_engine/src/builtins/error/mod.rs](https://github.com/boa-dev/boa/pull/2283/files#diff-3eb1e4b4b5c7210eb98192a5277f5a239148423c6b970c4ae05d1b267f8f1084)
- [boa_tester/src/exec/mod.rs](https://github.com/boa-dev/boa/pull/2283/files#diff-fc3d7ad7b5e64574258c9febbe56171f3309b74e0c8da35238a76002f3ee34d9)
This Pull Request fixes#1371. And yeah, the number of file changes is real...
It changes the following:
- Split the ast `Node` into `Statement` and `Expression`.
- Rewrite the parser and bytecompiler to conform to this change.
- Refactor some ast nodes into reusable structures.
- Rewrite `contains_arguments` and `contains` to ease the transition into a future ast visitor.
List of things that were apparently fixed by this refactor?:
- Implement read-assign operation for private accessors (e.g. `this.#field ||= 5`).
- `var await` declaration now allowed outside `async` functions and inside functions nested in async functions.
- Reject redeclarations of variables declared in the init list of a for loop.
Still missing some documentation adjustments, will try to do it ASAP.
I think it's time to address the elephant in the room.
This Pull Request will (hopefully!) solve part of #736.
This is a complete rewrite of `JsString`, but instead of storing `u8` bytes it stores `u16` words. The `encode!` macro (renamed to `utf16!` for simplicity) from the `const-utf16` crate allows us to create UTF-16 encoded arrays at compilation time. `JsString` implements `Deref<Target=[u16]>` to unlock the slice methods and possibly make some manipulations easier. However, we would need to create our own library of utilities for `JsString`.
This Pull Request changes the following:
- Implement `super` expression parsing / execution.
- Implement early errors for `super` expressions.
- Refactor / add internal slot representation for environment and function objects.
This Pull Request fixes/closes #948.
It changes the following:
- Implement the global `eval()` function.
Runtime code evaluation brings some challenges for environments. Currently the setting and getting of variable bindings is done via indices that are calculated at compile time. This prevents costly hashmap lookups at runtime.
Evaluiation at runtime needs access to existing compile time environments. This is a relatively easy change. We wrap compile time environments in `Gc` and make them accessible at runtime.
Because `eval()` can add var bindings to existing function environments, we have to adjust the environments for this. Because we cannot recompile all previously stored binding indices, we have to fallback to hashmap lookups at runtime. To prevent this from tanking our performance we add a flag to each environment that marks if any `eval()` has been executed in that environment (or outer environments). This makes it possible to retain the performance of precompiled environment lookups while having a fallback for `eval()`.
TLDR: `eval()` is not only horribly unsafe but also a burden for performance. [Never use eval()!](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval#never_use_eval!)
This Pull Request changes the following:
- Implement redeclaration errors in the parser
- Remove redeclaration errors from the compiler (this is a big step towards #1907)
- Fix some failing tests on the way
This requires a slight change in our public api. The Parser new requires a full `Context` instead of just the `Interner` for parsing new code. This is required, because if multiple scripts are parsed (e.g. every input in the REPL) global variables must be checked for redeclarations.