Skip to content

Commit bc073cb

Browse files
authored
Merge e375afd into 0e0ee49
2 parents 0e0ee49 + e375afd commit bc073cb

File tree

28 files changed

+2520
-523
lines changed

28 files changed

+2520
-523
lines changed

boa_engine/src/builtins/eval/mod.rs

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -81,16 +81,10 @@ impl Eval {
8181

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

84-
// Parse the script body (11.a - 11.d)
85-
// TODO: Implement errors for 11.e - 11.h
86-
let parse_result = if strict {
87-
context.parse_strict(x.as_bytes())
88-
} else {
89-
context.parse(x.as_bytes())
90-
};
91-
let body = match parse_result.map_err(|e| e.to_string()) {
84+
// Parse the script body and handle early errors (6 - 11)
85+
let body = match context.parse_eval(x.as_bytes(), direct, strict) {
9286
Ok(body) => body,
93-
Err(e) => return context.throw_syntax_error(e),
87+
Err(e) => return context.throw_syntax_error(e.to_string()),
9488
};
9589

9690
// 12 - 13 are implicit in the call of `Context::compile_with_new_declarative`.

boa_engine/src/builtins/function/mod.rs

Lines changed: 106 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ use crate::{
1919
internal_methods::get_prototype_from_constructor, JsObject, NativeObject, Object,
2020
ObjectData,
2121
},
22-
object::{ConstructorBuilder, FunctionBuilder, Ref, RefMut},
22+
object::{ConstructorBuilder, FunctionBuilder, JsFunction, PrivateElement, Ref, RefMut},
2323
property::{Attribute, PropertyDescriptor, PropertyKey},
2424
symbol::WellKnownSymbols,
2525
syntax::{ast::node::FormalParameterList, Parser},
@@ -108,7 +108,13 @@ impl ThisMode {
108108
}
109109
}
110110

111-
#[derive(Debug, Trace, Finalize, PartialEq, Clone)]
111+
/// Represents the `[[ConstructorKind]]` internal slot of function objects.
112+
///
113+
/// More information:
114+
/// - [ECMAScript specification][spec]
115+
///
116+
/// [spec]: https://tc39.es/ecma262/#sec-ecmascript-function-objects
117+
#[derive(Clone, Copy, Debug, PartialEq)]
112118
pub enum ConstructorKind {
113119
Base,
114120
Derived,
@@ -126,6 +132,18 @@ impl ConstructorKind {
126132
}
127133
}
128134

135+
/// Record containing the field definition of classes.
136+
///
137+
/// More information:
138+
/// - [ECMAScript specification][spec]
139+
///
140+
/// [spec]: https://tc39.es/ecma262/#sec-classfielddefinition-record-specification-type
141+
#[derive(Clone, Debug, Trace, Finalize)]
142+
pub enum ClassFieldDefinition {
143+
Public(PropertyKey, JsFunction),
144+
Private(Sym, JsFunction),
145+
}
146+
129147
/// Wrapper for `Gc<GcCell<dyn NativeObject>>` that allows passing additional
130148
/// captures through a `Copy` closure.
131149
///
@@ -189,6 +207,19 @@ pub enum Function {
189207
Ordinary {
190208
code: Gc<crate::vm::CodeBlock>,
191209
environments: DeclarativeEnvironmentStack,
210+
211+
/// The `[[ConstructorKind]]` internal slot.
212+
#[unsafe_ignore_trace]
213+
constructor_kind: ConstructorKind,
214+
215+
/// The `[[HomeObject]]` internal slot.
216+
home_object: Option<JsObject>,
217+
218+
/// The `[[Fields]]` internal slot.
219+
fields: Vec<ClassFieldDefinition>,
220+
221+
/// The `[[PrivateMethods]]` internal slot.
222+
private_methods: Vec<(Sym, PrivateElement)>,
192223
},
193224
Generator {
194225
code: Gc<crate::vm::CodeBlock>,
@@ -210,6 +241,79 @@ impl Function {
210241
Self::Ordinary { code, .. } | Self::Generator { code, .. } => code.constructor,
211242
}
212243
}
244+
245+
/// Returns true if the function object is a derived constructor.
246+
pub(crate) fn is_derived_constructor(&self) -> bool {
247+
if let Self::Ordinary {
248+
constructor_kind, ..
249+
} = self
250+
{
251+
constructor_kind.is_derived()
252+
} else {
253+
false
254+
}
255+
}
256+
257+
/// Returns a reference to the function `[[HomeObject]]` slot if present.
258+
pub(crate) fn get_home_object(&self) -> Option<&JsObject> {
259+
if let Self::Ordinary { home_object, .. } = self {
260+
home_object.as_ref()
261+
} else {
262+
None
263+
}
264+
}
265+
266+
/// Sets the `[[HomeObject]]` slot if present.
267+
pub(crate) fn set_home_object(&mut self, object: JsObject) {
268+
if let Self::Ordinary { home_object, .. } = self {
269+
*home_object = Some(object);
270+
}
271+
}
272+
273+
/// Returns the values of the `[[Fields]]` internal slot.
274+
pub(crate) fn get_fields(&self) -> &[ClassFieldDefinition] {
275+
if let Self::Ordinary { fields, .. } = self {
276+
fields
277+
} else {
278+
&[]
279+
}
280+
}
281+
282+
/// Pushes a value to the `[[Fields]]` internal slot if present.
283+
pub(crate) fn push_field(&mut self, key: PropertyKey, value: JsFunction) {
284+
if let Self::Ordinary { fields, .. } = self {
285+
fields.push(ClassFieldDefinition::Public(key, value));
286+
}
287+
}
288+
289+
/// Pushes a private value to the `[[Fields]]` internal slot if present.
290+
pub(crate) fn push_field_private(&mut self, key: Sym, value: JsFunction) {
291+
if let Self::Ordinary { fields, .. } = self {
292+
fields.push(ClassFieldDefinition::Private(key, value));
293+
}
294+
}
295+
296+
/// Returns the values of the `[[PrivateMethods]]` internal slot.
297+
pub(crate) fn get_private_methods(&self) -> &[(Sym, PrivateElement)] {
298+
if let Self::Ordinary {
299+
private_methods, ..
300+
} = self
301+
{
302+
private_methods
303+
} else {
304+
&[]
305+
}
306+
}
307+
308+
/// Pushes a private method to the `[[PrivateMethods]]` internal slot if present.
309+
pub(crate) fn push_private_method(&mut self, name: Sym, method: PrivateElement) {
310+
if let Self::Ordinary {
311+
private_methods, ..
312+
} = self
313+
{
314+
private_methods.push((name, method));
315+
}
316+
}
213317
}
214318

215319
/// Creates a new member function of a `Object` or `prototype`.

0 commit comments

Comments
 (0)