Skip to content

Commit

Permalink
Merge d1fce74 into 8af90a7
Browse files Browse the repository at this point in the history
  • Loading branch information
raskad authored Jun 13, 2022
2 parents 8af90a7 + d1fce74 commit f4aa3ec
Show file tree
Hide file tree
Showing 28 changed files with 2,521 additions and 520 deletions.
10 changes: 4 additions & 6 deletions boa_engine/src/builtins/eval/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -83,12 +83,10 @@ impl Eval {

// Parse the script body (11.a - 11.d)
// TODO: Implement errors for 11.e - 11.h
let parse_result = if strict {
context.parse_strict(x.as_bytes())
} else {
context.parse(x.as_bytes())
};
let body = match parse_result.map_err(|e| e.to_string()) {
let body = match context
.parse_eval(x.as_bytes(), direct, strict)
.map_err(|e| e.to_string())
{
Ok(body) => body,
Err(e) => return context.throw_syntax_error(e),
};
Expand Down
108 changes: 106 additions & 2 deletions boa_engine/src/builtins/function/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ use crate::{
internal_methods::get_prototype_from_constructor, JsObject, NativeObject, Object,
ObjectData,
},
object::{ConstructorBuilder, FunctionBuilder, Ref, RefMut},
object::{ConstructorBuilder, FunctionBuilder, JsFunction, PrivateElement, Ref, RefMut},
property::{Attribute, PropertyDescriptor, PropertyKey},
symbol::WellKnownSymbols,
syntax::{ast::node::FormalParameterList, Parser},
Expand Down Expand Up @@ -108,7 +108,13 @@ impl ThisMode {
}
}

#[derive(Debug, Trace, Finalize, PartialEq, Clone)]
/// Represents the `[[ConstructorKind]]` internal slot of function objects.
///
/// More information:
/// - [ECMAScript specification][spec]
///
/// [spec]: https://tc39.es/ecma262/#sec-ecmascript-function-objects
#[derive(Clone, Copy, Debug, PartialEq)]
pub enum ConstructorKind {
Base,
Derived,
Expand All @@ -126,6 +132,18 @@ impl ConstructorKind {
}
}

/// Record containing the field definition of classes.
///
/// More information:
/// - [ECMAScript specification][spec]
///
/// [spec]: https://tc39.es/ecma262/#sec-classfielddefinition-record-specification-type
#[derive(Clone, Debug, Trace, Finalize)]
pub enum ClassFieldDefinition {
Public(PropertyKey, JsFunction),
Private(Sym, JsFunction),
}

/// Wrapper for `Gc<GcCell<dyn NativeObject>>` that allows passing additional
/// captures through a `Copy` closure.
///
Expand Down Expand Up @@ -189,6 +207,19 @@ pub enum Function {
Ordinary {
code: Gc<crate::vm::CodeBlock>,
environments: DeclarativeEnvironmentStack,

/// The `[[ConstructorKind]]` internal slot.
#[unsafe_ignore_trace]
constructor_kind: ConstructorKind,

/// The `[[HomeObject]]` internal slot.
home_object: Option<JsObject>,

/// The `[[Fields]]` internal slot.
fields: Vec<ClassFieldDefinition>,

/// The `[[PrivateMethods]]` internal slot.
private_methods: Vec<(Sym, PrivateElement)>,
},
Generator {
code: Gc<crate::vm::CodeBlock>,
Expand All @@ -210,6 +241,79 @@ impl Function {
Self::Ordinary { code, .. } | Self::Generator { code, .. } => code.constructor,
}
}

/// Returns true if the function object is a derived constructor.
pub(crate) fn is_derived_constructor(&self) -> bool {
if let Self::Ordinary {
constructor_kind, ..
} = self
{
constructor_kind.is_derived()
} else {
false
}
}

/// Returns a reference to the function `[[HomeObject]]` slot if present.
pub(crate) fn get_home_object(&self) -> Option<&JsObject> {
if let Self::Ordinary { home_object, .. } = self {
home_object.as_ref()
} else {
None
}
}

/// Sets the `[[HomeObject]]` slot if present.
pub(crate) fn set_home_object(&mut self, object: &JsObject) {
if let Self::Ordinary { home_object, .. } = self {
*home_object = Some(object.clone());
}
}

/// Returns the values of the `[[Fields]]` internal slot.
pub(crate) fn get_fields(&self) -> &[ClassFieldDefinition] {
if let Self::Ordinary { fields, .. } = self {
fields
} else {
&[]
}
}

/// Pushes a value to the `[[Fields]]` internal slot if present.
pub(crate) fn push_field(&mut self, key: PropertyKey, value: JsFunction) {
if let Self::Ordinary { fields, .. } = self {
fields.push(ClassFieldDefinition::Public(key, value));
}
}

/// Pushes a private value to the `[[Fields]]` internal slot if present.
pub(crate) fn push_field_private(&mut self, key: Sym, value: JsFunction) {
if let Self::Ordinary { fields, .. } = self {
fields.push(ClassFieldDefinition::Private(key, value));
}
}

/// Returns the values of the `[[PrivateMethods]]` internal slot.
pub(crate) fn get_private_methods(&self) -> &[(Sym, PrivateElement)] {
if let Self::Ordinary {
private_methods, ..
} = self
{
private_methods
} else {
&[]
}
}

/// Pushes a private method to the `[[PrivateMethods]]` internal slot if present.
pub(crate) fn push_private_method(&mut self, name: Sym, method: PrivateElement) {
if let Self::Ordinary {
private_methods, ..
} = self
{
private_methods.push((name, method));
}
}
}

/// Creates a new member function of a `Object` or `prototype`.
Expand Down
Loading

0 comments on commit f4aa3ec

Please sign in to comment.