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

[Merged by Bors] - Implement delete for references #2395

Closed
wants to merge 3 commits into from
Closed
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
12 changes: 7 additions & 5 deletions boa_engine/src/bytecompiler/function.rs
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ impl FunctionCompiler {
if !(self.arrow) && !parameters.has_arguments() {
compiler
.context
.create_mutable_binding(Sym::ARGUMENTS.into(), false);
.create_mutable_binding(Sym::ARGUMENTS.into(), false, false);
compiler.code_block.arguments_binding = Some(
compiler
.context
Expand All @@ -124,7 +124,9 @@ impl FunctionCompiler {

match parameter.variable().binding() {
Binding::Identifier(ident) => {
compiler.context.create_mutable_binding(*ident, false);
compiler
.context
.create_mutable_binding(*ident, false, false);
// TODO: throw custom error if ident is in init
if let Some(init) = parameter.variable().init() {
let skip = compiler.emit_opcode_with_operand(Opcode::JumpIfNotUndefined);
Expand All @@ -135,7 +137,7 @@ impl FunctionCompiler {
}
Binding::Pattern(pattern) => {
for ident in pattern.idents() {
compiler.context.create_mutable_binding(ident, false);
compiler.context.create_mutable_binding(ident, false, false);
}
// TODO: throw custom error if ident is in init
if let Some(init) = parameter.variable().init() {
Expand Down Expand Up @@ -168,8 +170,8 @@ impl FunctionCompiler {
compiler.emit_opcode(Opcode::Yield);
}

compiler.create_decls(body);
compiler.compile_statement_list(body, false)?;
compiler.create_decls(body, false);
compiler.compile_statement_list(body, false, false)?;

if let Some(env_label) = env_label {
let (num_bindings, compile_environment) =
Expand Down
288 changes: 195 additions & 93 deletions boa_engine/src/bytecompiler/mod.rs

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions boa_engine/src/context/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -487,8 +487,8 @@ impl Context {
pub fn compile(&mut self, statement_list: &StatementList) -> JsResult<Gc<CodeBlock>> {
let _timer = Profiler::global().start_event("Compilation", "Main");
let mut compiler = ByteCompiler::new(Sym::MAIN, statement_list.strict(), self);
compiler.create_decls(statement_list);
compiler.compile_statement_list(statement_list, true)?;
compiler.create_decls(statement_list, false);
compiler.compile_statement_list(statement_list, true, false)?;
Ok(Gc::new(compiler.finish()))
}

Expand Down
9 changes: 7 additions & 2 deletions boa_engine/src/environments/compile.rs
Original file line number Diff line number Diff line change
Expand Up @@ -288,7 +288,12 @@ impl Context {
///
/// Panics if the global environment is not function scoped.
#[inline]
pub(crate) fn create_mutable_binding(&mut self, name: Identifier, function_scope: bool) {
pub(crate) fn create_mutable_binding(
&mut self,
name: Identifier,
function_scope: bool,
configurable: bool,
) {
if !self
.realm
.compile_env
Expand All @@ -311,7 +316,7 @@ impl Context {
.value(JsValue::Undefined)
.writable(true)
.enumerable(true)
.configurable(true)
.configurable(configurable)
.build(),
);
}
Expand Down
39 changes: 37 additions & 2 deletions boa_engine/src/environments/runtime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -556,7 +556,7 @@ impl DeclarativeEnvironmentStack {
/// This only considers function environments that are poisoned.
/// All other bindings are accessed via indices.
#[inline]
pub(crate) fn get_value_global_poisoned(&self, name: Identifier) -> Option<JsValue> {
pub(crate) fn get_value_if_global_poisoned(&self, name: Identifier) -> Option<JsValue> {
for env in self.stack.iter().rev() {
if !env.poisoned.get() {
return None;
Expand Down Expand Up @@ -689,7 +689,11 @@ impl DeclarativeEnvironmentStack {
///
/// Panics if the environment or binding index are out of range.
#[inline]
pub(crate) fn put_value_global_poisoned(&mut self, name: Identifier, value: &JsValue) -> bool {
pub(crate) fn put_value_if_global_poisoned(
&mut self,
name: Identifier,
value: &JsValue,
) -> bool {
for env in self.stack.iter().rev() {
if !env.poisoned.get() {
return false;
Expand All @@ -713,6 +717,37 @@ impl DeclarativeEnvironmentStack {
}
false
}

/// Checks if the name only exists as a global property.
///
/// A binding could be marked as `global`, and at the same time, exist in a deeper environment
/// context; if the global context is poisoned, an `eval` call could have added a binding that is
/// not global with the same name as the global binding. This double checks that the binding name
/// is truly a global property.
///
/// # Panics
///
/// Panics if the environment or binding index are out of range.
#[inline]
pub(crate) fn is_only_global_property(&mut self, name: Identifier) -> bool {
for env in self
.stack
.split_first()
.expect("global environment must exist")
.1
.iter()
.rev()
{
if !env.poisoned.get() {
return true;
}
let compile = env.compile.borrow();
if compile.is_function() && compile.get_binding(name).is_some() {
return false;
}
}
true
}
}

/// A binding locator contains all information about a binding that is needed to resolve it at runtime.
Expand Down
17 changes: 16 additions & 1 deletion boa_engine/src/object/internal_methods/global.rs
Original file line number Diff line number Diff line change
Expand Up @@ -387,11 +387,26 @@ pub(crate) fn global_set_no_receiver(
///
/// [spec]: https://tc39.es/ecma262/#sec-ordinarydelete
#[inline]
#[allow(clippy::unnecessary_wraps)]
#[allow(clippy::unnecessary_wraps, clippy::needless_pass_by_value)]
pub(crate) fn global_delete(
_obj: &JsObject,
key: &PropertyKey,
context: &mut Context,
) -> JsResult<bool> {
global_delete_no_receiver(key, context)
}

/// Abstract operation `OrdinaryDelete`.
///
/// More information:
/// - [ECMAScript reference][spec]
///
/// [spec]: https://tc39.es/ecma262/#sec-ordinarydelete
#[inline]
#[allow(clippy::unnecessary_wraps)]
pub(crate) fn global_delete_no_receiver(
key: &PropertyKey,
context: &mut Context,
) -> JsResult<bool> {
let _timer = Profiler::global().start_event("Object::global_delete", "object");
// 1. Assert: IsPropertyKey(P) is true.
Expand Down
4 changes: 3 additions & 1 deletion boa_engine/src/vm/code_block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,8 @@ impl CodeBlock {
| Opcode::DefInitConst
| Opcode::GetName
| Opcode::GetNameOrUndefined
| Opcode::SetName => {
| Opcode::SetName
| Opcode::DeleteName => {
let operand = self.read::<u32>(*pc);
*pc += size_of::<u32>();
format!(
Expand Down Expand Up @@ -344,6 +345,7 @@ impl CodeBlock {
| Opcode::SetPropertySetterByValue
| Opcode::DefineClassSetterByValue
| Opcode::DeletePropertyByValue
| Opcode::DeleteSuperThrow
| Opcode::ToPropertyKey
| Opcode::ToBoolean
| Opcode::Throw
Expand Down
2 changes: 1 addition & 1 deletion boa_engine/src/vm/opcode/await_stm/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use crate::{
///
/// Operation:
/// - Stops the current Async function and schedules it to resume later.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[derive(Debug, Clone, Copy)]
pub(crate) struct Await;

impl Operation for Await {
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 @@ -7,7 +7,7 @@ use crate::{
///
/// Operation:
/// - Binary logical `&&` operation
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[derive(Debug, Clone, Copy)]
pub(crate) struct LogicalAnd;

impl Operation for LogicalAnd {
Expand All @@ -29,7 +29,7 @@ impl Operation for LogicalAnd {
///
/// Operation:
/// - Binary logical `||` operation
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[derive(Debug, Clone, Copy)]
pub(crate) struct LogicalOr;

impl Operation for LogicalOr {
Expand All @@ -51,7 +51,7 @@ impl Operation for LogicalOr {
///
/// Operation:
/// - Binary logical `||` operation
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[derive(Debug, Clone, Copy)]
pub(crate) struct Coalesce;

impl Operation for Coalesce {
Expand Down
2 changes: 1 addition & 1 deletion boa_engine/src/vm/opcode/binary_ops/macro_defined.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ macro_rules! implement_bin_ops {
#[doc= "\n"]
#[doc="Operation:\n"]
#[doc= concat!(" - ", $doc_string)]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[derive(Debug, Clone, Copy)]
pub(crate) struct $name;

impl Operation for $name {
Expand Down
10 changes: 5 additions & 5 deletions boa_engine/src/vm/opcode/binary_ops/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ pub(crate) use macro_defined::*;
///
/// Operation:
/// - Binary `!=` operation
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[derive(Debug, Clone, Copy)]
pub(crate) struct NotEq;

impl Operation for NotEq {
Expand All @@ -34,7 +34,7 @@ impl Operation for NotEq {
///
/// Operation:
/// - Binary `===` operation
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[derive(Debug, Clone, Copy)]
pub(crate) struct StrictEq;

impl Operation for StrictEq {
Expand All @@ -53,7 +53,7 @@ impl Operation for StrictEq {
///
/// Operation:
/// - Binary `!==` operation
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[derive(Debug, Clone, Copy)]
pub(crate) struct StrictNotEq;

impl Operation for StrictNotEq {
Expand All @@ -72,7 +72,7 @@ impl Operation for StrictNotEq {
///
/// Operation:
/// - Binary `in` operation
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[derive(Debug, Clone, Copy)]
pub(crate) struct In;

impl Operation for In {
Expand Down Expand Up @@ -102,7 +102,7 @@ impl Operation for In {
///
/// Operation:
/// - Binary `instanceof` operation
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[derive(Debug, Clone, Copy)]
pub(crate) struct InstanceOf;

impl Operation for InstanceOf {
Expand Down
8 changes: 4 additions & 4 deletions boa_engine/src/vm/opcode/call/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use crate::{
///
/// Operation:
/// - Call a function named "eval".
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[derive(Debug, Clone, Copy)]
pub(crate) struct CallEval;

impl Operation for CallEval {
Expand Down Expand Up @@ -65,7 +65,7 @@ impl Operation for CallEval {
///
/// Operation:
/// - Call a function named "eval" where the arguments contain spreads.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[derive(Debug, Clone, Copy)]
pub(crate) struct CallEvalSpread;

impl Operation for CallEvalSpread {
Expand Down Expand Up @@ -127,7 +127,7 @@ impl Operation for CallEvalSpread {
///
/// Operation:
/// - Call a function
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[derive(Debug, Clone, Copy)]
pub(crate) struct Call;

impl Operation for Call {
Expand Down Expand Up @@ -166,7 +166,7 @@ impl Operation for Call {
}
}

#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[derive(Debug, Clone, Copy)]
pub(crate) struct CallSpread;

impl Operation for CallSpread {
Expand Down
2 changes: 1 addition & 1 deletion boa_engine/src/vm/opcode/concat/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use crate::{
///
/// Operation:
/// - Concat multiple stack objects into a string.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[derive(Debug, Clone, Copy)]
pub(crate) struct ConcatToString;

impl Operation for ConcatToString {
Expand Down
2 changes: 1 addition & 1 deletion boa_engine/src/vm/opcode/copy/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use crate::{
///
/// Operation:
/// - Copy all properties of one object to another object.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[derive(Debug, Clone, Copy)]
pub(crate) struct CopyDataProperties;

impl Operation for CopyDataProperties {
Expand Down
4 changes: 2 additions & 2 deletions boa_engine/src/vm/opcode/define/class/getter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use crate::{
///
/// Operation:
/// - Defines a class getter by name.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[derive(Debug, Clone, Copy)]
pub(crate) struct DefineClassGetterByName;

impl Operation for DefineClassGetterByName {
Expand Down Expand Up @@ -56,7 +56,7 @@ impl Operation for DefineClassGetterByName {
///
/// Operation:
/// - Defines a class getter by value.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[derive(Debug, Clone, Copy)]
pub(crate) struct DefineClassGetterByValue;

impl Operation for DefineClassGetterByValue {
Expand Down
4 changes: 2 additions & 2 deletions boa_engine/src/vm/opcode/define/class/method.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use crate::{
///
/// Operation:
/// - Defines a class method by name.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[derive(Debug, Clone, Copy)]
pub(crate) struct DefineClassMethodByName;

impl Operation for DefineClassMethodByName {
Expand Down Expand Up @@ -51,7 +51,7 @@ impl Operation for DefineClassMethodByName {
///
/// Operation:
/// - Defines a class method by value.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[derive(Debug, Clone, Copy)]
pub(crate) struct DefineClassMethodByValue;

impl Operation for DefineClassMethodByValue {
Expand Down
4 changes: 2 additions & 2 deletions boa_engine/src/vm/opcode/define/class/setter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use crate::{
///
/// Operation:
/// - Defines a class setter by name.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[derive(Debug, Clone, Copy)]
pub(crate) struct DefineClassSetterByName;

impl Operation for DefineClassSetterByName {
Expand Down Expand Up @@ -56,7 +56,7 @@ impl Operation for DefineClassSetterByName {
///
/// Operation:
/// - Defines a class setter by value.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[derive(Debug, Clone, Copy)]
pub(crate) struct DefineClassSetterByValue;

impl Operation for DefineClassSetterByValue {
Expand Down
Loading