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

Store active runnable and active function in CallFrame #3197

Merged
merged 5 commits into from
Sep 16, 2023
Merged
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
4 changes: 1 addition & 3 deletions boa_engine/src/builtins/array/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -174,9 +174,7 @@ impl BuiltInConstructor for Array {
// If NewTarget is undefined, let newTarget be the active function object; else let newTarget be NewTarget.
let new_target = &if new_target.is_undefined() {
context
.vm
.active_function
.clone()
.active_function_object()
.unwrap_or_else(|| context.intrinsics().constructors().array().constructor())
.into()
} else {
Expand Down
2 changes: 1 addition & 1 deletion boa_engine/src/builtins/async_function/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ impl BuiltInConstructor for AsyncFunction {
args: &[JsValue],
context: &mut Context<'_>,
) -> JsResult<JsValue> {
let active_function = context.vm.active_function.clone().unwrap_or_else(|| {
let active_function = context.active_function_object().unwrap_or_else(|| {
context
.intrinsics()
.constructors()
Expand Down
2 changes: 1 addition & 1 deletion boa_engine/src/builtins/async_generator_function/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ impl BuiltInConstructor for AsyncGeneratorFunction {
args: &[JsValue],
context: &mut Context<'_>,
) -> JsResult<JsValue> {
let active_function = context.vm.active_function.clone().unwrap_or_else(|| {
let active_function = context.active_function_object().unwrap_or_else(|| {
context
.intrinsics()
.constructors()
Expand Down
4 changes: 1 addition & 3 deletions boa_engine/src/builtins/error/aggregate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,9 +63,7 @@ impl BuiltInConstructor for AggregateError {
// 1. If NewTarget is undefined, let newTarget be the active function object; else let newTarget be NewTarget.
let new_target = &if new_target.is_undefined() {
context
.vm
.active_function
.clone()
.active_function_object()
.unwrap_or_else(|| {
context
.intrinsics()
Expand Down
4 changes: 1 addition & 3 deletions boa_engine/src/builtins/error/eval.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,9 +65,7 @@ impl BuiltInConstructor for EvalError {
// 1. If NewTarget is undefined, let newTarget be the active function object; else let newTarget be NewTarget.
let new_target = &if new_target.is_undefined() {
context
.vm
.active_function
.clone()
.active_function_object()
.unwrap_or_else(|| {
context
.intrinsics()
Expand Down
4 changes: 1 addition & 3 deletions boa_engine/src/builtins/error/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -165,9 +165,7 @@ impl BuiltInConstructor for Error {
// 1. If NewTarget is undefined, let newTarget be the active function object; else let newTarget be NewTarget.
let new_target = &if new_target.is_undefined() {
context
.vm
.active_function
.clone()
.active_function_object()
.unwrap_or_else(|| context.intrinsics().constructors().error().constructor())
.into()
} else {
Expand Down
4 changes: 1 addition & 3 deletions boa_engine/src/builtins/error/range.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,9 +63,7 @@ impl BuiltInConstructor for RangeError {
// 1. If NewTarget is undefined, let newTarget be the active function object; else let newTarget be NewTarget.
let new_target = &if new_target.is_undefined() {
context
.vm
.active_function
.clone()
.active_function_object()
.unwrap_or_else(|| {
context
.intrinsics()
Expand Down
4 changes: 1 addition & 3 deletions boa_engine/src/builtins/error/reference.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,7 @@ impl BuiltInConstructor for ReferenceError {
// 1. If NewTarget is undefined, let newTarget be the active function object; else let newTarget be NewTarget.
let new_target = &if new_target.is_undefined() {
context
.vm
.active_function
.clone()
.active_function_object()
.unwrap_or_else(|| {
context
.intrinsics()
Expand Down
4 changes: 1 addition & 3 deletions boa_engine/src/builtins/error/syntax.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,9 +65,7 @@ impl BuiltInConstructor for SyntaxError {
// 1. If NewTarget is undefined, let newTarget be the active function object; else let newTarget be NewTarget.
let new_target = &if new_target.is_undefined() {
context
.vm
.active_function
.clone()
.active_function_object()
.unwrap_or_else(|| {
context
.intrinsics()
Expand Down
4 changes: 1 addition & 3 deletions boa_engine/src/builtins/error/type.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,9 +73,7 @@ impl BuiltInConstructor for TypeError {
// 1. If NewTarget is undefined, let newTarget be the active function object; else let newTarget be NewTarget.
let new_target = &if new_target.is_undefined() {
context
.vm
.active_function
.clone()
.active_function_object()
.unwrap_or_else(|| {
context
.intrinsics()
Expand Down
4 changes: 1 addition & 3 deletions boa_engine/src/builtins/error/uri.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,9 +64,7 @@ impl BuiltInConstructor for UriError {
// 1. If NewTarget is undefined, let newTarget be the active function object; else let newTarget be NewTarget.
let new_target = &if new_target.is_undefined() {
context
.vm
.active_function
.clone()
.active_function_object()
.unwrap_or_else(|| {
context
.intrinsics()
Expand Down
2 changes: 1 addition & 1 deletion boa_engine/src/builtins/eval/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,7 @@ impl Eval {
let env_fp = context.vm.environments.len() as u32;
context
.vm
.push_frame(CallFrame::new(code_block).with_env_fp(env_fp));
.push_frame(CallFrame::new(code_block, None, None).with_env_fp(env_fp));
context.realm().resize_global_env();

let record = context.run();
Expand Down
4 changes: 1 addition & 3 deletions boa_engine/src/builtins/function/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -532,9 +532,7 @@ impl BuiltInConstructor for BuiltInFunctionObject {
context: &mut Context<'_>,
) -> JsResult<JsValue> {
let active_function = context
.vm
.active_function
.clone()
.active_function_object()
.unwrap_or_else(|| context.intrinsics().constructors().function().constructor());
Self::create_dynamic_function(active_function, new_target, args, false, false, context)
.map(Into::into)
Expand Down
6 changes: 0 additions & 6 deletions boa_engine/src/builtins/generator/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,6 @@ unsafe impl Trace for GeneratorState {
pub(crate) struct GeneratorContext {
pub(crate) environments: EnvironmentStack,
pub(crate) stack: Vec<JsValue>,
pub(crate) active_function: Option<JsObject>,
pub(crate) call_frame: Option<CallFrame>,
pub(crate) realm: Realm,
}
Expand All @@ -70,14 +69,12 @@ impl GeneratorContext {
pub(crate) fn new(
environments: EnvironmentStack,
stack: Vec<JsValue>,
active_function: Option<JsObject>,
call_frame: CallFrame,
realm: Realm,
) -> Self {
Self {
environments,
stack,
active_function,
call_frame: Some(call_frame),
realm,
}
Expand All @@ -90,7 +87,6 @@ impl GeneratorContext {
environments: context.vm.environments.clone(),
call_frame: Some(context.vm.frame().clone()),
stack: context.vm.stack[fp..].to_vec(),
active_function: context.vm.active_function.clone(),
realm: context.realm().clone(),
};

Expand All @@ -108,7 +104,6 @@ impl GeneratorContext {
) -> CompletionRecord {
std::mem::swap(&mut context.vm.environments, &mut self.environments);
std::mem::swap(&mut context.vm.stack, &mut self.stack);
std::mem::swap(&mut context.vm.active_function, &mut self.active_function);
context.swap_realm(&mut self.realm);
context
.vm
Expand All @@ -125,7 +120,6 @@ impl GeneratorContext {

std::mem::swap(&mut context.vm.environments, &mut self.environments);
std::mem::swap(&mut context.vm.stack, &mut self.stack);
std::mem::swap(&mut context.vm.active_function, &mut self.active_function);
context.swap_realm(&mut self.realm);
self.call_frame = context.vm.pop_frame();
assert!(self.call_frame.is_some());
Expand Down
2 changes: 1 addition & 1 deletion boa_engine/src/builtins/generator_function/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ impl BuiltInConstructor for GeneratorFunction {
args: &[JsValue],
context: &mut Context<'_>,
) -> JsResult<JsValue> {
let active_function = context.vm.active_function.clone().unwrap_or_else(|| {
let active_function = context.active_function_object().unwrap_or_else(|| {
context
.intrinsics()
.constructors()
Expand Down
4 changes: 1 addition & 3 deletions boa_engine/src/builtins/intl/collator/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -216,9 +216,7 @@ impl BuiltInConstructor for Collator {
// 1. If NewTarget is undefined, let newTarget be the active function object, else let newTarget be NewTarget.
let new_target = &if new_target.is_undefined() {
context
.vm
.active_function
.clone()
.active_function_object()
.unwrap_or_else(|| context.intrinsics().constructors().collator().constructor())
.into()
} else {
Expand Down
4 changes: 1 addition & 3 deletions boa_engine/src/builtins/intl/date_time_format.rs
Original file line number Diff line number Diff line change
Expand Up @@ -99,9 +99,7 @@ impl BuiltInConstructor for DateTimeFormat {
// 1. If NewTarget is undefined, let newTarget be the active function object, else let newTarget be NewTarget.
let new_target = &if new_target.is_undefined() {
context
.vm
.active_function
.clone()
.active_function_object()
.unwrap_or_else(|| {
context
.intrinsics()
Expand Down
2 changes: 1 addition & 1 deletion boa_engine/src/builtins/json/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ impl Json {
let env_fp = context.vm.environments.len() as u32;
context
.vm
.push_frame(CallFrame::new(code_block).with_env_fp(env_fp));
.push_frame(CallFrame::new(code_block, None, None).with_env_fp(env_fp));
context.realm().resize_global_env();
let record = context.run();
context.vm.pop_frame();
Expand Down
4 changes: 1 addition & 3 deletions boa_engine/src/builtins/object/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -131,9 +131,7 @@ impl BuiltInConstructor for Object {
if !new_target.is_undefined()
&& new_target
!= &context
.vm
.active_function
.clone()
.active_function_object()
.unwrap_or_else(|| context.intrinsics().constructors().object().constructor())
.into()
{
Expand Down
4 changes: 1 addition & 3 deletions boa_engine/src/builtins/regexp/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -172,9 +172,7 @@ impl BuiltInConstructor for RegExp {
if new_target.is_undefined() {
// a. Let newTarget be the active function object.
let new_target = context
.vm
.active_function
.clone()
.active_function_object()
.map_or(JsValue::undefined(), JsValue::new);

// b. If patternIsRegExp is true and flags is undefined, then
Expand Down
37 changes: 36 additions & 1 deletion boa_engine/src/context/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ use crate::{
property::{Attribute, PropertyDescriptor, PropertyKey},
realm::Realm,
script::Script,
vm::{CallFrame, Vm},
vm::{ActiveRunnable, CallFrame, Vm},
JsResult, JsValue, Source,
};
use boa_ast::{expression::Identifier, StatementList};
Expand Down Expand Up @@ -706,6 +706,41 @@ impl Context<'_> {
pub(crate) const fn is_strict(&self) -> bool {
self.strict
}

/// `9.4.1 GetActiveScriptOrModule ( )`
///
/// More information:
/// - [ECMAScript reference][spec]
///
/// [spec]: https://tc39.es/ecma262/#sec-getactivescriptormodule
pub(crate) fn get_active_script_or_module(&self) -> Option<ActiveRunnable> {
// 1. If the execution context stack is empty, return null.
// 2. Let ec be the topmost execution context on the execution context stack whose ScriptOrModule component is not null.
// 3. If no such execution context exists, return null. Otherwise, return ec's ScriptOrModule.
self.vm
.frames
.iter()
.rev()
.find_map(|frame| frame.active_runnable.clone())
}

/// Get `active function object`
///
/// More information:
/// - [ECMAScript reference][spec]
///
/// [spec]: https://tc39.es/ecma262/#active-function-object
pub(crate) fn active_function_object(&self) -> Option<JsObject> {
if self.vm.native_active_function.is_some() {
return self.vm.native_active_function.clone();
}

if let Some(frame) = self.vm.frames.last() {
return frame.active_function.clone();
}

None
}
}

impl<'host> Context<'host> {
Expand Down
11 changes: 2 additions & 9 deletions boa_engine/src/job.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ use std::{any::Any, cell::RefCell, collections::VecDeque, fmt::Debug, future::Fu
use crate::{
object::{JsFunction, NativeObject},
realm::Realm,
vm::ActiveRunnable,
Context, JsResult, JsValue,
};
use boa_gc::{Finalize, Trace};
Expand Down Expand Up @@ -69,7 +68,6 @@ pub struct NativeJob {
#[allow(clippy::type_complexity)]
f: Box<dyn FnOnce(&mut Context<'_>) -> JsResult<JsValue>>,
realm: Option<Realm>,
active_runnable: Option<ActiveRunnable>,
}

impl Debug for NativeJob {
Expand All @@ -87,19 +85,17 @@ impl NativeJob {
Self {
f: Box::new(f),
realm: None,
active_runnable: None,
}
}

/// Creates a new `NativeJob` from a closure and an execution realm.
pub fn with_realm<F>(f: F, realm: Realm, context: &mut Context<'_>) -> Self
pub fn with_realm<F>(f: F, realm: Realm, _context: &mut Context<'_>) -> Self
where
F: FnOnce(&mut Context<'_>) -> JsResult<JsValue> + 'static,
{
Self {
f: Box::new(f),
realm: Some(realm),
active_runnable: context.vm.active_runnable.clone(),
}
}

Expand All @@ -115,7 +111,7 @@ impl NativeJob {
///
/// If the native job has an execution realm defined, this sets the running execution
/// context to the realm's before calling the inner closure, and resets it after execution.
pub fn call(mut self, context: &mut Context<'_>) -> JsResult<JsValue> {
pub fn call(self, context: &mut Context<'_>) -> JsResult<JsValue> {
// If realm is not null, each time job is invoked the implementation must perform
// implementation-defined steps such that execution is prepared to evaluate ECMAScript
// code at the time of job's invocation.
Expand All @@ -126,12 +122,9 @@ impl NativeJob {
// invoked. If realm is not null, each time job is invoked the implementation must
// perform implementation-defined steps such that scriptOrModule is the active script or
// module at the time of job's invocation.
std::mem::swap(&mut context.vm.active_runnable, &mut self.active_runnable);

let result = (self.f)(context);

context.enter_realm(old_realm);
std::mem::swap(&mut context.vm.active_runnable, &mut self.active_runnable);

result
} else {
Expand Down
Loading