Upgrade to V8 3.3
Merge V8 at 3.3.10.39
Simple merge required updates to makefiles only.
Bug: 5688872
Change-Id: I14703f418235f5ce6013b9b3e2e502407a9f6dfd
diff --git a/src/preparser.h b/src/preparser.h
index b7fa6c7..2efd53e 100644
--- a/src/preparser.h
+++ b/src/preparser.h
@@ -1,4 +1,4 @@
-// Copyright 2010 the V8 project authors. All rights reserved.
+// 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:
@@ -33,7 +33,7 @@
// Preparsing checks a JavaScript program and emits preparse-data that helps
// a later parsing to be faster.
-// See preparse-data.h for the data.
+// See preparse-data-format.h for the data format.
// The PreParser checks that the syntax follows the grammar for JavaScript,
// and collects some information about the program along the way.
@@ -67,41 +67,226 @@
}
private:
+ // These types form an algebra over syntactic categories that is just
+ // rich enough to let us recognize and propagate the constructs that
+ // are either being counted in the preparser data, or is important
+ // to throw the correct syntax error exceptions.
+
enum ScopeType {
kTopLevelScope,
kFunctionScope
};
- // Types that allow us to recognize simple this-property assignments.
- // A simple this-property assignment is a statement on the form
- // "this.propertyName = {primitive constant or function parameter name);"
- // where propertyName isn't "__proto__".
- // The result is only relevant if the function body contains only
- // simple this-property assignments.
+ class Expression;
- enum StatementType {
- kUnknownStatement
+ class Identifier {
+ public:
+ static Identifier Default() {
+ return Identifier(kUnknownIdentifier);
+ }
+ static Identifier Eval() {
+ return Identifier(kEvalIdentifier);
+ }
+ static Identifier Arguments() {
+ return Identifier(kArgumentsIdentifier);
+ }
+ static Identifier FutureReserved() {
+ return Identifier(kFutureReservedIdentifier);
+ }
+ bool IsEval() { return type_ == kEvalIdentifier; }
+ bool IsArguments() { return type_ == kArgumentsIdentifier; }
+ bool IsEvalOrArguments() { return type_ >= kEvalIdentifier; }
+ bool IsFutureReserved() { return type_ == kFutureReservedIdentifier; }
+ bool IsValidStrictVariable() { return type_ == kUnknownIdentifier; }
+ private:
+ enum Type {
+ kUnknownIdentifier,
+ kFutureReservedIdentifier,
+ kEvalIdentifier,
+ kArgumentsIdentifier
+ };
+ explicit Identifier(Type type) : type_(type) { }
+ Type type_;
+
+ friend class Expression;
};
- enum ExpressionType {
- kUnknownExpression,
- kIdentifierExpression, // Used to detect labels.
- kThisExpression,
- kThisPropertyExpression
+ // Bits 0 and 1 are used to identify the type of expression:
+ // If bit 0 is set, it's an identifier.
+ // if bit 1 is set, it's a string literal.
+ // If neither is set, it's no particular type, and both set isn't
+ // use yet.
+ // Bit 2 is used to mark the expression as being parenthesized,
+ // so "(foo)" isn't recognized as a pure identifier (and possible label).
+ class Expression {
+ public:
+ static Expression Default() {
+ return Expression(kUnknownExpression);
+ }
+
+ static Expression FromIdentifier(Identifier id) {
+ return Expression(kIdentifierFlag | (id.type_ << kIdentifierShift));
+ }
+
+ static Expression StringLiteral() {
+ return Expression(kUnknownStringLiteral);
+ }
+
+ static Expression UseStrictStringLiteral() {
+ return Expression(kUseStrictString);
+ }
+
+ static Expression This() {
+ return Expression(kThisExpression);
+ }
+
+ static Expression ThisProperty() {
+ return Expression(kThisPropertyExpression);
+ }
+
+ static Expression StrictFunction() {
+ return Expression(kStrictFunctionExpression);
+ }
+
+ bool IsIdentifier() {
+ return (code_ & kIdentifierFlag) != 0;
+ }
+
+ // Only works corretly if it is actually an identifier expression.
+ PreParser::Identifier AsIdentifier() {
+ return PreParser::Identifier(
+ static_cast<PreParser::Identifier::Type>(code_ >> kIdentifierShift));
+ }
+
+ bool IsParenthesized() {
+ // If bit 0 or 1 is set, we interpret bit 2 as meaning parenthesized.
+ return (code_ & 7) > 4;
+ }
+
+ bool IsRawIdentifier() {
+ return !IsParenthesized() && IsIdentifier();
+ }
+
+ bool IsStringLiteral() { return (code_ & kStringLiteralFlag) != 0; }
+
+ bool IsRawStringLiteral() {
+ return !IsParenthesized() && IsStringLiteral();
+ }
+
+ bool IsUseStrictLiteral() {
+ return (code_ & kStringLiteralMask) == kUseStrictString;
+ }
+
+ bool IsThis() {
+ return code_ == kThisExpression;
+ }
+
+ bool IsThisProperty() {
+ return code_ == kThisPropertyExpression;
+ }
+
+ bool IsStrictFunction() {
+ return code_ == kStrictFunctionExpression;
+ }
+
+ Expression Parenthesize() {
+ int type = code_ & 3;
+ if (type != 0) {
+ // Identifiers and string literals can be parenthesized.
+ // They no longer work as labels or directive prologues,
+ // but are still recognized in other contexts.
+ return Expression(code_ | kParentesizedExpressionFlag);
+ }
+ // For other types of expressions, it's not important to remember
+ // the parentheses.
+ return *this;
+ }
+
+ private:
+ // First two/three bits are used as flags.
+ // Bit 0 and 1 represent identifiers or strings literals, and are
+ // mutually exclusive, but can both be absent.
+ // If bit 0 or 1 are set, bit 2 marks that the expression has
+ // been wrapped in parentheses (a string literal can no longer
+ // be a directive prologue, and an identifier can no longer be
+ // a label.
+ enum {
+ kUnknownExpression = 0,
+ // Identifiers
+ kIdentifierFlag = 1, // Used to detect labels.
+ kIdentifierShift = 3,
+
+ kStringLiteralFlag = 2, // Used to detect directive prologue.
+ kUnknownStringLiteral = kStringLiteralFlag,
+ kUseStrictString = kStringLiteralFlag | 8,
+ kStringLiteralMask = kUseStrictString,
+
+ kParentesizedExpressionFlag = 4, // Only if identifier or string literal.
+
+ // Below here applies if neither identifier nor string literal.
+ kThisExpression = 4,
+ kThisPropertyExpression = 8,
+ kStrictFunctionExpression = 12
+ };
+
+ explicit Expression(int expression_code) : code_(expression_code) { }
+
+ int code_;
};
- enum IdentifierType {
- kUnknownIdentifier
+ class Statement {
+ public:
+ static Statement Default() {
+ return Statement(kUnknownStatement);
+ }
+
+ static Statement FunctionDeclaration() {
+ return Statement(kFunctionDeclaration);
+ }
+
+ // Creates expression statement from expression.
+ // Preserves being an unparenthesized string literal, possibly
+ // "use strict".
+ static Statement ExpressionStatement(Expression expression) {
+ if (!expression.IsParenthesized()) {
+ if (expression.IsUseStrictLiteral()) {
+ return Statement(kUseStrictExpressionStatement);
+ }
+ if (expression.IsStringLiteral()) {
+ return Statement(kStringLiteralExpressionStatement);
+ }
+ }
+ return Default();
+ }
+
+ bool IsStringLiteral() {
+ return code_ != kUnknownStatement;
+ }
+
+ bool IsUseStrictLiteral() {
+ return code_ == kUseStrictExpressionStatement;
+ }
+
+ bool IsFunctionDeclaration() {
+ return code_ == kFunctionDeclaration;
+ }
+
+ private:
+ enum Type {
+ kUnknownStatement,
+ kStringLiteralExpressionStatement,
+ kUseStrictExpressionStatement,
+ kFunctionDeclaration
+ };
+
+ explicit Statement(Type code) : code_(code) {}
+ Type code_;
};
- enum SourceElementTypes {
+ enum SourceElements {
kUnknownSourceElements
};
- typedef int SourceElements;
- typedef int Expression;
- typedef int Statement;
- typedef int Identifier;
typedef int Arguments;
class Scope {
@@ -112,7 +297,8 @@
type_(type),
materialized_literal_count_(0),
expected_properties_(0),
- with_nesting_count_(0) {
+ with_nesting_count_(0),
+ strict_((prev_ != NULL) && prev_->is_strict()) {
*variable = this;
}
~Scope() { *variable_ = prev_; }
@@ -122,6 +308,8 @@
int expected_properties() { return expected_properties_; }
int materialized_literal_count() { return materialized_literal_count_; }
bool IsInsideWith() { return with_nesting_count_ != 0; }
+ bool is_strict() { return strict_; }
+ void set_strict() { strict_ = true; }
void EnterWith() { with_nesting_count_++; }
void LeaveWith() { with_nesting_count_--; }
@@ -132,6 +320,7 @@
int materialized_literal_count_;
int expected_properties_;
int with_nesting_count_;
+ bool strict_;
};
// Private constructor only used in PreParseProgram.
@@ -143,6 +332,8 @@
log_(log),
scope_(NULL),
stack_limit_(stack_limit),
+ strict_mode_violation_location_(i::Scanner::Location::invalid()),
+ strict_mode_violation_type_(NULL),
stack_overflow_(false),
allow_lazy_(true),
parenthesized_function_(false) { }
@@ -152,10 +343,13 @@
PreParseResult PreParse() {
Scope top_scope(&scope_, kTopLevelScope);
bool ok = true;
+ int start_position = scanner_->peek_location().beg_pos;
ParseSourceElements(i::Token::EOS, &ok);
if (stack_overflow_) return kPreParseStackOverflow;
if (!ok) {
ReportUnexpectedToken(scanner_->current_token());
+ } else if (scope_->is_strict()) {
+ CheckOctalLiteral(start_position, scanner_->location().end_pos, &ok);
}
return kPreParseSuccess;
}
@@ -169,6 +363,8 @@
log_->LogMessage(start_pos, end_pos, type, name_opt);
}
+ void CheckOctalLiteral(int beg_pos, int end_pos, bool* ok);
+
// All ParseXXX functions take as the last argument an *ok parameter
// which is set to false if parsing failed; it is unchanged otherwise.
// By making the 'exception handling' explicit, we are forced to check
@@ -245,6 +441,12 @@
bool peek_any_identifier();
+ void set_strict_mode() {
+ scope_->set_strict();
+ }
+
+ bool strict_mode() { return scope_->is_strict(); }
+
void Consume(i::Token::Value token) { Next(); }
void Expect(i::Token::Value token, bool* ok) {
@@ -265,10 +467,23 @@
static int Precedence(i::Token::Value tok, bool accept_IN);
+ void SetStrictModeViolation(i::Scanner::Location,
+ const char* type,
+ bool *ok);
+
+ void CheckDelayedStrictModeViolation(int beg_pos, int end_pos, bool* ok);
+
+ void StrictModeIdentifierViolation(i::Scanner::Location,
+ const char* eval_args_type,
+ Identifier identifier,
+ bool* ok);
+
i::JavaScriptScanner* scanner_;
i::ParserRecorder* log_;
Scope* scope_;
uintptr_t stack_limit_;
+ i::Scanner::Location strict_mode_violation_location_;
+ const char* strict_mode_violation_type_;
bool stack_overflow_;
bool allow_lazy_;
bool parenthesized_function_;