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