Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Merged by Bors] - Make Realm shareable between functions #2801

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 10 additions & 3 deletions boa_engine/src/builtins/array/array_iterator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ use crate::{
error::JsNativeError,
object::{JsObject, ObjectData},
property::{Attribute, PropertyNameKind},
realm::Realm,
symbol::JsSymbol,
Context, JsResult,
};
Expand All @@ -35,11 +36,17 @@ pub struct ArrayIterator {
}

impl IntrinsicObject for ArrayIterator {
fn init(intrinsics: &Intrinsics) {
fn init(realm: &Realm) {
let _timer = Profiler::global().start_event("ArrayIterator", "init");

BuiltInBuilder::with_intrinsic::<Self>(intrinsics)
.prototype(intrinsics.objects().iterator_prototypes().iterator())
BuiltInBuilder::with_intrinsic::<Self>(realm)
.prototype(
realm
.intrinsics()
.objects()
.iterator_prototypes()
.iterator(),
)
.static_method(Self::next, "next", 0)
.static_property(
JsSymbol::to_string_tag(),
Expand Down
27 changes: 16 additions & 11 deletions boa_engine/src/builtins/array/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ use crate::{
js_string,
object::{internal_methods::get_prototype_from_constructor, JsObject, ObjectData, CONSTRUCTOR},
property::{Attribute, PropertyDescriptor, PropertyNameKind},
realm::Realm,
symbol::JsSymbol,
value::{IntegerOrInfinity, JsValue},
Context, JsArgs, JsResult,
Expand All @@ -40,26 +41,28 @@ mod tests;
pub(crate) struct Array;

impl IntrinsicObject for Array {
fn init(intrinsics: &Intrinsics) {
fn init(realm: &Realm) {
let _timer = Profiler::global().start_event(Self::NAME, "init");

let symbol_iterator = JsSymbol::iterator();
let symbol_unscopables = JsSymbol::unscopables();

let get_species = BuiltInBuilder::new(intrinsics)
let get_species = BuiltInBuilder::new(realm)
.callable(Self::get_species)
.name("get [Symbol.species]")
.build();

let values_function =
BuiltInBuilder::with_object(intrinsics, intrinsics.objects().array_prototype_values())
.callable(Self::values)
.name("values")
.build();
let values_function = BuiltInBuilder::with_object(
realm,
realm.intrinsics().objects().array_prototype_values(),
)
.callable(Self::values)
.name("values")
.build();

let unscopables_object = Self::unscopables_object();

BuiltInBuilder::from_standard_constructor::<Self>(intrinsics)
BuiltInBuilder::from_standard_constructor::<Self>(realm)
.static_accessor(
JsSymbol::species(),
Some(get_species),
Expand Down Expand Up @@ -369,12 +372,14 @@ impl Array {
// 4. If IsConstructor(C) is true, then
if let Some(c) = c.as_constructor() {
// a. Let thisRealm be the current Realm Record.
let this_realm = &context.intrinsics().clone();
let this_realm = context.realm().clone();
// b. Let realmC be ? GetFunctionRealm(C).
let realm_c = &c.get_function_realm(context)?;
let realm_c = c.get_function_realm(context)?;

// c. If thisRealm and realmC are not the same Realm Record, then
if this_realm != realm_c && *c == realm_c.constructors().array().constructor() {
if this_realm != realm_c
&& *c == realm_c.intrinsics().constructors().array().constructor()
{
// i. If SameValue(C, realmC.[[Intrinsics]].[[%Array%]]) is true, set C to undefined.
// Note: fast path to step 6.
return Self::array_create(length, None, context);
Expand Down
9 changes: 5 additions & 4 deletions boa_engine/src/builtins/array_buffer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ use crate::{
error::JsNativeError,
object::{internal_methods::get_prototype_from_constructor, JsObject, ObjectData},
property::Attribute,
realm::Realm,
string::utf16,
symbol::JsSymbol,
value::{IntegerOrInfinity, Numeric},
Expand Down Expand Up @@ -47,22 +48,22 @@ impl ArrayBuffer {
}

impl IntrinsicObject for ArrayBuffer {
fn init(intrinsics: &Intrinsics) {
fn init(realm: &Realm) {
let _timer = Profiler::global().start_event(Self::NAME, "init");

let flag_attributes = Attribute::CONFIGURABLE | Attribute::NON_ENUMERABLE;

let get_species = BuiltInBuilder::new(intrinsics)
let get_species = BuiltInBuilder::new(realm)
.callable(Self::get_species)
.name("get [Symbol.species]")
.build();

let get_byte_length = BuiltInBuilder::new(intrinsics)
let get_byte_length = BuiltInBuilder::new(realm)
.callable(Self::get_byte_length)
.name("get byteLength")
.build();

BuiltInBuilder::from_standard_constructor::<Self>(intrinsics)
BuiltInBuilder::from_standard_constructor::<Self>(realm)
.accessor(
utf16!("byteLength"),
Some(get_byte_length),
Expand Down
11 changes: 7 additions & 4 deletions boa_engine/src/builtins/async_function/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ use crate::{
builtins::{function::BuiltInFunctionObject, BuiltInObject},
context::intrinsics::{Intrinsics, StandardConstructor, StandardConstructors},
property::Attribute,
realm::Realm,
symbol::JsSymbol,
Context, JsResult, JsValue,
};
Expand All @@ -23,12 +24,14 @@ use super::{BuiltInBuilder, BuiltInConstructor, IntrinsicObject};
pub struct AsyncFunction;

impl IntrinsicObject for AsyncFunction {
fn init(intrinsics: &Intrinsics) {
fn init(realm: &Realm) {
let _timer = Profiler::global().start_event(Self::NAME, "init");

BuiltInBuilder::from_standard_constructor::<Self>(intrinsics)
.prototype(intrinsics.constructors().function().constructor())
.inherits(Some(intrinsics.constructors().function().prototype()))
BuiltInBuilder::from_standard_constructor::<Self>(realm)
.prototype(realm.intrinsics().constructors().function().constructor())
.inherits(Some(
realm.intrinsics().constructors().function().prototype(),
))
.property(
JsSymbol::to_string_tag(),
Self::NAME,
Expand Down
64 changes: 38 additions & 26 deletions boa_engine/src/builtins/async_generator/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ use crate::{
native_function::NativeFunction,
object::{FunctionObjectBuilder, JsObject, CONSTRUCTOR},
property::Attribute,
realm::Realm,
symbol::JsSymbol,
value::JsValue,
vm::GeneratorResumeKind,
Expand Down Expand Up @@ -66,11 +67,17 @@ pub struct AsyncGenerator {
}

impl IntrinsicObject for AsyncGenerator {
fn init(intrinsics: &Intrinsics) {
fn init(realm: &Realm) {
let _timer = Profiler::global().start_event(Self::NAME, "init");

BuiltInBuilder::with_intrinsic::<Self>(intrinsics)
.prototype(intrinsics.objects().iterator_prototypes().async_iterator())
BuiltInBuilder::with_intrinsic::<Self>(realm)
.prototype(
realm
.intrinsics()
.objects()
.iterator_prototypes()
.async_iterator(),
)
.static_method(Self::next, "next", 1)
.static_method(Self::r#return, "return", 1)
.static_method(Self::throw, "throw", 1)
Expand All @@ -81,7 +88,8 @@ impl IntrinsicObject for AsyncGenerator {
)
.static_property(
CONSTRUCTOR,
intrinsics
realm
.intrinsics()
.constructors()
.async_generator_function()
.prototype(),
Expand Down Expand Up @@ -399,6 +407,7 @@ impl AsyncGenerator {
next: &AsyncGeneratorRequest,
completion: JsResult<JsValue>,
done: bool,
realm: Option<Realm>,
context: &mut Context<'_>,
) {
// 1. Let queue be generator.[[AsyncGeneratorQueue]].
Expand All @@ -422,15 +431,24 @@ impl AsyncGenerator {
Ok(value) => {
// a. Assert: completion.[[Type]] is normal.

// TODO: Realm handling not implemented yet.
// b. If realm is present, then
// i. Let oldRealm be the running execution context's Realm.
// ii. Set the running execution context's Realm to realm.
// iii. Let iteratorResult be CreateIterResultObject(value, done).
// iv. Set the running execution context's Realm to oldRealm.
// c. Else,
// i. Let iteratorResult be CreateIterResultObject(value, done).
let iterator_result = create_iter_result_object(value, done, context);
let iterator_result = if let Some(realm) = realm {
// i. Let oldRealm be the running execution context's Realm.
// ii. Set the running execution context's Realm to realm.
let old_realm = context.enter_realm(realm);

// iii. Let iteratorResult be CreateIterResultObject(value, done).
let iterator_result = create_iter_result_object(value, done, context);

// iv. Set the running execution context's Realm to oldRealm.
context.enter_realm(old_realm);

iterator_result
} else {
// c. Else,
// i. Let iteratorResult be CreateIterResultObject(value, done).
create_iter_result_object(value, done, context)
};

// d. Perform ! Call(promiseCapability.[[Resolve]], undefined, « iteratorResult »).
promise_capability
Expand Down Expand Up @@ -474,18 +492,15 @@ impl AsyncGenerator {

// 6. Push genContext onto the execution context stack; genContext is now the running execution context.
std::mem::swap(
&mut context.realm.environments,
&mut context.vm.environments,
&mut generator_context.environments,
);
std::mem::swap(&mut context.vm.stack, &mut generator_context.stack);
std::mem::swap(
&mut context.vm.active_function,
&mut generator_context.active_function,
);
std::mem::swap(
&mut context.realm.intrinsics,
&mut generator_context.realm_intrinsics,
);
let old_realm = context.enter_realm(generator_context.realm.clone());

context.vm.push_frame(generator_context.call_frame.clone());

Expand All @@ -508,7 +523,7 @@ impl AsyncGenerator {
let result = context.run();

std::mem::swap(
&mut context.realm.environments,
&mut context.vm.environments,
&mut generator_context.environments,
);
std::mem::swap(&mut context.vm.stack, &mut generator_context.stack);
Expand All @@ -517,10 +532,7 @@ impl AsyncGenerator {
&mut context.vm.active_function,
&mut generator_context.active_function,
);
std::mem::swap(
&mut context.realm.intrinsics,
&mut generator_context.realm_intrinsics,
);
context.enter_realm(old_realm);

generator
.borrow_mut()
Expand Down Expand Up @@ -575,7 +587,7 @@ impl AsyncGenerator {
gen.context = None;
let next = gen.queue.pop_front().expect("queue must not be empty");
drop(generator_borrow_mut);
Self::complete_step(&next, Err(value), true, context);
Self::complete_step(&next, Err(value), true, None, context);
Self::drain_queue(&generator, context);
return;
}
Expand Down Expand Up @@ -604,7 +616,7 @@ impl AsyncGenerator {
let result = Ok(args.get_or_undefined(0).clone());

// c. Perform AsyncGeneratorCompleteStep(generator, result, true).
Self::complete_step(&next, result, true, context);
Self::complete_step(&next, result, true, None, context);

// d. Perform AsyncGeneratorDrainQueue(generator).
Self::drain_queue(generator, context);
Expand Down Expand Up @@ -640,7 +652,7 @@ impl AsyncGenerator {
// c. Perform AsyncGeneratorCompleteStep(generator, result, true).
let next = gen.queue.pop_front().expect("must have one entry");
drop(generator_borrow_mut);
Self::complete_step(&next, result, true, context);
Self::complete_step(&next, result, true, None, context);

// d. Perform AsyncGeneratorDrainQueue(generator).
Self::drain_queue(generator, context);
Expand Down Expand Up @@ -721,7 +733,7 @@ impl AsyncGenerator {

// ii. Perform AsyncGeneratorCompleteStep(generator, completion, true).
let next = queue.pop_front().expect("must have entry");
Self::complete_step(&next, completion, true, context);
Self::complete_step(&next, completion, true, None, context);

// iii. If queue is empty, set done to true.
if queue.is_empty() {
Expand Down
11 changes: 7 additions & 4 deletions boa_engine/src/builtins/async_generator_function/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ use crate::{
context::intrinsics::{Intrinsics, StandardConstructor, StandardConstructors},
object::{JsObject, PROTOTYPE},
property::Attribute,
realm::Realm,
symbol::JsSymbol,
value::JsValue,
Context, JsResult,
Expand All @@ -23,15 +24,17 @@ use super::{BuiltInBuilder, BuiltInConstructor, IntrinsicObject};
pub struct AsyncGeneratorFunction;

impl IntrinsicObject for AsyncGeneratorFunction {
fn init(intrinsics: &Intrinsics) {
fn init(realm: &Realm) {
let _timer = Profiler::global().start_event(Self::NAME, "init");

BuiltInBuilder::from_standard_constructor::<Self>(intrinsics)
.inherits(Some(intrinsics.constructors().function().prototype()))
BuiltInBuilder::from_standard_constructor::<Self>(realm)
.inherits(Some(
realm.intrinsics().constructors().function().prototype(),
))
.constructor_attributes(Attribute::CONFIGURABLE)
.property(
PROTOTYPE,
intrinsics.objects().async_generator(),
realm.intrinsics().objects().async_generator(),
Attribute::CONFIGURABLE,
)
.property(
Expand Down
5 changes: 3 additions & 2 deletions boa_engine/src/builtins/bigint/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ use crate::{
error::JsNativeError,
object::JsObject,
property::Attribute,
realm::Realm,
symbol::JsSymbol,
value::{IntegerOrInfinity, PreferredType},
Context, JsArgs, JsBigInt, JsResult, JsValue,
Expand All @@ -35,10 +36,10 @@ mod tests;
pub struct BigInt;

impl IntrinsicObject for BigInt {
fn init(intrinsics: &Intrinsics) {
fn init(realm: &Realm) {
let _timer = Profiler::global().start_event(Self::NAME, "init");

BuiltInBuilder::from_standard_constructor::<Self>(intrinsics)
BuiltInBuilder::from_standard_constructor::<Self>(realm)
.method(Self::to_string, "toString", 0)
.method(Self::value_of, "valueOf", 0)
.static_method(Self::as_int_n, "asIntN", 2)
Expand Down
5 changes: 3 additions & 2 deletions boa_engine/src/builtins/boolean/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ use crate::{
context::intrinsics::{Intrinsics, StandardConstructor, StandardConstructors},
error::JsNativeError,
object::{internal_methods::get_prototype_from_constructor, JsObject, ObjectData},
realm::Realm,
Context, JsResult, JsValue,
};
use boa_profiler::Profiler;
Expand All @@ -28,10 +29,10 @@ use super::{BuiltInBuilder, BuiltInConstructor, IntrinsicObject};
pub(crate) struct Boolean;

impl IntrinsicObject for Boolean {
fn init(intrinsics: &Intrinsics) {
fn init(realm: &Realm) {
let _timer = Profiler::global().start_event(Self::NAME, "init");

BuiltInBuilder::from_standard_constructor::<Self>(intrinsics)
BuiltInBuilder::from_standard_constructor::<Self>(realm)
.method(Self::to_string, "toString", 0)
.method(Self::value_of, "valueOf", 0)
.build();
Expand Down
Loading