diff --git a/boa/src/syntax/ast/node/declaration/function_decl/mod.rs b/boa/src/syntax/ast/node/declaration/function_decl/mod.rs index 9309ce2e1e9..999faebdd42 100644 --- a/boa/src/syntax/ast/node/declaration/function_decl/mod.rs +++ b/boa/src/syntax/ast/node/declaration/function_decl/mod.rs @@ -94,18 +94,23 @@ impl Executable for FunctionDecl { // Set the name and assign it in the current environment val.set_field("name", self.name(), context)?; - context - .realm_mut() - .environment - .create_mutable_binding(self.name().to_owned(), false, VariableScope::Function) - .map_err(|e| e.to_error(context))?; - context - .realm_mut() - .environment - .initialize_binding(self.name(), val) - .map_err(|e| e.to_error(context))?; + let environment = &mut context.realm_mut().environment; + if environment.has_binding(self.name()) { + environment + .set_mutable_binding(self.name(), val, true) + .map_err(|e| e.to_error(context))?; + } else { + environment + .create_mutable_binding(self.name().to_owned(), false, VariableScope::Function) + .map_err(|e| e.to_error(context))?; + context + .realm_mut() + .environment + .initialize_binding(self.name(), val) + .map_err(|e| e.to_error(context))?; + } Ok(Value::undefined()) } } diff --git a/boa/src/syntax/ast/node/declaration/mod.rs b/boa/src/syntax/ast/node/declaration/mod.rs index a256a75e87f..ac5a0dbbb92 100644 --- a/boa/src/syntax/ast/node/declaration/mod.rs +++ b/boa/src/syntax/ast/node/declaration/mod.rs @@ -19,3 +19,6 @@ pub use self::{ let_decl_list::{LetDecl, LetDeclList}, var_decl_list::{VarDecl, VarDeclList}, }; + +#[cfg(test)] +mod tests; diff --git a/boa/src/syntax/ast/node/declaration/tests.rs b/boa/src/syntax/ast/node/declaration/tests.rs new file mode 100644 index 00000000000..a98ac86f523 --- /dev/null +++ b/boa/src/syntax/ast/node/declaration/tests.rs @@ -0,0 +1,12 @@ +use crate::exec; + +#[test] +fn duplicate_function_name() { + let scenario = r#" + function f () {} + function f () {return 12;} + f() + "#; + + assert_eq!(&exec(scenario), "12"); +}