Skip to content

Commit

Permalink
Make inline caching internal method aware
Browse files Browse the repository at this point in the history
  • Loading branch information
HalidOdat committed Apr 12, 2023
1 parent 42acaa5 commit 9ebac0a
Show file tree
Hide file tree
Showing 22 changed files with 341 additions and 300 deletions.
7 changes: 6 additions & 1 deletion boa_engine/src/builtins/array/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,10 @@ use crate::{
context::intrinsics::{Intrinsics, StandardConstructor, StandardConstructors},
error::JsNativeError,
js_string,
object::{internal_methods::get_prototype_from_constructor, JsObject, ObjectData, CONSTRUCTOR},
object::{
internal_methods::get_prototype_from_constructor, shape::slot::Slot, JsObject, ObjectData,
CONSTRUCTOR,
},
property::{Attribute, PropertyDescriptor, PropertyNameKind},
symbol::JsSymbol,
value::{IntegerOrInfinity, JsValue},
Expand Down Expand Up @@ -280,6 +283,7 @@ impl Array {
);

// 6. Perform ! OrdinaryDefineOwnProperty(A, "length", PropertyDescriptor { [[Value]]: 𝔽(length), [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: false }).
let mut slot = Slot::new();
crate::object::internal_methods::ordinary_define_own_property(
&array,
&utf16!("length").into(),
Expand All @@ -289,6 +293,7 @@ impl Array {
.enumerable(false)
.configurable(false)
.build(),
&mut slot,
context,
)?;

Expand Down
5 changes: 3 additions & 2 deletions boa_engine/src/builtins/function/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use crate::{
error::JsNativeError,
js_string,
native_function::NativeFunction,
object::{FunctionObjectBuilder, JsObject},
object::{shape::slot::Slot, FunctionObjectBuilder, JsObject},
property::{Attribute, PropertyDescriptor},
run_test_actions, JsValue, TestAction,
};
Expand Down Expand Up @@ -152,10 +152,11 @@ fn closure_capture_clone() {
|_, _, captures, context| {
let (string, object) = &captures;

let mut slot = Slot::new();
let hw = js_string!(
string,
&object
.__get_own_property__(&"key".into(), context)?
.__get_own_property__(&"key".into(), &mut slot, context)?
.and_then(|prop| prop.value().cloned())
.and_then(|val| val.as_string().cloned())
.ok_or_else(
Expand Down
11 changes: 7 additions & 4 deletions boa_engine/src/builtins/object/for_in_iterator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use crate::{
builtins::{iterable::create_iter_result_object, BuiltInBuilder, IntrinsicObject},
context::intrinsics::Intrinsics,
error::JsNativeError,
object::{JsObject, ObjectData},
object::{shape::slot::Slot, JsObject, ObjectData},
property::PropertyKey,
Context, JsResult, JsString, JsValue,
};
Expand Down Expand Up @@ -117,9 +117,12 @@ impl ForInIterator {
}
while let Some(r) = iterator.remaining_keys.pop_front() {
if !iterator.visited_keys.contains(&r) {
if let Some(desc) =
object.__get_own_property__(&PropertyKey::from(r.clone()), context)?
{
let mut slot = Slot::new();
if let Some(desc) = object.__get_own_property__(
&PropertyKey::from(r.clone()),
&mut slot,
context,
)? {
iterator.visited_keys.insert(r.clone());
if desc.expect_enumerable() {
return Ok(create_iter_result_object(JsValue::new(r), false, context));
Expand Down
25 changes: 16 additions & 9 deletions boa_engine/src/builtins/object/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ use crate::{
js_string,
native_function::NativeFunction,
object::{
internal_methods::get_prototype_from_constructor, FunctionObjectBuilder, IntegrityLevel,
JsObject, ObjectData, ObjectKind,
internal_methods::get_prototype_from_constructor, shape::slot::Slot, FunctionObjectBuilder,
IntegrityLevel, JsObject, ObjectData, ObjectKind,
},
property::{Attribute, PropertyDescriptor, PropertyKey, PropertyNameKind},
string::utf16,
Expand Down Expand Up @@ -336,7 +336,8 @@ impl Object {
// 3. Repeat
loop {
// a. Let desc be ? O.[[GetOwnProperty]](key).
let desc = obj.__get_own_property__(&key, context)?;
let mut slot = Slot::new();
let desc = obj.__get_own_property__(&key, &mut slot, context)?;

// b. If desc is not undefined, then
if let Some(current_desc) = desc {
Expand Down Expand Up @@ -380,7 +381,8 @@ impl Object {
// 3. Repeat
loop {
// a. Let desc be ? O.[[GetOwnProperty]](key).
let desc = obj.__get_own_property__(&key, context)?;
let mut slot = Slot::new();
let desc = obj.__get_own_property__(&key, &mut slot, context)?;

// b. If desc is not undefined, then
if let Some(current_desc) = desc {
Expand Down Expand Up @@ -460,7 +462,8 @@ impl Object {
let key = args.get_or_undefined(1).to_property_key(context)?;

// 3. Let desc be ? obj.[[GetOwnProperty]](key).
let desc = obj.__get_own_property__(&key, context)?;
let mut slot = Slot::new();
let desc = obj.__get_own_property__(&key, &mut slot, context)?;

// 4. Return FromPropertyDescriptor(desc).
Ok(Self::from_property_descriptor(desc, context))
Expand Down Expand Up @@ -493,7 +496,8 @@ impl Object {
// 4. For each element key of ownKeys, do
for key in own_keys {
// a. Let desc be ? obj.[[GetOwnProperty]](key).
let desc = obj.__get_own_property__(&key, context)?;
let mut slot = Slot::new();
let desc = obj.__get_own_property__(&key, &mut slot, context)?;

// b. Let descriptor be FromPropertyDescriptor(desc).
let descriptor = Self::from_property_descriptor(desc, context);
Expand Down Expand Up @@ -899,9 +903,10 @@ impl Object {
};

let key = key.to_property_key(context)?;
let mut slot = Slot::new();
let own_prop = this
.to_object(context)?
.__get_own_property__(&key, context)?;
.__get_own_property__(&key, &mut slot, context)?;

own_prop
.as_ref()
Expand Down Expand Up @@ -944,7 +949,8 @@ impl Object {
// 3.a.iii. For each element nextKey of keys, do
for key in keys {
// 3.a.iii.1. Let desc be ? from.[[GetOwnProperty]](nextKey).
if let Some(desc) = from.__get_own_property__(&key, context)? {
let mut slot = Slot::new();
if let Some(desc) = from.__get_own_property__(&key, &mut slot, context)? {
// 3.a.iii.2. If desc is not undefined and desc.[[Enumerable]] is true, then
if desc.expect_enumerable() {
// 3.a.iii.2.a. Let propValue be ? Get(from, nextKey).
Expand Down Expand Up @@ -1329,7 +1335,8 @@ fn object_define_properties(
for next_key in keys {
// a. Let propDesc be ? props.[[GetOwnProperty]](nextKey).
// b. If propDesc is not undefined and propDesc.[[Enumerable]] is true, then
if let Some(prop_desc) = props.__get_own_property__(&next_key, context)? {
let mut slot = Slot::new();
if let Some(prop_desc) = props.__get_own_property__(&next_key, &mut slot, context)? {
if prop_desc.expect_enumerable() {
// i. Let descObj be ? Get(props, nextKey).
let desc_obj = props.get(next_key.clone(), context)?;
Expand Down
9 changes: 6 additions & 3 deletions boa_engine/src/builtins/reflect/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use crate::{
builtins::{self, BuiltInObject},
context::intrinsics::Intrinsics,
error::JsNativeError,
object::JsObject,
object::{shape::slot::Slot, JsObject},
property::Attribute,
symbol::JsSymbol,
Context, JsArgs, JsResult, JsValue,
Expand Down Expand Up @@ -220,7 +220,8 @@ impl Reflect {
.cloned()
.unwrap_or_else(|| target.clone().into());
// 4. Return ? target.[[Get]](key, receiver).
target.__get__(&key, receiver, context)
let mut slot = Slot::new();
target.__get__(&key, receiver, &mut slot, context)
}

/// Gets a property of an object.
Expand Down Expand Up @@ -294,7 +295,9 @@ impl Reflect {
.get(1)
.unwrap_or(&JsValue::undefined())
.to_property_key(context)?;
Ok(target.__has_property__(&key, context)?.into())

let mut slot = Slot::new();
Ok(target.__has_property__(&key, &mut slot, context)?.into())
}

/// Returns `true` if the object is extensible, `false` otherwise.
Expand Down
11 changes: 7 additions & 4 deletions boa_engine/src/object/internal_methods/arguments.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use crate::{
object::JsObject,
object::{shape::slot::Slot, JsObject},
property::{DescriptorKind, PropertyDescriptor, PropertyKey},
Context, JsResult, JsValue,
};
Expand All @@ -25,11 +25,12 @@ pub(crate) static ARGUMENTS_EXOTIC_INTERNAL_METHODS: InternalObjectMethods =
pub(crate) fn arguments_exotic_get_own_property(
obj: &JsObject,
key: &PropertyKey,
slot: &mut Slot,
context: &mut Context<'_>,
) -> JsResult<Option<PropertyDescriptor>> {
// 1. Let desc be OrdinaryGetOwnProperty(args, P).
// 2. If desc is undefined, return desc.
let Some(desc) = super::ordinary_get_own_property(obj, key, context)? else {
let Some(desc) = super::ordinary_get_own_property(obj, key, slot, context)? else {
return Ok(None);
};

Expand Down Expand Up @@ -70,6 +71,7 @@ pub(crate) fn arguments_exotic_define_own_property(
obj: &JsObject,
key: &PropertyKey,
desc: PropertyDescriptor,
slot: &mut Slot,
context: &mut Context<'_>,
) -> JsResult<bool> {
// 2. Let isMapped be HasOwnProperty(map, P).
Expand Down Expand Up @@ -113,7 +115,7 @@ pub(crate) fn arguments_exotic_define_own_property(

// 5. Let allowed be ? OrdinaryDefineOwnProperty(args, P, newArgDesc).
// 6. If allowed is false, return false.
if !super::ordinary_define_own_property(obj, key, new_arg_desc, context)? {
if !super::ordinary_define_own_property(obj, key, new_arg_desc, slot, context)? {
return Ok(false);
}

Expand Down Expand Up @@ -161,6 +163,7 @@ pub(crate) fn arguments_exotic_get(
obj: &JsObject,
key: &PropertyKey,
receiver: JsValue,
slot: &mut Slot,
context: &mut Context<'_>,
) -> JsResult<JsValue> {
if let PropertyKey::Index(index) = key {
Expand All @@ -180,7 +183,7 @@ pub(crate) fn arguments_exotic_get(

// 3. If isMapped is false, then
// a. Return ? OrdinaryGet(args, P, Receiver).
super::ordinary_get(obj, key, receiver, context)
super::ordinary_get(obj, key, receiver, slot, context)
}

/// `[[Set]]` for arguments exotic objects.
Expand Down
24 changes: 16 additions & 8 deletions boa_engine/src/object/internal_methods/array.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::{
error::JsNativeError,
object::JsObject,
object::{shape::slot::Slot, JsObject},
property::{PropertyDescriptor, PropertyKey},
string::utf16,
Context, JsResult,
Expand Down Expand Up @@ -29,6 +29,7 @@ pub(crate) fn array_exotic_define_own_property(
obj: &JsObject,
key: &PropertyKey,
desc: PropertyDescriptor,
slot: &mut Slot,
context: &mut Context<'_>,
) -> JsResult<bool> {
// 1. Assert: IsPropertyKey(P) is true.
Expand All @@ -37,13 +38,13 @@ pub(crate) fn array_exotic_define_own_property(
PropertyKey::String(ref s) if s == utf16!("length") => {
// a. Return ? ArraySetLength(A, Desc).

array_set_length(obj, desc, context)
array_set_length(obj, desc, slot, context)
}
// 3. Else if P is an array index, then
PropertyKey::Index(index) if index < u32::MAX => {
// a. Let oldLenDesc be OrdinaryGetOwnProperty(A, "length").
let old_len_desc =
super::ordinary_get_own_property(obj, &utf16!("length").into(), context)?
super::ordinary_get_own_property(obj, &utf16!("length").into(), slot, context)?
.expect("the property descriptor must exist");

// b. Assert: ! IsDataDescriptor(oldLenDesc) is true.
Expand All @@ -66,7 +67,7 @@ pub(crate) fn array_exotic_define_own_property(
}

// h. Let succeeded be ! OrdinaryDefineOwnProperty(A, P, Desc).
if super::ordinary_define_own_property(obj, key, desc, context)? {
if super::ordinary_define_own_property(obj, key, desc, slot, context)? {
// j. If index ≥ oldLen, then
if index >= old_len {
// i. Set oldLenDesc.[[Value]] to index + 1𝔽.
Expand All @@ -81,6 +82,7 @@ pub(crate) fn array_exotic_define_own_property(
obj,
&utf16!("length").into(),
old_len_desc.into(),
slot,
context,
)?;

Expand All @@ -96,7 +98,7 @@ pub(crate) fn array_exotic_define_own_property(
}
}
// 4. Return OrdinaryDefineOwnProperty(A, P, Desc).
_ => super::ordinary_define_own_property(obj, key, desc, context),
_ => super::ordinary_define_own_property(obj, key, desc, slot, context),
}
}

Expand All @@ -109,12 +111,13 @@ pub(crate) fn array_exotic_define_own_property(
fn array_set_length(
obj: &JsObject,
desc: PropertyDescriptor,
slot: &mut Slot,
context: &mut Context<'_>,
) -> JsResult<bool> {
// 1. If Desc.[[Value]] is absent, then
let Some(new_len_val) = desc.value() else {
// a. Return OrdinaryDefineOwnProperty(A, "length", Desc).
return super::ordinary_define_own_property(obj, &utf16!("length").into(), desc, context);
return super::ordinary_define_own_property(obj, &utf16!("length").into(), desc, slot, context);
};

// 3. Let newLen be ? ToUint32(Desc.[[Value]]).
Expand All @@ -140,8 +143,9 @@ fn array_set_length(
.maybe_configurable(desc.configurable());

// 7. Let oldLenDesc be OrdinaryGetOwnProperty(A, "length").
let old_len_desc = super::ordinary_get_own_property(obj, &utf16!("length").into(), context)?
.expect("the property descriptor must exist");
let old_len_desc =
super::ordinary_get_own_property(obj, &utf16!("length").into(), slot, context)?
.expect("the property descriptor must exist");

// 8. Assert: ! IsDataDescriptor(oldLenDesc) is true.
debug_assert!(old_len_desc.is_data_descriptor());
Expand All @@ -159,6 +163,7 @@ fn array_set_length(
obj,
&utf16!("length").into(),
new_len_desc.build(),
slot,
context,
);
}
Expand Down Expand Up @@ -189,6 +194,7 @@ fn array_set_length(
obj,
&utf16!("length").into(),
new_len_desc.clone().build(),
slot,
context,
)
.expect("this OrdinaryDefineOwnProperty call must not fail")
Expand Down Expand Up @@ -226,6 +232,7 @@ fn array_set_length(
obj,
&utf16!("length").into(),
new_len_desc.build(),
slot,
context,
)
.expect("this OrdinaryDefineOwnProperty call must not fail");
Expand All @@ -243,6 +250,7 @@ fn array_set_length(
obj,
&utf16!("length").into(),
PropertyDescriptor::builder().writable(false).build(),
slot,
context,
)
.expect("this OrdinaryDefineOwnProperty call must not fail");
Expand Down
8 changes: 5 additions & 3 deletions boa_engine/src/object/internal_methods/global.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use crate::{
object::{InternalObjectMethods, JsObject, ORDINARY_INTERNAL_METHODS},
object::{shape::slot::Slot, InternalObjectMethods, JsObject, ORDINARY_INTERNAL_METHODS},
property::{PropertyDescriptor, PropertyKey},
value::JsValue,
Context, JsResult,
Expand Down Expand Up @@ -31,6 +31,7 @@ pub(crate) static GLOBAL_INTERNAL_METHODS: InternalObjectMethods = InternalObjec
pub(crate) fn global_get_own_property(
_obj: &JsObject,
key: &PropertyKey,
slot: &mut Slot,
context: &mut Context<'_>,
) -> JsResult<Option<PropertyDescriptor>> {
let _timer = Profiler::global().start_event("Object::global_get_own_property", "object");
Expand All @@ -48,7 +49,7 @@ pub(crate) fn global_get_own_property(
// 7. Set D.[[Enumerable]] to the value of X's [[Enumerable]] attribute.
// 8. Set D.[[Configurable]] to the value of X's [[Configurable]] attribute.
// 9. Return D.
Ok(context.realm.global_property_map.get(key))
Ok(context.realm.global_property_map.get_with_slot(key, slot))
}

/// Abstract operation `OrdinaryDefineOwnProperty`.
Expand All @@ -62,11 +63,12 @@ pub(crate) fn global_define_own_property(
obj: &JsObject,
key: &PropertyKey,
desc: PropertyDescriptor,
slot: &mut Slot,
context: &mut Context<'_>,
) -> JsResult<bool> {
let _timer = Profiler::global().start_event("Object::global_define_own_property", "object");
// 1. Let current be ? O.[[GetOwnProperty]](P).
let current = global_get_own_property(obj, key, context)?;
let current = global_get_own_property(obj, key, slot, context)?;

// 2. Let extensible be ? IsExtensible(O).
let extensible = obj.__is_extensible__(context)?;
Expand Down
Loading

0 comments on commit 9ebac0a

Please sign in to comment.