Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(vm): Reimplement FunctionDeclarationInstantiation as part of function compilation #402

Conversation

andreubotella
Copy link
Collaborator

FunctionDeclarationInstantiation is an abstract operation in the spec which runs at the start of a function call and sets up the parameters, lexical environments and variables for the function. Until now, we implemented it as a Rust function called before the function body was executed.

Since this operation is not implemented using bytecode, and it binds the function arguments, it couldn't support complex bindings (such as default values or object/array bindings) without reimplementing them.

This patch therefore instead implements this operation as bytecode instructions emitted before the function body. That way the binding of arguments can be compiled into a regular array binding pattern.

Doing this requires some way to pass the arguments into the VM, and have them stored in its state until they are evaluated. We do this by having Vm::execute take an optional arguments slice, which it stores on the iterator stack.

For generators, currently FunctionDeclarationInstantiation happens when the generator function is called, and this patch moves it to when the generator object is first resumed, which is correct. However, this means that the arguments must be stored until that first time the generator is resumed. To do this, the Option<Vm> field in GeneratorState::Suspended is made into an enum which can store either a Vm or a boxed slice of arguments.


This PR builds on top of #398, #399, #400 and #401, do not merge before those.

aapoalas
aapoalas previously approved these changes Aug 25, 2024
Copy link
Collaborator

@aapoalas aapoalas left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One word: Awesome!

nova_vm/src/engine/bytecode/executable.rs Show resolved Hide resolved
nova_vm/src/engine/bytecode/executable.rs Show resolved Hide resolved
nova_vm/src/engine/bytecode/vm.rs Show resolved Hide resolved
tests/expectations.json Outdated Show resolved Hide resolved
nova_vm/src/engine/bytecode/executable.rs Outdated Show resolved Hide resolved
nova_vm/src/engine/bytecode/vm.rs Outdated Show resolved Hide resolved
…ction compilation

FunctionDeclarationInstantiation is an abstract operation in the spec
which runs at the start of a function call and sets up the parameters,
lexical environments and variables for the function. Until now, we
implemented it as a Rust function called before the function body was
executed.

Since this operation is not implemented using bytecode, and it binds
the function arguments, it couldn't support complex bindings (such as
default values or object/array bindings) without reimplementing them.

This patch therefore instead implements this operation as bytecode
instructions emitted before the function body. That way the binding of
arguments can be compiled into a regular array binding pattern.

Doing this requires some way to pass the arguments into the VM, and
have them stored in its state until they are evaluated. We do this by
having `Vm::execute` take an optional arguments slice, which it stores
on the iterator stack.

For generators, currently FunctionDeclarationInstantiation happens
when the generator function is called, and this patch moves it to when
the generator object is first resumed, which is correct. However, this
means that the arguments must be stored until that first time the
generator is resumed. To do this, the `Option<Vm>` field in
`GeneratorState::Suspended` is made into an enum which can store
either a `Vm` or a boxed slice of arguments.
@andreubotella andreubotella force-pushed the bytecode-function-declaration-instantiation branch from b94dc2e to 83e89ac Compare August 25, 2024 18:44
aapoalas
aapoalas previously approved these changes Aug 25, 2024
@andreubotella andreubotella merged commit 257030c into trynova:main Aug 25, 2024
1 check passed
@andreubotella andreubotella deleted the bytecode-function-declaration-instantiation branch August 25, 2024 19:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants