Commit 20ce2c6f authored by Toon Verwaest's avatar Toon Verwaest Committed by Commit Bot

[parser] Use ScopedPtrList for more statement lists

In particular FunctionLiteral body. Now clients cannot use
function_literal->body() == nullptr anymore to figure out whether it was
preparsed; but have to check the eager compile hint.

Change-Id: Ia0d3a6b51c6fb7e803157e98a9d224224e03c8a7
Reviewed-on: https://chromium-review.googlesource.com/c/1317811Reviewed-by: 's avatarLeszek Swirski <leszeks@chromium.org>
Reviewed-by: 's avatarCamillo Bruni <cbruni@chromium.org>
Commit-Queue: Toon Verwaest <verwaest@chromium.org>
Cr-Commit-Position: refs/heads/master@{#57246}
parent 2d7b85a5
......@@ -316,6 +316,12 @@ class Block : public BreakableStatement {
Scope* scope() const { return scope_; }
void set_scope(Scope* scope) { scope_ = scope; }
void InitializeStatements(const ScopedPtrList<Statement>& statements,
Zone* zone) {
DCHECK_EQ(0, statements_.length());
statements.CopyTo(&statements_, zone);
}
private:
friend class AstNodeFactory;
......@@ -336,6 +342,9 @@ class Block : public BreakableStatement {
bit_field_ |= IgnoreCompletionField::encode(ignore_completion_value) |
IsLabeledField::encode(labels != nullptr);
}
Block(ZonePtrList<const AstRawString>* labels, bool ignore_completion_value)
: Block(nullptr, labels, 0, ignore_completion_value) {}
};
class LabeledBlock final : public Block {
......@@ -351,6 +360,10 @@ class LabeledBlock final : public Block {
DCHECK_GT(labels->length(), 0);
}
LabeledBlock(ZonePtrList<const AstRawString>* labels,
bool ignore_completion_value)
: LabeledBlock(nullptr, labels, 0, ignore_completion_value) {}
ZonePtrList<const AstRawString>* labels_;
};
......@@ -2277,7 +2290,7 @@ class FunctionLiteral final : public Expression {
const AstConsString* raw_name() const { return raw_name_; }
void set_raw_name(const AstConsString* name) { raw_name_ = name; }
DeclarationScope* scope() const { return scope_; }
ZonePtrList<Statement>* body() { return body_; }
ZonePtrList<Statement>* body() { return &body_; }
void set_function_token_position(int pos) { function_token_position_ = pos; }
int function_token_position() const { return function_token_position_; }
int start_position() const;
......@@ -2302,7 +2315,7 @@ class FunctionLiteral final : public Expression {
int expected_property_count() {
// Not valid for lazy functions.
DCHECK_NOT_NULL(body_);
DCHECK(ShouldEagerCompile());
return expected_property_count_;
}
int parameter_count() { return parameter_count_; }
......@@ -2342,7 +2355,7 @@ class FunctionLiteral final : public Expression {
bool has_duplicate_parameters() const {
// Not valid for lazy functions.
DCHECK_NOT_NULL(body_);
DCHECK(ShouldEagerCompile());
return HasDuplicateParameters::decode(bit_field_);
}
......@@ -2403,7 +2416,7 @@ class FunctionLiteral final : public Expression {
FunctionLiteral(
Zone* zone, const AstRawString* name, AstValueFactory* ast_value_factory,
DeclarationScope* scope, ZonePtrList<Statement>* body,
DeclarationScope* scope, const ScopedPtrList<Statement>& body,
int expected_property_count, int parameter_count, int function_length,
FunctionType function_type, ParameterFlag has_duplicate_parameters,
EagerCompileHint eager_compile_hint, int position, bool has_braces,
......@@ -2418,7 +2431,7 @@ class FunctionLiteral final : public Expression {
function_literal_id_(function_literal_id),
raw_name_(name ? ast_value_factory->NewConsString(name) : nullptr),
scope_(scope),
body_(body),
body_(0, nullptr),
raw_inferred_name_(ast_value_factory->empty_cons_string()),
produced_preparsed_scope_data_(produced_preparsed_scope_data) {
bit_field_ |= FunctionTypeBits::encode(function_type) |
......@@ -2429,7 +2442,7 @@ class FunctionLiteral final : public Expression {
RequiresInstanceFieldsInitializer::encode(false) |
HasBracesField::encode(has_braces) | IIFEBit::encode(false);
if (eager_compile_hint == kShouldEagerCompile) SetShouldEagerCompile();
DCHECK_EQ(body == nullptr, expected_property_count < 0);
body.CopyTo(&body_, zone);
}
class FunctionTypeBits
......@@ -2453,7 +2466,7 @@ class FunctionLiteral final : public Expression {
const AstConsString* raw_name_;
DeclarationScope* scope_;
ZonePtrList<Statement>* body_;
ZonePtrList<Statement> body_;
const AstConsString* raw_inferred_name_;
Handle<String> inferred_name_;
ProducedPreParsedScopeData* produced_preparsed_scope_data_;
......@@ -2902,13 +2915,22 @@ class AstNodeFactory final {
FunctionDeclaration(proxy, fun, is_sloppy_block_function, pos);
}
Block* NewBlock(int capacity, bool ignore_completion_value,
ZonePtrList<const AstRawString>* labels = nullptr) {
Block* NewBlock(int capacity, bool ignore_completion_value) {
return new (zone_) Block(zone_, nullptr, capacity, ignore_completion_value);
}
Block* NewBlock(bool ignore_completion_value,
ZonePtrList<const AstRawString>* labels) {
return labels != nullptr
? new (zone_) LabeledBlock(zone_, labels, capacity,
ignore_completion_value)
: new (zone_)
Block(zone_, labels, capacity, ignore_completion_value);
? new (zone_) LabeledBlock(labels, ignore_completion_value)
: new (zone_) Block(labels, ignore_completion_value);
}
Block* NewBlock(bool ignore_completion_value,
const ScopedPtrList<Statement>& statements) {
Block* result = NewBlock(ignore_completion_value, nullptr);
result->InitializeStatements(statements, zone_);
return result;
}
#define STATEMENT_WITH_LABELS(NodeType) \
......@@ -3273,7 +3295,7 @@ class AstNodeFactory final {
FunctionLiteral* NewFunctionLiteral(
const AstRawString* name, DeclarationScope* scope,
ZonePtrList<Statement>* body, int expected_property_count,
const ScopedPtrList<Statement>& body, int expected_property_count,
int parameter_count, int function_length,
FunctionLiteral::ParameterFlag has_duplicate_parameters,
FunctionLiteral::FunctionType function_type,
......@@ -3290,10 +3312,9 @@ class AstNodeFactory final {
// Creates a FunctionLiteral representing a top-level script, the
// result of an eval (top-level or otherwise), or the result of calling
// the Function constructor.
FunctionLiteral* NewScriptOrEvalFunctionLiteral(DeclarationScope* scope,
ZonePtrList<Statement>* body,
int expected_property_count,
int parameter_count) {
FunctionLiteral* NewScriptOrEvalFunctionLiteral(
DeclarationScope* scope, const ScopedPtrList<Statement>& body,
int expected_property_count, int parameter_count) {
return new (zone_) FunctionLiteral(
zone_, ast_value_factory_->empty_string(), ast_value_factory_, scope,
body, expected_property_count, parameter_count, parameter_count,
......
......@@ -14194,19 +14194,16 @@ void SharedFunctionInfo::InitFromFunctionLiteral(
// don't have the information yet. They're set later in
// SetSharedFunctionFlagsFromLiteral (compiler.cc), when the function is
// really parsed and compiled.
if (lit->body() != nullptr) {
if (lit->ShouldEagerCompile()) {
shared_info->set_length(lit->function_length());
shared_info->set_has_duplicate_parameters(lit->has_duplicate_parameters());
shared_info->SetExpectedNofPropertiesFromEstimate(lit);
DCHECK_NULL(lit->produced_preparsed_scope_data());
if (lit->ShouldEagerCompile()) {
// If we're about to eager compile, we'll have the function literal
// available, so there's no need to wastefully allocate an uncompiled
// data.
// TODO(leszeks): This should be explicitly passed as a parameter, rather
// than relying on a property of the literal.
needs_position_info = false;
}
// If we're about to eager compile, we'll have the function literal
// available, so there's no need to wastefully allocate an uncompiled data.
// TODO(leszeks): This should be explicitly passed as a parameter, rather
// than relying on a property of the literal.
needs_position_info = false;
} else {
// Set an invalid length for lazy functions. This way we can set the correct
// value after compiling, but avoid overwriting values set manually by the
......
This diff is collapsed.
This diff is collapsed.
......@@ -134,8 +134,7 @@ struct ParserTypes<Parser> {
typedef ZonePtrList<ClassLiteral::Property>* ClassPropertyList;
typedef ParserFormalParameters FormalParameters;
typedef v8::internal::Statement* Statement;
typedef ZonePtrList<v8::internal::Statement>* StatementList;
typedef ScopedPtrList<v8::internal::Statement> ScopedStatementList;
typedef ScopedPtrList<v8::internal::Statement> StatementList;
typedef ScopedPtrList<v8::internal::Expression> ExpressionList;
typedef ScopedPtrList<v8::internal::ObjectLiteralProperty> ObjectPropertyList;
typedef v8::internal::Block* Block;
......@@ -243,7 +242,7 @@ class V8_EXPORT_PRIVATE Parser : public NON_EXPORTED_BASE(ParserBase<Parser>) {
// We manually construct the AST and scopes for a top-level function and the
// function wrapper.
void ParseWrapped(Isolate* isolate, ParseInfo* info,
ZonePtrList<Statement>* body, DeclarationScope* scope,
ScopedPtrList<Statement>* body, DeclarationScope* scope,
Zone* zone);
ZonePtrList<const AstRawString>* PrepareWrappedArguments(Isolate* isolate,
......@@ -270,7 +269,7 @@ class V8_EXPORT_PRIVATE Parser : public NON_EXPORTED_BASE(ParserBase<Parser>) {
return reusable_preparser_;
}
void ParseModuleItemList(ZonePtrList<Statement>* body);
void ParseModuleItemList(ScopedPtrList<Statement>* body);
Statement* ParseModuleItem();
const AstRawString* ParseModuleSpecifier();
void ParseImportDeclaration();
......@@ -315,9 +314,9 @@ class V8_EXPORT_PRIVATE Parser : public NON_EXPORTED_BASE(ParserBase<Parser>) {
void GetUnexpectedTokenMessage(Token::Value token, MessageTemplate* message,
Scanner::Location* location, const char** arg);
void ParseAndRewriteGeneratorFunctionBody(int pos, FunctionKind kind,
ZonePtrList<Statement>* body);
void ParseAndRewriteAsyncGeneratorFunctionBody(int pos, FunctionKind kind,
ZonePtrList<Statement>* body);
ScopedPtrList<Statement>* body);
void ParseAndRewriteAsyncGeneratorFunctionBody(
int pos, FunctionKind kind, ScopedPtrList<Statement>* body);
void DeclareFunctionNameVar(const AstRawString* function_name,
FunctionLiteral::FunctionType function_type,
DeclarationScope* function_scope);
......@@ -466,9 +465,9 @@ class V8_EXPORT_PRIVATE Parser : public NON_EXPORTED_BASE(ParserBase<Parser>) {
const ParserFormalParameters& parameters);
Block* BuildRejectPromiseOnException(Block* block);
ZonePtrList<Statement>* ParseFunction(
const AstRawString* function_name, int pos, FunctionKind kind,
FunctionLiteral::FunctionType function_type,
void ParseFunction(
ScopedPtrList<Statement>* body, const AstRawString* function_name,
int pos, FunctionKind kind, FunctionLiteral::FunctionType function_type,
DeclarationScope* function_scope, int* num_parameters,
int* function_length, bool* has_duplicate_parameters,
int* expected_property_count, int* suspend_count,
......@@ -567,7 +566,7 @@ class V8_EXPORT_PRIVATE Parser : public NON_EXPORTED_BASE(ParserBase<Parser>) {
IteratorType type);
Statement* CheckCallable(Variable* var, Expression* error, int pos);
void RewriteAsyncFunctionBody(ZonePtrList<Statement>* body, Block* block,
void RewriteAsyncFunctionBody(ScopedPtrList<Statement>* body, Block* block,
Expression* return_value);
void AddArrowFunctionFormalParameters(ParserFormalParameters* parameters,
......
......@@ -82,8 +82,8 @@ PreParser::PreParseResult PreParser::PreParseProgram() {
FunctionState top_scope(&function_state_, &scope_, scope);
original_scope_ = scope_;
int start_position = scanner()->peek_location().beg_pos;
PreParserStatementList body;
ParseStatementList(body, Token::EOS);
PreParserScopedStatementList body(pointer_buffer());
ParseStatementList(&body, Token::EOS);
original_scope_ = nullptr;
if (stack_overflow()) return kPreParseStackOverflow;
if (is_strict(language_mode())) {
......@@ -299,10 +299,10 @@ PreParser::Expression PreParser::ParseFunctionLiteral(
Expect(Token::LBRACE);
// Parse function body.
PreParserStatementList body;
PreParserScopedStatementList body(pointer_buffer());
int pos = function_token_pos == kNoSourcePosition ? peek_position()
: function_token_pos;
ParseFunctionBody(body, function_name, pos, formals, kind, function_type,
ParseFunctionBody(&body, function_name, pos, formals, kind, function_type,
FunctionBodyType::kBlock, true);
// Parsing the body may change the language mode in our scope.
......@@ -348,8 +348,9 @@ PreParser::Expression PreParser::ParseFunctionLiteral(
PreParser::LazyParsingResult PreParser::ParseStatementListAndLogFunction(
PreParserFormalParameters* formals, bool may_abort) {
PreParserStatementList body;
LazyParsingResult result = ParseStatementList(body, Token::RBRACE, may_abort);
PreParserScopedStatementList body(pointer_buffer());
LazyParsingResult result =
ParseStatementList(&body, Token::RBRACE, may_abort);
if (result == kLazyParsingAborted) return result;
// Position right after terminal '}'.
......
......@@ -400,6 +400,7 @@ class PreParserStatementList {
class PreParserScopedStatementList {
public:
explicit PreParserScopedStatementList(std::vector<void*>* buffer) {}
void Rewind() {}
void Add(const PreParserStatement& element) {}
};
......@@ -453,6 +454,9 @@ class PreParserStatement {
return PreParserStatement(kJumpStatement);
}
void InitializeStatements(const PreParserScopedStatementList& statements,
Zone* zone) {}
// Creates expression statement from expression.
// Preserves being an unparenthesized string literal, possibly
// "use strict".
......@@ -665,7 +669,7 @@ class PreParserFactory {
}
PreParserExpression NewFunctionLiteral(
const PreParserIdentifier& name, Scope* scope,
PreParserStatementList body, int expected_property_count,
const PreParserScopedStatementList& body, int expected_property_count,
int parameter_count, int function_length,
FunctionLiteral::ParameterFlag has_duplicate_parameters,
FunctionLiteral::FunctionType function_type,
......@@ -687,9 +691,17 @@ class PreParserFactory {
PreParserStatement EmptyStatement() { return PreParserStatement::Default(); }
PreParserStatement NewBlock(
int capacity, bool ignore_completion_value,
ZonePtrList<const AstRawString>* labels = nullptr) {
PreParserStatement NewBlock(int capacity, bool ignore_completion_value) {
return PreParserStatement::Default();
}
PreParserStatement NewBlock(bool ignore_completion_value,
ZonePtrList<const AstRawString>* labels) {
return PreParserStatement::Default();
}
PreParserStatement NewBlock(bool ignore_completion_value,
const PreParserScopedStatementList& list) {
return PreParserStatement::Default();
}
......@@ -869,8 +881,7 @@ struct ParserTypes<PreParser> {
typedef PreParserPropertyList ClassPropertyList;
typedef PreParserFormalParameters FormalParameters;
typedef PreParserStatement Statement;
typedef PreParserStatementList StatementList;
typedef PreParserScopedStatementList ScopedStatementList;
typedef PreParserScopedStatementList StatementList;
typedef PreParserExpressionList ExpressionList;
typedef PreParserExpressionList ObjectPropertyList;
typedef PreParserStatement Block;
......@@ -1044,7 +1055,7 @@ class PreParser : public ParserBase<PreParser> {
V8_INLINE void PrepareGeneratorVariables() {}
V8_INLINE void RewriteAsyncFunctionBody(
PreParserStatementList body, PreParserStatement block,
const PreParserScopedStatementList* body, PreParserStatement block,
const PreParserExpression& return_value) {}
void DeclareAndInitializeVariables(
......@@ -1102,11 +1113,11 @@ class PreParser : public ParserBase<PreParser> {
Scanner::Location* location,
const char** arg) {}
V8_INLINE void ParseAndRewriteGeneratorFunctionBody(
int pos, FunctionKind kind, PreParserStatementList body) {
int pos, FunctionKind kind, PreParserScopedStatementList* body) {
ParseStatementList(body, Token::RBRACE);
}
V8_INLINE void ParseAndRewriteAsyncGeneratorFunctionBody(
int pos, FunctionKind kind, PreParserStatementList body) {
int pos, FunctionKind kind, PreParserScopedStatementList* body) {
ParseStatementList(body, Token::RBRACE);
}
V8_INLINE void DeclareFunctionNameVar(
......
......@@ -327,9 +327,12 @@ class ScopedPtrList final {
explicit ScopedPtrList(std::vector<void*>* buffer)
: buffer_(*buffer), start_(buffer->size()), end_(buffer->size()) {}
~ScopedPtrList() {
~ScopedPtrList() { Rewind(); }
void Rewind() {
DCHECK_EQ(buffer_.size(), end_);
buffer_.resize(start_);
end_ = start_;
}
int length() const { return static_cast<int>(end_ - start_); }
......
......@@ -1445,7 +1445,6 @@ TEST(DiscardFunctionBody) {
i::parsing::ParseProgram(&info, isolate);
function = info.literal();
CHECK_NOT_NULL(function);
CHECK_NOT_NULL(function->body());
CHECK_EQ(1, function->body()->length());
i::FunctionLiteral* inner =
function->body()->first()->AsExpressionStatement()->expression()->
......@@ -1461,7 +1460,7 @@ TEST(DiscardFunctionBody) {
// TODO(conradw): This path won't be hit until the other test cases can be
// uncommented.
UNREACHABLE();
CHECK_NOT_NULL(inner->body());
CHECK(inner->ShouldEagerCompile());
CHECK_GE(2, inner->body()->length());
i::Expression* exp = inner->body()->at(1)->AsExpressionStatement()->
expression()->AsBinaryOperation()->right();
......@@ -1475,7 +1474,7 @@ TEST(DiscardFunctionBody) {
AsFunctionLiteral();
}
}
CHECK_NULL(fun->body());
CHECK(!fun->ShouldEagerCompile());
}
}
......
......@@ -63,9 +63,11 @@ class BackgroundCompileTaskTest : public TestWithNativeContext {
outer_parse_info->zone(), script_scope, FUNCTION_SCOPE);
function_scope->set_start_position(shared->StartPosition());
function_scope->set_end_position(shared->EndPosition());
std::vector<void*> buffer;
ScopedPtrList<Statement> statements(&buffer);
const FunctionLiteral* function_literal =
ast_node_factory.NewFunctionLiteral(
function_name, function_scope, nullptr, -1, -1, -1,
function_name, function_scope, statements, -1, -1, -1,
FunctionLiteral::kNoDuplicateParameters,
FunctionLiteral::kAnonymousExpression,
FunctionLiteral::kShouldEagerCompile, shared->StartPosition(), true,
......
......@@ -85,9 +85,11 @@ class CompilerDispatcherTest : public TestWithNativeContext {
outer_parse_info->zone(), script_scope, FUNCTION_SCOPE);
function_scope->set_start_position(shared->StartPosition());
function_scope->set_end_position(shared->EndPosition());
std::vector<void*> pointer_buffer;
ScopedPtrList<Statement> statements(&pointer_buffer);
const FunctionLiteral* function_literal =
ast_node_factory.NewFunctionLiteral(
function_name, function_scope, nullptr, -1, -1, -1,
function_name, function_scope, statements, -1, -1, -1,
FunctionLiteral::kNoDuplicateParameters,
FunctionLiteral::kAnonymousExpression,
FunctionLiteral::kShouldEagerCompile, shared->StartPosition(), true,
......
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