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

Unified Diff: src/parser.cc

Issue 6697023: Merge 6800:7180 from the bleeding edge branch to the experimental/gc branch. (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/gc/
Patch Set: Created 9 years, 9 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/platform.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 7180)
+++ src/parser.cc (working copy)
@@ -283,11 +283,6 @@
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
@@ -305,9 +300,6 @@
// Captures the number of loops inside the scope.
int loop_count_;
- // Parsing strict mode code.
- bool strict_mode_;
-
// Bookkeeping
TemporaryScope** variable_;
TemporaryScope* parent_;
@@ -322,8 +314,6 @@
loop_count_(0),
variable_(variable),
parent_(*variable) {
- // Inherit the strict mode from the parent scope.
- strict_mode_ = (parent_ != NULL) && parent_->strict_mode_;
*variable = this;
}
@@ -665,13 +655,13 @@
scope);
TemporaryScope temp_scope(&this->temp_scope_);
if (strict_mode == kStrictMode) {
- temp_scope.EnableStrictMode();
+ top_scope_->EnableStrictMode();
}
ZoneList<Statement*>* body = new ZoneList<Statement*>(16);
bool ok = true;
int beg_loc = scanner().location().beg_pos;
ParseSourceElements(body, Token::EOS, &ok);
- if (ok && temp_scope_->StrictMode()) {
+ if (ok && top_scope_->is_strict_mode()) {
CheckOctalLiteral(beg_loc, scanner().location().end_pos, &ok);
}
if (ok) {
@@ -687,8 +677,7 @@
0,
source->length(),
false,
- temp_scope.ContainsLoops(),
- temp_scope.StrictMode());
+ temp_scope.ContainsLoops());
} else if (stack_overflow_) {
Top::StackOverflow();
}
@@ -703,38 +692,40 @@
return result;
}
-FunctionLiteral* Parser::ParseLazy(Handle<SharedFunctionInfo> info) {
+FunctionLiteral* Parser::ParseLazy(CompilationInfo* info) {
CompilationZoneScope zone_scope(DONT_DELETE_ON_EXIT);
HistogramTimerScope timer(&Counters::parse_lazy);
Handle<String> source(String::cast(script_->source()));
Counters::total_parse_size.Increment(source->length());
+ Handle<SharedFunctionInfo> shared_info = info->shared_info();
// Initialize parser state.
source->TryFlatten();
if (source->IsExternalTwoByteString()) {
ExternalTwoByteStringUC16CharacterStream stream(
Handle<ExternalTwoByteString>::cast(source),
- info->start_position(),
- info->end_position());
+ shared_info->start_position(),
+ shared_info->end_position());
FunctionLiteral* result = ParseLazy(info, &stream, &zone_scope);
return result;
} else {
GenericStringUC16CharacterStream stream(source,
- info->start_position(),
- info->end_position());
+ shared_info->start_position(),
+ shared_info->end_position());
FunctionLiteral* result = ParseLazy(info, &stream, &zone_scope);
return result;
}
}
-FunctionLiteral* Parser::ParseLazy(Handle<SharedFunctionInfo> info,
+FunctionLiteral* Parser::ParseLazy(CompilationInfo* info,
UC16CharacterStream* source,
ZoneScope* zone_scope) {
+ Handle<SharedFunctionInfo> shared_info = info->shared_info();
scanner_.Initialize(source);
ASSERT(target_stack_ == NULL);
- Handle<String> name(String::cast(info->name()));
+ Handle<String> name(String::cast(shared_info->name()));
fni_ = new FuncNameInferrer();
fni_->PushEnclosingName(name);
@@ -746,18 +737,20 @@
{
// Parse the function literal.
Handle<String> no_name = Factory::empty_symbol();
- Scope* scope =
- NewScope(top_scope_, Scope::GLOBAL_SCOPE, inside_with());
+ Scope* scope = NewScope(top_scope_, Scope::GLOBAL_SCOPE, inside_with());
+ if (!info->closure().is_null()) {
+ scope = Scope::DeserializeScopeChain(info, scope);
+ }
LexicalScope lexical_scope(&this->top_scope_, &this->with_nesting_level_,
scope);
TemporaryScope temp_scope(&this->temp_scope_);
- if (info->strict_mode()) {
- temp_scope.EnableStrictMode();
+ if (shared_info->strict_mode()) {
+ top_scope_->EnableStrictMode();
}
FunctionLiteralType type =
- info->is_expression() ? EXPRESSION : DECLARATION;
+ shared_info->is_expression() ? EXPRESSION : DECLARATION;
bool ok = true;
result = ParseFunctionLiteral(name,
false, // Strict mode name already checked.
@@ -775,7 +768,7 @@
zone_scope->DeleteOnExit();
if (stack_overflow_) Top::StackOverflow();
} else {
- Handle<String> inferred_name(info->inferred_name());
+ Handle<String> inferred_name(shared_info->inferred_name());
result->set_inferred_name(inferred_name);
}
return result;
@@ -803,10 +796,12 @@
MessageLocation location(script_,
source_location.beg_pos,
source_location.end_pos);
- Handle<JSArray> array = Factory::NewJSArray(args.length());
+ Handle<FixedArray> elements = Factory::NewFixedArray(args.length());
for (int i = 0; i < args.length(); i++) {
- SetElement(array, i, Factory::NewStringFromUtf8(CStrVector(args[i])));
+ Handle<String> arg_string = Factory::NewStringFromUtf8(CStrVector(args[i]));
+ elements->set(i, *arg_string);
}
+ Handle<JSArray> array = Factory::NewJSArrayWithElements(elements);
Handle<Object> result = Factory::NewSyntaxError(type, array);
Top::Throw(*result, &location);
}
@@ -818,10 +813,11 @@
MessageLocation location(script_,
source_location.beg_pos,
source_location.end_pos);
- Handle<JSArray> array = Factory::NewJSArray(args.length());
+ Handle<FixedArray> elements = Factory::NewFixedArray(args.length());
for (int i = 0; i < args.length(); i++) {
- SetElement(array, i, args[i]);
+ elements->set(i, *args[i]);
}
+ Handle<JSArray> array = Factory::NewJSArrayWithElements(elements);
Handle<Object> result = Factory::NewSyntaxError(type, array);
Top::Throw(*result, &location);
}
@@ -1106,8 +1102,21 @@
}
Scanner::Location token_loc = scanner().peek_location();
- Statement* stat = ParseStatement(NULL, CHECK_OK);
+ Statement* stat;
+ if (peek() == Token::FUNCTION) {
+ // FunctionDeclaration is only allowed in the context of SourceElements
+ // (Ecma 262 5th Edition, clause 14):
+ // SourceElement:
+ // Statement
+ // FunctionDeclaration
+ // Common language extension is to allow function declaration in place
+ // of any statement. This language extension is disabled in strict mode.
+ stat = ParseFunctionDeclaration(CHECK_OK);
+ } else {
+ stat = ParseStatement(NULL, CHECK_OK);
+ }
+
if (stat == NULL || stat->IsEmpty()) {
directive_prologue = false; // End of directive prologue.
continue;
@@ -1124,11 +1133,11 @@
Handle<String> directive = Handle<String>::cast(literal->handle());
// Check "use strict" directive (ES5 14.1).
- if (!temp_scope_->StrictMode() &&
+ if (!top_scope_->is_strict_mode() &&
directive->Equals(Heap::use_strict()) &&
token_loc.end_pos - token_loc.beg_pos ==
Heap::use_strict()->length() + 2) {
- temp_scope_->EnableStrictMode();
+ top_scope_->EnableStrictMode();
// "use strict" is the only directive for now.
directive_prologue = false;
}
@@ -1263,8 +1272,17 @@
return result;
}
- case Token::FUNCTION:
+ case Token::FUNCTION: {
+ // In strict mode, FunctionDeclaration is only allowed in the context
+ // of SourceElements.
+ if (top_scope_->is_strict_mode()) {
+ ReportMessageAt(scanner().peek_location(), "strict_function",
+ Vector<const char*>::empty());
+ *ok = false;
+ return NULL;
+ }
return ParseFunctionDeclaration(ok);
+ }
case Token::NATIVE:
return ParseNativeDeclaration(ok);
@@ -1515,6 +1533,11 @@
Consume(Token::VAR);
} else if (peek() == Token::CONST) {
Consume(Token::CONST);
+ if (top_scope_->is_strict_mode()) {
+ ReportMessage("strict_const", Vector<const char*>::empty());
+ *ok = false;
+ return NULL;
+ }
mode = Variable::CONST;
is_const = true;
} else {
@@ -1546,7 +1569,7 @@
if (fni_ != NULL) fni_->PushVariableName(name);
// Strict mode variables may not be named eval or arguments
- if (temp_scope_->StrictMode() && IsEvalOrArguments(name)) {
+ if (top_scope_->is_strict_mode() && IsEvalOrArguments(name)) {
ReportMessage("strict_var_name", Vector<const char*>::empty());
*ok = false;
return NULL;
@@ -1634,34 +1657,49 @@
if (top_scope_->is_global_scope()) {
// Compute the arguments for the runtime call.
- ZoneList<Expression*>* arguments = new ZoneList<Expression*>(2);
- // Be careful not to assign a value to the global variable if
- // we're in a with. The initialization value should not
- // necessarily be stored in the global object in that case,
- // which is why we need to generate a separate assignment node.
+ ZoneList<Expression*>* arguments = new ZoneList<Expression*>(3);
arguments->Add(new Literal(name)); // we have at least 1 parameter
- if (is_const || (value != NULL && !inside_with())) {
+ CallRuntime* initialize;
+
+ if (is_const) {
arguments->Add(value);
value = NULL; // zap the value to avoid the unnecessary assignment
- }
- // Construct the call to Runtime::DeclareGlobal{Variable,Const}Locally
- // and add it to the initialization statement block. Note that
- // this function does different things depending on if we have
- // 1 or 2 parameters.
- CallRuntime* initialize;
- if (is_const) {
+
+ // Construct the call to Runtime_InitializeConstGlobal
+ // and add it to the initialization statement block.
+ // Note that the function does different things depending on
+ // the number of arguments (1 or 2).
initialize =
- new CallRuntime(
- Factory::InitializeConstGlobal_symbol(),
- Runtime::FunctionForId(Runtime::kInitializeConstGlobal),
- arguments);
+ new CallRuntime(
+ Factory::InitializeConstGlobal_symbol(),
+ Runtime::FunctionForId(Runtime::kInitializeConstGlobal),
+ arguments);
} else {
+ // Add strict mode.
+ // We may want to pass singleton to avoid Literal allocations.
+ arguments->Add(NewNumberLiteral(
+ top_scope_->is_strict_mode() ? kStrictMode : kNonStrictMode));
+
+ // Be careful not to assign a value to the global variable if
+ // we're in a with. The initialization value should not
+ // necessarily be stored in the global object in that case,
+ // which is why we need to generate a separate assignment node.
+ if (value != NULL && !inside_with()) {
+ arguments->Add(value);
+ value = NULL; // zap the value to avoid the unnecessary assignment
+ }
+
+ // Construct the call to Runtime_InitializeVarGlobal
+ // and add it to the initialization statement block.
+ // Note that the function does different things depending on
+ // the number of arguments (2 or 3).
initialize =
- new CallRuntime(
- Factory::InitializeVarGlobal_symbol(),
- Runtime::FunctionForId(Runtime::kInitializeVarGlobal),
- arguments);
+ new CallRuntime(
+ Factory::InitializeVarGlobal_symbol(),
+ Runtime::FunctionForId(Runtime::kInitializeVarGlobal),
+ arguments);
}
+
block->AddStatement(new ExpressionStatement(initialize));
}
@@ -1913,7 +1951,7 @@
Expect(Token::WITH, CHECK_OK);
- if (temp_scope_->StrictMode()) {
+ if (top_scope_->is_strict_mode()) {
ReportMessage("strict_mode_with", Vector<const char*>::empty());
*ok = false;
return NULL;
@@ -2052,7 +2090,7 @@
Expect(Token::LPAREN, CHECK_OK);
Handle<String> name = ParseIdentifier(CHECK_OK);
- if (temp_scope_->StrictMode() && IsEvalOrArguments(name)) {
+ if (top_scope_->is_strict_mode() && IsEvalOrArguments(name)) {
ReportMessage("strict_catch_variable", Vector<const char*>::empty());
*ok = false;
return NULL;
@@ -2303,7 +2341,7 @@
expression = NewThrowReferenceError(type);
}
- if (temp_scope_->StrictMode()) {
+ if (top_scope_->is_strict_mode()) {
// Assignment to eval or arguments is disallowed in strict mode.
CheckStrictModeLValue(expression, "strict_lhs_assignment", CHECK_OK);
}
@@ -2522,7 +2560,7 @@
}
// "delete identifier" is a syntax error in strict mode.
- if (op == Token::DELETE && temp_scope_->StrictMode()) {
+ if (op == Token::DELETE && top_scope_->is_strict_mode()) {
VariableProxy* operand = expression->AsVariableProxy();
if (operand != NULL && !operand->is_this()) {
ReportMessage("strict_delete", Vector<const char*>::empty());
@@ -2545,7 +2583,7 @@
expression = NewThrowReferenceError(type);
}
- if (temp_scope_->StrictMode()) {
+ if (top_scope_->is_strict_mode()) {
// Prefix expression operand in strict mode may not be eval or arguments.
CheckStrictModeLValue(expression, "strict_lhs_prefix", CHECK_OK);
}
@@ -2576,7 +2614,7 @@
expression = NewThrowReferenceError(type);
}
- if (temp_scope_->StrictMode()) {
+ if (top_scope_->is_strict_mode()) {
// Postfix expression operand in strict mode may not be eval or arguments.
CheckStrictModeLValue(expression, "strict_lhs_prefix", CHECK_OK);
}
@@ -2784,7 +2822,7 @@
return ReportMessage("unexpected_token_identifier",
Vector<const char*>::empty());
case Token::FUTURE_RESERVED_WORD:
- return ReportMessage(temp_scope_->StrictMode() ?
+ return ReportMessage(top_scope_->is_strict_mode() ?
"unexpected_strict_reserved" :
"unexpected_token_identifier",
Vector<const char*>::empty());
@@ -3289,7 +3327,7 @@
new ZoneList<ObjectLiteral::Property*>(4);
int number_of_boilerplate_properties = 0;
- ObjectLiteralPropertyChecker checker(this, temp_scope_->StrictMode());
+ ObjectLiteralPropertyChecker checker(this, top_scope_->is_strict_mode());
Expect(Token::LBRACE, CHECK_OK);
Scanner::Location loc = scanner().location();
@@ -3586,7 +3624,7 @@
}
// Validate strict mode.
- if (temp_scope_->StrictMode()) {
+ if (top_scope_->is_strict_mode()) {
if (IsEvalOrArguments(name)) {
int position = function_token_position != RelocInfo::kNoPosition
? function_token_position
@@ -3640,8 +3678,7 @@
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);
@@ -3770,7 +3807,7 @@
Handle<String> Parser::ParseIdentifierOrReservedWord(bool* is_reserved,
bool* ok) {
*is_reserved = false;
- if (temp_scope_->StrictMode()) {
+ if (top_scope_->is_strict_mode()) {
Expect(Token::IDENTIFIER, ok);
} else {
if (!Check(Token::IDENTIFIER)) {
@@ -3801,7 +3838,7 @@
void Parser::CheckStrictModeLValue(Expression* expression,
const char* error,
bool* ok) {
- ASSERT(temp_scope_->StrictMode());
+ ASSERT(top_scope_->is_strict_mode());
VariableProxy* lhs = expression != NULL
? expression->AsVariableProxy()
: NULL;
@@ -3993,12 +4030,14 @@
MessageLocation location(Factory::NewScript(script),
source_location.beg_pos,
source_location.end_pos);
- int argc = (name_opt == NULL) ? 0 : 1;
- Handle<JSArray> array = Factory::NewJSArray(argc);
- if (name_opt != NULL) {
- SetElement(array,
- 0,
- Factory::NewStringFromUtf8(CStrVector(name_opt)));
+ Handle<JSArray> array;
+ if (name_opt == NULL) {
+ array = Factory::NewJSArray(0);
+ } else {
+ Handle<String> name = Factory::NewStringFromUtf8(CStrVector(name_opt));
+ Handle<FixedArray> element = Factory::NewFixedArray(1);
+ element->set(0, *name);
+ array = Factory::NewJSArrayWithElements(element);
}
Handle<Object> result = Factory::NewSyntaxError(message, array);
Top::Throw(*result, &location);
@@ -4070,7 +4109,7 @@
if (value.is_null()) return Handle<Object>::null();
uint32_t index;
if (key->AsArrayIndex(&index)) {
- SetOwnElement(json_object, index, value);
+ SetOwnElement(json_object, index, value, kNonStrictMode);
} else if (key->Equals(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
@@ -4273,6 +4312,8 @@
capture_index);
}
builder->AddAtom(body);
+ // For compatability with JSC and ES3, we allow quantifiers after
+ // lookaheads, and break in all cases.
break;
}
case '|': {
@@ -4346,7 +4387,7 @@
type,
captures_started());
builder = stored_state->builder();
- break;
+ continue;
}
case '[': {
RegExpTree* atom = ParseCharacterClass(CHECK_FAILED);
@@ -4369,11 +4410,11 @@
builder->AddAssertion(
new RegExpAssertion(RegExpAssertion::NON_BOUNDARY));
continue;
- // AtomEscape ::
- // CharacterClassEscape
- //
- // CharacterClassEscape :: one of
- // d D s S w W
+ // AtomEscape ::
+ // CharacterClassEscape
+ //
+ // CharacterClassEscape :: one of
+ // d D s S w W
case 'd': case 'D': case 's': case 'S': case 'w': case 'W': {
uc32 c = Next();
Advance(2);
@@ -5089,10 +5130,10 @@
Handle<Script> script = info->script();
if (info->is_lazy()) {
Parser parser(script, true, NULL, NULL);
- result = parser.ParseLazy(info->shared_info());
+ result = parser.ParseLazy(info);
} else {
bool allow_natives_syntax =
- FLAG_allow_natives_syntax || Bootstrapper::IsActive();
+ info->allows_natives_syntax() || FLAG_allow_natives_syntax;
ScriptDataImpl* pre_data = info->pre_parse_data();
Parser parser(script, allow_natives_syntax, info->extension(), pre_data);
if (pre_data != NULL && pre_data->has_error()) {
« no previous file with comments | « src/parser.h ('k') | src/platform.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698