full-codegen.h revision f7060e27768c550ace7ec48ad8c093466db52dfa
1f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke// Copyright 2010 the V8 project authors. All rights reserved.
2d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke// Redistribution and use in source and binary forms, with or without
3d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke// modification, are permitted provided that the following conditions are
4d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke// met:
5d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke//
6d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke//     * Redistributions of source code must retain the above copyright
7d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke//       notice, this list of conditions and the following disclaimer.
8d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke//     * Redistributions in binary form must reproduce the above
9d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke//       copyright notice, this list of conditions and the following
10d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke//       disclaimer in the documentation and/or other materials provided
11d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke//       with the distribution.
12d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke//     * Neither the name of Google Inc. nor the names of its
13d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke//       contributors may be used to endorse or promote products derived
14d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke//       from this software without specific prior written permission.
15d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke//
16d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
28d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke#ifndef V8_FULL_CODEGEN_H_
29d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke#define V8_FULL_CODEGEN_H_
30d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
31d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke#include "v8.h"
32d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
33d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke#include "ast.h"
34f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke#include "compiler.h"
35d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
36d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkenamespace v8 {
37d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkenamespace internal {
38d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
39d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkeclass FullCodeGenSyntaxChecker: public AstVisitor {
40d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke public:
41d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  FullCodeGenSyntaxChecker() : has_supported_syntax_(true) {}
42d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
43d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  void Check(FunctionLiteral* fun);
44d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
45d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  bool has_supported_syntax() { return has_supported_syntax_; }
46d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
47d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke private:
48d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  void VisitDeclarations(ZoneList<Declaration*>* decls);
49d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  void VisitStatements(ZoneList<Statement*>* stmts);
50d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
51d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // AST node visit functions.
52d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke#define DECLARE_VISIT(type) virtual void Visit##type(type* node);
53d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  AST_NODE_LIST(DECLARE_VISIT)
54d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke#undef DECLARE_VISIT
55d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
56d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  bool has_supported_syntax_;
57d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
58d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  DISALLOW_COPY_AND_ASSIGN(FullCodeGenSyntaxChecker);
59d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke};
60d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
61d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
62d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke// -----------------------------------------------------------------------------
63d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke// Full code generator.
64d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
65d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkeclass FullCodeGenerator: public AstVisitor {
66d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke public:
674515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke  enum Mode {
684515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke    PRIMARY,
694515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke    SECONDARY
704515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke  };
714515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke
723100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  explicit FullCodeGenerator(MacroAssembler* masm)
73d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke      : masm_(masm),
743100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu        info_(NULL),
75d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke        nesting_stack_(NULL),
76d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke        loop_depth_(0),
77d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke        location_(kStack),
78d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke        true_label_(NULL),
79d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke        false_label_(NULL) {
80d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  }
81d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
823100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  static Handle<Code> MakeCode(CompilationInfo* info);
83d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
843100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  void Generate(CompilationInfo* info, Mode mode);
85d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
86d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke private:
87d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  class Breakable;
88d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  class Iteration;
89d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  class TryCatch;
90d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  class TryFinally;
91d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  class Finally;
92d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  class ForIn;
93d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
94d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  class NestedStatement BASE_EMBEDDED {
95d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke   public:
96d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    explicit NestedStatement(FullCodeGenerator* codegen) : codegen_(codegen) {
97d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke      // Link into codegen's nesting stack.
98d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke      previous_ = codegen->nesting_stack_;
99d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke      codegen->nesting_stack_ = this;
100d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    }
101d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    virtual ~NestedStatement() {
102d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke      // Unlink from codegen's nesting stack.
103d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke      ASSERT_EQ(this, codegen_->nesting_stack_);
104d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke      codegen_->nesting_stack_ = previous_;
105d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    }
106d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
107d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    virtual Breakable* AsBreakable() { return NULL; }
108d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    virtual Iteration* AsIteration() { return NULL; }
109d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    virtual TryCatch* AsTryCatch() { return NULL; }
110d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    virtual TryFinally* AsTryFinally() { return NULL; }
111d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    virtual Finally* AsFinally() { return NULL; }
112d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    virtual ForIn* AsForIn() { return NULL; }
113d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
114d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    virtual bool IsContinueTarget(Statement* target) { return false; }
115d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    virtual bool IsBreakTarget(Statement* target) { return false; }
116d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
117d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    // Generate code to leave the nested statement. This includes
118d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    // cleaning up any stack elements in use and restoring the
119d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    // stack to the expectations of the surrounding statements.
120d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    // Takes a number of stack elements currently on top of the
121d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    // nested statement's stack, and returns a number of stack
122d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    // elements left on top of the surrounding statement's stack.
123d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    // The generated code must preserve the result register (which
124d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    // contains the value in case of a return).
125d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    virtual int Exit(int stack_depth) {
126d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke      // Default implementation for the case where there is
127d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke      // nothing to clean up.
128d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke      return stack_depth;
129d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    }
130d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    NestedStatement* outer() { return previous_; }
131d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke   protected:
132d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    MacroAssembler* masm() { return codegen_->masm(); }
133d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke   private:
134d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    FullCodeGenerator* codegen_;
135d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    NestedStatement* previous_;
136d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    DISALLOW_COPY_AND_ASSIGN(NestedStatement);
137d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  };
138d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
139d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  class Breakable : public NestedStatement {
140d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke   public:
141d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    Breakable(FullCodeGenerator* codegen,
142d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke              BreakableStatement* break_target)
143d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke        : NestedStatement(codegen),
144d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke          target_(break_target) {}
145d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    virtual ~Breakable() {}
146d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    virtual Breakable* AsBreakable() { return this; }
147d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    virtual bool IsBreakTarget(Statement* statement) {
148d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke      return target_ == statement;
149d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    }
150d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    BreakableStatement* statement() { return target_; }
151d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    Label* break_target() { return &break_target_label_; }
152d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke   private:
153d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    BreakableStatement* target_;
154d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    Label break_target_label_;
155d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    DISALLOW_COPY_AND_ASSIGN(Breakable);
156d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  };
157d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
158d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  class Iteration : public Breakable {
159d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke   public:
160d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    Iteration(FullCodeGenerator* codegen,
161d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke              IterationStatement* iteration_statement)
162d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke        : Breakable(codegen, iteration_statement) {}
163d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    virtual ~Iteration() {}
164d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    virtual Iteration* AsIteration() { return this; }
165d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    virtual bool IsContinueTarget(Statement* statement) {
166d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke      return this->statement() == statement;
167d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    }
168d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    Label* continue_target() { return &continue_target_label_; }
169d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke   private:
170d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    Label continue_target_label_;
171d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    DISALLOW_COPY_AND_ASSIGN(Iteration);
172d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  };
173d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
174d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // The environment inside the try block of a try/catch statement.
175d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  class TryCatch : public NestedStatement {
176d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke   public:
177d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    explicit TryCatch(FullCodeGenerator* codegen, Label* catch_entry)
178d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke        : NestedStatement(codegen), catch_entry_(catch_entry) { }
179d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    virtual ~TryCatch() {}
180d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    virtual TryCatch* AsTryCatch() { return this; }
181d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    Label* catch_entry() { return catch_entry_; }
182d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    virtual int Exit(int stack_depth);
183d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke   private:
184d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    Label* catch_entry_;
185d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    DISALLOW_COPY_AND_ASSIGN(TryCatch);
186d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  };
187d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
188d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // The environment inside the try block of a try/finally statement.
189d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  class TryFinally : public NestedStatement {
190d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke   public:
191d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    explicit TryFinally(FullCodeGenerator* codegen, Label* finally_entry)
192d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke        : NestedStatement(codegen), finally_entry_(finally_entry) { }
193d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    virtual ~TryFinally() {}
194d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    virtual TryFinally* AsTryFinally() { return this; }
195d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    Label* finally_entry() { return finally_entry_; }
196d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    virtual int Exit(int stack_depth);
197d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke   private:
198d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    Label* finally_entry_;
199d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    DISALLOW_COPY_AND_ASSIGN(TryFinally);
200d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  };
201d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
202d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // A FinallyEnvironment represents being inside a finally block.
203d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // Abnormal termination of the finally block needs to clean up
204d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // the block's parameters from the stack.
205d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  class Finally : public NestedStatement {
206d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke   public:
207d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    explicit Finally(FullCodeGenerator* codegen) : NestedStatement(codegen) { }
208d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    virtual ~Finally() {}
209d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    virtual Finally* AsFinally() { return this; }
210d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    virtual int Exit(int stack_depth) {
211d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke      return stack_depth + kFinallyStackElementCount;
212d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    }
213d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke   private:
214d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    // Number of extra stack slots occupied during a finally block.
215d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    static const int kFinallyStackElementCount = 2;
216d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    DISALLOW_COPY_AND_ASSIGN(Finally);
217d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  };
218d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
219d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // A ForInEnvironment represents being inside a for-in loop.
220d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // Abnormal termination of the for-in block needs to clean up
221d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // the block's temporary storage from the stack.
222d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  class ForIn : public Iteration {
223d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke   public:
224d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    ForIn(FullCodeGenerator* codegen,
225d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke          ForInStatement* statement)
226d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke        : Iteration(codegen, statement) { }
227d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    virtual ~ForIn() {}
228d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    virtual ForIn* AsForIn() { return this; }
229d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    virtual int Exit(int stack_depth) {
230d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke      return stack_depth + kForInStackElementCount;
231d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    }
232d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke   private:
233d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    static const int kForInStackElementCount = 5;
234d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    DISALLOW_COPY_AND_ASSIGN(ForIn);
235d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  };
236d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
237d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  enum Location {
238d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    kAccumulator,
239d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    kStack
240d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  };
241d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
242d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  int SlotOffset(Slot* slot);
243d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
244d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // Emit code to convert a pure value (in a register, slot, as a literal,
245d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // or on top of the stack) into the result expected according to an
246d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // expression context.
247d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  void Apply(Expression::Context context, Register reg);
248d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
249d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // Slot cannot have type Slot::LOOKUP.
250d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  void Apply(Expression::Context context, Slot* slot);
251d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
252d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  void Apply(Expression::Context context, Literal* lit);
253d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  void ApplyTOS(Expression::Context context);
254d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
255d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // Emit code to discard count elements from the top of stack, then convert
256d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // a pure value into the result expected according to an expression
257d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // context.
258d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  void DropAndApply(int count, Expression::Context context, Register reg);
259d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
260f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  // Set up branch labels for a test expression.
261f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  void PrepareTest(Label* materialize_true,
262f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke                   Label* materialize_false,
263f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke                   Label** if_true,
264f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke                   Label** if_false);
265f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke
266d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // Emit code to convert pure control flow to a pair of labels into the
267d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // result expected according to an expression context.
268d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  void Apply(Expression::Context context,
269d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke             Label* materialize_true,
270d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke             Label* materialize_false);
271d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
272f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  // Emit code to convert constant control flow (true or false) into
273f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  // the result expected according to an expression context.
274f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  void Apply(Expression::Context context, bool flag);
275f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke
276d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // Helper function to convert a pure value into a test context.  The value
277d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // is expected on the stack or the accumulator, depending on the platform.
278d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // See the platform-specific implementation for details.
279d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  void DoTest(Expression::Context context);
280d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
281d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  void Move(Slot* dst, Register source, Register scratch1, Register scratch2);
282d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  void Move(Register dst, Slot* source);
283d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
284d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // Return an operand used to read/write to a known (ie, non-LOOKUP) slot.
285d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // May emit code to traverse the context chain, destroying the scratch
286d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // register.
287d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  MemOperand EmitSlotSearch(Slot* slot, Register scratch);
288d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
289d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  void VisitForEffect(Expression* expr) {
290d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    Expression::Context saved_context = context_;
291d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    context_ = Expression::kEffect;
292d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    Visit(expr);
293d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    context_ = saved_context;
294d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  }
295d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
296d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  void VisitForValue(Expression* expr, Location where) {
297d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    Expression::Context saved_context = context_;
298d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    Location saved_location = location_;
299d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    context_ = Expression::kValue;
300d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    location_ = where;
301d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    Visit(expr);
302d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    context_ = saved_context;
303d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    location_ = saved_location;
304d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  }
305d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
306d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  void VisitForControl(Expression* expr, Label* if_true, Label* if_false) {
307d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    Expression::Context saved_context = context_;
308d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    Label* saved_true = true_label_;
309d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    Label* saved_false = false_label_;
310d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    context_ = Expression::kTest;
311d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    true_label_ = if_true;
312d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    false_label_ = if_false;
313d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    Visit(expr);
314d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    context_ = saved_context;
315d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    true_label_ = saved_true;
316d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    false_label_ = saved_false;
317d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  }
318d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
319d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  void VisitForValueControl(Expression* expr,
320d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke                            Location where,
321d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke                            Label* if_true,
322d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke                            Label* if_false) {
323d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    Expression::Context saved_context = context_;
324d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    Location saved_location = location_;
325d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    Label* saved_true = true_label_;
326d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    Label* saved_false = false_label_;
327d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    context_ = Expression::kValueTest;
328d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    location_ = where;
329d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    true_label_ = if_true;
330d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    false_label_ = if_false;
331d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    Visit(expr);
332d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    context_ = saved_context;
333d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    location_ = saved_location;
334d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    true_label_ = saved_true;
335d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    false_label_ = saved_false;
336d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  }
337d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
338d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  void VisitForControlValue(Expression* expr,
339d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke                            Location where,
340d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke                            Label* if_true,
341d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke                            Label* if_false) {
342d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    Expression::Context saved_context = context_;
343d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    Location saved_location = location_;
344d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    Label* saved_true = true_label_;
345d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    Label* saved_false = false_label_;
346d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    context_ = Expression::kTestValue;
347d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    location_ = where;
348d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    true_label_ = if_true;
349d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    false_label_ = if_false;
350d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    Visit(expr);
351d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    context_ = saved_context;
352d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    location_ = saved_location;
353d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    true_label_ = saved_true;
354d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    false_label_ = saved_false;
355d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  }
356d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
357d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  void VisitDeclarations(ZoneList<Declaration*>* declarations);
358d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  void DeclareGlobals(Handle<FixedArray> pairs);
359d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
360f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  // Platform-specific code for a variable, constant, or function
361f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  // declaration.  Functions have an initial value.
362f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  void EmitDeclaration(Variable* variable,
363f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke                       Variable::Mode mode,
364f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke                       FunctionLiteral* function);
365f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke
366d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // Platform-specific return sequence
367d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  void EmitReturnSequence(int position);
368d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
369d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // Platform-specific code sequences for calls
370d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  void EmitCallWithStub(Call* expr);
371d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  void EmitCallWithIC(Call* expr, Handle<Object> name, RelocInfo::Mode mode);
372d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
373f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke
374f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  // Platform-specific code for inline runtime calls.
375f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  void EmitInlineRuntimeCall(CallRuntime* expr);
376f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  void EmitIsSmi(ZoneList<Expression*>* arguments);
377f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  void EmitIsNonNegativeSmi(ZoneList<Expression*>* arguments);
378f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  void EmitIsObject(ZoneList<Expression*>* arguments);
379f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  void EmitIsUndetectableObject(ZoneList<Expression*>* arguments);
380f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  void EmitIsFunction(ZoneList<Expression*>* arguments);
381f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  void EmitIsArray(ZoneList<Expression*>* arguments);
382f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  void EmitIsRegExp(ZoneList<Expression*>* arguments);
383f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  void EmitIsConstructCall(ZoneList<Expression*>* arguments);
384f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  void EmitObjectEquals(ZoneList<Expression*>* arguments);
385f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  void EmitArguments(ZoneList<Expression*>* arguments);
386f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  void EmitArgumentsLength(ZoneList<Expression*>* arguments);
387f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  void EmitClassOf(ZoneList<Expression*>* arguments);
388f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  void EmitValueOf(ZoneList<Expression*>* arguments);
389f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  void EmitSetValueOf(ZoneList<Expression*>* arguments);
390f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  void EmitNumberToString(ZoneList<Expression*>* arguments);
391f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  void EmitCharFromCode(ZoneList<Expression*>* arguments);
392f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  void EmitFastCharCodeAt(ZoneList<Expression*>* arguments);
393f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  void EmitStringCompare(ZoneList<Expression*>* arguments);
394f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  void EmitStringAdd(ZoneList<Expression*>* arguments);
395f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  void EmitLog(ZoneList<Expression*>* arguments);
396f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  void EmitRandomHeapNumber(ZoneList<Expression*>* arguments);
397f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  void EmitSubString(ZoneList<Expression*>* arguments);
398f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  void EmitRegExpExec(ZoneList<Expression*>* arguments);
399f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  void EmitMathPow(ZoneList<Expression*>* arguments);
400f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  void EmitMathSin(ZoneList<Expression*>* arguments);
401f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  void EmitMathCos(ZoneList<Expression*>* arguments);
402f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  void EmitMathSqrt(ZoneList<Expression*>* arguments);
403f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  void EmitCallFunction(ZoneList<Expression*>* arguments);
404f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  void EmitRegExpConstructResult(ZoneList<Expression*>* arguments);
405f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  void EmitSwapElements(ZoneList<Expression*>* arguments);
406f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  void EmitGetFromCache(ZoneList<Expression*>* arguments);
407f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke
408d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // Platform-specific code for loading variables.
409d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  void EmitVariableLoad(Variable* expr, Expression::Context context);
410d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
411f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  // Platform-specific support for allocating a new closure based on
412f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  // the given function info.
413f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  void EmitNewClosure(Handle<SharedFunctionInfo> info);
414f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke
415d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // Platform-specific support for compiling assignments.
416d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
417d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // Load a value from a named property.
418d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // The receiver is left on the stack by the IC.
419d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  void EmitNamedPropertyLoad(Property* expr);
420d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
421d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // Load a value from a keyed property.
422d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // The receiver and the key is left on the stack by the IC.
423d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  void EmitKeyedPropertyLoad(Property* expr);
424d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
425d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // Apply the compound assignment operator. Expects the left operand on top
426d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // of the stack and the right one in the accumulator.
427d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  void EmitBinaryOp(Token::Value op, Expression::Context context);
428d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
429f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  // Assign to the given expression as if via '='. The right-hand-side value
430f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  // is expected in the accumulator.
431f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  void EmitAssignment(Expression* expr);
432f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke
433d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // Complete a variable assignment.  The right-hand-side value is expected
434d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // in the accumulator.
435f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  void EmitVariableAssignment(Variable* var,
436f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke                              Token::Value op,
437f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke                              Expression::Context context);
438d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
439d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // Complete a named property assignment.  The receiver is expected on top
440d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // of the stack and the right-hand-side value in the accumulator.
441d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  void EmitNamedPropertyAssignment(Assignment* expr);
442d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
443d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // Complete a keyed property assignment.  The receiver and key are
444d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // expected on top of the stack and the right-hand-side value in the
445d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // accumulator.
446d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  void EmitKeyedPropertyAssignment(Assignment* expr);
447d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
448f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  // Helper for compare operations. Expects the null-value in a register.
449f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  void EmitNullCompare(bool strict,
450f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke                       Register obj,
451f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke                       Register null_const,
452f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke                       Label* if_true,
453f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke                       Label* if_false,
454f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke                       Register scratch);
455f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke
456d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  void SetFunctionPosition(FunctionLiteral* fun);
457d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  void SetReturnPosition(FunctionLiteral* fun);
458d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  void SetStatementPosition(Statement* stmt);
459d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  void SetStatementPosition(int pos);
460d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  void SetSourcePosition(int pos);
461d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
462d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // Non-local control flow support.
463d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  void EnterFinallyBlock();
464d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  void ExitFinallyBlock();
465d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
466d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // Loop nesting counter.
467d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  int loop_depth() { return loop_depth_; }
468d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  void increment_loop_depth() { loop_depth_++; }
469d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  void decrement_loop_depth() {
470d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    ASSERT(loop_depth_ > 0);
471d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    loop_depth_--;
472d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  }
473d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
474d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  MacroAssembler* masm() { return masm_; }
4753100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
4763100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  Handle<Script> script() { return info_->script(); }
4773100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  bool is_eval() { return info_->is_eval(); }
4783100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  FunctionLiteral* function() { return info_->function(); }
4793100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  Scope* scope() { return info_->scope(); }
4803100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
481d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  static Register result_register();
482d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  static Register context_register();
483d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
484d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // Set fields in the stack frame. Offsets are the frame pointer relative
485d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // offsets defined in, e.g., StandardFrameConstants.
486d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  void StoreToFrameField(int frame_offset, Register value);
487d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
488d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // Load a value from the current context. Indices are defined as an enum
489d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // in v8::internal::Context.
490d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  void LoadContextField(Register dst, int context_index);
491d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
492d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // AST node visit functions.
493d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke#define DECLARE_VISIT(type) virtual void Visit##type(type* node);
494d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  AST_NODE_LIST(DECLARE_VISIT)
495d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke#undef DECLARE_VISIT
496d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // Handles the shortcutted logical binary operations in VisitBinaryOperation.
497d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  void EmitLogicalOperation(BinaryOperation* expr);
498d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
499d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  MacroAssembler* masm_;
5003100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  CompilationInfo* info_;
5014515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke
502d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  Label return_label_;
503d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  NestedStatement* nesting_stack_;
504d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  int loop_depth_;
505d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
506d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  Expression::Context context_;
507d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  Location location_;
508d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  Label* true_label_;
509d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  Label* false_label_;
510d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
511d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  friend class NestedStatement;
512d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
513d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  DISALLOW_COPY_AND_ASSIGN(FullCodeGenerator);
514d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke};
515d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
516d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
517d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} }  // namespace v8::internal
518d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
519d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke#endif  // V8_FULL_CODEGEN_H_
520