Index: src/parser.cc |
diff --git a/src/parser.cc b/src/parser.cc |
index 3c72dd0f72c7b47b05c08da86de112bee65468eb..d3fde9ef8f8c11da510708a6b1aa59c88dbbe1ce 100644 |
--- a/src/parser.cc |
+++ b/src/parser.cc |
@@ -298,7 +298,7 @@ FunctionLiteral* Parser::DefaultConstructor(bool call_super, Scope* scope, |
{ |
AstNodeFactory function_factory(ast_value_factory()); |
FunctionState function_state(&function_state_, &scope_, function_scope, |
- &function_factory); |
+ kDefaultConstructor, &function_factory); |
body = new (zone()) ZoneList<Statement*>(1, zone()); |
if (call_super) { |
@@ -946,7 +946,7 @@ FunctionLiteral* Parser::DoParseProgram(CompilationInfo* info, Scope** scope, |
// Enters 'scope'. |
AstNodeFactory function_factory(ast_value_factory()); |
FunctionState function_state(&function_state_, &scope_, *scope, |
- &function_factory); |
+ kNormalFunction, &function_factory); |
scope_->SetLanguageMode(info->language_mode()); |
ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(16, zone()); |
@@ -1066,7 +1066,7 @@ FunctionLiteral* Parser::ParseLazy(Utf16CharacterStream* source) { |
original_scope_ = scope; |
AstNodeFactory function_factory(ast_value_factory()); |
FunctionState function_state(&function_state_, &scope_, scope, |
- &function_factory); |
+ shared_info->kind(), &function_factory); |
DCHECK(is_sloppy(scope->language_mode()) || |
is_strict(info()->language_mode())); |
DCHECK(info()->language_mode() == shared_info->language_mode()); |
@@ -2650,11 +2650,17 @@ Statement* Parser::ParseReturnStatement(bool* ok) { |
tok == Token::SEMICOLON || |
tok == Token::RBRACE || |
tok == Token::EOS) { |
- return_value = GetLiteralUndefined(position()); |
+ if (FLAG_experimental_classes && |
+ IsSubclassConstructor(function_state_->kind())) { |
+ return_value = ThisExpression(scope_, factory(), loc.beg_pos); |
+ } else { |
+ return_value = GetLiteralUndefined(position()); |
+ } |
} else { |
return_value = ParseExpression(true, CHECK_OK); |
} |
ExpectSemicolon(CHECK_OK); |
+ |
if (is_generator()) { |
Expression* generator = factory()->NewVariableProxy( |
function_state_->generator_object_variable()); |
@@ -3671,7 +3677,7 @@ FunctionLiteral* Parser::ParseFunctionLiteral( |
// Parse function body. |
{ |
AstNodeFactory function_factory(ast_value_factory()); |
- FunctionState function_state(&function_state_, &scope_, scope, |
+ FunctionState function_state(&function_state_, &scope_, scope, kind, |
&function_factory); |
scope_->SetScopeName(function_name); |
@@ -3825,7 +3831,7 @@ FunctionLiteral* Parser::ParseFunctionLiteral( |
&expected_property_count, CHECK_OK); |
} else { |
body = ParseEagerFunctionBody(function_name, pos, fvar, fvar_init_op, |
- is_generator, CHECK_OK); |
+ kind, CHECK_OK); |
materialized_literal_count = function_state.materialized_literal_count(); |
expected_property_count = function_state.expected_property_count(); |
handler_count = function_state.handler_count(); |
@@ -3935,7 +3941,7 @@ void Parser::SkipLazyFunctionBody(const AstRawString* function_name, |
ZoneList<Statement*>* Parser::ParseEagerFunctionBody( |
const AstRawString* function_name, int pos, Variable* fvar, |
- Token::Value fvar_init_op, bool is_generator, bool* ok) { |
+ Token::Value fvar_init_op, FunctionKind kind, bool* ok) { |
// Everything inside an eagerly parsed function will be parsed eagerly |
// (see comment above). |
ParsingModeScope parsing_mode(this, PARSE_EAGERLY); |
@@ -3952,8 +3958,29 @@ ZoneList<Statement*>* Parser::ParseEagerFunctionBody( |
RelocInfo::kNoPosition), zone()); |
} |
+ |
+ // For concise constructors, check that they are constructed, |
+ // not called. |
+ if (FLAG_experimental_classes && i::IsConstructor(kind)) { |
+ ZoneList<Expression*>* arguments = |
+ new (zone()) ZoneList<Expression*>(0, zone()); |
+ CallRuntime* construct_check = factory()->NewCallRuntime( |
+ ast_value_factory()->is_construct_call_string(), |
+ Runtime::FunctionForId(Runtime::kInlineIsConstructCall), arguments, |
+ pos); |
+ CallRuntime* non_callable_error = factory()->NewCallRuntime( |
+ ast_value_factory()->empty_string(), |
+ Runtime::FunctionForId(Runtime::kThrowConstructorNonCallableError), |
+ arguments, pos); |
+ IfStatement* if_statement = factory()->NewIfStatement( |
+ factory()->NewUnaryOperation(Token::NOT, construct_check, pos), |
+ factory()->NewReturnStatement(non_callable_error, pos), |
+ factory()->NewEmptyStatement(pos), pos); |
+ body->Add(if_statement, zone()); |
+ } |
+ |
// For generators, allocate and yield an iterator on function entry. |
- if (is_generator) { |
+ if (IsGeneratorFunction(kind)) { |
ZoneList<Expression*>* arguments = |
new(zone()) ZoneList<Expression*>(0, zone()); |
CallRuntime* allocation = factory()->NewCallRuntime( |
@@ -3974,7 +4001,7 @@ ZoneList<Statement*>* Parser::ParseEagerFunctionBody( |
ParseStatementList(body, Token::RBRACE, false, NULL, CHECK_OK); |
- if (is_generator) { |
+ if (IsGeneratorFunction(kind)) { |
VariableProxy* get_proxy = factory()->NewVariableProxy( |
function_state_->generator_object_variable()); |
Expression* undefined = |
@@ -3985,6 +4012,14 @@ ZoneList<Statement*>* Parser::ParseEagerFunctionBody( |
yield, RelocInfo::kNoPosition), zone()); |
} |
+ if (FLAG_experimental_classes && IsSubclassConstructor(kind)) { |
+ body->Add( |
+ factory()->NewReturnStatement( |
+ this->ThisExpression(scope_, factory(), RelocInfo::kNoPosition), |
+ RelocInfo::kNoPosition), |
+ zone()); |
+ } |
+ |
Expect(Token::RBRACE, CHECK_OK); |
scope_->set_end_position(scanner()->location().end_pos); |
@@ -4025,7 +4060,7 @@ PreParser::PreParseResult Parser::ParseLazyFunctionBodyWithPreParser( |
reusable_preparser_->set_allow_strong_mode(allow_strong_mode()); |
} |
PreParser::PreParseResult result = reusable_preparser_->PreParseLazyFunction( |
- language_mode(), is_generator(), logger); |
+ language_mode(), function_state_->kind(), logger); |
if (pre_parse_timer_ != NULL) { |
pre_parse_timer_->Stop(); |
} |