diff --git a/nova_vm/src/engine/bytecode/bytecode_compiler/compile_context.rs b/nova_vm/src/engine/bytecode/bytecode_compiler/compile_context.rs index 5044e9ef0..8a72128bf 100644 --- a/nova_vm/src/engine/bytecode/bytecode_compiler/compile_context.rs +++ b/nova_vm/src/engine/bytecode/bytecode_compiler/compile_context.rs @@ -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. @@ -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(); } @@ -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() { @@ -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(); @@ -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. @@ -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. @@ -1288,6 +1277,7 @@ impl<'agent, 'script, 'gc, 'scope> CompileContext<'agent, 'script, 'gc, 'scope> } } +#[cfg(debug_assertions)] trait Undroppable { #[inline(always)] fn on_drop() { @@ -1307,6 +1297,7 @@ trait Undroppable { #[must_use] pub(crate) struct LexicalScope; +#[cfg(debug_assertions)] impl Undroppable for LexicalScope {} impl LexicalScope { @@ -1325,6 +1316,7 @@ impl Drop for LexicalScope { #[must_use] pub(crate) struct ClassStaticBlock; +#[cfg(debug_assertions)] impl Undroppable for ClassStaticBlock {} impl ClassStaticBlock { @@ -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 { @@ -1398,6 +1391,7 @@ impl Drop for StackValue { } pub(crate) struct StackVariable; +#[cfg(debug_assertions)] impl Undroppable for StackVariable {} impl StackVariable { @@ -1418,6 +1412,7 @@ impl Drop for StackVariable { pub(crate) struct StackResultValue { stack_slot: u32, } +#[cfg(debug_assertions)] impl Undroppable for StackResultValue {} impl StackResultValue { @@ -1482,6 +1477,7 @@ impl BlockEnvPrep { } pub(crate) struct PrivateScope; +#[cfg(debug_assertions)] impl Undroppable for PrivateScope {} impl PrivateScope { @@ -1498,6 +1494,7 @@ impl Drop for PrivateScope { } } pub(crate) struct TryCatchBlock(JumpIndex); +#[cfg(debug_assertions)] impl Undroppable for TryCatchBlock {} impl TryCatchBlock { @@ -1516,6 +1513,7 @@ impl Drop for TryCatchBlock { } } pub(crate) struct TryFinallyBlock; +#[cfg(debug_assertions)] impl Undroppable for TryFinallyBlock {} impl TryFinallyBlock { @@ -1537,6 +1535,7 @@ impl Drop for TryFinallyBlock { } } pub(crate) struct IfStatement; +#[cfg(debug_assertions)] impl Undroppable for IfStatement {} impl IfStatement { @@ -1553,6 +1552,7 @@ impl Drop for IfStatement { } } pub(crate) struct LabelledStatement; +#[cfg(debug_assertions)] impl Undroppable for LabelledStatement {} impl LabelledStatement { @@ -1569,6 +1569,7 @@ impl Drop for LabelledStatement { } } pub(crate) struct FinallyBlock; +#[cfg(debug_assertions)] impl Undroppable for FinallyBlock {} impl FinallyBlock { @@ -1590,6 +1591,7 @@ pub(crate) enum Loop { SyncIterator(JumpIndex), AsyncIterator(JumpIndex), } +#[cfg(debug_assertions)] impl Undroppable for Loop {} impl Loop { @@ -1626,6 +1628,7 @@ impl Drop for Loop { } } pub(crate) struct SwitchBlock; +#[cfg(debug_assertions)] impl Undroppable for SwitchBlock {} impl SwitchBlock { @@ -1642,6 +1645,7 @@ impl Drop for SwitchBlock { } } pub(crate) struct IteratorStackEntry(JumpIndex); +#[cfg(debug_assertions)] impl Undroppable for IteratorStackEntry {} impl IteratorStackEntry { @@ -1665,6 +1669,7 @@ impl Drop for IteratorStackEntry { } } pub(crate) struct ArrayDestructuring(JumpIndex); +#[cfg(debug_assertions)] impl Undroppable for ArrayDestructuring {} impl ArrayDestructuring { diff --git a/nova_vm/src/engine/bytecode/bytecode_compiler/exports.rs b/nova_vm/src/engine/bytecode/bytecode_compiler/exports.rs index a4ebd9921..8d8743cbc 100644 --- a/nova_vm/src/engine/bytecode/bytecode_compiler/exports.rs +++ b/nova_vm/src/engine/bytecode/bytecode_compiler/exports.rs @@ -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!(), _ => { @@ -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(()) } } diff --git a/tests/expectations.json b/tests/expectations.json index 1d0aa5926..ccc750044 100644 --- a/tests/expectations.json +++ b/tests/expectations.json @@ -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", diff --git a/tests/metrics.json b/tests/metrics.json index dd0589ba2..536f16939 100644 --- a/tests/metrics.json +++ b/tests/metrics.json @@ -1,8 +1,8 @@ { "results": { "crash": 40, - "fail": 7421, - "pass": 39891, + "fail": 7420, + "pass": 39892, "skip": 3326, "timeout": 18, "unresolved": 37