Commit cbf08248 authored by keuchel@chromium.org's avatar keuchel@chromium.org

Make the parser track the language mode instead of keeping its own harmony flag.

So far the parser had its own harmony flag to disable the harmony scoping
feature when parsing native functions. With the introduction of the extended
language mode this becomes unnecessary because native functions will never enter
the extended mode. The parser can thus track FLAG_harmony_scoping and the
language mode of the current scope to see if harmony features are allowed. The
scanner and preparser have to keep their flag, because they can't use
FLAG_harmony_scoping as it is not available for the preparser-process
executable.

This depends on:
http://codereview.chromium.org/8417035/

Review URL: http://codereview.chromium.org/8562002

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@10063 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 1e9a7267
...@@ -601,8 +601,8 @@ Parser::Parser(Handle<Script> script, ...@@ -601,8 +601,8 @@ Parser::Parser(Handle<Script> script,
fni_(NULL), fni_(NULL),
allow_natives_syntax_(allow_natives_syntax), allow_natives_syntax_(allow_natives_syntax),
stack_overflow_(false), stack_overflow_(false),
parenthesized_function_(false), parenthesized_function_(false) {
harmony_scoping_(false) { scanner().SetHarmonyScoping(FLAG_harmony_scoping);
AstNode::ResetIds(); AstNode::ResetIds();
} }
...@@ -665,7 +665,7 @@ FunctionLiteral* Parser::DoParseProgram(CompilationInfo* info, ...@@ -665,7 +665,7 @@ FunctionLiteral* Parser::DoParseProgram(CompilationInfo* info,
CheckOctalLiteral(beg_loc, scanner().location().end_pos, &ok); CheckOctalLiteral(beg_loc, scanner().location().end_pos, &ok);
} }
if (ok && harmony_scoping_) { if (ok && is_extended_mode()) {
CheckConflictingVarDeclarations(scope, &ok); CheckConflictingVarDeclarations(scope, &ok);
} }
...@@ -833,10 +833,6 @@ void Parser::ReportMessageAt(Scanner::Location source_location, ...@@ -833,10 +833,6 @@ void Parser::ReportMessageAt(Scanner::Location source_location,
isolate()->Throw(*result, &location); isolate()->Throw(*result, &location);
} }
void Parser::SetHarmonyScoping(bool block_scoping) {
scanner().SetHarmonyScoping(block_scoping);
harmony_scoping_ = block_scoping;
}
// Base class containing common code for the different finder classes used by // Base class containing common code for the different finder classes used by
// the parser. // the parser.
...@@ -1199,7 +1195,8 @@ void* Parser::ParseSourceElements(ZoneList<Statement*>* processor, ...@@ -1199,7 +1195,8 @@ void* Parser::ParseSourceElements(ZoneList<Statement*>* processor,
directive->Equals(isolate()->heap()->use_strict()) && directive->Equals(isolate()->heap()->use_strict()) &&
token_loc.end_pos - token_loc.beg_pos == token_loc.end_pos - token_loc.beg_pos ==
isolate()->heap()->use_strict()->length() + 2) { isolate()->heap()->use_strict()->length() + 2) {
top_scope_->SetLanguageMode(harmony_scoping_ // TODO(ES6): Fix entering extended mode, once it is specified.
top_scope_->SetLanguageMode(FLAG_harmony_scoping
? EXTENDED_MODE : STRICT_MODE); ? EXTENDED_MODE : STRICT_MODE);
// "use strict" is the only directive for now. // "use strict" is the only directive for now.
directive_prologue = false; directive_prologue = false;
...@@ -1413,7 +1410,7 @@ VariableProxy* Parser::Declare(Handle<String> name, ...@@ -1413,7 +1410,7 @@ VariableProxy* Parser::Declare(Handle<String> name,
var->mode() == CONST || var->mode() == CONST ||
var->mode() == CONST_HARMONY || var->mode() == CONST_HARMONY ||
var->mode() == LET); var->mode() == LET);
if (harmony_scoping_) { if (is_extended_mode()) {
// In harmony mode we treat re-declarations as early errors. See // In harmony mode we treat re-declarations as early errors. See
// ES5 16 for a definition of early errors. // ES5 16 for a definition of early errors.
SmartArrayPointer<char> c_string = name->ToCString(DISALLOW_NULLS); SmartArrayPointer<char> c_string = name->ToCString(DISALLOW_NULLS);
...@@ -1585,7 +1582,7 @@ Statement* Parser::ParseFunctionDeclaration(bool* ok) { ...@@ -1585,7 +1582,7 @@ Statement* Parser::ParseFunctionDeclaration(bool* ok) {
// Even if we're not at the top-level of the global or a function // Even if we're not at the top-level of the global or a function
// scope, we treat is as such and introduce the function with it's // scope, we treat is as such and introduce the function with it's
// initial value upon entering the corresponding scope. // initial value upon entering the corresponding scope.
VariableMode mode = harmony_scoping_ ? LET : VAR; VariableMode mode = is_extended_mode() ? LET : VAR;
Declare(name, mode, fun, true, CHECK_OK); Declare(name, mode, fun, true, CHECK_OK);
return EmptyStatement(); return EmptyStatement();
} }
...@@ -2326,7 +2323,7 @@ TryStatement* Parser::ParseTryStatement(bool* ok) { ...@@ -2326,7 +2323,7 @@ TryStatement* Parser::ParseTryStatement(bool* ok) {
if (peek() == Token::LBRACE) { if (peek() == Token::LBRACE) {
Target target(&this->target_stack_, &catch_collector); Target target(&this->target_stack_, &catch_collector);
VariableMode mode = harmony_scoping_ ? LET : VAR; VariableMode mode = is_extended_mode() ? LET : VAR;
catch_variable = catch_variable =
catch_scope->DeclareLocal(name, mode, kCreatedInitialized); catch_scope->DeclareLocal(name, mode, kCreatedInitialized);
...@@ -3936,7 +3933,7 @@ FunctionLiteral* Parser::ParseFunctionLiteral(Handle<String> function_name, ...@@ -3936,7 +3933,7 @@ FunctionLiteral* Parser::ParseFunctionLiteral(Handle<String> function_name,
// Function declarations are function scoped in normal mode, so they are // Function declarations are function scoped in normal mode, so they are
// hoisted. In harmony block scoping mode they are block scoped, so they // hoisted. In harmony block scoping mode they are block scoped, so they
// are not hoisted. // are not hoisted.
Scope* scope = (type == FunctionLiteral::DECLARATION && !harmony_scoping_) Scope* scope = (type == FunctionLiteral::DECLARATION && !is_extended_mode())
? NewScope(top_scope_->DeclarationScope(), FUNCTION_SCOPE) ? NewScope(top_scope_->DeclarationScope(), FUNCTION_SCOPE)
: NewScope(top_scope_, FUNCTION_SCOPE); : NewScope(top_scope_, FUNCTION_SCOPE);
ZoneList<Statement*>* body = NULL; ZoneList<Statement*>* body = NULL;
...@@ -3977,7 +3974,7 @@ FunctionLiteral* Parser::ParseFunctionLiteral(Handle<String> function_name, ...@@ -3977,7 +3974,7 @@ FunctionLiteral* Parser::ParseFunctionLiteral(Handle<String> function_name,
reserved_loc = scanner().location(); reserved_loc = scanner().location();
} }
top_scope_->DeclareParameter(param_name, harmony_scoping_ ? LET : VAR); top_scope_->DeclareParameter(param_name, is_extended_mode() ? LET : VAR);
num_parameters++; num_parameters++;
if (num_parameters > kMaxNumFunctionParameters) { if (num_parameters > kMaxNumFunctionParameters) {
ReportMessageAt(scanner().location(), "too_many_parameters", ReportMessageAt(scanner().location(), "too_many_parameters",
...@@ -4002,7 +3999,7 @@ FunctionLiteral* Parser::ParseFunctionLiteral(Handle<String> function_name, ...@@ -4002,7 +3999,7 @@ FunctionLiteral* Parser::ParseFunctionLiteral(Handle<String> function_name,
Token::Value fvar_init_op = Token::INIT_CONST; Token::Value fvar_init_op = Token::INIT_CONST;
if (type == FunctionLiteral::NAMED_EXPRESSION) { if (type == FunctionLiteral::NAMED_EXPRESSION) {
VariableMode fvar_mode; VariableMode fvar_mode;
if (harmony_scoping_) { if (is_extended_mode()) {
fvar_mode = CONST_HARMONY; fvar_mode = CONST_HARMONY;
fvar_init_op = Token::INIT_CONST_HARMONY; fvar_init_op = Token::INIT_CONST_HARMONY;
} else { } else {
...@@ -4120,7 +4117,7 @@ FunctionLiteral* Parser::ParseFunctionLiteral(Handle<String> function_name, ...@@ -4120,7 +4117,7 @@ FunctionLiteral* Parser::ParseFunctionLiteral(Handle<String> function_name,
} }
} }
if (harmony_scoping_) { if (is_extended_mode()) {
CheckConflictingVarDeclarations(scope, CHECK_OK); CheckConflictingVarDeclarations(scope, CHECK_OK);
} }
...@@ -5360,7 +5357,7 @@ static ScriptDataImpl* DoPreParse(UC16CharacterStream* source, ...@@ -5360,7 +5357,7 @@ static ScriptDataImpl* DoPreParse(UC16CharacterStream* source,
Isolate* isolate = Isolate::Current(); Isolate* isolate = Isolate::Current();
HistogramTimerScope timer(isolate->counters()->pre_parse()); HistogramTimerScope timer(isolate->counters()->pre_parse());
Scanner scanner(isolate->unicode_cache()); Scanner scanner(isolate->unicode_cache());
scanner.SetHarmonyScoping((flags & kHarmonyScoping) != 0); scanner.SetHarmonyScoping(FLAG_harmony_scoping);
scanner.Initialize(source); scanner.Initialize(source);
intptr_t stack_limit = isolate->stack_guard()->real_climit(); intptr_t stack_limit = isolate->stack_guard()->real_climit();
if (!preparser::PreParser::PreParseProgram(&scanner, if (!preparser::PreParser::PreParseProgram(&scanner,
...@@ -5433,14 +5430,12 @@ bool ParserApi::Parse(CompilationInfo* info) { ...@@ -5433,14 +5430,12 @@ bool ParserApi::Parse(CompilationInfo* info) {
ASSERT(info->function() == NULL); ASSERT(info->function() == NULL);
FunctionLiteral* result = NULL; FunctionLiteral* result = NULL;
Handle<Script> script = info->script(); Handle<Script> script = info->script();
bool harmony_scoping = !info->is_native() && FLAG_harmony_scoping;
if (info->is_lazy()) { if (info->is_lazy()) {
ASSERT(!info->is_eval()); ASSERT(!info->is_eval());
bool allow_natives_syntax = bool allow_natives_syntax =
FLAG_allow_natives_syntax || FLAG_allow_natives_syntax ||
info->is_native(); info->is_native();
Parser parser(script, allow_natives_syntax, NULL, NULL); Parser parser(script, allow_natives_syntax, NULL, NULL);
parser.SetHarmonyScoping(harmony_scoping);
result = parser.ParseLazy(info); result = parser.ParseLazy(info);
} else { } else {
// Whether we allow %identifier(..) syntax. // Whether we allow %identifier(..) syntax.
...@@ -5451,7 +5446,6 @@ bool ParserApi::Parse(CompilationInfo* info) { ...@@ -5451,7 +5446,6 @@ bool ParserApi::Parse(CompilationInfo* info) {
allow_natives_syntax, allow_natives_syntax,
info->extension(), info->extension(),
pre_data); pre_data);
parser.SetHarmonyScoping(harmony_scoping);
if (pre_data != NULL && pre_data->has_error()) { if (pre_data != NULL && pre_data->has_error()) {
Scanner::Location loc = pre_data->MessageLocation(); Scanner::Location loc = pre_data->MessageLocation();
const char* message = pre_data->BuildMessage(); const char* message = pre_data->BuildMessage();
......
...@@ -440,7 +440,6 @@ class Parser { ...@@ -440,7 +440,6 @@ class Parser {
void ReportMessageAt(Scanner::Location loc, void ReportMessageAt(Scanner::Location loc,
const char* message, const char* message,
Vector<Handle<String> > args); Vector<Handle<String> > args);
void SetHarmonyScoping(bool block_scoping);
private: private:
// Limit on number of function parameters is chosen arbitrarily. // Limit on number of function parameters is chosen arbitrarily.
...@@ -491,6 +490,10 @@ class Parser { ...@@ -491,6 +490,10 @@ class Parser {
Scanner& scanner() { return scanner_; } Scanner& scanner() { return scanner_; }
Mode mode() const { return mode_; } Mode mode() const { return mode_; }
ScriptDataImpl* pre_data() const { return pre_data_; } ScriptDataImpl* pre_data() const { return pre_data_; }
bool is_extended_mode() {
ASSERT(top_scope_ != NULL);
return top_scope_->is_extended_mode();
}
// Check if the given string is 'eval' or 'arguments'. // Check if the given string is 'eval' or 'arguments'.
bool IsEvalOrArguments(Handle<String> string); bool IsEvalOrArguments(Handle<String> string);
...@@ -746,7 +749,6 @@ class Parser { ...@@ -746,7 +749,6 @@ class Parser {
// Heuristically that means that the function will be called immediately, // Heuristically that means that the function will be called immediately,
// so never lazily compile it. // so never lazily compile it.
bool parenthesized_function_; bool parenthesized_function_;
bool harmony_scoping_;
friend class BlockState; friend class BlockState;
friend class FunctionState; friend class FunctionState;
......
...@@ -844,6 +844,7 @@ TEST(ScopePositions) { ...@@ -844,6 +844,7 @@ TEST(ScopePositions) {
int marker; int marker;
i::Isolate::Current()->stack_guard()->SetStackLimit( i::Isolate::Current()->stack_guard()->SetStackLimit(
reinterpret_cast<uintptr_t>(&marker) - 128 * 1024); reinterpret_cast<uintptr_t>(&marker) - 128 * 1024);
i::FLAG_harmony_scoping = true;
for (int i = 0; source_data[i].outer_prefix; i++) { for (int i = 0; source_data[i].outer_prefix; i++) {
int kPrefixLen = i::StrLength(source_data[i].outer_prefix); int kPrefixLen = i::StrLength(source_data[i].outer_prefix);
...@@ -862,7 +863,6 @@ TEST(ScopePositions) { ...@@ -862,7 +863,6 @@ TEST(ScopePositions) {
FACTORY->NewStringFromAscii(i::CStrVector(program.start()))); FACTORY->NewStringFromAscii(i::CStrVector(program.start())));
i::Handle<i::Script> script = FACTORY->NewScript(source); i::Handle<i::Script> script = FACTORY->NewScript(source);
i::Parser parser(script, false, NULL, NULL); i::Parser parser(script, false, NULL, NULL);
parser.SetHarmonyScoping(true);
i::CompilationInfo info(script); i::CompilationInfo info(script);
info.MarkAsGlobal(); info.MarkAsGlobal();
info.SetLanguageMode(source_data[i].language_mode); info.SetLanguageMode(source_data[i].language_mode);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment