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

Unified Diff: src/parser.h

Issue 1309813007: [es6] implement destructuring assignment (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Cache te right scope in DeclareAndInitializeVariables() 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
Index: src/parser.h
diff --git a/src/parser.h b/src/parser.h
index 6c641721861146f7d53c9f9f31f322802276e6e6..ea3c7acf9faea7e92e88d08e75191abcf12278d5 100644
--- a/src/parser.h
+++ b/src/parser.h
@@ -888,6 +888,11 @@ class ParserTraits {
ZoneList<v8::internal::Expression*>* args,
int pos);
+ // Rewrite all DestructuringAssignments in the current FunctionState.
+ V8_INLINE void RewriteDestructuringAssignments();
+
+ V8_INLINE void ShouldRewriteDestructuringAssignment(Expression* assignment);
+
private:
Parser* parser_;
};
@@ -1035,6 +1040,10 @@ class Parser : public ParserBase<ParserTraits> {
const DeclarationParsingResult::Declaration* declaration,
ZoneList<const AstRawString*>* names, bool* ok);
+ static void RewriteDestructuringAssignment(Parser* parser,
+ Assignment* assignment,
+ Scope* Scope, bool* ok);
+
void set_initializer_position(int pos) { initializer_position_ = pos; }
private:
@@ -1046,6 +1055,16 @@ class Parser : public ParserBase<ParserTraits> {
#undef DECLARE_VISIT
void Visit(AstNode* node) override;
+ enum PatternContext {
+ BINDING,
+ INITIALIZER,
+ ASSIGNMENT,
+ ASSIGNMENT_INITIALIZER
+ };
+
+ PatternContext context() const { return context_; }
+ void set_context(PatternContext context) { context_ = context; }
+
void RecurseIntoSubpattern(AstNode* pattern, Expression* value) {
Expression* old_value = current_value_;
current_value_ = value;
@@ -1053,14 +1072,57 @@ class Parser : public ParserBase<ParserTraits> {
current_value_ = old_value;
}
+ void VisitObjectLiteral(ObjectLiteral* node, Variable** temp_var);
+ void VisitArrayLiteral(ArrayLiteral* node, Variable** temp_var);
+
+ bool IsBindingContext() const { return IsBindingContext(context_); }
+ bool IsInitializerContext() const { return context_ != ASSIGNMENT; }
+ bool IsAssignmentContext() const { return IsAssignmentContext(context_); }
+ bool IsAssignmentContext(PatternContext c) const {
+ return c == ASSIGNMENT || c == ASSIGNMENT_INITIALIZER;
+ }
+ bool IsBindingContext(PatternContext c) const {
+ return c == BINDING || c == INITIALIZER;
+ }
+ PatternContext SetAssignmentContextIfNeeded(Expression* node) {
+ PatternContext old_context = context();
+ if (node->IsAssignment() && node->AsAssignment()->op() == Token::ASSIGN) {
+ set_context(ASSIGNMENT);
+ }
+ return old_context;
+ }
+
+ PatternContext SetInitializerContextIfNeeded(Expression* node) {
adamk 2015/11/25 21:05:28 Any reason all of these functions need to be in th
caitp (gmail) 2015/11/25 21:41:51 No real reason, it was just convenient while writi
+ // Set appropriate initializer context for BindingElement and
+ // AssignmentElement nodes
+ PatternContext old_context = context();
+ if (node->IsAssignment() && node->AsAssignment()->op() == Token::ASSIGN) {
+ switch (old_context) {
+ case BINDING:
+ set_context(INITIALIZER);
+ break;
+ case ASSIGNMENT:
+ set_context(ASSIGNMENT_INITIALIZER);
+ break;
+ default:
+ break;
+ }
+ }
+ return old_context;
+ }
+
Variable* CreateTempVar(Expression* value = nullptr);
- AstNodeFactory* factory() const { return descriptor_->parser->factory(); }
+ AstNodeFactory* factory() const { return parser_->factory(); }
AstValueFactory* ast_value_factory() const {
- return descriptor_->parser->ast_value_factory();
+ return parser_->ast_value_factory();
}
- Zone* zone() const { return descriptor_->parser->zone(); }
+ Zone* zone() const { return parser_->zone(); }
+ Scope* scope() const { return scope_; }
+ Scope* scope_;
+ Parser* parser_;
+ PatternContext context_;
Expression* pattern_;
int initializer_position_;
Block* block_;
@@ -1210,6 +1272,11 @@ class Parser : public ParserBase<ParserTraits> {
void SetLanguageMode(Scope* scope, LanguageMode mode);
void RaiseLanguageMode(LanguageMode mode);
+ V8_INLINE void RewriteDestructuringAssignments();
+
+ friend class InitializerRewriter;
+ void RewriteParameterInitializer(Expression* expr, Scope* scope);
+
Scanner scanner_;
PreParser* reusable_preparser_;
Scope* original_scope_; // for ES5 function declarations in sloppy eval
@@ -1398,6 +1465,54 @@ DoExpression* ParserTraits::ParseDoExpression(bool* ok) {
}
+void ParserTraits::RewriteDestructuringAssignments() {
+ parser_->RewriteDestructuringAssignments();
+}
+
+
+void Parser::RewriteDestructuringAssignments() {
adamk 2015/11/25 21:05:28 Another "why is this in the header?" question.
+ FunctionState* func = function_state_;
+ if (!allow_harmony_destructuring_assignment()) return;
+ typedef typename ParserBase<ParserTraits>::DestructuringAssignment Pair;
+ const List<Pair>& assignments = func->destructuring_assignments_to_rewrite();
+ for (int i = assignments.length() - 1; i >= 0; --i) {
+ // Rewrite list in reverse, so that nested assignment patterns are rewritten
+ // correctly.
+ Pair pair = assignments.at(i);
+ Assignment* to_rewrite = pair.assignment->AsAssignment();
+ Scope* scope = pair.scope;
+ DCHECK_NOT_NULL(to_rewrite);
+ DCHECK(to_rewrite->is_destructuring_assignment());
+ if (!to_rewrite->destructuring_assignment()) {
+ bool ok = true;
+ PatternRewriter::RewriteDestructuringAssignment(this, to_rewrite, scope,
+ &ok);
+ DCHECK(ok);
+ }
+ }
+}
+
+
+void ParserTraits::ShouldRewriteDestructuringAssignment(Expression* expr) {
adamk 2015/11/25 21:05:28 And here... Also, as mentioned before, this name
caitp (gmail) 2015/11/25 21:41:51 Acknowledged.
+ DCHECK(expr->IsAssignment());
+ Assignment* assignment = expr->AsAssignment();
+ DCHECK(!assignment->is_destructuring_assignment());
+ DCHECK_EQ(Token::ASSIGN, assignment->op());
+ assignment->set_is_destructuring_assignment();
+ parser_->function_state_->AddDestructuringAssignment(
+ Parser::DestructuringAssignment(assignment, parser_->scope_));
+}
+
+inline void Parser::PatternRewriter::VisitObjectLiteral(ObjectLiteral* node) {
adamk 2015/11/25 21:05:28 And here and the below. parser.h is long enough as
+ Variable* temp_var = nullptr;
+ VisitObjectLiteral(node, &temp_var);
+}
+
+inline void Parser::PatternRewriter::VisitArrayLiteral(ArrayLiteral* node) {
+ Variable* temp_var = nullptr;
+ VisitArrayLiteral(node, &temp_var);
+}
+
} // namespace internal
} // namespace v8

Powered by Google App Engine
This is Rietveld 408576698