We currently have a fair amount of code of the form:
if (is<Child>(parent)) {
auto& child = static_cast<Child&>(parent);
if (child.foo()) {
}
}
This new cast allows us to instead write code of the form:
if (auto* child = as_if<Child>(parent); child && child->foo()) {
}
N.B. The name "as_if" was chosen because we are considering renaming
verify_cast to "as".
Co-authored-by: Tim Ledbetter <tim.ledbetter@ladybird.org>
Interestingly, the spec has a note saying:
> window.postMessage() performs StructuredSerializeWithTransfer on
> its arguments, but is careful to do so immediately, inside the
> synchronous portion of its algorithm. Thus it is able to use the
> algorithms without needing to prepare to run script and prepare
> to run a callback.
But there is no note about the deserialization steps. In any case, we do
need callbacks enabled here.
...Which doesn't do anything given start() itself doesn't do anything,
but this is a subtle enough point of the spec that it seems worthwhile
to implement now for whenever this does become meaningful.
For example, running `alert(1)` will pause the event loop, during which
time no JavaScript should execute. This patch extends this disruption to
microtasks. This avoids a crash inside the microtask executor, which
asserts the JS execution context stack is empty.
This makes us behave the same as Firefox in the following page:
<script>
queueMicrotask(() => {
console.log("inside microtask");
});
alert("hi");
</script>
Before the aforementioned assertion was added, we would execute that
microtask before showing the alert. Firefox does not do this, and now
we don't either.
Implements idea described in
https://docs.google.com/document/d/1vEW86DaeVs4uQzNFI5R-_xS9TcS1Cs_EUsHRSgCHGu8
Invalidation sets are used to reduce the number of elements marked for
style recalculation by collecting metadata from style rules about the
dependencies between properties that could affect an element’s style.
Currently, this optimization is only applied to style invalidation
triggered by class list mutations on an element.
We were previously crashing when invoking 'scroll to the fragment' on
such documents as it was unable to find the active document. This is
as a result of our AD-HOC implementation not setting up the document
fully to mark it is active before running the parser.
Fixes a crash on https://tweakers.net.
This is sub-optimal but let's rebuild the whole tree for now, since this
case gets quite complicated and there are more valuable things to chase
after first.
Thanks to Gingeh for the reduced test case!
This updates our local ICU overlay port to use ICU 76.1. This includes
Unicode 16 and CLDR 46.
Upstream vcpkg is not able to supply versions past 74 yet due to various
dependency issues, but we are able to use this version ourselves. The
overlay port now includes a patch to revert ICU's dependence on autoconf
2.72 for now, as this version is not yet available on all systems.
All of the test changes were cross-referenced with Firefox to ensure
correctness.
In ICU 76, the default was changed from "arab" to "latn". See:
c149724509
The whole point of these tests was to use a non-Latin numbering system.
This patch ensures that is the case to make following patches easier to
grok.
This separates the StringBuilder constructor into 2 constructors. This
essentially allows forming code of the following pattern:
StringBuilder foo() { return {}; }
Otherwise, we would get the following compiler error:
chosen constructor is explicit in copy-initialization
Due to the explicitness of the StringBuilder constructor.
This is required for an upcoming update to ICU 76, where we use our
StringBuilder in templated ICU code.
These common cases now cause us to invalidate the layout tree starting
at the relevant parent node instead of invalidating the entire tree.
- DOM node insertion
- DOM node removal
- innerHTML setter
- textContent setter
This makes a lot of dynamic content much faster. For example, demos
on shadertoy.com go from ~18 fps to ~28 fps on my machine.
DOM nodes now have two additional flags:
- Needs layout tree update
- Child needs layout tree update
These work similarly to the needs-style-update flags, but instead signal
the need to rebuild the corresponding part of the layout tree.
When a specific DOM node needs a layout tree update, we try to create
a new subtree starting at that node, and then replace the subtree in the
old layout tree with the newly created subtree.
This required some refactoring in TreeBuilder so that we can skip over
entire subtrees during a tree update.
Note that no partial updates happen yet (as of this commit) since we
always invalidate the full layout tree still. That will change in the
next commit.
Instead just update the existing wrapper with computed values from the
table box, to insure that upside-down "inheritance" works as expected.
This allows table fixup to run on partially updated layout trees without
adding a new layer of unnecessary wrappers every time.
While PendingPullIntos are typically visted by their controller there
were some cases that we were removing those references from the
controller and storing them in a SinglyLinkedList on the stack which
is not safe.
Instead, make PendingPullInto a GC::Cell type, which also allows us
to remove an awkward copy of the struct where the underlying reference
was previously being destroyed.
While we don't yet have a working `using` implementation with our byte
code, we can still keep our DisposableStack implementation up to date.
The changes brought in here are all editorial, and set us up to start
an AsyncDisposableStack implementation.
Previously it only deoptimized the parent scope if the current scope
contains direct eval, which is incorrect because code ran in direct
eval mode has access to the entire scope chain it was executed in.
The fix is to also propagate direct eval's presence if the current
scope is marked as being screwed by direct eval.
This fixes Google's botguard failing to complete on Google sign in, as
it tried to access local variables outside of a direct parent function
with eval, causing it throw "unhandled" exceptions. Unhandled is in
quotes because their bytecode VM _technically_ caught it, but it was
considered an unhandled exception. This was determined by removing get
optimizations and then adding debug output for every get operation.
Using this, I noticed that for these errors, it would access the
'message' and 'stack' properties. This is because their error handler
function noticed this was not a synthesised error, which is never
expected to happen. That was determined by using Chrome Devtools 'pause
on handled exception' feature, and noticing it never threw a '[var] is
not defined' exception, but only synthesized error objects which
contained a sentinel value to let it know it was synthesized.
I added debug output to eval to print out what was being eval'd because
it makes heavy use of eval. This revealed that the exceptions only came
from eval.
I then dumped every generated executable and noticed the variables it
was trying to access were generated as local variables in the top
scope. This led to checking what makes a variable considered local or
not, which then lead to this block of code in ~ScopePusher that
propagates eval presence only to the immediate parent scope. This
variable directly controls whether to create all variables properly
with variable environments and bindings or allow them to be stored as
local registers tied to that function's executable.
Since this now lets botguard run to completion, it no longer considers
us to be an insecure/potential bot browser when signing in, now
allowing us to be able to sign in to Google.
The spec never mentions the possibility for the `hash` member of
`RsaHashedKeyAlgorithm` to be a string, it should be a `KeyAlgorithm`
object containing a `name` string member.
Spec: https://w3c.github.io/webcrypto/#dfn-RsaHashedKeyAlgorithm