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] - Remove strict flag from Context #2069

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
2 changes: 1 addition & 1 deletion boa_cli/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ where
use boa_engine::syntax::parser::Parser;

let src_bytes = src.as_ref();
Parser::new(src_bytes, false)
Parser::new(src_bytes)
.parse_all(context)
.map_err(|e| format!("ParsingError: {e}"))
}
Expand Down
7 changes: 6 additions & 1 deletion boa_engine/src/builtins/eval/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,12 @@ impl Eval {

// Parse the script body (11.a - 11.d)
// TODO: Implement errors for 11.e - 11.h
let body = match context.parse(x.as_bytes()).map_err(|e| e.to_string()) {
let parse_result = if strict {
context.parse_strict(x.as_bytes())
} else {
context.parse(x.as_bytes())
};
let body = match parse_result.map_err(|e| e.to_string()) {
Ok(body) => body,
Err(e) => return context.throw_syntax_error(e),
};
Expand Down
32 changes: 14 additions & 18 deletions boa_engine/src/context/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,9 +82,6 @@ pub struct Context {
/// Intrinsic objects
intrinsics: Intrinsics,

/// Whether or not global strict mode is active.
strict: bool,

pub(crate) vm: Vm,
}

Expand All @@ -96,7 +93,6 @@ impl Default for Context {
#[cfg(feature = "console")]
console: Console::default(),
intrinsics: Intrinsics::default(),
strict: false,
vm: Vm {
frame: None,
stack: Vec::with_capacity(1024),
Expand Down Expand Up @@ -149,18 +145,6 @@ impl Context {
&mut self.console
}

/// Returns if strict mode is currently active.
#[inline]
pub fn strict(&self) -> bool {
self.strict
}

/// Set the global strict mode of the context.
#[inline]
pub fn set_strict_mode(&mut self, strict: bool) {
self.strict = strict;
}

/// Sets up the default global objects within Global
#[inline]
fn create_intrinsics(&mut self) {
Expand All @@ -178,11 +162,23 @@ impl Context {
)
}

/// Parse the given source text.
pub fn parse<S>(&mut self, src: S) -> Result<StatementList, ParseError>
where
S: AsRef<[u8]>,
{
Parser::new(src.as_ref(), self.strict).parse_all(self)
let mut parser = Parser::new(src.as_ref());
parser.parse_all(self)
}

/// Parse the given source text in strict mode.
pub(crate) fn parse_strict<S>(&mut self, src: S) -> Result<StatementList, ParseError>
where
S: AsRef<[u8]>,
{
let mut parser = Parser::new(src.as_ref());
parser.set_strict();
parser.parse_all(self)
}

/// <https://tc39.es/ecma262/#sec-call>
Expand Down Expand Up @@ -641,7 +637,7 @@ impl Context {
{
let main_timer = Profiler::global().start_event("Evaluation", "Main");

let parsing_result = Parser::new(src.as_ref(), false)
let parsing_result = Parser::new(src.as_ref())
.parse_all(self)
.map_err(|e| e.to_string());

Expand Down
7 changes: 7 additions & 0 deletions boa_engine/src/syntax/ast/node/await_expr/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,13 @@ pub struct AwaitExpr {
expr: Box<Node>,
}

impl AwaitExpr {
/// Return the expression that should be awaited.
pub(crate) fn expr(&self) -> &Node {
&self.expr
}
}

impl<T> From<T> for AwaitExpr
where
T: Into<Box<Node>>,
Expand Down
108 changes: 108 additions & 0 deletions boa_engine/src/syntax/ast/node/declaration/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,114 @@ impl DeclarationPattern {
DeclarationPattern::Array(pattern) => pattern.init(),
}
}

/// Returns true if the node contains a identifier reference named 'arguments'.
///
/// More information:
/// - [ECMAScript specification][spec]
///
/// [spec]: https://tc39.es/ecma262/#sec-static-semantics-containsarguments
#[inline]
pub(crate) fn contains_arguments(&self) -> bool {
jedel1043 marked this conversation as resolved.
Show resolved Hide resolved
match self {
DeclarationPattern::Object(pattern) => {
if let Some(init) = pattern.init() {
if init.contains_arguments() {
return true;
}
}
for binding in pattern.bindings() {
match binding {
BindingPatternTypeObject::SingleName {
property_name,
default_init,
..
} => {
if let PropertyName::Computed(node) = property_name {
if node.contains_arguments() {
return true;
}
}
if let Some(init) = default_init {
if init.contains_arguments() {
return true;
}
}
}
BindingPatternTypeObject::RestGetConstField {
get_const_field, ..
} => {
if get_const_field.obj().contains_arguments() {
return true;
}
}
BindingPatternTypeObject::BindingPattern {
ident,
pattern,
default_init,
} => {
if let PropertyName::Computed(node) = ident {
if node.contains_arguments() {
return true;
}
}
if pattern.contains_arguments() {
return true;
}
if let Some(init) = default_init {
if init.contains_arguments() {
return true;
}
}
}
_ => {}
}
}
}
DeclarationPattern::Array(pattern) => {
if let Some(init) = pattern.init() {
if init.contains_arguments() {
return true;
}
}
for binding in pattern.bindings() {
match binding {
BindingPatternTypeArray::SingleName {
default_init: Some(init),
..
} => {
if init.contains_arguments() {
return true;
}
}
BindingPatternTypeArray::GetField { get_field }
| BindingPatternTypeArray::GetFieldRest { get_field } => {
if get_field.obj().contains_arguments() {
return true;
}
if get_field.field().contains_arguments() {
return true;
}
}
BindingPatternTypeArray::GetConstField { get_const_field }
| BindingPatternTypeArray::GetConstFieldRest { get_const_field } => {
if get_const_field.obj().contains_arguments() {
return true;
}
}
BindingPatternTypeArray::BindingPattern { pattern }
| BindingPatternTypeArray::BindingPatternRest { pattern } => {
if pattern.contains_arguments() {
return true;
}
}
_ => {}
}
}
}
}
false
}
}

/// `DeclarationPatternObject` represents an object binding pattern.
Expand Down
23 changes: 22 additions & 1 deletion boa_engine/src/syntax/ast/node/identifier/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
//! Local identifier node.

use crate::syntax::ast::node::Node;
use crate::syntax::{
ast::{node::Node, Position},
parser::ParseError,
};
use boa_gc::{unsafe_empty_trace, Finalize, Trace};
use boa_interner::{Interner, Sym, ToInternedString};

Expand Down Expand Up @@ -39,6 +42,24 @@ impl Identifier {
pub fn sym(self) -> Sym {
self.ident
}

/// Returns an error if `arguments` or `eval` are used as identifier in strict mode.
pub(crate) fn check_strict_arguments_or_eval(
self,
position: Position,
) -> Result<(), ParseError> {
match self.ident {
Sym::ARGUMENTS => Err(ParseError::general(
"unexpected identifier 'arguments' in strict mode",
position,
)),
Sym::EVAL => Err(ParseError::general(
"unexpected identifier 'eval' in strict mode",
position,
)),
_ => Ok(()),
}
}
}

impl ToInternedString for Identifier {
Expand Down
Loading