Skip to content

Commit

Permalink
Implement abstract operation GetPrototypeFromConstructor
Browse files Browse the repository at this point in the history
  • Loading branch information
jedel1043 committed Sep 7, 2021
1 parent 87e7ca3 commit 4248dc4
Show file tree
Hide file tree
Showing 19 changed files with 160 additions and 191 deletions.
19 changes: 9 additions & 10 deletions boa/src/builtins/array/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,10 @@ use crate::{
builtins::array::array_iterator::ArrayIterator,
builtins::BuiltIn,
builtins::Number,
object::{ConstructorBuilder, FunctionBuilder, JsObject, ObjectData, PROTOTYPE},
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 +133,11 @@ 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,
|intrinsics| intrinsics.array_object().prototype(),
context,
)?;

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

use crate::{
builtins::BuiltIn,
object::{ConstructorBuilder, ObjectData, PROTOTYPE},
object::{internal_methods::get_prototype_from_constructor, ConstructorBuilder, ObjectData},
property::Attribute,
BoaProfiler, Context, JsResult, JsValue,
};
Expand Down Expand Up @@ -66,15 +66,11 @@ 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,
|intrinsics| intrinsics.object_object().prototype(),
context,
)?;
let boolean = JsValue::new_object(context);

boolean
Expand Down
16 changes: 6 additions & 10 deletions boa/src/builtins/date/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ mod tests;
use crate::{
builtins::BuiltIn,
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 +340,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,
|intrinsics| intrinsics.object_object().prototype(),
context,
)?;
let obj = context.construct_object();
obj.set_prototype_instance(prototype.into());
let this = obj.into();
Expand Down
17 changes: 7 additions & 10 deletions boa/src/builtins/error/eval.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@
//! [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::object::internal_methods::get_prototype_from_constructor;

use crate::{
builtins::BuiltIn,
object::{ConstructorBuilder, ObjectData},
Expand Down Expand Up @@ -62,15 +63,11 @@ 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,
|intrinsics| intrinsics.error_object().prototype(),
context,
)?;
let obj = context.construct_object();
obj.set_prototype_instance(prototype.into());
let this = JsValue::new(obj);
Expand Down
16 changes: 6 additions & 10 deletions boa/src/builtins/error/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
use crate::{
builtins::BuiltIn,
object::{ConstructorBuilder, ObjectData, PROTOTYPE},
object::{internal_methods::get_prototype_from_constructor, ConstructorBuilder, ObjectData},
profiler::BoaProfiler,
property::Attribute,
Context, JsResult, JsValue,
Expand Down Expand Up @@ -78,15 +78,11 @@ 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,
|intrinsics| intrinsics.error_object().prototype(),
context,
)?;
let obj = context.construct_object();
obj.set_prototype_instance(prototype.into());
let this = JsValue::new(obj);
Expand Down
16 changes: 6 additions & 10 deletions boa/src/builtins/error/range.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
use crate::{
builtins::BuiltIn,
object::{ConstructorBuilder, ObjectData, PROTOTYPE},
object::{internal_methods::get_prototype_from_constructor, ConstructorBuilder, ObjectData},
profiler::BoaProfiler,
property::Attribute,
Context, JsResult, JsValue,
Expand Down Expand Up @@ -59,15 +59,11 @@ 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,
|intrinsics| intrinsics.error_object().prototype(),
context,
)?;
let obj = context.construct_object();
obj.set_prototype_instance(prototype.into());
let this = JsValue::new(obj);
Expand Down
16 changes: 6 additions & 10 deletions boa/src/builtins/error/reference.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
use crate::{
builtins::BuiltIn,
object::{ConstructorBuilder, ObjectData, PROTOTYPE},
object::{internal_methods::get_prototype_from_constructor, ConstructorBuilder, ObjectData},
profiler::BoaProfiler,
property::Attribute,
Context, JsResult, JsValue,
Expand Down Expand Up @@ -58,15 +58,11 @@ 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,
|intrinsics| intrinsics.error_object().prototype(),
context,
)?;
let obj = context.construct_object();
obj.set_prototype_instance(prototype.into());
let this = JsValue::new(obj);
Expand Down
16 changes: 6 additions & 10 deletions boa/src/builtins/error/syntax.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
use crate::{
builtins::BuiltIn,
object::{ConstructorBuilder, ObjectData, PROTOTYPE},
object::{internal_methods::get_prototype_from_constructor, ConstructorBuilder, ObjectData},
profiler::BoaProfiler,
property::Attribute,
Context, JsResult, JsValue,
Expand Down Expand Up @@ -61,15 +61,11 @@ 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,
|intrinsics| intrinsics.error_object().prototype(),
context,
)?;
let obj = context.construct_object();
obj.set_prototype_instance(prototype.into());
let this = JsValue::new(obj);
Expand Down
16 changes: 6 additions & 10 deletions boa/src/builtins/error/type.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
use crate::{
builtins::BuiltIn,
object::{ConstructorBuilder, ObjectData, PROTOTYPE},
object::{internal_methods::get_prototype_from_constructor, ConstructorBuilder, ObjectData},
property::Attribute,
BoaProfiler, Context, JsResult, JsValue,
};
Expand Down Expand Up @@ -64,15 +64,11 @@ 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,
|intrinsics| intrinsics.error_object().prototype(),
context,
)?;
let obj = context.construct_object();
obj.set_prototype_instance(prototype.into());
let this = JsValue::new(obj);
Expand Down
16 changes: 6 additions & 10 deletions boa/src/builtins/error/uri.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
use crate::{
builtins::BuiltIn,
object::{ConstructorBuilder, ObjectData, PROTOTYPE},
object::{internal_methods::get_prototype_from_constructor, ConstructorBuilder, ObjectData},
profiler::BoaProfiler,
property::Attribute,
Context, JsResult, JsValue,
Expand Down Expand Up @@ -60,15 +60,11 @@ 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,
|intrinsics| intrinsics.error_object().prototype(),
context,
)?;
let obj = context.construct_object();
obj.set_prototype_instance(prototype.into());
let this = JsValue::new(obj);
Expand Down
17 changes: 7 additions & 10 deletions boa/src/builtins/function/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@
//! [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::object::internal_methods::get_prototype_from_constructor;

use crate::{
builtins::{Array, BuiltIn},
environment::lexical_environment::Environment,
Expand Down Expand Up @@ -302,15 +303,11 @@ 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,
|intrinsics| intrinsics.object_object().prototype(),
context,
)?;
let this = JsValue::new_object(context);

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

use crate::{
builtins::BuiltIn,
object::{ConstructorBuilder, FunctionBuilder, ObjectData, PROTOTYPE},
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 +117,11 @@ 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,
|intrinsics| intrinsics.map_object().prototype(),
context,
)?;

let obj = context.construct_object();
obj.set_prototype_instance(prototype.into());
Expand Down
16 changes: 6 additions & 10 deletions boa/src/builtins/number/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ use super::string::is_trimmable_whitespace;
use super::{function::make_builtin_fn, JsArgs};
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 +166,11 @@ 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,
|intrinsics| intrinsics.object_object().prototype(),
context,
)?;
let this = JsValue::new_object(context);
this.as_object()
.expect("this should be an object")
Expand Down
Loading

0 comments on commit 4248dc4

Please sign in to comment.