Skip to content

Commit

Permalink
Remove GetArrowFunction opcode
Browse files Browse the repository at this point in the history
  • Loading branch information
HalidOdat committed Oct 30, 2023
1 parent 228bc72 commit 31d0412
Show file tree
Hide file tree
Showing 9 changed files with 55 additions and 138 deletions.
25 changes: 5 additions & 20 deletions boa_engine/src/bytecompiler/class.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,10 +88,7 @@ impl ByteCompiler<'_, '_> {

let code = Gc::new(compiler.finish());
let index = self.push_function_to_constants(code);
self.emit(
Opcode::GetFunction,
&[Operand::Varying(index), Operand::Bool(false)],
);
self.emit_with_varying_operand(Opcode::GetFunction, index);

self.emit_opcode(Opcode::Dup);
if let Some(node) = class.super_ref() {
Expand Down Expand Up @@ -301,10 +298,7 @@ impl ByteCompiler<'_, '_> {

let code = Gc::new(field_compiler.finish());
let index = self.push_function_to_constants(code);
self.emit(
Opcode::GetFunction,
&[Operand::Varying(index), Operand::Bool(false)],
);
self.emit_with_varying_operand(Opcode::GetFunction, index);
self.emit_opcode(Opcode::PushClassField);
}
ClassElement::PrivateFieldDefinition(name, field) => {
Expand All @@ -330,10 +324,7 @@ impl ByteCompiler<'_, '_> {

let code = Gc::new(field_compiler.finish());
let index = self.push_function_to_constants(code);
self.emit(
Opcode::GetFunction,
&[Operand::Varying(index), Operand::Bool(false)],
);
self.emit_with_varying_operand(Opcode::GetFunction, index);
self.emit_with_varying_operand(Opcode::PushClassFieldPrivate, name_index);
}
ClassElement::StaticFieldDefinition(name, field) => {
Expand Down Expand Up @@ -554,10 +545,7 @@ impl ByteCompiler<'_, '_> {
StaticElement::StaticBlock(code) => {
self.emit_opcode(Opcode::Dup);
let index = self.push_function_to_constants(code);
self.emit(
Opcode::GetFunction,
&[Operand::Varying(index), Operand::Bool(false)],
);
self.emit_with_varying_operand(Opcode::GetFunction, index);
self.emit_opcode(Opcode::SetHomeObject);
self.emit_with_varying_operand(Opcode::Call, 0);
self.emit_opcode(Opcode::Pop);
Expand All @@ -566,10 +554,7 @@ impl ByteCompiler<'_, '_> {
self.emit_opcode(Opcode::Dup);
self.emit_opcode(Opcode::Dup);
let index = self.push_function_to_constants(code);
self.emit(
Opcode::GetFunction,
&[Operand::Varying(index), Operand::Bool(false)],
);
self.emit_with_varying_operand(Opcode::GetFunction, index);
self.emit_opcode(Opcode::SetHomeObject);
self.emit_with_varying_operand(Opcode::Call, 0);
if let Some(name_index) = name_index {
Expand Down
9 changes: 3 additions & 6 deletions boa_engine/src/bytecompiler/declarations.rs
Original file line number Diff line number Diff line change
Expand Up @@ -282,7 +282,7 @@ impl ByteCompiler<'_, '_> {
let _ = self.push_function_to_constants(code.clone());

// b. Let fo be InstantiateFunctionObject of f with arguments env and privateEnv.
let function = create_function_object_fast(code, false, self.context);
let function = create_function_object_fast(code, self.context);

// c. Perform ? env.CreateGlobalFunctionBinding(fn, fo, false).
self.context
Expand Down Expand Up @@ -729,7 +729,7 @@ impl ByteCompiler<'_, '_> {
let _ = self.push_function_to_constants(code.clone());

// b. Let fo be InstantiateFunctionObject of f with arguments lexEnv and privateEnv.
let function = create_function_object_fast(code, false, self.context);
let function = create_function_object_fast(code, self.context);

// i. Perform ? varEnv.CreateGlobalFunctionBinding(fn, fo, true).
self.context
Expand All @@ -739,10 +739,7 @@ impl ByteCompiler<'_, '_> {
else {
// b. Let fo be InstantiateFunctionObject of f with arguments lexEnv and privateEnv.
let index = self.push_function_to_constants(code);
self.emit(
Opcode::GetFunction,
&[Operand::Varying(index), Operand::Bool(false)],
);
self.emit_with_varying_operand(Opcode::GetFunction, index);

// i. Let bindingExists be ! varEnv.HasBinding(fn).
let binding_exists = var_env.has_binding(name);
Expand Down
14 changes: 11 additions & 3 deletions boa_engine/src/bytecompiler/function.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ pub(crate) struct FunctionCompiler {
r#async: bool,
strict: bool,
arrow: bool,
method: bool,
binding_identifier: Option<Sym>,
}

Expand All @@ -32,6 +33,7 @@ impl FunctionCompiler {
r#async: false,
strict: false,
arrow: false,
method: false,
binding_identifier: None,
}
}
Expand All @@ -53,6 +55,11 @@ impl FunctionCompiler {
self.arrow = arrow;
self
}
/// Indicate if the function is a method function.
pub(crate) const fn method(mut self, method: bool) -> Self {
self.method = method;
self
}
/// Indicate if the function is a generator function.
pub(crate) const fn generator(mut self, generator: bool) -> Self {
self.generator = generator;
Expand Down Expand Up @@ -105,9 +112,10 @@ impl FunctionCompiler {
compiler
.code_block_flags
.set(CodeBlockFlags::IS_GENERATOR, self.generator);
compiler
.code_block_flags
.set(CodeBlockFlags::IS_ARROW, self.arrow);
compiler.code_block_flags.set(
CodeBlockFlags::HAS_PROTOTYPE_PROPERTY,
!self.arrow && !self.method,
);

if self.arrow {
compiler.this_mode = ThisMode::Lexical;
Expand Down
34 changes: 6 additions & 28 deletions boa_engine/src/bytecompiler/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -299,6 +299,7 @@ impl<'ctx, 'host> ByteCompiler<'ctx, 'host> {
) -> ByteCompiler<'ctx, 'host> {
let mut code_block_flags = CodeBlockFlags::empty();
code_block_flags.set(CodeBlockFlags::STRICT, strict);
code_block_flags |= CodeBlockFlags::HAS_PROTOTYPE_PROPERTY;
Self {
function_name: name,
length: 0,
Expand Down Expand Up @@ -1253,18 +1254,9 @@ impl<'ctx, 'host> ByteCompiler<'ctx, 'host> {
use_expr: bool,
) {
let name = function.name;
let arrow = function.kind.is_arrow();

let index = self.function(function);

if arrow {
self.emit(Opcode::GetArrowFunction, &[Operand::Varying(index)]);
} else {
self.emit(
Opcode::GetFunction,
&[Operand::Varying(index), Operand::Bool(false)],
);
}
self.emit_with_varying_operand(Opcode::GetFunction, index);

match node_kind {
NodeKind::Declaration => {
Expand Down Expand Up @@ -1312,6 +1304,7 @@ impl<'ctx, 'host> ByteCompiler<'ctx, 'host> {
.r#async(r#async)
.strict(self.strict())
.arrow(arrow)
.method(true)
.binding_identifier(binding_identifier)
.compile(
parameters,
Expand All @@ -1322,15 +1315,7 @@ impl<'ctx, 'host> ByteCompiler<'ctx, 'host> {
);

let index = self.push_function_to_constants(code);

if arrow {
self.emit(Opcode::GetArrowFunction, &[Operand::Varying(index)]);
} else {
self.emit(
Opcode::GetFunction,
&[Operand::Varying(index), Operand::Bool(true)],
);
}
self.emit_with_varying_operand(Opcode::GetFunction, index);
}

/// Compile a class method AST Node into bytecode.
Expand Down Expand Up @@ -1364,6 +1349,7 @@ impl<'ctx, 'host> ByteCompiler<'ctx, 'host> {
.r#async(r#async)
.strict(true)
.arrow(arrow)
.method(true)
.binding_identifier(binding_identifier)
.compile(
parameters,
Expand All @@ -1374,15 +1360,7 @@ impl<'ctx, 'host> ByteCompiler<'ctx, 'host> {
);

let index = self.push_function_to_constants(code);

if arrow {
self.emit(Opcode::GetArrowFunction, &[Operand::Varying(index)]);
} else {
self.emit(
Opcode::GetFunction,
&[Operand::Varying(index), Operand::Bool(true)],
);
}
self.emit_with_varying_operand(Opcode::GetFunction, index);
}

fn call(&mut self, callable: Callable<'_>, use_expr: bool) {
Expand Down
2 changes: 1 addition & 1 deletion boa_engine/src/module/source.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1655,7 +1655,7 @@ impl SourceTextModule {
for (index, locator) in functions {
let code = codeblock.constant_function(index as usize);

let function = create_function_object_fast(code, false, context);
let function = create_function_object_fast(code, context);

context.vm.environments.put_lexical_value(
locator.environment_index(),
Expand Down
36 changes: 17 additions & 19 deletions boa_engine/src/vm/code_block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,9 @@ bitflags! {

const IS_ASYNC = 0b1000_0000;
const IS_GENERATOR = 0b0001_0000_0000;
const IS_ARROW = 0b0010_0000_0000;

/// Arrow and method functions don't have `"prototype"` property.
const HAS_PROTOTYPE_PROPERTY = 0b0010_0000_0000;

/// Trace instruction execution to `stdout`.
#[cfg(feature = "trace")]
Expand Down Expand Up @@ -268,9 +270,11 @@ impl CodeBlock {
!self.is_async() && !self.is_generator()
}

/// Returns true if this function an arrow function.
pub(crate) fn is_arrow(&self) -> bool {
self.flags.get().contains(CodeBlockFlags::IS_ARROW)
/// Returns true if this function has the `"prototype"` property when function object is created.
pub(crate) fn has_prototype_property(&self) -> bool {
self.flags
.get()
.contains(CodeBlockFlags::HAS_PROTOTYPE_PROPERTY)
}

/// Find exception [`Handler`] in the code block given the current program counter (`pc`).
Expand Down Expand Up @@ -453,15 +457,7 @@ impl CodeBlock {
Instruction::TemplateCreate { count, site } => {
format!("{}, {site}", count.value())
}
Instruction::GetFunction { index, method } => {
let index = index.value() as usize;
format!(
"{index:04}: '{}' (length: {}), method: {method}",
self.constant_function(index).name().to_std_string_escaped(),
self.constant_function(index).length
)
}
Instruction::GetArrowFunction { index } => {
Instruction::GetFunction { index } => {
let index = index.value() as usize;
format!(
"{index:04}: '{}' (length: {})",
Expand Down Expand Up @@ -714,7 +710,8 @@ impl CodeBlock {
| Instruction::Reserved57
| Instruction::Reserved58
| Instruction::Reserved59
| Instruction::Reserved60 => unreachable!("Reserved opcodes are unrechable"),
| Instruction::Reserved60
| Instruction::Reserved61 => unreachable!("Reserved opcodes are unrechable"),
}
}
}
Expand Down Expand Up @@ -919,7 +916,6 @@ pub(crate) fn create_function_object(
/// with all the properties and prototype set.
pub(crate) fn create_function_object_fast(
code: Gc<CodeBlock>,
method: bool,
context: &mut Context<'_>,
) -> JsObject {
let _timer = Profiler::global().start_event("create_function_object_fast", "vm");
Expand All @@ -931,16 +927,18 @@ pub(crate) fn create_function_object_fast(

let is_async = code.is_async();
let is_generator = code.is_generator();
let is_arrow = code.is_arrow();
let has_prototype_property = code.has_prototype_property();
let function = OrdinaryFunction::new(
code,
context.vm.environments.clone(),
script_or_module,
context.realm().clone(),
);

let data =
ObjectData::ordinary_function(function, !method && !is_arrow && !is_async && !is_generator);
let data = ObjectData::ordinary_function(
function,
has_prototype_property && !is_async && !is_generator,
);

if is_generator {
let prototype = JsObject::from_proto_and_data_with_shared_shape(
Expand All @@ -965,7 +963,7 @@ pub(crate) fn create_function_object_fast(
.templates()
.async_function()
.create(data, vec![length, name])
} else if is_arrow || method {
} else if !has_prototype_property {
context
.intrinsics()
.templates()
Expand Down
5 changes: 3 additions & 2 deletions boa_engine/src/vm/flowgraph/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -242,7 +242,7 @@ impl CodeBlock {
graph.add_node(previous_pc, NodeShape::None, label.into(), Color::None);
graph.add_edge(previous_pc, pc, None, Color::None, EdgeStyle::Line);
}
Instruction::GetArrowFunction { .. } | Instruction::GetFunction { .. } => {
Instruction::GetFunction { .. } => {
graph.add_node(previous_pc, NodeShape::None, label.into(), Color::None);
graph.add_edge(previous_pc, pc, None, Color::None, EdgeStyle::Line);
}
Expand Down Expand Up @@ -519,7 +519,8 @@ impl CodeBlock {
| Instruction::Reserved57
| Instruction::Reserved58
| Instruction::Reserved59
| Instruction::Reserved60 => unreachable!("Reserved opcodes are unrechable"),
| Instruction::Reserved60
| Instruction::Reserved61 => unreachable!("Reserved opcodes are unrechable"),
}
}

Expand Down
Loading

0 comments on commit 31d0412

Please sign in to comment.