Skip to content

Commit

Permalink
Store internal object methods as static struct
Browse files Browse the repository at this point in the history
  • Loading branch information
jedel1043 committed Aug 24, 2021
1 parent 6b3e634 commit 8b533d8
Show file tree
Hide file tree
Showing 5 changed files with 59 additions and 72 deletions.
9 changes: 8 additions & 1 deletion boa/src/object/internal_methods/array.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,20 @@ use crate::{
Context, JsResult,
};

use super::{InternalObjectMethods, ORDINARY_INTERNAL_METHODS};

pub(crate) static ARRAY_EXOTIC_INTERNAL_METHODS: InternalObjectMethods = InternalObjectMethods {
__define_own_property__: array_exotic_define_own_property,
..ORDINARY_INTERNAL_METHODS
};

/// Define an own property for an array.
///
/// More information:
/// - [ECMAScript reference][spec]
///
/// [spec]: https://tc39.es/ecma262/#sec-array-exotic-objects-defineownproperty-p-desc
pub(crate) fn array_define_own_property(
pub(crate) fn array_exotic_define_own_property(
obj: &GcObject,
key: PropertyKey,
desc: PropertyDescriptor,
Expand Down
31 changes: 13 additions & 18 deletions boa/src/object/internal_methods/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,19 @@ impl GcObject {
}
}

pub(crate) static ORDINARY_INTERNAL_METHODS: InternalObjectMethods = InternalObjectMethods {
__get_prototype_of__: ordinary_get_prototype_of,
__set_prototype_of__: ordinary_set_prototype_of,
__is_extensible__: ordinary_is_extensible,
__prevent_extensions__: ordinary_prevent_extensions,
__get_own_property__: ordinary_get_own_property,
__define_own_property__: ordinary_define_own_property,
__has_property__: ordinary_has_property,
__get__: ordinary_get,
__set__: ordinary_set,
__delete__: ordinary_delete,
__own_property_keys__: ordinary_own_property_keys,
};
#[derive(Clone, Copy)]
pub(crate) struct InternalObjectMethods {
pub(crate) __get_prototype_of__: fn(&GcObject, &mut Context) -> JsResult<JsValue>,
Expand All @@ -177,24 +190,6 @@ pub(crate) struct InternalObjectMethods {
pub(crate) __own_property_keys__: fn(&GcObject, &mut Context) -> JsResult<Vec<PropertyKey>>,
}

impl Default for InternalObjectMethods {
fn default() -> Self {
Self {
__get_prototype_of__: ordinary_get_prototype_of,
__set_prototype_of__: ordinary_set_prototype_of,
__is_extensible__: ordinary_is_extensible,
__prevent_extensions__: ordinary_prevent_extensions,
__get_own_property__: ordinary_get_own_property,
__define_own_property__: ordinary_define_own_property,
__has_property__: ordinary_has_property,
__get__: ordinary_get,
__set__: ordinary_set,
__delete__: ordinary_delete,
__own_property_keys__: ordinary_own_property_keys,
}
}
}

/// Returns either the prototype or null
///
/// More information:
Expand Down
20 changes: 11 additions & 9 deletions boa/src/object/internal_methods/string.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,15 @@ use crate::{
Context, JsResult, JsValue,
};

use super::{InternalObjectMethods, ORDINARY_INTERNAL_METHODS};

pub(crate) static STRING_EXOTIC_INTERNAL_METHODS: InternalObjectMethods = InternalObjectMethods {
__get_own_property__: string_exotic_get_own_property,
__define_own_property__: string_exotic_define_own_property,
__own_property_keys__: string_exotic_own_property_keys,
..ORDINARY_INTERNAL_METHODS
};

/// Gets own property of 'String' exotic object
///
/// More information:
Expand Down Expand Up @@ -97,20 +106,13 @@ pub(crate) fn string_exotic_own_property_keys(
#[allow(clippy::float_cmp)]
#[inline]
fn string_get_own_property(obj: &GcObject, key: &PropertyKey) -> Option<PropertyDescriptor> {
let obj = obj.borrow();

let pos = match key {
PropertyKey::Index(index) => *index as usize,
PropertyKey::String(index) => {
let index = index.canonical_numeric_index_string()?;
if index != ((index as usize) as f64) {
return None;
}
index as usize
}
_ => return None,
};

let string = obj
.borrow()
.as_string()
.expect("string exotic method should only be callable from string objects");

Expand Down
59 changes: 27 additions & 32 deletions boa/src/object/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,11 @@ pub use gcobject::{GcObject, RecursionLimiter, Ref, RefMut};
use internal_methods::InternalObjectMethods;
pub use property_map::*;

use self::internal_methods::{
array::ARRAY_EXOTIC_INTERNAL_METHODS, string::STRING_EXOTIC_INTERNAL_METHODS,
ORDINARY_INTERNAL_METHODS,
};

/// Static `prototype`, usually set on constructors as a key to point to their respective prototype object.
pub static PROTOTYPE: &str = "prototype";

Expand Down Expand Up @@ -79,8 +84,7 @@ pub struct Object {
#[derive(Trace, Finalize)]
pub struct ObjectData {
kind: ObjectKind,
#[unsafe_ignore_trace]
internal_methods: InternalObjectMethods,
internal_methods: &'static InternalObjectMethods,
}

#[derive(Debug, Trace, Finalize)]
Expand Down Expand Up @@ -112,137 +116,128 @@ impl ObjectData {
pub fn array() -> Self {
Self {
kind: ObjectKind::Array,
internal_methods: InternalObjectMethods {
__define_own_property__: internal_methods::array::array_define_own_property,
..Default::default()
},
internal_methods: &ARRAY_EXOTIC_INTERNAL_METHODS,
}
}

pub fn array_iterator(array_iterator: ArrayIterator) -> Self {
Self {
kind: ObjectKind::ArrayIterator(array_iterator),
internal_methods: InternalObjectMethods::default(),
internal_methods: &ORDINARY_INTERNAL_METHODS,
}
}
pub fn map(map: OrderedMap<JsValue>) -> Self {
Self {
kind: ObjectKind::Map(map),
internal_methods: InternalObjectMethods::default(),
internal_methods: &ORDINARY_INTERNAL_METHODS,
}
}
pub fn map_iterator(map_iterator: MapIterator) -> Self {
Self {
kind: ObjectKind::MapIterator(map_iterator),
internal_methods: InternalObjectMethods::default(),
internal_methods: &ORDINARY_INTERNAL_METHODS,
}
}
pub fn reg_exp(reg_exp: Box<RegExp>) -> Self {
Self {
kind: ObjectKind::RegExp(reg_exp),
internal_methods: InternalObjectMethods::default(),
internal_methods: &ORDINARY_INTERNAL_METHODS,
}
}
pub fn reg_exp_string_iterator(reg_exp_string_iterator: RegExpStringIterator) -> Self {
Self {
kind: ObjectKind::RegExpStringIterator(reg_exp_string_iterator),
internal_methods: InternalObjectMethods::default(),
internal_methods: &ORDINARY_INTERNAL_METHODS,
}
}
pub fn big_int(big_int: JsBigInt) -> Self {
Self {
kind: ObjectKind::BigInt(big_int),
internal_methods: InternalObjectMethods::default(),
internal_methods: &ORDINARY_INTERNAL_METHODS,
}
}
pub fn boolean(boolean: bool) -> Self {
Self {
kind: ObjectKind::Boolean(boolean),
internal_methods: InternalObjectMethods::default(),
internal_methods: &ORDINARY_INTERNAL_METHODS,
}
}
pub fn for_in_iterator(for_in_iterator: ForInIterator) -> Self {
Self {
kind: ObjectKind::ForInIterator(for_in_iterator),
internal_methods: InternalObjectMethods::default(),
internal_methods: &ORDINARY_INTERNAL_METHODS,
}
}
pub fn function(function: Function) -> Self {
Self {
kind: ObjectKind::Function(function),
internal_methods: InternalObjectMethods::default(),
internal_methods: &ORDINARY_INTERNAL_METHODS,
}
}
pub fn set(set: OrderedSet<JsValue>) -> Self {
Self {
kind: ObjectKind::Set(set),
internal_methods: InternalObjectMethods::default(),
internal_methods: &ORDINARY_INTERNAL_METHODS,
}
}
pub fn set_iterator(set_iterator: SetIterator) -> Self {
Self {
kind: ObjectKind::SetIterator(set_iterator),
internal_methods: InternalObjectMethods::default(),
internal_methods: &ORDINARY_INTERNAL_METHODS,
}
}
pub fn string(string: JsString) -> Self {
Self {
kind: ObjectKind::String(string),
internal_methods: InternalObjectMethods {
__get_own_property__: internal_methods::string::string_exotic_get_own_property,
__define_own_property__:
internal_methods::string::string_exotic_define_own_property,
__own_property_keys__: internal_methods::string::string_exotic_own_property_keys,
..Default::default()
},
internal_methods: &STRING_EXOTIC_INTERNAL_METHODS,
}
}
pub fn string_iterator(string_iterator: StringIterator) -> Self {
Self {
kind: ObjectKind::StringIterator(string_iterator),
internal_methods: InternalObjectMethods::default(),
internal_methods: &ORDINARY_INTERNAL_METHODS,
}
}
pub fn number(number: f64) -> Self {
Self {
kind: ObjectKind::Number(number),
internal_methods: InternalObjectMethods::default(),
internal_methods: &ORDINARY_INTERNAL_METHODS,
}
}
pub fn symbol(symbol: JsSymbol) -> Self {
Self {
kind: ObjectKind::Symbol(symbol),
internal_methods: InternalObjectMethods::default(),
internal_methods: &ORDINARY_INTERNAL_METHODS,
}
}
pub fn error() -> Self {
Self {
kind: ObjectKind::Error,
internal_methods: InternalObjectMethods::default(),
internal_methods: &ORDINARY_INTERNAL_METHODS,
}
}
pub fn ordinary() -> Self {
Self {
kind: ObjectKind::Ordinary,
internal_methods: InternalObjectMethods::default(),
internal_methods: &ORDINARY_INTERNAL_METHODS,
}
}
pub fn date(date: Date) -> Self {
Self {
kind: ObjectKind::Date(date),
internal_methods: InternalObjectMethods::default(),
internal_methods: &ORDINARY_INTERNAL_METHODS,
}
}
pub fn global() -> Self {
Self {
kind: ObjectKind::Global,
internal_methods: InternalObjectMethods::default(),
internal_methods: &ORDINARY_INTERNAL_METHODS,
}
}
pub fn native_object(native_object: Box<dyn NativeObject>) -> Self {
Self {
kind: ObjectKind::NativeObject(native_object),
internal_methods: InternalObjectMethods::default(),
internal_methods: &ORDINARY_INTERNAL_METHODS,
}
}
}
Expand Down
12 changes: 0 additions & 12 deletions boa/src/string.rs
Original file line number Diff line number Diff line change
Expand Up @@ -264,18 +264,6 @@ impl JsString {
_ => fast_float::parse(string).unwrap_or(f64::NAN),
}
}

pub(crate) fn canonical_numeric_index_string(&self) -> Option<f64> {
if self == "-0" {
return Some(-0.0);
}
let n = self.string_to_number();
if self != n.to_string().as_str() {
None
} else {
Some(n)
}
}
}

impl Finalize for JsString {}
Expand Down

0 comments on commit 8b533d8

Please sign in to comment.