Skip to content

Commit

Permalink
Merge e375afd into 0e0ee49
Browse files Browse the repository at this point in the history
  • Loading branch information
raskad authored Jun 13, 2022
2 parents 0e0ee49 + e375afd commit bc073cb
Show file tree
Hide file tree
Showing 28 changed files with 2,520 additions and 523 deletions.
12 changes: 3 additions & 9 deletions boa_engine/src/builtins/eval/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,16 +81,10 @@ impl Eval {

// Because of implementation details the following code differs from the spec.

// 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()) {
// Parse the script body and handle early errors (6 - 11)
let body = match context.parse_eval(x.as_bytes(), direct, strict) {
Ok(body) => body,
Err(e) => return context.throw_syntax_error(e),
Err(e) => return context.throw_syntax_error(e.to_string()),
};

// 12 - 13 are implicit in the call of `Context::compile_with_new_declarative`.
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);
}
}

/// 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 bc073cb

Please sign in to comment.