| 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();
|
| }
|
|
|