Skip to content

Commit

Permalink
Implement Inline Caching
Browse files Browse the repository at this point in the history
  • Loading branch information
HalidOdat committed Nov 30, 2023
1 parent b2223cb commit 8365e91
Show file tree
Hide file tree
Showing 44 changed files with 853 additions and 268 deletions.
7 changes: 5 additions & 2 deletions 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, InternalMethodContext},
JsObject, ObjectData, CONSTRUCTOR,
},
property::{Attribute, PropertyDescriptor, PropertyNameKind},
realm::Realm,
string::common::StaticJsStrings,
Expand Down Expand Up @@ -349,7 +352,7 @@ impl Array {
.enumerable(false)
.configurable(false)
.build(),
context,
&mut InternalMethodContext::new(context),
)?;

Ok(array)
Expand Down
5 changes: 4 additions & 1 deletion boa_engine/src/builtins/function/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,10 @@ fn closure_capture_clone() {
let hw = js_string!(
string,
&object
.__get_own_property__(&js_string!("key").into(), context)?
.__get_own_property__(
&js_string!("key").into(),
&mut context.into()
)?
.and_then(|prop| prop.value().cloned())
.and_then(|val| val.as_string().cloned())
.ok_or_else(
Expand Down
6 changes: 3 additions & 3 deletions boa_engine/src/builtins/json/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ use crate::{
context::intrinsics::Intrinsics,
error::JsNativeError,
js_string,
object::JsObject,
object::{internal_methods::InternalMethodContext, JsObject},
property::{Attribute, PropertyNameKind},
realm::Realm,
string::{common::StaticJsStrings, utf16, CodePoint},
Expand Down Expand Up @@ -198,7 +198,7 @@ impl Json {
// 3. If newElement is undefined, then
if new_element.is_undefined() {
// a. Perform ? val.[[Delete]](prop).
obj.__delete__(&i.into(), context)?;
obj.__delete__(&i.into(), &mut InternalMethodContext::new(context))?;
}
// 4. Else,
else {
Expand Down Expand Up @@ -227,7 +227,7 @@ impl Json {
// 2. If newElement is undefined, then
if new_element.is_undefined() {
// a. Perform ? val.[[Delete]](P).
obj.__delete__(&p.into(), context)?;
obj.__delete__(&p.into(), &mut InternalMethodContext::new(context))?;
}
// 3. Else,
else {
Expand Down
12 changes: 7 additions & 5 deletions boa_engine/src/builtins/object/for_in_iterator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use crate::{
context::intrinsics::Intrinsics,
error::JsNativeError,
js_string,
object::{JsObject, ObjectData},
object::{internal_methods::InternalMethodContext, JsObject, ObjectData},
property::PropertyKey,
realm::Realm,
Context, JsResult, JsString, JsValue,
Expand Down Expand Up @@ -106,7 +106,8 @@ impl ForInIterator {
let mut object = iterator.object.to_object(context)?;
loop {
if !iterator.object_was_visited {
let keys = object.__own_property_keys__(context)?;
let keys =
object.__own_property_keys__(&mut InternalMethodContext::new(context))?;
for k in keys {
match k {
PropertyKey::String(ref k) => {
Expand All @@ -124,9 +125,10 @@ 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)?
{
if let Some(desc) = object.__get_own_property__(
&PropertyKey::from(r.clone()),
&mut InternalMethodContext::new(context),
)? {
iterator.visited_keys.insert(r.clone());
if desc.expect_enumerable() {
return Ok(create_iter_result_object(JsValue::new(r), false, context));
Expand Down
52 changes: 32 additions & 20 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, InternalMethodContext},
FunctionObjectBuilder, IntegrityLevel, JsObject, ObjectData, ObjectKind,
},
property::{Attribute, PropertyDescriptor, PropertyKey, PropertyNameKind},
realm::Realm,
Expand Down Expand Up @@ -211,7 +211,7 @@ impl Object {
let obj = this.to_object(context)?;

// 2. Return ? O.[[GetPrototypeOf]]().
let proto = obj.__get_prototype_of__(context)?;
let proto = obj.__get_prototype_of__(&mut InternalMethodContext::new(context))?;

Ok(proto.map_or(JsValue::Null, JsValue::new))
}
Expand Down Expand Up @@ -248,7 +248,8 @@ impl Object {
};

// 4. Let status be ? O.[[SetPrototypeOf]](proto).
let status = object.__set_prototype_of__(proto, context)?;
let status =
object.__set_prototype_of__(proto, &mut InternalMethodContext::new(context))?;

// 5. If status is false, throw a TypeError exception.
if !status {
Expand Down Expand Up @@ -371,7 +372,8 @@ impl Object {
// 3. Repeat
loop {
// a. Let desc be ? O.[[GetOwnProperty]](key).
let desc = obj.__get_own_property__(&key, context)?;

let desc = obj.__get_own_property__(&key, &mut InternalMethodContext::new(context))?;

// b. If desc is not undefined, then
if let Some(current_desc) = desc {
Expand All @@ -383,7 +385,7 @@ impl Object {
Ok(JsValue::undefined())
};
}
match obj.__get_prototype_of__(context)? {
match obj.__get_prototype_of__(&mut InternalMethodContext::new(context))? {
// c. Set O to ? O.[[GetPrototypeOf]]().
Some(o) => obj = o,
// d. If O is null, return undefined.
Expand Down Expand Up @@ -415,7 +417,8 @@ impl Object {
// 3. Repeat
loop {
// a. Let desc be ? O.[[GetOwnProperty]](key).
let desc = obj.__get_own_property__(&key, context)?;

let desc = obj.__get_own_property__(&key, &mut InternalMethodContext::new(context))?;

// b. If desc is not undefined, then
if let Some(current_desc) = desc {
Expand All @@ -427,7 +430,7 @@ impl Object {
Ok(JsValue::undefined())
};
}
match obj.__get_prototype_of__(context)? {
match obj.__get_prototype_of__(&mut InternalMethodContext::new(context))? {
// c. Set O to ? O.[[GetPrototypeOf]]().
Some(o) => obj = o,
// d. If O is null, return undefined.
Expand Down Expand Up @@ -496,7 +499,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 desc = obj.__get_own_property__(&key, &mut InternalMethodContext::new(context))?;

// 4. Return FromPropertyDescriptor(desc).
Ok(Self::from_property_descriptor(desc, context))
Expand All @@ -521,15 +525,16 @@ impl Object {
let obj = args.get_or_undefined(0).to_object(context)?;

// 2. Let ownKeys be ? obj.[[OwnPropertyKeys]]().
let own_keys = obj.__own_property_keys__(context)?;
let own_keys = obj.__own_property_keys__(&mut InternalMethodContext::new(context))?;

// 3. Let descriptors be OrdinaryObjectCreate(%Object.prototype%).
let descriptors = JsObject::with_object_proto(context.intrinsics());

// 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 desc = obj.__get_own_property__(&key, &mut InternalMethodContext::new(context))?;

// b. Let descriptor be FromPropertyDescriptor(desc).
let descriptor = Self::from_property_descriptor(desc, context);
Expand Down Expand Up @@ -642,7 +647,7 @@ impl Object {

// 2. Return ? obj.[[GetPrototypeOf]]().
Ok(obj
.__get_prototype_of__(context)?
.__get_prototype_of__(&mut InternalMethodContext::new(context))?
.map_or(JsValue::Null, JsValue::new))
}

Expand Down Expand Up @@ -693,7 +698,7 @@ impl Object {
};

// 4. Let status be ? O.[[SetPrototypeOf]](proto).
let status = obj.__set_prototype_of__(proto, context)?;
let status = obj.__set_prototype_of__(proto, &mut InternalMethodContext::new(context))?;

// 5. If status is false, throw a TypeError exception.
if !status {
Expand Down Expand Up @@ -931,9 +936,10 @@ impl Object {
};

let key = key.to_property_key(context)?;

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

own_prop
.as_ref()
Expand Down Expand Up @@ -972,11 +978,14 @@ impl Object {
.to_object(context)
.expect("this ToObject call must not fail");
// 3.a.ii. Let keys be ? from.[[OwnPropertyKeys]]().
let keys = from.__own_property_keys__(context)?;
let keys = from.__own_property_keys__(&mut InternalMethodContext::new(context))?;
// 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)? {

if let Some(desc) =
from.__get_own_property__(&key, &mut InternalMethodContext::new(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 @@ -1187,7 +1196,7 @@ impl Object {

if let Some(o) = o.as_object() {
// 2. Let status be ? O.[[PreventExtensions]]().
let status = o.__prevent_extensions__(context)?;
let status = o.__prevent_extensions__(&mut InternalMethodContext::new(context))?;
// 3. If status is false, throw a TypeError exception.
if !status {
return Err(JsNativeError::typ()
Expand Down Expand Up @@ -1444,7 +1453,7 @@ fn object_define_properties(
let props = &props.to_object(context)?;

// 3. Let keys be ? props.[[OwnPropertyKeys]]().
let keys = props.__own_property_keys__(context)?;
let keys = props.__own_property_keys__(&mut InternalMethodContext::new(context))?;

// 4. Let descriptors be a new empty List.
let mut descriptors: Vec<(PropertyKey, PropertyDescriptor)> = Vec::new();
Expand All @@ -1453,7 +1462,10 @@ 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)? {

if let Some(prop_desc) =
props.__get_own_property__(&next_key, &mut InternalMethodContext::new(context))?
{
if prop_desc.expect_enumerable() {
// i. Let descObj be ? Get(props, nextKey).
let desc_obj = props.get(next_key.clone(), context)?;
Expand Down Expand Up @@ -1501,7 +1513,7 @@ fn get_own_property_keys(
let obj = o.to_object(context)?;

// 2. Let keys be ? obj.[[OwnPropertyKeys]]().
let keys = obj.__own_property_keys__(context)?;
let keys = obj.__own_property_keys__(&mut InternalMethodContext::new(context))?;

// 3. Let nameList be a new empty List.
// 4. For each element nextKey of keys, do
Expand Down
44 changes: 33 additions & 11 deletions boa_engine/src/builtins/reflect/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ use crate::{
context::intrinsics::Intrinsics,
error::JsNativeError,
js_string,
object::JsObject,
object::{internal_methods::InternalMethodContext, JsObject},
property::Attribute,
realm::Realm,
string::common::StaticJsStrings,
Expand Down Expand Up @@ -166,7 +166,11 @@ impl Reflect {
.into();

target
.__define_own_property__(&key, prop_desc.to_property_descriptor(context)?, context)
.__define_own_property__(
&key,
prop_desc.to_property_descriptor(context)?,
&mut InternalMethodContext::new(context),
)
.map(Into::into)
}

Expand All @@ -189,7 +193,9 @@ impl Reflect {
.ok_or_else(|| JsNativeError::typ().with_message("target must be an object"))?;
let key = args.get_or_undefined(1).to_property_key(context)?;

Ok(target.__delete__(&key, context)?.into())
Ok(target
.__delete__(&key, &mut InternalMethodContext::new(context))?
.into())
}

/// Gets a property of an object.
Expand All @@ -215,7 +221,8 @@ impl Reflect {
.cloned()
.unwrap_or_else(|| target.clone().into());
// 4. Return ? target.[[Get]](key, receiver).
target.__get__(&key, receiver, context)

target.__get__(&key, receiver, &mut InternalMethodContext::new(context))
}

/// Gets a property of an object.
Expand Down Expand Up @@ -264,7 +271,7 @@ impl Reflect {
.and_then(JsValue::as_object)
.ok_or_else(|| JsNativeError::typ().with_message("target must be an object"))?;
Ok(target
.__get_prototype_of__(context)?
.__get_prototype_of__(&mut InternalMethodContext::new(context))?
.map_or(JsValue::Null, JsValue::new))
}

Expand All @@ -285,7 +292,10 @@ impl Reflect {
.get(1)
.unwrap_or(&JsValue::undefined())
.to_property_key(context)?;
Ok(target.__has_property__(&key, context)?.into())

Ok(target
.__has_property__(&key, &mut InternalMethodContext::new(context))?
.into())
}

/// Returns `true` if the object is extensible, `false` otherwise.
Expand All @@ -305,7 +315,9 @@ impl Reflect {
.get(0)
.and_then(JsValue::as_object)
.ok_or_else(|| JsNativeError::typ().with_message("target must be an object"))?;
Ok(target.__is_extensible__(context)?.into())
Ok(target
.__is_extensible__(&mut InternalMethodContext::new(context))?
.into())
}

/// Returns an array of object own property keys.
Expand All @@ -327,7 +339,7 @@ impl Reflect {
.ok_or_else(|| JsNativeError::typ().with_message("target must be an object"))?;

let keys: Vec<JsValue> = target
.__own_property_keys__(context)?
.__own_property_keys__(&mut InternalMethodContext::new(context))?
.into_iter()
.map(Into::into)
.collect();
Expand All @@ -353,7 +365,9 @@ impl Reflect {
.and_then(JsValue::as_object)
.ok_or_else(|| JsNativeError::typ().with_message("target must be an object"))?;

Ok(target.__prevent_extensions__(context)?.into())
Ok(target
.__prevent_extensions__(&mut InternalMethodContext::new(context))?
.into())
}

/// Sets a property of an object.
Expand All @@ -375,8 +389,14 @@ impl Reflect {
.get(3)
.cloned()
.unwrap_or_else(|| target.clone().into());

Ok(target
.__set__(key, value.clone(), receiver, context)?
.__set__(
key,
value.clone(),
receiver,
&mut InternalMethodContext::new(context),
)?
.into())
}

Expand Down Expand Up @@ -406,6 +426,8 @@ impl Reflect {
.into())
}
};
Ok(target.__set_prototype_of__(proto, context)?.into())
Ok(target
.__set_prototype_of__(proto, &mut InternalMethodContext::new(context))?
.into())
}
}
Loading

0 comments on commit 8365e91

Please sign in to comment.