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