Browse Source

Prevent allocation of field names (#2901)

pull/2905/head
Haled Odat 1 year ago committed by GitHub
parent
commit
d20304ea21
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 6
      boa_engine/src/bytecompiler/mod.rs
  2. 10
      boa_engine/src/vm/code_block.rs
  3. 2
      boa_engine/src/vm/flowgraph/mod.rs
  4. 12
      boa_engine/src/vm/opcode/define/class/getter.rs
  5. 14
      boa_engine/src/vm/opcode/define/class/method.rs
  6. 12
      boa_engine/src/vm/opcode/define/class/setter.rs
  7. 8
      boa_engine/src/vm/opcode/define/own_property.rs
  8. 11
      boa_engine/src/vm/opcode/delete/mod.rs
  9. 9
      boa_engine/src/vm/opcode/get/property.rs
  10. 19
      boa_engine/src/vm/opcode/set/property.rs

6
boa_engine/src/bytecompiler/mod.rs

@ -14,6 +14,7 @@ mod utils;
use crate::{ use crate::{
builtins::function::ThisMode, builtins::function::ThisMode,
environments::{BindingLocator, CompileTimeEnvironment}, environments::{BindingLocator, CompileTimeEnvironment},
js_string,
vm::{BindingOpcode, CodeBlock, Opcode}, vm::{BindingOpcode, CodeBlock, Opcode},
Context, JsBigInt, JsString, JsValue, Context, JsBigInt, JsString, JsValue,
}; };
@ -241,7 +242,7 @@ pub struct ByteCompiler<'ctx, 'host> {
pub(crate) literals: Vec<JsValue>, pub(crate) literals: Vec<JsValue>,
/// Property field names. /// Property field names.
pub(crate) names: Vec<Identifier>, pub(crate) names: Vec<JsString>,
/// Private names. /// Private names.
pub(crate) private_names: Vec<PrivateName>, pub(crate) private_names: Vec<PrivateName>,
@ -363,8 +364,9 @@ impl<'ctx, 'host> ByteCompiler<'ctx, 'host> {
return *index; return *index;
} }
let string = self.interner().resolve_expect(name.sym()).utf16();
let index = self.names.len() as u32; let index = self.names.len() as u32;
self.names.push(name); self.names.push(js_string!(string));
self.names_map.insert(name, index); self.names_map.insert(name, index);
index index
} }

10
boa_engine/src/vm/code_block.rs

@ -18,10 +18,7 @@ use crate::{
vm::CallFrame, vm::CallFrame,
Context, JsError, JsResult, JsString, JsValue, Context, JsError, JsResult, JsString, JsValue,
}; };
use boa_ast::{ use boa_ast::function::{FormalParameterList, PrivateName};
expression::Identifier,
function::{FormalParameterList, PrivateName},
};
use boa_gc::{Finalize, Gc, GcRefCell, Trace}; use boa_gc::{Finalize, Gc, GcRefCell, Trace};
use boa_interner::Sym; use boa_interner::Sym;
use boa_profiler::Profiler; use boa_profiler::Profiler;
@ -89,8 +86,7 @@ pub struct CodeBlock {
pub(crate) literals: Box<[JsValue]>, pub(crate) literals: Box<[JsValue]>,
/// Property field names. /// Property field names.
#[unsafe_ignore_trace] pub(crate) names: Box<[JsString]>,
pub(crate) names: Box<[Identifier]>,
/// Private names. /// Private names.
#[unsafe_ignore_trace] #[unsafe_ignore_trace]
@ -365,7 +361,7 @@ impl CodeBlock {
*pc += size_of::<u32>(); *pc += size_of::<u32>();
format!( format!(
"{operand:04}: '{}'", "{operand:04}: '{}'",
interner.resolve_expect(self.names[operand as usize].sym()), self.names[operand as usize].to_std_string_escaped(),
) )
} }
Opcode::SetPrivateField Opcode::SetPrivateField

2
boa_engine/src/vm/flowgraph/mod.rs

@ -444,7 +444,7 @@ impl CodeBlock {
pc += size_of::<u32>(); pc += size_of::<u32>();
let label = format!( let label = format!(
"{opcode_str} '{}'", "{opcode_str} '{}'",
interner.resolve_expect(self.names[operand as usize].sym()), self.names[operand as usize].to_std_string_escaped(),
); );
graph.add_node(previous_pc, NodeShape::None, label.into(), Color::None); graph.add_node(previous_pc, NodeShape::None, label.into(), Color::None);
graph.add_edge(previous_pc, pc, None, Color::None, EdgeStyle::Line); graph.add_edge(previous_pc, pc, None, Color::None, EdgeStyle::Line);

12
boa_engine/src/vm/opcode/define/class/getter.rs

@ -22,10 +22,8 @@ impl Operation for DefineClassStaticGetterByName {
let function = context.vm.pop(); let function = context.vm.pop();
let class = context.vm.pop(); let class = context.vm.pop();
let class = class.as_object().expect("class must be object"); let class = class.as_object().expect("class must be object");
let key = context let key = context.vm.frame().code_block.names[index as usize]
.interner() .clone()
.resolve_expect(context.vm.frame().code_block.names[index as usize].sym())
.into_common::<JsString>(false)
.into(); .into();
{ {
let function_object = function let function_object = function
@ -74,10 +72,8 @@ impl Operation for DefineClassGetterByName {
let function = context.vm.pop(); let function = context.vm.pop();
let class_proto = context.vm.pop(); let class_proto = context.vm.pop();
let class_proto = class_proto.as_object().expect("class must be object"); let class_proto = class_proto.as_object().expect("class must be object");
let key = context let key = context.vm.frame().code_block.names[index as usize]
.interner() .clone()
.resolve_expect(context.vm.frame().code_block.names[index as usize].sym())
.into_common::<JsString>(false)
.into(); .into();
{ {
let function_object = function let function_object = function

14
boa_engine/src/vm/opcode/define/class/method.rs

@ -3,7 +3,7 @@ use crate::{
object::CONSTRUCTOR, object::CONSTRUCTOR,
property::PropertyDescriptor, property::PropertyDescriptor,
vm::{opcode::Operation, CompletionType}, vm::{opcode::Operation, CompletionType},
Context, JsResult, JsString, Context, JsResult,
}; };
/// `DefineClassStaticMethodByName` implements the Opcode Operation for `Opcode::DefineClassStaticMethodByName` /// `DefineClassStaticMethodByName` implements the Opcode Operation for `Opcode::DefineClassStaticMethodByName`
@ -22,10 +22,8 @@ impl Operation for DefineClassStaticMethodByName {
let function = context.vm.pop(); let function = context.vm.pop();
let class = context.vm.pop(); let class = context.vm.pop();
let class = class.as_object().expect("class must be object"); let class = class.as_object().expect("class must be object");
let key = context let key = context.vm.frame().code_block.names[index as usize]
.interner() .clone()
.resolve_expect(context.vm.frame().code_block.names[index as usize].sym())
.into_common::<JsString>(false)
.into(); .into();
{ {
let function_object = function let function_object = function
@ -70,10 +68,8 @@ impl Operation for DefineClassMethodByName {
let function = context.vm.pop(); let function = context.vm.pop();
let class_proto = context.vm.pop(); let class_proto = context.vm.pop();
let class_proto = class_proto.as_object().expect("class must be object"); let class_proto = class_proto.as_object().expect("class must be object");
let key = context let key = context.vm.frame().code_block.names[index as usize]
.interner() .clone()
.resolve_expect(context.vm.frame().code_block.names[index as usize].sym())
.into_common::<JsString>(false)
.into(); .into();
{ {
let function_object = function let function_object = function

12
boa_engine/src/vm/opcode/define/class/setter.rs

@ -22,10 +22,8 @@ impl Operation for DefineClassStaticSetterByName {
let function = context.vm.pop(); let function = context.vm.pop();
let class = context.vm.pop(); let class = context.vm.pop();
let class = class.as_object().expect("class must be object"); let class = class.as_object().expect("class must be object");
let key = context let key = context.vm.frame().code_block.names[index as usize]
.interner() .clone()
.resolve_expect(context.vm.frame().code_block.names[index as usize].sym())
.into_common::<JsString>(false)
.into(); .into();
{ {
let function_object = function let function_object = function
@ -75,10 +73,8 @@ impl Operation for DefineClassSetterByName {
let function = context.vm.pop(); let function = context.vm.pop();
let class_proto = context.vm.pop(); let class_proto = context.vm.pop();
let class_proto = class_proto.as_object().expect("class must be object"); let class_proto = class_proto.as_object().expect("class must be object");
let key = context let key = context.vm.frame().code_block.names[index as usize]
.interner() .clone()
.resolve_expect(context.vm.frame().code_block.names[index as usize].sym())
.into_common::<JsString>(false)
.into(); .into();
{ {
let function_object = function let function_object = function

8
boa_engine/src/vm/opcode/define/own_property.rs

@ -1,7 +1,7 @@
use crate::{ use crate::{
property::PropertyDescriptor, property::PropertyDescriptor,
vm::{opcode::Operation, CompletionType}, vm::{opcode::Operation, CompletionType},
Context, JsNativeError, JsResult, JsString, Context, JsNativeError, JsResult,
}; };
/// `DefineOwnPropertyByName` implements the Opcode Operation for `Opcode::DefineOwnPropertyByName` /// `DefineOwnPropertyByName` implements the Opcode Operation for `Opcode::DefineOwnPropertyByName`
@ -24,11 +24,7 @@ impl Operation for DefineOwnPropertyByName {
} else { } else {
object.to_object(context)? object.to_object(context)?
}; };
let name = context.vm.frame().code_block.names[index as usize]; let name = context.vm.frame().code_block.names[index as usize].clone();
let name = context
.interner()
.resolve_expect(name.sym())
.into_common::<JsString>(false);
object.__define_own_property__( object.__define_own_property__(
&name.into(), &name.into(),
PropertyDescriptor::builder() PropertyDescriptor::builder()

11
boa_engine/src/vm/opcode/delete/mod.rs

@ -1,7 +1,7 @@
use crate::{ use crate::{
error::JsNativeError, error::JsNativeError,
vm::{opcode::Operation, CompletionType}, vm::{opcode::Operation, CompletionType},
Context, JsResult, JsString, Context, JsResult,
}; };
/// `DeletePropertyByName` implements the Opcode Operation for `Opcode::DeletePropertyByName` /// `DeletePropertyByName` implements the Opcode Operation for `Opcode::DeletePropertyByName`
@ -17,14 +17,11 @@ impl Operation for DeletePropertyByName {
fn execute(context: &mut Context<'_>) -> JsResult<CompletionType> { fn execute(context: &mut Context<'_>) -> JsResult<CompletionType> {
let index = context.vm.read::<u32>(); let index = context.vm.read::<u32>();
let key = context.vm.frame().code_block.names[index as usize];
let key = context
.interner()
.resolve_expect(key.sym())
.into_common::<JsString>(false)
.into();
let value = context.vm.pop(); let value = context.vm.pop();
let object = value.to_object(context)?; let object = value.to_object(context)?;
let key = context.vm.frame().code_block.names[index as usize]
.clone()
.into();
let result = object.__delete__(&key, context)?; let result = object.__delete__(&key, context)?;
if !result && context.vm.frame().code_block.strict { if !result && context.vm.frame().code_block.strict {
return Err(JsNativeError::typ() return Err(JsNativeError::typ()

9
boa_engine/src/vm/opcode/get/property.rs

@ -1,5 +1,4 @@
use crate::{ use crate::{
js_string,
property::PropertyKey, property::PropertyKey,
vm::{opcode::Operation, CompletionType}, vm::{opcode::Operation, CompletionType},
Context, JsResult, JsValue, Context, JsResult, JsValue,
@ -26,8 +25,9 @@ impl Operation for GetPropertyByName {
value.to_object(context)? value.to_object(context)?
}; };
let name = context.vm.frame().code_block.names[index as usize]; let key = context.vm.frame().code_block.names[index as usize]
let key: PropertyKey = context.interner().resolve_expect(name.sym()).utf16().into(); .clone()
.into();
let result = object.__get__(&key, value, context)?; let result = object.__get__(&key, value, context)?;
context.vm.push(result); context.vm.push(result);
@ -93,8 +93,7 @@ impl Operation for GetMethod {
fn execute(context: &mut Context<'_>) -> JsResult<CompletionType> { fn execute(context: &mut Context<'_>) -> JsResult<CompletionType> {
let index = context.vm.read::<u32>(); let index = context.vm.read::<u32>();
let name = context.vm.frame().code_block.names[index as usize]; let key = context.vm.frame().code_block.names[index as usize].clone();
let key = js_string!(context.interner().resolve_expect(name.sym()).utf16());
let value = context.vm.pop(); let value = context.vm.pop();
let method = value.get_method(key, context)?; let method = value.get_method(key, context)?;

19
boa_engine/src/vm/opcode/set/property.rs

@ -30,8 +30,9 @@ impl Operation for SetPropertyByName {
object.to_object(context)? object.to_object(context)?
}; };
let name = context.vm.frame().code_block.names[index as usize]; let name: PropertyKey = context.vm.frame().code_block.names[index as usize]
let name: PropertyKey = context.interner().resolve_expect(name.sym()).utf16().into(); .clone()
.into();
let succeeded = object.__set__(name.clone(), value.clone(), receiver, context)?; let succeeded = object.__set__(name.clone(), value.clone(), receiver, context)?;
if !succeeded && context.vm.frame().code_block.strict { if !succeeded && context.vm.frame().code_block.strict {
@ -163,11 +164,8 @@ impl Operation for SetPropertyGetterByName {
let value = context.vm.pop(); let value = context.vm.pop();
let object = context.vm.pop(); let object = context.vm.pop();
let object = object.to_object(context)?; let object = object.to_object(context)?;
let name = context.vm.frame().code_block.names[index as usize]; let name = context.vm.frame().code_block.names[index as usize]
let name = context .clone()
.interner()
.resolve_expect(name.sym())
.into_common::<JsString>(false)
.into(); .into();
let set = object let set = object
.__get_own_property__(&name, context)? .__get_own_property__(&name, context)?
@ -240,11 +238,8 @@ impl Operation for SetPropertySetterByName {
let value = context.vm.pop(); let value = context.vm.pop();
let object = context.vm.pop(); let object = context.vm.pop();
let object = object.to_object(context)?; let object = object.to_object(context)?;
let name = context.vm.frame().code_block.names[index as usize]; let name = context.vm.frame().code_block.names[index as usize]
let name = context .clone()
.interner()
.resolve_expect(name.sym())
.into_common::<JsString>(false)
.into(); .into();
let get = object let get = object
.__get_own_property__(&name, context)? .__get_own_property__(&name, context)?

Loading…
Cancel
Save