Browse Source

Return function execution result from constructor if the function returned (#1463)

if the function returned
pull/1470/head
raskad 3 years ago committed by GitHub
parent
commit
08eb76779a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 11
      boa/src/builtins/regexp/mod.rs
  2. 24
      boa/src/object/gcobject.rs

11
boa/src/builtins/regexp/mod.rs

@ -1211,7 +1211,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)?;
@ -1592,8 +1595,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();

24
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() {

Loading…
Cancel
Save