diff --git a/boa/src/exec/block/mod.rs b/boa/src/exec/block/mod.rs index 5771bbffd7e..ddf4bd3f17d 100644 --- a/boa/src/exec/block/mod.rs +++ b/boa/src/exec/block/mod.rs @@ -16,7 +16,9 @@ impl Executable for Block { ))); } - let mut obj = Value::null(); + // https://tc39.es/ecma262/#sec-block-runtime-semantics-evaluation + // The return value is uninitialized, which means it defaults to Value::Undefined + let mut obj = Value::default(); for statement in self.statements() { obj = statement.run(interpreter)?; diff --git a/boa/src/exec/statement_list.rs b/boa/src/exec/statement_list.rs index 530d9c76e09..bb358cb8869 100644 --- a/boa/src/exec/statement_list.rs +++ b/boa/src/exec/statement_list.rs @@ -6,7 +6,10 @@ use crate::{builtins::value::Value, syntax::ast::node::StatementList, BoaProfile impl Executable for StatementList { fn run(&self, interpreter: &mut Interpreter) -> Result { let _timer = BoaProfiler::global().start_event("StatementList", "exec"); - let mut obj = Value::null(); + + // https://tc39.es/ecma262/#sec-block-runtime-semantics-evaluation + // The return value is uninitialized, which means it defaults to Value::Undefined + let mut obj = Value::default(); interpreter.set_current_state(InterpreterState::Executing); for (i, item) in self.statements().iter().enumerate() { let val = item.run(interpreter)?; diff --git a/boa/src/exec/tests.rs b/boa/src/exec/tests.rs index d10afc5f511..c44289d5479 100644 --- a/boa/src/exec/tests.rs +++ b/boa/src/exec/tests.rs @@ -15,6 +15,12 @@ fn function_declaration_returns_undefined() { assert_eq!(&exec(scenario), "undefined"); } +#[test] +fn empty_function_returns_undefined() { + let scenario = "(function () {}) ()"; + assert_eq!(&exec(scenario), "undefined"); +} + #[test] fn property_accessor_member_expression_dot_notation_on_string_literal() { let scenario = r#" @@ -1205,3 +1211,9 @@ fn comma_operator() { "#; assert_eq!(&exec(scenario), "2"); } + +#[test] +fn test_result_of_empty_block() { + let scenario = "{}"; + assert_eq!(&exec(scenario), "undefined"); +}