full-codegen.h revision e0cee9b3ed82e2391fd85d118aeaa4ea361c687d
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"
34b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#include "code-stubs.h"
35b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#include "codegen.h"
36f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke#include "compiler.h"
37d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
38d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkenamespace v8 {
39d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkenamespace internal {
40d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
41b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// Forward declarations.
42b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochclass JumpPatchSite;
43b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
447f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch// AST node visitor which can tell whether a given statement will be breakable
457f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch// when the code is compiled by the full compiler in the debugger. This means
467f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch// that there will be an IC (load/store/call) in the code generated for the
477f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch// debugger to piggybag on.
487f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochclass BreakableStatementChecker: public AstVisitor {
497f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch public:
507f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  BreakableStatementChecker() : is_breakable_(false) {}
517f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
527f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  void Check(Statement* stmt);
537f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  void Check(Expression* stmt);
547f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
557f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  bool is_breakable() { return is_breakable_; }
567f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
577f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch private:
587f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  // AST node visit functions.
597f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch#define DECLARE_VISIT(type) virtual void Visit##type(type* node);
607f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  AST_NODE_LIST(DECLARE_VISIT)
617f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch#undef DECLARE_VISIT
627f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
637f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  bool is_breakable_;
647f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
657f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  DISALLOW_COPY_AND_ASSIGN(BreakableStatementChecker);
667f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch};
677f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
687f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
69d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke// -----------------------------------------------------------------------------
70d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke// Full code generator.
71d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
72d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkeclass FullCodeGenerator: public AstVisitor {
73d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke public:
74b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  enum State {
75b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    NO_REGISTERS,
76b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    TOS_REG
77b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  };
78b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
793100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  explicit FullCodeGenerator(MacroAssembler* masm)
80d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke      : masm_(masm),
813100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu        info_(NULL),
82d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke        nesting_stack_(NULL),
83d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke        loop_depth_(0),
84b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch        context_(NULL),
85b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch        bailout_entries_(0),
86b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch        stack_checks_(2),  // There's always at least one.
87b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch        forward_bailout_stack_(NULL),
88b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch        forward_bailout_pending_(NULL) {
89d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  }
90d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
91f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch  static bool MakeCode(CompilationInfo* info);
92d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
93756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  void Generate(CompilationInfo* info);
94b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void PopulateDeoptimizationData(Handle<Code> code);
95b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
96b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  class StateField : public BitField<State, 0, 8> { };
97b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  class PcField    : public BitField<unsigned, 8, 32-8> { };
98b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
99b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  static const char* State2String(State state) {
100b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    switch (state) {
101b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      case NO_REGISTERS: return "NO_REGISTERS";
102b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      case TOS_REG: return "TOS_REG";
103b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    }
104b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    UNREACHABLE();
105b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    return NULL;
106b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
107d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
108d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke private:
109d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  class Breakable;
110d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  class Iteration;
111d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  class TryCatch;
112d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  class TryFinally;
113d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  class Finally;
114d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  class ForIn;
115d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
116d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  class NestedStatement BASE_EMBEDDED {
117d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke   public:
118d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    explicit NestedStatement(FullCodeGenerator* codegen) : codegen_(codegen) {
119d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke      // Link into codegen's nesting stack.
120d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke      previous_ = codegen->nesting_stack_;
121d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke      codegen->nesting_stack_ = this;
122d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    }
123d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    virtual ~NestedStatement() {
124d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke      // Unlink from codegen's nesting stack.
125d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke      ASSERT_EQ(this, codegen_->nesting_stack_);
126d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke      codegen_->nesting_stack_ = previous_;
127d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    }
128d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
129d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    virtual Breakable* AsBreakable() { return NULL; }
130d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    virtual Iteration* AsIteration() { return NULL; }
131d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    virtual TryCatch* AsTryCatch() { return NULL; }
132d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    virtual TryFinally* AsTryFinally() { return NULL; }
133d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    virtual Finally* AsFinally() { return NULL; }
134d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    virtual ForIn* AsForIn() { return NULL; }
135d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
136d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    virtual bool IsContinueTarget(Statement* target) { return false; }
137d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    virtual bool IsBreakTarget(Statement* target) { return false; }
138d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
139d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    // Generate code to leave the nested statement. This includes
140d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    // cleaning up any stack elements in use and restoring the
141d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    // stack to the expectations of the surrounding statements.
142d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    // Takes a number of stack elements currently on top of the
143d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    // nested statement's stack, and returns a number of stack
144d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    // elements left on top of the surrounding statement's stack.
145d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    // The generated code must preserve the result register (which
146d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    // contains the value in case of a return).
147d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    virtual int Exit(int stack_depth) {
148d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke      // Default implementation for the case where there is
149d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke      // nothing to clean up.
150d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke      return stack_depth;
151d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    }
152d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    NestedStatement* outer() { return previous_; }
153d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke   protected:
154d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    MacroAssembler* masm() { return codegen_->masm(); }
155d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke   private:
156d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    FullCodeGenerator* codegen_;
157d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    NestedStatement* previous_;
158d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    DISALLOW_COPY_AND_ASSIGN(NestedStatement);
159d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  };
160d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
161d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  class Breakable : public NestedStatement {
162d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke   public:
163d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    Breakable(FullCodeGenerator* codegen,
164d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke              BreakableStatement* break_target)
165d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke        : NestedStatement(codegen),
166d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke          target_(break_target) {}
167d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    virtual ~Breakable() {}
168d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    virtual Breakable* AsBreakable() { return this; }
169d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    virtual bool IsBreakTarget(Statement* statement) {
170d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke      return target_ == statement;
171d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    }
172d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    BreakableStatement* statement() { return target_; }
173d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    Label* break_target() { return &break_target_label_; }
174d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke   private:
175d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    BreakableStatement* target_;
176d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    Label break_target_label_;
177d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    DISALLOW_COPY_AND_ASSIGN(Breakable);
178d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  };
179d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
180d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  class Iteration : public Breakable {
181d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke   public:
182d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    Iteration(FullCodeGenerator* codegen,
183d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke              IterationStatement* iteration_statement)
184d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke        : Breakable(codegen, iteration_statement) {}
185d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    virtual ~Iteration() {}
186d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    virtual Iteration* AsIteration() { return this; }
187d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    virtual bool IsContinueTarget(Statement* statement) {
188d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke      return this->statement() == statement;
189d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    }
190d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    Label* continue_target() { return &continue_target_label_; }
191d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke   private:
192d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    Label continue_target_label_;
193d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    DISALLOW_COPY_AND_ASSIGN(Iteration);
194d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  };
195d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
196d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // The environment inside the try block of a try/catch statement.
197d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  class TryCatch : public NestedStatement {
198d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke   public:
199d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    explicit TryCatch(FullCodeGenerator* codegen, Label* catch_entry)
200d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke        : NestedStatement(codegen), catch_entry_(catch_entry) { }
201d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    virtual ~TryCatch() {}
202d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    virtual TryCatch* AsTryCatch() { return this; }
203d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    Label* catch_entry() { return catch_entry_; }
204d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    virtual int Exit(int stack_depth);
205d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke   private:
206d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    Label* catch_entry_;
207d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    DISALLOW_COPY_AND_ASSIGN(TryCatch);
208d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  };
209d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
210d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // The environment inside the try block of a try/finally statement.
211d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  class TryFinally : public NestedStatement {
212d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke   public:
213d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    explicit TryFinally(FullCodeGenerator* codegen, Label* finally_entry)
214d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke        : NestedStatement(codegen), finally_entry_(finally_entry) { }
215d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    virtual ~TryFinally() {}
216d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    virtual TryFinally* AsTryFinally() { return this; }
217d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    Label* finally_entry() { return finally_entry_; }
218d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    virtual int Exit(int stack_depth);
219d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke   private:
220d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    Label* finally_entry_;
221d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    DISALLOW_COPY_AND_ASSIGN(TryFinally);
222d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  };
223d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
224d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // A FinallyEnvironment represents being inside a finally block.
225d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // Abnormal termination of the finally block needs to clean up
226d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // the block's parameters from the stack.
227d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  class Finally : public NestedStatement {
228d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke   public:
229d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    explicit Finally(FullCodeGenerator* codegen) : NestedStatement(codegen) { }
230d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    virtual ~Finally() {}
231d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    virtual Finally* AsFinally() { return this; }
232d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    virtual int Exit(int stack_depth) {
233d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke      return stack_depth + kFinallyStackElementCount;
234d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    }
235d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke   private:
236d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    // Number of extra stack slots occupied during a finally block.
237d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    static const int kFinallyStackElementCount = 2;
238d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    DISALLOW_COPY_AND_ASSIGN(Finally);
239d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  };
240d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
241d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // A ForInEnvironment represents being inside a for-in loop.
242d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // Abnormal termination of the for-in block needs to clean up
243d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // the block's temporary storage from the stack.
244d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  class ForIn : public Iteration {
245d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke   public:
246d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    ForIn(FullCodeGenerator* codegen,
247d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke          ForInStatement* statement)
248d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke        : Iteration(codegen, statement) { }
249d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    virtual ~ForIn() {}
250d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    virtual ForIn* AsForIn() { return this; }
251d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    virtual int Exit(int stack_depth) {
252d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke      return stack_depth + kForInStackElementCount;
253d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    }
254d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke   private:
255d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    static const int kForInStackElementCount = 5;
256d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    DISALLOW_COPY_AND_ASSIGN(ForIn);
257d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  };
258d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
259b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // The forward bailout stack keeps track of the expressions that can
260b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // bail out to just before the control flow is split in a child
261b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // node. The stack elements are linked together through the parent
262b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // link when visiting expressions in test contexts after requesting
263b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // bailout in child forwarding.
264b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  class ForwardBailoutStack BASE_EMBEDDED {
265b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch   public:
266b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    ForwardBailoutStack(Expression* expr, ForwardBailoutStack* parent)
267b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch        : expr_(expr), parent_(parent) { }
268b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
269b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    Expression* expr() const { return expr_; }
270b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    ForwardBailoutStack* parent() const { return parent_; }
271b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
272b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch   private:
273b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    Expression* const expr_;
274b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    ForwardBailoutStack* const parent_;
275b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  };
276b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2770d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  // Type of a member function that generates inline code for a native function.
2780d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  typedef void (FullCodeGenerator::*InlineFunctionGenerator)
2790d5e116f6aee03185f237311a943491bb079a768Kristian Monsen      (ZoneList<Expression*>*);
2800d5e116f6aee03185f237311a943491bb079a768Kristian Monsen
2810d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  static const InlineFunctionGenerator kInlineFunctionGenerators[];
2820d5e116f6aee03185f237311a943491bb079a768Kristian Monsen
283db5a90a88cfcddb042912799e872037c6548b8a3Ben Murdoch  // A platform-specific utility to overwrite the accumulator register
284db5a90a88cfcddb042912799e872037c6548b8a3Ben Murdoch  // with a GC-safe value.
285db5a90a88cfcddb042912799e872037c6548b8a3Ben Murdoch  void ClearAccumulator();
286db5a90a88cfcddb042912799e872037c6548b8a3Ben Murdoch
28780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  // Compute the frame pointer relative offset for a given local or
28880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  // parameter slot.
289d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  int SlotOffset(Slot* slot);
290d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
29180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  // Determine whether or not to inline the smi case for the given
29280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  // operation.
29380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  bool ShouldInlineSmiCase(Token::Value op);
29480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen
295d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // Helper function to convert a pure value into a test context.  The value
296d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // is expected on the stack or the accumulator, depending on the platform.
297d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // See the platform-specific implementation for details.
29880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  void DoTest(Label* if_true, Label* if_false, Label* fall_through);
29980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen
30080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  // Helper function to split control flow and avoid a branch to the
30180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  // fall-through label if it is set up.
30280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  void Split(Condition cc,
30380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen             Label* if_true,
30480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen             Label* if_false,
30580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen             Label* fall_through);
306d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
307d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  void Move(Slot* dst, Register source, Register scratch1, Register scratch2);
308d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  void Move(Register dst, Slot* source);
309d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
310d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // Return an operand used to read/write to a known (ie, non-LOOKUP) slot.
311d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // May emit code to traverse the context chain, destroying the scratch
312d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // register.
313d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  MemOperand EmitSlotSearch(Slot* slot, Register scratch);
314d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
315b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Forward the bailout responsibility for the given expression to
316b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // the next child visited (which must be in a test context).
317b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void ForwardBailoutToChild(Expression* expr);
318b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
319d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  void VisitForEffect(Expression* expr) {
3200d5e116f6aee03185f237311a943491bb079a768Kristian Monsen    EffectContext context(this);
321b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    HandleInNonTestContext(expr, NO_REGISTERS);
3220d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  }
3230d5e116f6aee03185f237311a943491bb079a768Kristian Monsen
3240d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  void VisitForAccumulatorValue(Expression* expr) {
3250d5e116f6aee03185f237311a943491bb079a768Kristian Monsen    AccumulatorValueContext context(this);
326b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    HandleInNonTestContext(expr, TOS_REG);
327d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  }
328d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
3290d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  void VisitForStackValue(Expression* expr) {
3300d5e116f6aee03185f237311a943491bb079a768Kristian Monsen    StackValueContext context(this);
331b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    HandleInNonTestContext(expr, NO_REGISTERS);
332d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  }
333d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
33480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  void VisitForControl(Expression* expr,
33580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen                       Label* if_true,
33680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen                       Label* if_false,
33780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen                       Label* fall_through) {
3380d5e116f6aee03185f237311a943491bb079a768Kristian Monsen    TestContext context(this, if_true, if_false, fall_through);
339b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    VisitInTestContext(expr);
340b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    // Forwarding bailouts to children is a one shot operation. It
341b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    // should have been processed at this point.
342b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    ASSERT(forward_bailout_pending_ == NULL);
343d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  }
344d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
345b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void HandleInNonTestContext(Expression* expr, State state);
346b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void VisitInTestContext(Expression* expr);
347b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
348d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  void VisitDeclarations(ZoneList<Declaration*>* declarations);
349d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  void DeclareGlobals(Handle<FixedArray> pairs);
350d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
35180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  // Try to perform a comparison as a fast inlined literal compare if
35280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  // the operands allow it.  Returns true if the compare operations
35380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  // has been matched and all code generated; false otherwise.
35480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  bool TryLiteralCompare(Token::Value op,
35580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen                         Expression* left,
35680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen                         Expression* right,
35780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen                         Label* if_true,
35880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen                         Label* if_false,
35980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen                         Label* fall_through);
36080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen
361b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Bailout support.
362b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void PrepareForBailout(AstNode* node, State state);
363b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void PrepareForBailoutForId(int id, State state);
364b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
365b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Record a call's return site offset, used to rebuild the frame if the
366b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // called function was inlined at the site.
367b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void RecordJSReturnSite(Call* call);
368b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
369b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Prepare for bailout before a test (or compare) and branch.  If
370b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // should_normalize, then the following comparison will not handle the
371b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // canonical JS true value so we will insert a (dead) test against true at
372b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // the actual bailout target from the optimized code. If not
373b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // should_normalize, the true and false labels are ignored.
374b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void PrepareForBailoutBeforeSplit(State state,
375b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch                                    bool should_normalize,
376b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch                                    Label* if_true,
377b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch                                    Label* if_false);
378b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
379f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  // Platform-specific code for a variable, constant, or function
380f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  // declaration.  Functions have an initial value.
381f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  void EmitDeclaration(Variable* variable,
382f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke                       Variable::Mode mode,
383f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke                       FunctionLiteral* function);
384f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke
385b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Platform-specific code for checking the stack limit at the back edge of
386b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // a loop.
387b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void EmitStackCheck(IterationStatement* stmt);
388b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Record the OSR AST id corresponding to a stack check in the code.
389b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void RecordStackCheck(int osr_ast_id);
390b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Emit a table of stack check ids and pcs into the code stream.  Return
391b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // the offset of the start of the table.
392b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  unsigned EmitStackCheckTable();
393b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
394d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // Platform-specific return sequence
3957f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  void EmitReturnSequence();
396d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
397d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // Platform-specific code sequences for calls
398d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  void EmitCallWithStub(Call* expr);
399d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  void EmitCallWithIC(Call* expr, Handle<Object> name, RelocInfo::Mode mode);
4007f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  void EmitKeyedCallWithIC(Call* expr, Expression* key, RelocInfo::Mode mode);
401d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
402f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  // Platform-specific code for inline runtime calls.
4030d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  InlineFunctionGenerator FindInlineFunctionGenerator(Runtime::FunctionId id);
4040d5e116f6aee03185f237311a943491bb079a768Kristian Monsen
405f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  void EmitInlineRuntimeCall(CallRuntime* expr);
406791712a13f1814dd3ab5d1a5ab8ff5dbc476f6d6Steve Block
407791712a13f1814dd3ab5d1a5ab8ff5dbc476f6d6Steve Block#define EMIT_INLINE_RUNTIME_CALL(name, x, y) \
408791712a13f1814dd3ab5d1a5ab8ff5dbc476f6d6Steve Block  void Emit##name(ZoneList<Expression*>* arguments);
4090d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  INLINE_FUNCTION_LIST(EMIT_INLINE_RUNTIME_CALL)
410791712a13f1814dd3ab5d1a5ab8ff5dbc476f6d6Steve Block  INLINE_RUNTIME_FUNCTION_LIST(EMIT_INLINE_RUNTIME_CALL)
411791712a13f1814dd3ab5d1a5ab8ff5dbc476f6d6Steve Block#undef EMIT_INLINE_RUNTIME_CALL
412f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke
413d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // Platform-specific code for loading variables.
41459151504615d929945dc59db37bf1166937748c6Steve Block  void EmitLoadGlobalSlotCheckExtensions(Slot* slot,
41559151504615d929945dc59db37bf1166937748c6Steve Block                                         TypeofState typeof_state,
41659151504615d929945dc59db37bf1166937748c6Steve Block                                         Label* slow);
41759151504615d929945dc59db37bf1166937748c6Steve Block  MemOperand ContextSlotOperandCheckExtensions(Slot* slot, Label* slow);
41859151504615d929945dc59db37bf1166937748c6Steve Block  void EmitDynamicLoadFromSlotFastCase(Slot* slot,
41959151504615d929945dc59db37bf1166937748c6Steve Block                                       TypeofState typeof_state,
42059151504615d929945dc59db37bf1166937748c6Steve Block                                       Label* slow,
42159151504615d929945dc59db37bf1166937748c6Steve Block                                       Label* done);
4220d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  void EmitVariableLoad(Variable* expr);
423d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
424e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  enum ResolveEvalFlag {
425e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch    SKIP_CONTEXT_LOOKUP,
426e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch    PERFORM_CONTEXT_LOOKUP
427e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  };
428e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
429e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  // Expects the arguments and the function already pushed.
430e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  void EmitResolvePossiblyDirectEval(ResolveEvalFlag flag, int arg_count);
431e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
432f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  // Platform-specific support for allocating a new closure based on
433f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  // the given function info.
4348a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  void EmitNewClosure(Handle<SharedFunctionInfo> info, bool pretenure);
435f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke
436d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // Platform-specific support for compiling assignments.
437d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
438d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // Load a value from a named property.
439d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // The receiver is left on the stack by the IC.
440d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  void EmitNamedPropertyLoad(Property* expr);
441d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
442d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // Load a value from a keyed property.
443d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // The receiver and the key is left on the stack by the IC.
444d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  void EmitKeyedPropertyLoad(Property* expr);
445d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
446d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // Apply the compound assignment operator. Expects the left operand on top
447d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // of the stack and the right one in the accumulator.
44880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  void EmitBinaryOp(Token::Value op,
44980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen                    OverwriteMode mode);
45080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen
45180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  // Helper functions for generating inlined smi code for certain
45280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  // binary operations.
45380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  void EmitInlineSmiBinaryOp(Expression* expr,
45480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen                             Token::Value op,
45580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen                             OverwriteMode mode,
45680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen                             Expression* left,
457e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch                             Expression* right);
458d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
459f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  // Assign to the given expression as if via '='. The right-hand-side value
460f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  // is expected in the accumulator.
461b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void EmitAssignment(Expression* expr, int bailout_ast_id);
462f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke
463d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // Complete a variable assignment.  The right-hand-side value is expected
464d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // in the accumulator.
465f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  void EmitVariableAssignment(Variable* var,
4660d5e116f6aee03185f237311a943491bb079a768Kristian Monsen                              Token::Value op);
467d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
468d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // Complete a named property assignment.  The receiver is expected on top
469d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // of the stack and the right-hand-side value in the accumulator.
470d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  void EmitNamedPropertyAssignment(Assignment* expr);
471d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
472d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // Complete a keyed property assignment.  The receiver and key are
473d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // expected on top of the stack and the right-hand-side value in the
474d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // accumulator.
475d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  void EmitKeyedPropertyAssignment(Assignment* expr);
476d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
477d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  void SetFunctionPosition(FunctionLiteral* fun);
478d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  void SetReturnPosition(FunctionLiteral* fun);
479d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  void SetStatementPosition(Statement* stmt);
4807f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  void SetExpressionPosition(Expression* expr, int pos);
481d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  void SetStatementPosition(int pos);
482b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void SetSourcePosition(int pos);
483d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
484d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // Non-local control flow support.
485d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  void EnterFinallyBlock();
486d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  void ExitFinallyBlock();
487d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
488d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // Loop nesting counter.
489d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  int loop_depth() { return loop_depth_; }
490d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  void increment_loop_depth() { loop_depth_++; }
491d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  void decrement_loop_depth() {
492d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    ASSERT(loop_depth_ > 0);
493d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    loop_depth_--;
494d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  }
495d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
496d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  MacroAssembler* masm() { return masm_; }
4973100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
4980d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  class ExpressionContext;
4990d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  const ExpressionContext* context() { return context_; }
5000d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  void set_new_context(const ExpressionContext* context) { context_ = context; }
5010d5e116f6aee03185f237311a943491bb079a768Kristian Monsen
5023100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  Handle<Script> script() { return info_->script(); }
5033100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  bool is_eval() { return info_->is_eval(); }
5041e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  bool is_strict() { return function()->strict_mode(); }
5051e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  StrictModeFlag strict_mode_flag() {
5061e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    return is_strict() ? kStrictMode : kNonStrictMode;
5071e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  }
5083100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  FunctionLiteral* function() { return info_->function(); }
5093100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  Scope* scope() { return info_->scope(); }
5103100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
511d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  static Register result_register();
512d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  static Register context_register();
513d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
5140d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  // Helper for calling an IC stub.
5150d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  void EmitCallIC(Handle<Code> ic, RelocInfo::Mode mode);
5160d5e116f6aee03185f237311a943491bb079a768Kristian Monsen
517b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Calling an IC stub with a patch site. Passing NULL for patch_site
5181e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  // or non NULL patch_site which is not activated indicates no inlined smi code
5191e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  // and emits a nop after the IC call.
520b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void EmitCallIC(Handle<Code> ic, JumpPatchSite* patch_site);
521b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
522d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // Set fields in the stack frame. Offsets are the frame pointer relative
523d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // offsets defined in, e.g., StandardFrameConstants.
524d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  void StoreToFrameField(int frame_offset, Register value);
525d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
526d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // Load a value from the current context. Indices are defined as an enum
527d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // in v8::internal::Context.
528d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  void LoadContextField(Register dst, int context_index);
529d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
530d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // AST node visit functions.
531d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke#define DECLARE_VISIT(type) virtual void Visit##type(type* node);
532d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  AST_NODE_LIST(DECLARE_VISIT)
533d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke#undef DECLARE_VISIT
534d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // Handles the shortcutted logical binary operations in VisitBinaryOperation.
535d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  void EmitLogicalOperation(BinaryOperation* expr);
536d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
5370d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  void VisitForTypeofValue(Expression* expr);
53880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen
539b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  struct BailoutEntry {
540b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    unsigned id;
541b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    unsigned pc_and_state;
542b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  };
5434515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke
544d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
545b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  class ExpressionContext BASE_EMBEDDED {
5460d5e116f6aee03185f237311a943491bb079a768Kristian Monsen   public:
5470d5e116f6aee03185f237311a943491bb079a768Kristian Monsen    explicit ExpressionContext(FullCodeGenerator* codegen)
5480d5e116f6aee03185f237311a943491bb079a768Kristian Monsen        : masm_(codegen->masm()), old_(codegen->context()), codegen_(codegen) {
5490d5e116f6aee03185f237311a943491bb079a768Kristian Monsen      codegen->set_new_context(this);
5500d5e116f6aee03185f237311a943491bb079a768Kristian Monsen    }
5510d5e116f6aee03185f237311a943491bb079a768Kristian Monsen
5520d5e116f6aee03185f237311a943491bb079a768Kristian Monsen    virtual ~ExpressionContext() {
5530d5e116f6aee03185f237311a943491bb079a768Kristian Monsen      codegen_->set_new_context(old_);
5540d5e116f6aee03185f237311a943491bb079a768Kristian Monsen    }
5550d5e116f6aee03185f237311a943491bb079a768Kristian Monsen
5560d5e116f6aee03185f237311a943491bb079a768Kristian Monsen    // Convert constant control flow (true or false) to the result expected for
5570d5e116f6aee03185f237311a943491bb079a768Kristian Monsen    // this expression context.
5580d5e116f6aee03185f237311a943491bb079a768Kristian Monsen    virtual void Plug(bool flag) const = 0;
5590d5e116f6aee03185f237311a943491bb079a768Kristian Monsen
5600d5e116f6aee03185f237311a943491bb079a768Kristian Monsen    // Emit code to convert a pure value (in a register, slot, as a literal,
5610d5e116f6aee03185f237311a943491bb079a768Kristian Monsen    // or on top of the stack) into the result expected according to this
5620d5e116f6aee03185f237311a943491bb079a768Kristian Monsen    // expression context.
5630d5e116f6aee03185f237311a943491bb079a768Kristian Monsen    virtual void Plug(Register reg) const = 0;
5640d5e116f6aee03185f237311a943491bb079a768Kristian Monsen    virtual void Plug(Slot* slot) const = 0;
5650d5e116f6aee03185f237311a943491bb079a768Kristian Monsen    virtual void Plug(Handle<Object> lit) const = 0;
5660d5e116f6aee03185f237311a943491bb079a768Kristian Monsen    virtual void Plug(Heap::RootListIndex index) const = 0;
5670d5e116f6aee03185f237311a943491bb079a768Kristian Monsen    virtual void PlugTOS() const = 0;
5680d5e116f6aee03185f237311a943491bb079a768Kristian Monsen
5690d5e116f6aee03185f237311a943491bb079a768Kristian Monsen    // Emit code to convert pure control flow to a pair of unbound labels into
5700d5e116f6aee03185f237311a943491bb079a768Kristian Monsen    // the result expected according to this expression context.  The
571b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    // implementation will bind both labels unless it's a TestContext, which
572b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    // won't bind them at this point.
5730d5e116f6aee03185f237311a943491bb079a768Kristian Monsen    virtual void Plug(Label* materialize_true,
5740d5e116f6aee03185f237311a943491bb079a768Kristian Monsen                      Label* materialize_false) const = 0;
5750d5e116f6aee03185f237311a943491bb079a768Kristian Monsen
5760d5e116f6aee03185f237311a943491bb079a768Kristian Monsen    // Emit code to discard count elements from the top of stack, then convert
5770d5e116f6aee03185f237311a943491bb079a768Kristian Monsen    // a pure value into the result expected according to this expression
5780d5e116f6aee03185f237311a943491bb079a768Kristian Monsen    // context.
5790d5e116f6aee03185f237311a943491bb079a768Kristian Monsen    virtual void DropAndPlug(int count, Register reg) const = 0;
5800d5e116f6aee03185f237311a943491bb079a768Kristian Monsen
5810d5e116f6aee03185f237311a943491bb079a768Kristian Monsen    // For shortcutting operations || and &&.
5820d5e116f6aee03185f237311a943491bb079a768Kristian Monsen    virtual void EmitLogicalLeft(BinaryOperation* expr,
5830d5e116f6aee03185f237311a943491bb079a768Kristian Monsen                                 Label* eval_right,
5840d5e116f6aee03185f237311a943491bb079a768Kristian Monsen                                 Label* done) const = 0;
5850d5e116f6aee03185f237311a943491bb079a768Kristian Monsen
5860d5e116f6aee03185f237311a943491bb079a768Kristian Monsen    // Set up branch labels for a test expression.  The three Label** parameters
5870d5e116f6aee03185f237311a943491bb079a768Kristian Monsen    // are output parameters.
5880d5e116f6aee03185f237311a943491bb079a768Kristian Monsen    virtual void PrepareTest(Label* materialize_true,
5890d5e116f6aee03185f237311a943491bb079a768Kristian Monsen                             Label* materialize_false,
5900d5e116f6aee03185f237311a943491bb079a768Kristian Monsen                             Label** if_true,
5910d5e116f6aee03185f237311a943491bb079a768Kristian Monsen                             Label** if_false,
5920d5e116f6aee03185f237311a943491bb079a768Kristian Monsen                             Label** fall_through) const = 0;
5930d5e116f6aee03185f237311a943491bb079a768Kristian Monsen
594b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    virtual void HandleExpression(Expression* expr) const = 0;
595b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
5960d5e116f6aee03185f237311a943491bb079a768Kristian Monsen    // Returns true if we are evaluating only for side effects (ie if the result
597b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    // will be discarded).
5980d5e116f6aee03185f237311a943491bb079a768Kristian Monsen    virtual bool IsEffect() const { return false; }
5990d5e116f6aee03185f237311a943491bb079a768Kristian Monsen
6000d5e116f6aee03185f237311a943491bb079a768Kristian Monsen    // Returns true if we are branching on the value rather than materializing
601b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    // it.  Only used for asserts.
6020d5e116f6aee03185f237311a943491bb079a768Kristian Monsen    virtual bool IsTest() const { return false; }
6030d5e116f6aee03185f237311a943491bb079a768Kristian Monsen
6040d5e116f6aee03185f237311a943491bb079a768Kristian Monsen   protected:
6050d5e116f6aee03185f237311a943491bb079a768Kristian Monsen    FullCodeGenerator* codegen() const { return codegen_; }
6060d5e116f6aee03185f237311a943491bb079a768Kristian Monsen    MacroAssembler* masm() const { return masm_; }
6070d5e116f6aee03185f237311a943491bb079a768Kristian Monsen    MacroAssembler* masm_;
6080d5e116f6aee03185f237311a943491bb079a768Kristian Monsen
6090d5e116f6aee03185f237311a943491bb079a768Kristian Monsen   private:
6100d5e116f6aee03185f237311a943491bb079a768Kristian Monsen    const ExpressionContext* old_;
6110d5e116f6aee03185f237311a943491bb079a768Kristian Monsen    FullCodeGenerator* codegen_;
6120d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  };
6130d5e116f6aee03185f237311a943491bb079a768Kristian Monsen
6140d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  class AccumulatorValueContext : public ExpressionContext {
6150d5e116f6aee03185f237311a943491bb079a768Kristian Monsen   public:
6160d5e116f6aee03185f237311a943491bb079a768Kristian Monsen    explicit AccumulatorValueContext(FullCodeGenerator* codegen)
6170d5e116f6aee03185f237311a943491bb079a768Kristian Monsen        : ExpressionContext(codegen) { }
6180d5e116f6aee03185f237311a943491bb079a768Kristian Monsen
6190d5e116f6aee03185f237311a943491bb079a768Kristian Monsen    virtual void Plug(bool flag) const;
6200d5e116f6aee03185f237311a943491bb079a768Kristian Monsen    virtual void Plug(Register reg) const;
6210d5e116f6aee03185f237311a943491bb079a768Kristian Monsen    virtual void Plug(Label* materialize_true, Label* materialize_false) const;
6220d5e116f6aee03185f237311a943491bb079a768Kristian Monsen    virtual void Plug(Slot* slot) const;
6230d5e116f6aee03185f237311a943491bb079a768Kristian Monsen    virtual void Plug(Handle<Object> lit) const;
6240d5e116f6aee03185f237311a943491bb079a768Kristian Monsen    virtual void Plug(Heap::RootListIndex) const;
6250d5e116f6aee03185f237311a943491bb079a768Kristian Monsen    virtual void PlugTOS() const;
6260d5e116f6aee03185f237311a943491bb079a768Kristian Monsen    virtual void DropAndPlug(int count, Register reg) const;
6270d5e116f6aee03185f237311a943491bb079a768Kristian Monsen    virtual void EmitLogicalLeft(BinaryOperation* expr,
6280d5e116f6aee03185f237311a943491bb079a768Kristian Monsen                                 Label* eval_right,
6290d5e116f6aee03185f237311a943491bb079a768Kristian Monsen                                 Label* done) const;
6300d5e116f6aee03185f237311a943491bb079a768Kristian Monsen    virtual void PrepareTest(Label* materialize_true,
6310d5e116f6aee03185f237311a943491bb079a768Kristian Monsen                             Label* materialize_false,
6320d5e116f6aee03185f237311a943491bb079a768Kristian Monsen                             Label** if_true,
6330d5e116f6aee03185f237311a943491bb079a768Kristian Monsen                             Label** if_false,
6340d5e116f6aee03185f237311a943491bb079a768Kristian Monsen                             Label** fall_through) const;
635b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    virtual void HandleExpression(Expression* expr) const;
6360d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  };
6370d5e116f6aee03185f237311a943491bb079a768Kristian Monsen
6380d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  class StackValueContext : public ExpressionContext {
6390d5e116f6aee03185f237311a943491bb079a768Kristian Monsen   public:
6400d5e116f6aee03185f237311a943491bb079a768Kristian Monsen    explicit StackValueContext(FullCodeGenerator* codegen)
6410d5e116f6aee03185f237311a943491bb079a768Kristian Monsen        : ExpressionContext(codegen) { }
6420d5e116f6aee03185f237311a943491bb079a768Kristian Monsen
6430d5e116f6aee03185f237311a943491bb079a768Kristian Monsen    virtual void Plug(bool flag) const;
6440d5e116f6aee03185f237311a943491bb079a768Kristian Monsen    virtual void Plug(Register reg) const;
6450d5e116f6aee03185f237311a943491bb079a768Kristian Monsen    virtual void Plug(Label* materialize_true, Label* materialize_false) const;
6460d5e116f6aee03185f237311a943491bb079a768Kristian Monsen    virtual void Plug(Slot* slot) const;
6470d5e116f6aee03185f237311a943491bb079a768Kristian Monsen    virtual void Plug(Handle<Object> lit) const;
6480d5e116f6aee03185f237311a943491bb079a768Kristian Monsen    virtual void Plug(Heap::RootListIndex) const;
6490d5e116f6aee03185f237311a943491bb079a768Kristian Monsen    virtual void PlugTOS() const;
6500d5e116f6aee03185f237311a943491bb079a768Kristian Monsen    virtual void DropAndPlug(int count, Register reg) const;
6510d5e116f6aee03185f237311a943491bb079a768Kristian Monsen    virtual void EmitLogicalLeft(BinaryOperation* expr,
6520d5e116f6aee03185f237311a943491bb079a768Kristian Monsen                                 Label* eval_right,
6530d5e116f6aee03185f237311a943491bb079a768Kristian Monsen                                 Label* done) const;
6540d5e116f6aee03185f237311a943491bb079a768Kristian Monsen    virtual void PrepareTest(Label* materialize_true,
6550d5e116f6aee03185f237311a943491bb079a768Kristian Monsen                             Label* materialize_false,
6560d5e116f6aee03185f237311a943491bb079a768Kristian Monsen                             Label** if_true,
6570d5e116f6aee03185f237311a943491bb079a768Kristian Monsen                             Label** if_false,
6580d5e116f6aee03185f237311a943491bb079a768Kristian Monsen                             Label** fall_through) const;
659b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    virtual void HandleExpression(Expression* expr) const;
6600d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  };
6610d5e116f6aee03185f237311a943491bb079a768Kristian Monsen
6620d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  class TestContext : public ExpressionContext {
6630d5e116f6aee03185f237311a943491bb079a768Kristian Monsen   public:
6640d5e116f6aee03185f237311a943491bb079a768Kristian Monsen    explicit TestContext(FullCodeGenerator* codegen,
6650d5e116f6aee03185f237311a943491bb079a768Kristian Monsen                         Label* true_label,
6660d5e116f6aee03185f237311a943491bb079a768Kristian Monsen                         Label* false_label,
6670d5e116f6aee03185f237311a943491bb079a768Kristian Monsen                         Label* fall_through)
6680d5e116f6aee03185f237311a943491bb079a768Kristian Monsen        : ExpressionContext(codegen),
6690d5e116f6aee03185f237311a943491bb079a768Kristian Monsen          true_label_(true_label),
6700d5e116f6aee03185f237311a943491bb079a768Kristian Monsen          false_label_(false_label),
6710d5e116f6aee03185f237311a943491bb079a768Kristian Monsen          fall_through_(fall_through) { }
6720d5e116f6aee03185f237311a943491bb079a768Kristian Monsen
673f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch    static const TestContext* cast(const ExpressionContext* context) {
674f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch      ASSERT(context->IsTest());
675f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch      return reinterpret_cast<const TestContext*>(context);
676f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch    }
677f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch
678f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch    Label* true_label() const { return true_label_; }
679f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch    Label* false_label() const { return false_label_; }
680f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch    Label* fall_through() const { return fall_through_; }
681f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch
6820d5e116f6aee03185f237311a943491bb079a768Kristian Monsen    virtual void Plug(bool flag) const;
6830d5e116f6aee03185f237311a943491bb079a768Kristian Monsen    virtual void Plug(Register reg) const;
6840d5e116f6aee03185f237311a943491bb079a768Kristian Monsen    virtual void Plug(Label* materialize_true, Label* materialize_false) const;
6850d5e116f6aee03185f237311a943491bb079a768Kristian Monsen    virtual void Plug(Slot* slot) const;
6860d5e116f6aee03185f237311a943491bb079a768Kristian Monsen    virtual void Plug(Handle<Object> lit) const;
6870d5e116f6aee03185f237311a943491bb079a768Kristian Monsen    virtual void Plug(Heap::RootListIndex) const;
6880d5e116f6aee03185f237311a943491bb079a768Kristian Monsen    virtual void PlugTOS() const;
6890d5e116f6aee03185f237311a943491bb079a768Kristian Monsen    virtual void DropAndPlug(int count, Register reg) const;
6900d5e116f6aee03185f237311a943491bb079a768Kristian Monsen    virtual void EmitLogicalLeft(BinaryOperation* expr,
6910d5e116f6aee03185f237311a943491bb079a768Kristian Monsen                                 Label* eval_right,
6920d5e116f6aee03185f237311a943491bb079a768Kristian Monsen                                 Label* done) const;
6930d5e116f6aee03185f237311a943491bb079a768Kristian Monsen    virtual void PrepareTest(Label* materialize_true,
6940d5e116f6aee03185f237311a943491bb079a768Kristian Monsen                             Label* materialize_false,
6950d5e116f6aee03185f237311a943491bb079a768Kristian Monsen                             Label** if_true,
6960d5e116f6aee03185f237311a943491bb079a768Kristian Monsen                             Label** if_false,
6970d5e116f6aee03185f237311a943491bb079a768Kristian Monsen                             Label** fall_through) const;
698b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    virtual void HandleExpression(Expression* expr) const;
6990d5e116f6aee03185f237311a943491bb079a768Kristian Monsen    virtual bool IsTest() const { return true; }
7000d5e116f6aee03185f237311a943491bb079a768Kristian Monsen
7010d5e116f6aee03185f237311a943491bb079a768Kristian Monsen   private:
7020d5e116f6aee03185f237311a943491bb079a768Kristian Monsen    Label* true_label_;
7030d5e116f6aee03185f237311a943491bb079a768Kristian Monsen    Label* false_label_;
7040d5e116f6aee03185f237311a943491bb079a768Kristian Monsen    Label* fall_through_;
7050d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  };
7060d5e116f6aee03185f237311a943491bb079a768Kristian Monsen
7070d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  class EffectContext : public ExpressionContext {
7080d5e116f6aee03185f237311a943491bb079a768Kristian Monsen   public:
7090d5e116f6aee03185f237311a943491bb079a768Kristian Monsen    explicit EffectContext(FullCodeGenerator* codegen)
7100d5e116f6aee03185f237311a943491bb079a768Kristian Monsen        : ExpressionContext(codegen) { }
7110d5e116f6aee03185f237311a943491bb079a768Kristian Monsen
7120d5e116f6aee03185f237311a943491bb079a768Kristian Monsen    virtual void Plug(bool flag) const;
7130d5e116f6aee03185f237311a943491bb079a768Kristian Monsen    virtual void Plug(Register reg) const;
7140d5e116f6aee03185f237311a943491bb079a768Kristian Monsen    virtual void Plug(Label* materialize_true, Label* materialize_false) const;
7150d5e116f6aee03185f237311a943491bb079a768Kristian Monsen    virtual void Plug(Slot* slot) const;
7160d5e116f6aee03185f237311a943491bb079a768Kristian Monsen    virtual void Plug(Handle<Object> lit) const;
7170d5e116f6aee03185f237311a943491bb079a768Kristian Monsen    virtual void Plug(Heap::RootListIndex) const;
7180d5e116f6aee03185f237311a943491bb079a768Kristian Monsen    virtual void PlugTOS() const;
7190d5e116f6aee03185f237311a943491bb079a768Kristian Monsen    virtual void DropAndPlug(int count, Register reg) const;
7200d5e116f6aee03185f237311a943491bb079a768Kristian Monsen    virtual void EmitLogicalLeft(BinaryOperation* expr,
7210d5e116f6aee03185f237311a943491bb079a768Kristian Monsen                                 Label* eval_right,
7220d5e116f6aee03185f237311a943491bb079a768Kristian Monsen                                 Label* done) const;
7230d5e116f6aee03185f237311a943491bb079a768Kristian Monsen    virtual void PrepareTest(Label* materialize_true,
7240d5e116f6aee03185f237311a943491bb079a768Kristian Monsen                             Label* materialize_false,
7250d5e116f6aee03185f237311a943491bb079a768Kristian Monsen                             Label** if_true,
7260d5e116f6aee03185f237311a943491bb079a768Kristian Monsen                             Label** if_false,
7270d5e116f6aee03185f237311a943491bb079a768Kristian Monsen                             Label** fall_through) const;
728b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    virtual void HandleExpression(Expression* expr) const;
7290d5e116f6aee03185f237311a943491bb079a768Kristian Monsen    virtual bool IsEffect() const { return true; }
7300d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  };
7310d5e116f6aee03185f237311a943491bb079a768Kristian Monsen
732b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  MacroAssembler* masm_;
733b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  CompilationInfo* info_;
734b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  Label return_label_;
735b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  NestedStatement* nesting_stack_;
736b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  int loop_depth_;
7370d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  const ExpressionContext* context_;
738b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  ZoneList<BailoutEntry> bailout_entries_;
739b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  ZoneList<BailoutEntry> stack_checks_;
740b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  ForwardBailoutStack* forward_bailout_stack_;
741b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  ForwardBailoutStack* forward_bailout_pending_;
742d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
743d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  friend class NestedStatement;
744d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
745d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  DISALLOW_COPY_AND_ASSIGN(FullCodeGenerator);
746d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke};
747d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
748d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
749d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} }  // namespace v8::internal
750d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
751d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke#endif  // V8_FULL_CODEGEN_H_
752