* 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
* Update to primary docs to account for console update
* fix intra-doc link
* Forgot a period
* Fixing the errors on runtime docs
* Add hidden panic to example
* 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
It was reported that the `dbg!` output of native errors was too long. This PR skips printing the `Realm` of a `JsNativeError`. It also improves the `dbg!` output of `Realm` by skipping printing `Inner` and only printing the inner fields of `Inner`.
Noticed we were using this pattern on a couple of places, so I abstracted it behind a `ContextCleanupGuard` struct.
Let me know if you remember another place where this pattern would apply.
Bumps [regress](https://github.com/ridiculousfish/regress) from 0.5.0 to 0.6.0.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a href="https://github.com/ridiculousfish/regress/releases">regress's releases</a>.</em></p>
<blockquote>
<h2>v0.6.0</h2>
<p>Version 0.6.0 of regress, REGex in Rust with EmcaScript Syntax.</p>
<ul>
<li>Unpaired surrogates are now properly handled in accordance with the EcmaScript spec (<a href="https://github.com/jedel1043"><code>@jedel1043</code></a> in <a href="https://redirect.github.com/ridiculousfish/regress/pull/60">ridiculousfish/regress#60</a>)</li>
<li>Invalid ranges like <code>[a-\s]</code> are now permitted in non-Unicode mode, in accordance with Annex B of EcmaScript spec (<a href="https://github.com/HalidOdat"><code>@HalidOdat</code></a> in <a href="https://redirect.github.com/ridiculousfish/regress/pull/62">ridiculousfish/regress#62</a>)</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a href="b0814a7435"><code>b0814a7</code></a> Release regress 0.6.0</li>
<li><a href="dcc8ab63c8"><code>dcc8ab6</code></a> Fix valid character sets in Annex-B</li>
<li><a href="e724b5c04c"><code>e724b5c</code></a> Run <code>cargo clippy</code></li>
<li><a href="701e366172"><code>701e366</code></a> Expand comments further</li>
<li><a href="79890137f8"><code>7989013</code></a> Fix surrogates parsing on regex</li>
<li>See full diff in <a href="https://github.com/ridiculousfish/regress/compare/v0.5.0...v0.6.0">compare view</a></li>
</ul>
</details>
<br />
[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=regress&package-manager=cargo&previous-version=0.5.0&new-version=0.6.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)
Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`.
[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)
---
<details>
<summary>Dependabot commands and options</summary>
<br />
You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
- `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
</details>
This PR implements `Hidden Classes`, I named them as `Shapes` (like Spidermonkey does), calling them maps like v8 seems confusing because there already is a JS builtin, likewise with `Hidden classes` since there are already classes in JS.
There are two types of shapes: `shared` shapes that create the transition tree, and are shared between objects, this is mainly intended for user defined objects this makes more sense because shapes can create transitions trees, doing that for the builtins seems wasteful (unless users wanted to creating an object with the same property names and the same property attributes in the same order... which seems unlikely). That's why I added `unique` shapes, only one object has it. This is similar to previous solution, but this architecture enables us to use inline caching.
There will probably be a performance hit until we implement inline caching.
There still a lot of work that needs to be done, on this:
- [x] Move Property Attributes to shape
- [x] Move Prototype to shape
- [x] ~~Move extensible flag to shape~~, On further evaluation this doesn't give any benefit (at least right now), since it isn't used by inline caching also adding one more transition.
- [x] Implement delete for unique shapes.
- [x] If the chain is too long we should probably convert it into a `unique` shape
- [x] Figure out threshold ~~(maybe more that 256 properties ?)~~ curently set to an arbitrary number (`1024`)
- [x] Implement shared property table between shared shapes
- [x] Add code Document
- [x] Varying size storage for properties (get+set = 2, data = 1)
- [x] Add shapes to more object:
- [x] ordinary object
- [x] Arrays
- [x] Functions
- [x] Other builtins
- [x] Add `shapes.md` doc explaining shapes in depth with mermaid diagrams :)
- [x] Add `$boa.shape` module
- [x] `$boa.shape.id(o)`
- [x] `$boa.shape.type(o)`
- [x] `$boa.shape.same(o1, o2)`
- [x] add doc to `boa_object.md`
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.
Most of the time that we have a `ByValue` ( `[ value ]` syntax ) it is for arrays and the value is usually an index. This PR adds a fast path to the instructions (without calling `.borrow()` on the object to check if its an array)
For example, this code:
```js
let a = [1, 2, 3]
for (let i = 0 ; i < 10000000; ++i) {
a[i % 3] += a[ (i + 1) % 3 ]
}
```
Using `hyperfine`, it ran `1.38` times faster on this PR.
```bash
Benchmark 1: ./boa_main test.js
Time (mean ± σ): 16.504 s ± 0.192 s [User: 16.440 s, System: 0.020 s]
Range (min … max): 16.328 s … 16.938 s 10 runs
Benchmark 2: ./boa_direct_array_access test.js
Time (mean ± σ): 11.982 s ± 0.038 s [User: 11.939 s, System: 0.013 s]
Range (min … max): 11.914 s … 12.035 s 10 runs
Summary
'./boa_direct_array_access test.js' ran
1.38 ± 0.02 times faster than './boa_main test.js'
```