full-codegen-arm.cc revision 13e2dadd00298019ed862f2b2fc5068bba730bcf
13ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Copyright 2012 the V8 project authors. All rights reserved.
2b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Use of this source code is governed by a BSD-style license that can be
3b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// found in the LICENSE file.
4b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#if V8_TARGET_ARCH_ARM
6b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
7014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/ast/scopes.h"
8b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/code-factory.h"
9b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/code-stubs.h"
10b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/codegen.h"
11014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/debug/debug.h"
12014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/full-codegen/full-codegen.h"
13b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/ic/ic.h"
14014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/parsing/parser.h"
15b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
16b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/arm/code-stubs-arm.h"
17b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/arm/macro-assembler-arm.h"
189fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block
193ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Blocknamespace v8 {
203ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Blocknamespace internal {
213ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
22109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch#define __ ACCESS_MASM(masm())
231e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
241e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block// A patch site is a location in the code which it is possible to patch. This
251e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block// class has a number of methods to emit the code which is patchable and the
261e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block// method EmitPatchInfo to record a marker back to the patchable code. This
271e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block// marker is a cmp rx, #yyy instruction, and x * 0x00000fff + yyy (raw 12 bit
281e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block// immediate value is used) is the delta from the pc to the first instruction of
291e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block// the patchable code.
301e0659c275bb392c045087af4f6b0d7565cb3d77Steve Blockclass JumpPatchSite BASE_EMBEDDED {
311e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block public:
321e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  explicit JumpPatchSite(MacroAssembler* masm) : masm_(masm) {
331e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block#ifdef DEBUG
341e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    info_emitted_ = false;
351e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block#endif
361e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  }
371e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
381e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  ~JumpPatchSite() {
39b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(patch_site_.is_bound() == info_emitted_);
401e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  }
411e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
421e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  // When initially emitting this ensure that a jump is always generated to skip
431e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  // the inlined smi code.
441e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  void EmitJumpIfNotSmi(Register reg, Label* target) {
45b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(!patch_site_.is_bound() && !info_emitted_);
46db1b4389239a7132c9cde0915dbd3f775dc1027aBen Murdoch    Assembler::BlockConstPoolScope block_const_pool(masm_);
471e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    __ bind(&patch_site_);
481e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    __ cmp(reg, Operand(reg));
491e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    __ b(eq, target);  // Always taken before patched.
501e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  }
511e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
521e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  // When initially emitting this ensure that a jump is never generated to skip
531e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  // the inlined smi code.
541e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  void EmitJumpIfSmi(Register reg, Label* target) {
55b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(!patch_site_.is_bound() && !info_emitted_);
56db1b4389239a7132c9cde0915dbd3f775dc1027aBen Murdoch    Assembler::BlockConstPoolScope block_const_pool(masm_);
571e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    __ bind(&patch_site_);
581e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    __ cmp(reg, Operand(reg));
591e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    __ b(ne, target);  // Never taken before patched.
601e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  }
611e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
621e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  void EmitPatchInfo() {
63b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Block literal pool emission whilst recording patch site information.
64b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Assembler::BlockConstPoolScope block_const_pool(masm_);
653fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    if (patch_site_.is_bound()) {
663fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      int delta_to_patch_site = masm_->InstructionsGeneratedSince(&patch_site_);
673fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      Register reg;
683fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      reg.set_code(delta_to_patch_site / kOff12Mask);
693fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      __ cmp_raw_immediate(reg, delta_to_patch_site % kOff12Mask);
701e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block#ifdef DEBUG
713fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      info_emitted_ = true;
721e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block#endif
733fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    } else {
743fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      __ nop();  // Signals no inlined code.
753fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    }
761e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  }
771e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
781e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block private:
79109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  MacroAssembler* masm() { return masm_; }
801e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  MacroAssembler* masm_;
811e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  Label patch_site_;
821e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block#ifdef DEBUG
831e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  bool info_emitted_;
841e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block#endif
851e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block};
861e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
871e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
883ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block// Generate code for a JS function.  On entry to the function the receiver
893ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block// and arguments have been pushed on the stack left to right.  The actual
903ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block// argument count matches the formal parameter count expected by the
913ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block// function.
923ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block//
933ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block// The live registers are:
943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch//   o r1: the JS function object being called (i.e., ourselves)
95014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch//   o r3: the new target value
963ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block//   o cp: our context
97014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch//   o pp: our caller's constant pool pointer (if enabled)
983ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block//   o fp: our caller's frame pointer
993ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block//   o sp: stack pointer
1003ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block//   o lr: return address
1013ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block//
1023ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block// The function builds a JS frame.  Please see JavaScriptFrameConstants in
1033ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block// frames-arm.h for its layout.
1043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid FullCodeGenerator::Generate() {
1053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  CompilationInfo* info = info_;
106b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  profiling_counter_ = isolate()->factory()->NewCell(
107b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Handle<Smi>(Smi::FromInt(FLAG_interrupt_budget), isolate()));
108014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  SetFunctionPosition(literal());
1096ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  Comment cmnt(masm_, "[ function compiled by full code generator");
1103ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
111b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ProfileEntryHookStub::MaybeCallEntryHook(masm_);
112b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
113014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (FLAG_debug_code && info->ExpectsJSReceiverAsReceiver()) {
1143fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    int receiver_offset = info->scope()->num_parameters() * kPointerSize;
115b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    __ ldr(r2, MemOperand(sp, receiver_offset));
116014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    __ AssertNotSmi(r2);
117014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    __ CompareObjectType(r2, r2, no_reg, FIRST_JS_RECEIVER_TYPE);
118014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    __ Assert(ge, kSloppyFunctionExpectsJSReceiverReceiver);
119257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  }
120257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
1213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Open a frame scope to indicate that there is a frame on the stack.  The
1223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // MANUAL indicates that the scope shouldn't actually generate code to set up
1233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // the frame (that is done below).
1243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  FrameScope frame_scope(masm_, StackFrame::MANUAL);
1253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
126b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  info->set_prologue_offset(masm_->pc_offset());
127014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  __ Prologue(info->GeneratePreagedPrologue());
1283ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
129756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  { Comment cmnt(masm_, "[ Allocate locals");
130b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    int locals_count = info->scope()->num_stack_slots();
131b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Generators allocate locals, if any, in context slots.
132014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK(!IsGeneratorFunction(info->literal()->kind()) || locals_count == 0);
133109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    OperandStackDepthIncrement(locals_count);
134b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (locals_count > 0) {
135b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (locals_count >= 128) {
136b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        Label ok;
137b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        __ sub(r9, sp, Operand(locals_count * kPointerSize));
138b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        __ LoadRoot(r2, Heap::kRealStackLimitRootIndex);
139b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        __ cmp(r9, Operand(r2));
140b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        __ b(hs, &ok);
141014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ CallRuntime(Runtime::kThrowStackOverflow);
142b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        __ bind(&ok);
143b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
144b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      __ LoadRoot(r9, Heap::kUndefinedValueRootIndex);
145b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      int kMaxPushes = FLAG_optimize_for_size ? 4 : 32;
146b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (locals_count >= kMaxPushes) {
147b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        int loop_iterations = locals_count / kMaxPushes;
148b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        __ mov(r2, Operand(loop_iterations));
149b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        Label loop_header;
150b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        __ bind(&loop_header);
151b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        // Do pushes.
152b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        for (int i = 0; i < kMaxPushes; i++) {
153b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          __ push(r9);
154b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        }
155b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        // Continue loop if not done.
156b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        __ sub(r2, r2, Operand(1), SetCC);
157b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        __ b(&loop_header, ne);
158b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
159b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      int remaining = locals_count % kMaxPushes;
160b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // Emit the remaining pushes.
161b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      for (int i  = 0; i < remaining; i++) {
162b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        __ push(r9);
163b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
1644515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke    }
165756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  }
166d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
167014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool function_in_register_r1 = true;
1684515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke
169756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  // Possibly allocate a local context.
170014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (info->scope()->num_heap_slots() > 0) {
171b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Argument to NewContext is the function, which is still in r1.
172b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Comment cmnt(masm_, "[ Allocate context");
173b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    bool need_write_barrier = true;
174014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    int slots = info->scope()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS;
175014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (info->scope()->is_script_scope()) {
176b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      __ push(r1);
177014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ Push(info->scope()->GetScopeInfo(info->isolate()));
178014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ CallRuntime(Runtime::kNewScriptContext);
179bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      PrepareForBailoutForId(BailoutId::ScriptContext(),
180bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                             BailoutState::TOS_REGISTER);
181014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // The new target value is not used, clobbering is safe.
182014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      DCHECK_NULL(info->scope()->new_target_var());
183756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick    } else {
184014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (info->scope()->new_target_var() != nullptr) {
185014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ push(r3);  // Preserve new target.
186014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
187014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (slots <= FastNewContextStub::kMaximumSlots) {
188014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        FastNewContextStub stub(isolate(), slots);
189014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ CallStub(&stub);
190014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        // Result of FastNewContextStub is always in new space.
191014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        need_write_barrier = false;
192014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      } else {
193014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ push(r1);
194014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ CallRuntime(Runtime::kNewFunctionContext);
195014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
196014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (info->scope()->new_target_var() != nullptr) {
197014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ pop(r3);  // Preserve new target.
198014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
199756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick    }
200014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    function_in_register_r1 = false;
201b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Context is returned in r0.  It replaces the context passed to us.
202b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // It's saved in the stack and kept live in cp.
203b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    __ mov(cp, r0);
204b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    __ str(r0, MemOperand(fp, StandardFrameConstants::kContextOffset));
205756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick    // Copy any necessary parameters into the context.
2063fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    int num_parameters = info->scope()->num_parameters();
207014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    int first_parameter = info->scope()->has_this_declaration() ? -1 : 0;
208014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    for (int i = first_parameter; i < num_parameters; i++) {
209014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Variable* var = (i == -1) ? scope()->receiver() : scope()->parameter(i);
210589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      if (var->IsContextSlot()) {
211756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick        int parameter_offset = StandardFrameConstants::kCallerSPOffset +
212756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick            (num_parameters - 1 - i) * kPointerSize;
213756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick        // Load parameter from stack.
214756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick        __ ldr(r0, MemOperand(fp, parameter_offset));
215756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick        // Store it in the context.
216014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        MemOperand target = ContextMemOperand(cp, var->index());
2173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        __ str(r0, target);
2183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
2193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        // Update the write barrier.
220b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        if (need_write_barrier) {
221014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          __ RecordWriteContextSlot(cp, target.offset(), r0, r2,
222014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                    kLRHasBeenSaved, kDontSaveFPRegs);
223b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        } else if (FLAG_debug_code) {
224b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          Label done;
225b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          __ JumpIfInNewSpace(cp, r0, &done);
226b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          __ Abort(kExpectedNewSpaceObject);
227b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          __ bind(&done);
228b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        }
229d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block      }
230d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    }
231756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  }
232d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
233014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Register holding this function and new target are both trashed in case we
234014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // bailout here. But since that can happen only when new target is not used
235014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // and we allocate a context, the value of |function_in_register| is correct.
236bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  PrepareForBailoutForId(BailoutId::FunctionContext(),
237bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                         BailoutState::NO_REGISTERS);
238014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
239014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Possibly set up a local binding to the this function which is used in
240014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // derived constructors with super calls.
241014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Variable* this_function_var = scope()->this_function_var();
242014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (this_function_var != nullptr) {
243014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Comment cmnt(masm_, "[ This function");
244014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (!function_in_register_r1) {
245014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ ldr(r1, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
246014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // The write barrier clobbers register again, keep it marked as such.
247014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
248014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    SetVar(this_function_var, r1, r0, r2);
249014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
250014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
251014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Possibly set up a local binding to the new target value.
252014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Variable* new_target_var = scope()->new_target_var();
253014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (new_target_var != nullptr) {
254014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Comment cmnt(masm_, "[ new.target");
255014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    SetVar(new_target_var, r3, r0, r2);
256014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
257014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
258014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Possibly allocate RestParameters
259014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int rest_index;
260014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Variable* rest_param = scope()->rest_parameter(&rest_index);
261014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (rest_param) {
262014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Comment cmnt(masm_, "[ Allocate rest parameter array");
263109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    if (!function_in_register_r1) {
264109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      __ ldr(r1, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
265109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    }
266109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    FastNewRestParameterStub stub(isolate());
267f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch    __ CallStub(&stub);
268109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    function_in_register_r1 = false;
269014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    SetVar(rest_param, r0, r1, r2);
270014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
271014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2720d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  Variable* arguments = scope()->arguments();
273756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  if (arguments != NULL) {
274756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick    // Function uses arguments object.
275756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick    Comment cmnt(masm_, "[ Allocate arguments object");
276014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (!function_in_register_r1) {
277756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick      // Load this again, if it's used by the local context below.
278014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ ldr(r1, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
279d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    }
280109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    if (is_strict(language_mode()) || !has_simple_parameters()) {
281109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      FastNewStrictArgumentsStub stub(isolate());
282109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      __ CallStub(&stub);
283109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    } else if (literal()->has_duplicate_parameters()) {
284109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      __ Push(r1);
285109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      __ CallRuntime(Runtime::kNewSloppyArguments_Generic);
286109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    } else {
287109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      FastNewSloppyArgumentsStub stub(isolate());
288109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      __ CallStub(&stub);
289109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    }
29044f0eee88ff00398ff7f715fab053374d808c90dSteve Block
291589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    SetVar(arguments, r0, r1, r2);
292d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  }
293d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
294b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  if (FLAG_trace) {
295014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    __ CallRuntime(Runtime::kTraceEnter);
296b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
297b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2983b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  // Visit the declarations and body.
299bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  PrepareForBailoutForId(BailoutId::FunctionEntry(),
300bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                         BailoutState::NO_REGISTERS);
3013b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  {
302e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch    Comment cmnt(masm_, "[ Declarations");
3033b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    VisitDeclarations(scope()->declarations());
3043b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  }
305e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
3063b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  // Assert that the declarations do not use ICs. Otherwise the debugger
3073b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  // won't be able to redirect a PC at an IC to the correct IC in newly
3083b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  // recompiled code.
3093b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  DCHECK_EQ(0, ic_total_count_);
3103b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
3113b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  {
3123b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    Comment cmnt(masm_, "[ Stack check");
313bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    PrepareForBailoutForId(BailoutId::Declarations(),
314bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                           BailoutState::NO_REGISTERS);
3153b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    Label ok;
3163b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    __ LoadRoot(ip, Heap::kStackLimitRootIndex);
3173b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    __ cmp(sp, Operand(ip));
3183b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    __ b(hs, &ok);
3193b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    Handle<Code> stack_check = isolate()->builtins()->StackCheck();
3203b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    PredictableCodeSizeScope predictable(masm_);
3213b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    predictable.ExpectSize(
3223b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        masm_->CallSize(stack_check, RelocInfo::CODE_TARGET));
3233b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    __ Call(stack_check, RelocInfo::CODE_TARGET);
3243b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    __ bind(&ok);
3253b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  }
326e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
3273b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  {
3283b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    Comment cmnt(masm_, "[ Body");
3293b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    DCHECK(loop_depth() == 0);
3303b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    VisitStatements(literal()->body());
3313b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    DCHECK(loop_depth() == 0);
3323ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  }
3333ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
334e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  // Always emit a 'return undefined' in case control fell off the end of
335e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  // the body.
3363ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  { Comment cmnt(masm_, "[ return <undefined>;");
3373ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block    __ LoadRoot(r0, Heap::kUndefinedValueRootIndex);
338d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  }
3397f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  EmitReturnSequence();
340b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
341b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Force emit the constant pool, so it doesn't get emitted in the middle
342b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // of the back edge table.
343b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  masm()->CheckConstPool(true, false);
344d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block}
345d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
346d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
347db5a90a88cfcddb042912799e872037c6548b8a3Ben Murdochvoid FullCodeGenerator::ClearAccumulator() {
348db5a90a88cfcddb042912799e872037c6548b8a3Ben Murdoch  __ mov(r0, Operand(Smi::FromInt(0)));
349db5a90a88cfcddb042912799e872037c6548b8a3Ben Murdoch}
350db5a90a88cfcddb042912799e872037c6548b8a3Ben Murdoch
351db5a90a88cfcddb042912799e872037c6548b8a3Ben Murdoch
3523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid FullCodeGenerator::EmitProfilingCounterDecrement(int delta) {
3533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  __ mov(r2, Operand(profiling_counter_));
354b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  __ ldr(r3, FieldMemOperand(r2, Cell::kValueOffset));
3553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  __ sub(r3, r3, Operand(Smi::FromInt(delta)), SetCC);
356b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  __ str(r3, FieldMemOperand(r2, Cell::kValueOffset));
3573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
3583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
3593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
360b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef CAN_USE_ARMV7_INSTRUCTIONS
361b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic const int kProfileCounterResetSequenceLength = 5 * Assembler::kInstrSize;
362b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#else
363b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic const int kProfileCounterResetSequenceLength = 7 * Assembler::kInstrSize;
364b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif
365b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
366b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid FullCodeGenerator::EmitProfilingCounterReset() {
368b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Assembler::BlockConstPoolScope block_const_pool(masm_);
369b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  PredictableCodeSizeScope predictable_code_size_scope(
370b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      masm_, kProfileCounterResetSequenceLength);
371b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Label start;
372b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  __ bind(&start);
3733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  int reset_value = FLAG_interrupt_budget;
3743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  __ mov(r2, Operand(profiling_counter_));
375b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // The mov instruction above can be either 1 to 3 (for ARMv7) or 1 to 5
376b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // instructions (for ARMv6) depending upon whether it is an extended constant
377b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // pool - insert nop to compensate.
378b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int expected_instr_count =
379b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      (kProfileCounterResetSequenceLength / Assembler::kInstrSize) - 2;
380b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(masm_->InstructionsGeneratedSince(&start) <= expected_instr_count);
381b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  while (masm_->InstructionsGeneratedSince(&start) != expected_instr_count) {
382b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    __ nop();
383b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  __ mov(r3, Operand(Smi::FromInt(reset_value)));
385b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  __ str(r3, FieldMemOperand(r2, Cell::kValueOffset));
3863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
3873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
3883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
389b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid FullCodeGenerator::EmitBackEdgeBookkeeping(IterationStatement* stmt,
390b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                                Label* back_edge_target) {
391b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Comment cmnt(masm_, "[ Back edge bookkeeping");
392b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Block literal pools whilst emitting back edge code.
393b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Assembler::BlockConstPoolScope block_const_pool(masm_);
394b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  Label ok;
3953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
396b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(back_edge_target->is_bound());
397b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int distance = masm_->SizeOfCodeGeneratedSince(back_edge_target);
398b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int weight = Min(kMaxBackEdgeWeight,
399b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                   Max(1, distance / kCodeSizeMultiplier));
400b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EmitProfilingCounterDecrement(weight);
401b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  __ b(pl, &ok);
402b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  __ Call(isolate()->builtins()->InterruptCheck(), RelocInfo::CODE_TARGET);
4033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
404086aeeaae12517475c22695a200be45495516549Ben Murdoch  // Record a mapping of this PC offset to the OSR id.  This is used to find
405086aeeaae12517475c22695a200be45495516549Ben Murdoch  // the AST id from the unoptimized code in order to use it as a key into
406086aeeaae12517475c22695a200be45495516549Ben Murdoch  // the deoptimization input data found in the optimized code.
407b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  RecordBackEdge(stmt->OsrEntryId());
408086aeeaae12517475c22695a200be45495516549Ben Murdoch
409b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EmitProfilingCounterReset();
4103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
411b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  __ bind(&ok);
412bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  PrepareForBailoutForId(stmt->EntryId(), BailoutState::NO_REGISTERS);
413086aeeaae12517475c22695a200be45495516549Ben Murdoch  // Record a mapping of the OSR id to this PC.  This is used if the OSR
414086aeeaae12517475c22695a200be45495516549Ben Murdoch  // entry becomes the target of a bailout.  We don't expect it to be, but
415086aeeaae12517475c22695a200be45495516549Ben Murdoch  // we want it to work if it is.
416bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  PrepareForBailoutForId(stmt->OsrEntryId(), BailoutState::NO_REGISTERS);
417b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
418b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
419109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochvoid FullCodeGenerator::EmitProfilingCounterHandlingForReturnSequence(
420109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    bool is_tail_call) {
421109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  // Pretend that the exit is a backwards jump to the entry.
422109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  int weight = 1;
423109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  if (info_->ShouldSelfOptimize()) {
424109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    weight = FLAG_interrupt_budget / FLAG_self_opt_count;
425109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  } else {
426109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    int distance = masm_->pc_offset();
427109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    weight = Min(kMaxBackEdgeWeight, Max(1, distance / kCodeSizeMultiplier));
428109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  }
429109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  EmitProfilingCounterDecrement(weight);
430109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  Label ok;
431109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  __ b(pl, &ok);
432109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  // Don't need to save result register if we are going to do a tail call.
433109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  if (!is_tail_call) {
434109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    __ push(r0);
435109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  }
436109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  __ Call(isolate()->builtins()->InterruptCheck(), RelocInfo::CODE_TARGET);
437109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  if (!is_tail_call) {
438109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    __ pop(r0);
439109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  }
440109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  EmitProfilingCounterReset();
441109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  __ bind(&ok);
442109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch}
443b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
4447f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid FullCodeGenerator::EmitReturnSequence() {
445d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  Comment cmnt(masm_, "[ Return sequence");
446d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  if (return_label_.is_bound()) {
447d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    __ b(&return_label_);
448d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  } else {
449d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    __ bind(&return_label_);
4503ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block    if (FLAG_trace) {
4513ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block      // Push the return value on the stack as the parameter.
4523ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block      // Runtime::TraceExit returns its parameter in r0.
4533ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block      __ push(r0);
454014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ CallRuntime(Runtime::kTraceExit);
4553ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block    }
456109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    EmitProfilingCounterHandlingForReturnSequence(false);
4573ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
4586ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    // Make sure that the constant pool is not emitted inside of the return
4596ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    // sequence.
4606ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    { Assembler::BlockConstPoolScope block_const_pool(masm_);
461014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      int32_t arg_count = info_->scope()->num_parameters() + 1;
462014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      int32_t sp_delta = arg_count * kPointerSize;
463014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      SetReturnPosition(literal());
464b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // TODO(svenpanne) The code below is sometimes 4 words, sometimes 5!
465b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      PredictableCodeSizeScope predictable(masm_, -1);
466014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ LeaveFrame(StackFrame::JAVA_SCRIPT);
467b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      { ConstantPoolUnavailableScope constant_pool_unavailable(masm_);
468b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        __ add(sp, sp, Operand(sp_delta));
469b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        __ Jump(lr);
470b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
471d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    }
472d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  }
473d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block}
474d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
475bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdochvoid FullCodeGenerator::RestoreContext() {
476bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
477bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch}
478d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
479589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdochvoid FullCodeGenerator::StackValueContext::Plug(Variable* var) const {
480b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(var->IsStackAllocated() || var->IsContextSlot());
481589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  codegen()->GetVar(result_register(), var);
482109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  codegen()->PushOperand(result_register());
483d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block}
484d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
485d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
4860d5e116f6aee03185f237311a943491bb079a768Kristian Monsenvoid FullCodeGenerator::EffectContext::Plug(Heap::RootListIndex index) const {
4870d5e116f6aee03185f237311a943491bb079a768Kristian Monsen}
4880d5e116f6aee03185f237311a943491bb079a768Kristian Monsen
4890d5e116f6aee03185f237311a943491bb079a768Kristian Monsen
4900d5e116f6aee03185f237311a943491bb079a768Kristian Monsenvoid FullCodeGenerator::AccumulatorValueContext::Plug(
4910d5e116f6aee03185f237311a943491bb079a768Kristian Monsen    Heap::RootListIndex index) const {
4920d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  __ LoadRoot(result_register(), index);
4930d5e116f6aee03185f237311a943491bb079a768Kristian Monsen}
4940d5e116f6aee03185f237311a943491bb079a768Kristian Monsen
4950d5e116f6aee03185f237311a943491bb079a768Kristian Monsen
4960d5e116f6aee03185f237311a943491bb079a768Kristian Monsenvoid FullCodeGenerator::StackValueContext::Plug(
4970d5e116f6aee03185f237311a943491bb079a768Kristian Monsen    Heap::RootListIndex index) const {
4980d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  __ LoadRoot(result_register(), index);
499109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  codegen()->PushOperand(result_register());
5000d5e116f6aee03185f237311a943491bb079a768Kristian Monsen}
5010d5e116f6aee03185f237311a943491bb079a768Kristian Monsen
5020d5e116f6aee03185f237311a943491bb079a768Kristian Monsen
5030d5e116f6aee03185f237311a943491bb079a768Kristian Monsenvoid FullCodeGenerator::TestContext::Plug(Heap::RootListIndex index) const {
5043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  codegen()->PrepareForBailoutBeforeSplit(condition(),
505b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch                                          true,
506b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch                                          true_label_,
507b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch                                          false_label_);
5080d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  if (index == Heap::kUndefinedValueRootIndex ||
5090d5e116f6aee03185f237311a943491bb079a768Kristian Monsen      index == Heap::kNullValueRootIndex ||
5100d5e116f6aee03185f237311a943491bb079a768Kristian Monsen      index == Heap::kFalseValueRootIndex) {
511b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    if (false_label_ != fall_through_) __ b(false_label_);
5120d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  } else if (index == Heap::kTrueValueRootIndex) {
513b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    if (true_label_ != fall_through_) __ b(true_label_);
5140d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  } else {
5150d5e116f6aee03185f237311a943491bb079a768Kristian Monsen    __ LoadRoot(result_register(), index);
5163fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    codegen()->DoTest(this);
517e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  }
518d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block}
519d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
520d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
5210d5e116f6aee03185f237311a943491bb079a768Kristian Monsenvoid FullCodeGenerator::EffectContext::Plug(Handle<Object> lit) const {
5220d5e116f6aee03185f237311a943491bb079a768Kristian Monsen}
523e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
524e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
5250d5e116f6aee03185f237311a943491bb079a768Kristian Monsenvoid FullCodeGenerator::AccumulatorValueContext::Plug(
5260d5e116f6aee03185f237311a943491bb079a768Kristian Monsen    Handle<Object> lit) const {
5270d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  __ mov(result_register(), Operand(lit));
5280d5e116f6aee03185f237311a943491bb079a768Kristian Monsen}
529e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
5300d5e116f6aee03185f237311a943491bb079a768Kristian Monsen
5310d5e116f6aee03185f237311a943491bb079a768Kristian Monsenvoid FullCodeGenerator::StackValueContext::Plug(Handle<Object> lit) const {
532b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Immediates cannot be pushed directly.
5330d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  __ mov(result_register(), Operand(lit));
534109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  codegen()->PushOperand(result_register());
5350d5e116f6aee03185f237311a943491bb079a768Kristian Monsen}
5360d5e116f6aee03185f237311a943491bb079a768Kristian Monsen
5370d5e116f6aee03185f237311a943491bb079a768Kristian Monsen
5380d5e116f6aee03185f237311a943491bb079a768Kristian Monsenvoid FullCodeGenerator::TestContext::Plug(Handle<Object> lit) const {
5393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  codegen()->PrepareForBailoutBeforeSplit(condition(),
540b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch                                          true,
541b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch                                          true_label_,
542b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch                                          false_label_);
54313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  DCHECK(lit->IsNull(isolate()) || lit->IsUndefined(isolate()) ||
54413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch         !lit->IsUndetectable());
54513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  if (lit->IsUndefined(isolate()) || lit->IsNull(isolate()) ||
54613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      lit->IsFalse(isolate())) {
547b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    if (false_label_ != fall_through_) __ b(false_label_);
54813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  } else if (lit->IsTrue(isolate()) || lit->IsJSObject()) {
549b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    if (true_label_ != fall_through_) __ b(true_label_);
5500d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  } else if (lit->IsString()) {
5510d5e116f6aee03185f237311a943491bb079a768Kristian Monsen    if (String::cast(*lit)->length() == 0) {
5528b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch      if (false_label_ != fall_through_) __ b(false_label_);
5530d5e116f6aee03185f237311a943491bb079a768Kristian Monsen    } else {
554b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      if (true_label_ != fall_through_) __ b(true_label_);
5550d5e116f6aee03185f237311a943491bb079a768Kristian Monsen    }
5560d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  } else if (lit->IsSmi()) {
5570d5e116f6aee03185f237311a943491bb079a768Kristian Monsen    if (Smi::cast(*lit)->value() == 0) {
558b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      if (false_label_ != fall_through_) __ b(false_label_);
5590d5e116f6aee03185f237311a943491bb079a768Kristian Monsen    } else {
560b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      if (true_label_ != fall_through_) __ b(true_label_);
5610d5e116f6aee03185f237311a943491bb079a768Kristian Monsen    }
5620d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  } else {
5630d5e116f6aee03185f237311a943491bb079a768Kristian Monsen    // For simplicity we always test the accumulator register.
5640d5e116f6aee03185f237311a943491bb079a768Kristian Monsen    __ mov(result_register(), Operand(lit));
5653fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    codegen()->DoTest(this);
566d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  }
567d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block}
568d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
569d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
5700d5e116f6aee03185f237311a943491bb079a768Kristian Monsenvoid FullCodeGenerator::StackValueContext::DropAndPlug(int count,
5710d5e116f6aee03185f237311a943491bb079a768Kristian Monsen                                                       Register reg) const {
572b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(count > 0);
573109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  if (count > 1) codegen()->DropOperands(count - 1);
5740d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  __ str(reg, MemOperand(sp, 0));
575f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke}
576f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke
577d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
5780d5e116f6aee03185f237311a943491bb079a768Kristian Monsenvoid FullCodeGenerator::EffectContext::Plug(Label* materialize_true,
5790d5e116f6aee03185f237311a943491bb079a768Kristian Monsen                                            Label* materialize_false) const {
580b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(materialize_true == materialize_false);
5810d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  __ bind(materialize_true);
5820d5e116f6aee03185f237311a943491bb079a768Kristian Monsen}
583e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
5840d5e116f6aee03185f237311a943491bb079a768Kristian Monsen
5850d5e116f6aee03185f237311a943491bb079a768Kristian Monsenvoid FullCodeGenerator::AccumulatorValueContext::Plug(
5860d5e116f6aee03185f237311a943491bb079a768Kristian Monsen    Label* materialize_true,
5870d5e116f6aee03185f237311a943491bb079a768Kristian Monsen    Label* materialize_false) const {
5880d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  Label done;
5890d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  __ bind(materialize_true);
5900d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  __ LoadRoot(result_register(), Heap::kTrueValueRootIndex);
5910d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  __ jmp(&done);
5920d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  __ bind(materialize_false);
5930d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  __ LoadRoot(result_register(), Heap::kFalseValueRootIndex);
5940d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  __ bind(&done);
595d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block}
596d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
597d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
5980d5e116f6aee03185f237311a943491bb079a768Kristian Monsenvoid FullCodeGenerator::StackValueContext::Plug(
5990d5e116f6aee03185f237311a943491bb079a768Kristian Monsen    Label* materialize_true,
6000d5e116f6aee03185f237311a943491bb079a768Kristian Monsen    Label* materialize_false) const {
6010d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  Label done;
6020d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  __ bind(materialize_true);
6030d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  __ LoadRoot(ip, Heap::kTrueValueRootIndex);
6040d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  __ jmp(&done);
6050d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  __ bind(materialize_false);
6060d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  __ LoadRoot(ip, Heap::kFalseValueRootIndex);
6070d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  __ bind(&done);
608109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  codegen()->PushOperand(ip);
6090d5e116f6aee03185f237311a943491bb079a768Kristian Monsen}
6100d5e116f6aee03185f237311a943491bb079a768Kristian Monsen
6110d5e116f6aee03185f237311a943491bb079a768Kristian Monsen
6120d5e116f6aee03185f237311a943491bb079a768Kristian Monsenvoid FullCodeGenerator::TestContext::Plug(Label* materialize_true,
6130d5e116f6aee03185f237311a943491bb079a768Kristian Monsen                                          Label* materialize_false) const {
614b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(materialize_true == true_label_);
615b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(materialize_false == false_label_);
6160d5e116f6aee03185f237311a943491bb079a768Kristian Monsen}
6170d5e116f6aee03185f237311a943491bb079a768Kristian Monsen
6180d5e116f6aee03185f237311a943491bb079a768Kristian Monsen
6190d5e116f6aee03185f237311a943491bb079a768Kristian Monsenvoid FullCodeGenerator::AccumulatorValueContext::Plug(bool flag) const {
6200d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  Heap::RootListIndex value_root_index =
6210d5e116f6aee03185f237311a943491bb079a768Kristian Monsen      flag ? Heap::kTrueValueRootIndex : Heap::kFalseValueRootIndex;
6220d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  __ LoadRoot(result_register(), value_root_index);
6230d5e116f6aee03185f237311a943491bb079a768Kristian Monsen}
6240d5e116f6aee03185f237311a943491bb079a768Kristian Monsen
6250d5e116f6aee03185f237311a943491bb079a768Kristian Monsen
6260d5e116f6aee03185f237311a943491bb079a768Kristian Monsenvoid FullCodeGenerator::StackValueContext::Plug(bool flag) const {
6270d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  Heap::RootListIndex value_root_index =
6280d5e116f6aee03185f237311a943491bb079a768Kristian Monsen      flag ? Heap::kTrueValueRootIndex : Heap::kFalseValueRootIndex;
6290d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  __ LoadRoot(ip, value_root_index);
630109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  codegen()->PushOperand(ip);
6310d5e116f6aee03185f237311a943491bb079a768Kristian Monsen}
6320d5e116f6aee03185f237311a943491bb079a768Kristian Monsen
6330d5e116f6aee03185f237311a943491bb079a768Kristian Monsen
6340d5e116f6aee03185f237311a943491bb079a768Kristian Monsenvoid FullCodeGenerator::TestContext::Plug(bool flag) const {
6353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  codegen()->PrepareForBailoutBeforeSplit(condition(),
636b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch                                          true,
637b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch                                          true_label_,
638b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch                                          false_label_);
6390d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  if (flag) {
6400d5e116f6aee03185f237311a943491bb079a768Kristian Monsen    if (true_label_ != fall_through_) __ b(true_label_);
6410d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  } else {
6420d5e116f6aee03185f237311a943491bb079a768Kristian Monsen    if (false_label_ != fall_through_) __ b(false_label_);
643f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  }
644f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke}
645f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke
646f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke
6473fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochvoid FullCodeGenerator::DoTest(Expression* condition,
6483fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch                               Label* if_true,
64980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen                               Label* if_false,
65080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen                               Label* fall_through) {
6513b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  Handle<Code> ic = ToBooleanICStub::GetUninitialized(isolate());
652b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CallIC(ic, condition->test_id());
653014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  __ CompareRoot(result_register(), Heap::kTrueValueRootIndex);
654014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Split(eq, if_true, if_false, fall_through);
65580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen}
656d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
657e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
6581e0659c275bb392c045087af4f6b0d7565cb3d77Steve Blockvoid FullCodeGenerator::Split(Condition cond,
65980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen                              Label* if_true,
66080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen                              Label* if_false,
66180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen                              Label* fall_through) {
66280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  if (if_false == fall_through) {
6631e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    __ b(cond, if_true);
66480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  } else if (if_true == fall_through) {
6651e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    __ b(NegateCondition(cond), if_false);
66680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  } else {
6671e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    __ b(cond, if_true);
66880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen    __ b(if_false);
669d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  }
670d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block}
671d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
672d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
673589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben MurdochMemOperand FullCodeGenerator::StackOperand(Variable* var) {
674b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(var->IsStackAllocated());
675589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  // Offset is negative because higher indexes are at lower addresses.
676589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  int offset = -var->index() * kPointerSize;
677589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  // Adjust by a (parameter or local) base offset.
678589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  if (var->IsParameter()) {
679589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    offset += (info_->scope()->num_parameters() + 1) * kPointerSize;
680589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  } else {
681589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    offset += JavaScriptFrameConstants::kLocal0Offset;
682e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  }
683589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  return MemOperand(fp, offset);
684e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke}
685e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
686e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
687589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben MurdochMemOperand FullCodeGenerator::VarOperand(Variable* var, Register scratch) {
688b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(var->IsContextSlot() || var->IsStackAllocated());
689589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  if (var->IsContextSlot()) {
690589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    int context_chain_length = scope()->ContextChainLength(var->scope());
691589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    __ LoadContext(scratch, context_chain_length);
692014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return ContextMemOperand(scratch, var->index());
693589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  } else {
694589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    return StackOperand(var);
695589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  }
696589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch}
697589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch
698589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch
699589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdochvoid FullCodeGenerator::GetVar(Register dest, Variable* var) {
700e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  // Use destination as scratch.
701589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  MemOperand location = VarOperand(var, dest);
702589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  __ ldr(dest, location);
703e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke}
704e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
705e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
706589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdochvoid FullCodeGenerator::SetVar(Variable* var,
707589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch                               Register src,
708589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch                               Register scratch0,
709589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch                               Register scratch1) {
710b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(var->IsContextSlot() || var->IsStackAllocated());
711b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(!scratch0.is(src));
712b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(!scratch0.is(scratch1));
713b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(!scratch1.is(src));
714589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  MemOperand location = VarOperand(var, scratch0);
715e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  __ str(src, location);
7163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
717e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  // Emit the write barrier code if the location is in the heap.
718589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  if (var->IsContextSlot()) {
7193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    __ RecordWriteContextSlot(scratch0,
7203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                              location.offset(),
7213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                              src,
7223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                              scratch1,
7233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                              kLRHasBeenSaved,
7243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                              kDontSaveFPRegs);
725e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  }
726d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block}
727d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
728d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
7293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid FullCodeGenerator::PrepareForBailoutBeforeSplit(Expression* expr,
730b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch                                                     bool should_normalize,
731b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch                                                     Label* if_true,
732b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch                                                     Label* if_false) {
733b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Only prepare for bailouts before splits if we're in a test
734b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // context. Otherwise, we let the Visit function deal with the
735b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // preparation to avoid preparing with the same AST id twice.
736014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (!context()->IsTest()) return;
737b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
738b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  Label skip;
739b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  if (should_normalize) __ b(&skip);
740bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  PrepareForBailout(expr, BailoutState::TOS_REGISTER);
741b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  if (should_normalize) {
742b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    __ LoadRoot(ip, Heap::kTrueValueRootIndex);
743b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    __ cmp(r0, ip);
744b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    Split(eq, if_true, if_false, NULL);
745b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    __ bind(&skip);
746b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
747b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
748b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
749b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
750b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid FullCodeGenerator::EmitDebugCheckDeclarationContext(Variable* variable) {
751b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // The variable in the declaration always resides in the current function
752b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // context.
753b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK_EQ(0, scope()->ContextChainLength(variable->scope()));
754109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  if (FLAG_debug_code) {
755b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Check that we're not inside a with or catch context.
756b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    __ ldr(r1, FieldMemOperand(cp, HeapObject::kMapOffset));
757b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    __ CompareRoot(r1, Heap::kWithContextMapRootIndex);
758b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    __ Check(ne, kDeclarationInWithContext);
759b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    __ CompareRoot(r1, Heap::kCatchContextMapRootIndex);
760b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    __ Check(ne, kDeclarationInCatchContext);
761b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
762b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
763b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
764b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
765b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid FullCodeGenerator::VisitVariableDeclaration(
766b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    VariableDeclaration* declaration) {
767589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  // If it was not possible to allocate the variable at compile time, we
768589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  // need to "declare" it at runtime to make sure it actually exists in the
769589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  // local context.
770b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  VariableProxy* proxy = declaration->proxy();
771b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  VariableMode mode = declaration->mode();
772589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  Variable* variable = proxy->var();
773bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  bool hole_init = mode == LET || mode == CONST;
774589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  switch (variable->location()) {
775014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case VariableLocation::GLOBAL:
776014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case VariableLocation::UNALLOCATED:
777bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      DCHECK(!variable->binding_needs_init());
778b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      globals_->Add(variable->name(), zone());
779bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      globals_->Add(isolate()->factory()->undefined_value(), zone());
780589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      break;
781589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch
782014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case VariableLocation::PARAMETER:
783014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case VariableLocation::LOCAL:
784b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (hole_init) {
785b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        Comment cmnt(masm_, "[ VariableDeclaration");
786014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ LoadRoot(r0, Heap::kTheHoleValueRootIndex);
787014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ str(r0, StackOperand(variable));
788d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block      }
78969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch      break;
790d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
791014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case VariableLocation::CONTEXT:
792b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (hole_init) {
793b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        Comment cmnt(masm_, "[ VariableDeclaration");
794b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        EmitDebugCheckDeclarationContext(variable);
795014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ LoadRoot(r0, Heap::kTheHoleValueRootIndex);
796014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ str(r0, ContextMemOperand(cp, variable->index()));
79769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch        // No write barrier since the_hole_value is in old space.
798bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch        PrepareForBailoutForId(proxy->id(), BailoutState::NO_REGISTERS);
79969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch      }
80069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch      break;
801257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
802014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case VariableLocation::LOOKUP: {
803b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Comment cmnt(masm_, "[ VariableDeclaration");
80413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      DCHECK_EQ(VAR, mode);
80513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      DCHECK(!hole_init);
80669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch      __ mov(r2, Operand(variable->name()));
80713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      __ Push(r2);
80813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      __ CallRuntime(Runtime::kDeclareEvalVar);
809bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      PrepareForBailoutForId(proxy->id(), BailoutState::NO_REGISTERS);
810b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
811b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
812b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
813b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
814b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
815b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
816b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid FullCodeGenerator::VisitFunctionDeclaration(
817b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    FunctionDeclaration* declaration) {
818b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  VariableProxy* proxy = declaration->proxy();
819b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Variable* variable = proxy->var();
820b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  switch (variable->location()) {
821014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case VariableLocation::GLOBAL:
822014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case VariableLocation::UNALLOCATED: {
823b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      globals_->Add(variable->name(), zone());
824b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Handle<SharedFunctionInfo> function =
825014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          Compiler::GetSharedFunctionInfo(declaration->fun(), script(), info_);
826b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // Check for stack-overflow exception.
827b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (function.is_null()) return SetStackOverflow();
828b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      globals_->Add(function, zone());
829b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
830b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
831b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
832014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case VariableLocation::PARAMETER:
833014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case VariableLocation::LOCAL: {
834b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Comment cmnt(masm_, "[ FunctionDeclaration");
835b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      VisitForAccumulatorValue(declaration->fun());
836b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      __ str(result_register(), StackOperand(variable));
837b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
838b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
839b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
840014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case VariableLocation::CONTEXT: {
841b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Comment cmnt(masm_, "[ FunctionDeclaration");
842b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      EmitDebugCheckDeclarationContext(variable);
843b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      VisitForAccumulatorValue(declaration->fun());
844014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ str(result_register(), ContextMemOperand(cp, variable->index()));
845b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      int offset = Context::SlotOffset(variable->index());
846b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // We know that we have written a function, which is not a smi.
847b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      __ RecordWriteContextSlot(cp,
848b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                offset,
849b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                result_register(),
850b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                r2,
851b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                kLRHasBeenSaved,
852b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                kDontSaveFPRegs,
853b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                EMIT_REMEMBERED_SET,
854b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                OMIT_SMI_CHECK);
855bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      PrepareForBailoutForId(proxy->id(), BailoutState::NO_REGISTERS);
856b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
857b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
858b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
859014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case VariableLocation::LOOKUP: {
860b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Comment cmnt(masm_, "[ FunctionDeclaration");
861b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      __ mov(r2, Operand(variable->name()));
862109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      PushOperand(r2);
863b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // Push initial value for function declaration.
864b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      VisitForStackValue(declaration->fun());
86513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      CallRuntimeWithOperands(Runtime::kDeclareEvalFunction);
866bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      PrepareForBailoutForId(proxy->id(), BailoutState::NO_REGISTERS);
86769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch      break;
868d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    }
8693ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  }
8703ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block}
8713ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
8723ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
873d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) {
8743ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  // Call the runtime to declare the globals.
875589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  __ mov(r1, Operand(pairs));
876589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  __ mov(r0, Operand(Smi::FromInt(DeclareGlobalsFlags())));
877014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  __ Push(r1, r0);
878014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  __ CallRuntime(Runtime::kDeclareGlobals);
8793ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  // Return value is ignored.
8803ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block}
8813ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
8823ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
883b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid FullCodeGenerator::DeclareModules(Handle<FixedArray> descriptions) {
884b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Call the runtime to declare the modules.
885b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  __ Push(descriptions);
886014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  __ CallRuntime(Runtime::kDeclareModules);
887b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Return value is ignored.
888b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
889b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
890b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
891f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarkevoid FullCodeGenerator::VisitSwitchStatement(SwitchStatement* stmt) {
892f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  Comment cmnt(masm_, "[ SwitchStatement");
893f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  Breakable nested_statement(this, stmt);
894f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  SetStatementPosition(stmt);
895e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
896f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  // Keep the switch value on the stack until a case matches.
8970d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  VisitForStackValue(stmt->tag());
898bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  PrepareForBailoutForId(stmt->EntryId(), BailoutState::NO_REGISTERS);
899b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
900f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  ZoneList<CaseClause*>* clauses = stmt->cases();
901f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  CaseClause* default_clause = NULL;  // Can occur anywhere in the list.
902f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke
903f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  Label next_test;  // Recycled for each test.
904f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  // Compile all the tests with branches to their bodies.
905f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  for (int i = 0; i < clauses->length(); i++) {
906f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke    CaseClause* clause = clauses->at(i);
9078b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    clause->body_target()->Unuse();
9081e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
909f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke    // The default is not a test, but remember it as final fall through.
910f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke    if (clause->is_default()) {
911f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke      default_clause = clause;
912f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke      continue;
913f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke    }
914f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke
915f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke    Comment cmnt(masm_, "[ Case comparison");
916f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke    __ bind(&next_test);
917f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke    next_test.Unuse();
918f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke
919f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke    // Compile the label expression.
9200d5e116f6aee03185f237311a943491bb079a768Kristian Monsen    VisitForAccumulatorValue(clause->label());
921f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke
92280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen    // Perform the comparison as if via '==='.
923f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke    __ ldr(r1, MemOperand(sp, 0));  // Switch value.
9240d5e116f6aee03185f237311a943491bb079a768Kristian Monsen    bool inline_smi_code = ShouldInlineSmiCase(Token::EQ_STRICT);
9251e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    JumpPatchSite patch_site(masm_);
9260d5e116f6aee03185f237311a943491bb079a768Kristian Monsen    if (inline_smi_code) {
92780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen      Label slow_case;
92880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen      __ orr(r2, r1, r0);
9291e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block      patch_site.EmitJumpIfNotSmi(r2, &slow_case);
9301e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
93180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen      __ cmp(r1, r0);
93280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen      __ b(ne, &next_test);
93380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen      __ Drop(1);  // Switch value is no longer needed.
9348b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch      __ b(clause->body_target());
9351e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block      __ bind(&slow_case);
93680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen    }
93780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen
9381e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    // Record position before stub call for type feedback.
939014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    SetExpressionPosition(clause);
940109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    Handle<Code> ic =
941109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        CodeFactory::CompareIC(isolate(), Token::EQ_STRICT).code();
942b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CallIC(ic, clause->CompareId());
9433fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    patch_site.EmitPatchInfo();
944257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
945b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Label skip;
946b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    __ b(&skip);
947bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    PrepareForBailout(clause, BailoutState::TOS_REGISTER);
948b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    __ LoadRoot(ip, Heap::kTrueValueRootIndex);
949b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    __ cmp(r0, ip);
950b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    __ b(ne, &next_test);
951b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    __ Drop(1);
952b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    __ jmp(clause->body_target());
953b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    __ bind(&skip);
954b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
955b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    __ cmp(r0, Operand::Zero());
956f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke    __ b(ne, &next_test);
957f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke    __ Drop(1);  // Switch value is no longer needed.
9588b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    __ b(clause->body_target());
959f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  }
960f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke
961f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  // Discard the test value and jump to the default if present, otherwise to
962f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  // the end of the statement.
963f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  __ bind(&next_test);
964109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  DropOperands(1);  // Switch value is no longer needed.
965f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  if (default_clause == NULL) {
96669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch    __ b(nested_statement.break_label());
967f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  } else {
9688b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    __ b(default_clause->body_target());
969f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  }
970f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke
971f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  // Compile all the case bodies.
972f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  for (int i = 0; i < clauses->length(); i++) {
973f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke    Comment cmnt(masm_, "[ Case body");
974f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke    CaseClause* clause = clauses->at(i);
9758b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    __ bind(clause->body_target());
976bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    PrepareForBailoutForId(clause->EntryId(), BailoutState::NO_REGISTERS);
977f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke    VisitStatements(clause->statements());
978f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  }
979f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke
98069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  __ bind(nested_statement.break_label());
981bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  PrepareForBailoutForId(stmt->ExitId(), BailoutState::NO_REGISTERS);
982f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke}
983f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke
984f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke
985f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarkevoid FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) {
986f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  Comment cmnt(masm_, "[ ForInStatement");
987014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  SetStatementPosition(stmt, SKIP_BREAK);
988014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
989958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  FeedbackVectorSlot slot = stmt->ForInFeedbackSlot();
990f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke
991109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  // Get the object to enumerate over.
992014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  SetExpressionAsStatementPosition(stmt->enumerable());
9930d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  VisitForAccumulatorValue(stmt->enumerable());
9943b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  OperandStackDepthIncrement(5);
9953b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
9963b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  Label loop, exit;
9973b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  Iteration loop_statement(this, stmt);
9983b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  increment_loop_depth();
999f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke
1000109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  // If the object is null or undefined, skip over the loop, otherwise convert
1001109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  // it to a JS receiver.  See ECMA-262 version 5, section 12.6.4.
1002f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  Label convert, done_convert;
10031e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  __ JumpIfSmi(r0, &convert);
1004014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  __ CompareObjectType(r0, r1, r1, FIRST_JS_RECEIVER_TYPE);
10053fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  __ b(ge, &done_convert);
1006109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  __ CompareRoot(r0, Heap::kNullValueRootIndex);
1007109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  __ b(eq, &exit);
1008109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  __ CompareRoot(r0, Heap::kUndefinedValueRootIndex);
1009109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  __ b(eq, &exit);
1010f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  __ bind(&convert);
1011014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  ToObjectStub stub(isolate());
1012014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  __ CallStub(&stub);
1013f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  __ bind(&done_convert);
1014bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  PrepareForBailoutForId(stmt->ToObjectId(), BailoutState::TOS_REGISTER);
1015f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  __ push(r0);
1016f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke
1017bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  // Check cache validity in generated code. If we cannot guarantee cache
1018bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  // validity, call the runtime system to check cache validity or get the
1019bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  // property names in a fixed array. Note: Proxies never have an enum cache,
1020bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  // so will always take the slow path.
1021109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  Label call_runtime;
1022109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  __ CheckEnumCache(&call_runtime);
1023e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
1024e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  // The enum cache is valid.  Load the map of the object being
1025e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  // iterated over and use the cache for the iteration.
1026e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  Label use_cache;
1027e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  __ ldr(r0, FieldMemOperand(r0, HeapObject::kMapOffset));
1028e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  __ b(&use_cache);
1029f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke
1030f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  // Get the set of properties to enumerate.
1031e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  __ bind(&call_runtime);
1032f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  __ push(r0);  // Duplicate the enumerable object on the stack.
1033109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  __ CallRuntime(Runtime::kForInEnumerate);
1034bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  PrepareForBailoutForId(stmt->EnumId(), BailoutState::TOS_REGISTER);
1035f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke
1036f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  // If we got a map from the runtime call, we can do a fast
1037f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  // modification check. Otherwise, we got a fixed array, and we have
1038f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  // to do a slow check.
1039f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  Label fixed_array;
1040b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  __ ldr(r2, FieldMemOperand(r0, HeapObject::kMapOffset));
1041f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  __ LoadRoot(ip, Heap::kMetaMapRootIndex);
1042b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  __ cmp(r2, ip);
1043f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  __ b(ne, &fixed_array);
1044f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke
1045f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  // We got a map in register r0. Get the enumeration cache from it.
1046b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Label no_descriptors;
1047e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  __ bind(&use_cache);
1048b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1049b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  __ EnumLength(r1, r0);
1050b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  __ cmp(r1, Operand(Smi::FromInt(0)));
1051b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  __ b(eq, &no_descriptors);
1052b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1053b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  __ LoadInstanceDescriptors(r0, r2);
1054b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  __ ldr(r2, FieldMemOperand(r2, DescriptorArray::kEnumCacheOffset));
1055b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  __ ldr(r2, FieldMemOperand(r2, DescriptorArray::kEnumCacheBridgeCacheOffset));
1056f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke
10573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Set up the four remaining stack slots.
1058f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  __ push(r0);  // Map.
1059f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  __ mov(r0, Operand(Smi::FromInt(0)));
1060f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  // Push enumeration cache, enumeration cache length (as smi) and zero.
1061f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  __ Push(r2, r1, r0);
1062f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  __ jmp(&loop);
1063f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke
1064b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  __ bind(&no_descriptors);
1065b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  __ Drop(1);
1066b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  __ jmp(&exit);
1067b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1068f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  // We got a fixed array in register r0. Iterate through that.
1069f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  __ bind(&fixed_array);
10703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1071014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  __ mov(r1, Operand(Smi::FromInt(1)));  // Smi(1) indicates slow check
10723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  __ Push(r1, r0);  // Smi and array
1073f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  __ ldr(r1, FieldMemOperand(r0, FixedArray::kLengthOffset));
1074109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  __ Push(r1);  // Fixed array length (as smi).
1075bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  PrepareForBailoutForId(stmt->PrepareId(), BailoutState::NO_REGISTERS);
1076f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  __ mov(r0, Operand(Smi::FromInt(0)));
1077109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  __ Push(r0);  // Initial index.
1078f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke
1079f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  // Generate code for doing the condition check.
1080f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  __ bind(&loop);
1081014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  SetExpressionAsStatementPosition(stmt->each());
1082958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1083f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  // Load the current count to r0, load the length to r1.
1084f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  __ Ldrd(r0, r1, MemOperand(sp, 0 * kPointerSize));
1085f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  __ cmp(r0, r1);  // Compare to the array length.
108669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  __ b(hs, loop_statement.break_label());
1087f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke
1088f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  // Get the current entry of the array into register r3.
1089f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  __ ldr(r2, MemOperand(sp, 2 * kPointerSize));
1090f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  __ add(r2, r2, Operand(FixedArray::kHeaderSize - kHeapObjectTag));
1091b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  __ ldr(r3, MemOperand::PointerAddressFromSmiKey(r2, r0));
1092f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke
10933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Get the expected map from the stack or a smi in the
1094f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  // permanent slow case into register r2.
1095f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  __ ldr(r2, MemOperand(sp, 3 * kPointerSize));
1096f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke
1097f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  // Check if the expected map still matches that of the enumerable.
10983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // If not, we may have to filter the key.
1099f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  Label update_each;
1100f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  __ ldr(r1, MemOperand(sp, 4 * kPointerSize));
1101f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  __ ldr(r4, FieldMemOperand(r1, HeapObject::kMapOffset));
1102f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  __ cmp(r4, Operand(r2));
1103f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  __ b(eq, &update_each);
1104f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke
11053b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  // We need to filter the key, record slow-path here.
11063b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  int const vector_index = SmiFromSlot(slot)->value();
1107109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  __ EmitLoadTypeFeedbackVector(r0);
1108109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  __ mov(r2, Operand(TypeFeedbackVector::MegamorphicSentinel(isolate())));
1109109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  __ str(r2, FieldMemOperand(r0, FixedArray::OffsetOfElementAt(vector_index)));
1110109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
1111756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  // Convert the entry to a string or (smi) 0 if it isn't a property
1112756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  // any more. If the property has been removed while iterating, we
1113f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  // just skip it.
1114f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  __ push(r1);  // Enumerable.
1115f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  __ push(r3);  // Current entry.
1116014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  __ CallRuntime(Runtime::kForInFilter);
1117bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  PrepareForBailoutForId(stmt->FilterId(), BailoutState::TOS_REGISTER);
1118014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  __ mov(r3, Operand(r0));
1119014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  __ LoadRoot(ip, Heap::kUndefinedValueRootIndex);
1120014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  __ cmp(r0, ip);
112169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  __ b(eq, loop_statement.continue_label());
1122f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke
1123f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  // Update the 'each' property or variable from the possibly filtered
1124f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  // entry in register r3.
1125f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  __ bind(&update_each);
1126f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  __ mov(result_register(), r3);
1127f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  // Perform the assignment as if via '='.
1128b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  { EffectContext context(this);
1129014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    EmitAssignment(stmt->each(), stmt->EachFeedbackSlot());
1130bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    PrepareForBailoutForId(stmt->AssignmentId(), BailoutState::NO_REGISTERS);
1131b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
1132f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke
1133014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Both Crankshaft and Turbofan expect BodyId to be right before stmt->body().
1134bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  PrepareForBailoutForId(stmt->BodyId(), BailoutState::NO_REGISTERS);
1135f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  // Generate code for the body of the loop.
1136f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  Visit(stmt->body());
1137f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke
1138f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  // Generate code for the going to the next element by incrementing
1139f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  // the index (smi) stored on top of the stack.
114069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  __ bind(loop_statement.continue_label());
1141f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  __ pop(r0);
1142f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  __ add(r0, r0, Operand(Smi::FromInt(1)));
1143f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  __ push(r0);
1144f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke
1145b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EmitBackEdgeBookkeeping(stmt, &loop);
1146b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  __ b(&loop);
1147f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke
1148f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  // Remove the pointers stored on the stack.
114969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  __ bind(loop_statement.break_label());
1150109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  DropOperands(5);
1151f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke
1152f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  // Exit and decrement the loop depth.
1153bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  PrepareForBailoutForId(stmt->ExitId(), BailoutState::NO_REGISTERS);
1154f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  __ bind(&exit);
1155f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  decrement_loop_depth();
1156f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke}
11573ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
11583ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
1159014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid FullCodeGenerator::EmitSetHomeObject(Expression* initializer, int offset,
1160014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                          FeedbackVectorSlot slot) {
1161014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(NeedsHomeObject(initializer));
1162014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  __ ldr(StoreDescriptor::ReceiverRegister(), MemOperand(sp));
1163014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  __ mov(StoreDescriptor::NameRegister(),
1164014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch         Operand(isolate()->factory()->home_object_symbol()));
1165014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  __ ldr(StoreDescriptor::ValueRegister(),
1166014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch         MemOperand(sp, offset * kPointerSize));
1167014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  EmitLoadStoreICSlot(slot);
1168014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  CallStoreIC();
1169b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1170b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1171b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1172014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid FullCodeGenerator::EmitSetHomeObjectAccumulator(Expression* initializer,
1173014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                                     int offset,
1174014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                                     FeedbackVectorSlot slot) {
1175014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(NeedsHomeObject(initializer));
1176014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  __ Move(StoreDescriptor::ReceiverRegister(), r0);
1177014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  __ mov(StoreDescriptor::NameRegister(),
1178014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch         Operand(isolate()->factory()->home_object_symbol()));
1179014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  __ ldr(StoreDescriptor::ValueRegister(),
1180014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch         MemOperand(sp, offset * kPointerSize));
1181014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  EmitLoadStoreICSlot(slot);
1182014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  CallStoreIC();
1183958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
1184958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1185958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1186b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid FullCodeGenerator::EmitLoadGlobalCheckExtensions(VariableProxy* proxy,
1187014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                                      TypeofMode typeof_mode,
1188589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch                                                      Label* slow) {
1189257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  Register current = cp;
1190257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  Register next = r1;
1191257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  Register temp = r2;
1192257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
1193257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  Scope* s = scope();
1194257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  while (s != NULL) {
1195257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    if (s->num_heap_slots() > 0) {
1196b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (s->calls_sloppy_eval()) {
1197014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        // Check that extension is "the hole".
1198014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ ldr(temp, ContextMemOperand(current, Context::EXTENSION_INDEX));
1199014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ JumpIfNotRoot(temp, Heap::kTheHoleValueRootIndex, slow);
1200257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      }
1201257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      // Load next context in chain.
1202014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ ldr(next, ContextMemOperand(current, Context::PREVIOUS_INDEX));
1203257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      // Walk the rest of the chain without clobbering cp.
1204257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      current = next;
1205257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    }
1206257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    // If no outer scope calls eval, we do not need to check more
1207257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    // context extensions.
1208b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (!s->outer_scope_calls_sloppy_eval() || s->is_eval_scope()) break;
1209257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    s = s->outer_scope();
1210257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  }
1211257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
1212257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  if (s->is_eval_scope()) {
1213257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    Label loop, fast;
1214257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    if (!current.is(next)) {
1215257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      __ Move(next, current);
1216257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    }
1217257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    __ bind(&loop);
1218b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Terminate at native context.
1219257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    __ ldr(temp, FieldMemOperand(next, HeapObject::kMapOffset));
1220b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    __ LoadRoot(ip, Heap::kNativeContextMapRootIndex);
1221257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    __ cmp(temp, ip);
1222257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    __ b(eq, &fast);
1223014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // Check that extension is "the hole".
1224014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    __ ldr(temp, ContextMemOperand(next, Context::EXTENSION_INDEX));
1225014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    __ JumpIfNotRoot(temp, Heap::kTheHoleValueRootIndex, slow);
1226257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    // Load next context in chain.
1227014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    __ ldr(next, ContextMemOperand(next, Context::PREVIOUS_INDEX));
1228257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    __ b(&loop);
1229257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    __ bind(&fast);
1230257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  }
1231257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
1232014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // All extension objects were empty and it is safe to use a normal global
1233014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // load machinery.
1234014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  EmitGlobalVariableLoad(proxy, typeof_mode);
1235257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch}
1236257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
1237257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
1238589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben MurdochMemOperand FullCodeGenerator::ContextSlotOperandCheckExtensions(Variable* var,
1239589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch                                                                Label* slow) {
1240b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(var->IsContextSlot());
1241e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  Register context = cp;
124259151504615d929945dc59db37bf1166937748c6Steve Block  Register next = r3;
124359151504615d929945dc59db37bf1166937748c6Steve Block  Register temp = r4;
124459151504615d929945dc59db37bf1166937748c6Steve Block
1245589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  for (Scope* s = scope(); s != var->scope(); s = s->outer_scope()) {
124659151504615d929945dc59db37bf1166937748c6Steve Block    if (s->num_heap_slots() > 0) {
1247b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (s->calls_sloppy_eval()) {
1248014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        // Check that extension is "the hole".
1249014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ ldr(temp, ContextMemOperand(context, Context::EXTENSION_INDEX));
1250014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ JumpIfNotRoot(temp, Heap::kTheHoleValueRootIndex, slow);
125159151504615d929945dc59db37bf1166937748c6Steve Block      }
1252014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ ldr(next, ContextMemOperand(context, Context::PREVIOUS_INDEX));
125359151504615d929945dc59db37bf1166937748c6Steve Block      // Walk the rest of the chain without clobbering cp.
1254e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch      context = next;
125559151504615d929945dc59db37bf1166937748c6Steve Block    }
125659151504615d929945dc59db37bf1166937748c6Steve Block  }
1257014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Check that last extension is "the hole".
1258014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  __ ldr(temp, ContextMemOperand(context, Context::EXTENSION_INDEX));
1259014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  __ JumpIfNotRoot(temp, Heap::kTheHoleValueRootIndex, slow);
1260e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
1261e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  // This function is used only for loads, not stores, so it's safe to
1262e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  // return an cp-based operand (the write barrier cannot be allowed to
1263e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  // destroy the cp register).
1264014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return ContextMemOperand(context, var->index());
126559151504615d929945dc59db37bf1166937748c6Steve Block}
126659151504615d929945dc59db37bf1166937748c6Steve Block
126759151504615d929945dc59db37bf1166937748c6Steve Block
1268b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid FullCodeGenerator::EmitDynamicLookupFastCase(VariableProxy* proxy,
1269014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                                  TypeofMode typeof_mode,
1270014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                                  Label* slow, Label* done) {
127159151504615d929945dc59db37bf1166937748c6Steve Block  // Generate fast-case code for variables that might be shadowed by
127259151504615d929945dc59db37bf1166937748c6Steve Block  // eval-introduced variables.  Eval is used a lot without
127359151504615d929945dc59db37bf1166937748c6Steve Block  // introducing variables.  In those cases, we do not want to
127459151504615d929945dc59db37bf1166937748c6Steve Block  // perform a runtime call for all variables in the scope
127559151504615d929945dc59db37bf1166937748c6Steve Block  // containing the eval.
1276b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Variable* var = proxy->var();
12773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (var->mode() == DYNAMIC_GLOBAL) {
1278014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    EmitLoadGlobalCheckExtensions(proxy, typeof_mode, slow);
127959151504615d929945dc59db37bf1166937748c6Steve Block    __ jmp(done);
12803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  } else if (var->mode() == DYNAMIC_LOCAL) {
1281589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    Variable* local = var->local_if_not_shadowed();
1282589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    __ ldr(r0, ContextSlotOperandCheckExtensions(local, slow));
1283bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    if (local->mode() == LET || local->mode() == CONST) {
1284589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      __ CompareRoot(r0, Heap::kTheHoleValueRootIndex);
1285bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      __ b(ne, done);
1286bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      __ mov(r0, Operand(var->name()));
1287bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      __ push(r0);
1288bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      __ CallRuntime(Runtime::kThrowReferenceError);
128959151504615d929945dc59db37bf1166937748c6Steve Block    }
1290589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    __ jmp(done);
129159151504615d929945dc59db37bf1166937748c6Steve Block  }
129259151504615d929945dc59db37bf1166937748c6Steve Block}
129359151504615d929945dc59db37bf1166937748c6Steve Block
129459151504615d929945dc59db37bf1166937748c6Steve Block
1295014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid FullCodeGenerator::EmitGlobalVariableLoad(VariableProxy* proxy,
1296014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                               TypeofMode typeof_mode) {
129713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch#ifdef DEBUG
1298014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Variable* var = proxy->var();
1299014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(var->IsUnallocatedOrGlobalSlot() ||
1300014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch         (var->IsLookupSlot() && var->mode() == DYNAMIC_GLOBAL));
130113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch#endif
130213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  __ mov(LoadGlobalDescriptor::SlotRegister(),
1303014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch         Operand(SmiFromSlot(proxy->VariableFeedbackSlot())));
130413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  CallLoadGlobalIC(typeof_mode);
1305014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1306014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1307014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1308014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy,
1309014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                         TypeofMode typeof_mode) {
13103fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  // Record position before possible IC call.
1311014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  SetExpressionPosition(proxy);
1312bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  PrepareForBailoutForId(proxy->BeforeId(), BailoutState::NO_REGISTERS);
13133fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  Variable* var = proxy->var();
13143fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
1315589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  // Three cases: global variables, lookup variables, and all other types of
1316589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  // variables.
1317589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  switch (var->location()) {
1318014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case VariableLocation::GLOBAL:
1319014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case VariableLocation::UNALLOCATED: {
1320b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Comment cmnt(masm_, "[ Global variable");
1321014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      EmitGlobalVariableLoad(proxy, typeof_mode);
1322589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      context()->Plug(r0);
1323589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      break;
1324589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    }
132559151504615d929945dc59db37bf1166937748c6Steve Block
1326014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case VariableLocation::PARAMETER:
1327014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case VariableLocation::LOCAL:
1328014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case VariableLocation::CONTEXT: {
1329014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      DCHECK_EQ(NOT_INSIDE_TYPEOF, typeof_mode);
1330b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Comment cmnt(masm_, var->IsContextSlot() ? "[ Context variable"
1331b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                               : "[ Stack variable");
1332014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (NeedsHoleCheckForLoad(proxy)) {
1333014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        // Let and const need a read barrier.
1334014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        GetVar(r0, var);
1335014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ CompareRoot(r0, Heap::kTheHoleValueRootIndex);
1336014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        if (var->mode() == LET || var->mode() == CONST) {
1337014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          // Throw a reference error when using an uninitialized let/const
1338014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          // binding in harmony mode.
1339014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          Label done;
1340014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          __ b(ne, &done);
1341014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          __ mov(r0, Operand(var->name()));
1342014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          __ push(r0);
1343014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          __ CallRuntime(Runtime::kThrowReferenceError);
1344014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          __ bind(&done);
1345589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        }
1346014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        context()->Plug(r0);
1347014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        break;
1348589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      }
13493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      context()->Plug(var);
1350589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      break;
1351589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    }
1352d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
1353014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case VariableLocation::LOOKUP: {
1354b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Comment cmnt(masm_, "[ Lookup variable");
1355589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      Label done, slow;
1356589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      // Generate code for loading from variables potentially shadowed
1357589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      // by eval-introduced variables.
1358014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      EmitDynamicLookupFastCase(proxy, typeof_mode, &slow, &done);
1359589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      __ bind(&slow);
1360109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      __ Push(var->name());
1361014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Runtime::FunctionId function_id =
1362014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          typeof_mode == NOT_INSIDE_TYPEOF
1363014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch              ? Runtime::kLoadLookupSlot
1364109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch              : Runtime::kLoadLookupSlotInsideTypeof;
1365014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ CallRuntime(function_id);
136669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch      __ bind(&done);
136769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch      context()->Plug(r0);
13680d5e116f6aee03185f237311a943491bb079a768Kristian Monsen    }
13693ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  }
13703ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block}
13713ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
13723ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
1373014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid FullCodeGenerator::EmitAccessor(ObjectLiteralProperty* property) {
1374014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Expression* expression = (property == NULL) ? NULL : property->value();
13753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (expression == NULL) {
13763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    __ LoadRoot(r1, Heap::kNullValueRootIndex);
1377109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    PushOperand(r1);
13783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  } else {
13793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    VisitForStackValue(expression);
1380014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (NeedsHomeObject(expression)) {
1381014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      DCHECK(property->kind() == ObjectLiteral::Property::GETTER ||
1382014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch             property->kind() == ObjectLiteral::Property::SETTER);
1383014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      int offset = property->kind() == ObjectLiteral::Property::GETTER ? 2 : 3;
1384014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      EmitSetHomeObject(expression, offset, property->GetSlot());
1385014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
13863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
13873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
13883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
13893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1390d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
1391d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  Comment cmnt(masm_, "[ ObjectLiteral");
1392b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
13933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<FixedArray> constant_properties = expr->constant_properties();
1394b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  __ ldr(r3, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
13956ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  __ mov(r2, Operand(Smi::FromInt(expr->literal_index())));
13963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  __ mov(r1, Operand(constant_properties));
1397014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int flags = expr->ComputeFlags();
139844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  __ mov(r0, Operand(Smi::FromInt(flags)));
1399014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (MustCreateObjectLiteralWithRuntime(expr)) {
1400b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    __ Push(r3, r2, r1, r0);
1401014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    __ CallRuntime(Runtime::kCreateObjectLiteral);
14023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  } else {
1403014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    FastCloneShallowObjectStub stub(isolate(), expr->properties_count());
14043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    __ CallStub(&stub);
1405bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    RestoreContext();
1406d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  }
1407bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  PrepareForBailoutForId(expr->CreateLiteralId(), BailoutState::TOS_REGISTER);
1408d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
1409e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  // If result_saved is true the result is on top of the stack.  If
1410e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  // result_saved is false the result is in r0.
1411d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  bool result_saved = false;
1412d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
1413b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  AccessorTable accessor_table(zone());
1414014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int property_index = 0;
1415014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (; property_index < expr->properties()->length(); property_index++) {
1416014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    ObjectLiteral::Property* property = expr->properties()->at(property_index);
1417014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (property->is_computed_name()) break;
1418d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    if (property->IsCompileTimeValue()) continue;
1419d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
1420014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Literal* key = property->key()->AsLiteral();
1421d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    Expression* value = property->value();
1422d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    if (!result_saved) {
1423109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      PushOperand(r0);  // Save result on stack
1424d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block      result_saved = true;
1425d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    }
1426d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    switch (property->kind()) {
1427d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block      case ObjectLiteral::Property::CONSTANT:
1428d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block        UNREACHABLE();
1429e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke      case ObjectLiteral::Property::MATERIALIZED_LITERAL:
1430b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        DCHECK(!CompileTimeValue::IsCompileTimeValue(property->value()));
1431e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke        // Fall through.
1432d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block      case ObjectLiteral::Property::COMPUTED:
1433958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        // It is safe to use [[Put]] here because the boilerplate already
1434958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        // contains computed properties with an uninitialized value.
1435b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        if (key->value()->IsInternalizedString()) {
14363e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu          if (property->emit_store()) {
1437b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch            VisitForAccumulatorValue(value);
1438b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            DCHECK(StoreDescriptor::ValueRegister().is(r0));
1439b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            __ mov(StoreDescriptor::NameRegister(), Operand(key->value()));
1440b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            __ ldr(StoreDescriptor::ReceiverRegister(), MemOperand(sp));
1441014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            EmitLoadStoreICSlot(property->GetSlot(0));
1442014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            CallStoreIC();
1443bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch            PrepareForBailoutForId(key->id(), BailoutState::NO_REGISTERS);
1444958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1445958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier            if (NeedsHomeObject(value)) {
1446014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch              EmitSetHomeObjectAccumulator(value, 0, property->GetSlot(1));
1447958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier            }
1448b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch          } else {
1449b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch            VisitForEffect(value);
14503e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu          }
1451d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block          break;
1452d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block        }
1453e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke        // Duplicate receiver on stack.
1454e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke        __ ldr(r0, MemOperand(sp));
1455109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        PushOperand(r0);
14560d5e116f6aee03185f237311a943491bb079a768Kristian Monsen        VisitForStackValue(key);
14570d5e116f6aee03185f237311a943491bb079a768Kristian Monsen        VisitForStackValue(value);
14583e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu        if (property->emit_store()) {
1459014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          if (NeedsHomeObject(value)) {
1460014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            EmitSetHomeObject(value, 2, property->GetSlot());
1461014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          }
1462b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          __ mov(r0, Operand(Smi::FromInt(SLOPPY)));  // PropertyAttributes
1463109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch          PushOperand(r0);
1464109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch          CallRuntimeWithOperands(Runtime::kSetProperty);
14653e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu        } else {
1466109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch          DropOperands(3);
14673e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu        }
1468d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block        break;
1469b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      case ObjectLiteral::Property::PROTOTYPE:
1470b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        // Duplicate receiver on stack.
1471b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        __ ldr(r0, MemOperand(sp));
1472109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        PushOperand(r0);
1473b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        VisitForStackValue(value);
1474014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        DCHECK(property->emit_store());
1475109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        CallRuntimeWithOperands(Runtime::kInternalSetPrototype);
1476014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        PrepareForBailoutForId(expr->GetIdForPropertySet(property_index),
1477bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                               BailoutState::NO_REGISTERS);
1478b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        break;
1479b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1480e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke      case ObjectLiteral::Property::GETTER:
1481014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        if (property->emit_store()) {
148213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch          AccessorTable::Iterator it = accessor_table.lookup(key);
148313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch          it->second->bailout_id = expr->GetIdForPropertySet(property_index);
148413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch          it->second->getter = property;
1485014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        }
14863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        break;
1487d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block      case ObjectLiteral::Property::SETTER:
1488014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        if (property->emit_store()) {
148913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch          AccessorTable::Iterator it = accessor_table.lookup(key);
149013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch          it->second->bailout_id = expr->GetIdForPropertySet(property_index);
149113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch          it->second->setter = property;
1492014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        }
1493d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block        break;
1494d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    }
1495d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  }
1496e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
14973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Emit code to define accessors, using only a single call to the runtime for
14983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // each pair of corresponding getters and setters.
14993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  for (AccessorTable::Iterator it = accessor_table.begin();
15003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch       it != accessor_table.end();
15013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch       ++it) {
15023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    __ ldr(r0, MemOperand(sp));  // Duplicate receiver.
1503109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    PushOperand(r0);
15043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    VisitForStackValue(it->first);
15053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    EmitAccessor(it->second->getter);
15063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    EmitAccessor(it->second->setter);
15073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    __ mov(r0, Operand(Smi::FromInt(NONE)));
1508109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    PushOperand(r0);
1509109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    CallRuntimeWithOperands(Runtime::kDefineAccessorPropertyUnchecked);
151013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    PrepareForBailoutForId(it->second->bailout_id, BailoutState::NO_REGISTERS);
1511014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1512014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1513014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Object literals have two parts. The "static" part on the left contains no
1514014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // computed property names, and so we can compute its map ahead of time; see
1515014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // runtime.cc::CreateObjectLiteralBoilerplate. The second "dynamic" part
1516014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // starts with the first computed property name, and continues with all
1517014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // properties to its right.  All the code from above initializes the static
1518014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // component of the object literal, and arranges for the map of the result to
1519014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // reflect the static order in which the keys appear. For the dynamic
1520014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // properties, we compile them into a series of "SetOwnProperty" runtime
1521014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // calls. This will preserve insertion order.
1522014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (; property_index < expr->properties()->length(); property_index++) {
1523014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    ObjectLiteral::Property* property = expr->properties()->at(property_index);
1524014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1525014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Expression* value = property->value();
1526014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (!result_saved) {
1527109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      PushOperand(r0);  // Save result on the stack
1528014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      result_saved = true;
1529014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1530014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1531014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    __ ldr(r0, MemOperand(sp));  // Duplicate receiver.
1532109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    PushOperand(r0);
1533014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1534014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (property->kind() == ObjectLiteral::Property::PROTOTYPE) {
1535014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      DCHECK(!property->is_computed_name());
1536014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      VisitForStackValue(value);
1537014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      DCHECK(property->emit_store());
1538109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      CallRuntimeWithOperands(Runtime::kInternalSetPrototype);
1539014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      PrepareForBailoutForId(expr->GetIdForPropertySet(property_index),
1540bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                             BailoutState::NO_REGISTERS);
1541014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    } else {
1542014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      EmitPropertyKey(property, expr->GetIdForPropertyName(property_index));
1543014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      VisitForStackValue(value);
1544014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (NeedsHomeObject(value)) {
1545014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        EmitSetHomeObject(value, 2, property->GetSlot());
1546014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
1547014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1548014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      switch (property->kind()) {
1549014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        case ObjectLiteral::Property::CONSTANT:
1550014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        case ObjectLiteral::Property::MATERIALIZED_LITERAL:
1551014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        case ObjectLiteral::Property::COMPUTED:
1552014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          if (property->emit_store()) {
1553109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch            PushOperand(Smi::FromInt(NONE));
1554109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch            PushOperand(Smi::FromInt(property->NeedsSetFunctionName()));
1555109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch            CallRuntimeWithOperands(Runtime::kDefineDataPropertyInLiteral);
155613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch            PrepareForBailoutForId(expr->GetIdForPropertySet(property_index),
155713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch                                   BailoutState::NO_REGISTERS);
1558014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          } else {
1559109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch            DropOperands(3);
1560014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          }
1561014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          break;
1562014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1563014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        case ObjectLiteral::Property::PROTOTYPE:
1564014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          UNREACHABLE();
1565014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          break;
1566014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1567014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        case ObjectLiteral::Property::GETTER:
1568109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch          PushOperand(Smi::FromInt(NONE));
1569109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch          CallRuntimeWithOperands(Runtime::kDefineGetterPropertyUnchecked);
1570014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          break;
1571014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1572014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        case ObjectLiteral::Property::SETTER:
1573109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch          PushOperand(Smi::FromInt(NONE));
1574109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch          CallRuntimeWithOperands(Runtime::kDefineSetterPropertyUnchecked);
1575014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          break;
1576014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
1577014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
15783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
15793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1580e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  if (result_saved) {
15810d5e116f6aee03185f237311a943491bb079a768Kristian Monsen    context()->PlugTOS();
1582e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  } else {
15830d5e116f6aee03185f237311a943491bb079a768Kristian Monsen    context()->Plug(r0);
15843ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  }
15853ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block}
15863ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
15873ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
1588d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) {
15893ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  Comment cmnt(masm_, "[ ArrayLiteral");
1590f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke
15913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<FixedArray> constant_elements = expr->constant_elements();
1592014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool has_fast_elements =
1593014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      IsFastObjectElementsKind(expr->constant_elements_kind());
15943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<FixedArrayBase> constant_elements_values(
15953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      FixedArrayBase::cast(constant_elements->get(1)));
1596f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke
1597b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  AllocationSiteMode allocation_site_mode = TRACK_ALLOCATION_SITE;
1598b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (has_fast_elements && !FLAG_allocation_site_pretenuring) {
1599b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // If the only customer of allocation sites is transitioning, then
1600b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // we can turn it off if we don't have anywhere else to transition to.
1601b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    allocation_site_mode = DONT_TRACK_ALLOCATION_SITE;
1602b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1603b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
16043ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  __ ldr(r3, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
16053ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  __ mov(r2, Operand(Smi::FromInt(expr->literal_index())));
16063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  __ mov(r1, Operand(constant_elements));
1607014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (MustCreateArrayLiteralWithRuntime(expr)) {
1608014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    __ mov(r0, Operand(Smi::FromInt(expr->ComputeFlags())));
1609b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    __ Push(r3, r2, r1, r0);
1610014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    __ CallRuntime(Runtime::kCreateArrayLiteral);
1611f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  } else {
1612b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    FastCloneShallowArrayStub stub(isolate(), allocation_site_mode);
1613f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke    __ CallStub(&stub);
16143ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  }
1615bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  PrepareForBailoutForId(expr->CreateLiteralId(), BailoutState::TOS_REGISTER);
16163ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
16173ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  bool result_saved = false;  // Is the result saved to the stack?
1618014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  ZoneList<Expression*>* subexprs = expr->values();
1619014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int length = subexprs->length();
16203ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
16213ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  // Emit code to evaluate all the non-constant subexpressions and to store
16223ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  // them into the newly cloned array.
1623014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int array_index = 0;
1624014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (; array_index < length; array_index++) {
1625014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Expression* subexpr = subexprs->at(array_index);
1626109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    DCHECK(!subexpr->IsSpread());
1627014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
16283ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block    // If the subexpression is a literal or a simple materialized literal it
16293ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block    // is already set in the cloned array.
1630b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (CompileTimeValue::IsCompileTimeValue(subexpr)) continue;
16313ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
16323ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block    if (!result_saved) {
1633109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      PushOperand(r0);
16343ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block      result_saved = true;
16353ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block    }
16360d5e116f6aee03185f237311a943491bb079a768Kristian Monsen    VisitForAccumulatorValue(subexpr);
16373ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
1638014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    __ mov(StoreDescriptor::NameRegister(), Operand(Smi::FromInt(array_index)));
1639014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    __ ldr(StoreDescriptor::ReceiverRegister(), MemOperand(sp, 0));
1640014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    EmitLoadStoreICSlot(expr->LiteralFeedbackSlot());
1641014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Handle<Code> ic =
1642014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        CodeFactory::KeyedStoreIC(isolate(), language_mode()).code();
1643014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    CallIC(ic);
1644014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1645bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    PrepareForBailoutForId(expr->GetIdForElement(array_index),
1646bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                           BailoutState::NO_REGISTERS);
1647014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1648014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1649014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // In case the array literal contains spread expressions it has two parts. The
1650014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // first part is  the "static" array which has a literal index is  handled
1651014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // above. The second part is the part after the first spread expression
1652014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // (inclusive) and these elements gets appended to the array. Note that the
1653014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // number elements an iterable produces is unknown ahead of time.
1654014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (array_index < length && result_saved) {
1655109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    PopOperand(r0);
1656014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    result_saved = false;
1657014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1658014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (; array_index < length; array_index++) {
1659014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Expression* subexpr = subexprs->at(array_index);
1660014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1661109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    PushOperand(r0);
1662109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    DCHECK(!subexpr->IsSpread());
1663109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    VisitForStackValue(subexpr);
1664109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    CallRuntimeWithOperands(Runtime::kAppendElement);
1665b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1666bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    PrepareForBailoutForId(expr->GetIdForElement(array_index),
1667bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                           BailoutState::NO_REGISTERS);
16683ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  }
16693ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
1670e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  if (result_saved) {
16710d5e116f6aee03185f237311a943491bb079a768Kristian Monsen    context()->PlugTOS();
1672e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  } else {
16730d5e116f6aee03185f237311a943491bb079a768Kristian Monsen    context()->Plug(r0);
16743ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  }
16753ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block}
16763ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
16773ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
1678402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescuvoid FullCodeGenerator::VisitAssignment(Assignment* expr) {
1679014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(expr->target()->IsValidReferenceExpressionOrThis());
1680b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1681402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  Comment cmnt(masm_, "[ Assignment");
1682f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke
168380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  Property* property = expr->target()->AsProperty();
1684014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  LhsKind assign_type = Property::GetAssignType(property);
1685402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
1686402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  // Evaluate LHS expression.
1687402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  switch (assign_type) {
1688402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu    case VARIABLE:
1689402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu      // Nothing to do here.
1690402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu      break;
1691402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu    case NAMED_PROPERTY:
1692402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu      if (expr->is_compound()) {
1693b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        // We need the receiver both on the stack and in the register.
1694b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        VisitForStackValue(property->obj());
1695b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        __ ldr(LoadDescriptor::ReceiverRegister(), MemOperand(sp, 0));
1696402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu      } else {
16970d5e116f6aee03185f237311a943491bb079a768Kristian Monsen        VisitForStackValue(property->obj());
1698402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu      }
1699402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu      break;
1700958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    case NAMED_SUPER_PROPERTY:
1701014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      VisitForStackValue(
1702014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          property->obj()->AsSuperPropertyReference()->this_var());
1703014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      VisitForAccumulatorValue(
1704014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          property->obj()->AsSuperPropertyReference()->home_object());
1705109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      PushOperand(result_register());
1706958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      if (expr->is_compound()) {
1707958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        const Register scratch = r1;
1708958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        __ ldr(scratch, MemOperand(sp, kPointerSize));
1709109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        PushOperand(scratch);
1710109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        PushOperand(result_register());
1711958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      }
1712958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      break;
1713958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    case KEYED_SUPER_PROPERTY:
1714014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      VisitForStackValue(
1715014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          property->obj()->AsSuperPropertyReference()->this_var());
1716014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      VisitForStackValue(
1717014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          property->obj()->AsSuperPropertyReference()->home_object());
1718958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      VisitForAccumulatorValue(property->key());
1719109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      PushOperand(result_register());
1720958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      if (expr->is_compound()) {
1721958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        const Register scratch = r1;
1722958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        __ ldr(scratch, MemOperand(sp, 2 * kPointerSize));
1723109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        PushOperand(scratch);
1724958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        __ ldr(scratch, MemOperand(sp, 2 * kPointerSize));
1725109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        PushOperand(scratch);
1726109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        PushOperand(result_register());
1727958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      }
1728958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      break;
1729402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu    case KEYED_PROPERTY:
173025f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen      if (expr->is_compound()) {
17313fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch        VisitForStackValue(property->obj());
1732b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        VisitForStackValue(property->key());
1733b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        __ ldr(LoadDescriptor::ReceiverRegister(),
1734b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch               MemOperand(sp, 1 * kPointerSize));
1735b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        __ ldr(LoadDescriptor::NameRegister(), MemOperand(sp, 0));
173625f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen      } else {
17373fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch        VisitForStackValue(property->obj());
17383fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch        VisitForStackValue(property->key());
173925f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen      }
1740402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu      break;
1741402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  }
1742402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
17438b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  // For compound assignments we need another deoptimization point after the
17448b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  // variable/property load.
1745402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  if (expr->is_compound()) {
17460d5e116f6aee03185f237311a943491bb079a768Kristian Monsen    { AccumulatorValueContext context(this);
17470d5e116f6aee03185f237311a943491bb079a768Kristian Monsen      switch (assign_type) {
17480d5e116f6aee03185f237311a943491bb079a768Kristian Monsen        case VARIABLE:
17493fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch          EmitVariableLoad(expr->target()->AsVariableProxy());
1750bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch          PrepareForBailout(expr->target(), BailoutState::TOS_REGISTER);
17510d5e116f6aee03185f237311a943491bb079a768Kristian Monsen          break;
17520d5e116f6aee03185f237311a943491bb079a768Kristian Monsen        case NAMED_PROPERTY:
17530d5e116f6aee03185f237311a943491bb079a768Kristian Monsen          EmitNamedPropertyLoad(property);
1754bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch          PrepareForBailoutForId(property->LoadId(),
1755bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                                 BailoutState::TOS_REGISTER);
17560d5e116f6aee03185f237311a943491bb079a768Kristian Monsen          break;
1757958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        case NAMED_SUPER_PROPERTY:
1758958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier          EmitNamedSuperPropertyLoad(property);
1759bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch          PrepareForBailoutForId(property->LoadId(),
1760bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                                 BailoutState::TOS_REGISTER);
1761958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier          break;
1762958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        case KEYED_SUPER_PROPERTY:
1763958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier          EmitKeyedSuperPropertyLoad(property);
1764bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch          PrepareForBailoutForId(property->LoadId(),
1765bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                                 BailoutState::TOS_REGISTER);
1766958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier          break;
17670d5e116f6aee03185f237311a943491bb079a768Kristian Monsen        case KEYED_PROPERTY:
17680d5e116f6aee03185f237311a943491bb079a768Kristian Monsen          EmitKeyedPropertyLoad(property);
1769bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch          PrepareForBailoutForId(property->LoadId(),
1770bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                                 BailoutState::TOS_REGISTER);
17710d5e116f6aee03185f237311a943491bb079a768Kristian Monsen          break;
17720d5e116f6aee03185f237311a943491bb079a768Kristian Monsen      }
1773402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu    }
1774402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
177580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen    Token::Value op = expr->binary_op();
1776109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    PushOperand(r0);  // Left operand goes on the stack.
1777e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch    VisitForAccumulatorValue(expr->value());
1778402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
17790d5e116f6aee03185f237311a943491bb079a768Kristian Monsen    AccumulatorValueContext context(this);
178080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen    if (ShouldInlineSmiCase(op)) {
1781257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      EmitInlineSmiBinaryOp(expr->binary_operation(),
178280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen                            op,
178380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen                            expr->target(),
1784e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch                            expr->value());
178580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen    } else {
1786014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      EmitBinaryOp(expr->binary_operation(), op);
178780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen    }
1788b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1789b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    // Deoptimization point in case the binary operation may have side effects.
1790bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    PrepareForBailout(expr->binary_operation(), BailoutState::TOS_REGISTER);
179180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  } else {
17920d5e116f6aee03185f237311a943491bb079a768Kristian Monsen    VisitForAccumulatorValue(expr->value());
1793402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  }
1794402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
1795014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  SetExpressionPosition(expr);
1796402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
1797402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  // Store the value.
1798402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  switch (assign_type) {
1799402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu    case VARIABLE:
1800402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu      EmitVariableAssignment(expr->target()->AsVariableProxy()->var(),
1801014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                             expr->op(), expr->AssignmentSlot());
1802bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER);
1803b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      context()->Plug(r0);
1804402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu      break;
1805402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu    case NAMED_PROPERTY:
1806402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu      EmitNamedPropertyAssignment(expr);
1807402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu      break;
1808958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    case NAMED_SUPER_PROPERTY:
1809958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      EmitNamedSuperPropertyStore(property);
1810958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      context()->Plug(r0);
1811958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      break;
1812958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    case KEYED_SUPER_PROPERTY:
1813958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      EmitKeyedSuperPropertyStore(property);
1814958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      context()->Plug(r0);
1815958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      break;
1816402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu    case KEYED_PROPERTY:
1817402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu      EmitKeyedPropertyAssignment(expr);
1818402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu      break;
1819402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  }
1820402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu}
1821402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
1822402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
1823b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid FullCodeGenerator::VisitYield(Yield* expr) {
1824b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Comment cmnt(masm_, "[ Yield");
1825014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  SetExpressionPosition(expr);
1826014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1827b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Evaluate yielded value first; the initial iterator definition depends on
1828b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // this.  It stays on the stack while we update the iterator.
1829b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  VisitForStackValue(expr->expression());
1830e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
1831bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  Label suspend, continuation, post_runtime, resume, exception;
18323b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
18333b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  __ jmp(&suspend);
18343b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  __ bind(&continuation);
1835bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  // When we arrive here, r0 holds the generator object.
18363b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  __ RecordGeneratorContinuation();
1837bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  __ ldr(r1, FieldMemOperand(r0, JSGeneratorObject::kResumeModeOffset));
183813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  __ ldr(r0, FieldMemOperand(r0, JSGeneratorObject::kInputOrDebugPosOffset));
1839bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  STATIC_ASSERT(JSGeneratorObject::kNext < JSGeneratorObject::kReturn);
1840bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  STATIC_ASSERT(JSGeneratorObject::kThrow > JSGeneratorObject::kReturn);
1841bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  __ cmp(r1, Operand(Smi::FromInt(JSGeneratorObject::kReturn)));
1842bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  __ b(lt, &resume);
1843bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  __ Push(result_register());
1844bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  __ b(gt, &exception);
18453b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  EmitCreateIteratorResult(true);
18463b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  EmitUnwindAndReturn();
18473b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
1848bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  __ bind(&exception);
1849bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  __ CallRuntime(Runtime::kThrow);
1850bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
18513b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  __ bind(&suspend);
18523b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  OperandStackDepthIncrement(1);  // Not popped on this path.
18533b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  VisitForAccumulatorValue(expr->generator_object());
18543b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  DCHECK(continuation.pos() > 0 && Smi::IsValid(continuation.pos()));
18553b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  __ mov(r1, Operand(Smi::FromInt(continuation.pos())));
18563b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  __ str(r1, FieldMemOperand(r0, JSGeneratorObject::kContinuationOffset));
18573b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  __ str(cp, FieldMemOperand(r0, JSGeneratorObject::kContextOffset));
18583b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  __ mov(r1, cp);
18593b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  __ RecordWriteField(r0, JSGeneratorObject::kContextOffset, r1, r2,
18603b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                      kLRHasBeenSaved, kDontSaveFPRegs);
18613b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  __ add(r1, fp, Operand(StandardFrameConstants::kExpressionsOffset));
18623b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  __ cmp(sp, r1);
18633b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  __ b(eq, &post_runtime);
18643b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  __ push(r0);  // generator object
18653b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  __ CallRuntime(Runtime::kSuspendJSGeneratorObject, 1);
1866bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  RestoreContext();
18673b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  __ bind(&post_runtime);
18683b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  PopOperand(result_register());
18693b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  EmitReturnSequence();
1870e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
18713b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  __ bind(&resume);
18723b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  context()->Plug(result_register());
1873b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1874e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
1875109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochvoid FullCodeGenerator::PushOperands(Register reg1, Register reg2) {
1876109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  OperandStackDepthIncrement(2);
1877109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  __ Push(reg1, reg2);
1878109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch}
1879109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
1880109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochvoid FullCodeGenerator::PopOperands(Register reg1, Register reg2) {
1881109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  OperandStackDepthDecrement(2);
1882109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  __ Pop(reg1, reg2);
1883109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch}
1884109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
1885109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochvoid FullCodeGenerator::EmitOperandStackDepthCheck() {
1886109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  if (FLAG_debug_code) {
1887109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    int expected_diff = StandardFrameConstants::kFixedFrameSizeFromFp +
1888109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch                        operand_stack_depth_ * kPointerSize;
1889109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    __ sub(r0, fp, sp);
1890109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    __ cmp(r0, Operand(expected_diff));
1891109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    __ Assert(eq, kUnexpectedStackDepth);
1892109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  }
1893109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch}
1894b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1895b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid FullCodeGenerator::EmitCreateIteratorResult(bool done) {
1896014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Label allocate, done_allocate;
1897014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1898bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  __ Allocate(JSIteratorResult::kSize, r0, r2, r3, &allocate,
1899bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch              NO_ALLOCATION_FLAGS);
1900014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  __ b(&done_allocate);
1901014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1902014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  __ bind(&allocate);
1903014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  __ Push(Smi::FromInt(JSIteratorResult::kSize));
1904014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  __ CallRuntime(Runtime::kAllocateInNewSpace);
1905014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1906014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  __ bind(&done_allocate);
1907014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  __ LoadNativeContextSlot(Context::ITERATOR_RESULT_MAP_INDEX, r1);
19083b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  PopOperand(r2);
1909014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  __ LoadRoot(r3,
1910014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch              done ? Heap::kTrueValueRootIndex : Heap::kFalseValueRootIndex);
1911014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  __ LoadRoot(r4, Heap::kEmptyFixedArrayRootIndex);
1912b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  __ str(r1, FieldMemOperand(r0, HeapObject::kMapOffset));
1913b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  __ str(r4, FieldMemOperand(r0, JSObject::kPropertiesOffset));
1914b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  __ str(r4, FieldMemOperand(r0, JSObject::kElementsOffset));
1915014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  __ str(r2, FieldMemOperand(r0, JSIteratorResult::kValueOffset));
1916014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  __ str(r3, FieldMemOperand(r0, JSIteratorResult::kDoneOffset));
1917b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1918b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1919b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1920b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr,
1921b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                              Token::Value op,
1922b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                              Expression* left_expr,
1923b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                              Expression* right_expr) {
1924b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Label done, smi_case, stub_call;
1925b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1926b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Register scratch1 = r2;
1927b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Register scratch2 = r3;
1928b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1929b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Get the arguments.
1930b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Register left = r1;
1931b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Register right = r0;
1932109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  PopOperand(left);
1933b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1934b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Perform combined smi check on both operands.
1935b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  __ orr(scratch1, left, Operand(right));
1936b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  STATIC_ASSERT(kSmiTag == 0);
1937b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  JumpPatchSite patch_site(masm_);
1938b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  patch_site.EmitJumpIfSmi(scratch1, &smi_case);
1939b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1940b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  __ bind(&stub_call);
1941109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), op).code();
1942b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CallIC(code, expr->BinaryOperationFeedbackId());
1943b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  patch_site.EmitPatchInfo();
1944b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  __ jmp(&done);
1945b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1946b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  __ bind(&smi_case);
1947b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Smi case. This code works the same way as the smi-smi case in the type
1948b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // recording binary operation stub, see
1949b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  switch (op) {
1950b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case Token::SAR:
1951b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      __ GetLeastBitsFromSmi(scratch1, right, 5);
1952e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch      __ mov(right, Operand(left, ASR, scratch1));
1953e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch      __ bic(right, right, Operand(kSmiTagMask));
1954e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch      break;
1955e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch    case Token::SHL: {
1956e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch      __ SmiUntag(scratch1, left);
1957e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch      __ GetLeastBitsFromSmi(scratch2, right, 5);
1958e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch      __ mov(scratch1, Operand(scratch1, LSL, scratch2));
1959b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      __ TrySmiTag(right, scratch1, &stub_call);
1960e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch      break;
1961e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch    }
1962e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch    case Token::SHR: {
1963e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch      __ SmiUntag(scratch1, left);
1964e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch      __ GetLeastBitsFromSmi(scratch2, right, 5);
1965e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch      __ mov(scratch1, Operand(scratch1, LSR, scratch2));
1966e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch      __ tst(scratch1, Operand(0xc0000000));
1967e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch      __ b(ne, &stub_call);
1968e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch      __ SmiTag(right, scratch1);
1969e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch      break;
1970e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch    }
1971e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch    case Token::ADD:
1972e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch      __ add(scratch1, left, Operand(right), SetCC);
1973e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch      __ b(vs, &stub_call);
1974e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch      __ mov(right, scratch1);
1975e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch      break;
1976e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch    case Token::SUB:
1977e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch      __ sub(scratch1, left, Operand(right), SetCC);
1978e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch      __ b(vs, &stub_call);
1979e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch      __ mov(right, scratch1);
1980e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch      break;
1981e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch    case Token::MUL: {
1982e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch      __ SmiUntag(ip, right);
1983e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch      __ smull(scratch1, scratch2, left, ip);
1984e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch      __ mov(ip, Operand(scratch1, ASR, 31));
1985e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch      __ cmp(ip, Operand(scratch2));
1986e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch      __ b(ne, &stub_call);
1987b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      __ cmp(scratch1, Operand::Zero());
1988e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch      __ mov(right, Operand(scratch1), LeaveCC, ne);
1989e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch      __ b(ne, &done);
1990e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch      __ add(scratch2, right, Operand(left), SetCC);
1991e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch      __ mov(right, Operand(Smi::FromInt(0)), LeaveCC, pl);
1992e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch      __ b(mi, &stub_call);
1993e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch      break;
1994e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch    }
1995e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch    case Token::BIT_OR:
1996e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch      __ orr(right, left, Operand(right));
1997e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch      break;
1998e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch    case Token::BIT_AND:
1999e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch      __ and_(right, left, Operand(right));
2000e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch      break;
2001e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch    case Token::BIT_XOR:
2002e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch      __ eor(right, left, Operand(right));
2003e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch      break;
2004e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch    default:
2005e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch      UNREACHABLE();
2006e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  }
2007e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
2008e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  __ bind(&done);
2009e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  context()->Plug(r0);
201080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen}
201180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen
201280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen
2013958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid FullCodeGenerator::EmitClassDefineProperties(ClassLiteral* lit) {
2014958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  for (int i = 0; i < lit->properties()->length(); i++) {
2015958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    ObjectLiteral::Property* property = lit->properties()->at(i);
2016958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    Expression* value = property->value();
2017958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
2018109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    Register scratch = r1;
2019958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    if (property->is_static()) {
2020958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      __ ldr(scratch, MemOperand(sp, kPointerSize));  // constructor
2021958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    } else {
2022958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      __ ldr(scratch, MemOperand(sp, 0));  // prototype
2023958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    }
2024109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    PushOperand(scratch);
2025014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    EmitPropertyKey(property, lit->GetIdForProperty(i));
2026014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2027014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // The static prototype property is read only. We handle the non computed
2028014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // property name case in the parser. Since this is the only case where we
2029014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // need to check for an own read only property we special case this so we do
2030014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // not need to do this for every property.
2031014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (property->is_static() && property->is_computed_name()) {
2032014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ CallRuntime(Runtime::kThrowIfStaticPrototype);
2033014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ push(r0);
2034014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
2035014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2036958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    VisitForStackValue(value);
2037014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (NeedsHomeObject(value)) {
2038014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      EmitSetHomeObject(value, 2, property->GetSlot());
2039014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
2040958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
2041958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    switch (property->kind()) {
2042958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      case ObjectLiteral::Property::CONSTANT:
2043958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      case ObjectLiteral::Property::MATERIALIZED_LITERAL:
2044958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      case ObjectLiteral::Property::PROTOTYPE:
2045014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        UNREACHABLE();
2046014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      case ObjectLiteral::Property::COMPUTED:
2047109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        PushOperand(Smi::FromInt(DONT_ENUM));
2048109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        PushOperand(Smi::FromInt(property->NeedsSetFunctionName()));
2049109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        CallRuntimeWithOperands(Runtime::kDefineDataPropertyInLiteral);
2050958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        break;
2051958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
2052958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      case ObjectLiteral::Property::GETTER:
2053109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        PushOperand(Smi::FromInt(DONT_ENUM));
2054109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        CallRuntimeWithOperands(Runtime::kDefineGetterPropertyUnchecked);
2055958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        break;
2056958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
2057958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      case ObjectLiteral::Property::SETTER:
2058109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        PushOperand(Smi::FromInt(DONT_ENUM));
2059109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        CallRuntimeWithOperands(Runtime::kDefineSetterPropertyUnchecked);
2060958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        break;
2061958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
2062958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      default:
2063958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        UNREACHABLE();
2064958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    }
2065958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
2066958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
2067958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
2068958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
2069014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr, Token::Value op) {
2070109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  PopOperand(r1);
2071109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), op).code();
20723fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  JumpPatchSite patch_site(masm_);    // unbound, signals no inlined smi code.
2073b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CallIC(code, expr->BinaryOperationFeedbackId());
20743fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  patch_site.EmitPatchInfo();
20750d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  context()->Plug(r0);
2076e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke}
2077e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
2078e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
2079014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid FullCodeGenerator::EmitAssignment(Expression* expr,
2080014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                       FeedbackVectorSlot slot) {
2081014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(expr->IsValidReferenceExpressionOrThis());
2082f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke
2083f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  Property* prop = expr->AsProperty();
2084014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  LhsKind assign_type = Property::GetAssignType(prop);
2085f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke
2086f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  switch (assign_type) {
2087f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke    case VARIABLE: {
2088f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke      Variable* var = expr->AsVariableProxy()->var();
20890d5e116f6aee03185f237311a943491bb079a768Kristian Monsen      EffectContext context(this);
2090014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      EmitVariableAssignment(var, Token::ASSIGN, slot);
2091f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke      break;
2092f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke    }
2093f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke    case NAMED_PROPERTY: {
2094109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      PushOperand(r0);  // Preserve value.
20950d5e116f6aee03185f237311a943491bb079a768Kristian Monsen      VisitForAccumulatorValue(prop->obj());
2096b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      __ Move(StoreDescriptor::ReceiverRegister(), r0);
2097109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      PopOperand(StoreDescriptor::ValueRegister());  // Restore value.
2098b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      __ mov(StoreDescriptor::NameRegister(),
2099b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch             Operand(prop->key()->AsLiteral()->value()));
2100014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      EmitLoadStoreICSlot(slot);
2101b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      CallStoreIC();
2102f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke      break;
2103f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke    }
2104958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    case NAMED_SUPER_PROPERTY: {
2105109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      PushOperand(r0);
2106014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var());
2107014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      VisitForAccumulatorValue(
2108014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          prop->obj()->AsSuperPropertyReference()->home_object());
2109958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      // stack: value, this; r0: home_object
2110958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      Register scratch = r2;
2111958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      Register scratch2 = r3;
2112958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      __ mov(scratch, result_register());              // home_object
2113958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      __ ldr(r0, MemOperand(sp, kPointerSize));        // value
2114958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      __ ldr(scratch2, MemOperand(sp, 0));             // this
2115958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      __ str(scratch2, MemOperand(sp, kPointerSize));  // this
2116958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      __ str(scratch, MemOperand(sp, 0));              // home_object
2117958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      // stack: this, home_object; r0: value
2118958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      EmitNamedSuperPropertyStore(prop);
2119958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      break;
2120958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    }
2121958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    case KEYED_SUPER_PROPERTY: {
2122109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      PushOperand(r0);
2123014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var());
2124014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      VisitForStackValue(
2125014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          prop->obj()->AsSuperPropertyReference()->home_object());
2126958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      VisitForAccumulatorValue(prop->key());
2127958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      Register scratch = r2;
2128958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      Register scratch2 = r3;
2129958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      __ ldr(scratch2, MemOperand(sp, 2 * kPointerSize));  // value
2130958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      // stack: value, this, home_object; r0: key, r3: value
2131958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      __ ldr(scratch, MemOperand(sp, kPointerSize));  // this
2132958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      __ str(scratch, MemOperand(sp, 2 * kPointerSize));
2133958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      __ ldr(scratch, MemOperand(sp, 0));  // home_object
2134958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      __ str(scratch, MemOperand(sp, kPointerSize));
2135958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      __ str(r0, MemOperand(sp, 0));
2136958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      __ Move(r0, scratch2);
2137958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      // stack: this, home_object, key; r0: value.
2138958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      EmitKeyedSuperPropertyStore(prop);
2139958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      break;
2140958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    }
2141f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke    case KEYED_PROPERTY: {
2142109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      PushOperand(r0);  // Preserve value.
21433fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      VisitForStackValue(prop->obj());
21443fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      VisitForAccumulatorValue(prop->key());
2145b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      __ Move(StoreDescriptor::NameRegister(), r0);
2146109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      PopOperands(StoreDescriptor::ValueRegister(),
2147109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch                  StoreDescriptor::ReceiverRegister());
2148014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      EmitLoadStoreICSlot(slot);
2149b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Handle<Code> ic =
2150014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          CodeFactory::KeyedStoreIC(isolate(), language_mode()).code();
21513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      CallIC(ic);
2152f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke      break;
2153f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke    }
2154f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  }
2155b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  context()->Plug(r0);
2156f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke}
2157f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke
2158f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke
2159b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid FullCodeGenerator::EmitStoreToStackLocalOrContextSlot(
2160b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Variable* var, MemOperand location) {
2161b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  __ str(result_register(), location);
2162b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (var->IsContextSlot()) {
2163b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // RecordWrite may destroy all its register arguments.
2164b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    __ mov(r3, result_register());
2165b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    int offset = Context::SlotOffset(var->index());
2166b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    __ RecordWriteContextSlot(
2167b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        r1, offset, r3, r2, kLRHasBeenSaved, kDontSaveFPRegs);
2168b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2169b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2170b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2171b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2172014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid FullCodeGenerator::EmitVariableAssignment(Variable* var, Token::Value op,
2173014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                               FeedbackVectorSlot slot) {
2174589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  if (var->IsUnallocated()) {
2175589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    // Global var, const, or let.
2176b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    __ mov(StoreDescriptor::NameRegister(), Operand(var->name()));
2177014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    __ LoadGlobalObject(StoreDescriptor::ReceiverRegister());
2178014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    EmitLoadStoreICSlot(slot);
2179b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CallStoreIC();
2180b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2181014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else if (var->mode() == LET && op != Token::INIT) {
2182589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    // Non-initializing assignment to let variable needs a write barrier.
2183b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(!var->IsLookupSlot());
2184b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(var->IsStackAllocated() || var->IsContextSlot());
2185b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Label assign;
2186b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    MemOperand location = VarOperand(var, r1);
2187b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    __ ldr(r3, location);
2188b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    __ CompareRoot(r3, Heap::kTheHoleValueRootIndex);
2189b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    __ b(ne, &assign);
2190b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    __ mov(r3, Operand(var->name()));
2191b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    __ push(r3);
2192014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    __ CallRuntime(Runtime::kThrowReferenceError);
2193b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Perform the assignment.
2194b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    __ bind(&assign);
2195b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    EmitStoreToStackLocalOrContextSlot(var, location);
2196b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2197014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else if (var->mode() == CONST && op != Token::INIT) {
2198014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // Assignment to const variable needs a write barrier.
2199014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK(!var->IsLookupSlot());
2200014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK(var->IsStackAllocated() || var->IsContextSlot());
2201014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Label const_error;
2202014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    MemOperand location = VarOperand(var, r1);
2203014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    __ ldr(r3, location);
2204014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    __ CompareRoot(r3, Heap::kTheHoleValueRootIndex);
2205014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    __ b(ne, &const_error);
2206014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    __ mov(r3, Operand(var->name()));
2207014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    __ push(r3);
2208014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    __ CallRuntime(Runtime::kThrowReferenceError);
2209014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    __ bind(&const_error);
2210014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    __ CallRuntime(Runtime::kThrowConstAssignError);
2211014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2212014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else if (var->is_this() && var->mode() == CONST && op == Token::INIT) {
2213014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // Initializing assignment to const {this} needs a write barrier.
2214014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK(var->IsStackAllocated() || var->IsContextSlot());
2215014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Label uninitialized_this;
2216014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    MemOperand location = VarOperand(var, r1);
2217014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    __ ldr(r3, location);
2218014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    __ CompareRoot(r3, Heap::kTheHoleValueRootIndex);
2219014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    __ b(eq, &uninitialized_this);
2220014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    __ mov(r0, Operand(var->name()));
2221014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    __ Push(r0);
2222014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    __ CallRuntime(Runtime::kThrowReferenceError);
2223014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    __ bind(&uninitialized_this);
2224014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    EmitStoreToStackLocalOrContextSlot(var, location);
2225014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2226bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  } else if (!var->is_const_mode() || op == Token::INIT) {
2227014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (var->IsLookupSlot()) {
2228014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // Assignment to var.
2229109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      __ Push(var->name());
2230109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      __ Push(r0);
2231109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      __ CallRuntime(is_strict(language_mode())
2232109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch                         ? Runtime::kStoreLookupSlot_Strict
2233109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch                         : Runtime::kStoreLookupSlot_Sloppy);
2234014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    } else {
2235014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // Assignment to var or initializing assignment to let/const in harmony
2236014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // mode.
2237014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      DCHECK((var->IsStackAllocated() || var->IsContextSlot()));
2238014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      MemOperand location = VarOperand(var, r1);
2239109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      if (FLAG_debug_code && var->mode() == LET && op == Token::INIT) {
2240014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        // Check for an uninitialized let binding.
2241589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        __ ldr(r2, location);
2242589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        __ CompareRoot(r2, Heap::kTheHoleValueRootIndex);
2243b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        __ Check(eq, kLetBindingReInitialization);
2244589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      }
2245b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      EmitStoreToStackLocalOrContextSlot(var, location);
22463ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block    }
2247014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2248014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else {
2249014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK(var->mode() == CONST_LEGACY && op != Token::INIT);
2250014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (is_strict(language_mode())) {
2251014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ CallRuntime(Runtime::kThrowConstAssignError);
2252014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
2253014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // Silently ignore store in sloppy mode.
22543ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  }
22553ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block}
22563ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
22573ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
2258d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) {
2259d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  // Assignment to a property, using a named store IC.
2260d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  Property* prop = expr->target()->AsProperty();
2261b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(prop != NULL);
2262b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(prop->key()->IsLiteral());
2263d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
2264b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  __ mov(StoreDescriptor::NameRegister(),
2265b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch         Operand(prop->key()->AsLiteral()->value()));
2266109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  PopOperand(StoreDescriptor::ReceiverRegister());
2267014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  EmitLoadStoreICSlot(expr->AssignmentSlot());
2268014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  CallStoreIC();
2269d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
2270bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER);
2271b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  context()->Plug(r0);
2272d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block}
2273d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
2274d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
2275958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid FullCodeGenerator::EmitNamedSuperPropertyStore(Property* prop) {
2276958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  // Assignment to named property of super.
2277958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  // r0 : value
2278958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  // stack : receiver ('this'), home_object
2279958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  DCHECK(prop != NULL);
2280958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  Literal* key = prop->key()->AsLiteral();
2281958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  DCHECK(key != NULL);
2282958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
2283109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  PushOperand(key->value());
2284109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  PushOperand(r0);
2285109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  CallRuntimeWithOperands(is_strict(language_mode())
2286109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch                              ? Runtime::kStoreToSuper_Strict
2287109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch                              : Runtime::kStoreToSuper_Sloppy);
2288958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
2289958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
2290958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
2291958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid FullCodeGenerator::EmitKeyedSuperPropertyStore(Property* prop) {
2292958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  // Assignment to named property of super.
2293958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  // r0 : value
2294958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  // stack : receiver ('this'), home_object, key
2295958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  DCHECK(prop != NULL);
2296958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
2297109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  PushOperand(r0);
2298109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  CallRuntimeWithOperands(is_strict(language_mode())
2299109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch                              ? Runtime::kStoreKeyedToSuper_Strict
2300109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch                              : Runtime::kStoreKeyedToSuper_Sloppy);
2301958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
2302958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
2303958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
2304d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) {
2305d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  // Assignment to a property, using a keyed store IC.
2306109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  PopOperands(StoreDescriptor::ReceiverRegister(),
2307109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch              StoreDescriptor::NameRegister());
2308b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(StoreDescriptor::ValueRegister().is(r0));
2309f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke
2310014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Handle<Code> ic =
2311014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      CodeFactory::KeyedStoreIC(isolate(), language_mode()).code();
2312014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  EmitLoadStoreICSlot(expr->AssignmentSlot());
2313014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  CallIC(ic);
2314d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
2315bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER);
2316014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  context()->Plug(r0);
2317d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block}
2318d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
23193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
23203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid FullCodeGenerator::CallIC(Handle<Code> code,
2321b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                               TypeFeedbackId ast_id) {
23223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  ic_total_count_++;
2323b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // All calls must have a predictable size in full-codegen code to ensure that
2324b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // the debugger can patch them correctly.
2325b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  __ Call(code, RelocInfo::CODE_TARGET, ast_id, al,
2326b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          NEVER_INLINE_TARGET_ADDRESS);
23273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
23283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
2329b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2330b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Code common for calls using the IC.
2331b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid FullCodeGenerator::EmitCallWithLoadIC(Call* expr) {
2332b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Expression* callee = expr->expression();
2333b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2334b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Get the target function.
2335014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  ConvertReceiverMode convert_mode;
2336014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (callee->IsVariableProxy()) {
2337b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    { StackValueContext context(this);
2338b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      EmitVariableLoad(callee->AsVariableProxy());
2339bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      PrepareForBailout(callee, BailoutState::NO_REGISTERS);
23403e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu    }
2341b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Push undefined as receiver. This is patched in the method prologue if it
2342b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // is a sloppy mode method.
2343014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    __ LoadRoot(ip, Heap::kUndefinedValueRootIndex);
2344109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    PushOperand(ip);
2345014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    convert_mode = ConvertReceiverMode::kNullOrUndefined;
2346b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
2347b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Load the function from the receiver.
2348b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(callee->IsProperty());
2349b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(!callee->AsProperty()->IsSuperAccess());
2350b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    __ ldr(LoadDescriptor::ReceiverRegister(), MemOperand(sp, 0));
2351b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    EmitNamedPropertyLoad(callee->AsProperty());
2352bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    PrepareForBailoutForId(callee->AsProperty()->LoadId(),
2353bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                           BailoutState::TOS_REGISTER);
2354b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Push the target function under the receiver.
2355b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    __ ldr(ip, MemOperand(sp, 0));
2356109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    PushOperand(ip);
2357b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    __ str(r0, MemOperand(sp, kPointerSize));
2358014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    convert_mode = ConvertReceiverMode::kNotNullOrUndefined;
23593ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  }
2360b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2361014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  EmitCall(expr, convert_mode);
2362d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block}
2363d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
2364d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
2365b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid FullCodeGenerator::EmitSuperCallWithLoadIC(Call* expr) {
2366b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Expression* callee = expr->expression();
2367b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(callee->IsProperty());
2368b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Property* prop = callee->AsProperty();
2369b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(prop->IsSuperAccess());
2370014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  SetExpressionPosition(prop);
2371b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2372b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Literal* key = prop->key()->AsLiteral();
2373b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(!key->value()->IsSmi());
2374b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Load the function from the receiver.
2375b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const Register scratch = r1;
2376014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  SuperPropertyReference* super_ref = prop->obj()->AsSuperPropertyReference();
2377014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  VisitForStackValue(super_ref->home_object());
2378b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  VisitForAccumulatorValue(super_ref->this_var());
2379109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  PushOperand(r0);
2380109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  PushOperand(r0);
2381958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  __ ldr(scratch, MemOperand(sp, kPointerSize * 2));
2382109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  PushOperand(scratch);
2383109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  PushOperand(key->value());
2384b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2385b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Stack here:
2386b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  //  - home_object
2387b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  //  - this (receiver)
2388958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  //  - this (receiver) <-- LoadFromSuper will pop here and below.
2389958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  //  - home_object
2390b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  //  - key
2391109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  CallRuntimeWithOperands(Runtime::kLoadFromSuper);
2392bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  PrepareForBailoutForId(prop->LoadId(), BailoutState::TOS_REGISTER);
2393b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2394b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Replace home_object with target function.
2395b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  __ str(r0, MemOperand(sp, kPointerSize));
2396b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2397b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Stack here:
2398b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // - target function
2399b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // - this (receiver)
2400014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  EmitCall(expr);
2401b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2402b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2403b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2404b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Code common for calls using the IC.
2405b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid FullCodeGenerator::EmitKeyedCallWithLoadIC(Call* expr,
2406b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                                Expression* key) {
24078a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  // Load the key.
24088a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  VisitForAccumulatorValue(key);
24098a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
2410b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Expression* callee = expr->expression();
24118a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
2412b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Load the function from the receiver.
2413b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(callee->IsProperty());
2414b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  __ ldr(LoadDescriptor::ReceiverRegister(), MemOperand(sp, 0));
2415b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  __ Move(LoadDescriptor::NameRegister(), r0);
2416b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EmitKeyedPropertyLoad(callee->AsProperty());
2417bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  PrepareForBailoutForId(callee->AsProperty()->LoadId(),
2418bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                         BailoutState::TOS_REGISTER);
2419b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2420b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Push the target function under the receiver.
2421b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  __ ldr(ip, MemOperand(sp, 0));
2422109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  PushOperand(ip);
2423b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  __ str(r0, MemOperand(sp, kPointerSize));
2424b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2425014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  EmitCall(expr, ConvertReceiverMode::kNotNullOrUndefined);
24269dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen}
24279dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen
24289dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen
2429958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid FullCodeGenerator::EmitKeyedSuperCallWithLoadIC(Call* expr) {
2430958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  Expression* callee = expr->expression();
2431958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  DCHECK(callee->IsProperty());
2432958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  Property* prop = callee->AsProperty();
2433958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  DCHECK(prop->IsSuperAccess());
2434958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
2435014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  SetExpressionPosition(prop);
2436958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  // Load the function from the receiver.
2437958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  const Register scratch = r1;
2438014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  SuperPropertyReference* super_ref = prop->obj()->AsSuperPropertyReference();
2439014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  VisitForStackValue(super_ref->home_object());
2440958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  VisitForAccumulatorValue(super_ref->this_var());
2441109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  PushOperand(r0);
2442109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  PushOperand(r0);
2443958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  __ ldr(scratch, MemOperand(sp, kPointerSize * 2));
2444109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  PushOperand(scratch);
2445958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  VisitForStackValue(prop->key());
2446958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
2447958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  // Stack here:
2448958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  //  - home_object
2449958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  //  - this (receiver)
2450958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  //  - this (receiver) <-- LoadKeyedFromSuper will pop here and below.
2451958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  //  - home_object
2452958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  //  - key
2453109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  CallRuntimeWithOperands(Runtime::kLoadKeyedFromSuper);
2454bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  PrepareForBailoutForId(prop->LoadId(), BailoutState::TOS_REGISTER);
2455958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
2456958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  // Replace home_object with target function.
2457958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  __ str(r0, MemOperand(sp, kPointerSize));
2458958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
2459958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  // Stack here:
2460958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  // - target function
2461958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  // - this (receiver)
2462014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  EmitCall(expr);
2463958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
2464958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
2465958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
2466014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid FullCodeGenerator::EmitCall(Call* expr, ConvertReceiverMode mode) {
2467b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Load the arguments.
2468d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  ZoneList<Expression*>* args = expr->arguments();
2469d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  int arg_count = args->length();
2470014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (int i = 0; i < arg_count; i++) {
2471014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    VisitForStackValue(args->at(i));
2472d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  }
2473b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2474bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  PrepareForBailoutForId(expr->CallId(), BailoutState::NO_REGISTERS);
24753b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  SetCallPosition(expr, expr->tail_call_mode());
2476109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  if (expr->tail_call_mode() == TailCallMode::kAllow) {
2477109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    if (FLAG_trace) {
2478109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      __ CallRuntime(Runtime::kTraceTailCall);
2479109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    }
2480109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    // Update profiling counters before the tail call since we will
2481109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    // not return to this function.
2482109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    EmitProfilingCounterHandlingForReturnSequence(true);
2483109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  }
2484109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  Handle<Code> ic =
2485109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      CodeFactory::CallIC(isolate(), arg_count, mode, expr->tail_call_mode())
2486109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch          .code();
2487014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  __ mov(r3, Operand(SmiFromSlot(expr->CallFeedbackICSlot())));
24883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  __ ldr(r1, MemOperand(sp, (arg_count + 1) * kPointerSize));
2489b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Don't assign a type feedback id to the IC, since type feedback is provided
2490b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // by the vector above.
2491b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CallIC(ic);
2492109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  OperandStackDepthDecrement(arg_count + 1);
2493b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2494b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  RecordJSReturnSite(expr);
2495bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  RestoreContext();
24960d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  context()->DropAndPlug(1, r0);
2497d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block}
2498d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
2499bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdochvoid FullCodeGenerator::EmitResolvePossiblyDirectEval(Call* expr) {
2500bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  int arg_count = expr->arguments()->length();
2501014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // r4: copy of the first argument or undefined if it doesn't exist.
2502e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  if (arg_count > 0) {
2503014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    __ ldr(r4, MemOperand(sp, arg_count * kPointerSize));
2504e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  } else {
2505014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    __ LoadRoot(r4, Heap::kUndefinedValueRootIndex);
2506e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  }
2507e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
2508b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // r3: the receiver of the enclosing function.
2509014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  __ ldr(r3, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
2510b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2511014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // r2: language mode.
2512014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  __ mov(r2, Operand(Smi::FromInt(language_mode())));
2513e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
2514b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // r1: the start position of the scope the calls resides in.
25153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  __ mov(r1, Operand(Smi::FromInt(scope()->start_position())));
25163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
2517bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  // r0: the source position of the eval call.
2518bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  __ mov(r0, Operand(Smi::FromInt(expr->position())));
2519bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
25203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Do the runtime call.
2521bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  __ Push(r4, r3, r2, r1, r0);
2522014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  __ CallRuntime(Runtime::kResolvePossiblyDirectEval);
2523958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
2524958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
2525958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
2526014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// See http://www.ecma-international.org/ecma-262/6.0/#sec-function-calls.
2527014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid FullCodeGenerator::PushCalleeAndWithBaseObject(Call* expr) {
2528014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  VariableProxy* callee = expr->expression()->AsVariableProxy();
2529014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (callee->var()->IsLookupSlot()) {
253059151504615d929945dc59db37bf1166937748c6Steve Block    Label slow, done;
2531014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    SetExpressionPosition(callee);
2532014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // Generate code for loading from variables potentially shadowed
2533014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // by eval-introduced variables.
2534014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    EmitDynamicLookupFastCase(callee, NOT_INSIDE_TYPEOF, &slow, &done);
253559151504615d929945dc59db37bf1166937748c6Steve Block
253659151504615d929945dc59db37bf1166937748c6Steve Block    __ bind(&slow);
25370d5e116f6aee03185f237311a943491bb079a768Kristian Monsen    // Call the runtime to find the function to call (returned in r0)
253859151504615d929945dc59db37bf1166937748c6Steve Block    // and the object holding it (returned in edx).
2539109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    __ Push(callee->name());
2540109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    __ CallRuntime(Runtime::kLoadLookupSlotForCall);
2541109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    PushOperands(r0, r1);  // Function, receiver.
2542bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    PrepareForBailoutForId(expr->LookupId(), BailoutState::NO_REGISTERS);
254359151504615d929945dc59db37bf1166937748c6Steve Block
254459151504615d929945dc59db37bf1166937748c6Steve Block    // If fast case code has been generated, emit code to push the
254559151504615d929945dc59db37bf1166937748c6Steve Block    // function and receiver and have the slow path jump around this
254659151504615d929945dc59db37bf1166937748c6Steve Block    // code.
254759151504615d929945dc59db37bf1166937748c6Steve Block    if (done.is_linked()) {
254859151504615d929945dc59db37bf1166937748c6Steve Block      Label call;
254959151504615d929945dc59db37bf1166937748c6Steve Block      __ b(&call);
255059151504615d929945dc59db37bf1166937748c6Steve Block      __ bind(&done);
255159151504615d929945dc59db37bf1166937748c6Steve Block      // Push function.
255259151504615d929945dc59db37bf1166937748c6Steve Block      __ push(r0);
25533fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      // The receiver is implicitly the global receiver. Indicate this
25543fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      // by passing the hole to the call function stub.
2555b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      __ LoadRoot(r1, Heap::kUndefinedValueRootIndex);
255659151504615d929945dc59db37bf1166937748c6Steve Block      __ push(r1);
255759151504615d929945dc59db37bf1166937748c6Steve Block      __ bind(&call);
255859151504615d929945dc59db37bf1166937748c6Steve Block    }
25593ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  } else {
2560014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    VisitForStackValue(callee);
2561014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // refEnv.WithBaseObject()
2562014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    __ LoadRoot(r2, Heap::kUndefinedValueRootIndex);
2563109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    PushOperand(r2);  // Reserved receiver slot.
25643ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  }
2565014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2566b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2567014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2568014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid FullCodeGenerator::EmitPossiblyEvalCall(Call* expr) {
2569014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // In a call to eval, we first call
2570bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  // Runtime_ResolvePossiblyDirectEval to resolve the function we need
2571014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // to call.  Then we call the resolved function using the given arguments.
2572014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  ZoneList<Expression*>* args = expr->arguments();
2573014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int arg_count = args->length();
2574014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2575014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  PushCalleeAndWithBaseObject(expr);
2576014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2577014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Push the arguments.
2578014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (int i = 0; i < arg_count; i++) {
2579014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    VisitForStackValue(args->at(i));
2580014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2581014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2582014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Push a copy of the function (found below the arguments) and
2583014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // resolve eval.
2584014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  __ ldr(r1, MemOperand(sp, (arg_count + 1) * kPointerSize));
2585014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  __ push(r1);
2586bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  EmitResolvePossiblyDirectEval(expr);
2587014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2588014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Touch up the stack with the resolved function.
2589014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  __ str(r0, MemOperand(sp, (arg_count + 1) * kPointerSize));
2590014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2591bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  PrepareForBailoutForId(expr->EvalId(), BailoutState::NO_REGISTERS);
2592014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2593014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Record source position for debugger.
2594014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  SetCallPosition(expr);
2595014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  __ ldr(r1, MemOperand(sp, (arg_count + 1) * kPointerSize));
2596014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  __ mov(r0, Operand(arg_count));
2597109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  __ Call(isolate()->builtins()->Call(ConvertReceiverMode::kAny,
2598109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch                                      expr->tail_call_mode()),
2599109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch          RelocInfo::CODE_TARGET);
2600109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  OperandStackDepthDecrement(arg_count + 1);
2601014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  RecordJSReturnSite(expr);
2602bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  RestoreContext();
2603014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  context()->DropAndPlug(1, r0);
26043ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block}
26053ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
26063ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
2607d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::VisitCallNew(CallNew* expr) {
2608d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  Comment cmnt(masm_, "[ CallNew");
2609d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  // According to ECMA-262, section 11.2.2, page 44, the function
2610d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  // expression in new calls must be evaluated before the
2611d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  // arguments.
261280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen
261380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  // Push constructor on the stack.  If it's not a function it's used as
261480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  // receiver for CALL_NON_FUNCTION, otherwise the value on the stack is
261580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  // ignored.
2616014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(!expr->expression()->IsSuperPropertyReference());
2617014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  VisitForStackValue(expr->expression());
2618d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
2619d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  // Push the arguments ("left-to-right") on the stack.
2620d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  ZoneList<Expression*>* args = expr->arguments();
2621d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  int arg_count = args->length();
2622d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  for (int i = 0; i < arg_count; i++) {
26230d5e116f6aee03185f237311a943491bb079a768Kristian Monsen    VisitForStackValue(args->at(i));
2624d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  }
2625d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
2626d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  // Call the construct call builtin that handles allocation and
2627d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  // constructor invocation.
2628014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  SetConstructCallPosition(expr);
2629d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
263080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  // Load function and argument count into r1 and r0.
2631d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  __ mov(r0, Operand(arg_count));
263280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  __ ldr(r1, MemOperand(sp, arg_count * kPointerSize));
2633d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
2634b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Record call targets in unoptimized code.
2635014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  __ EmitLoadTypeFeedbackVector(r2);
2636958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  __ mov(r3, Operand(SmiFromSlot(expr->CallNewFeedbackSlot())));
2637b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2638014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  CallConstructStub stub(isolate());
2639014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  __ Call(stub.GetCode(), RelocInfo::CODE_TARGET);
2640109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  OperandStackDepthDecrement(arg_count + 1);
2641bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  PrepareForBailoutForId(expr->ReturnId(), BailoutState::TOS_REGISTER);
2642bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  RestoreContext();
26430d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  context()->Plug(r0);
2644d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block}
2645d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
2646d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
2647014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid FullCodeGenerator::EmitSuperConstructorCall(Call* expr) {
2648014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  SuperCallReference* super_call_ref =
2649014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      expr->expression()->AsSuperCallReference();
2650014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK_NOT_NULL(super_call_ref);
2651f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke
2652014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Push the super constructor target on the stack (may be null,
2653014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // but the Construct builtin can deal with that properly).
2654014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  VisitForAccumulatorValue(super_call_ref->this_function_var());
2655014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  __ AssertFunction(result_register());
2656014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  __ ldr(result_register(),
2657014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch         FieldMemOperand(result_register(), HeapObject::kMapOffset));
2658014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  __ ldr(result_register(),
2659014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch         FieldMemOperand(result_register(), Map::kPrototypeOffset));
2660109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  PushOperand(result_register());
2661f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke
2662014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Push the arguments ("left-to-right") on the stack.
2663014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  ZoneList<Expression*>* args = expr->arguments();
2664014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int arg_count = args->length();
2665014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (int i = 0; i < arg_count; i++) {
2666014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    VisitForStackValue(args->at(i));
2667014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2668f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke
2669014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Call the construct call builtin that handles allocation and
2670014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // constructor invocation.
2671014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  SetConstructCallPosition(expr);
2672f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke
2673014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Load new target into r3.
2674014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  VisitForAccumulatorValue(super_call_ref->new_target_var());
2675014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  __ mov(r3, result_register());
2676f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke
2677014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Load function and argument count into r1 and r0.
2678014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  __ mov(r0, Operand(arg_count));
2679014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  __ ldr(r1, MemOperand(sp, arg_count * kPointerSize));
2680f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke
2681014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  __ Call(isolate()->builtins()->Construct(), RelocInfo::CODE_TARGET);
2682109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  OperandStackDepthDecrement(arg_count + 1);
2683f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke
2684014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  RecordJSReturnSite(expr);
2685bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  RestoreContext();
2686014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  context()->Plug(r0);
2687f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke}
2688f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke
2689f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke
2690014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid FullCodeGenerator::EmitIsSmi(CallRuntime* expr) {
26913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  ZoneList<Expression*>* args = expr->arguments();
2692b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(args->length() == 1);
2693f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke
26940d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  VisitForAccumulatorValue(args->at(0));
2695f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke
2696f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  Label materialize_true, materialize_false;
2697f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  Label* if_true = NULL;
2698f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  Label* if_false = NULL;
269980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  Label* fall_through = NULL;
27000d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  context()->PrepareTest(&materialize_true, &materialize_false,
27010d5e116f6aee03185f237311a943491bb079a768Kristian Monsen                         &if_true, &if_false, &fall_through);
270280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen
27033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
2704014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  __ SmiTst(r0);
2705014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Split(eq, if_true, if_false, fall_through);
2706f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke
27070d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  context()->Plug(if_true, if_false);
2708f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke}
2709f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke
2710f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke
2711014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid FullCodeGenerator::EmitIsJSReceiver(CallRuntime* expr) {
27123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  ZoneList<Expression*>* args = expr->arguments();
2713b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(args->length() == 1);
27143bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch
27150d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  VisitForAccumulatorValue(args->at(0));
27163bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch
27173bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch  Label materialize_true, materialize_false;
27183bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch  Label* if_true = NULL;
27193bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch  Label* if_false = NULL;
272080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  Label* fall_through = NULL;
27210d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  context()->PrepareTest(&materialize_true, &materialize_false,
27220d5e116f6aee03185f237311a943491bb079a768Kristian Monsen                         &if_true, &if_false, &fall_through);
27233bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch
27241e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  __ JumpIfSmi(r0, if_false);
2725014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  __ CompareObjectType(r0, r1, r1, FIRST_JS_RECEIVER_TYPE);
27263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
272780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  Split(ge, if_true, if_false, fall_through);
27283bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch
27290d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  context()->Plug(if_true, if_false);
27303bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch}
27313bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch
27323bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch
27333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid FullCodeGenerator::EmitIsArray(CallRuntime* expr) {
27343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  ZoneList<Expression*>* args = expr->arguments();
2735b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(args->length() == 1);
2736f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke
27370d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  VisitForAccumulatorValue(args->at(0));
2738f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke
2739f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  Label materialize_true, materialize_false;
2740f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  Label* if_true = NULL;
2741f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  Label* if_false = NULL;
274280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  Label* fall_through = NULL;
27430d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  context()->PrepareTest(&materialize_true, &materialize_false,
27440d5e116f6aee03185f237311a943491bb079a768Kristian Monsen                         &if_true, &if_false, &fall_through);
2745f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke
27461e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  __ JumpIfSmi(r0, if_false);
2747f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  __ CompareObjectType(r0, r1, r1, JS_ARRAY_TYPE);
27483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
274980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  Split(eq, if_true, if_false, fall_through);
2750f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke
27510d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  context()->Plug(if_true, if_false);
2752f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke}
2753f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke
2754f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke
2755014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid FullCodeGenerator::EmitIsTypedArray(CallRuntime* expr) {
27563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  ZoneList<Expression*>* args = expr->arguments();
2757b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(args->length() == 1);
2758f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke
27590d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  VisitForAccumulatorValue(args->at(0));
2760f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke
2761f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  Label materialize_true, materialize_false;
2762f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  Label* if_true = NULL;
2763f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  Label* if_false = NULL;
276480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  Label* fall_through = NULL;
2765014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  context()->PrepareTest(&materialize_true, &materialize_false, &if_true,
2766014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                         &if_false, &fall_through);
2767f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke
27681e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  __ JumpIfSmi(r0, if_false);
2769014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  __ CompareObjectType(r0, r1, r1, JS_TYPED_ARRAY_TYPE);
27703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
277180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  Split(eq, if_true, if_false, fall_through);
2772f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke
27730d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  context()->Plug(if_true, if_false);
2774f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke}
2775f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke
2776f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke
2777014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid FullCodeGenerator::EmitIsRegExp(CallRuntime* expr) {
2778958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  ZoneList<Expression*>* args = expr->arguments();
2779958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  DCHECK(args->length() == 1);
2780958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
2781958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  VisitForAccumulatorValue(args->at(0));
2782958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
2783958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  Label materialize_true, materialize_false;
2784958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  Label* if_true = NULL;
2785958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  Label* if_false = NULL;
2786958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  Label* fall_through = NULL;
2787014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  context()->PrepareTest(&materialize_true, &materialize_false,
2788014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                         &if_true, &if_false, &fall_through);
2789958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
2790958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  __ JumpIfSmi(r0, if_false);
2791014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  __ CompareObjectType(r0, r1, r1, JS_REGEXP_TYPE);
2792958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
2793014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Split(eq, if_true, if_false, fall_through);
2794958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
2795958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  context()->Plug(if_true, if_false);
2796958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
2797958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
2798f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke
2799014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid FullCodeGenerator::EmitIsJSProxy(CallRuntime* expr) {
2800014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  ZoneList<Expression*>* args = expr->arguments();
2801014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(args->length() == 1);
2802014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2803014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  VisitForAccumulatorValue(args->at(0));
2804f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke
2805f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  Label materialize_true, materialize_false;
2806f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  Label* if_true = NULL;
2807f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  Label* if_false = NULL;
280880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  Label* fall_through = NULL;
2809014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  context()->PrepareTest(&materialize_true, &materialize_false, &if_true,
2810014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                         &if_false, &fall_through);
2811f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke
2812014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  __ JumpIfSmi(r0, if_false);
2813014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  __ CompareObjectType(r0, r1, r1, JS_PROXY_TYPE);
28143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
281580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  Split(eq, if_true, if_false, fall_through);
2816f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke
28170d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  context()->Plug(if_true, if_false);
2818f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke}
2819f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke
2820f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke
28213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid FullCodeGenerator::EmitClassOf(CallRuntime* expr) {
28223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  ZoneList<Expression*>* args = expr->arguments();
2823b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(args->length() == 1);
2824f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  Label done, null, function, non_function_constructor;
2825f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke
28260d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  VisitForAccumulatorValue(args->at(0));
2827f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke
2828014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // If the object is not a JSReceiver, we return null.
28291e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  __ JumpIfSmi(r0, &null);
2830014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  STATIC_ASSERT(LAST_JS_RECEIVER_TYPE == LAST_TYPE);
2831014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  __ CompareObjectType(r0, r0, r1, FIRST_JS_RECEIVER_TYPE);
28323fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  // Map is now in r0.
2833f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  __ b(lt, &null);
28343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
28353b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  // Return 'Function' for JSFunction and JSBoundFunction objects.
28363b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  __ cmp(r1, Operand(FIRST_FUNCTION_TYPE));
28373b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  STATIC_ASSERT(LAST_FUNCTION_TYPE == LAST_TYPE);
28383b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  __ b(hs, &function);
28393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
28403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Check if the constructor in the map is a JS function.
2841014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Register instance_type = r2;
2842014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  __ GetMapConstructor(r0, r0, r1, instance_type);
2843014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  __ cmp(instance_type, Operand(JS_FUNCTION_TYPE));
2844f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  __ b(ne, &non_function_constructor);
2845f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke
2846f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  // r0 now contains the constructor function. Grab the
2847f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  // instance class name from there.
2848f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  __ ldr(r0, FieldMemOperand(r0, JSFunction::kSharedFunctionInfoOffset));
2849f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  __ ldr(r0, FieldMemOperand(r0, SharedFunctionInfo::kInstanceClassNameOffset));
2850f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  __ b(&done);
2851f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke
2852f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  // Functions have class 'Function'.
2853f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  __ bind(&function);
2854b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  __ LoadRoot(r0, Heap::kFunction_stringRootIndex);
2855f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  __ jmp(&done);
2856f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke
2857f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  // Objects with a non-function constructor have class 'Object'.
2858f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  __ bind(&non_function_constructor);
2859b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  __ LoadRoot(r0, Heap::kObject_stringRootIndex);
2860f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  __ jmp(&done);
2861f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke
2862f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  // Non-JS objects have class null.
2863f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  __ bind(&null);
2864f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  __ LoadRoot(r0, Heap::kNullValueRootIndex);
2865f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke
2866f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  // All done.
2867f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  __ bind(&done);
2868f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke
28690d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  context()->Plug(r0);
2870f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke}
2871f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke
2872f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke
28733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid FullCodeGenerator::EmitValueOf(CallRuntime* expr) {
28743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  ZoneList<Expression*>* args = expr->arguments();
2875b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(args->length() == 1);
28760d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  VisitForAccumulatorValue(args->at(0));  // Load the object.
2877f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke
2878f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  Label done;
2879f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  // If the object is a smi return the object.
28801e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  __ JumpIfSmi(r0, &done);
2881f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  // If the object is not a value type, return the object.
2882f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  __ CompareObjectType(r0, r1, r1, JS_VALUE_TYPE);
2883b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  __ ldr(r0, FieldMemOperand(r0, JSValue::kValueOffset), eq);
2884f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke
2885f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  __ bind(&done);
28860d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  context()->Plug(r0);
2887f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke}
2888f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke
2889f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke
28903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid FullCodeGenerator::EmitStringCharFromCode(CallRuntime* expr) {
28913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  ZoneList<Expression*>* args = expr->arguments();
2892b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(args->length() == 1);
28930d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  VisitForAccumulatorValue(args->at(0));
2894f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke
28957f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  Label done;
28967f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  StringCharFromCodeGenerator generator(r0, r1);
28977f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  generator.GenerateFast(masm_);
28987f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  __ jmp(&done);
2899f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke
29007f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  NopRuntimeCallHelper call_helper;
29017f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  generator.GenerateSlow(masm_, call_helper);
2902f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke
2903f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  __ bind(&done);
29040d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  context()->Plug(r1);
2905f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke}
2906f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke
2907f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke
29083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid FullCodeGenerator::EmitStringCharCodeAt(CallRuntime* expr) {
29093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  ZoneList<Expression*>* args = expr->arguments();
2910b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(args->length() == 2);
29110d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  VisitForStackValue(args->at(0));
29120d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  VisitForAccumulatorValue(args->at(1));
29137f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
29147f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  Register object = r1;
29157f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  Register index = r0;
29167f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  Register result = r3;
29177f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
2918109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  PopOperand(object);
29197f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
29207f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  Label need_conversion;
29217f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  Label index_out_of_range;
29227f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  Label done;
292313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  StringCharCodeAtGenerator generator(object, index, result, &need_conversion,
292413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch                                      &need_conversion, &index_out_of_range);
29257f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  generator.GenerateFast(masm_);
29267f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  __ jmp(&done);
29277f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
29287f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  __ bind(&index_out_of_range);
29297f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  // When the index is out of range, the spec requires us to return
29307f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  // NaN.
29317f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  __ LoadRoot(result, Heap::kNanValueRootIndex);
29327f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  __ jmp(&done);
29337f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
29347f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  __ bind(&need_conversion);
29357f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  // Load the undefined value into the result register, which will
29367f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  // trigger conversion.
29377f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  __ LoadRoot(result, Heap::kUndefinedValueRootIndex);
29387f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  __ jmp(&done);
29397f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
29407f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  NopRuntimeCallHelper call_helper;
2941014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  generator.GenerateSlow(masm_, NOT_PART_OF_IC_HANDLER, call_helper);
29427f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
29437f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  __ bind(&done);
29440d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  context()->Plug(result);
29457f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch}
29467f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
29477f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
2948014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid FullCodeGenerator::EmitCall(CallRuntime* expr) {
29493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  ZoneList<Expression*>* args = expr->arguments();
2950014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK_LE(2, args->length());
2951014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Push target, receiver and arguments onto the stack.
2952014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (Expression* const arg : *args) {
2953014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    VisitForStackValue(arg);
2954f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  }
2955bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  PrepareForBailoutForId(expr->CallId(), BailoutState::NO_REGISTERS);
2956014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Move target to r1.
2957014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int const argc = args->length() - 2;
2958014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  __ ldr(r1, MemOperand(sp, (argc + 1) * kPointerSize));
2959014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Call the target.
2960014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  __ mov(r0, Operand(argc));
2961014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  __ Call(isolate()->builtins()->Call(), RelocInfo::CODE_TARGET);
2962109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  OperandStackDepthDecrement(argc + 1);
2963bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  RestoreContext();
2964014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Discard the function left on TOS.
2965014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  context()->DropAndPlug(1, r0);
2966f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke}
2967f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke
2968f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke
29693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid FullCodeGenerator::EmitHasCachedArrayIndex(CallRuntime* expr) {
29703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  ZoneList<Expression*>* args = expr->arguments();
29710d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  VisitForAccumulatorValue(args->at(0));
297280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen
297380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  Label materialize_true, materialize_false;
297480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  Label* if_true = NULL;
297580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  Label* if_false = NULL;
297680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  Label* fall_through = NULL;
29770d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  context()->PrepareTest(&materialize_true, &materialize_false,
29780d5e116f6aee03185f237311a943491bb079a768Kristian Monsen                         &if_true, &if_false, &fall_through);
297980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen
298080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  __ ldr(r0, FieldMemOperand(r0, String::kHashFieldOffset));
298180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  __ tst(r0, Operand(String::kContainsCachedArrayIndexMask));
29823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
2983b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  Split(eq, if_true, if_false, fall_through);
298480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen
29850d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  context()->Plug(if_true, if_false);
298680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen}
298780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen
298880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen
29893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid FullCodeGenerator::EmitGetCachedArrayIndex(CallRuntime* expr) {
29903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  ZoneList<Expression*>* args = expr->arguments();
2991b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(args->length() == 1);
29920d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  VisitForAccumulatorValue(args->at(0));
2993e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
2994b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  __ AssertString(r0);
2995e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
299680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  __ ldr(r0, FieldMemOperand(r0, String::kHashFieldOffset));
299780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  __ IndexFromHash(r0, r0);
2998e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
29990d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  context()->Plug(r0);
300080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen}
300180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen
300280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen
3003014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid FullCodeGenerator::EmitGetSuperConstructor(CallRuntime* expr) {
3004014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  ZoneList<Expression*>* args = expr->arguments();
3005014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK_EQ(1, args->length());
3006014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  VisitForAccumulatorValue(args->at(0));
3007014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  __ AssertFunction(r0);
3008014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  __ ldr(r0, FieldMemOperand(r0, HeapObject::kMapOffset));
3009014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  __ ldr(r0, FieldMemOperand(r0, Map::kPrototypeOffset));
3010014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  context()->Plug(r0);
3011014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
3012014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3013b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid FullCodeGenerator::EmitDebugIsActive(CallRuntime* expr) {
3014b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(expr->arguments()->length() == 0);
3015b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ExternalReference debug_is_active =
3016b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      ExternalReference::debug_is_active_address(isolate());
3017b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  __ mov(ip, Operand(debug_is_active));
3018b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  __ ldrb(r0, MemOperand(ip));
3019b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  __ SmiTag(r0);
3020b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  context()->Plug(r0);
3021b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
3022b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3023b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3024014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid FullCodeGenerator::EmitCreateIterResultObject(CallRuntime* expr) {
3025014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  ZoneList<Expression*>* args = expr->arguments();
3026014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK_EQ(2, args->length());
3027014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  VisitForStackValue(args->at(0));
3028014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  VisitForStackValue(args->at(1));
3029014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3030014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Label runtime, done;
3031014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3032bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  __ Allocate(JSIteratorResult::kSize, r0, r2, r3, &runtime,
3033bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch              NO_ALLOCATION_FLAGS);
3034014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  __ LoadNativeContextSlot(Context::ITERATOR_RESULT_MAP_INDEX, r1);
3035014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  __ pop(r3);
3036014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  __ pop(r2);
3037014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  __ LoadRoot(r4, Heap::kEmptyFixedArrayRootIndex);
3038014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  __ str(r1, FieldMemOperand(r0, HeapObject::kMapOffset));
3039014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  __ str(r4, FieldMemOperand(r0, JSObject::kPropertiesOffset));
3040014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  __ str(r4, FieldMemOperand(r0, JSObject::kElementsOffset));
3041014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  __ str(r2, FieldMemOperand(r0, JSIteratorResult::kValueOffset));
3042014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  __ str(r3, FieldMemOperand(r0, JSIteratorResult::kDoneOffset));
3043014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  STATIC_ASSERT(JSIteratorResult::kSize == 5 * kPointerSize);
3044014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  __ b(&done);
3045014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3046014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  __ bind(&runtime);
3047109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  CallRuntimeWithOperands(Runtime::kCreateIterResultObject);
3048014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3049014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  __ bind(&done);
3050014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  context()->Plug(r0);
3051014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
3052f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke
3053014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3054014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid FullCodeGenerator::EmitLoadJSRuntimeFunction(CallRuntime* expr) {
30553b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  // Push function.
30563b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  __ LoadNativeContextSlot(expr->context_index(), r0);
30573b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  PushOperand(r0);
30583b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
3059014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Push undefined as the receiver.
3060014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  __ LoadRoot(r0, Heap::kUndefinedValueRootIndex);
3061109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  PushOperand(r0);
3062014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
3063014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3064014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3065014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid FullCodeGenerator::EmitCallJSRuntimeFunction(CallRuntime* expr) {
30663ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  ZoneList<Expression*>* args = expr->arguments();
3067b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int arg_count = args->length();
30683ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
3069014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  SetCallPosition(expr);
3070014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  __ ldr(r1, MemOperand(sp, (arg_count + 1) * kPointerSize));
3071014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  __ mov(r0, Operand(arg_count));
3072014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  __ Call(isolate()->builtins()->Call(ConvertReceiverMode::kNullOrUndefined),
3073014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          RelocInfo::CODE_TARGET);
3074109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  OperandStackDepthDecrement(arg_count + 1);
3075bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  RestoreContext();
3076d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block}
3077d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
3078d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
3079d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
3080d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  switch (expr->op()) {
3081f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke    case Token::DELETE: {
3082f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke      Comment cmnt(masm_, "[ UnaryOperation (DELETE)");
3083589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      Property* property = expr->expression()->AsProperty();
3084589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      VariableProxy* proxy = expr->expression()->AsVariableProxy();
3085e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
3086589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      if (property != NULL) {
3087589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        VisitForStackValue(property->obj());
3088589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        VisitForStackValue(property->key());
3089109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        CallRuntimeWithOperands(is_strict(language_mode())
3090109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch                                    ? Runtime::kDeleteProperty_Strict
3091109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch                                    : Runtime::kDeleteProperty_Sloppy);
309269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch        context()->Plug(r0);
3093589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      } else if (proxy != NULL) {
3094589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        Variable* var = proxy->var();
3095014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        // Delete of an unqualified identifier is disallowed in strict mode but
3096014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        // "delete this" is allowed.
3097014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        bool is_this = var->HasThisName(isolate());
3098014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        DCHECK(is_sloppy(language_mode()) || is_this);
3099014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        if (var->IsUnallocatedOrGlobalSlot()) {
3100014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          __ LoadGlobalObject(r2);
3101e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch          __ mov(r1, Operand(var->name()));
3102014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          __ Push(r2, r1);
3103014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          __ CallRuntime(Runtime::kDeleteProperty_Sloppy);
3104e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch          context()->Plug(r0);
3105589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        } else if (var->IsStackAllocated() || var->IsContextSlot()) {
3106e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch          // Result of deleting non-global, non-dynamic variables is false.
3107e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch          // The subexpression does not have side effects.
3108014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          context()->Plug(is_this);
3109e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch        } else {
3110e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch          // Non-global variable.  Call the runtime to try to delete from the
3111e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch          // context where the variable was introduced.
3112109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch          __ Push(var->name());
3113014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          __ CallRuntime(Runtime::kDeleteLookupSlot);
3114e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch          context()->Plug(r0);
3115e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch        }
31161e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block      } else {
3117e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch        // Result of deleting non-property, non-variable reference is true.
3118e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch        // The subexpression may have side effects.
3119e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch        VisitForEffect(expr->expression());
3120e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch        context()->Plug(true);
3121f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke      }
3122f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke      break;
3123f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke    }
3124f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke
3125d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    case Token::VOID: {
3126d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block      Comment cmnt(masm_, "[ UnaryOperation (VOID)");
3127e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke      VisitForEffect(expr->expression());
31280d5e116f6aee03185f237311a943491bb079a768Kristian Monsen      context()->Plug(Heap::kUndefinedValueRootIndex);
3129d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block      break;
3130d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    }
3131d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
3132d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    case Token::NOT: {
3133d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block      Comment cmnt(masm_, "[ UnaryOperation (NOT)");
3134e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch      if (context()->IsEffect()) {
3135e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch        // Unary NOT has no side effects so it's only necessary to visit the
3136e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch        // subexpression.  Match the optimizing compiler by not branching.
3137e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch        VisitForEffect(expr->expression());
31383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      } else if (context()->IsTest()) {
31393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        const TestContext* test = TestContext::cast(context());
31403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        // The labels are swapped for the recursive call.
31413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        VisitForControl(expr->expression(),
31423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                        test->false_label(),
31433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                        test->true_label(),
31443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                        test->fall_through());
31453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        context()->Plug(test->true_label(), test->false_label());
3146e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch      } else {
31473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        // We handle value contexts explicitly rather than simply visiting
31483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        // for control and plugging the control flow into the context,
31493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        // because we need to prepare a pair of extra administrative AST ids
31503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        // for the optimizing compiler.
3151b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        DCHECK(context()->IsAccumulatorValue() || context()->IsStackValue());
31523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        Label materialize_true, materialize_false, done;
31533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        VisitForControl(expr->expression(),
31543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                        &materialize_false,
31553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                        &materialize_true,
31563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                        &materialize_true);
3157109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        if (!context()->IsAccumulatorValue()) OperandStackDepthIncrement(1);
31583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        __ bind(&materialize_true);
3159bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch        PrepareForBailoutForId(expr->MaterializeTrueId(),
3160bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                               BailoutState::NO_REGISTERS);
31613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        __ LoadRoot(r0, Heap::kTrueValueRootIndex);
31623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        if (context()->IsStackValue()) __ push(r0);
31633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        __ jmp(&done);
31643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        __ bind(&materialize_false);
3165bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch        PrepareForBailoutForId(expr->MaterializeFalseId(),
3166bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                               BailoutState::NO_REGISTERS);
31673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        __ LoadRoot(r0, Heap::kFalseValueRootIndex);
31683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        if (context()->IsStackValue()) __ push(r0);
31693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        __ bind(&done);
3170e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch      }
3171d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block      break;
3172d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    }
3173d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
3174d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    case Token::TYPEOF: {
3175d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block      Comment cmnt(masm_, "[ UnaryOperation (TYPEOF)");
3176014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      {
3177014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        AccumulatorValueContext context(this);
31780d5e116f6aee03185f237311a943491bb079a768Kristian Monsen        VisitForTypeofValue(expr->expression());
31790d5e116f6aee03185f237311a943491bb079a768Kristian Monsen      }
3180014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ mov(r3, r0);
3181014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      TypeofStub typeof_stub(isolate());
3182014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ CallStub(&typeof_stub);
31830d5e116f6aee03185f237311a943491bb079a768Kristian Monsen      context()->Plug(r0);
3184d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block      break;
31853ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block    }
3186d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
3187d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    default:
3188d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block      UNREACHABLE();
31893ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  }
3190d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block}
3191d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
3192d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
3193d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
3194014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(expr->expression()->IsValidReferenceExpressionOrThis());
3195b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3196d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  Comment cmnt(masm_, "[ CountOperation");
319780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen
3198e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  Property* prop = expr->expression()->AsProperty();
3199014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  LhsKind assign_type = Property::GetAssignType(prop);
3200e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
3201e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  // Evaluate expression and get value.
3202e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  if (assign_type == VARIABLE) {
3203b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(expr->expression()->AsVariableProxy()->var() != NULL);
32040d5e116f6aee03185f237311a943491bb079a768Kristian Monsen    AccumulatorValueContext context(this);
32053fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    EmitVariableLoad(expr->expression()->AsVariableProxy());
32063ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  } else {
3207e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke    // Reserve space for result of postfix operation.
32080d5e116f6aee03185f237311a943491bb079a768Kristian Monsen    if (expr->is_postfix() && !context()->IsEffect()) {
3209e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke      __ mov(ip, Operand(Smi::FromInt(0)));
3210109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      PushOperand(ip);
3211e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke    }
3212958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    switch (assign_type) {
3213958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      case NAMED_PROPERTY: {
3214958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        // Put the object both on the stack and in the register.
3215958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        VisitForStackValue(prop->obj());
3216958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        __ ldr(LoadDescriptor::ReceiverRegister(), MemOperand(sp, 0));
3217958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        EmitNamedPropertyLoad(prop);
3218958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        break;
3219958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      }
3220958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
3221958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      case NAMED_SUPER_PROPERTY: {
3222014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var());
3223014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        VisitForAccumulatorValue(
3224014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            prop->obj()->AsSuperPropertyReference()->home_object());
3225109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        PushOperand(result_register());
3226958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        const Register scratch = r1;
3227958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        __ ldr(scratch, MemOperand(sp, kPointerSize));
3228109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        PushOperand(scratch);
3229109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        PushOperand(result_register());
3230958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        EmitNamedSuperPropertyLoad(prop);
3231958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        break;
3232958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      }
3233958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
3234958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      case KEYED_SUPER_PROPERTY: {
3235014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var());
3236014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        VisitForStackValue(
3237014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            prop->obj()->AsSuperPropertyReference()->home_object());
3238958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        VisitForAccumulatorValue(prop->key());
3239109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        PushOperand(result_register());
3240958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        const Register scratch = r1;
3241958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        __ ldr(scratch, MemOperand(sp, 2 * kPointerSize));
3242109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        PushOperand(scratch);
3243958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        __ ldr(scratch, MemOperand(sp, 2 * kPointerSize));
3244109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        PushOperand(scratch);
3245109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        PushOperand(result_register());
3246958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        EmitKeyedSuperPropertyLoad(prop);
3247958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        break;
3248958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      }
3249958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
3250958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      case KEYED_PROPERTY: {
3251958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        VisitForStackValue(prop->obj());
3252958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        VisitForStackValue(prop->key());
3253958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        __ ldr(LoadDescriptor::ReceiverRegister(),
3254958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier               MemOperand(sp, 1 * kPointerSize));
3255958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        __ ldr(LoadDescriptor::NameRegister(), MemOperand(sp, 0));
3256958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        EmitKeyedPropertyLoad(prop);
3257958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        break;
3258958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      }
3259958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
3260958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      case VARIABLE:
3261958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        UNREACHABLE();
3262e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke    }
3263d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  }
3264d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
3265b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // We need a second deoptimization point after loading the value
3266b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // in case evaluating the property load my have a side effect.
32678b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  if (assign_type == VARIABLE) {
3268bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    PrepareForBailout(expr->expression(), BailoutState::TOS_REGISTER);
32698b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  } else {
3270bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    PrepareForBailoutForId(prop->LoadId(), BailoutState::TOS_REGISTER);
32718b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  }
3272b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
3273b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Inline smi case if we are in a loop.
3274b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Label stub_call, done;
3275b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  JumpPatchSite patch_site(masm_);
3276b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3277b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int count_value = expr->op() == Token::INC ? 1 : -1;
3278b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (ShouldInlineSmiCase(expr->op())) {
3279b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Label slow;
3280b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    patch_site.EmitJumpIfNotSmi(r0, &slow);
3281b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3282b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Save result for postfix expressions.
3283b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (expr->is_postfix()) {
3284b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (!context()->IsEffect()) {
3285b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        // Save the result on the stack. If we have a named or keyed property
3286b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        // we store the result under the receiver that is currently on top
3287b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        // of the stack.
3288b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        switch (assign_type) {
3289b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          case VARIABLE:
3290b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            __ push(r0);
3291b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            break;
3292b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          case NAMED_PROPERTY:
3293b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            __ str(r0, MemOperand(sp, kPointerSize));
3294b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            break;
3295958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier          case NAMED_SUPER_PROPERTY:
3296958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier            __ str(r0, MemOperand(sp, 2 * kPointerSize));
3297958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier            break;
3298b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          case KEYED_PROPERTY:
3299b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            __ str(r0, MemOperand(sp, 2 * kPointerSize));
3300b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            break;
3301958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier          case KEYED_SUPER_PROPERTY:
3302958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier            __ str(r0, MemOperand(sp, 3 * kPointerSize));
3303958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier            break;
3304b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        }
3305b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
3306b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
3307b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3308b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    __ add(r0, r0, Operand(Smi::FromInt(count_value)), SetCC);
3309b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    __ b(vc, &done);
3310b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Call stub. Undo operation first.
3311b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    __ sub(r0, r0, Operand(Smi::FromInt(count_value)));
3312b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    __ jmp(&stub_call);
3313b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    __ bind(&slow);
3314b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
33153b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
33163b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  // Convert old value into a number.
331713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  __ Call(isolate()->builtins()->ToNumber(), RelocInfo::CODE_TARGET);
3318bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  PrepareForBailoutForId(expr->ToNumberId(), BailoutState::TOS_REGISTER);
3319e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
3320e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  // Save result for postfix expressions.
3321e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  if (expr->is_postfix()) {
33220d5e116f6aee03185f237311a943491bb079a768Kristian Monsen    if (!context()->IsEffect()) {
33230d5e116f6aee03185f237311a943491bb079a768Kristian Monsen      // Save the result on the stack. If we have a named or keyed property
33240d5e116f6aee03185f237311a943491bb079a768Kristian Monsen      // we store the result under the receiver that is currently on top
33250d5e116f6aee03185f237311a943491bb079a768Kristian Monsen      // of the stack.
33260d5e116f6aee03185f237311a943491bb079a768Kristian Monsen      switch (assign_type) {
33270d5e116f6aee03185f237311a943491bb079a768Kristian Monsen        case VARIABLE:
3328109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch          PushOperand(r0);
33290d5e116f6aee03185f237311a943491bb079a768Kristian Monsen          break;
33300d5e116f6aee03185f237311a943491bb079a768Kristian Monsen        case NAMED_PROPERTY:
33310d5e116f6aee03185f237311a943491bb079a768Kristian Monsen          __ str(r0, MemOperand(sp, kPointerSize));
33320d5e116f6aee03185f237311a943491bb079a768Kristian Monsen          break;
3333958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        case NAMED_SUPER_PROPERTY:
3334958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier          __ str(r0, MemOperand(sp, 2 * kPointerSize));
3335958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier          break;
33360d5e116f6aee03185f237311a943491bb079a768Kristian Monsen        case KEYED_PROPERTY:
33370d5e116f6aee03185f237311a943491bb079a768Kristian Monsen          __ str(r0, MemOperand(sp, 2 * kPointerSize));
33380d5e116f6aee03185f237311a943491bb079a768Kristian Monsen          break;
3339958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        case KEYED_SUPER_PROPERTY:
3340958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier          __ str(r0, MemOperand(sp, 3 * kPointerSize));
3341958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier          break;
33420d5e116f6aee03185f237311a943491bb079a768Kristian Monsen      }
3343e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke    }
3344e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  }
3345e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
3346d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
3347b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  __ bind(&stub_call);
3348b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  __ mov(r1, r0);
3349b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  __ mov(r0, Operand(Smi::FromInt(count_value)));
3350b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
3351014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  SetExpressionPosition(expr);
3352b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
3353109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), Token::ADD).code();
3354b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CallIC(code, expr->CountBinOpFeedbackId());
33553fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  patch_site.EmitPatchInfo();
3356d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  __ bind(&done);
3357e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
3358e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  // Store the value returned in r0.
3359e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  switch (assign_type) {
3360e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke    case VARIABLE:
3361e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke      if (expr->is_postfix()) {
33620d5e116f6aee03185f237311a943491bb079a768Kristian Monsen        { EffectContext context(this);
33630d5e116f6aee03185f237311a943491bb079a768Kristian Monsen          EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(),
3364014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                 Token::ASSIGN, expr->CountSlot());
3365bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch          PrepareForBailoutForId(expr->AssignmentId(),
3366bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                                 BailoutState::TOS_REGISTER);
3367b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch          context.Plug(r0);
33680d5e116f6aee03185f237311a943491bb079a768Kristian Monsen        }
33690d5e116f6aee03185f237311a943491bb079a768Kristian Monsen        // For all contexts except EffectConstant We have the result on
3370e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke        // top of the stack.
33710d5e116f6aee03185f237311a943491bb079a768Kristian Monsen        if (!context()->IsEffect()) {
33720d5e116f6aee03185f237311a943491bb079a768Kristian Monsen          context()->PlugTOS();
3373e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke        }
3374e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke      } else {
3375e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke        EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(),
3376014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                               Token::ASSIGN, expr->CountSlot());
3377bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch        PrepareForBailoutForId(expr->AssignmentId(),
3378bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                               BailoutState::TOS_REGISTER);
3379b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch        context()->Plug(r0);
3380e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke      }
3381d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block      break;
3382e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke    case NAMED_PROPERTY: {
3383b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      __ mov(StoreDescriptor::NameRegister(),
3384b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch             Operand(prop->key()->AsLiteral()->value()));
3385109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      PopOperand(StoreDescriptor::ReceiverRegister());
3386014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      EmitLoadStoreICSlot(expr->CountSlot());
3387014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      CallStoreIC();
3388bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER);
3389e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke      if (expr->is_postfix()) {
33900d5e116f6aee03185f237311a943491bb079a768Kristian Monsen        if (!context()->IsEffect()) {
33910d5e116f6aee03185f237311a943491bb079a768Kristian Monsen          context()->PlugTOS();
3392e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke        }
3393e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke      } else {
33940d5e116f6aee03185f237311a943491bb079a768Kristian Monsen        context()->Plug(r0);
3395e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke      }
3396d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block      break;
3397d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    }
3398958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    case NAMED_SUPER_PROPERTY: {
3399958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      EmitNamedSuperPropertyStore(prop);
3400958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      if (expr->is_postfix()) {
3401958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        if (!context()->IsEffect()) {
3402958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier          context()->PlugTOS();
3403958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        }
3404958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      } else {
3405958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        context()->Plug(r0);
3406958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      }
3407958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      break;
3408958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    }
3409958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    case KEYED_SUPER_PROPERTY: {
3410958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      EmitKeyedSuperPropertyStore(prop);
3411958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      if (expr->is_postfix()) {
3412958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        if (!context()->IsEffect()) {
3413958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier          context()->PlugTOS();
3414958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        }
3415958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      } else {
3416958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        context()->Plug(r0);
3417958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      }
3418958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      break;
3419958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    }
3420e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke    case KEYED_PROPERTY: {
3421109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      PopOperands(StoreDescriptor::ReceiverRegister(),
3422109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch                  StoreDescriptor::NameRegister());
3423b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Handle<Code> ic =
3424014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          CodeFactory::KeyedStoreIC(isolate(), language_mode()).code();
3425014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      EmitLoadStoreICSlot(expr->CountSlot());
3426014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      CallIC(ic);
3427bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER);
3428e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke      if (expr->is_postfix()) {
34290d5e116f6aee03185f237311a943491bb079a768Kristian Monsen        if (!context()->IsEffect()) {
34300d5e116f6aee03185f237311a943491bb079a768Kristian Monsen          context()->PlugTOS();
3431e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke        }
3432e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke      } else {
34330d5e116f6aee03185f237311a943491bb079a768Kristian Monsen        context()->Plug(r0);
3434e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke      }
3435d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block      break;
3436d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    }
34373ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  }
34383ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block}
34393ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
34403ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
34413fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochvoid FullCodeGenerator::EmitLiteralCompareTypeof(Expression* expr,
34423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                                 Expression* sub_expr,
34433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                                 Handle<String> check) {
34443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Label materialize_true, materialize_false;
34453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Label* if_true = NULL;
34463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Label* if_false = NULL;
34473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Label* fall_through = NULL;
34483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  context()->PrepareTest(&materialize_true, &materialize_false,
34493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                         &if_true, &if_false, &fall_through);
34503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
34510d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  { AccumulatorValueContext context(this);
34523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    VisitForTypeofValue(sub_expr);
34530d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  }
34543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
3455b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
3456b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Factory* factory = isolate()->factory();
3457b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (String::Equals(check, factory->number_string())) {
3458e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch    __ JumpIfSmi(r0, if_true);
345980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen    __ ldr(r0, FieldMemOperand(r0, HeapObject::kMapOffset));
346080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen    __ LoadRoot(ip, Heap::kHeapNumberMapRootIndex);
346180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen    __ cmp(r0, ip);
346280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen    Split(eq, if_true, if_false, fall_through);
3463b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else if (String::Equals(check, factory->string_string())) {
3464e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch    __ JumpIfSmi(r0, if_false);
3465e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch    __ CompareObjectType(r0, r0, r1, FIRST_NONSTRING_TYPE);
3466014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Split(lt, if_true, if_false, fall_through);
3467b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else if (String::Equals(check, factory->symbol_string())) {
3468b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    __ JumpIfSmi(r0, if_false);
3469b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    __ CompareObjectType(r0, r0, r1, SYMBOL_TYPE);
3470b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Split(eq, if_true, if_false, fall_through);
3471b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else if (String::Equals(check, factory->boolean_string())) {
3472e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch    __ CompareRoot(r0, Heap::kTrueValueRootIndex);
3473f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke    __ b(eq, if_true);
3474e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch    __ CompareRoot(r0, Heap::kFalseValueRootIndex);
347580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen    Split(eq, if_true, if_false, fall_through);
3476b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else if (String::Equals(check, factory->undefined_string())) {
3477109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    __ CompareRoot(r0, Heap::kNullValueRootIndex);
3478109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    __ b(eq, if_false);
3479e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch    __ JumpIfSmi(r0, if_false);
348080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen    // Check for undetectable objects => true.
348180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen    __ ldr(r0, FieldMemOperand(r0, HeapObject::kMapOffset));
348280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen    __ ldrb(r1, FieldMemOperand(r0, Map::kBitFieldOffset));
3483e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch    __ tst(r1, Operand(1 << Map::kIsUndetectable));
3484e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch    Split(ne, if_true, if_false, fall_through);
3485e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
3486b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else if (String::Equals(check, factory->function_string())) {
3487e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch    __ JumpIfSmi(r0, if_false);
3488014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    __ ldr(r0, FieldMemOperand(r0, HeapObject::kMapOffset));
3489014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    __ ldrb(r1, FieldMemOperand(r0, Map::kBitFieldOffset));
3490014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    __ and_(r1, r1,
3491014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            Operand((1 << Map::kIsCallable) | (1 << Map::kIsUndetectable)));
3492014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    __ cmp(r1, Operand(1 << Map::kIsCallable));
34933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    Split(eq, if_true, if_false, fall_through);
3494b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else if (String::Equals(check, factory->object_string())) {
3495e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch    __ JumpIfSmi(r0, if_false);
3496b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    __ CompareRoot(r0, Heap::kNullValueRootIndex);
3497b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    __ b(eq, if_true);
3498014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    STATIC_ASSERT(LAST_JS_RECEIVER_TYPE == LAST_TYPE);
3499014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    __ CompareObjectType(r0, r0, r1, FIRST_JS_RECEIVER_TYPE);
35003fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    __ b(lt, if_false);
3501014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // Check for callable or undetectable objects => false.
3502e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch    __ ldrb(r1, FieldMemOperand(r0, Map::kBitFieldOffset));
3503014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    __ tst(r1, Operand((1 << Map::kIsCallable) | (1 << Map::kIsUndetectable)));
3504014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Split(eq, if_true, if_false, fall_through);
3505014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// clang-format off
3506014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define SIMD128_TYPE(TYPE, Type, type, lane_count, lane_type)   \
3507014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else if (String::Equals(check, factory->type##_string())) { \
3508014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    __ JumpIfSmi(r0, if_false);                                 \
3509014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    __ ldr(r0, FieldMemOperand(r0, HeapObject::kMapOffset));    \
3510014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    __ CompareRoot(r0, Heap::k##Type##MapRootIndex);            \
3511e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch    Split(eq, if_true, if_false, fall_through);
3512014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  SIMD128_TYPES(SIMD128_TYPE)
3513014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#undef SIMD128_TYPE
3514014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // clang-format on
351580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  } else {
351680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen    if (if_false != fall_through) __ jmp(if_false);
3517f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  }
35183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  context()->Plug(if_true, if_false);
3519f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke}
3520f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke
3521f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke
3522d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::VisitCompareOperation(CompareOperation* expr) {
3523d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  Comment cmnt(masm_, "[ CompareOperation");
3524e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
35253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // First we try a fast inlined version of the compare when one of
35263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // the operands is a literal.
35273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (TryLiteralCompare(expr)) return;
35283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
3529e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  // Always perform the comparison for its control flow.  Pack the result
3530e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  // into the expression's context after the comparison is performed.
3531f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  Label materialize_true, materialize_false;
3532f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  Label* if_true = NULL;
3533f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  Label* if_false = NULL;
353480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  Label* fall_through = NULL;
35350d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  context()->PrepareTest(&materialize_true, &materialize_false,
35360d5e116f6aee03185f237311a943491bb079a768Kristian Monsen                         &if_true, &if_false, &fall_through);
353780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen
35383fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  Token::Value op = expr->op();
35390d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  VisitForStackValue(expr->left());
354080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  switch (op) {
3541e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke    case Token::IN:
35420d5e116f6aee03185f237311a943491bb079a768Kristian Monsen      VisitForStackValue(expr->right());
3543bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      SetExpressionPosition(expr);
3544bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      EmitHasProperty();
35453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      PrepareForBailoutBeforeSplit(expr, false, NULL, NULL);
3546014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ CompareRoot(r0, Heap::kTrueValueRootIndex);
354780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen      Split(eq, if_true, if_false, fall_through);
3548d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block      break;
3549d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
3550d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    case Token::INSTANCEOF: {
3551014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      VisitForAccumulatorValue(expr->right());
3552bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      SetExpressionPosition(expr);
3553109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      PopOperand(r1);
3554014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      InstanceOfStub stub(isolate());
3555d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block      __ CallStub(&stub);
3556014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      PrepareForBailoutBeforeSplit(expr, false, NULL, NULL);
3557014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ CompareRoot(r0, Heap::kTrueValueRootIndex);
355880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen      Split(eq, if_true, if_false, fall_through);
3559d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block      break;
3560d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    }
3561d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
3562d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    default: {
35630d5e116f6aee03185f237311a943491bb079a768Kristian Monsen      VisitForAccumulatorValue(expr->right());
3564bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      SetExpressionPosition(expr);
3565b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Condition cond = CompareIC::ComputeCondition(op);
3566109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      PopOperand(r1);
3567d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
35680d5e116f6aee03185f237311a943491bb079a768Kristian Monsen      bool inline_smi_code = ShouldInlineSmiCase(op);
35691e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block      JumpPatchSite patch_site(masm_);
35700d5e116f6aee03185f237311a943491bb079a768Kristian Monsen      if (inline_smi_code) {
357180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen        Label slow_case;
357280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen        __ orr(r2, r0, Operand(r1));
35731e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block        patch_site.EmitJumpIfNotSmi(r2, &slow_case);
357480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen        __ cmp(r1, r0);
35751e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block        Split(cond, if_true, if_false, NULL);
357680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen        __ bind(&slow_case);
357780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen      }
35781e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
3579109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      Handle<Code> ic = CodeFactory::CompareIC(isolate(), op).code();
3580b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      CallIC(ic, expr->CompareOperationFeedbackId());
35813fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      patch_site.EmitPatchInfo();
35823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
3583b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      __ cmp(r0, Operand::Zero());
35841e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block      Split(cond, if_true, if_false, fall_through);
35853ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block    }
35863ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  }
35873ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
3588e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  // Convert the result of the comparison into one expected for this
3589e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  // expression's context.
35900d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  context()->Plug(if_true, if_false);
3591e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke}
35923ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
3593d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
35943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid FullCodeGenerator::EmitLiteralCompareNil(CompareOperation* expr,
35953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                              Expression* sub_expr,
35963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                              NilValue nil) {
359780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  Label materialize_true, materialize_false;
359880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  Label* if_true = NULL;
359980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  Label* if_false = NULL;
360080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  Label* fall_through = NULL;
36010d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  context()->PrepareTest(&materialize_true, &materialize_false,
36020d5e116f6aee03185f237311a943491bb079a768Kristian Monsen                         &if_true, &if_false, &fall_through);
360380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen
36043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  VisitForAccumulatorValue(sub_expr);
36053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
36063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (expr->op() == Token::EQ_STRICT) {
3607b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Heap::RootListIndex nil_value = nil == kNullValue ?
3608b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        Heap::kNullValueRootIndex :
3609b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        Heap::kUndefinedValueRootIndex;
3610b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    __ LoadRoot(r1, nil_value);
361180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen    __ cmp(r0, r1);
361280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen    Split(eq, if_true, if_false, fall_through);
3613b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
36143b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    __ JumpIfSmi(r0, if_false);
36153b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    __ ldr(r0, FieldMemOperand(r0, HeapObject::kMapOffset));
36163b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    __ ldrb(r1, FieldMemOperand(r0, Map::kBitFieldOffset));
36173b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    __ tst(r1, Operand(1 << Map::kIsUndetectable));
36183b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    Split(ne, if_true, if_false, fall_through);
361980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  }
36200d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  context()->Plug(if_true, if_false);
362180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen}
362280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen
362380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen
36240d5e116f6aee03185f237311a943491bb079a768Kristian MonsenRegister FullCodeGenerator::result_register() {
36250d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  return r0;
36260d5e116f6aee03185f237311a943491bb079a768Kristian Monsen}
3627d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
3628e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
36290d5e116f6aee03185f237311a943491bb079a768Kristian MonsenRegister FullCodeGenerator::context_register() {
36300d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  return cp;
36310d5e116f6aee03185f237311a943491bb079a768Kristian Monsen}
36320d5e116f6aee03185f237311a943491bb079a768Kristian Monsen
36333b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdochvoid FullCodeGenerator::LoadFromFrameField(int frame_offset, Register value) {
36343b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  DCHECK_EQ(POINTER_SIZE_ALIGN(frame_offset), frame_offset);
36353b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  __ ldr(value, MemOperand(fp, frame_offset));
36363b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch}
36370d5e116f6aee03185f237311a943491bb079a768Kristian Monsen
3638d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::StoreToFrameField(int frame_offset, Register value) {
3639b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK_EQ(POINTER_SIZE_ALIGN(frame_offset), frame_offset);
3640e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  __ str(value, MemOperand(fp, frame_offset));
3641d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block}
36423ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
3643e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
3644d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::LoadContextField(Register dst, int context_index) {
3645014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  __ ldr(dst, ContextMemOperand(cp, context_index));
36463ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block}
36473ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
3648d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
36493fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochvoid FullCodeGenerator::PushFunctionArgumentForContextAllocation() {
3650014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Scope* closure_scope = scope()->ClosureScope();
3651014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (closure_scope->is_script_scope() ||
3652014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      closure_scope->is_module_scope()) {
3653b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Contexts nested in the native context have a canonical empty function
36543fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    // as their closure, not the anonymous closure containing the global
3655014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // code.
3656014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    __ LoadNativeContextSlot(Context::CLOSURE_INDEX, ip);
3657014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else if (closure_scope->is_eval_scope()) {
36583fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    // Contexts created by a call to eval have the same closure as the
36593fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    // context calling eval, not the anonymous closure containing the eval
36603fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    // code.  Fetch it from the context.
3661014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    __ ldr(ip, ContextMemOperand(cp, Context::CLOSURE_INDEX));
36623fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  } else {
3663014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK(closure_scope->is_function_scope());
36643fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    __ ldr(ip, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
36653fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  }
3666109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  PushOperand(ip);
36673fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch}
36683fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
36693fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
3670e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke// ----------------------------------------------------------------------------
3671e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke// Non-local control flow support.
3672e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
3673d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::EnterFinallyBlock() {
3674b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(!result_register().is(r1));
3675b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Store pending message while executing finally block.
3676b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ExternalReference pending_message_obj =
3677b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      ExternalReference::address_of_pending_message_obj(isolate());
3678b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  __ mov(ip, Operand(pending_message_obj));
3679b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  __ ldr(r1, MemOperand(ip));
3680109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  PushOperand(r1);
3681b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3682014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  ClearPendingMessage();
3683e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke}
3684e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
3685e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
3686d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkevoid FullCodeGenerator::ExitFinallyBlock() {
3687b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(!result_register().is(r1));
3688b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Restore pending message from stack.
3689109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  PopOperand(r1);
3690b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ExternalReference pending_message_obj =
3691b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      ExternalReference::address_of_pending_message_obj(isolate());
3692b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  __ mov(ip, Operand(pending_message_obj));
3693b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  __ str(r1, MemOperand(ip));
3694e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke}
3695e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
3696d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
3697014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid FullCodeGenerator::ClearPendingMessage() {
3698014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(!result_register().is(r1));
3699014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  ExternalReference pending_message_obj =
3700014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      ExternalReference::address_of_pending_message_obj(isolate());
3701014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  __ LoadRoot(r1, Heap::kTheHoleValueRootIndex);
3702014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  __ mov(ip, Operand(pending_message_obj));
3703014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  __ str(r1, MemOperand(ip));
3704014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
3705d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
370669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch
3707109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochvoid FullCodeGenerator::DeferredCommands::EmitCommands() {
3708109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  DCHECK(!result_register().is(r1));
3709109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  __ Pop(result_register());  // Restore the accumulator.
3710109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  __ Pop(r1);                 // Get the token.
3711109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  for (DeferredCommand cmd : commands_) {
3712109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    Label skip;
3713109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    __ cmp(r1, Operand(Smi::FromInt(cmd.token)));
3714109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    __ b(ne, &skip);
3715109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    switch (cmd.command) {
3716109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      case kReturn:
3717109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        codegen_->EmitUnwindAndReturn();
3718109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        break;
3719109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      case kThrow:
3720109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        __ Push(result_register());
3721109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        __ CallRuntime(Runtime::kReThrow);
3722109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        break;
3723109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      case kContinue:
3724109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        codegen_->EmitContinue(cmd.target);
3725109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        break;
3726109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      case kBreak:
3727109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        codegen_->EmitBreak(cmd.target);
3728109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        break;
3729109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    }
3730109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    __ bind(&skip);
3731109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  }
3732109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch}
373369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch
373469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch#undef __
373569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch
3736b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3737b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic Address GetInterruptImmediateLoadAddress(Address pc) {
3738b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Address load_address = pc - 2 * Assembler::kInstrSize;
3739014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (!FLAG_enable_embedded_constant_pool) {
3740b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(Assembler::IsLdrPcImmediateOffset(Memory::int32_at(load_address)));
3741b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else if (Assembler::IsLdrPpRegOffset(Memory::int32_at(load_address))) {
3742b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // This is an extended constant pool lookup.
3743b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (CpuFeatures::IsSupported(ARMv7)) {
3744b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      load_address -= 2 * Assembler::kInstrSize;
3745b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      DCHECK(Assembler::IsMovW(Memory::int32_at(load_address)));
3746b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      DCHECK(Assembler::IsMovT(
3747b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          Memory::int32_at(load_address + Assembler::kInstrSize)));
3748b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    } else {
3749b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      load_address -= 4 * Assembler::kInstrSize;
3750b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      DCHECK(Assembler::IsMovImmed(Memory::int32_at(load_address)));
3751b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      DCHECK(Assembler::IsOrrImmed(
3752b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          Memory::int32_at(load_address + Assembler::kInstrSize)));
3753b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      DCHECK(Assembler::IsOrrImmed(
3754b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          Memory::int32_at(load_address + 2 * Assembler::kInstrSize)));
3755b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      DCHECK(Assembler::IsOrrImmed(
3756b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          Memory::int32_at(load_address + 3 * Assembler::kInstrSize)));
3757b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
3758b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else if (CpuFeatures::IsSupported(ARMv7) &&
3759b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch             Assembler::IsMovT(Memory::int32_at(load_address))) {
3760b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // This is a movw / movt immediate load.
3761b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    load_address -= Assembler::kInstrSize;
3762b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(Assembler::IsMovW(Memory::int32_at(load_address)));
3763b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else if (!CpuFeatures::IsSupported(ARMv7) &&
3764b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch             Assembler::IsOrrImmed(Memory::int32_at(load_address))) {
3765b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // This is a mov / orr immediate load.
3766b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    load_address -= 3 * Assembler::kInstrSize;
3767b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(Assembler::IsMovImmed(Memory::int32_at(load_address)));
3768b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(Assembler::IsOrrImmed(
3769b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        Memory::int32_at(load_address + Assembler::kInstrSize)));
3770b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(Assembler::IsOrrImmed(
3771b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        Memory::int32_at(load_address + 2 * Assembler::kInstrSize)));
3772b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
3773b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // This is a small constant pool lookup.
3774b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(Assembler::IsLdrPpImmediateOffset(Memory::int32_at(load_address)));
3775b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3776b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return load_address;
3777b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
3778b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3779b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3780b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid BackEdgeTable::PatchAt(Code* unoptimized_code,
3781b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                            Address pc,
3782b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                            BackEdgeState target_state,
3783b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                            Code* replacement_code) {
3784b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Address pc_immediate_load_address = GetInterruptImmediateLoadAddress(pc);
3785b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Address branch_address = pc_immediate_load_address - Assembler::kInstrSize;
3786014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Isolate* isolate = unoptimized_code->GetIsolate();
3787014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  CodePatcher patcher(isolate, branch_address, 1);
3788b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  switch (target_state) {
3789b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case INTERRUPT:
3790b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    {
3791b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      //  <decrement profiling counter>
3792b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      //   bpl ok
3793b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      //   ; load interrupt stub address into ip - either of (for ARMv7):
3794b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      //   ; <small cp load>      |  <extended cp load> |  <immediate load>
3795b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      //   ldr ip, [pc/pp, #imm]  |   movw ip, #imm     |   movw ip, #imm
3796b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      //                          |   movt ip, #imm     |   movw ip, #imm
3797b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      //                          |   ldr  ip, [pp, ip]
3798b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      //   ; or (for ARMv6):
3799b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      //   ; <small cp load>      |  <extended cp load> |  <immediate load>
3800b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      //   ldr ip, [pc/pp, #imm]  |   mov ip, #imm      |   mov ip, #imm
3801b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      //                          |   orr ip, ip, #imm> |   orr ip, ip, #imm
3802b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      //                          |   orr ip, ip, #imm> |   orr ip, ip, #imm
3803b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      //                          |   orr ip, ip, #imm> |   orr ip, ip, #imm
3804b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      //   blx ip
3805b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      //  <reset profiling counter>
3806b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      //  ok-label
3807b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3808b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // Calculate branch offset to the ok-label - this is the difference
3809b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // between the branch address and |pc| (which points at <blx ip>) plus
3810b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // kProfileCounterResetSequence instructions
3811b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      int branch_offset = pc - Instruction::kPCReadOffset - branch_address +
3812b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                          kProfileCounterResetSequenceLength;
3813b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      patcher.masm()->b(branch_offset, pl);
3814b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
3815b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
3816b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case ON_STACK_REPLACEMENT:
3817b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      //  <decrement profiling counter>
3818b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      //   mov r0, r0 (NOP)
3819b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      //   ; load on-stack replacement address into ip - either of (for ARMv7):
3820b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      //   ; <small cp load>      |  <extended cp load> |  <immediate load>
3821b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      //   ldr ip, [pc/pp, #imm]  |   movw ip, #imm     |   movw ip, #imm
3822b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      //                          |   movt ip, #imm>    |   movw ip, #imm
3823b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      //                          |   ldr  ip, [pp, ip]
3824b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      //   ; or (for ARMv6):
3825b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      //   ; <small cp load>      |  <extended cp load> |  <immediate load>
3826b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      //   ldr ip, [pc/pp, #imm]  |   mov ip, #imm      |   mov ip, #imm
3827b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      //                          |   orr ip, ip, #imm> |   orr ip, ip, #imm
3828b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      //                          |   orr ip, ip, #imm> |   orr ip, ip, #imm
3829b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      //                          |   orr ip, ip, #imm> |   orr ip, ip, #imm
3830b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      //   blx ip
3831b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      //  <reset profiling counter>
3832b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      //  ok-label
3833b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      patcher.masm()->nop();
3834b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
3835b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3836b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3837b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Replace the call address.
3838014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Assembler::set_target_address_at(isolate, pc_immediate_load_address,
3839014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                   unoptimized_code, replacement_code->entry());
3840b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3841b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  unoptimized_code->GetHeap()->incremental_marking()->RecordCodeTargetPatch(
3842b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      unoptimized_code, pc_immediate_load_address, replacement_code);
3843b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
3844b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3845b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3846b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochBackEdgeTable::BackEdgeState BackEdgeTable::GetBackEdgeState(
3847b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Isolate* isolate,
3848b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Code* unoptimized_code,
3849b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Address pc) {
3850b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(Assembler::IsBlxIp(Memory::int32_at(pc - Assembler::kInstrSize)));
3851b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3852b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Address pc_immediate_load_address = GetInterruptImmediateLoadAddress(pc);
3853b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Address branch_address = pc_immediate_load_address - Assembler::kInstrSize;
38543b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch#ifdef DEBUG
3855b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Address interrupt_address = Assembler::target_address_at(
3856b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      pc_immediate_load_address, unoptimized_code);
38573b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch#endif
3858b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3859b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (Assembler::IsBranch(Assembler::instr_at(branch_address))) {
3860b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(interrupt_address ==
3861b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch           isolate->builtins()->InterruptCheck()->entry());
3862b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return INTERRUPT;
3863b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3864b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3865b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(Assembler::IsNop(Assembler::instr_at(branch_address)));
3866b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3867b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(interrupt_address ==
38683b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch         isolate->builtins()->OnStackReplacement()->entry());
38693b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  return ON_STACK_REPLACEMENT;
3870b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
3871b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3872b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3873014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}  // namespace internal
3874014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}  // namespace v8
3875f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke
3876f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke#endif  // V8_TARGET_ARCH_ARM
3877