Skip to content

Commit

Permalink
Implement abstract operation GetPrototypeFromConstructor (#1561)
Browse files Browse the repository at this point in the history
  • Loading branch information
jedel1043 authored Sep 8, 2021
1 parent 9f5ee5f commit c91af15
Show file tree
Hide file tree
Showing 18 changed files with 126 additions and 175 deletions.
17 changes: 7 additions & 10 deletions boa/src/builtins/array/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,11 @@ use crate::{
builtins::array::array_iterator::ArrayIterator,
builtins::BuiltIn,
builtins::Number,
object::{ConstructorBuilder, FunctionBuilder, JsObject, ObjectData, PROTOTYPE},
context::StandardObjects,
object::{
internal_methods::get_prototype_from_constructor, ConstructorBuilder, FunctionBuilder,
JsObject, ObjectData,
},
property::{Attribute, PropertyDescriptor, PropertyNameKind},
symbol::WellKnownSymbols,
value::{IntegerOrInfinity, JsValue},
Expand Down Expand Up @@ -130,15 +134,8 @@ impl Array {
) -> JsResult<JsValue> {
// If NewTarget is undefined, let newTarget be the active function object; else let newTarget be NewTarget.
// 2. Let proto be ? GetPrototypeFromConstructor(newTarget, "%Array.prototype%").
let prototype = new_target
.as_object()
.and_then(|obj| {
obj.__get__(&PROTOTYPE.into(), obj.clone().into(), context)
.map(|o| o.as_object())
.transpose()
})
.transpose()?
.unwrap_or_else(|| context.standard_objects().array_object().prototype());
let prototype =
get_prototype_from_constructor(new_target, StandardObjects::array_object, context)?;

// 3. Let numberOfArgs be the number of elements in values.
let number_of_args = args.len();
Expand Down
14 changes: 4 additions & 10 deletions boa/src/builtins/boolean/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ mod tests;

use crate::{
builtins::BuiltIn,
object::{ConstructorBuilder, ObjectData, PROTOTYPE},
context::StandardObjects,
object::{internal_methods::get_prototype_from_constructor, ConstructorBuilder, ObjectData},
property::Attribute,
BoaProfiler, Context, JsResult, JsValue,
};
Expand Down Expand Up @@ -66,15 +67,8 @@ impl Boolean {
if new_target.is_undefined() {
return Ok(JsValue::new(data));
}
let prototype = new_target
.as_object()
.and_then(|obj| {
obj.__get__(&PROTOTYPE.into(), obj.clone().into(), context)
.map(|o| o.as_object())
.transpose()
})
.transpose()?
.unwrap_or_else(|| context.standard_objects().object_object().prototype());
let prototype =
get_prototype_from_constructor(new_target, StandardObjects::boolean_object, context)?;
let boolean = JsValue::new_object(context);

boolean
Expand Down
17 changes: 7 additions & 10 deletions boa/src/builtins/date/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@ mod tests;

use crate::{
builtins::BuiltIn,
context::StandardObjects,
gc::{empty_trace, Finalize, Trace},
object::{ConstructorBuilder, ObjectData, PROTOTYPE},
object::{internal_methods::get_prototype_from_constructor, ConstructorBuilder, ObjectData},
property::Attribute,
symbol::WellKnownSymbols,
value::{JsValue, PreferredType},
Expand Down Expand Up @@ -340,15 +341,11 @@ impl Date {
if new_target.is_undefined() {
Ok(Self::make_date_string())
} else {
let prototype = new_target
.as_object()
.and_then(|obj| {
obj.__get__(&PROTOTYPE.into(), obj.clone().into(), context)
.map(|o| o.as_object())
.transpose()
})
.transpose()?
.unwrap_or_else(|| context.standard_objects().object_object().prototype());
let prototype = get_prototype_from_constructor(
new_target,
StandardObjects::object_object,
context,
)?;
let obj = context.construct_object();
obj.set_prototype_instance(prototype.into());
let this = obj.into();
Expand Down
15 changes: 5 additions & 10 deletions boa/src/builtins/error/eval.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@
//! [spec]: https://tc39.es/ecma262/#sec-native-error-types-used-in-this-standard-evalerror
//! [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/EvalError

use crate::object::PROTOTYPE;
use crate::context::StandardObjects;
use crate::object::internal_methods::get_prototype_from_constructor;

use crate::{
builtins::BuiltIn,
object::{ConstructorBuilder, ObjectData},
Expand Down Expand Up @@ -62,15 +64,8 @@ impl EvalError {
args: &[JsValue],
context: &mut Context,
) -> JsResult<JsValue> {
let prototype = new_target
.as_object()
.and_then(|obj| {
obj.__get__(&PROTOTYPE.into(), obj.clone().into(), context)
.map(|o| o.as_object())
.transpose()
})
.transpose()?
.unwrap_or_else(|| context.standard_objects().error_object().prototype());
let prototype =
get_prototype_from_constructor(new_target, StandardObjects::error_object, context)?;
let obj = context.construct_object();
obj.set_prototype_instance(prototype.into());
let this = JsValue::new(obj);
Expand Down
14 changes: 4 additions & 10 deletions boa/src/builtins/error/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@

use crate::{
builtins::BuiltIn,
object::{ConstructorBuilder, ObjectData, PROTOTYPE},
context::StandardObjects,
object::{internal_methods::get_prototype_from_constructor, ConstructorBuilder, ObjectData},
profiler::BoaProfiler,
property::Attribute,
Context, JsResult, JsValue,
Expand Down Expand Up @@ -78,15 +79,8 @@ impl Error {
args: &[JsValue],
context: &mut Context,
) -> JsResult<JsValue> {
let prototype = new_target
.as_object()
.and_then(|obj| {
obj.__get__(&PROTOTYPE.into(), obj.clone().into(), context)
.map(|o| o.as_object())
.transpose()
})
.transpose()?
.unwrap_or_else(|| context.standard_objects().error_object().prototype());
let prototype =
get_prototype_from_constructor(new_target, StandardObjects::error_object, context)?;
let obj = context.construct_object();
obj.set_prototype_instance(prototype.into());
let this = JsValue::new(obj);
Expand Down
14 changes: 4 additions & 10 deletions boa/src/builtins/error/range.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@

use crate::{
builtins::BuiltIn,
object::{ConstructorBuilder, ObjectData, PROTOTYPE},
context::StandardObjects,
object::{internal_methods::get_prototype_from_constructor, ConstructorBuilder, ObjectData},
profiler::BoaProfiler,
property::Attribute,
Context, JsResult, JsValue,
Expand Down Expand Up @@ -59,15 +60,8 @@ impl RangeError {
args: &[JsValue],
context: &mut Context,
) -> JsResult<JsValue> {
let prototype = new_target
.as_object()
.and_then(|obj| {
obj.__get__(&PROTOTYPE.into(), obj.clone().into(), context)
.map(|o| o.as_object())
.transpose()
})
.transpose()?
.unwrap_or_else(|| context.standard_objects().error_object().prototype());
let prototype =
get_prototype_from_constructor(new_target, StandardObjects::error_object, context)?;
let obj = context.construct_object();
obj.set_prototype_instance(prototype.into());
let this = JsValue::new(obj);
Expand Down
14 changes: 4 additions & 10 deletions boa/src/builtins/error/reference.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@

use crate::{
builtins::BuiltIn,
object::{ConstructorBuilder, ObjectData, PROTOTYPE},
context::StandardObjects,
object::{internal_methods::get_prototype_from_constructor, ConstructorBuilder, ObjectData},
profiler::BoaProfiler,
property::Attribute,
Context, JsResult, JsValue,
Expand Down Expand Up @@ -58,15 +59,8 @@ impl ReferenceError {
args: &[JsValue],
context: &mut Context,
) -> JsResult<JsValue> {
let prototype = new_target
.as_object()
.and_then(|obj| {
obj.__get__(&PROTOTYPE.into(), obj.clone().into(), context)
.map(|o| o.as_object())
.transpose()
})
.transpose()?
.unwrap_or_else(|| context.standard_objects().error_object().prototype());
let prototype =
get_prototype_from_constructor(new_target, StandardObjects::error_object, context)?;
let obj = context.construct_object();
obj.set_prototype_instance(prototype.into());
let this = JsValue::new(obj);
Expand Down
14 changes: 4 additions & 10 deletions boa/src/builtins/error/syntax.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@

use crate::{
builtins::BuiltIn,
object::{ConstructorBuilder, ObjectData, PROTOTYPE},
context::StandardObjects,
object::{internal_methods::get_prototype_from_constructor, ConstructorBuilder, ObjectData},
profiler::BoaProfiler,
property::Attribute,
Context, JsResult, JsValue,
Expand Down Expand Up @@ -61,15 +62,8 @@ impl SyntaxError {
args: &[JsValue],
context: &mut Context,
) -> JsResult<JsValue> {
let prototype = new_target
.as_object()
.and_then(|obj| {
obj.__get__(&PROTOTYPE.into(), obj.clone().into(), context)
.map(|o| o.as_object())
.transpose()
})
.transpose()?
.unwrap_or_else(|| context.standard_objects().error_object().prototype());
let prototype =
get_prototype_from_constructor(new_target, StandardObjects::error_object, context)?;
let obj = context.construct_object();
obj.set_prototype_instance(prototype.into());
let this = JsValue::new(obj);
Expand Down
14 changes: 4 additions & 10 deletions boa/src/builtins/error/type.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@

use crate::{
builtins::BuiltIn,
object::{ConstructorBuilder, ObjectData, PROTOTYPE},
context::StandardObjects,
object::{internal_methods::get_prototype_from_constructor, ConstructorBuilder, ObjectData},
property::Attribute,
BoaProfiler, Context, JsResult, JsValue,
};
Expand Down Expand Up @@ -64,15 +65,8 @@ impl TypeError {
args: &[JsValue],
context: &mut Context,
) -> JsResult<JsValue> {
let prototype = new_target
.as_object()
.and_then(|obj| {
obj.__get__(&PROTOTYPE.into(), obj.clone().into(), context)
.map(|o| o.as_object())
.transpose()
})
.transpose()?
.unwrap_or_else(|| context.standard_objects().error_object().prototype());
let prototype =
get_prototype_from_constructor(new_target, StandardObjects::error_object, context)?;
let obj = context.construct_object();
obj.set_prototype_instance(prototype.into());
let this = JsValue::new(obj);
Expand Down
14 changes: 4 additions & 10 deletions boa/src/builtins/error/uri.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@

use crate::{
builtins::BuiltIn,
object::{ConstructorBuilder, ObjectData, PROTOTYPE},
context::StandardObjects,
object::{internal_methods::get_prototype_from_constructor, ConstructorBuilder, ObjectData},
profiler::BoaProfiler,
property::Attribute,
Context, JsResult, JsValue,
Expand Down Expand Up @@ -60,15 +61,8 @@ impl UriError {
args: &[JsValue],
context: &mut Context,
) -> JsResult<JsValue> {
let prototype = new_target
.as_object()
.and_then(|obj| {
obj.__get__(&PROTOTYPE.into(), obj.clone().into(), context)
.map(|o| o.as_object())
.transpose()
})
.transpose()?
.unwrap_or_else(|| context.standard_objects().error_object().prototype());
let prototype =
get_prototype_from_constructor(new_target, StandardObjects::error_object, context)?;
let obj = context.construct_object();
obj.set_prototype_instance(prototype.into());
let this = JsValue::new(obj);
Expand Down
15 changes: 5 additions & 10 deletions boa/src/builtins/function/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@
//! [spec]: https://tc39.es/ecma262/#sec-function-objects
//! [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function

use crate::object::PROTOTYPE;
use crate::context::StandardObjects;
use crate::object::internal_methods::get_prototype_from_constructor;

use crate::{
builtins::{Array, BuiltIn},
environment::lexical_environment::Environment,
Expand Down Expand Up @@ -302,15 +304,8 @@ impl BuiltInFunctionObject {
_: &[JsValue],
context: &mut Context,
) -> JsResult<JsValue> {
let prototype = new_target
.as_object()
.and_then(|obj| {
obj.__get__(&PROTOTYPE.into(), obj.clone().into(), context)
.map(|o| o.as_object())
.transpose()
})
.transpose()?
.unwrap_or_else(|| context.standard_objects().object_object().prototype());
let prototype =
get_prototype_from_constructor(new_target, StandardObjects::function_object, context)?;
let this = JsValue::new_object(context);

this.as_object()
Expand Down
18 changes: 7 additions & 11 deletions boa/src/builtins/map/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,11 @@

use crate::{
builtins::BuiltIn,
object::{ConstructorBuilder, FunctionBuilder, ObjectData, PROTOTYPE},
context::StandardObjects,
object::{
internal_methods::get_prototype_from_constructor, ConstructorBuilder, FunctionBuilder,
ObjectData,
},
property::{Attribute, PropertyDescriptor, PropertyNameKind},
symbol::WellKnownSymbols,
BoaProfiler, Context, JsResult, JsValue,
Expand Down Expand Up @@ -114,16 +118,8 @@ impl Map {
return context
.throw_type_error("calling a builtin Map constructor without new is forbidden");
}
let map_prototype = context.standard_objects().map_object().prototype();
let prototype = new_target
.as_object()
.and_then(|obj| {
obj.__get__(&PROTOTYPE.into(), obj.clone().into(), context)
.map(|o| o.as_object())
.transpose()
})
.transpose()?
.unwrap_or(map_prototype);
let prototype =
get_prototype_from_constructor(new_target, StandardObjects::map_object, context)?;

let obj = context.construct_object();
obj.set_prototype_instance(prototype.into());
Expand Down
14 changes: 4 additions & 10 deletions boa/src/builtins/number/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,10 @@

use super::string::is_trimmable_whitespace;
use super::{function::make_builtin_fn, JsArgs};
use crate::context::StandardObjects;
use crate::{
builtins::BuiltIn,
object::{ConstructorBuilder, ObjectData, PROTOTYPE},
object::{internal_methods::get_prototype_from_constructor, ConstructorBuilder, ObjectData},
property::Attribute,
value::{AbstractRelation, IntegerOrInfinity, JsValue},
BoaProfiler, Context, JsResult,
Expand Down Expand Up @@ -166,15 +167,8 @@ impl Number {
if new_target.is_undefined() {
return Ok(JsValue::new(data));
}
let prototype = new_target
.as_object()
.and_then(|obj| {
obj.__get__(&PROTOTYPE.into(), obj.clone().into(), context)
.map(|o| o.as_object())
.transpose()
})
.transpose()?
.unwrap_or_else(|| context.standard_objects().object_object().prototype());
let prototype =
get_prototype_from_constructor(new_target, StandardObjects::number_object, context)?;
let this = JsValue::new_object(context);
this.as_object()
.expect("this should be an object")
Expand Down
Loading

0 comments on commit c91af15

Please sign in to comment.