Browse Source

Skip prototype field definition for arrow function (#2388)

This Pull Request changes the following:

- Skip prototype field definition for arrow function
- Add `GetArrowFunction` opcode
pull/2391/head
raskad 2 years ago
parent
commit
203c1961bb
  1. 4
      boa_engine/src/builtins/function/mod.rs
  2. 2
      boa_engine/src/bytecompiler/mod.rs
  3. 6
      boa_engine/src/vm/code_block.rs
  4. 1
      boa_engine/src/vm/mod.rs
  5. 24
      boa_engine/src/vm/opcode/get/function.rs
  6. 9
      boa_engine/src/vm/opcode/mod.rs

4
boa_engine/src/builtins/function/mod.rs

@ -616,7 +616,7 @@ impl BuiltInFunctionObject {
let function_object = if generator { let function_object = if generator {
crate::vm::create_generator_function_object(code, r#async, context) crate::vm::create_generator_function_object(code, r#async, context)
} else { } else {
crate::vm::create_function_object(code, r#async, Some(prototype), context) crate::vm::create_function_object(code, r#async, false, Some(prototype), context)
}; };
context.realm.environments.extend(environments); context.realm.environments.extend(environments);
@ -647,7 +647,7 @@ impl BuiltInFunctionObject {
let environments = context.realm.environments.pop_to_global(); let environments = context.realm.environments.pop_to_global();
let function_object = let function_object =
crate::vm::create_function_object(code, r#async, Some(prototype), context); crate::vm::create_function_object(code, r#async, false, Some(prototype), context);
context.realm.environments.extend(environments); context.realm.environments.extend(environments);
Ok(function_object) Ok(function_object)

2
boa_engine/src/bytecompiler/mod.rs

@ -2317,6 +2317,8 @@ impl<'b> ByteCompiler<'b> {
self.emit(Opcode::GetGenerator, &[index]); self.emit(Opcode::GetGenerator, &[index]);
} else if r#async { } else if r#async {
self.emit(Opcode::GetFunctionAsync, &[index]); self.emit(Opcode::GetFunctionAsync, &[index]);
} else if arrow {
self.emit(Opcode::GetArrowFunction, &[index]);
} else { } else {
self.emit(Opcode::GetFunction, &[index]); self.emit(Opcode::GetFunction, &[index]);
} }

6
boa_engine/src/vm/code_block.rs

@ -223,7 +223,8 @@ impl CodeBlock {
*pc += size_of::<u32>(); *pc += size_of::<u32>();
format!("{operand1}, {operand2}") format!("{operand1}, {operand2}")
} }
Opcode::GetFunction Opcode::GetArrowFunction
| Opcode::GetFunction
| Opcode::GetFunctionAsync | Opcode::GetFunctionAsync
| Opcode::GetGenerator | Opcode::GetGenerator
| Opcode::GetGeneratorAsync => { | Opcode::GetGeneratorAsync => {
@ -458,6 +459,7 @@ impl ToInternedString for CodeBlock {
pub(crate) fn create_function_object( pub(crate) fn create_function_object(
code: Gc<CodeBlock>, code: Gc<CodeBlock>,
r#async: bool, r#async: bool,
arrow: bool,
prototype: Option<JsObject>, prototype: Option<JsObject>,
context: &mut Context, context: &mut Context,
) -> JsObject { ) -> JsObject {
@ -551,7 +553,7 @@ pub(crate) fn create_function_object(
constructor constructor
.define_property_or_throw(js_string!("name"), name_property, context) .define_property_or_throw(js_string!("name"), name_property, context)
.expect("failed to define the name property of the function"); .expect("failed to define the name property of the function");
if !r#async { if !r#async && !arrow {
constructor constructor
.define_property_or_throw(js_string!("prototype"), prototype_property, context) .define_property_or_throw(js_string!("prototype"), prototype_property, context)
.expect("failed to define the prototype property of the function"); .expect("failed to define the prototype property of the function");

1
boa_engine/src/vm/mod.rs

@ -250,6 +250,7 @@ impl Context {
Opcode::SuperCallDerived => SuperCallDerived::execute(self)?, Opcode::SuperCallDerived => SuperCallDerived::execute(self)?,
Opcode::Case => Case::execute(self)?, Opcode::Case => Case::execute(self)?,
Opcode::Default => Default::execute(self)?, Opcode::Default => Default::execute(self)?,
Opcode::GetArrowFunction => GetArrowFunction::execute(self)?,
Opcode::GetFunction => GetFunction::execute(self)?, Opcode::GetFunction => GetFunction::execute(self)?,
Opcode::GetFunctionAsync => GetFunctionAsync::execute(self)?, Opcode::GetFunctionAsync => GetFunctionAsync::execute(self)?,
Opcode::GetGenerator => GetGenerator::execute(self)?, Opcode::GetGenerator => GetGenerator::execute(self)?,

24
boa_engine/src/vm/opcode/get/function.rs

@ -3,6 +3,26 @@ use crate::{
Context, JsResult, Context, JsResult,
}; };
/// `GetArrowFunction` implements the Opcode Operation for `Opcode::GetArrowFunction`
///
/// Operation:
/// - Get arrow function from the pre-compiled inner functions.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub(crate) struct GetArrowFunction;
impl Operation for GetArrowFunction {
const NAME: &'static str = "GetArrowFunction";
const INSTRUCTION: &'static str = "INST - GetArrowFunction";
fn execute(context: &mut Context) -> JsResult<ShouldExit> {
let index = context.vm.read::<u32>();
let code = context.vm.frame().code.functions[index as usize].clone();
let function = create_function_object(code, false, true, None, context);
context.vm.push(function);
Ok(ShouldExit::False)
}
}
/// `GetFunction` implements the Opcode Operation for `Opcode::GetFunction` /// `GetFunction` implements the Opcode Operation for `Opcode::GetFunction`
/// ///
/// Operation: /// Operation:
@ -17,7 +37,7 @@ impl Operation for GetFunction {
fn execute(context: &mut Context) -> JsResult<ShouldExit> { fn execute(context: &mut Context) -> JsResult<ShouldExit> {
let index = context.vm.read::<u32>(); let index = context.vm.read::<u32>();
let code = context.vm.frame().code.functions[index as usize].clone(); let code = context.vm.frame().code.functions[index as usize].clone();
let function = create_function_object(code, false, None, context); let function = create_function_object(code, false, false, None, context);
context.vm.push(function); context.vm.push(function);
Ok(ShouldExit::False) Ok(ShouldExit::False)
} }
@ -37,7 +57,7 @@ impl Operation for GetFunctionAsync {
fn execute(context: &mut Context) -> JsResult<ShouldExit> { fn execute(context: &mut Context) -> JsResult<ShouldExit> {
let index = context.vm.read::<u32>(); let index = context.vm.read::<u32>();
let code = context.vm.frame().code.functions[index as usize].clone(); let code = context.vm.frame().code.functions[index as usize].clone();
let function = create_function_object(code, true, None, context); let function = create_function_object(code, true, false, None, context);
context.vm.push(function); context.vm.push(function);
Ok(ShouldExit::False) Ok(ShouldExit::False)
} }

9
boa_engine/src/vm/opcode/mod.rs

@ -1022,6 +1022,13 @@ pub enum Opcode {
/// Stack: `value` **=>** /// Stack: `value` **=>**
Default, Default,
/// Get arrow function from the pre-compiled inner functions.
///
/// Operands: address: `u32`
///
/// Stack: **=>** func
GetArrowFunction,
/// Get function from the pre-compiled inner functions. /// Get function from the pre-compiled inner functions.
/// ///
/// Operands: address: `u32` /// Operands: address: `u32`
@ -1441,6 +1448,7 @@ impl Opcode {
Self::SuperCallDerived => SuperCallDerived::NAME, Self::SuperCallDerived => SuperCallDerived::NAME,
Self::Case => Case::NAME, Self::Case => Case::NAME,
Self::Default => Default::NAME, Self::Default => Default::NAME,
Self::GetArrowFunction => GetArrowFunction::NAME,
Self::GetFunction => GetFunction::NAME, Self::GetFunction => GetFunction::NAME,
Self::GetFunctionAsync => GetFunctionAsync::NAME, Self::GetFunctionAsync => GetFunctionAsync::NAME,
Self::GetGenerator => GetGenerator::NAME, Self::GetGenerator => GetGenerator::NAME,
@ -1588,6 +1596,7 @@ impl Opcode {
Self::SuperCallDerived => SuperCallDerived::INSTRUCTION, Self::SuperCallDerived => SuperCallDerived::INSTRUCTION,
Self::Case => Case::INSTRUCTION, Self::Case => Case::INSTRUCTION,
Self::Default => Default::INSTRUCTION, Self::Default => Default::INSTRUCTION,
Self::GetArrowFunction => GetArrowFunction::INSTRUCTION,
Self::GetFunction => GetFunction::INSTRUCTION, Self::GetFunction => GetFunction::INSTRUCTION,
Self::GetFunctionAsync => GetFunctionAsync::INSTRUCTION, Self::GetFunctionAsync => GetFunctionAsync::INSTRUCTION,
Self::GetGenerator => GetGenerator::INSTRUCTION, Self::GetGenerator => GetGenerator::INSTRUCTION,

Loading…
Cancel
Save