Return function execution result from constructor if the function returned
if the function returned
@@ -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() {
