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

Prevent allocation of field names #2901

Merged
merged 1 commit into from
May 5, 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
6 changes: 4 additions & 2 deletions boa_engine/src/bytecompiler/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ mod utils;
use crate::{
builtins::function::ThisMode,
environments::{BindingLocator, CompileTimeEnvironment},
js_string,
vm::{BindingOpcode, CodeBlock, Opcode},
Context, JsBigInt, JsString, JsValue,
};
Expand Down Expand Up @@ -241,7 +242,7 @@ pub struct ByteCompiler<'ctx, 'host> {
pub(crate) literals: Vec<JsValue>,

/// Property field names.
pub(crate) names: Vec<Identifier>,
pub(crate) names: Vec<JsString>,

/// Private names.
pub(crate) private_names: Vec<PrivateName>,
Expand Down Expand Up @@ -363,8 +364,9 @@ impl<'ctx, 'host> ByteCompiler<'ctx, 'host> {
return *index;
}

let string = self.interner().resolve_expect(name.sym()).utf16();
let index = self.names.len() as u32;
self.names.push(name);
self.names.push(js_string!(string));
self.names_map.insert(name, index);
index
}
Expand Down
10 changes: 3 additions & 7 deletions boa_engine/src/vm/code_block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,7 @@ use crate::{
vm::CallFrame,
Context, JsError, JsResult, JsString, JsValue,
};
use boa_ast::{
expression::Identifier,
function::{FormalParameterList, PrivateName},
};
use boa_ast::function::{FormalParameterList, PrivateName};
use boa_gc::{Finalize, Gc, GcRefCell, Trace};
use boa_interner::Sym;
use boa_profiler::Profiler;
Expand Down Expand Up @@ -89,8 +86,7 @@ pub struct CodeBlock {
pub(crate) literals: Box<[JsValue]>,

/// Property field names.
#[unsafe_ignore_trace]
pub(crate) names: Box<[Identifier]>,
pub(crate) names: Box<[JsString]>,

/// Private names.
#[unsafe_ignore_trace]
Expand Down Expand Up @@ -365,7 +361,7 @@ impl CodeBlock {
*pc += size_of::<u32>();
format!(
"{operand:04}: '{}'",
interner.resolve_expect(self.names[operand as usize].sym()),
self.names[operand as usize].to_std_string_escaped(),
)
}
Opcode::SetPrivateField
Expand Down
2 changes: 1 addition & 1 deletion boa_engine/src/vm/flowgraph/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -445,7 +445,7 @@ impl CodeBlock {
pc += size_of::<u32>();
let label = format!(
"{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_edge(previous_pc, pc, None, Color::None, EdgeStyle::Line);
Expand Down
12 changes: 4 additions & 8 deletions boa_engine/src/vm/opcode/define/class/getter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,8 @@ impl Operation for DefineClassStaticGetterByName {
let function = context.vm.pop();
let class = context.vm.pop();
let class = class.as_object().expect("class must be object");
let key = context
.interner()
.resolve_expect(context.vm.frame().code_block.names[index as usize].sym())
.into_common::<JsString>(false)
let key = context.vm.frame().code_block.names[index as usize]
.clone()
.into();
{
let function_object = function
Expand Down Expand Up @@ -74,10 +72,8 @@ impl Operation for DefineClassGetterByName {
let function = context.vm.pop();
let class_proto = context.vm.pop();
let class_proto = class_proto.as_object().expect("class must be object");
let key = context
.interner()
.resolve_expect(context.vm.frame().code_block.names[index as usize].sym())
.into_common::<JsString>(false)
let key = context.vm.frame().code_block.names[index as usize]
.clone()
.into();
{
let function_object = function
Expand Down
14 changes: 5 additions & 9 deletions boa_engine/src/vm/opcode/define/class/method.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use crate::{
object::CONSTRUCTOR,
property::PropertyDescriptor,
vm::{opcode::Operation, CompletionType},
Context, JsResult, JsString,
Context, JsResult,
};

/// `DefineClassStaticMethodByName` implements the Opcode Operation for `Opcode::DefineClassStaticMethodByName`
Expand All @@ -22,10 +22,8 @@ impl Operation for DefineClassStaticMethodByName {
let function = context.vm.pop();
let class = context.vm.pop();
let class = class.as_object().expect("class must be object");
let key = context
.interner()
.resolve_expect(context.vm.frame().code_block.names[index as usize].sym())
.into_common::<JsString>(false)
let key = context.vm.frame().code_block.names[index as usize]
.clone()
.into();
{
let function_object = function
Expand Down Expand Up @@ -70,10 +68,8 @@ impl Operation for DefineClassMethodByName {
let function = context.vm.pop();
let class_proto = context.vm.pop();
let class_proto = class_proto.as_object().expect("class must be object");
let key = context
.interner()
.resolve_expect(context.vm.frame().code_block.names[index as usize].sym())
.into_common::<JsString>(false)
let key = context.vm.frame().code_block.names[index as usize]
.clone()
.into();
{
let function_object = function
Expand Down
12 changes: 4 additions & 8 deletions boa_engine/src/vm/opcode/define/class/setter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,8 @@ impl Operation for DefineClassStaticSetterByName {
let function = context.vm.pop();
let class = context.vm.pop();
let class = class.as_object().expect("class must be object");
let key = context
.interner()
.resolve_expect(context.vm.frame().code_block.names[index as usize].sym())
.into_common::<JsString>(false)
let key = context.vm.frame().code_block.names[index as usize]
.clone()
.into();
{
let function_object = function
Expand Down Expand Up @@ -75,10 +73,8 @@ impl Operation for DefineClassSetterByName {
let function = context.vm.pop();
let class_proto = context.vm.pop();
let class_proto = class_proto.as_object().expect("class must be object");
let key = context
.interner()
.resolve_expect(context.vm.frame().code_block.names[index as usize].sym())
.into_common::<JsString>(false)
let key = context.vm.frame().code_block.names[index as usize]
.clone()
.into();
{
let function_object = function
Expand Down
8 changes: 2 additions & 6 deletions boa_engine/src/vm/opcode/define/own_property.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::{
property::PropertyDescriptor,
vm::{opcode::Operation, CompletionType},
Context, JsNativeError, JsResult, JsString,
Context, JsNativeError, JsResult,
};

/// `DefineOwnPropertyByName` implements the Opcode Operation for `Opcode::DefineOwnPropertyByName`
Expand All @@ -24,11 +24,7 @@ impl Operation for DefineOwnPropertyByName {
} else {
object.to_object(context)?
};
let name = context.vm.frame().code_block.names[index as usize];
let name = context
.interner()
.resolve_expect(name.sym())
.into_common::<JsString>(false);
let name = context.vm.frame().code_block.names[index as usize].clone();
object.__define_own_property__(
&name.into(),
PropertyDescriptor::builder()
Expand Down
11 changes: 4 additions & 7 deletions boa_engine/src/vm/opcode/delete/mod.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::{
error::JsNativeError,
vm::{opcode::Operation, CompletionType},
Context, JsResult, JsString,
Context, JsResult,
};

/// `DeletePropertyByName` implements the Opcode Operation for `Opcode::DeletePropertyByName`
Expand All @@ -17,14 +17,11 @@ impl Operation for DeletePropertyByName {

fn execute(context: &mut Context<'_>) -> JsResult<CompletionType> {
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 object = value.to_object(context)?;
let key = context.vm.frame().code_block.names[index as usize]
.clone()
.into();
let result = object.__delete__(&key, context)?;
if !result && context.vm.frame().code_block.strict {
return Err(JsNativeError::typ()
Expand Down
9 changes: 4 additions & 5 deletions boa_engine/src/vm/opcode/get/property.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
use crate::{
js_string,
property::PropertyKey,
vm::{opcode::Operation, CompletionType},
Context, JsResult, JsValue,
Expand All @@ -26,8 +25,9 @@ impl Operation for GetPropertyByName {
value.to_object(context)?
};

let name = context.vm.frame().code_block.names[index as usize];
let key: PropertyKey = context.interner().resolve_expect(name.sym()).utf16().into();
let key = context.vm.frame().code_block.names[index as usize]
.clone()
.into();
let result = object.__get__(&key, value, context)?;

context.vm.push(result);
Expand Down Expand Up @@ -93,8 +93,7 @@ impl Operation for GetMethod {

fn execute(context: &mut Context<'_>) -> JsResult<CompletionType> {
let index = context.vm.read::<u32>();
let name = context.vm.frame().code_block.names[index as usize];
let key = js_string!(context.interner().resolve_expect(name.sym()).utf16());
let key = context.vm.frame().code_block.names[index as usize].clone();
let value = context.vm.pop();

let method = value.get_method(key, context)?;
Expand Down
19 changes: 7 additions & 12 deletions boa_engine/src/vm/opcode/set/property.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,9 @@ impl Operation for SetPropertyByName {
object.to_object(context)?
};

let name = context.vm.frame().code_block.names[index as usize];
let name: PropertyKey = context.interner().resolve_expect(name.sym()).utf16().into();
let name: PropertyKey = context.vm.frame().code_block.names[index as usize]
.clone()
.into();

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