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

Unified Diff: src/pattern-rewriter.cc

Issue 1481613002: Create ast/ and parsing/ subdirectories and move appropriate files (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Rebase Created 5 years, 1 month 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/parsing/token.cc ('k') | src/ppc/codegen-ppc.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/pattern-rewriter.cc
diff --git a/src/pattern-rewriter.cc b/src/pattern-rewriter.cc
deleted file mode 100644
index e5231155687b7b2826881537777938a85078e721..0000000000000000000000000000000000000000
--- a/src/pattern-rewriter.cc
+++ /dev/null
@@ -1,435 +0,0 @@
-// Copyright 2015 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "src/ast.h"
-#include "src/messages.h"
-#include "src/parameter-initializer-rewriter.h"
-#include "src/parser.h"
-
-namespace v8 {
-
-namespace internal {
-
-
-void Parser::PatternRewriter::DeclareAndInitializeVariables(
- Block* block, const DeclarationDescriptor* declaration_descriptor,
- const DeclarationParsingResult::Declaration* declaration,
- ZoneList<const AstRawString*>* names, bool* ok) {
- PatternRewriter rewriter;
-
- rewriter.pattern_ = declaration->pattern;
- rewriter.initializer_position_ = declaration->initializer_position;
- rewriter.block_ = block;
- rewriter.descriptor_ = declaration_descriptor;
- rewriter.names_ = names;
- rewriter.ok_ = ok;
-
- rewriter.RecurseIntoSubpattern(rewriter.pattern_, declaration->initializer);
-}
-
-
-void Parser::PatternRewriter::VisitVariableProxy(VariableProxy* pattern) {
- Expression* value = current_value_;
- descriptor_->scope->RemoveUnresolved(pattern);
-
- // Declare variable.
- // Note that we *always* must treat the initial value via a separate init
- // assignment for variables and constants because the value must be assigned
- // when the variable is encountered in the source. But the variable/constant
- // is declared (and set to 'undefined') upon entering the function within
- // which the variable or constant is declared. Only function variables have
- // an initial value in the declaration (because they are initialized upon
- // entering the function).
- //
- // If we have a legacy const declaration, in an inner scope, the proxy
- // is always bound to the declared variable (independent of possibly
- // surrounding 'with' statements).
- // For let/const declarations in harmony mode, we can also immediately
- // pre-resolve the proxy because it resides in the same scope as the
- // declaration.
- Parser* parser = descriptor_->parser;
- const AstRawString* name = pattern->raw_name();
- VariableProxy* proxy = parser->NewUnresolved(name, descriptor_->mode);
- Declaration* declaration = factory()->NewVariableDeclaration(
- proxy, descriptor_->mode, descriptor_->scope,
- descriptor_->declaration_pos);
- Variable* var = parser->Declare(declaration, descriptor_->declaration_kind,
- descriptor_->mode != VAR, ok_,
- descriptor_->hoist_scope);
- if (!*ok_) return;
- DCHECK_NOT_NULL(var);
- DCHECK(!proxy->is_resolved() || proxy->var() == var);
- var->set_initializer_position(initializer_position_);
-
- DCHECK(initializer_position_ != RelocInfo::kNoPosition);
-
- if (descriptor_->declaration_scope->num_var_or_const() >
- kMaxNumFunctionLocals) {
- parser->ReportMessage(MessageTemplate::kTooManyVariables);
- *ok_ = false;
- return;
- }
- if (names_) {
- names_->Add(name, zone());
- }
-
- // Initialize variables if needed. A
- // declaration of the form:
- //
- // var v = x;
- //
- // is syntactic sugar for:
- //
- // var v; v = x;
- //
- // In particular, we need to re-lookup 'v' (in scope_, not
- // declaration_scope) as it may be a different 'v' than the 'v' in the
- // declaration (e.g., if we are inside a 'with' statement or 'catch'
- // block).
- //
- // However, note that const declarations are different! A const
- // declaration of the form:
- //
- // const c = x;
- //
- // is *not* syntactic sugar for:
- //
- // const c; c = x;
- //
- // The "variable" c initialized to x is the same as the declared
- // one - there is no re-lookup (see the last parameter of the
- // Declare() call above).
- Scope* initialization_scope = descriptor_->is_const
- ? descriptor_->declaration_scope
- : descriptor_->scope;
-
-
- // Global variable declarations must be compiled in a specific
- // way. When the script containing the global variable declaration
- // is entered, the global variable must be declared, so that if it
- // doesn't exist (on the global object itself, see ES5 errata) it
- // gets created with an initial undefined value. This is handled
- // by the declarations part of the function representing the
- // top-level global code; see Runtime::DeclareGlobalVariable. If
- // it already exists (in the object or in a prototype), it is
- // *not* touched until the variable declaration statement is
- // executed.
- //
- // Executing the variable declaration statement will always
- // guarantee to give the global object an own property.
- // This way, global variable declarations can shadow
- // properties in the prototype chain, but only after the variable
- // declaration statement has been executed. This is important in
- // browsers where the global object (window) has lots of
- // properties defined in prototype objects.
- if (initialization_scope->is_script_scope() &&
- !IsLexicalVariableMode(descriptor_->mode)) {
- // Compute the arguments for the runtime
- // call.test-parsing/InitializedDeclarationsInStrictForOfError
- ZoneList<Expression*>* arguments =
- new (zone()) ZoneList<Expression*>(3, zone());
- // We have at least 1 parameter.
- arguments->Add(
- factory()->NewStringLiteral(name, descriptor_->declaration_pos),
- zone());
- CallRuntime* initialize;
-
- if (descriptor_->is_const) {
- arguments->Add(value, zone());
- value = NULL; // zap the value to avoid the unnecessary assignment
-
- // Construct the call to Runtime_InitializeConstGlobal
- // and add it to the initialization statement block.
- // Note that the function does different things depending on
- // the number of arguments (1 or 2).
- initialize =
- factory()->NewCallRuntime(Runtime::kInitializeConstGlobal, arguments,
- descriptor_->initialization_pos);
- } else {
- // Add language mode.
- // We may want to pass singleton to avoid Literal allocations.
- LanguageMode language_mode = initialization_scope->language_mode();
- arguments->Add(factory()->NewNumberLiteral(language_mode,
- descriptor_->declaration_pos),
- zone());
-
- // Be careful not to assign a value to the global variable if
- // we're in a with. The initialization value should not
- // necessarily be stored in the global object in that case,
- // which is why we need to generate a separate assignment node.
- if (value != NULL && !descriptor_->scope->inside_with()) {
- arguments->Add(value, zone());
- value = NULL; // zap the value to avoid the unnecessary assignment
- // Construct the call to Runtime_InitializeVarGlobal
- // and add it to the initialization statement block.
- initialize =
- factory()->NewCallRuntime(Runtime::kInitializeVarGlobal, arguments,
- descriptor_->declaration_pos);
- } else {
- initialize = NULL;
- }
- }
-
- if (initialize != NULL) {
- block_->statements()->Add(
- factory()->NewExpressionStatement(initialize, RelocInfo::kNoPosition),
- zone());
- }
- } else if (value != nullptr && (descriptor_->mode == CONST_LEGACY ||
- IsLexicalVariableMode(descriptor_->mode))) {
- // Constant initializations always assign to the declared constant which
- // is always at the function scope level. This is only relevant for
- // dynamically looked-up variables and constants (the
- // start context for constant lookups is always the function context,
- // while it is the top context for var declared variables). Sigh...
- // For 'let' and 'const' declared variables in harmony mode the
- // initialization also always assigns to the declared variable.
- DCHECK_NOT_NULL(proxy);
- DCHECK_NOT_NULL(proxy->var());
- DCHECK_NOT_NULL(value);
- Assignment* assignment = factory()->NewAssignment(
- Token::INIT, proxy, value, descriptor_->initialization_pos);
- block_->statements()->Add(
- factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition),
- zone());
- value = NULL;
- }
-
- // Add an assignment node to the initialization statement block if we still
- // have a pending initialization value.
- if (value != NULL) {
- DCHECK(descriptor_->mode == VAR);
- // 'var' initializations are simply assignments (with all the consequences
- // if they are inside a 'with' statement - they may change a 'with' object
- // property).
- VariableProxy* proxy = initialization_scope->NewUnresolved(factory(), name);
- Assignment* assignment = factory()->NewAssignment(
- Token::INIT, proxy, value, descriptor_->initialization_pos);
- block_->statements()->Add(
- factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition),
- zone());
- }
-}
-
-
-Variable* Parser::PatternRewriter::CreateTempVar(Expression* value) {
- auto temp = descriptor_->parser->scope_->NewTemporary(
- ast_value_factory()->empty_string());
- if (value != nullptr) {
- auto assignment = factory()->NewAssignment(
- Token::ASSIGN, factory()->NewVariableProxy(temp), value,
- RelocInfo::kNoPosition);
-
- block_->statements()->Add(
- factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition),
- zone());
- }
- return temp;
-}
-
-
-void Parser::PatternRewriter::VisitObjectLiteral(ObjectLiteral* pattern) {
- auto temp = CreateTempVar(current_value_);
-
- block_->statements()->Add(descriptor_->parser->BuildAssertIsCoercible(temp),
- zone());
-
- for (ObjectLiteralProperty* property : *pattern->properties()) {
- RecurseIntoSubpattern(
- property->value(),
- factory()->NewProperty(factory()->NewVariableProxy(temp),
- property->key(), RelocInfo::kNoPosition));
- }
-}
-
-
-void Parser::PatternRewriter::VisitArrayLiteral(ArrayLiteral* node) {
- auto temp = CreateTempVar(current_value_);
-
- block_->statements()->Add(descriptor_->parser->BuildAssertIsCoercible(temp),
- zone());
-
- auto iterator = CreateTempVar(descriptor_->parser->GetIterator(
- factory()->NewVariableProxy(temp), factory()));
- auto done = CreateTempVar(
- factory()->NewBooleanLiteral(false, RelocInfo::kNoPosition));
- auto result = CreateTempVar();
- auto v = CreateTempVar();
-
- Spread* spread = nullptr;
- for (Expression* value : *node->values()) {
- if (value->IsSpread()) {
- spread = value->AsSpread();
- break;
- }
-
- // if (!done) {
- // result = IteratorNext(iterator);
- // v = (done = result.done) ? undefined : result.value;
- // }
- auto next_block =
- factory()->NewBlock(nullptr, 2, true, RelocInfo::kNoPosition);
- next_block->statements()->Add(
- factory()->NewExpressionStatement(
- descriptor_->parser->BuildIteratorNextResult(
- factory()->NewVariableProxy(iterator), result,
- RelocInfo::kNoPosition),
- RelocInfo::kNoPosition),
- zone());
-
- auto assign_to_done = factory()->NewAssignment(
- Token::ASSIGN, factory()->NewVariableProxy(done),
- factory()->NewProperty(
- factory()->NewVariableProxy(result),
- factory()->NewStringLiteral(ast_value_factory()->done_string(),
- RelocInfo::kNoPosition),
- RelocInfo::kNoPosition),
- RelocInfo::kNoPosition);
- auto next_value = factory()->NewConditional(
- assign_to_done, factory()->NewUndefinedLiteral(RelocInfo::kNoPosition),
- factory()->NewProperty(
- factory()->NewVariableProxy(result),
- factory()->NewStringLiteral(ast_value_factory()->value_string(),
- RelocInfo::kNoPosition),
- RelocInfo::kNoPosition),
- RelocInfo::kNoPosition);
- next_block->statements()->Add(
- factory()->NewExpressionStatement(
- factory()->NewAssignment(Token::ASSIGN,
- factory()->NewVariableProxy(v), next_value,
- RelocInfo::kNoPosition),
- RelocInfo::kNoPosition),
- zone());
-
- auto if_statement = factory()->NewIfStatement(
- factory()->NewUnaryOperation(Token::NOT,
- factory()->NewVariableProxy(done),
- RelocInfo::kNoPosition),
- next_block, factory()->NewEmptyStatement(RelocInfo::kNoPosition),
- RelocInfo::kNoPosition);
- block_->statements()->Add(if_statement, zone());
-
- if (!(value->IsLiteral() && value->AsLiteral()->raw_value()->IsTheHole())) {
- RecurseIntoSubpattern(value, factory()->NewVariableProxy(v));
- }
- }
-
- if (spread != nullptr) {
- // array = [];
- // if (!done) %concat_iterable_to_array(array, iterator);
- auto empty_exprs = new (zone()) ZoneList<Expression*>(0, zone());
- auto array = CreateTempVar(factory()->NewArrayLiteral(
- empty_exprs,
- // Reuse pattern's literal index - it is unused since there is no
- // actual literal allocated.
- node->literal_index(), is_strong(descriptor_->parser->language_mode()),
- RelocInfo::kNoPosition));
-
- auto arguments = new (zone()) ZoneList<Expression*>(2, zone());
- arguments->Add(factory()->NewVariableProxy(array), zone());
- arguments->Add(factory()->NewVariableProxy(iterator), zone());
- auto spread_into_array_call =
- factory()->NewCallRuntime(Context::CONCAT_ITERABLE_TO_ARRAY_INDEX,
- arguments, RelocInfo::kNoPosition);
-
- auto if_statement = factory()->NewIfStatement(
- factory()->NewUnaryOperation(Token::NOT,
- factory()->NewVariableProxy(done),
- RelocInfo::kNoPosition),
- factory()->NewExpressionStatement(spread_into_array_call,
- RelocInfo::kNoPosition),
- factory()->NewEmptyStatement(RelocInfo::kNoPosition),
- RelocInfo::kNoPosition);
- block_->statements()->Add(if_statement, zone());
-
- RecurseIntoSubpattern(spread->expression(),
- factory()->NewVariableProxy(array));
- }
-}
-
-
-void Parser::PatternRewriter::VisitAssignment(Assignment* node) {
- // let {<pattern> = <init>} = <value>
- // becomes
- // temp = <value>;
- // <pattern> = temp === undefined ? <init> : temp;
- DCHECK(node->op() == Token::ASSIGN);
- auto temp = CreateTempVar(current_value_);
- Expression* is_undefined = factory()->NewCompareOperation(
- Token::EQ_STRICT, factory()->NewVariableProxy(temp),
- factory()->NewUndefinedLiteral(RelocInfo::kNoPosition),
- RelocInfo::kNoPosition);
- Expression* initializer = node->value();
- if (descriptor_->declaration_kind == DeclarationDescriptor::PARAMETER &&
- descriptor_->scope->is_arrow_scope()) {
- // TODO(adamk): Only call this if necessary.
- RewriteParameterInitializerScope(
- descriptor_->parser->stack_limit(), initializer,
- descriptor_->scope->outer_scope(), descriptor_->scope);
- }
- Expression* value = factory()->NewConditional(
- is_undefined, initializer, factory()->NewVariableProxy(temp),
- RelocInfo::kNoPosition);
- RecurseIntoSubpattern(node->target(), value);
-}
-
-
-// =============== UNREACHABLE =============================
-
-void Parser::PatternRewriter::Visit(AstNode* node) { UNREACHABLE(); }
-
-#define NOT_A_PATTERN(Node) \
- void Parser::PatternRewriter::Visit##Node(v8::internal::Node*) { \
- UNREACHABLE(); \
- }
-
-NOT_A_PATTERN(BinaryOperation)
-NOT_A_PATTERN(Block)
-NOT_A_PATTERN(BreakStatement)
-NOT_A_PATTERN(Call)
-NOT_A_PATTERN(CallNew)
-NOT_A_PATTERN(CallRuntime)
-NOT_A_PATTERN(CaseClause)
-NOT_A_PATTERN(ClassLiteral)
-NOT_A_PATTERN(CompareOperation)
-NOT_A_PATTERN(Conditional)
-NOT_A_PATTERN(ContinueStatement)
-NOT_A_PATTERN(CountOperation)
-NOT_A_PATTERN(DebuggerStatement)
-NOT_A_PATTERN(DoExpression)
-NOT_A_PATTERN(DoWhileStatement)
-NOT_A_PATTERN(EmptyStatement)
-NOT_A_PATTERN(EmptyParentheses)
-NOT_A_PATTERN(ExportDeclaration)
-NOT_A_PATTERN(ExpressionStatement)
-NOT_A_PATTERN(ForInStatement)
-NOT_A_PATTERN(ForOfStatement)
-NOT_A_PATTERN(ForStatement)
-NOT_A_PATTERN(FunctionDeclaration)
-NOT_A_PATTERN(FunctionLiteral)
-NOT_A_PATTERN(IfStatement)
-NOT_A_PATTERN(ImportDeclaration)
-NOT_A_PATTERN(Literal)
-NOT_A_PATTERN(NativeFunctionLiteral)
-NOT_A_PATTERN(Property)
-NOT_A_PATTERN(RegExpLiteral)
-NOT_A_PATTERN(ReturnStatement)
-NOT_A_PATTERN(SloppyBlockFunctionStatement)
-NOT_A_PATTERN(Spread)
-NOT_A_PATTERN(SuperPropertyReference)
-NOT_A_PATTERN(SuperCallReference)
-NOT_A_PATTERN(SwitchStatement)
-NOT_A_PATTERN(ThisFunction)
-NOT_A_PATTERN(Throw)
-NOT_A_PATTERN(TryCatchStatement)
-NOT_A_PATTERN(TryFinallyStatement)
-NOT_A_PATTERN(UnaryOperation)
-NOT_A_PATTERN(VariableDeclaration)
-NOT_A_PATTERN(WhileStatement)
-NOT_A_PATTERN(WithStatement)
-NOT_A_PATTERN(Yield)
-
-#undef NOT_A_PATTERN
-} // namespace internal
-} // namespace v8
« no previous file with comments | « src/parsing/token.cc ('k') | src/ppc/codegen-ppc.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698