blob: 3e3587b2bd75bcf6646bcd18635bf1a8f956d55c [file] [log] [blame]
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001// Copyright 2015 the V8 project authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "src/parsing/parameter-initializer-rewriter.h"
6
7#include "src/ast/ast.h"
8#include "src/ast/ast-expression-visitor.h"
9#include "src/ast/scopes.h"
10
11namespace v8 {
12namespace internal {
13
14namespace {
15
16
17class Rewriter final : public AstExpressionVisitor {
18 public:
19 Rewriter(uintptr_t stack_limit, Expression* initializer, Scope* old_scope,
20 Scope* new_scope)
21 : AstExpressionVisitor(stack_limit, initializer),
22 old_scope_(old_scope),
23 new_scope_(new_scope) {}
24
25 private:
26 void VisitExpression(Expression* expr) override {}
27
28 void VisitFunctionLiteral(FunctionLiteral* expr) override;
29 void VisitClassLiteral(ClassLiteral* expr) override;
30 void VisitVariableProxy(VariableProxy* expr) override;
31
32 Scope* old_scope_;
33 Scope* new_scope_;
34};
35
36
37void Rewriter::VisitFunctionLiteral(FunctionLiteral* function_literal) {
38 function_literal->scope()->ReplaceOuterScope(new_scope_);
39}
40
41
42void Rewriter::VisitClassLiteral(ClassLiteral* class_literal) {
43 class_literal->scope()->ReplaceOuterScope(new_scope_);
44 if (class_literal->extends() != nullptr) {
45 Visit(class_literal->extends());
46 }
47 // No need to visit the constructor since it will have the class
48 // scope on its scope chain.
49 ZoneList<ObjectLiteralProperty*>* props = class_literal->properties();
50 for (int i = 0; i < props->length(); ++i) {
51 ObjectLiteralProperty* prop = props->at(i);
52 if (!prop->key()->IsLiteral()) {
53 Visit(prop->key());
54 }
55 // No need to visit the values, since all values are functions with
56 // the class scope on their scope chain.
57 DCHECK(prop->value()->IsFunctionLiteral());
58 }
59}
60
61
62void Rewriter::VisitVariableProxy(VariableProxy* proxy) {
63 if (proxy->is_resolved()) {
64 Variable* var = proxy->var();
Ben Murdochda12d292016-06-02 14:46:10 +010065 if (var->mode() != TEMPORARY) return;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000066 if (old_scope_->RemoveTemporary(var)) {
67 var->set_scope(new_scope_);
68 new_scope_->AddTemporary(var);
69 }
70 } else if (old_scope_->RemoveUnresolved(proxy)) {
71 new_scope_->AddUnresolved(proxy);
72 }
73}
74
75
76} // anonymous namespace
77
78
79void RewriteParameterInitializerScope(uintptr_t stack_limit,
80 Expression* initializer, Scope* old_scope,
81 Scope* new_scope) {
82 Rewriter rewriter(stack_limit, initializer, old_scope, new_scope);
83 rewriter.Run();
84}
85
86
87} // namespace internal
88} // namespace v8