The basic idea is that a global object cannot just come out of nowhere,
it must be associated to a realm - so get it from there, if needed.
This is to enforce the changes from all the previous commits by not
handing out global objects unless you actually have an initialized
realm (either stored somewhere, or the VM's current realm).
- Prefer VM::current_realm() over GlobalObject::associated_realm()
- Prefer VM::heap() over GlobalObject::heap()
- Prefer Cell::vm() over Cell::global_object()
- Prefer Wrapper::vm() over Wrapper::global_object()
- Inline Realm::global_object() calls used to access intrinsics as they
will later perform a direct lookup without going through the global
object
This is needed so that the allocated NativeFunction receives the correct
realm, usually forwarded from the Object's initialize() function, rather
than using the current realm.
Global object initialization is tightly coupled to realm creation, so
simply pass it to the function instead of relying on the non-standard
'associated realm' concept, which I'd like to remove later.
This works essentially the same way as regular Object::initialize() now.
Additionally this allows us to forward the realm to GlobalObject's
add_constructor() / initialize_constructor() helpers, so they set the
correct realm on the allocated constructor function object.
This is a continuation of the previous six commits.
The global object is only needed to return it if the execution context
stack is empty, but that doesn't seem like a useful thing to allow in
the first place - if you're not currently executing JS, and the
execution context stack is empty, there is no this value to retrieve.
This is a continuation of the previous five commits.
A first big step into the direction of no longer having to pass a realm
(or currently, a global object) trough layers upon layers of AOs!
Unlike the create() APIs we can safely assume that this is only ever
called when a running execution context and therefore current realm
exists. If not, you can always manually allocate the Error and put it in
a Completion :^)
In the spec, throw exceptions implicitly use the current realm's
intrinsics as well: https://tc39.es/ecma262/#sec-throw-an-exception
This is a continuation of the previous three commits.
Now that create() receives the allocating realm, we can simply forward
that to allocate(), which accounts for the majority of these changes.
Additionally, we can get rid of the realm_from_global_object() in one
place, with one more remaining in VM::throw_completion().
This is a continuation of the previous two commits.
As allocating a JS cell already primarily involves a realm instead of a
global object, and we'll need to pass one to the allocate() function
itself eventually (it's bridged via the global object right now), the
create() functions need to receive a realm as well.
The plan is for this to be the highest-level function that actually
receives a realm and passes it around, AOs on an even higher level will
use the "current realm" concept via VM::current_realm() as that's what
the spec assumes; passing around realms (or global objects, for that
matter) on higher AO levels is pointless and unlike for allocating
individual objects, which may happen outside of regular JS execution, we
don't need control over the specific realm that is being used there.
This is a continuation of the previous commit.
Calling initialize() is the first thing that's done after allocating a
cell on the JS heap - and in the common case of allocating an object,
that's where properties are assigned and intrinsics occasionally
accessed.
Since those are supposed to live on the realm eventually, this is
another step into that direction.
No functional changes - we can still very easily get to the global
object via `Realm::global_object()`. This is in preparation of moving
the intrinsics to the realm and no longer having to pass a global
object when allocating any object.
In a few (now, and many more in subsequent commits) places we get a
realm using `GlobalObject::associated_realm()`, this is intended to be
temporary. For example, create() functions will later receive the same
treatment and are passed a realm instead of a global object.
Instead of having "Flip Horizontally" in both the Image and Layer menus,
we now have "Flip Image Horizontally" and "Flip Layer Horizontally".
This same concept applied to other, similar actions.
This currently has exactly one setting: The background colour for card
games. My thinking is, it's better to not have a Settings application
for each individual game we include in the system, since most will only
have a small number of settings, all Settings windows have tabs anyway,
and I don't want to flood the Settings app list unnecessarily.
As for having a single setting for all the card games: it's nice when
things match. :^)
Use Breadcrumbbars on_segment_change instead of on_segment_click.
This allows us to remove the manual handler invokation in the
open_child_directory_action
The Undo/Redo actions now tell you what kind of action will be
undone/redone. This is achieved by adding an "action text" field to the
ImageUndoCommand and having everyone who calls did_complete_action()
provide this text.
The non-AA outline ellipse was drawn outside the bounding rectangle
unlike all other ellipses. This commit now scales it to match the
size of the other ellipse drawing modes (AA, filled, etc).
This mirrors the "open parent directory" action, but traverses the
breadcrumbbar segments from left-to-right instead. The name is a little
bit strange, and maybe we can come up with something better.
It does feel pretty nice to use though. :^)
Commit 75d1840cf detects if the initial path provided to the FileManager
contains a dotfile, and if so, forces the FileManager to show dotfiles.
However, it does this by activating the "Show Dotfiles" action. This has
the side effect of always setting and persisting the configuration,
overriding whatever the user's preference was.
Instead, only transiently update the view to show dotfiles if the path
contains a dotfile.
Removes some verbiage and arranges things consistent with other
settings dialogs.
Ideally we shouldn't litter UIs with shortcuts, tips, tricks,
self-evident or redundant descriptions, etc, so this can be
refined again in the future once there's an official way to expose/
customize keyboard shortcuts.
This was disabled originally because of performance paranoia, but it
resulted in flickering sometimes, so let's err on the side of nicer
looking terminals. :^)
Using the fact that there are 2^52-2 NaN representations we can
"NaN-box" all the Values possible. This means that Value no longer has
an explicit "Type" but that information is now stored in the bits of a
double. This is done by "tagging" the top two bytes of the double.
For a full explanation see the large comment with asserts at the top of
Value.
We can also use the exact representation of the tags to make checking
properties like nullish, or is_cell quicker. But the largest gains are
in the fact that the size of a Value is now halved.
The SunSpider and other benchmarks have been ran to confirm that there
are no regressions in performance compared to the previous
implementation. The tests never performed worse and in some cases
performed better. But the biggest differences can be seen in memory
usage when large arrays are allocated. A simple test which allocates a
1000 arrays of size 100000 has roughly half the memory usage.
There is also space in the representations for future expansions such as
tuples and records.
To ensure that Values on the stack and registers are not lost during
garbage collection we also have to add a check to the Heap to check for
any of the cell tags and extracting the canonical form of the pointer
if it matches.
When the given needle is not found, replace displays a widget that says
the needle is not found, but replace all does not.
This change adds that widget to replace all.
This fixes an issue where the window resize overlay would display
inaccurate "columns x rows" after a font change. This happened because
we kept using size increments derived from the original font.