Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(239)

Unified Diff: src/parser.cc

Issue 6606006: [Isolates] Merge 6500:6700 from bleeding_edge to isolates. (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/isolates/
Patch Set: '' Created 9 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/parser.h ('k') | src/preparser.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/parser.cc
===================================================================
--- src/parser.cc (revision 7006)
+++ src/parser.cc (working copy)
@@ -622,7 +622,8 @@
FunctionLiteral* Parser::ParseProgram(Handle<String> source,
- bool in_global_context) {
+ bool in_global_context,
+ StrictModeFlag strict_mode) {
CompilationZoneScope zone_scope(DONT_DELETE_ON_EXIT);
HistogramTimerScope timer(COUNTERS->parse());
@@ -638,17 +639,18 @@
ExternalTwoByteStringUC16CharacterStream stream(
Handle<ExternalTwoByteString>::cast(source), 0, source->length());
scanner_.Initialize(&stream);
- return DoParseProgram(source, in_global_context, &zone_scope);
+ return DoParseProgram(source, in_global_context, strict_mode, &zone_scope);
} else {
GenericStringUC16CharacterStream stream(source, 0, source->length());
scanner_.Initialize(&stream);
- return DoParseProgram(source, in_global_context, &zone_scope);
+ return DoParseProgram(source, in_global_context, strict_mode, &zone_scope);
}
}
FunctionLiteral* Parser::DoParseProgram(Handle<String> source,
bool in_global_context,
+ StrictModeFlag strict_mode,
ZoneScope* zone_scope) {
ASSERT(target_stack_ == NULL);
if (pre_data_ != NULL) pre_data_->Initialize();
@@ -668,6 +670,9 @@
LexicalScope lexical_scope(&this->top_scope_, &this->with_nesting_level_,
scope);
TemporaryScope temp_scope(&this->temp_scope_);
+ if (strict_mode == kStrictMode) {
+ temp_scope.EnableStrictMode();
+ }
ZoneList<Statement*>* body = new ZoneList<Statement*>(16);
bool ok = true;
int beg_loc = scanner().location().beg_pos;
@@ -753,14 +758,18 @@
scope);
TemporaryScope temp_scope(&this->temp_scope_);
+ if (info->strict_mode()) {
+ temp_scope.EnableStrictMode();
+ }
+
FunctionLiteralType type =
info->is_expression() ? EXPRESSION : DECLARATION;
bool ok = true;
- result = ParseFunctionLiteral(name, RelocInfo::kNoPosition, type, &ok);
+ result = ParseFunctionLiteral(name,
+ false, // Strict mode name already checked.
+ RelocInfo::kNoPosition, type, &ok);
// Make sure the results agree.
ASSERT(ok == (result != NULL));
- // The only errors should be stack overflows.
- ASSERT(ok || stack_overflow_);
}
// Make sure the target stack is empty.
@@ -769,8 +778,8 @@
// If there was a stack overflow we have to get rid of AST and it is
// not safe to do before scope has been deleted.
if (result == NULL) {
- isolate()->StackOverflow();
zone_scope->DeleteOnExit();
+ if (stack_overflow_) isolate()->StackOverflow();
} else {
Handle<String> inferred_name(info->inferred_name());
result->set_inferred_name(inferred_name);
@@ -1446,8 +1455,10 @@
// 'function' Identifier '(' FormalParameterListopt ')' '{' FunctionBody '}'
Expect(Token::FUNCTION, CHECK_OK);
int function_token_position = scanner().location().beg_pos;
- Handle<String> name = ParseIdentifier(CHECK_OK);
+ bool is_reserved = false;
+ Handle<String> name = ParseIdentifierOrReservedWord(&is_reserved, CHECK_OK);
FunctionLiteral* fun = ParseFunctionLiteral(name,
+ is_reserved,
function_token_position,
DECLARATION,
CHECK_OK);
@@ -1706,7 +1717,7 @@
// ExpressionStatement | LabelledStatement ::
// Expression ';'
// Identifier ':' Statement
- bool starts_with_idenfifier = (peek() == Token::IDENTIFIER);
+ bool starts_with_idenfifier = peek_any_identifier();
Expression* expr = ParseExpression(true, CHECK_OK);
if (peek() == Token::COLON && starts_with_idenfifier && expr &&
expr->AsVariableProxy() != NULL &&
@@ -2302,6 +2313,11 @@
expression = NewThrowReferenceError(type);
}
+ if (temp_scope_->StrictMode()) {
+ // Assignment to eval or arguments is disallowed in strict mode.
+ CheckStrictModeLValue(expression, "strict_lhs_assignment", CHECK_OK);
+ }
+
Token::Value op = Next(); // Get assignment operator.
int pos = scanner().location().beg_pos;
Expression* right = ParseAssignmentExpression(accept_IN, CHECK_OK);
@@ -2529,6 +2545,12 @@
isolate()->factory()->invalid_lhs_in_prefix_op_symbol();
expression = NewThrowReferenceError(type);
}
+
+ if (temp_scope_->StrictMode()) {
+ // Prefix expression operand in strict mode may not be eval or arguments.
+ CheckStrictModeLValue(expression, "strict_lhs_prefix", CHECK_OK);
+ }
+
int position = scanner().location().beg_pos;
IncrementOperation* increment = new IncrementOperation(op, expression);
return new CountOperation(true /* prefix */, increment, position);
@@ -2555,6 +2577,12 @@
isolate()->factory()->invalid_lhs_in_postfix_op_symbol();
expression = NewThrowReferenceError(type);
}
+
+ if (temp_scope_->StrictMode()) {
+ // Postfix expression operand in strict mode may not be eval or arguments.
+ CheckStrictModeLValue(expression, "strict_lhs_prefix", CHECK_OK);
+ }
+
Token::Value next = Next();
int position = scanner().location().beg_pos;
IncrementOperation* increment = new IncrementOperation(next, expression);
@@ -2684,9 +2712,12 @@
Expect(Token::FUNCTION, CHECK_OK);
int function_token_position = scanner().location().beg_pos;
Handle<String> name;
- if (peek() == Token::IDENTIFIER) name = ParseIdentifier(CHECK_OK);
- result = ParseFunctionLiteral(name, function_token_position,
- NESTED, CHECK_OK);
+ bool is_reserved_name = false;
+ if (peek_any_identifier()) {
+ name = ParseIdentifierOrReservedWord(&is_reserved_name, CHECK_OK);
+ }
+ result = ParseFunctionLiteral(name, is_reserved_name,
+ function_token_position, NESTED, CHECK_OK);
} else {
result = ParsePrimaryExpression(CHECK_OK);
}
@@ -2755,6 +2786,11 @@
case Token::IDENTIFIER:
return ReportMessage("unexpected_token_identifier",
Vector<const char*>::empty());
+ case Token::FUTURE_RESERVED_WORD:
+ return ReportMessage(temp_scope_->StrictMode() ?
+ "unexpected_strict_reserved" :
+ "unexpected_token_identifier",
+ Vector<const char*>::empty());
default:
const char* name = Token::String(token);
ASSERT(name != NULL);
@@ -2810,7 +2846,8 @@
result = new Literal(isolate()->factory()->false_value());
break;
- case Token::IDENTIFIER: {
+ case Token::IDENTIFIER:
+ case Token::FUTURE_RESERVED_WORD: {
Handle<String> name = ParseIdentifier(CHECK_OK);
if (fni_ != NULL) fni_->PushVariableName(name);
result = top_scope_->NewUnresolved(name, inside_with());
@@ -3031,7 +3068,7 @@
// Defined in ast.cc
bool IsEqualString(void* first, void* second);
-bool IsEqualSmi(void* first, void* second);
+bool IsEqualNumber(void* first, void* second);
// Validation per 11.1.5 Object Initialiser
@@ -3039,7 +3076,7 @@
public:
ObjectLiteralPropertyChecker(Parser* parser, bool strict) :
props(&IsEqualString),
- elems(&IsEqualSmi),
+ elems(&IsEqualNumber),
parser_(parser),
strict_(strict) {
}
@@ -3088,13 +3125,12 @@
uint32_t hash;
HashMap* map;
void* key;
- Smi* smi_key_location;
if (handle->IsSymbol()) {
Handle<String> name(String::cast(*handle));
if (name->AsArrayIndex(&hash)) {
- smi_key_location = Smi::FromInt(hash);
- key = &smi_key_location;
+ Handle<Object> key_handle = FACTORY->NewNumberFromUint(hash);
+ key = key_handle.location();
map = &elems;
} else {
key = handle.location();
@@ -3218,6 +3254,7 @@
Token::Value next = Next();
bool is_keyword = Token::IsKeyword(next);
if (next == Token::IDENTIFIER || next == Token::NUMBER ||
+ next == Token::FUTURE_RESERVED_WORD ||
next == Token::STRING || is_keyword) {
Handle<String> name;
if (is_keyword) {
@@ -3227,6 +3264,7 @@
}
FunctionLiteral* value =
ParseFunctionLiteral(name,
+ false, // reserved words are allowed here
RelocInfo::kNoPosition,
DECLARATION,
CHECK_OK);
@@ -3269,6 +3307,7 @@
Scanner::Location loc = scanner().peek_location();
switch (next) {
+ case Token::FUTURE_RESERVED_WORD:
case Token::IDENTIFIER: {
bool is_getter = false;
bool is_setter = false;
@@ -3417,6 +3456,7 @@
FunctionLiteral* Parser::ParseFunctionLiteral(Handle<String> var_name,
+ bool name_is_reserved,
int function_token_position,
FunctionLiteralType type,
bool* ok) {
@@ -3451,10 +3491,13 @@
int start_pos = scanner().location().beg_pos;
Scanner::Location name_loc = Scanner::NoLocation();
Scanner::Location dupe_loc = Scanner::NoLocation();
+ Scanner::Location reserved_loc = Scanner::NoLocation();
bool done = (peek() == Token::RPAREN);
while (!done) {
- Handle<String> param_name = ParseIdentifier(CHECK_OK);
+ bool is_reserved = false;
+ Handle<String> param_name =
+ ParseIdentifierOrReservedWord(&is_reserved, CHECK_OK);
// Store locations for possible future error reports.
if (!name_loc.IsValid() && IsEvalOrArguments(param_name)) {
@@ -3463,10 +3506,19 @@
if (!dupe_loc.IsValid() && top_scope_->IsDeclared(param_name)) {
dupe_loc = scanner().location();
}
+ if (!reserved_loc.IsValid() && is_reserved) {
+ reserved_loc = scanner().location();
+ }
Variable* parameter = top_scope_->DeclareLocal(param_name, Variable::VAR);
top_scope_->AddParameter(parameter);
num_parameters++;
+ if (num_parameters > kMaxNumFunctionParameters) {
+ ReportMessageAt(scanner().location(), "too_many_parameters",
+ Vector<const char*>::empty());
+ *ok = false;
+ return NULL;
+ }
done = (peek() == Token::RPAREN);
if (!done) Expect(Token::COMMA, CHECK_OK);
}
@@ -3544,7 +3596,8 @@
int position = function_token_position != RelocInfo::kNoPosition
? function_token_position
: (start_pos > 0 ? start_pos - 1 : start_pos);
- ReportMessageAt(Scanner::Location(position, start_pos),
+ Scanner::Location location = Scanner::Location(position, start_pos);
+ ReportMessageAt(location,
"strict_function_name", Vector<const char*>::empty());
*ok = false;
return NULL;
@@ -3561,6 +3614,22 @@
*ok = false;
return NULL;
}
+ if (name_is_reserved) {
+ int position = function_token_position != RelocInfo::kNoPosition
+ ? function_token_position
+ : (start_pos > 0 ? start_pos - 1 : start_pos);
+ Scanner::Location location = Scanner::Location(position, start_pos);
+ ReportMessageAt(location, "strict_reserved_word",
+ Vector<const char*>::empty());
+ *ok = false;
+ return NULL;
+ }
+ if (reserved_loc.IsValid()) {
+ ReportMessageAt(reserved_loc, "strict_reserved_word",
+ Vector<const char*>::empty());
+ *ok = false;
+ return NULL;
+ }
CheckOctalLiteral(start_pos, end_pos, CHECK_OK);
}
@@ -3632,6 +3701,13 @@
}
+bool Parser::peek_any_identifier() {
+ Token::Value next = peek();
+ return next == Token::IDENTIFIER ||
+ next == Token::FUTURE_RESERVED_WORD;
+}
+
+
void Parser::Consume(Token::Value token) {
Token::Value next = Next();
USE(next);
@@ -3691,7 +3767,22 @@
Handle<String> Parser::ParseIdentifier(bool* ok) {
- Expect(Token::IDENTIFIER, ok);
+ bool is_reserved;
+ return ParseIdentifierOrReservedWord(&is_reserved, ok);
+}
+
+
+Handle<String> Parser::ParseIdentifierOrReservedWord(bool* is_reserved,
+ bool* ok) {
+ *is_reserved = false;
+ if (temp_scope_->StrictMode()) {
+ Expect(Token::IDENTIFIER, ok);
+ } else {
+ if (!Check(Token::IDENTIFIER)) {
+ Expect(Token::FUTURE_RESERVED_WORD, ok);
+ *is_reserved = true;
+ }
+ }
if (!*ok) return Handle<String>();
return GetSymbol(ok);
}
@@ -3699,7 +3790,9 @@
Handle<String> Parser::ParseIdentifierName(bool* ok) {
Token::Value next = Next();
- if (next != Token::IDENTIFIER && !Token::IsKeyword(next)) {
+ if (next != Token::IDENTIFIER &&
+ next != Token::FUTURE_RESERVED_WORD &&
+ !Token::IsKeyword(next)) {
ReportUnexpectedToken(next);
*ok = false;
return Handle<String>();
@@ -3707,6 +3800,24 @@
return GetSymbol(ok);
}
+
+// Checks LHS expression for assignment and prefix/postfix increment/decrement
+// in strict mode.
+void Parser::CheckStrictModeLValue(Expression* expression,
+ const char* error,
+ bool* ok) {
+ ASSERT(temp_scope_->StrictMode());
+ VariableProxy* lhs = expression != NULL
+ ? expression->AsVariableProxy()
+ : NULL;
+
+ if (lhs != NULL && !lhs->is_this() && IsEvalOrArguments(lhs->name())) {
+ ReportMessage(error, Vector<const char*>::empty());
+ *ok = false;
+ }
+}
+
+
// Checks whether octal literal last seen is between beg_pos and end_pos.
// If so, reports an error.
void Parser::CheckOctalLiteral(int beg_pos, int end_pos, bool* ok) {
@@ -3721,20 +3832,18 @@
// This function reads an identifier and determines whether or not it
-// is 'get' or 'set'. The reason for not using ParseIdentifier and
-// checking on the output is that this involves heap allocation which
-// we can't do during preparsing.
+// is 'get' or 'set'.
Handle<String> Parser::ParseIdentifierOrGetOrSet(bool* is_get,
bool* is_set,
bool* ok) {
- Expect(Token::IDENTIFIER, ok);
+ Handle<String> result = ParseIdentifier(ok);
if (!*ok) return Handle<String>();
if (scanner().is_literal_ascii() && scanner().literal_length() == 3) {
const char* token = scanner().literal_ascii_string().start();
*is_get = strncmp(token, "get", 3) == 0;
*is_set = !*is_get && strncmp(token, "set", 3) == 0;
}
- return GetSymbol(ok);
+ return result;
}
@@ -3878,6 +3987,7 @@
message = "unexpected_token_string";
break;
case Token::IDENTIFIER:
+ case Token::FUTURE_RESERVED_WORD:
message = "unexpected_token_identifier";
break;
default:
@@ -3928,16 +4038,10 @@
Handle<Object> JsonParser::ParseJsonValue() {
Token::Value token = scanner_.Next();
switch (token) {
- case Token::STRING: {
+ case Token::STRING:
return GetString();
- }
- case Token::NUMBER: {
- ASSERT(scanner_.is_literal_ascii());
- double value = StringToDouble(scanner_.literal_ascii_string(),
- NO_FLAGS, // Hex, octal or trailing junk.
- OS::nan_value());
- return isolate()->factory()->NewNumber(value);
- }
+ case Token::NUMBER:
+ return isolate()->factory()->NewNumber(scanner_.number());
case Token::FALSE_LITERAL:
return isolate()->factory()->false_value();
case Token::TRUE_LITERAL:
@@ -3980,6 +4084,11 @@
uint32_t index;
if (key->AsArrayIndex(&index)) {
SetOwnElement(json_object, index, value);
+ } else if (key->Equals(isolate()->heap()->Proto_symbol())) {
+ // We can't remove the __proto__ accessor since it's hardcoded
+ // in several places. Instead go along and add the value as
+ // the prototype of the created object if possible.
+ SetPrototype(json_object, value);
} else {
SetLocalPropertyIgnoreAttributes(json_object, key, value, NONE);
}
@@ -4991,7 +5100,9 @@
ASSERT(info->isolate()->has_pending_exception());
} else {
Handle<String> source = Handle<String>(String::cast(script->source()));
- result = parser.ParseProgram(source, info->is_global());
+ result = parser.ParseProgram(source,
+ info->is_global(),
+ info->StrictMode());
}
}
« no previous file with comments | « src/parser.h ('k') | src/preparser.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698