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

Unified Diff: src/parser.cc

Issue 885643004: new classes: assert that constructors are not callable and rewrite 'return;' (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Fix bit width Created 5 years, 10 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/preparser.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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();
}
« no previous file with comments | « src/parser.h ('k') | src/preparser.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698