int start_position,
int end_position,
bool is_expression,
- bool contains_loops,
- bool strict_mode)
+ bool contains_loops)
: name_(name),
scope_(scope),
body_(body),
end_position_(end_position),
is_expression_(is_expression),
contains_loops_(contains_loops),
- strict_mode_(strict_mode),
function_token_position_(RelocInfo::kNoPosition),
inferred_name_(Heap::empty_string()),
try_full_codegen_(false),
int end_position() const { return end_position_; }
bool is_expression() const { return is_expression_; }
bool contains_loops() const { return contains_loops_; }
- bool strict_mode() const { return strict_mode_; }
int materialized_literal_count() { return materialized_literal_count_; }
int expected_property_count() { return expected_property_count_; }
int end_position_;
bool is_expression_;
bool contains_loops_;
- bool strict_mode_;
int function_token_position_;
Handle<String> inferred_name_;
bool try_full_codegen_;
// parser.cc
DEFINE_bool(allow_natives_syntax, false, "allow natives syntax")
-DEFINE_bool(strict_mode, true, "allow strict mode directives")
// rewriter.cc
DEFINE_bool(optimize_ast, true, "optimize the ast")
V(global_eval_symbol, "GlobalEval") \
V(identity_hash_symbol, "v8::IdentityHash") \
V(closure_symbol, "(closure)") \
- V(use_strict, "use strict") \
V(KeyedLoadExternalArray_symbol, "KeyedLoadExternalArray") \
V(KeyedStoreExternalArray_symbol, "KeyedStoreExternalArray")
array_indexof_not_defined: "Array.getIndexOf: Argument undefined",
object_not_extensible: "Can't add property %0, object is not extensible",
illegal_access: "Illegal access",
- invalid_preparser_data: "Invalid preparser data for function %0",
- strict_mode_with: "Strict mode code may not include a with statement",
- strict_catch_variable: "Catch variable may not be eval or arguments in strict mode",
- strict_param_name: "Parameter name eval or arguments is not allowed in strict mode",
- strict_param_dupe: "Strict mode function may not have duplicate parameter names",
- strict_var_name: "Variable name may not be eval or arguments in strict mode",
- strict_function_name: "Function name may not be eval or arguments in strict mode",
+ invalid_preparser_data: "Invalid preparser data for function %0"
};
}
var format = kMessages[message.type];
void AddLoop() { loop_count_++; }
bool ContainsLoops() const { return loop_count_ > 0; }
- bool StrictMode() { return strict_mode_; }
- void EnableStrictMode() {
- strict_mode_ = FLAG_strict_mode;
- }
-
private:
// Captures the number of literals that need materialization in the
// function. Includes regexp literals, and boilerplate for object
// Captures the number of loops inside the scope.
int loop_count_;
- // Parsing strict mode code.
- bool strict_mode_;
-
// Bookkeeping
TemporaryScope** variable_;
TemporaryScope* parent_;
loop_count_(0),
variable_(variable),
parent_(*variable) {
- // Inherit the strict mode from the parent scope.
- strict_mode_ = (parent_ != NULL) && parent_->strict_mode_;
*variable = this;
}
int prev_level_;
};
+
// ----------------------------------------------------------------------------
// The CHECK_OK macro is a convenient macro to enforce error
// handling for functions that may fail (by returning !*ok).
0,
source->length(),
false,
- temp_scope.ContainsLoops(),
- temp_scope.StrictMode());
+ temp_scope.ContainsLoops());
} else if (stack_overflow_) {
Top::StackOverflow();
}
ASSERT(processor != NULL);
InitializationBlockFinder block_finder;
ThisNamedPropertyAssigmentFinder this_property_assignment_finder;
- bool directive_prologue = true; // Parsing directive prologue.
-
while (peek() != end_token) {
- if (directive_prologue && peek() != Token::STRING) {
- directive_prologue = false;
- }
-
- Scanner::Location token_loc = scanner().peek_location();
Statement* stat = ParseStatement(NULL, CHECK_OK);
-
- if (stat == NULL || stat->IsEmpty()) {
- directive_prologue = false; // End of directive prologue.
- continue;
- }
-
- if (directive_prologue) {
- // A shot at a directive.
- ExpressionStatement *e_stat;
- Literal *literal;
- // Still processing directive prologue?
- if ((e_stat = stat->AsExpressionStatement()) != NULL &&
- (literal = e_stat->expression()->AsLiteral()) != NULL &&
- literal->handle()->IsString()) {
- Handle<String> directive = Handle<String>::cast(literal->handle());
-
- // Check "use strict" directive (ES5 14.1).
- if (!temp_scope_->StrictMode() &&
- directive->Equals(Heap::use_strict()) &&
- token_loc.end_pos - token_loc.beg_pos ==
- Heap::use_strict()->length() + 2) {
- temp_scope_->EnableStrictMode();
- // "use strict" is the only directive for now.
- directive_prologue = false;
- }
- } else {
- // End of the directive prologue.
- directive_prologue = false;
- }
- }
-
+ if (stat == NULL || stat->IsEmpty()) continue;
// We find and mark the initialization blocks on top level code only.
// This is because the optimization prevents reuse of the map transitions,
// so it should be used only for code that will only be run once.
return result;
}
-static bool IsEvalOrArguments(Handle<String> string) {
- return string.is_identical_to(Factory::eval_symbol()) ||
- string.is_identical_to(Factory::arguments_symbol());
-}
// If the variable declaration declares exactly one non-const
// variable, then *var is set to that variable. In all other cases,
Handle<String> name = ParseIdentifier(CHECK_OK);
if (fni_ != NULL) fni_->PushVariableName(name);
- // Strict mode variables may not be named eval or arguments
- if (temp_scope_->StrictMode() && IsEvalOrArguments(name)) {
- ReportMessage("strict_var_name", Vector<const char*>::empty());
- *ok = false;
- return NULL;
- }
-
// Declare variable.
// Note that we *always* must treat the initial value via a separate init
// assignment for variables and constants because the value must be assigned
// 'with' '(' Expression ')' Statement
Expect(Token::WITH, CHECK_OK);
-
- if (temp_scope_->StrictMode()) {
- ReportMessage("strict_mode_with", Vector<const char*>::empty());
- *ok = false;
- return NULL;
- }
-
Expect(Token::LPAREN, CHECK_OK);
Expression* expr = ParseExpression(true, CHECK_OK);
Expect(Token::RPAREN, CHECK_OK);
Expect(Token::LPAREN, CHECK_OK);
Handle<String> name = ParseIdentifier(CHECK_OK);
-
- if (temp_scope_->StrictMode() && IsEvalOrArguments(name)) {
- ReportMessage("strict_catch_variable", Vector<const char*>::empty());
- *ok = false;
- return NULL;
- }
-
Expect(Token::RPAREN, CHECK_OK);
if (peek() == Token::LBRACE) {
// '(' (Identifier)*[','] ')'
Expect(Token::LPAREN, CHECK_OK);
int start_pos = scanner().location().beg_pos;
- Scanner::Location eval_loc(RelocInfo::kNoPosition, RelocInfo::kNoPosition);
- Scanner::Location dupe_loc(RelocInfo::kNoPosition, RelocInfo::kNoPosition);
-
bool done = (peek() == Token::RPAREN);
while (!done) {
Handle<String> param_name = ParseIdentifier(CHECK_OK);
- Variable* parameter = top_scope_->DeclareLocal(param_name, Variable::VAR);
-
- // Store locations for possible future error reports.
- if (eval_loc.beg_pos == RelocInfo::kNoPosition &&
- IsEvalOrArguments(param_name)) {
- // Store location for later
- eval_loc = scanner().location();
- }
- if (dupe_loc.beg_pos == RelocInfo::kNoPosition &&
- top_scope_->IsParameterDeclared(param_name)) {
- // Store location for later
- dupe_loc = scanner().location();
- }
-
- top_scope_->AddParameter(parameter);
+ top_scope_->AddParameter(top_scope_->DeclareLocal(param_name,
+ Variable::VAR));
num_parameters++;
done = (peek() == Token::RPAREN);
if (!done) Expect(Token::COMMA, CHECK_OK);
end_pos = scanner().location().end_pos;
}
- // Validate strict mode.
- if (temp_scope_->StrictMode()) {
- if (IsEvalOrArguments(name)) {
- int position = function_token_position != RelocInfo::kNoPosition
- ? function_token_position
- : (start_pos > 0 ? start_pos - 1 : start_pos);
- ReportMessageAt(Scanner::Location(position, start_pos),
- "strict_function_name", Vector<const char*>::empty());
- *ok = false;
- return NULL;
- }
- if (eval_loc.beg_pos != RelocInfo::kNoPosition) {
- ReportMessageAt(eval_loc, "strict_param_name",
- Vector<const char*>::empty());
- *ok = false;
- return NULL;
- }
- if (dupe_loc.beg_pos != RelocInfo::kNoPosition) {
- ReportMessageAt(dupe_loc, "strict_param_dupe",
- Vector<const char*>::empty());
- *ok = false;
- return NULL;
- }
- // TODO(mmaly): Check for octal escape sequence here.
- }
-
FunctionLiteral* function_literal =
new FunctionLiteral(name,
top_scope_,
start_pos,
end_pos,
function_name->length() > 0,
- temp_scope.ContainsLoops(),
- temp_scope.StrictMode());
+ temp_scope.ContainsLoops());
function_literal->set_function_token_position(function_token_position);
if (fni_ != NULL && !is_named) fni_->AddFunction(function_literal);
}
-bool Scope::IsParameterDeclared(Handle<String> name) {
- ASSERT(name->IsSymbol());
- for (int i = 0, length = num_parameters(); i < length; i ++) {
- ASSERT(parameter(i)->name()->IsSymbol());
- if (name.is_identical_to(parameter(i)->name())) {
- return true;
- }
- }
- return false;
-}
-
-
#ifdef DEBUG
static const char* Header(Scope::Type type) {
switch (type) {
int ContextChainLength(Scope* scope);
// ---------------------------------------------------------------------------
- // Strict mode support.
- bool IsParameterDeclared(Handle<String> name);
-
- // ---------------------------------------------------------------------------
// Debugging.
#ifdef DEBUG
+++ /dev/null
-// Copyright 2011 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-function CheckStrictMode(code, exception) {
- assertDoesNotThrow(code);
- assertThrows("'use strict';\n" + code, exception);
- assertThrows('"use strict";\n' + code, exception);
- assertDoesNotThrow("\
- function outer() {\
- function inner() {\n"
- + code +
- "\n}\
- }");
- assertThrows("\
- function outer() {\
- 'use strict';\
- function inner() {\n"
- + code +
- "\n}\
- }", exception);
-}
-
-// Incorrect 'use strict' directive.
-function UseStrictEscape() {
- "use\\x20strict";
- with ({}) {};
-}
-
-// 'use strict' in non-directive position.
-function UseStrictNonDirective() {
- void(0);
- "use strict";
- with ({}) {};
-}
-
-// Multiple directives, including "use strict".
-assertThrows('\
-"directive 1";\
-"another directive";\
-"use strict";\
-"directive after strict";\
-"and one more";\
-with({}) {}', SyntaxError);
-
-// 'with' disallowed in strict mode.
-CheckStrictMode("with({}) {}", SyntaxError);
-
-// Function named 'eval'.
-CheckStrictMode("function eval() {}", SyntaxError)
-
-// Function named 'arguments'.
-CheckStrictMode("function arguments() {}", SyntaxError)
-
-// Function parameter named 'eval'.
-CheckStrictMode("function foo(a, b, eval, c, d) {}", SyntaxError)
-
-// Function parameter named 'arguments'.
-CheckStrictMode("function foo(a, b, arguments, c, d) {}", SyntaxError)
-
-// Property accessor parameter named 'eval'.
-CheckStrictMode("var o = { set foo(eval) {} }", SyntaxError)
-
-// Property accessor parameter named 'arguments'.
-CheckStrictMode("var o = { set foo(arguments) {} }", SyntaxError)
-
-// Duplicate function parameter name.
-CheckStrictMode("function foo(a, b, c, d, b) {}", SyntaxError)
-
-// catch(eval)
-CheckStrictMode("try{}catch(eval){};", SyntaxError)
-
-// catch(arguments)
-CheckStrictMode("try{}catch(arguments){};", SyntaxError)
-
-// var eval
-CheckStrictMode("var eval;", SyntaxError)
-
-// var arguments
-CheckStrictMode("var arguments;", SyntaxError)
-
-// Strict mode applies to the function in which the directive is used..
-assertThrows('\
-function foo(eval) {\
- "use strict";\
-}', SyntaxError);
-
-// Strict mode doesn't affect the outer stop of strict code.
-function NotStrict(eval) {
- function Strict() {
- "use strict";
- }
- with ({}) {};
-}