Skip to content

Commit

Permalink
Remove redundant param_count field from CallFrame
Browse files Browse the repository at this point in the history
  • Loading branch information
HalidOdat committed May 25, 2023
1 parent 7ae8582 commit b2ec55c
Show file tree
Hide file tree
Showing 19 changed files with 88 additions and 103 deletions.
26 changes: 9 additions & 17 deletions boa_engine/src/vm/call_frame/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,18 +19,17 @@ pub(crate) use env_stack::EnvStackEntry;
#[derive(Clone, Debug, Finalize, Trace)]
pub struct CallFrame {
pub(crate) code_block: Gc<CodeBlock>,
pub(crate) pc: usize,
pub(crate) fp: usize,
pub(crate) pc: u32,
pub(crate) fp: u32,
#[unsafe_ignore_trace]
pub(crate) abrupt_completion: Option<AbruptCompletionRecord>,
#[unsafe_ignore_trace]
pub(crate) r#yield: bool,
pub(crate) pop_on_return: usize,
pub(crate) pop_on_return: u32,
// Tracks the number of environments in environment entry.
// On abrupt returns this is used to decide how many environments need to be pop'ed.
pub(crate) env_stack: Vec<EnvStackEntry>,
pub(crate) param_count: usize,
pub(crate) arg_count: usize,
pub(crate) argument_count: u32,
#[unsafe_ignore_trace]
pub(crate) generator_resume_kind: GeneratorResumeKind,
pub(crate) promise_capability: Option<PromiseCapability>,
Expand Down Expand Up @@ -68,8 +67,7 @@ impl CallFrame {
env_stack: Vec::from([EnvStackEntry::new(0, max_length)]),
abrupt_completion: None,
r#yield: false,
param_count: 0,
arg_count: 0,
argument_count: 0,
generator_resume_kind: GeneratorResumeKind::Normal,
promise_capability: None,
async_generator: None,
Expand All @@ -78,22 +76,16 @@ impl CallFrame {
}
}

/// Updates a `CallFrame`'s `param_count` field with the value provided.
pub(crate) fn with_param_count(mut self, count: usize) -> Self {
self.param_count = count;
self
}

/// Updates a `CallFrame`'s `arg_count` field with the value provided.
pub(crate) fn with_arg_count(mut self, count: usize) -> Self {
self.arg_count = count;
/// Updates a `CallFrame`'s `argument_count` field with the value provided.
pub(crate) fn with_argument_count(mut self, count: u32) -> Self {
self.argument_count = count;
self
}
}

/// ---- `CallFrame` stack methods ----
impl CallFrame {
pub(crate) fn set_frame_pointer(&mut self, pointer: usize) {
pub(crate) fn set_frame_pointer(&mut self, pointer: u32) {
self.fp = pointer;
}

Expand Down
19 changes: 6 additions & 13 deletions boa_engine/src/vm/code_block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1063,7 +1063,7 @@ impl JsObject {
);
}

let arg_count = args.len();
let argument_count = args.len();

// Push function arguments to the stack.
let mut args = if code.params.as_ref().len() > args.len() {
Expand All @@ -1081,11 +1081,7 @@ impl JsObject {

std::mem::swap(&mut context.vm.stack, &mut stack);

let param_count = code.params.as_ref().len();

let mut frame = CallFrame::new(code)
.with_param_count(param_count)
.with_arg_count(arg_count);
let mut frame = CallFrame::new(code).with_argument_count(argument_count as u32);
frame.promise_capability = promise_capability.clone();

std::mem::swap(&mut context.vm.active_runnable, &mut script_or_module);
Expand Down Expand Up @@ -1326,7 +1322,7 @@ impl JsObject {
);
}

let arg_count = args.len();
let argument_count = args.len();

// Push function arguments to the stack.
let args = if code.params.as_ref().len() > args.len() {
Expand All @@ -1344,16 +1340,13 @@ impl JsObject {
context.vm.push(arg.clone());
}

let param_count = code.params.as_ref().len();
let has_binding_identifier = code.has_binding_identifier;

std::mem::swap(&mut context.vm.active_runnable, &mut script_or_module);

context.vm.push_frame(
CallFrame::new(code)
.with_param_count(param_count)
.with_arg_count(arg_count),
);
context
.vm
.push_frame(CallFrame::new(code).with_argument_count(argument_count as u32));

let record = context.run();

Expand Down
22 changes: 12 additions & 10 deletions boa_engine/src/vm/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -114,8 +114,8 @@ impl Vm {

#[track_caller]
pub(crate) fn read<T: Readable>(&mut self) -> T {
let value = self.frame().code_block.read::<T>(self.frame().pc);
self.frame_mut().pc += size_of::<T>();
let value = self.frame().code_block.read::<T>(self.frame().pc as usize);
self.frame_mut().pc += size_of::<T>() as u32;
value
}

Expand Down Expand Up @@ -159,7 +159,7 @@ impl Context<'_> {
fn execute_instruction(&mut self) -> JsResult<CompletionType> {
let opcode: Opcode = {
let _timer = Profiler::global().start_event("Opcode retrieval", "vm");
let opcode = self.vm.frame().code_block.bytecode[self.vm.frame().pc]
let opcode = self.vm.frame().code_block.bytecode[self.vm.frame().pc as usize]
.try_into()
.expect("could not convert code at PC to opcode");
self.vm.frame_mut().pc += 1;
Expand Down Expand Up @@ -213,15 +213,17 @@ impl Context<'_> {
}

let current_stack_length = self.vm.stack.len();
self.vm.frame_mut().set_frame_pointer(current_stack_length);
self.vm
.frame_mut()
.set_frame_pointer(current_stack_length as u32);

// If the current executing function is an async function we have to resolve/reject it's promise at the end.
// The relevant spec section is 3. in [AsyncBlockStart](https://tc39.es/ecma262/#sec-asyncblockstart).
let promise_capability = self.vm.frame().promise_capability.clone();

let execution_completion = loop {
// 1. Exit the execution loop if program counter ever is equal to or exceeds the amount of instructions
if self.vm.frame().code_block.bytecode.len() <= self.vm.frame().pc {
if self.vm.frame().code_block.bytecode.len() <= self.vm.frame().pc as usize {
break CompletionType::Normal;
}

Expand All @@ -238,7 +240,7 @@ impl Context<'_> {
// 1. Run the next instruction.
#[cfg(feature = "trace")]
let result = if self.vm.trace || self.vm.frame().code_block.trace.get() {
let mut pc = self.vm.frame().pc;
let mut pc = self.vm.frame().pc as usize;
let opcode: Opcode = self
.vm
.frame()
Expand Down Expand Up @@ -357,18 +359,18 @@ impl Context<'_> {
// Determine the execution result
let execution_result = if execution_completion == CompletionType::Throw {
self.vm.frame_mut().abrupt_completion = None;
self.vm.stack.truncate(self.vm.frame().fp);
self.vm.stack.truncate(self.vm.frame().fp as usize);
JsValue::undefined()
} else if execution_completion == CompletionType::Return {
self.vm.frame_mut().abrupt_completion = None;
let result = self.vm.pop();
self.vm.stack.truncate(self.vm.frame().fp);
self.vm.stack.truncate(self.vm.frame().fp as usize);
result
} else if self.vm.stack.len() <= self.vm.frame().fp {
} else if self.vm.stack.len() <= self.vm.frame().fp as usize {
JsValue::undefined()
} else {
let result = self.vm.pop();
self.vm.stack.truncate(self.vm.frame().fp);
self.vm.stack.truncate(self.vm.frame().fp as usize);
result
};

Expand Down
6 changes: 3 additions & 3 deletions boa_engine/src/vm/opcode/binary_ops/logical.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ impl Operation for LogicalAnd {
let exit = context.vm.read::<u32>();
let lhs = context.vm.pop();
if !lhs.to_boolean() {
context.vm.frame_mut().pc = exit as usize;
context.vm.frame_mut().pc = exit;
context.vm.push(lhs);
}
Ok(CompletionType::Normal)
Expand All @@ -40,7 +40,7 @@ impl Operation for LogicalOr {
let exit = context.vm.read::<u32>();
let lhs = context.vm.pop();
if lhs.to_boolean() {
context.vm.frame_mut().pc = exit as usize;
context.vm.frame_mut().pc = exit;
context.vm.push(lhs);
}
Ok(CompletionType::Normal)
Expand All @@ -62,7 +62,7 @@ impl Operation for Coalesce {
let exit = context.vm.read::<u32>();
let lhs = context.vm.pop();
if !lhs.is_null_or_undefined() {
context.vm.frame_mut().pc = exit as usize;
context.vm.frame_mut().pc = exit;
context.vm.push(lhs);
}
Ok(CompletionType::Normal)
Expand Down
2 changes: 1 addition & 1 deletion boa_engine/src/vm/opcode/control_flow/break.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ impl Operation for Break {
context.vm.frame_mut().abrupt_completion = Some(new_record);

// 3. Set program counter and finally return fields.
context.vm.frame_mut().pc = jump_address as usize;
context.vm.frame_mut().pc = jump_address;
Ok(CompletionType::Normal)
}
}
2 changes: 1 addition & 1 deletion boa_engine/src/vm/opcode/control_flow/catch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ impl Operation for CatchStart {
const INSTRUCTION: &'static str = "INST - CatchStart";

fn execute(context: &mut Context<'_>) -> JsResult<CompletionType> {
let start = context.vm.frame().pc as u32 - 1;
let start = context.vm.frame().pc - 1;
let finally = context.vm.read::<u32>();

context
Expand Down
2 changes: 1 addition & 1 deletion boa_engine/src/vm/opcode/control_flow/continue.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ impl Operation for Continue {
context.vm.frame_mut().abrupt_completion = Some(new_record);

// 3. Set program counter and finally return fields.
context.vm.frame_mut().pc = jump_address as usize;
context.vm.frame_mut().pc = jump_address;
Ok(CompletionType::Normal)
}
}
28 changes: 13 additions & 15 deletions boa_engine/src/vm/opcode/control_flow/finally.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,12 @@ impl Operation for FinallyEnd {
const INSTRUCTION: &'static str = "INST - FinallyEnd";

fn execute(context: &mut Context<'_>) -> JsResult<CompletionType> {
let finally_candidates = context.vm.frame().env_stack.iter().filter(|env| {
env.is_finally_env() && context.vm.frame().pc < (env.start_address() as usize)
});
let finally_candidates = context
.vm
.frame()
.env_stack
.iter()
.filter(|env| env.is_finally_env() && context.vm.frame().pc < env.start_address());

let next_finally = match finally_candidates.last() {
Some(env) => env.start_address(),
Expand All @@ -53,7 +56,7 @@ impl Operation for FinallyEnd {
let mut envs_to_pop = 0;
match context.vm.frame().abrupt_completion {
Some(record) if next_finally < record.target() => {
context.vm.frame_mut().pc = next_finally as usize;
context.vm.frame_mut().pc = next_finally;

while let Some(env_entry) = context.vm.frame().env_stack.last() {
if next_finally <= env_entry.exit_address() {
Expand All @@ -67,11 +70,9 @@ impl Operation for FinallyEnd {
let env_truncation_len = context.vm.environments.len().saturating_sub(envs_to_pop);
context.vm.environments.truncate(env_truncation_len);
}
Some(record)
if record.is_break() && context.vm.frame().pc < record.target() as usize =>
{
Some(record) if record.is_break() && context.vm.frame().pc < record.target() => {
// handle the continuation of an abrupt break.
context.vm.frame_mut().pc = record.target() as usize;
context.vm.frame_mut().pc = record.target();
while let Some(env_entry) = context.vm.frame().env_stack.last() {
if record.target() == env_entry.exit_address() {
break;
Expand All @@ -86,11 +87,9 @@ impl Operation for FinallyEnd {
let env_truncation_len = context.vm.environments.len().saturating_sub(envs_to_pop);
context.vm.environments.truncate(env_truncation_len);
}
Some(record)
if record.is_continue() && context.vm.frame().pc > record.target() as usize =>
{
Some(record) if record.is_continue() && context.vm.frame().pc > record.target() => {
// Handle the continuation of an abrupt continue
context.vm.frame_mut().pc = record.target() as usize;
context.vm.frame_mut().pc = record.target();
while let Some(env_entry) = context.vm.frame().env_stack.last() {
if env_entry.start_address() == record.target() {
break;
Expand All @@ -107,10 +106,9 @@ impl Operation for FinallyEnd {
return Ok(CompletionType::Return);
}
Some(record)
if record.is_throw_with_target()
&& context.vm.frame().pc < record.target() as usize =>
if record.is_throw_with_target() && context.vm.frame().pc < record.target() =>
{
context.vm.frame_mut().pc = record.target() as usize;
context.vm.frame_mut().pc = record.target();
while let Some(env_entry) = context.vm.frame_mut().env_stack.pop() {
envs_to_pop += env_entry.env_num();
if env_entry.start_address() == record.target() {
Expand Down
2 changes: 1 addition & 1 deletion boa_engine/src/vm/opcode/control_flow/labelled.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ impl Operation for LabelledStart {
const INSTRUCTION: &'static str = "INST - LabelledStart";

fn execute(context: &mut Context<'_>) -> JsResult<CompletionType> {
let start = context.vm.frame().pc as u32 - 1;
let start = context.vm.frame().pc - 1;
let end = context.vm.read::<u32>();
context
.vm
Expand Down
6 changes: 3 additions & 3 deletions boa_engine/src/vm/opcode/control_flow/return.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,10 @@ impl Operation for Return {
let mut finally_address = None;
while let Some(env_entry) = context.vm.frame().env_stack.last() {
if env_entry.is_finally_env() {
if (env_entry.start_address() as usize) < current_address {
finally_address = Some(env_entry.exit_address() as usize);
if env_entry.start_address() < current_address {
finally_address = Some(env_entry.exit_address());
} else {
finally_address = Some(env_entry.start_address() as usize);
finally_address = Some(env_entry.start_address());
}
break;
}
Expand Down
14 changes: 7 additions & 7 deletions boa_engine/src/vm/opcode/control_flow/throw.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ impl Operation for Throw {
context.vm.frame_mut().env_stack.pop();
break;
} else if env_entry.is_finally_env() {
if current_address > (env_entry.start_address() as usize) {
if current_address > env_entry.start_address() {
target_address = env_entry.exit_address();
} else {
target_address = env_entry.start_address();
Expand All @@ -79,9 +79,9 @@ impl Operation for Throw {
context.vm.environments.truncate(env_truncation_len);

if target_address == catch_target {
context.vm.frame_mut().pc = catch_target as usize;
context.vm.frame_mut().pc = catch_target;
} else {
context.vm.frame_mut().pc = target_address as usize;
context.vm.frame_mut().pc = target_address;
};

for _ in 0..context.vm.frame().pop_on_return {
Expand All @@ -101,10 +101,10 @@ impl Operation for Throw {
let mut env_stack_to_pop = 0;
for env_entry in context.vm.frame_mut().env_stack.iter_mut().rev() {
if env_entry.is_finally_env() {
if (env_entry.start_address() as usize) < current_address {
target_address = Some(env_entry.exit_address() as usize);
if env_entry.start_address() < current_address {
target_address = Some(env_entry.exit_address());
} else {
target_address = Some(env_entry.start_address() as usize);
target_address = Some(env_entry.start_address());
}
break;
};
Expand Down Expand Up @@ -133,7 +133,7 @@ impl Operation for Throw {
.vm
.stack
.len()
.saturating_sub(context.vm.frame().pop_on_return);
.saturating_sub(context.vm.frame().pop_on_return as usize);
context.vm.stack.truncate(previous_stack_size);
context.vm.frame_mut().pop_on_return = 0;

Expand Down
4 changes: 2 additions & 2 deletions boa_engine/src/vm/opcode/environment/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -220,8 +220,8 @@ impl Operation for SuperCallDerived {
const INSTRUCTION: &'static str = "INST - SuperCallDerived";

fn execute(context: &mut Context<'_>) -> JsResult<CompletionType> {
let argument_count = context.vm.frame().arg_count;
let mut arguments = Vec::with_capacity(argument_count);
let argument_count = context.vm.frame().argument_count;
let mut arguments = Vec::with_capacity(argument_count as usize);
for _ in 0..argument_count {
arguments.push(context.vm.pop());
}
Expand Down
Loading

0 comments on commit b2ec55c

Please sign in to comment.