Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 30 additions & 25 deletions nova_vm/src/engine/bytecode/bytecode_compiler/compile_context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -250,10 +250,8 @@ impl<'agent, 'script, 'gc, 'scope> CompileContext<'agent, 'script, 'gc, 'scope>
/// Exit a lexical scope.
fn exit_lexical_scope(&mut self, scope: LexicalScope) {
core::mem::forget(scope);
debug_assert!(matches!(
self.control_flow_stack.pop(),
Some(ControlFlowStackEntry::LexicalScope)
));
let entry = self.control_flow_stack.pop();
debug_assert!(matches!(entry, Some(ControlFlowStackEntry::LexicalScope)));
if self.is_unreachable() {
// OPTIMISATION: We don't need to add exit handling if this line is
// unreachable.
Expand Down Expand Up @@ -281,10 +279,8 @@ impl<'agent, 'script, 'gc, 'scope> CompileContext<'agent, 'script, 'gc, 'scope>
/// Forget a StackValue.
fn pop_stack_value(&mut self, var: StackValue) {
core::mem::forget(var);
debug_assert!(matches!(
self.control_flow_stack.pop(),
Some(ControlFlowStackEntry::StackValue)
));
let entry = self.control_flow_stack.pop();
debug_assert!(matches!(entry, Some(ControlFlowStackEntry::StackValue)));
self.executable.pop_stack();
}

Expand Down Expand Up @@ -337,10 +333,8 @@ impl<'agent, 'script, 'gc, 'scope> CompileContext<'agent, 'script, 'gc, 'scope>
/// Pop a lexical variable.
fn pop_stack_variable(&mut self, var: StackVariable) {
core::mem::forget(var);
debug_assert!(matches!(
self.control_flow_stack.pop(),
Some(ControlFlowStackEntry::StackValue)
));
let entry = self.control_flow_stack.pop();
debug_assert!(matches!(entry, Some(ControlFlowStackEntry::StackValue)));
self.stack_variables.pop().unwrap();
self.executable.pop_stack();
if self.is_unreachable() {
Expand Down Expand Up @@ -370,8 +364,9 @@ impl<'agent, 'script, 'gc, 'scope> CompileContext<'agent, 'script, 'gc, 'scope>

fn pop_stack_result_value(&mut self, result: StackResultValue) {
core::mem::forget(result);
let entry = self.control_flow_stack.pop();
debug_assert!(matches!(
self.control_flow_stack.pop(),
entry,
Some(ControlFlowStackEntry::StackResultValue)
));
self.executable.pop_stack();
Expand Down Expand Up @@ -404,10 +399,8 @@ impl<'agent, 'script, 'gc, 'scope> CompileContext<'agent, 'script, 'gc, 'scope>
/// Enter a private environment scope.
fn exit_private_scope(&mut self, scope: PrivateScope) {
core::mem::forget(scope);
debug_assert!(matches!(
self.control_flow_stack.pop(),
Some(ControlFlowStackEntry::PrivateScope)
));
let entry = self.control_flow_stack.pop();
debug_assert!(matches!(entry, Some(ControlFlowStackEntry::PrivateScope)));
if self.is_unreachable() {
// OPTIMISATION: We don't need to add exit handling if this line is
// unreachable.
Expand All @@ -429,14 +422,10 @@ impl<'agent, 'script, 'gc, 'scope> CompileContext<'agent, 'script, 'gc, 'scope>
/// Exit a lexical scope.
fn exit_class_static_block(&mut self, scope: ClassStaticBlock) {
core::mem::forget(scope);
debug_assert!(matches!(
self.control_flow_stack.pop(),
Some(ControlFlowStackEntry::VariableScope)
));
debug_assert!(matches!(
self.control_flow_stack.pop(),
Some(ControlFlowStackEntry::LexicalScope)
));
let entry = self.control_flow_stack.pop();
debug_assert!(matches!(entry, Some(ControlFlowStackEntry::VariableScope)));
let entry = self.control_flow_stack.pop();
debug_assert!(matches!(entry, Some(ControlFlowStackEntry::LexicalScope)));
if self.is_unreachable() {
// OPTIMISATION: We don't need to add exit handling if this line is
// unreachable.
Expand Down Expand Up @@ -1288,6 +1277,7 @@ impl<'agent, 'script, 'gc, 'scope> CompileContext<'agent, 'script, 'gc, 'scope>
}
}

#[cfg(debug_assertions)]
trait Undroppable {
#[inline(always)]
fn on_drop() {
Expand All @@ -1307,6 +1297,7 @@ trait Undroppable {

#[must_use]
pub(crate) struct LexicalScope;
#[cfg(debug_assertions)]
impl Undroppable for LexicalScope {}

impl LexicalScope {
Expand All @@ -1325,6 +1316,7 @@ impl Drop for LexicalScope {

#[must_use]
pub(crate) struct ClassStaticBlock;
#[cfg(debug_assertions)]
impl Undroppable for ClassStaticBlock {}

impl ClassStaticBlock {
Expand All @@ -1344,6 +1336,7 @@ impl Drop for ClassStaticBlock {
/// A Value was pushed onto the VM stack. The Value must be popped from the
/// stack under all possible execution paths.
pub(crate) struct StackValue;
#[cfg(debug_assertions)]
impl Undroppable for StackValue {}

impl StackValue {
Expand Down Expand Up @@ -1398,6 +1391,7 @@ impl Drop for StackValue {
}

pub(crate) struct StackVariable;
#[cfg(debug_assertions)]
impl Undroppable for StackVariable {}

impl StackVariable {
Expand All @@ -1418,6 +1412,7 @@ impl Drop for StackVariable {
pub(crate) struct StackResultValue {
stack_slot: u32,
}
#[cfg(debug_assertions)]
impl Undroppable for StackResultValue {}

impl StackResultValue {
Expand Down Expand Up @@ -1482,6 +1477,7 @@ impl BlockEnvPrep {
}

pub(crate) struct PrivateScope;
#[cfg(debug_assertions)]
impl Undroppable for PrivateScope {}

impl PrivateScope {
Expand All @@ -1498,6 +1494,7 @@ impl Drop for PrivateScope {
}
}
pub(crate) struct TryCatchBlock(JumpIndex);
#[cfg(debug_assertions)]
impl Undroppable for TryCatchBlock {}

impl TryCatchBlock {
Expand All @@ -1516,6 +1513,7 @@ impl Drop for TryCatchBlock {
}
}
pub(crate) struct TryFinallyBlock;
#[cfg(debug_assertions)]
impl Undroppable for TryFinallyBlock {}

impl TryFinallyBlock {
Expand All @@ -1537,6 +1535,7 @@ impl Drop for TryFinallyBlock {
}
}
pub(crate) struct IfStatement;
#[cfg(debug_assertions)]
impl Undroppable for IfStatement {}

impl IfStatement {
Expand All @@ -1553,6 +1552,7 @@ impl Drop for IfStatement {
}
}
pub(crate) struct LabelledStatement;
#[cfg(debug_assertions)]
impl Undroppable for LabelledStatement {}

impl LabelledStatement {
Expand All @@ -1569,6 +1569,7 @@ impl Drop for LabelledStatement {
}
}
pub(crate) struct FinallyBlock;
#[cfg(debug_assertions)]
impl Undroppable for FinallyBlock {}

impl FinallyBlock {
Expand All @@ -1590,6 +1591,7 @@ pub(crate) enum Loop {
SyncIterator(JumpIndex),
AsyncIterator(JumpIndex),
}
#[cfg(debug_assertions)]
impl Undroppable for Loop {}

impl Loop {
Expand Down Expand Up @@ -1626,6 +1628,7 @@ impl Drop for Loop {
}
}
pub(crate) struct SwitchBlock;
#[cfg(debug_assertions)]
impl Undroppable for SwitchBlock {}

impl SwitchBlock {
Expand All @@ -1642,6 +1645,7 @@ impl Drop for SwitchBlock {
}
}
pub(crate) struct IteratorStackEntry(JumpIndex);
#[cfg(debug_assertions)]
impl Undroppable for IteratorStackEntry {}

impl IteratorStackEntry {
Expand All @@ -1665,6 +1669,7 @@ impl Drop for IteratorStackEntry {
}
}
pub(crate) struct ArrayDestructuring(JumpIndex);
#[cfg(debug_assertions)]
impl Undroppable for ArrayDestructuring {}

impl ArrayDestructuring {
Expand Down
47 changes: 20 additions & 27 deletions nova_vm/src/engine/bytecode/bytecode_compiler/exports.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,31 +46,28 @@ impl<'a, 's, 'gc, 'scope> CompileEvaluation<'a, 's, 'gc, 'scope>
// ExportDeclaration : export default HoistableDeclaration
// 1. Return ? Evaluation of HoistableDeclaration.
ast::ExportDefaultDeclarationKind::FunctionDeclaration(decl) => {
if decl.id.is_none() {
ctx.add_instruction_with_constant(
Instruction::StoreConstant,
BUILTIN_STRING_MEMORY.default,
);
ctx.name_identifier = Some(NamedEvaluationParameter::Result);
}
decl.compile(ctx);
ControlFlow::Continue(())
}
// ExportDeclaration : export default ClassDeclaration
ast::ExportDefaultDeclarationKind::ClassDeclaration(decl) => {
// 1. Let value be ? BindingClassDeclarationEvaluation of ClassDeclaration.
ctx.add_instruction_with_constant(
Instruction::StoreConstant,
BUILTIN_STRING_MEMORY.default,
);
ctx.name_identifier = Some(NamedEvaluationParameter::Result);
if decl.id.is_none() {
ctx.add_instruction_with_constant(
Instruction::StoreConstant,
BUILTIN_STRING_MEMORY.default,
);
ctx.name_identifier = Some(NamedEvaluationParameter::Result);
}
if let Err(err) = decl.compile(ctx) {
return ControlFlow::Break(err.into());
};
// 2. Let className be the sole element of the BoundNames of ClassDeclaration.
// 3. If className is "*default*", then
// a. Let env be the running execution context's LexicalEnvironment.
// b. Perform ? InitializeBoundName("*default*", value, env).
ctx.add_instruction_with_identifier(
Instruction::ResolveBinding,
BUILTIN_STRING_MEMORY._default_.to_property_key(),
);
ctx.add_instruction(Instruction::InitializeReferencedBinding);
// 4. Return empty.
ControlFlow::Continue(())
}
ast::ExportDefaultDeclarationKind::TSInterfaceDeclaration(_) => unreachable!(),
_ => {
Expand All @@ -91,18 +88,14 @@ impl<'a, 's, 'gc, 'scope> CompileEvaluation<'a, 's, 'gc, 'scope>
// a. Let rhs be ? Evaluation of AssignmentExpression.
// b. Let value be ? GetValue(rhs).
value_result_to_statement_result(expr.compile(ctx).and_then(|r| r.get_value(ctx)))?;

// 3. Let env be the running execution context's LexicalEnvironment.
// 4. Perform ? InitializeBoundName("*default*", value, env).
ctx.add_instruction_with_identifier(
Instruction::ResolveBinding,
BUILTIN_STRING_MEMORY._default_.to_property_key(),
);
ctx.add_instruction(Instruction::InitializeReferencedBinding);
// 5. Return empty.
ControlFlow::Continue(())
}
}
ctx.add_instruction_with_identifier(
Instruction::ResolveBinding,
BUILTIN_STRING_MEMORY._default_.to_property_key(),
);
ctx.add_instruction(Instruction::InitializeReferencedBinding);
ControlFlow::Continue(())
}
}

Expand Down
1 change: 0 additions & 1 deletion tests/expectations.json
Original file line number Diff line number Diff line change
Expand Up @@ -6340,7 +6340,6 @@
"language/expressions/dynamic-import/syntax/valid/nested-with-expression-script-code-valid.js": "FAIL",
"language/expressions/dynamic-import/syntax/valid/top-level-import-source-script-code-valid.js": "FAIL",
"language/expressions/dynamic-import/syntax/valid/top-level-script-code-valid.js": "FAIL",
"language/expressions/dynamic-import/update-to-dynamic-import.js": "FAIL",
"language/expressions/dynamic-import/usage/nested-arrow-assignment-expression-eval-script-code-host-resolves-module-code.js": "FAIL",
"language/expressions/dynamic-import/usage/nested-arrow-import-then-eval-script-code-host-resolves-module-code.js": "FAIL",
"language/expressions/dynamic-import/usage/nested-async-arrow-function-await-eval-script-code-host-resolves-module-code.js": "FAIL",
Expand Down
4 changes: 2 additions & 2 deletions tests/metrics.json
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
{
"results": {
"crash": 40,
"fail": 7421,
"pass": 39891,
"fail": 7420,
"pass": 39892,
"skip": 3326,
"timeout": 18,
"unresolved": 37
Expand Down