Reviewers: Jakob,
Message:
PTAL.
Description:
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/
Please review this at http://codereview.chromium.org/8562002/
SVN Base: https://v8.googlecode.com/svn/branches/bleeding_edge
Affected files:
M src/compiler.cc
M src/parser.h
M src/parser.cc
M src/scanner.h
M test/cctest/test-parsing.cc
Index: src/compiler.cc
diff --git a/src/compiler.cc b/src/compiler.cc
index
c66cb5053fdcbaa65cdda992750477e801b430f5..b8b8f3717673f64a99e8d8aa0925c600646be317
100644
--- a/src/compiler.cc
+++ b/src/compiler.cc
@@ -482,9 +482,6 @@ Handle<SharedFunctionInfo>
Compiler::Compile(Handle<String> source,
if ((natives == NATIVES_CODE) || FLAG_allow_natives_syntax) {
flags |= kAllowNativesSyntax;
}
- if (natives != NATIVES_CODE && FLAG_harmony_scoping) {
- flags |= kHarmonyScoping;
- }
if (pre_data == NULL
&& source_length >= FLAG_min_preparse_length) {
if (source->IsExternalTwoByteString()) {
Index: src/parser.cc
diff --git a/src/parser.cc b/src/parser.cc
index
9435e703daa1ba4a0c9301f875382887bfaafb00..de4457c3dd991b3ab36bc54ff16024000608a66c
100644
--- a/src/parser.cc
+++ b/src/parser.cc
@@ -601,8 +601,8 @@ Parser::Parser(Handle<Script> script,
fni_(NULL),
allow_natives_syntax_(allow_natives_syntax),
stack_overflow_(false),
- parenthesized_function_(false),
- harmony_scoping_(false) {
+ parenthesized_function_(false) {
+ scanner().SetHarmonyScoping(FLAG_harmony_scoping);
AstNode::ResetIds();
}
@@ -666,7 +666,7 @@ FunctionLiteral* Parser::DoParseProgram(Handle<String>
source,
CheckOctalLiteral(beg_loc, scanner().location().end_pos, &ok);
}
- if (ok && harmony_scoping_) {
+ if (ok && is_extended_mode()) {
CheckConflictingVarDeclarations(scope, &ok);
}
@@ -833,10 +833,6 @@ void Parser::ReportMessageAt(Scanner::Location
source_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
// the parser.
@@ -1199,7 +1195,8 @@ void*
Parser::ParseSourceElements(ZoneList<Statement*>* processor,
directive->Equals(isolate()->heap()->use_strict()) &&
token_loc.end_pos - token_loc.beg_pos ==
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);
// "use strict" is the only directive for now.
directive_prologue = false;
@@ -1413,7 +1410,7 @@ VariableProxy* Parser::Declare(Handle<String> name,
var->mode() == CONST ||
var->mode() == CONST_HARMONY ||
var->mode() == LET);
- if (harmony_scoping_) {
+ if (is_extended_mode()) {
// In harmony mode we treat re-declarations as early errors. See
// ES5 16 for a definition of early errors.
SmartArrayPointer<char> c_string =
name->ToCString(DISALLOW_NULLS);
@@ -1571,7 +1568,7 @@ Statement* Parser::ParseFunctionDeclaration(bool* ok)
{
// 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
// 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);
return EmptyStatement();
}
@@ -2304,7 +2301,7 @@ TryStatement* Parser::ParseTryStatement(bool* ok) {
if (peek() == Token::LBRACE) {
Target target(&this->target_stack_, &catch_collector);
- VariableMode mode = harmony_scoping_ ? LET : VAR;
+ VariableMode mode = is_extended_mode() ? LET : VAR;
catch_variable =
catch_scope->DeclareLocal(name, mode, kCreatedInitialized);
@@ -3915,7 +3912,7 @@ FunctionLiteral*
Parser::ParseFunctionLiteral(Handle<String> function_name,
// Function declarations are function scoped in normal mode, so they are
// hoisted. In harmony block scoping mode they are block scoped, so they
// 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_, FUNCTION_SCOPE);
ZoneList<Statement*>* body = NULL;
@@ -3956,7 +3953,7 @@ FunctionLiteral*
Parser::ParseFunctionLiteral(Handle<String> function_name,
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++;
if (num_parameters > kMaxNumFunctionParameters) {
ReportMessageAt(scanner().location(), "too_many_parameters",
@@ -3981,7 +3978,7 @@ FunctionLiteral*
Parser::ParseFunctionLiteral(Handle<String> function_name,
Token::Value fvar_init_op = Token::INIT_CONST;
if (type == FunctionLiteral::NAMED_EXPRESSION) {
VariableMode fvar_mode;
- if (harmony_scoping_) {
+ if (is_extended_mode()) {
fvar_mode = CONST_HARMONY;
fvar_init_op = Token::INIT_CONST_HARMONY;
} else {
@@ -4099,7 +4096,7 @@ FunctionLiteral*
Parser::ParseFunctionLiteral(Handle<String> function_name,
}
}
- if (harmony_scoping_) {
+ if (is_extended_mode()) {
CheckConflictingVarDeclarations(scope, CHECK_OK);
}
@@ -5338,7 +5335,7 @@ static ScriptDataImpl*
DoPreParse(UC16CharacterStream* source,
ParserRecorder* recorder) {
Isolate* isolate = Isolate::Current();
Scanner scanner(isolate->unicode_cache());
- scanner.SetHarmonyScoping((flags & kHarmonyScoping) != 0);
+ scanner.SetHarmonyScoping(FLAG_harmony_scoping);
scanner.Initialize(source);
intptr_t stack_limit = isolate->stack_guard()->real_climit();
if (!preparser::PreParser::PreParseProgram(&scanner,
@@ -5411,13 +5408,11 @@ bool ParserApi::Parse(CompilationInfo* info) {
ASSERT(info->function() == NULL);
FunctionLiteral* result = NULL;
Handle<Script> script = info->script();
- bool harmony_scoping = !info->is_native() && FLAG_harmony_scoping;
if (info->is_lazy()) {
bool allow_natives_syntax =
FLAG_allow_natives_syntax ||
info->is_native();
Parser parser(script, allow_natives_syntax, NULL, NULL);
- parser.SetHarmonyScoping(harmony_scoping);
result = parser.ParseLazy(info);
} else {
// Whether we allow %identifier(..) syntax.
@@ -5428,7 +5423,6 @@ bool ParserApi::Parse(CompilationInfo* info) {
allow_natives_syntax,
info->extension(),
pre_data);
- parser.SetHarmonyScoping(harmony_scoping);
if (pre_data != NULL && pre_data->has_error()) {
Scanner::Location loc = pre_data->MessageLocation();
const char* message = pre_data->BuildMessage();
Index: src/parser.h
diff --git a/src/parser.h b/src/parser.h
index
e55c158fc2881152a8542b120823e395a2eb253e..11bee75c978fabd2f9cabf3c5f777977d282148e
100644
--- a/src/parser.h
+++ b/src/parser.h
@@ -443,7 +443,6 @@ class Parser {
void ReportMessageAt(Scanner::Location loc,
const char* message,
Vector<Handle<String> > args);
- void SetHarmonyScoping(bool block_scoping);
private:
// Limit on number of function parameters is chosen arbitrarily.
@@ -495,6 +494,10 @@ class Parser {
Scanner& scanner() { return scanner_; }
Mode mode() const { return mode_; }
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'.
bool IsEvalOrArguments(Handle<String> string);
@@ -749,7 +752,6 @@ class Parser {
// Heuristically that means that the function will be called immediately,
// so never lazily compile it.
bool parenthesized_function_;
- bool harmony_scoping_;
friend class BlockState;
friend class FunctionState;
Index: src/scanner.h
diff --git a/src/scanner.h b/src/scanner.h
index
88e3bceb1b4d5119f13890c45b0f7eeed89b5b90..4cf181ba72df7a20c4a560de242ecd1e17359f2c
100644
--- a/src/scanner.h
+++ b/src/scanner.h
@@ -47,8 +47,7 @@ namespace internal {
enum ParsingFlags {
kNoParsingFlags = 0,
kAllowLazy = 1,
- kAllowNativesSyntax = 2,
- kHarmonyScoping = 4
+ kAllowNativesSyntax = 2
};
Index: test/cctest/test-parsing.cc
diff --git a/test/cctest/test-parsing.cc b/test/cctest/test-parsing.cc
index
c2bde79b13b28a4333c95f781b3eeb4fd27a5d6f..4029484111cda555762e61bdd6336d35f2a0f594
100755
--- a/test/cctest/test-parsing.cc
+++ b/test/cctest/test-parsing.cc
@@ -860,11 +860,13 @@ TEST(ScopePositions) {
i::Handle<i::String> source(
FACTORY->NewStringFromAscii(i::CStrVector(program.start())));
i::Handle<i::Script> script = FACTORY->NewScript(source);
+ bool harmony_scoping = i::FLAG_harmony_scoping;
+ i::FLAG_harmony_scoping = true;
i::Parser parser(script, false, NULL, NULL);
- parser.SetHarmonyScoping(true);
i::FunctionLiteral* function =
parser.ParseProgram(source, true, source_data[i].language_mode);
- ASSERT(function != NULL);
+ i::FLAG_harmony_scoping = harmony_scoping;
+ CHECK(function != NULL);
// Check scope types and positions.
i::Scope* scope = function->scope();
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev