diff --git a/boa/src/builtins/regexp/mod.rs b/boa/src/builtins/regexp/mod.rs index 5c1d6f82b97..2d209f3c1fd 100644 --- a/boa/src/builtins/regexp/mod.rs +++ b/boa/src/builtins/regexp/mod.rs @@ -1171,7 +1171,10 @@ impl RegExp { let flags = this.get_field("flags", context)?.to_string(context)?; // 6. Let matcher be ? Construct(C, « R, flags »). - let matcher = RegExp::constructor(&c, &[this.clone(), flags.clone().into()], context)?; + let matcher = c + .as_object() + .expect("SpeciesConstructor returned non Object") + .construct(&[this.clone(), flags.clone().into()], &c, context)?; // 7. Let lastIndex be ? ToLength(? Get(R, "lastIndex")). let last_index = this.get_field("lastIndex", context)?.to_length(context)?; @@ -1539,8 +1542,10 @@ impl RegExp { }; // 10. Let splitter be ? Construct(C, « rx, newFlags »). - let splitter = - RegExp::constructor(&constructor, &[this.clone(), new_flags.into()], context)?; + let splitter = constructor + .as_object() + .expect("SpeciesConstructor returned non Object") + .construct(&[Value::from(rx), new_flags.into()], &constructor, context)?; // 11. Let A be ! ArrayCreate(0). let a = Array::array_create(0, None, context).unwrap(); diff --git a/boa/src/object/gcobject.rs b/boa/src/object/gcobject.rs index 2841399d06e..0e71943cc14 100644 --- a/boa/src/object/gcobject.rs +++ b/boa/src/object/gcobject.rs @@ -12,6 +12,7 @@ use crate::{ function_environment_record::{BindingStatus, FunctionEnvironmentRecord}, lexical_environment::Environment, }, + exec::InterpreterState, property::{PropertyDescriptor, PropertyKey}, symbol::WellKnownSymbols, syntax::ast::node::RcStatementList, @@ -312,6 +313,21 @@ impl GcObject { context.pop_environment(); if construct { + // https://tc39.es/ecma262/#sec-ecmascript-function-objects-construct-argumentslist-newtarget + // 12. If result.[[Type]] is return, then + if context.executor().get_current_state() == &InterpreterState::Return { + // a. If Type(result.[[Value]]) is Object, return NormalCompletion(result.[[Value]]). + if let Ok(v) = &result { + if v.is_object() { + return result; + } + } + } + + // 13. Else, ReturnIfAbrupt(result). + result?; + + // 14. Return ? constructorEnv.GetThisBinding(). this } else { result @@ -785,12 +801,14 @@ impl GcObject { } // 4. If Type(C) is not Object, throw a TypeError exception. - if !c.is_object() { + let c = if let Some(c) = c.as_object() { + c + } else { return context.throw_type_error("property 'constructor' is not an object"); - } + }; // 5. Let S be ? Get(C, @@species). - let s = c.get_field(WellKnownSymbols::species(), context)?; + let s = c.get(WellKnownSymbols::species(), context)?; // 6. If S is either undefined or null, return defaultConstructor. if s.is_null_or_undefined() {