1864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// Copyright 2012 the V8 project authors. All rights reserved. 2864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// Use of this source code is governed by a BSD-style license that can be 3864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// found in the LICENSE file. 4864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 5196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/v8.h" 6864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 7864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org#if V8_TARGET_ARCH_X87 8864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 9b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org#include "src/code-factory.h" 10196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/code-stubs.h" 11196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/codegen.h" 12196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/compiler.h" 13196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/debug.h" 14196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/full-codegen.h" 15a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org#include "src/ic/ic.h" 16196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/isolate-inl.h" 17196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/parser.h" 18196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/scopes.h" 19864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 20864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgnamespace v8 { 21864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgnamespace internal { 22864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 23864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org#define __ ACCESS_MASM(masm_) 24864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 25864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 26864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgclass JumpPatchSite BASE_EMBEDDED { 27864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org public: 28864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org explicit JumpPatchSite(MacroAssembler* masm) : masm_(masm) { 29864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org#ifdef DEBUG 30864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org info_emitted_ = false; 31864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org#endif 32864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 33864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 34864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ~JumpPatchSite() { 35e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(patch_site_.is_bound() == info_emitted_); 36864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 37864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 38864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void EmitJumpIfNotSmi(Register reg, 39864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label* target, 40864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label::Distance distance = Label::kFar) { 41864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ test(reg, Immediate(kSmiTagMask)); 42864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org EmitJump(not_carry, target, distance); // Always taken before patched. 43864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 44864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 45864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void EmitJumpIfSmi(Register reg, 46864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label* target, 47864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label::Distance distance = Label::kFar) { 48864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ test(reg, Immediate(kSmiTagMask)); 49864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org EmitJump(carry, target, distance); // Never taken before patched. 50864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 51864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 52864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void EmitPatchInfo() { 53864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (patch_site_.is_bound()) { 54864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int delta_to_patch_site = masm_->SizeOfCodeGeneratedSince(&patch_site_); 55e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(is_uint8(delta_to_patch_site)); 56864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ test(eax, Immediate(delta_to_patch_site)); 57864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org#ifdef DEBUG 58864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org info_emitted_ = true; 59864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org#endif 60864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 61864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ nop(); // Signals no inlined code. 62864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 63864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 64864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 65864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org private: 66864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // jc will be patched with jz, jnc will become jnz. 67864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org void EmitJump(Condition cc, Label* target, Label::Distance distance) { 68e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!patch_site_.is_bound() && !info_emitted_); 69e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(cc == carry || cc == not_carry); 70864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&patch_site_); 71864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(cc, target, distance); 72864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 73864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 74864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org MacroAssembler* masm_; 75864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label patch_site_; 76864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org#ifdef DEBUG 77864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org bool info_emitted_; 78864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org#endif 79864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org}; 80864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 81864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 82864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// Generate code for a JS function. On entry to the function the receiver 83864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// and arguments have been pushed on the stack left to right, with the 84864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// return address on top of them. The actual argument count matches the 85864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// formal parameter count expected by the function. 86864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// 87864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// The live registers are: 88864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// o edi: the JS function object being called (i.e. ourselves) 89864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// o esi: our context 90864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// o ebp: our caller's frame pointer 91864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// o esp: stack pointer (pointing to return address) 92864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// 93864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// The function builds a JS frame. Please see JavaScriptFrameConstants in 94864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// frames-x87.h for its layout. 95864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid FullCodeGenerator::Generate() { 96864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org CompilationInfo* info = info_; 97864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org handler_table_ = 98864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org isolate()->factory()->NewFixedArray(function()->handler_count(), TENURED); 99864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 100864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org profiling_counter_ = isolate()->factory()->NewCell( 101864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Handle<Smi>(Smi::FromInt(FLAG_interrupt_budget), isolate())); 102864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org SetFunctionPosition(function()); 103864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Comment cmnt(masm_, "[ function compiled by full code generator"); 104864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 105864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ProfileEntryHookStub::MaybeCallEntryHook(masm_); 106864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 107864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org#ifdef DEBUG 108864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (strlen(FLAG_stop_at) > 0 && 109864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org info->function()->name()->IsUtf8EqualTo(CStrVector(FLAG_stop_at))) { 110864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ int3(); 111864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 112864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org#endif 113864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 114864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Sloppy mode functions and builtins need to replace the receiver with the 115864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // global proxy when called as functions (without an explicit receiver 116864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // object). 117864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (info->strict_mode() == SLOPPY && !info->is_native()) { 118864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label ok; 119864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // +1 for return address. 120864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int receiver_offset = (info->scope()->num_parameters() + 1) * kPointerSize; 121864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(ecx, Operand(esp, receiver_offset)); 122864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 123864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ cmp(ecx, isolate()->factory()->undefined_value()); 124864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(not_equal, &ok, Label::kNear); 125864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 126864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(ecx, GlobalObjectOperand()); 127d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org __ mov(ecx, FieldOperand(ecx, GlobalObject::kGlobalProxyOffset)); 128864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 129864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(Operand(esp, receiver_offset), ecx); 130864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 131864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&ok); 132864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 133864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 134864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Open a frame scope to indicate that there is a frame on the stack. The 135864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // MANUAL indicates that the scope shouldn't actually generate code to set up 136864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // the frame (that is done below). 137864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org FrameScope frame_scope(masm_, StackFrame::MANUAL); 138864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 139864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org info->set_prologue_offset(masm_->pc_offset()); 140864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ Prologue(info->IsCodePreAgingActive()); 141864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org info->AddNoFrameRange(0, masm_->pc_offset()); 142864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 143864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org { Comment cmnt(masm_, "[ Allocate locals"); 144864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int locals_count = info->scope()->num_stack_slots(); 145864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Generators allocate locals, if any, in context slots. 146e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!info->function()->is_generator() || locals_count == 0); 147864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (locals_count == 1) { 148864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(Immediate(isolate()->factory()->undefined_value())); 149864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else if (locals_count > 1) { 150864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (locals_count >= 128) { 1513ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org Label ok; 1523ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org __ mov(ecx, esp); 1533ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org __ sub(ecx, Immediate(locals_count * kPointerSize)); 1543ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org ExternalReference stack_limit = 1553ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org ExternalReference::address_of_real_stack_limit(isolate()); 1563ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org __ cmp(ecx, Operand::StaticVariable(stack_limit)); 1573ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org __ j(above_equal, &ok, Label::kNear); 1583ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org __ InvokeBuiltin(Builtins::STACK_OVERFLOW, CALL_FUNCTION); 1593ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org __ bind(&ok); 160864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 161864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(eax, Immediate(isolate()->factory()->undefined_value())); 162864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org const int kMaxPushes = 32; 163864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (locals_count >= kMaxPushes) { 164864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int loop_iterations = locals_count / kMaxPushes; 165864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(ecx, loop_iterations); 166864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label loop_header; 167864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&loop_header); 168864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Do pushes. 169864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org for (int i = 0; i < kMaxPushes; i++) { 170864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(eax); 171864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 172864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ dec(ecx); 173864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(not_zero, &loop_header, Label::kNear); 174864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 175864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int remaining = locals_count % kMaxPushes; 176864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Emit the remaining pushes. 177864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org for (int i = 0; i < remaining; i++) { 178864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(eax); 179864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 180864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 181864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 182864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 183864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org bool function_in_register = true; 184864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 185864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Possibly allocate a local context. 186864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int heap_slots = info->scope()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS; 187864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (heap_slots > 0) { 188864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Comment cmnt(masm_, "[ Allocate context"); 189d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org bool need_write_barrier = true; 190864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Argument to NewContext is the function, which is still in edi. 191864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (FLAG_harmony_scoping && info->scope()->is_global_scope()) { 192864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(edi); 193864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ Push(info->scope()->GetScopeInfo()); 19447390597afd6b17870f41dfb5dd8c057aea1f068machenbach@chromium.org __ CallRuntime(Runtime::kNewGlobalContext, 2); 195864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else if (heap_slots <= FastNewContextStub::kMaximumSlots) { 196864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org FastNewContextStub stub(isolate(), heap_slots); 197864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ CallStub(&stub); 198d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org // Result of FastNewContextStub is always in new space. 199d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org need_write_barrier = false; 200864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 201864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(edi); 20247390597afd6b17870f41dfb5dd8c057aea1f068machenbach@chromium.org __ CallRuntime(Runtime::kNewFunctionContext, 1); 203864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 204864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org function_in_register = false; 205864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Context is returned in eax. It replaces the context passed to us. 206864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // It's saved in the stack and kept live in esi. 207864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(esi, eax); 208864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(Operand(ebp, StandardFrameConstants::kContextOffset), eax); 209864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 210864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Copy parameters into context if necessary. 211864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int num_parameters = info->scope()->num_parameters(); 212864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org for (int i = 0; i < num_parameters; i++) { 213864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Variable* var = scope()->parameter(i); 214864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (var->IsContextSlot()) { 215864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int parameter_offset = StandardFrameConstants::kCallerSPOffset + 216864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org (num_parameters - 1 - i) * kPointerSize; 217864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Load parameter from stack. 218864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(eax, Operand(ebp, parameter_offset)); 219864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Store it in the context. 220864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int context_offset = Context::SlotOffset(var->index()); 221864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(Operand(esi, context_offset), eax); 222864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Update the write barrier. This clobbers eax and ebx. 223d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org if (need_write_barrier) { 22406b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ RecordWriteContextSlot(esi, context_offset, eax, ebx, 22506b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org kDontSaveFPRegs); 226d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org } else if (FLAG_debug_code) { 227d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org Label done; 228d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org __ JumpIfInNewSpace(esi, eax, &done, Label::kNear); 229d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org __ Abort(kExpectedNewSpaceObject); 230d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org __ bind(&done); 231d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org } 232864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 233864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 234864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 235864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 236864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Variable* arguments = scope()->arguments(); 237864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (arguments != NULL) { 238864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Function uses arguments object. 239864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Comment cmnt(masm_, "[ Allocate arguments object"); 240864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (function_in_register) { 241864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(edi); 242864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 243864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(Operand(ebp, JavaScriptFrameConstants::kFunctionOffset)); 244864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 245864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Receiver is just before the parameters on the caller's stack. 246864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int num_parameters = info->scope()->num_parameters(); 247864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int offset = num_parameters * kPointerSize; 248864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ lea(edx, 249864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Operand(ebp, StandardFrameConstants::kCallerSPOffset + offset)); 250864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(edx); 251864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(Immediate(Smi::FromInt(num_parameters))); 252864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Arguments to ArgumentsAccessStub: 253864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // function, receiver address, parameter count. 254864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // The stub will rewrite receiver and parameter count if the previous 255864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // stack frame was an arguments adapter frame. 256864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ArgumentsAccessStub::Type type; 257864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (strict_mode() == STRICT) { 258864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org type = ArgumentsAccessStub::NEW_STRICT; 259864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else if (function()->has_duplicate_parameters()) { 260864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org type = ArgumentsAccessStub::NEW_SLOPPY_SLOW; 261864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 262864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org type = ArgumentsAccessStub::NEW_SLOPPY_FAST; 263864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 264864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ArgumentsAccessStub stub(isolate(), type); 265864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ CallStub(&stub); 266864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 267864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org SetVar(arguments, eax, ebx, edx); 268864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 269864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 270864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (FLAG_trace) { 271864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ CallRuntime(Runtime::kTraceEnter, 0); 272864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 273864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 274864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Visit the declarations and body unless there is an illegal 275864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // redeclaration. 276864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (scope()->HasIllegalRedeclaration()) { 277864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Comment cmnt(masm_, "[ Declarations"); 278864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org scope()->VisitIllegalRedeclaration(this); 279864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 280864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 281864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org PrepareForBailoutForId(BailoutId::FunctionEntry(), NO_REGISTERS); 282864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org { Comment cmnt(masm_, "[ Declarations"); 283864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // For named function expressions, declare the function name as a 284864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // constant. 285864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (scope()->is_function_scope() && scope()->function() != NULL) { 286864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org VariableDeclaration* function = scope()->function(); 287e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(function->proxy()->var()->mode() == CONST || 288864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org function->proxy()->var()->mode() == CONST_LEGACY); 289e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(function->proxy()->var()->location() != Variable::UNALLOCATED); 290864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org VisitVariableDeclaration(function); 291864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 292864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org VisitDeclarations(scope()->declarations()); 293864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 294864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 295864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org { Comment cmnt(masm_, "[ Stack check"); 296864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org PrepareForBailoutForId(BailoutId::Declarations(), NO_REGISTERS); 2973ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org Label ok; 2983ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org ExternalReference stack_limit 2993ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org = ExternalReference::address_of_stack_limit(isolate()); 3003ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org __ cmp(esp, Operand::StaticVariable(stack_limit)); 3013ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org __ j(above_equal, &ok, Label::kNear); 3023ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org __ call(isolate()->builtins()->StackCheck(), RelocInfo::CODE_TARGET); 3033ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org __ bind(&ok); 304864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 305864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 306864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org { Comment cmnt(masm_, "[ Body"); 307e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(loop_depth() == 0); 308864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org VisitStatements(function()->body()); 309e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(loop_depth() == 0); 310864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 311864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 312864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 313864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Always emit a 'return undefined' in case control fell off the end of 314864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // the body. 315864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org { Comment cmnt(masm_, "[ return <undefined>;"); 316864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(eax, isolate()->factory()->undefined_value()); 317864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org EmitReturnSequence(); 318864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 319864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 320864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 321864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 322864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid FullCodeGenerator::ClearAccumulator() { 323864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ Move(eax, Immediate(Smi::FromInt(0))); 324864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 325864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 326864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 327864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid FullCodeGenerator::EmitProfilingCounterDecrement(int delta) { 328864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(ebx, Immediate(profiling_counter_)); 329864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ sub(FieldOperand(ebx, Cell::kValueOffset), 330864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Immediate(Smi::FromInt(delta))); 331864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 332864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 333864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 334864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid FullCodeGenerator::EmitProfilingCounterReset() { 335864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int reset_value = FLAG_interrupt_budget; 336864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(ebx, Immediate(profiling_counter_)); 337864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(FieldOperand(ebx, Cell::kValueOffset), 338864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Immediate(Smi::FromInt(reset_value))); 339864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 340864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 341864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 342864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid FullCodeGenerator::EmitBackEdgeBookkeeping(IterationStatement* stmt, 343864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label* back_edge_target) { 344864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Comment cmnt(masm_, "[ Back edge bookkeeping"); 345864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label ok; 346864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 347e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(back_edge_target->is_bound()); 348864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int distance = masm_->SizeOfCodeGeneratedSince(back_edge_target); 349864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int weight = Min(kMaxBackEdgeWeight, 350864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Max(1, distance / kCodeSizeMultiplier)); 351864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org EmitProfilingCounterDecrement(weight); 352864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(positive, &ok, Label::kNear); 353864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ call(isolate()->builtins()->InterruptCheck(), RelocInfo::CODE_TARGET); 354864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 355864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Record a mapping of this PC offset to the OSR id. This is used to find 356864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // the AST id from the unoptimized code in order to use it as a key into 357864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // the deoptimization input data found in the optimized code. 358864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org RecordBackEdge(stmt->OsrEntryId()); 359864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 360864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org EmitProfilingCounterReset(); 361864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 362864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&ok); 363864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org PrepareForBailoutForId(stmt->EntryId(), NO_REGISTERS); 364864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Record a mapping of the OSR id to this PC. This is used if the OSR 365864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // entry becomes the target of a bailout. We don't expect it to be, but 366864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // we want it to work if it is. 367864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org PrepareForBailoutForId(stmt->OsrEntryId(), NO_REGISTERS); 368864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 369864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 370864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 371864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid FullCodeGenerator::EmitReturnSequence() { 372864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Comment cmnt(masm_, "[ Return sequence"); 373864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (return_label_.is_bound()) { 374864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ jmp(&return_label_); 375864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 376864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Common return label 377864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&return_label_); 378864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (FLAG_trace) { 379864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(eax); 380864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ CallRuntime(Runtime::kTraceExit, 1); 381864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 382864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Pretend that the exit is a backwards jump to the entry. 383864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int weight = 1; 384864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (info_->ShouldSelfOptimize()) { 385864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org weight = FLAG_interrupt_budget / FLAG_self_opt_count; 386864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 387864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int distance = masm_->pc_offset(); 388864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org weight = Min(kMaxBackEdgeWeight, 389864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Max(1, distance / kCodeSizeMultiplier)); 390864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 391864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org EmitProfilingCounterDecrement(weight); 392864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label ok; 393864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(positive, &ok, Label::kNear); 394864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(eax); 395864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ call(isolate()->builtins()->InterruptCheck(), 396864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org RelocInfo::CODE_TARGET); 397864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ pop(eax); 398864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org EmitProfilingCounterReset(); 399864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&ok); 400864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org#ifdef DEBUG 401864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Add a label for checking the size of the code used for returning. 402864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label check_exit_codesize; 403864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org masm_->bind(&check_exit_codesize); 404864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org#endif 405864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org SetSourcePosition(function()->end_position() - 1); 406864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ RecordJSReturn(); 407864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Do not use the leave instruction here because it is too short to 408864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // patch with the code required by the debugger. 409864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(esp, ebp); 410864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int no_frame_start = masm_->pc_offset(); 411864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ pop(ebp); 412864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 413864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int arguments_bytes = (info_->scope()->num_parameters() + 1) * kPointerSize; 414864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ Ret(arguments_bytes, ecx); 415864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Check that the size of the code used for returning is large enough 416864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // for the debugger's requirements. 417e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(Assembler::kJSReturnSequenceLength <= 418864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org masm_->SizeOfCodeGeneratedSince(&check_exit_codesize)); 419864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org info_->AddNoFrameRange(no_frame_start, masm_->pc_offset()); 420864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 421864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 422864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 423864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 424864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid FullCodeGenerator::EffectContext::Plug(Variable* var) const { 425e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(var->IsStackAllocated() || var->IsContextSlot()); 426864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 427864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 428864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 429864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid FullCodeGenerator::AccumulatorValueContext::Plug(Variable* var) const { 430e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(var->IsStackAllocated() || var->IsContextSlot()); 431864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org codegen()->GetVar(result_register(), var); 432864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 433864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 434864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 435864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid FullCodeGenerator::StackValueContext::Plug(Variable* var) const { 436e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(var->IsStackAllocated() || var->IsContextSlot()); 437864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org MemOperand operand = codegen()->VarOperand(var, result_register()); 438864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Memory operands can be pushed directly. 439864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(operand); 440864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 441864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 442864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 443864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid FullCodeGenerator::TestContext::Plug(Variable* var) const { 444864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // For simplicity we always test the accumulator register. 445864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org codegen()->GetVar(result_register(), var); 446864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org codegen()->PrepareForBailoutBeforeSplit(condition(), false, NULL, NULL); 447864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org codegen()->DoTest(this); 448864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 449864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 450864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 451864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid FullCodeGenerator::EffectContext::Plug(Heap::RootListIndex index) const { 452864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org UNREACHABLE(); // Not used on X87. 453864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 454864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 455864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 456864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid FullCodeGenerator::AccumulatorValueContext::Plug( 457864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Heap::RootListIndex index) const { 458864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org UNREACHABLE(); // Not used on X87. 459864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 460864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 461864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 462864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid FullCodeGenerator::StackValueContext::Plug( 463864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Heap::RootListIndex index) const { 464864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org UNREACHABLE(); // Not used on X87. 465864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 466864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 467864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 468864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid FullCodeGenerator::TestContext::Plug(Heap::RootListIndex index) const { 469864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org UNREACHABLE(); // Not used on X87. 470864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 471864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 472864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 473864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid FullCodeGenerator::EffectContext::Plug(Handle<Object> lit) const { 474864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 475864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 476864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 477864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid FullCodeGenerator::AccumulatorValueContext::Plug( 478864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Handle<Object> lit) const { 479864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (lit->IsSmi()) { 480864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ SafeMove(result_register(), Immediate(lit)); 481864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 482864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ Move(result_register(), Immediate(lit)); 483864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 484864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 485864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 486864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 487864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid FullCodeGenerator::StackValueContext::Plug(Handle<Object> lit) const { 488864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (lit->IsSmi()) { 489864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ SafePush(Immediate(lit)); 490864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 491864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(Immediate(lit)); 492864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 493864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 494864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 495864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 496864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid FullCodeGenerator::TestContext::Plug(Handle<Object> lit) const { 497864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org codegen()->PrepareForBailoutBeforeSplit(condition(), 498864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org true, 499864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org true_label_, 500864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org false_label_); 501e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!lit->IsUndetectableObject()); // There are no undetectable literals. 502864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (lit->IsUndefined() || lit->IsNull() || lit->IsFalse()) { 503864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (false_label_ != fall_through_) __ jmp(false_label_); 504864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else if (lit->IsTrue() || lit->IsJSObject()) { 505864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (true_label_ != fall_through_) __ jmp(true_label_); 506864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else if (lit->IsString()) { 507864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (String::cast(*lit)->length() == 0) { 508864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (false_label_ != fall_through_) __ jmp(false_label_); 509864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 510864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (true_label_ != fall_through_) __ jmp(true_label_); 511864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 512864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else if (lit->IsSmi()) { 513864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (Smi::cast(*lit)->value() == 0) { 514864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (false_label_ != fall_through_) __ jmp(false_label_); 515864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 516864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (true_label_ != fall_through_) __ jmp(true_label_); 517864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 518864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 519864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // For simplicity we always test the accumulator register. 520864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(result_register(), lit); 521864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org codegen()->DoTest(this); 522864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 523864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 524864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 525864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 526864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid FullCodeGenerator::EffectContext::DropAndPlug(int count, 527864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register reg) const { 528e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(count > 0); 529864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ Drop(count); 530864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 531864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 532864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 533864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid FullCodeGenerator::AccumulatorValueContext::DropAndPlug( 534864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int count, 535864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register reg) const { 536e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(count > 0); 537864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ Drop(count); 538864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ Move(result_register(), reg); 539864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 540864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 541864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 542864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid FullCodeGenerator::StackValueContext::DropAndPlug(int count, 543864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register reg) const { 544e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(count > 0); 545864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (count > 1) __ Drop(count - 1); 546864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(Operand(esp, 0), reg); 547864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 548864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 549864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 550864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid FullCodeGenerator::TestContext::DropAndPlug(int count, 551864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register reg) const { 552e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(count > 0); 553864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // For simplicity we always test the accumulator register. 554864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ Drop(count); 555864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ Move(result_register(), reg); 556864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org codegen()->PrepareForBailoutBeforeSplit(condition(), false, NULL, NULL); 557864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org codegen()->DoTest(this); 558864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 559864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 560864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 561864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid FullCodeGenerator::EffectContext::Plug(Label* materialize_true, 562864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label* materialize_false) const { 563e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(materialize_true == materialize_false); 564864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(materialize_true); 565864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 566864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 567864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 568864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid FullCodeGenerator::AccumulatorValueContext::Plug( 569864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label* materialize_true, 570864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label* materialize_false) const { 571864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label done; 572864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(materialize_true); 573864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(result_register(), isolate()->factory()->true_value()); 574864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ jmp(&done, Label::kNear); 575864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(materialize_false); 576864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(result_register(), isolate()->factory()->false_value()); 577864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&done); 578864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 579864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 580864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 581864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid FullCodeGenerator::StackValueContext::Plug( 582864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label* materialize_true, 583864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label* materialize_false) const { 584864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label done; 585864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(materialize_true); 586864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(Immediate(isolate()->factory()->true_value())); 587864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ jmp(&done, Label::kNear); 588864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(materialize_false); 589864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(Immediate(isolate()->factory()->false_value())); 590864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&done); 591864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 592864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 593864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 594864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid FullCodeGenerator::TestContext::Plug(Label* materialize_true, 595864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label* materialize_false) const { 596e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(materialize_true == true_label_); 597e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(materialize_false == false_label_); 598864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 599864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 600864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 601864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid FullCodeGenerator::EffectContext::Plug(bool flag) const { 602864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 603864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 604864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 605864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid FullCodeGenerator::AccumulatorValueContext::Plug(bool flag) const { 606864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Handle<Object> value = flag 607864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ? isolate()->factory()->true_value() 608864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org : isolate()->factory()->false_value(); 609864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(result_register(), value); 610864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 611864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 612864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 613864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid FullCodeGenerator::StackValueContext::Plug(bool flag) const { 614864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Handle<Object> value = flag 615864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ? isolate()->factory()->true_value() 616864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org : isolate()->factory()->false_value(); 617864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(Immediate(value)); 618864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 619864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 620864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 621864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid FullCodeGenerator::TestContext::Plug(bool flag) const { 622864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org codegen()->PrepareForBailoutBeforeSplit(condition(), 623864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org true, 624864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org true_label_, 625864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org false_label_); 626864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (flag) { 627864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (true_label_ != fall_through_) __ jmp(true_label_); 628864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 629864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (false_label_ != fall_through_) __ jmp(false_label_); 630864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 631864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 632864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 633864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 634864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid FullCodeGenerator::DoTest(Expression* condition, 635864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label* if_true, 636864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label* if_false, 637864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label* fall_through) { 638864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Handle<Code> ic = ToBooleanStub::GetUninitialized(isolate()); 639864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org CallIC(ic, condition->test_id()); 640864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ test(result_register(), result_register()); 641864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // The stub returns nonzero for true. 642864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Split(not_zero, if_true, if_false, fall_through); 643864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 644864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 645864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 646864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid FullCodeGenerator::Split(Condition cc, 647864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label* if_true, 648864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label* if_false, 649864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label* fall_through) { 650864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (if_false == fall_through) { 651864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(cc, if_true); 652864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else if (if_true == fall_through) { 653864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(NegateCondition(cc), if_false); 654864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 655864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(cc, if_true); 656864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ jmp(if_false); 657864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 658864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 659864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 660864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 661864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgMemOperand FullCodeGenerator::StackOperand(Variable* var) { 662e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(var->IsStackAllocated()); 663864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Offset is negative because higher indexes are at lower addresses. 664864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int offset = -var->index() * kPointerSize; 665864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Adjust by a (parameter or local) base offset. 666864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (var->IsParameter()) { 667864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org offset += (info_->scope()->num_parameters() + 1) * kPointerSize; 668864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 669864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org offset += JavaScriptFrameConstants::kLocal0Offset; 670864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 671864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return Operand(ebp, offset); 672864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 673864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 674864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 675864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgMemOperand FullCodeGenerator::VarOperand(Variable* var, Register scratch) { 676e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(var->IsContextSlot() || var->IsStackAllocated()); 677864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (var->IsContextSlot()) { 678864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int context_chain_length = scope()->ContextChainLength(var->scope()); 679864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ LoadContext(scratch, context_chain_length); 680864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return ContextOperand(scratch, var->index()); 681864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 682864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return StackOperand(var); 683864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 684864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 685864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 686864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 687864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid FullCodeGenerator::GetVar(Register dest, Variable* var) { 688e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(var->IsContextSlot() || var->IsStackAllocated()); 689864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org MemOperand location = VarOperand(var, dest); 690864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(dest, location); 691864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 692864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 693864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 694864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid FullCodeGenerator::SetVar(Variable* var, 695864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register src, 696864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register scratch0, 697864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register scratch1) { 698e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(var->IsContextSlot() || var->IsStackAllocated()); 699e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!scratch0.is(src)); 700e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!scratch0.is(scratch1)); 701e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!scratch1.is(src)); 702864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org MemOperand location = VarOperand(var, scratch0); 703864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(location, src); 704864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 705864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Emit the write barrier code if the location is in the heap. 706864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (var->IsContextSlot()) { 707864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int offset = Context::SlotOffset(var->index()); 708e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!scratch0.is(esi) && !src.is(esi) && !scratch1.is(esi)); 70906b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ RecordWriteContextSlot(scratch0, offset, src, scratch1, kDontSaveFPRegs); 710864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 711864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 712864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 713864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 714864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid FullCodeGenerator::PrepareForBailoutBeforeSplit(Expression* expr, 715864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org bool should_normalize, 716864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label* if_true, 717864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label* if_false) { 718864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Only prepare for bailouts before splits if we're in a test 719864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // context. Otherwise, we let the Visit function deal with the 720864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // preparation to avoid preparing with the same AST id twice. 721864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (!context()->IsTest() || !info_->IsOptimizable()) return; 722864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 723864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label skip; 724864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (should_normalize) __ jmp(&skip, Label::kNear); 725864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org PrepareForBailout(expr, TOS_REG); 726864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (should_normalize) { 727864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ cmp(eax, isolate()->factory()->true_value()); 728864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Split(equal, if_true, if_false, NULL); 729864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&skip); 730864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 731864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 732864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 733864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 734864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid FullCodeGenerator::EmitDebugCheckDeclarationContext(Variable* variable) { 735864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // The variable in the declaration always resides in the current context. 736e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK_EQ(0, scope()->ContextChainLength(variable->scope())); 737864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (generate_debug_code_) { 738864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Check that we're not inside a with or catch context. 739864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(ebx, FieldOperand(esi, HeapObject::kMapOffset)); 740864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ cmp(ebx, isolate()->factory()->with_context_map()); 741864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ Check(not_equal, kDeclarationInWithContext); 742864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ cmp(ebx, isolate()->factory()->catch_context_map()); 743864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ Check(not_equal, kDeclarationInCatchContext); 744864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 745864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 746864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 747864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 748864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid FullCodeGenerator::VisitVariableDeclaration( 749864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org VariableDeclaration* declaration) { 750864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // If it was not possible to allocate the variable at compile time, we 751864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // need to "declare" it at runtime to make sure it actually exists in the 752864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // local context. 753864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org VariableProxy* proxy = declaration->proxy(); 754864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org VariableMode mode = declaration->mode(); 755864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Variable* variable = proxy->var(); 756864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org bool hole_init = mode == LET || mode == CONST || mode == CONST_LEGACY; 757864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org switch (variable->location()) { 758864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case Variable::UNALLOCATED: 759864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org globals_->Add(variable->name(), zone()); 760864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org globals_->Add(variable->binding_needs_init() 761864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ? isolate()->factory()->the_hole_value() 762864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org : isolate()->factory()->undefined_value(), zone()); 763864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org break; 764864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 765864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case Variable::PARAMETER: 766864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case Variable::LOCAL: 767864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (hole_init) { 768864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Comment cmnt(masm_, "[ VariableDeclaration"); 769864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(StackOperand(variable), 770864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Immediate(isolate()->factory()->the_hole_value())); 771864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 772864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org break; 773864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 774864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case Variable::CONTEXT: 775864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (hole_init) { 776864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Comment cmnt(masm_, "[ VariableDeclaration"); 777864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org EmitDebugCheckDeclarationContext(variable); 778864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(ContextOperand(esi, variable->index()), 779864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Immediate(isolate()->factory()->the_hole_value())); 780864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // No write barrier since the hole value is in old space. 781864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org PrepareForBailoutForId(proxy->id(), NO_REGISTERS); 782864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 783864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org break; 784864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 785864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case Variable::LOOKUP: { 786864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Comment cmnt(masm_, "[ VariableDeclaration"); 787864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(esi); 788864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(Immediate(variable->name())); 789864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // VariableDeclaration nodes are always introduced in one of four modes. 790e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(IsDeclaredVariableMode(mode)); 791864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org PropertyAttributes attr = 792864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org IsImmutableVariableMode(mode) ? READ_ONLY : NONE; 793864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(Immediate(Smi::FromInt(attr))); 794864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Push initial value, if any. 795864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Note: For variables we must not push an initial value (such as 796864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // 'undefined') because we may have a (legal) redeclaration and we 797864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // must not destroy the current value. 798864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (hole_init) { 799864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(Immediate(isolate()->factory()->the_hole_value())); 800864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 801864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(Immediate(Smi::FromInt(0))); // Indicates no initial value. 802864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 803d6472083da14af6fde0101cc78f95ababd7cc077machenbach@chromium.org __ CallRuntime(Runtime::kDeclareLookupSlot, 4); 804864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org break; 805864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 806864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 807864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 808864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 809864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 810864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid FullCodeGenerator::VisitFunctionDeclaration( 811864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org FunctionDeclaration* declaration) { 812864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org VariableProxy* proxy = declaration->proxy(); 813864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Variable* variable = proxy->var(); 814864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org switch (variable->location()) { 815864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case Variable::UNALLOCATED: { 816864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org globals_->Add(variable->name(), zone()); 817864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Handle<SharedFunctionInfo> function = 8187c0666e15d1f68f0fef5db9e5c409fab010ed816machenbach@chromium.org Compiler::BuildFunctionInfo(declaration->fun(), script(), info_); 819864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Check for stack-overflow exception. 820864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (function.is_null()) return SetStackOverflow(); 821864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org globals_->Add(function, zone()); 822864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org break; 823864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 824864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 825864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case Variable::PARAMETER: 826864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case Variable::LOCAL: { 827864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Comment cmnt(masm_, "[ FunctionDeclaration"); 828864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org VisitForAccumulatorValue(declaration->fun()); 829864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(StackOperand(variable), result_register()); 830864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org break; 831864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 832864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 833864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case Variable::CONTEXT: { 834864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Comment cmnt(masm_, "[ FunctionDeclaration"); 835864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org EmitDebugCheckDeclarationContext(variable); 836864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org VisitForAccumulatorValue(declaration->fun()); 837864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(ContextOperand(esi, variable->index()), result_register()); 838864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // We know that we have written a function, which is not a smi. 83906b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ RecordWriteContextSlot(esi, Context::SlotOffset(variable->index()), 84006b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org result_register(), ecx, kDontSaveFPRegs, 84106b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org EMIT_REMEMBERED_SET, OMIT_SMI_CHECK); 842864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org PrepareForBailoutForId(proxy->id(), NO_REGISTERS); 843864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org break; 844864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 845864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 846864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case Variable::LOOKUP: { 847864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Comment cmnt(masm_, "[ FunctionDeclaration"); 848864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(esi); 849864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(Immediate(variable->name())); 850864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(Immediate(Smi::FromInt(NONE))); 851864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org VisitForStackValue(declaration->fun()); 852d6472083da14af6fde0101cc78f95ababd7cc077machenbach@chromium.org __ CallRuntime(Runtime::kDeclareLookupSlot, 4); 853864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org break; 854864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 855864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 856864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 857864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 858864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 859864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid FullCodeGenerator::VisitModuleDeclaration(ModuleDeclaration* declaration) { 860864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Variable* variable = declaration->proxy()->var(); 861e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(variable->location() == Variable::CONTEXT); 862e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(variable->interface()->IsFrozen()); 863864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 864864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Comment cmnt(masm_, "[ ModuleDeclaration"); 865864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org EmitDebugCheckDeclarationContext(variable); 866864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 867864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Load instance object. 868864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ LoadContext(eax, scope_->ContextChainLength(scope_->GlobalScope())); 869864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(eax, ContextOperand(eax, variable->interface()->Index())); 870864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(eax, ContextOperand(eax, Context::EXTENSION_INDEX)); 871864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 872864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Assign it. 873864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(ContextOperand(esi, variable->index()), eax); 874864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // We know that we have written a module, which is not a smi. 87506b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ RecordWriteContextSlot(esi, Context::SlotOffset(variable->index()), eax, 87606b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org ecx, kDontSaveFPRegs, EMIT_REMEMBERED_SET, 877864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org OMIT_SMI_CHECK); 878864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org PrepareForBailoutForId(declaration->proxy()->id(), NO_REGISTERS); 879864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 880864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Traverse into body. 881864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Visit(declaration->module()); 882864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 883864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 884864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 885864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid FullCodeGenerator::VisitImportDeclaration(ImportDeclaration* declaration) { 886864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org VariableProxy* proxy = declaration->proxy(); 887864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Variable* variable = proxy->var(); 888864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org switch (variable->location()) { 889864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case Variable::UNALLOCATED: 890864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // TODO(rossberg) 891864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org break; 892864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 893864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case Variable::CONTEXT: { 894864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Comment cmnt(masm_, "[ ImportDeclaration"); 895864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org EmitDebugCheckDeclarationContext(variable); 896864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // TODO(rossberg) 897864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org break; 898864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 899864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 900864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case Variable::PARAMETER: 901864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case Variable::LOCAL: 902864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case Variable::LOOKUP: 903864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org UNREACHABLE(); 904864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 905864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 906864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 907864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 908864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid FullCodeGenerator::VisitExportDeclaration(ExportDeclaration* declaration) { 909864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // TODO(rossberg) 910864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 911864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 912864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 913864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid FullCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) { 914864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Call the runtime to declare the globals. 915864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(esi); // The context is the first argument. 916864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ Push(pairs); 917864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ Push(Smi::FromInt(DeclareGlobalsFlags())); 91847390597afd6b17870f41dfb5dd8c057aea1f068machenbach@chromium.org __ CallRuntime(Runtime::kDeclareGlobals, 3); 919864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Return value is ignored. 920864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 921864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 922864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 923864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid FullCodeGenerator::DeclareModules(Handle<FixedArray> descriptions) { 924864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Call the runtime to declare the modules. 925864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ Push(descriptions); 92647390597afd6b17870f41dfb5dd8c057aea1f068machenbach@chromium.org __ CallRuntime(Runtime::kDeclareModules, 1); 927864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Return value is ignored. 928864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 929864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 930864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 931864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid FullCodeGenerator::VisitSwitchStatement(SwitchStatement* stmt) { 932864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Comment cmnt(masm_, "[ SwitchStatement"); 933864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Breakable nested_statement(this, stmt); 934864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org SetStatementPosition(stmt); 935864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 936864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Keep the switch value on the stack until a case matches. 937864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org VisitForStackValue(stmt->tag()); 938864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org PrepareForBailoutForId(stmt->EntryId(), NO_REGISTERS); 939864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 940864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ZoneList<CaseClause*>* clauses = stmt->cases(); 941864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org CaseClause* default_clause = NULL; // Can occur anywhere in the list. 942864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 943864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label next_test; // Recycled for each test. 944864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Compile all the tests with branches to their bodies. 945864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org for (int i = 0; i < clauses->length(); i++) { 946864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org CaseClause* clause = clauses->at(i); 947864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org clause->body_target()->Unuse(); 948864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 949864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // The default is not a test, but remember it as final fall through. 950864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (clause->is_default()) { 951864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org default_clause = clause; 952864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org continue; 953864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 954864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 955864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Comment cmnt(masm_, "[ Case comparison"); 956864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&next_test); 957864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org next_test.Unuse(); 958864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 959864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Compile the label expression. 960864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org VisitForAccumulatorValue(clause->label()); 961864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 962864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Perform the comparison as if via '==='. 963864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(edx, Operand(esp, 0)); // Switch value. 964864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org bool inline_smi_code = ShouldInlineSmiCase(Token::EQ_STRICT); 965864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org JumpPatchSite patch_site(masm_); 966864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (inline_smi_code) { 967864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label slow_case; 968864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(ecx, edx); 969864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ or_(ecx, eax); 970864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org patch_site.EmitJumpIfNotSmi(ecx, &slow_case, Label::kNear); 971864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 972864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ cmp(edx, eax); 973864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(not_equal, &next_test); 974864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ Drop(1); // Switch value is no longer needed. 975864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ jmp(clause->body_target()); 976864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&slow_case); 977864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 978864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 979864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Record position before stub call for type feedback. 980864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org SetSourcePosition(clause->position()); 981b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org Handle<Code> ic = 982b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org CodeFactory::CompareIC(isolate(), Token::EQ_STRICT).code(); 983864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org CallIC(ic, clause->CompareId()); 984864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org patch_site.EmitPatchInfo(); 985864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 986864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label skip; 987864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ jmp(&skip, Label::kNear); 988864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org PrepareForBailout(clause, TOS_REG); 989864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ cmp(eax, isolate()->factory()->true_value()); 990864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(not_equal, &next_test); 991864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ Drop(1); 992864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ jmp(clause->body_target()); 993864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&skip); 994864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 995864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ test(eax, eax); 996864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(not_equal, &next_test); 997864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ Drop(1); // Switch value is no longer needed. 998864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ jmp(clause->body_target()); 999864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 1000864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1001864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Discard the test value and jump to the default if present, otherwise to 1002864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // the end of the statement. 1003864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&next_test); 1004864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ Drop(1); // Switch value is no longer needed. 1005864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (default_clause == NULL) { 1006864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ jmp(nested_statement.break_label()); 1007864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 1008864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ jmp(default_clause->body_target()); 1009864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 1010864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1011864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Compile all the case bodies. 1012864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org for (int i = 0; i < clauses->length(); i++) { 1013864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Comment cmnt(masm_, "[ Case body"); 1014864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org CaseClause* clause = clauses->at(i); 1015864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(clause->body_target()); 1016864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org PrepareForBailoutForId(clause->EntryId(), NO_REGISTERS); 1017864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org VisitStatements(clause->statements()); 1018864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 1019864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1020864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(nested_statement.break_label()); 1021864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS); 1022864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 1023864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1024864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1025864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) { 1026864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Comment cmnt(masm_, "[ ForInStatement"); 1027864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int slot = stmt->ForInFeedbackSlot(); 1028864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1029864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org SetStatementPosition(stmt); 1030864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1031864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label loop, exit; 1032864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ForIn loop_statement(this, stmt); 1033864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org increment_loop_depth(); 1034864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1035864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Get the object to enumerate over. If the object is null or undefined, skip 1036864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // over the loop. See ECMA-262 version 5, section 12.6.4. 1037864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org VisitForAccumulatorValue(stmt->enumerable()); 1038864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ cmp(eax, isolate()->factory()->undefined_value()); 1039864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(equal, &exit); 1040864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ cmp(eax, isolate()->factory()->null_value()); 1041864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(equal, &exit); 1042864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1043864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org PrepareForBailoutForId(stmt->PrepareId(), TOS_REG); 1044864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1045864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Convert the object to a JS object. 1046864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label convert, done_convert; 1047864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ JumpIfSmi(eax, &convert, Label::kNear); 1048864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ CmpObjectType(eax, FIRST_SPEC_OBJECT_TYPE, ecx); 1049864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(above_equal, &done_convert, Label::kNear); 1050864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&convert); 1051864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(eax); 1052864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ InvokeBuiltin(Builtins::TO_OBJECT, CALL_FUNCTION); 1053864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&done_convert); 1054864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(eax); 1055864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1056864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Check for proxies. 1057864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label call_runtime, use_cache, fixed_array; 1058864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org STATIC_ASSERT(FIRST_JS_PROXY_TYPE == FIRST_SPEC_OBJECT_TYPE); 1059864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ CmpObjectType(eax, LAST_JS_PROXY_TYPE, ecx); 1060864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(below_equal, &call_runtime); 1061864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1062864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Check cache validity in generated code. This is a fast case for 1063864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // the JSObject::IsSimpleEnum cache validity checks. If we cannot 1064864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // guarantee cache validity, call the runtime system to check cache 1065864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // validity or get the property names in a fixed array. 1066864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ CheckEnumCache(&call_runtime); 1067864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1068864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(eax, FieldOperand(eax, HeapObject::kMapOffset)); 1069864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ jmp(&use_cache, Label::kNear); 1070864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1071864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Get the set of properties to enumerate. 1072864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&call_runtime); 1073864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(eax); 1074864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ CallRuntime(Runtime::kGetPropertyNamesFast, 1); 1075864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ cmp(FieldOperand(eax, HeapObject::kMapOffset), 1076864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org isolate()->factory()->meta_map()); 1077864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(not_equal, &fixed_array); 1078864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1079864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1080864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // We got a map in register eax. Get the enumeration cache from it. 1081864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label no_descriptors; 1082864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&use_cache); 1083864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1084864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ EnumLength(edx, eax); 1085864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ cmp(edx, Immediate(Smi::FromInt(0))); 1086864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(equal, &no_descriptors); 1087864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1088864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ LoadInstanceDescriptors(eax, ecx); 1089864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(ecx, FieldOperand(ecx, DescriptorArray::kEnumCacheOffset)); 1090864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(ecx, FieldOperand(ecx, DescriptorArray::kEnumCacheBridgeCacheOffset)); 1091864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1092864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Set up the four remaining stack slots. 1093864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(eax); // Map. 1094864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(ecx); // Enumeration cache. 1095864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(edx); // Number of valid entries for the map in the enum cache. 1096864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(Immediate(Smi::FromInt(0))); // Initial index. 1097864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ jmp(&loop); 1098864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1099864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&no_descriptors); 1100864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ add(esp, Immediate(kPointerSize)); 1101864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ jmp(&exit); 1102864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1103864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // We got a fixed array in register eax. Iterate through that. 1104864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label non_proxy; 1105864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&fixed_array); 1106864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1107864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // No need for a write barrier, we are storing a Smi in the feedback vector. 1108864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ LoadHeapObject(ebx, FeedbackVector()); 1109864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(FieldOperand(ebx, FixedArray::OffsetOfElementAt(slot)), 1110a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org Immediate(TypeFeedbackVector::MegamorphicSentinel(isolate()))); 1111864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1112864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(ebx, Immediate(Smi::FromInt(1))); // Smi indicates slow check 1113864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(ecx, Operand(esp, 0 * kPointerSize)); // Get enumerated object 1114864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org STATIC_ASSERT(FIRST_JS_PROXY_TYPE == FIRST_SPEC_OBJECT_TYPE); 1115864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ CmpObjectType(ecx, LAST_JS_PROXY_TYPE, ecx); 1116864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(above, &non_proxy); 1117864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ Move(ebx, Immediate(Smi::FromInt(0))); // Zero indicates proxy 1118864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&non_proxy); 1119864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(ebx); // Smi 1120864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(eax); // Array 1121864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(eax, FieldOperand(eax, FixedArray::kLengthOffset)); 1122864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(eax); // Fixed array length (as smi). 1123864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(Immediate(Smi::FromInt(0))); // Initial index. 1124864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1125864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Generate code for doing the condition check. 1126864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org PrepareForBailoutForId(stmt->BodyId(), NO_REGISTERS); 1127864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&loop); 1128864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(eax, Operand(esp, 0 * kPointerSize)); // Get the current index. 1129864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ cmp(eax, Operand(esp, 1 * kPointerSize)); // Compare to the array length. 1130864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(above_equal, loop_statement.break_label()); 1131864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1132864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Get the current entry of the array into register ebx. 1133864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(ebx, Operand(esp, 2 * kPointerSize)); 1134864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(ebx, FieldOperand(ebx, eax, times_2, FixedArray::kHeaderSize)); 1135864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1136864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Get the expected map from the stack or a smi in the 1137864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // permanent slow case into register edx. 1138864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(edx, Operand(esp, 3 * kPointerSize)); 1139864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1140864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Check if the expected map still matches that of the enumerable. 1141864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // If not, we may have to filter the key. 1142864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label update_each; 1143864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(ecx, Operand(esp, 4 * kPointerSize)); 1144864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ cmp(edx, FieldOperand(ecx, HeapObject::kMapOffset)); 1145864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(equal, &update_each, Label::kNear); 1146864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1147864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // For proxies, no filtering is done. 1148864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // TODO(rossberg): What if only a prototype is a proxy? Not specified yet. 1149e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(Smi::FromInt(0) == 0); 1150864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ test(edx, edx); 1151864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(zero, &update_each); 1152864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1153864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Convert the entry to a string or null if it isn't a property 1154864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // anymore. If the property has been removed while iterating, we 1155864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // just skip it. 1156864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(ecx); // Enumerable. 1157864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(ebx); // Current entry. 1158864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ InvokeBuiltin(Builtins::FILTER_KEY, CALL_FUNCTION); 1159864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ test(eax, eax); 1160864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(equal, loop_statement.continue_label()); 1161864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(ebx, eax); 1162864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1163864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Update the 'each' property or variable from the possibly filtered 1164864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // entry in register ebx. 1165864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&update_each); 1166864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(result_register(), ebx); 1167864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Perform the assignment as if via '='. 1168864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org { EffectContext context(this); 1169864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org EmitAssignment(stmt->each()); 1170864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 1171864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1172864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Generate code for the body of the loop. 1173864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Visit(stmt->body()); 1174864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1175864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Generate code for going to the next element by incrementing the 1176864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // index (smi) stored on top of the stack. 1177864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(loop_statement.continue_label()); 1178864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ add(Operand(esp, 0 * kPointerSize), Immediate(Smi::FromInt(1))); 1179864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1180864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org EmitBackEdgeBookkeeping(stmt, &loop); 1181864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ jmp(&loop); 1182864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1183864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Remove the pointers stored on the stack. 1184864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(loop_statement.break_label()); 1185864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ add(esp, Immediate(5 * kPointerSize)); 1186864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1187864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Exit and decrement the loop depth. 1188864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS); 1189864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&exit); 1190864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org decrement_loop_depth(); 1191864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 1192864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1193864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1194864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid FullCodeGenerator::VisitForOfStatement(ForOfStatement* stmt) { 1195864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Comment cmnt(masm_, "[ ForOfStatement"); 1196864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org SetStatementPosition(stmt); 1197864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1198864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Iteration loop_statement(this, stmt); 1199864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org increment_loop_depth(); 1200864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 12011845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org // var iterator = iterable[Symbol.iterator](); 12021845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org VisitForEffect(stmt->assign_iterator()); 1203864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1204864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Loop entry. 1205864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(loop_statement.continue_label()); 1206864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1207864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // result = iterator.next() 1208864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org VisitForEffect(stmt->next_result()); 1209864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1210864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // if (result.done) break; 1211864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label result_not_done; 1212864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org VisitForControl(stmt->result_done(), 1213864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org loop_statement.break_label(), 1214864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org &result_not_done, 1215864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org &result_not_done); 1216864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&result_not_done); 1217864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1218864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // each = result.value 1219864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org VisitForEffect(stmt->assign_each()); 1220864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1221864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Generate code for the body of the loop. 1222864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Visit(stmt->body()); 1223864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1224864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Check stack before looping. 1225864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org PrepareForBailoutForId(stmt->BackEdgeId(), NO_REGISTERS); 1226864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org EmitBackEdgeBookkeeping(stmt, loop_statement.continue_label()); 1227864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ jmp(loop_statement.continue_label()); 1228864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1229864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Exit and decrement the loop depth. 1230864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS); 1231864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(loop_statement.break_label()); 1232864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org decrement_loop_depth(); 1233864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 1234864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1235864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1236864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid FullCodeGenerator::EmitNewClosure(Handle<SharedFunctionInfo> info, 1237864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org bool pretenure) { 1238864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Use the fast case closure allocation code that allocates in new 1239864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // space for nested functions that don't need literals cloning. If 1240864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // we're running with the --always-opt or the --prepare-always-opt 1241864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // flag, we need to use the runtime function so that the new function 1242864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // we are creating here gets a chance to have its code optimized and 1243864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // doesn't just get a copy of the existing unoptimized code. 1244864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (!FLAG_always_opt && 1245864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org !FLAG_prepare_always_opt && 1246864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org !pretenure && 1247864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org scope()->is_function_scope() && 1248864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org info->num_literals() == 0) { 12492c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org FastNewClosureStub stub(isolate(), info->strict_mode(), info->kind()); 1250864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(ebx, Immediate(info)); 1251864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ CallStub(&stub); 1252864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 1253864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(esi); 1254864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(Immediate(info)); 1255864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(Immediate(pretenure 1256864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ? isolate()->factory()->true_value() 1257864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org : isolate()->factory()->false_value())); 125847390597afd6b17870f41dfb5dd8c057aea1f068machenbach@chromium.org __ CallRuntime(Runtime::kNewClosure, 3); 1259864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 1260864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org context()->Plug(eax); 1261864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 1262864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1263864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1264864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid FullCodeGenerator::VisitVariableProxy(VariableProxy* expr) { 1265864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Comment cmnt(masm_, "[ VariableProxy"); 1266864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org EmitVariableLoad(expr); 1267864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 1268864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1269864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1270a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.orgvoid FullCodeGenerator::EmitLoadHomeObject(SuperReference* expr) { 1271a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org Comment cnmt(masm_, "[ SuperReference "); 1272a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org 1273a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org __ mov(LoadDescriptor::ReceiverRegister(), 1274a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org Operand(ebp, JavaScriptFrameConstants::kFunctionOffset)); 1275a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org 1276a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org Handle<Symbol> home_object_symbol(isolate()->heap()->home_object_symbol()); 1277a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org __ mov(LoadDescriptor::NameRegister(), home_object_symbol); 1278a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org 1279a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org CallLoadIC(NOT_CONTEXTUAL, expr->HomeObjectFeedbackId()); 1280a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org 1281a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org __ cmp(eax, isolate()->factory()->undefined_value()); 1282a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org Label done; 1283a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org __ j(not_equal, &done); 1284a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org __ CallRuntime(Runtime::kThrowNonMethodError, 0); 1285a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org __ bind(&done); 1286a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org} 1287a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org 1288a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org 12897c0666e15d1f68f0fef5db9e5c409fab010ed816machenbach@chromium.orgvoid FullCodeGenerator::EmitLoadGlobalCheckExtensions(VariableProxy* proxy, 1290864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org TypeofState typeof_state, 1291864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label* slow) { 1292864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register context = esi; 1293864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register temp = edx; 1294864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1295864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Scope* s = scope(); 1296864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org while (s != NULL) { 1297864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (s->num_heap_slots() > 0) { 1298864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (s->calls_sloppy_eval()) { 1299864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Check that extension is NULL. 1300864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ cmp(ContextOperand(context, Context::EXTENSION_INDEX), 1301864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Immediate(0)); 1302864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(not_equal, slow); 1303864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 1304864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Load next context in chain. 1305864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(temp, ContextOperand(context, Context::PREVIOUS_INDEX)); 1306864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Walk the rest of the chain without clobbering esi. 1307864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org context = temp; 1308864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 1309864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // If no outer scope calls eval, we do not need to check more 1310864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // context extensions. If we have reached an eval scope, we check 1311864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // all extensions from this point. 1312864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (!s->outer_scope_calls_sloppy_eval() || s->is_eval_scope()) break; 1313864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org s = s->outer_scope(); 1314864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 1315864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1316864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (s != NULL && s->is_eval_scope()) { 1317864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Loop up the context chain. There is no frame effect so it is 1318864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // safe to use raw labels here. 1319864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label next, fast; 1320864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (!context.is(temp)) { 1321864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(temp, context); 1322864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 1323864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&next); 1324864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Terminate at native context. 1325864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ cmp(FieldOperand(temp, HeapObject::kMapOffset), 1326864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Immediate(isolate()->factory()->native_context_map())); 1327864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(equal, &fast, Label::kNear); 1328864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Check that extension is NULL. 1329864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ cmp(ContextOperand(temp, Context::EXTENSION_INDEX), Immediate(0)); 1330864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(not_equal, slow); 1331864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Load next context in chain. 1332864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(temp, ContextOperand(temp, Context::PREVIOUS_INDEX)); 1333864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ jmp(&next); 1334864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&fast); 1335864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 1336864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1337864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // All extension objects were empty and it is safe to use a global 1338864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // load IC call. 133942ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org __ mov(LoadDescriptor::ReceiverRegister(), GlobalObjectOperand()); 134042ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org __ mov(LoadDescriptor::NameRegister(), proxy->var()->name()); 13417c0666e15d1f68f0fef5db9e5c409fab010ed816machenbach@chromium.org if (FLAG_vector_ics) { 134242ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org __ mov(VectorLoadICDescriptor::SlotRegister(), 13437c0666e15d1f68f0fef5db9e5c409fab010ed816machenbach@chromium.org Immediate(Smi::FromInt(proxy->VariableFeedbackSlot()))); 13447c0666e15d1f68f0fef5db9e5c409fab010ed816machenbach@chromium.org } 13457c0666e15d1f68f0fef5db9e5c409fab010ed816machenbach@chromium.org 1346864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ContextualMode mode = (typeof_state == INSIDE_TYPEOF) 1347864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ? NOT_CONTEXTUAL 1348864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org : CONTEXTUAL; 1349864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1350864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org CallLoadIC(mode); 1351864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 1352864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1353864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1354864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgMemOperand FullCodeGenerator::ContextSlotOperandCheckExtensions(Variable* var, 1355864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label* slow) { 1356e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(var->IsContextSlot()); 1357864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register context = esi; 1358864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register temp = ebx; 1359864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1360864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org for (Scope* s = scope(); s != var->scope(); s = s->outer_scope()) { 1361864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (s->num_heap_slots() > 0) { 1362864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (s->calls_sloppy_eval()) { 1363864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Check that extension is NULL. 1364864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ cmp(ContextOperand(context, Context::EXTENSION_INDEX), 1365864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Immediate(0)); 1366864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(not_equal, slow); 1367864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 1368864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(temp, ContextOperand(context, Context::PREVIOUS_INDEX)); 1369864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Walk the rest of the chain without clobbering esi. 1370864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org context = temp; 1371864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 1372864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 1373864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Check that last extension is NULL. 1374864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ cmp(ContextOperand(context, Context::EXTENSION_INDEX), Immediate(0)); 1375864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(not_equal, slow); 1376864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1377864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // This function is used only for loads, not stores, so it's safe to 1378864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // return an esi-based operand (the write barrier cannot be allowed to 1379864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // destroy the esi register). 1380864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return ContextOperand(context, var->index()); 1381864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 1382864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1383864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 13847c0666e15d1f68f0fef5db9e5c409fab010ed816machenbach@chromium.orgvoid FullCodeGenerator::EmitDynamicLookupFastCase(VariableProxy* proxy, 1385864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org TypeofState typeof_state, 1386864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label* slow, 1387864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label* done) { 1388864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Generate fast-case code for variables that might be shadowed by 1389864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // eval-introduced variables. Eval is used a lot without 1390864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // introducing variables. In those cases, we do not want to 1391864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // perform a runtime call for all variables in the scope 1392864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // containing the eval. 13937c0666e15d1f68f0fef5db9e5c409fab010ed816machenbach@chromium.org Variable* var = proxy->var(); 1394864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (var->mode() == DYNAMIC_GLOBAL) { 13957c0666e15d1f68f0fef5db9e5c409fab010ed816machenbach@chromium.org EmitLoadGlobalCheckExtensions(proxy, typeof_state, slow); 1396864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ jmp(done); 1397864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else if (var->mode() == DYNAMIC_LOCAL) { 1398864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Variable* local = var->local_if_not_shadowed(); 1399864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(eax, ContextSlotOperandCheckExtensions(local, slow)); 1400864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (local->mode() == LET || local->mode() == CONST || 1401864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org local->mode() == CONST_LEGACY) { 1402864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ cmp(eax, isolate()->factory()->the_hole_value()); 1403864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(not_equal, done); 1404864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (local->mode() == CONST_LEGACY) { 1405864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(eax, isolate()->factory()->undefined_value()); 1406864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { // LET || CONST 1407864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(Immediate(var->name())); 140847390597afd6b17870f41dfb5dd8c057aea1f068machenbach@chromium.org __ CallRuntime(Runtime::kThrowReferenceError, 1); 1409864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 1410864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 1411864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ jmp(done); 1412864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 1413864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 1414864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1415864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1416864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy) { 1417864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Record position before possible IC call. 1418864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org SetSourcePosition(proxy->position()); 1419864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Variable* var = proxy->var(); 1420864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1421864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Three cases: global variables, lookup variables, and all other types of 1422864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // variables. 1423864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org switch (var->location()) { 1424864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case Variable::UNALLOCATED: { 1425864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Comment cmnt(masm_, "[ Global variable"); 142642ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org __ mov(LoadDescriptor::ReceiverRegister(), GlobalObjectOperand()); 142742ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org __ mov(LoadDescriptor::NameRegister(), var->name()); 14287c0666e15d1f68f0fef5db9e5c409fab010ed816machenbach@chromium.org if (FLAG_vector_ics) { 142942ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org __ mov(VectorLoadICDescriptor::SlotRegister(), 14307c0666e15d1f68f0fef5db9e5c409fab010ed816machenbach@chromium.org Immediate(Smi::FromInt(proxy->VariableFeedbackSlot()))); 14317c0666e15d1f68f0fef5db9e5c409fab010ed816machenbach@chromium.org } 1432864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org CallLoadIC(CONTEXTUAL); 1433864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org context()->Plug(eax); 1434864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org break; 1435864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 1436864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1437864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case Variable::PARAMETER: 1438864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case Variable::LOCAL: 1439864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case Variable::CONTEXT: { 1440864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Comment cmnt(masm_, var->IsContextSlot() ? "[ Context variable" 1441864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org : "[ Stack variable"); 1442864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (var->binding_needs_init()) { 1443864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // var->scope() may be NULL when the proxy is located in eval code and 1444864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // refers to a potential outside binding. Currently those bindings are 1445864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // always looked up dynamically, i.e. in that case 1446864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // var->location() == LOOKUP. 1447864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // always holds. 1448e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(var->scope() != NULL); 1449864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1450864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Check if the binding really needs an initialization check. The check 1451864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // can be skipped in the following situation: we have a LET or CONST 1452864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // binding in harmony mode, both the Variable and the VariableProxy have 1453864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // the same declaration scope (i.e. they are both in global code, in the 1454864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // same function or in the same eval code) and the VariableProxy is in 1455864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // the source physically located after the initializer of the variable. 1456864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // 1457864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // We cannot skip any initialization checks for CONST in non-harmony 1458864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // mode because const variables may be declared but never initialized: 1459864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // if (false) { const x; }; var y = x; 1460864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // 1461864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // The condition on the declaration scopes is a conservative check for 1462864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // nested functions that access a binding and are called before the 1463864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // binding is initialized: 1464864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // function() { f(); let x = 1; function f() { x = 2; } } 1465864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // 1466864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org bool skip_init_check; 1467864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (var->scope()->DeclarationScope() != scope()->DeclarationScope()) { 1468864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org skip_init_check = false; 1469864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 1470864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Check that we always have valid source position. 1471e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(var->initializer_position() != RelocInfo::kNoPosition); 1472e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(proxy->position() != RelocInfo::kNoPosition); 1473864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org skip_init_check = var->mode() != CONST_LEGACY && 1474864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org var->initializer_position() < proxy->position(); 1475864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 1476864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1477864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (!skip_init_check) { 1478864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Let and const need a read barrier. 1479864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label done; 1480864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org GetVar(eax, var); 1481864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ cmp(eax, isolate()->factory()->the_hole_value()); 1482864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(not_equal, &done, Label::kNear); 1483864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (var->mode() == LET || var->mode() == CONST) { 1484864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Throw a reference error when using an uninitialized let/const 1485864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // binding in harmony mode. 1486864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(Immediate(var->name())); 148747390597afd6b17870f41dfb5dd8c057aea1f068machenbach@chromium.org __ CallRuntime(Runtime::kThrowReferenceError, 1); 1488864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 1489864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Uninitalized const bindings outside of harmony mode are unholed. 1490e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(var->mode() == CONST_LEGACY); 1491864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(eax, isolate()->factory()->undefined_value()); 1492864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 1493864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&done); 1494864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org context()->Plug(eax); 1495864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org break; 1496864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 1497864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 1498864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org context()->Plug(var); 1499864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org break; 1500864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 1501864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1502864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case Variable::LOOKUP: { 1503864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Comment cmnt(masm_, "[ Lookup variable"); 1504864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label done, slow; 1505864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Generate code for loading from variables potentially shadowed 1506864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // by eval-introduced variables. 15077c0666e15d1f68f0fef5db9e5c409fab010ed816machenbach@chromium.org EmitDynamicLookupFastCase(proxy, NOT_INSIDE_TYPEOF, &slow, &done); 1508864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&slow); 1509864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(esi); // Context. 1510864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(Immediate(var->name())); 15114c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org __ CallRuntime(Runtime::kLoadLookupSlot, 2); 1512864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&done); 1513864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org context()->Plug(eax); 1514864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org break; 1515864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 1516864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 1517864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 1518864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1519864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1520864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid FullCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) { 1521864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Comment cmnt(masm_, "[ RegExpLiteral"); 1522864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label materialized; 1523864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Registers will be used as follows: 1524864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // edi = JS function. 1525864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // ecx = literals array. 1526864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // ebx = regexp literal. 1527864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // eax = regexp literal clone. 1528864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(edi, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset)); 1529864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(ecx, FieldOperand(edi, JSFunction::kLiteralsOffset)); 1530864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int literal_offset = 1531864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org FixedArray::kHeaderSize + expr->literal_index() * kPointerSize; 1532864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(ebx, FieldOperand(ecx, literal_offset)); 1533864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ cmp(ebx, isolate()->factory()->undefined_value()); 1534864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(not_equal, &materialized, Label::kNear); 1535864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1536864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Create regexp literal using runtime function 1537864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Result will be in eax. 1538864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(ecx); 1539864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(Immediate(Smi::FromInt(expr->literal_index()))); 1540864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(Immediate(expr->pattern())); 1541864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(Immediate(expr->flags())); 154247390597afd6b17870f41dfb5dd8c057aea1f068machenbach@chromium.org __ CallRuntime(Runtime::kMaterializeRegExpLiteral, 4); 1543864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(ebx, eax); 1544864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1545864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&materialized); 1546864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int size = JSRegExp::kSize + JSRegExp::kInObjectFieldCount * kPointerSize; 1547864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label allocated, runtime_allocate; 1548864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ Allocate(size, eax, ecx, edx, &runtime_allocate, TAG_OBJECT); 1549864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ jmp(&allocated); 1550864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1551864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&runtime_allocate); 1552864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(ebx); 1553864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(Immediate(Smi::FromInt(size))); 155447390597afd6b17870f41dfb5dd8c057aea1f068machenbach@chromium.org __ CallRuntime(Runtime::kAllocateInNewSpace, 1); 1555864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ pop(ebx); 1556864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1557864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&allocated); 1558864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Copy the content into the newly allocated memory. 1559864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // (Unroll copy loop once for better throughput). 1560864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org for (int i = 0; i < size - kPointerSize; i += 2 * kPointerSize) { 1561864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(edx, FieldOperand(ebx, i)); 1562864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(ecx, FieldOperand(ebx, i + kPointerSize)); 1563864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(FieldOperand(eax, i), edx); 1564864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(FieldOperand(eax, i + kPointerSize), ecx); 1565864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 1566864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if ((size % (2 * kPointerSize)) != 0) { 1567864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(edx, FieldOperand(ebx, size - kPointerSize)); 1568864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(FieldOperand(eax, size - kPointerSize), edx); 1569864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 1570864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org context()->Plug(eax); 1571864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 1572864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1573864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1574864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid FullCodeGenerator::EmitAccessor(Expression* expression) { 1575864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (expression == NULL) { 1576864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(Immediate(isolate()->factory()->null_value())); 1577864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 1578864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org VisitForStackValue(expression); 1579864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 1580864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 1581864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1582864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1583864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) { 1584864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Comment cmnt(masm_, "[ ObjectLiteral"); 1585864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1586864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org expr->BuildConstantProperties(isolate()); 1587864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Handle<FixedArray> constant_properties = expr->constant_properties(); 1588864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int flags = expr->fast_elements() 1589864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ? ObjectLiteral::kFastElements 1590864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org : ObjectLiteral::kNoFlags; 1591864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org flags |= expr->has_function() 1592864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ? ObjectLiteral::kHasFunction 1593864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org : ObjectLiteral::kNoFlags; 1594864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int properties_count = constant_properties->length() / 2; 1595864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (expr->may_store_doubles() || expr->depth() > 1 || 1596864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org masm()->serializer_enabled() || 1597864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org flags != ObjectLiteral::kFastElements || 1598864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org properties_count > FastCloneShallowObjectStub::kMaximumClonedProperties) { 1599864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(edi, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset)); 1600864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(FieldOperand(edi, JSFunction::kLiteralsOffset)); 1601864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(Immediate(Smi::FromInt(expr->literal_index()))); 1602864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(Immediate(constant_properties)); 1603864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(Immediate(Smi::FromInt(flags))); 160447390597afd6b17870f41dfb5dd8c057aea1f068machenbach@chromium.org __ CallRuntime(Runtime::kCreateObjectLiteral, 4); 1605864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 1606864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(edi, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset)); 1607864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(eax, FieldOperand(edi, JSFunction::kLiteralsOffset)); 1608864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(ebx, Immediate(Smi::FromInt(expr->literal_index()))); 1609864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(ecx, Immediate(constant_properties)); 1610864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(edx, Immediate(Smi::FromInt(flags))); 1611864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org FastCloneShallowObjectStub stub(isolate(), properties_count); 1612864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ CallStub(&stub); 1613864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 1614864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1615864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // If result_saved is true the result is on top of the stack. If 1616864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // result_saved is false the result is in eax. 1617864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org bool result_saved = false; 1618864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1619864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Mark all computed expressions that are bound to a key that 1620864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // is shadowed by a later occurrence of the same key. For the 1621864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // marked expressions, no store code is emitted. 1622864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org expr->CalculateEmitStore(zone()); 1623864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1624864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org AccessorTable accessor_table(zone()); 1625864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org for (int i = 0; i < expr->properties()->length(); i++) { 1626864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ObjectLiteral::Property* property = expr->properties()->at(i); 1627864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (property->IsCompileTimeValue()) continue; 1628864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1629864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Literal* key = property->key(); 1630864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Expression* value = property->value(); 1631864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (!result_saved) { 1632864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(eax); // Save result on the stack 1633864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org result_saved = true; 1634864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 1635864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org switch (property->kind()) { 1636864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case ObjectLiteral::Property::CONSTANT: 1637864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org UNREACHABLE(); 1638864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case ObjectLiteral::Property::MATERIALIZED_LITERAL: 1639e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!CompileTimeValue::IsCompileTimeValue(value)); 1640864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Fall through. 1641864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case ObjectLiteral::Property::COMPUTED: 1642864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (key->value()->IsInternalizedString()) { 1643864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (property->emit_store()) { 1644864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org VisitForAccumulatorValue(value); 164542ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org DCHECK(StoreDescriptor::ValueRegister().is(eax)); 164642ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org __ mov(StoreDescriptor::NameRegister(), Immediate(key->value())); 164742ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org __ mov(StoreDescriptor::ReceiverRegister(), Operand(esp, 0)); 1648864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org CallStoreIC(key->LiteralFeedbackId()); 1649864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org PrepareForBailoutForId(key->id(), NO_REGISTERS); 1650864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 1651864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org VisitForEffect(value); 1652864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 1653864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org break; 1654864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 1655864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(Operand(esp, 0)); // Duplicate receiver. 1656864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org VisitForStackValue(key); 1657864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org VisitForStackValue(value); 1658864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (property->emit_store()) { 165960fc910a49e86bb7faeeee0017abbd1ca05d16e8machenbach@chromium.org __ push(Immediate(Smi::FromInt(SLOPPY))); // Strict mode 166060fc910a49e86bb7faeeee0017abbd1ca05d16e8machenbach@chromium.org __ CallRuntime(Runtime::kSetProperty, 4); 1661864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 1662864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ Drop(3); 1663864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 1664864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org break; 1665864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case ObjectLiteral::Property::PROTOTYPE: 1666864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(Operand(esp, 0)); // Duplicate receiver. 1667864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org VisitForStackValue(value); 1668864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (property->emit_store()) { 1669864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ CallRuntime(Runtime::kSetPrototype, 2); 1670864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 1671864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ Drop(2); 1672864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 1673864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org break; 1674864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case ObjectLiteral::Property::GETTER: 1675864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org accessor_table.lookup(key)->second->getter = value; 1676864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org break; 1677864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case ObjectLiteral::Property::SETTER: 1678864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org accessor_table.lookup(key)->second->setter = value; 1679864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org break; 1680864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 1681864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 1682864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1683864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Emit code to define accessors, using only a single call to the runtime for 1684864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // each pair of corresponding getters and setters. 1685864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org for (AccessorTable::Iterator it = accessor_table.begin(); 1686864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org it != accessor_table.end(); 1687864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ++it) { 1688864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(Operand(esp, 0)); // Duplicate receiver. 1689864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org VisitForStackValue(it->first); 1690864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org EmitAccessor(it->second->getter); 1691864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org EmitAccessor(it->second->setter); 1692864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(Immediate(Smi::FromInt(NONE))); 1693248dd43badb99ffce44eae2d767cda3cefaad521machenbach@chromium.org __ CallRuntime(Runtime::kDefineAccessorPropertyUnchecked, 5); 1694864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 1695864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1696864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (expr->has_function()) { 1697e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(result_saved); 1698864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(Operand(esp, 0)); 1699864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ CallRuntime(Runtime::kToFastProperties, 1); 1700864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 1701864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1702864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (result_saved) { 1703864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org context()->PlugTOS(); 1704864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 1705864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org context()->Plug(eax); 1706864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 1707864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 1708864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1709864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1710864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid FullCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) { 1711864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Comment cmnt(masm_, "[ ArrayLiteral"); 1712864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1713864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org expr->BuildConstantElements(isolate()); 1714864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int flags = expr->depth() == 1 1715864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ? ArrayLiteral::kShallowElements 1716864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org : ArrayLiteral::kNoFlags; 1717864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1718864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ZoneList<Expression*>* subexprs = expr->values(); 1719864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int length = subexprs->length(); 1720864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Handle<FixedArray> constant_elements = expr->constant_elements(); 1721e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK_EQ(2, constant_elements->length()); 1722864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ElementsKind constant_elements_kind = 1723864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org static_cast<ElementsKind>(Smi::cast(constant_elements->get(0))->value()); 1724864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org bool has_constant_fast_elements = 1725864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org IsFastObjectElementsKind(constant_elements_kind); 1726864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Handle<FixedArrayBase> constant_elements_values( 1727864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org FixedArrayBase::cast(constant_elements->get(1))); 1728864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1729864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org AllocationSiteMode allocation_site_mode = TRACK_ALLOCATION_SITE; 1730864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (has_constant_fast_elements && !FLAG_allocation_site_pretenuring) { 1731864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // If the only customer of allocation sites is transitioning, then 1732864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // we can turn it off if we don't have anywhere else to transition to. 1733864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org allocation_site_mode = DONT_TRACK_ALLOCATION_SITE; 1734864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 1735864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1736e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org if (expr->depth() > 1 || length > JSObject::kInitialMaxFastElementArray) { 1737864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(ebx, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset)); 1738864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(FieldOperand(ebx, JSFunction::kLiteralsOffset)); 1739864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(Immediate(Smi::FromInt(expr->literal_index()))); 1740864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(Immediate(constant_elements)); 1741864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(Immediate(Smi::FromInt(flags))); 174247390597afd6b17870f41dfb5dd8c057aea1f068machenbach@chromium.org __ CallRuntime(Runtime::kCreateArrayLiteral, 4); 1743864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 1744864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(ebx, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset)); 1745864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(eax, FieldOperand(ebx, JSFunction::kLiteralsOffset)); 1746864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(ebx, Immediate(Smi::FromInt(expr->literal_index()))); 1747864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(ecx, Immediate(constant_elements)); 1748864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org FastCloneShallowArrayStub stub(isolate(), allocation_site_mode); 1749864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ CallStub(&stub); 1750864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 1751864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1752864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org bool result_saved = false; // Is the result saved to the stack? 1753864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1754864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Emit code to evaluate all the non-constant subexpressions and to store 1755864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // them into the newly cloned array. 1756864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org for (int i = 0; i < length; i++) { 1757864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Expression* subexpr = subexprs->at(i); 1758864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // If the subexpression is a literal or a simple materialized literal it 1759864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // is already set in the cloned array. 1760864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (CompileTimeValue::IsCompileTimeValue(subexpr)) continue; 1761864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1762864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (!result_saved) { 1763864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(eax); // array literal. 1764864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(Immediate(Smi::FromInt(expr->literal_index()))); 1765864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org result_saved = true; 1766864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 1767864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org VisitForAccumulatorValue(subexpr); 1768864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1769864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (IsFastObjectElementsKind(constant_elements_kind)) { 1770864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Fast-case array literal with ElementsKind of FAST_*_ELEMENTS, they 1771864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // cannot transition and don't need to call the runtime stub. 1772864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int offset = FixedArray::kHeaderSize + (i * kPointerSize); 1773864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(ebx, Operand(esp, kPointerSize)); // Copy of array literal. 1774864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(ebx, FieldOperand(ebx, JSObject::kElementsOffset)); 1775864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Store the subexpression value in the array's elements. 1776864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(FieldOperand(ebx, offset), result_register()); 1777864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Update the write barrier for the array store. 177806b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ RecordWriteField(ebx, offset, result_register(), ecx, kDontSaveFPRegs, 177906b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org EMIT_REMEMBERED_SET, INLINE_SMI_CHECK); 1780864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 1781864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Store the subexpression value in the array's elements. 1782864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(ecx, Immediate(Smi::FromInt(i))); 1783864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org StoreArrayLiteralElementStub stub(isolate()); 1784864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ CallStub(&stub); 1785864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 1786864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1787864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org PrepareForBailoutForId(expr->GetIdForElement(i), NO_REGISTERS); 1788864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 1789864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1790864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (result_saved) { 1791864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ add(esp, Immediate(kPointerSize)); // literal index 1792864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org context()->PlugTOS(); 1793864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 1794864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org context()->Plug(eax); 1795864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 1796864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 1797864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1798864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1799864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid FullCodeGenerator::VisitAssignment(Assignment* expr) { 1800e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(expr->target()->IsValidReferenceExpression()); 1801864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1802864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Comment cmnt(masm_, "[ Assignment"); 1803864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1804864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Left-hand side can only be a property, a global or a (parameter or local) 1805864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // slot. 1806864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org enum LhsKind { VARIABLE, NAMED_PROPERTY, KEYED_PROPERTY }; 1807864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org LhsKind assign_type = VARIABLE; 1808864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Property* property = expr->target()->AsProperty(); 1809864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (property != NULL) { 1810864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org assign_type = (property->key()->IsPropertyName()) 1811864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ? NAMED_PROPERTY 1812864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org : KEYED_PROPERTY; 1813864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 1814864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1815864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Evaluate LHS expression. 1816864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org switch (assign_type) { 1817864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case VARIABLE: 1818864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Nothing to do here. 1819864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org break; 1820864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case NAMED_PROPERTY: 1821864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (expr->is_compound()) { 182258a725587734a6889c689668fd01f0157ed749a6machenbach@chromium.org // We need the receiver both on the stack and in the register. 1823864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org VisitForStackValue(property->obj()); 182442ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org __ mov(LoadDescriptor::ReceiverRegister(), Operand(esp, 0)); 1825864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 1826864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org VisitForStackValue(property->obj()); 1827864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 1828864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org break; 1829864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case KEYED_PROPERTY: { 1830864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (expr->is_compound()) { 1831864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org VisitForStackValue(property->obj()); 1832864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org VisitForStackValue(property->key()); 183342ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org __ mov(LoadDescriptor::ReceiverRegister(), Operand(esp, kPointerSize)); 183442ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org __ mov(LoadDescriptor::NameRegister(), Operand(esp, 0)); 1835864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 1836864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org VisitForStackValue(property->obj()); 1837864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org VisitForStackValue(property->key()); 1838864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 1839864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org break; 1840864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 1841864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 1842864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1843864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // For compound assignments we need another deoptimization point after the 1844864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // variable/property load. 1845864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (expr->is_compound()) { 1846864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org AccumulatorValueContext result_context(this); 1847864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org { AccumulatorValueContext left_operand_context(this); 1848864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org switch (assign_type) { 1849864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case VARIABLE: 1850864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org EmitVariableLoad(expr->target()->AsVariableProxy()); 1851864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org PrepareForBailout(expr->target(), TOS_REG); 1852864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org break; 1853864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case NAMED_PROPERTY: 1854864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org EmitNamedPropertyLoad(property); 1855864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org PrepareForBailoutForId(property->LoadId(), TOS_REG); 1856864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org break; 1857864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case KEYED_PROPERTY: 1858864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org EmitKeyedPropertyLoad(property); 1859864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org PrepareForBailoutForId(property->LoadId(), TOS_REG); 1860864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org break; 1861864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 1862864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 1863864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1864864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Token::Value op = expr->binary_op(); 1865864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(eax); // Left operand goes on the stack. 1866864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org VisitForAccumulatorValue(expr->value()); 1867864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1868864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org OverwriteMode mode = expr->value()->ResultOverwriteAllowed() 1869864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ? OVERWRITE_RIGHT 1870864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org : NO_OVERWRITE; 1871864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org SetSourcePosition(expr->position() + 1); 1872864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (ShouldInlineSmiCase(op)) { 1873864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org EmitInlineSmiBinaryOp(expr->binary_operation(), 1874864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org op, 1875864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org mode, 1876864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org expr->target(), 1877864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org expr->value()); 1878864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 1879864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org EmitBinaryOp(expr->binary_operation(), op, mode); 1880864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 1881864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1882864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Deoptimization point in case the binary operation may have side effects. 1883864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org PrepareForBailout(expr->binary_operation(), TOS_REG); 1884864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 1885864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org VisitForAccumulatorValue(expr->value()); 1886864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 1887864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1888864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Record source position before possible IC call. 1889864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org SetSourcePosition(expr->position()); 1890864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1891864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Store the value. 1892864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org switch (assign_type) { 1893864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case VARIABLE: 1894864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org EmitVariableAssignment(expr->target()->AsVariableProxy()->var(), 1895864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org expr->op()); 1896864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 1897864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org context()->Plug(eax); 1898864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org break; 1899864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case NAMED_PROPERTY: 1900864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org EmitNamedPropertyAssignment(expr); 1901864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org break; 1902864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case KEYED_PROPERTY: 1903864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org EmitKeyedPropertyAssignment(expr); 1904864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org break; 1905864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 1906864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 1907864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1908864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1909864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid FullCodeGenerator::VisitYield(Yield* expr) { 1910864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Comment cmnt(masm_, "[ Yield"); 1911864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Evaluate yielded value first; the initial iterator definition depends on 1912864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // this. It stays on the stack while we update the iterator. 1913864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org VisitForStackValue(expr->expression()); 1914864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1915864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org switch (expr->yield_kind()) { 191621d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org case Yield::kSuspend: 1917864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Pop value from top-of-stack slot; box result into result register. 1918864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org EmitCreateIteratorResult(false); 1919864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(result_register()); 1920864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Fall through. 192121d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org case Yield::kInitial: { 1922864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label suspend, continuation, post_runtime, resume; 1923864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1924864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ jmp(&suspend); 1925864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1926864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&continuation); 1927864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ jmp(&resume); 1928864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1929864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&suspend); 1930864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org VisitForAccumulatorValue(expr->generator_object()); 1931e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(continuation.pos() > 0 && Smi::IsValid(continuation.pos())); 1932864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(FieldOperand(eax, JSGeneratorObject::kContinuationOffset), 1933864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Immediate(Smi::FromInt(continuation.pos()))); 1934864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(FieldOperand(eax, JSGeneratorObject::kContextOffset), esi); 1935864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(ecx, esi); 193606b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ RecordWriteField(eax, JSGeneratorObject::kContextOffset, ecx, edx, 193706b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org kDontSaveFPRegs); 1938864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ lea(ebx, Operand(ebp, StandardFrameConstants::kExpressionsOffset)); 1939864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ cmp(esp, ebx); 1940864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(equal, &post_runtime); 1941864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(eax); // generator object 194247390597afd6b17870f41dfb5dd8c057aea1f068machenbach@chromium.org __ CallRuntime(Runtime::kSuspendJSGeneratorObject, 1); 1943864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(context_register(), 1944864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Operand(ebp, StandardFrameConstants::kContextOffset)); 1945864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&post_runtime); 1946864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ pop(result_register()); 1947864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org EmitReturnSequence(); 1948864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1949864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&resume); 1950864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org context()->Plug(result_register()); 1951864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org break; 1952864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 1953864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 195421d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org case Yield::kFinal: { 1955864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org VisitForAccumulatorValue(expr->generator_object()); 1956864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(FieldOperand(result_register(), 1957864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org JSGeneratorObject::kContinuationOffset), 1958864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Immediate(Smi::FromInt(JSGeneratorObject::kGeneratorClosed))); 1959864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Pop value from top-of-stack slot, box result into result register. 1960864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org EmitCreateIteratorResult(true); 1961864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org EmitUnwindBeforeReturn(); 1962864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org EmitReturnSequence(); 1963864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org break; 1964864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 1965864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 196621d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org case Yield::kDelegating: { 1967864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org VisitForStackValue(expr->generator_object()); 1968864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1969864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Initial stack layout is as follows: 1970864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // [sp + 1 * kPointerSize] iter 1971864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // [sp + 0 * kPointerSize] g 1972864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1973864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label l_catch, l_try, l_suspend, l_continuation, l_resume; 1974864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label l_next, l_call, l_loop; 197542ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org Register load_receiver = LoadDescriptor::ReceiverRegister(); 197642ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org Register load_name = LoadDescriptor::NameRegister(); 197758a725587734a6889c689668fd01f0157ed749a6machenbach@chromium.org 1978864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Initial send value is undefined. 1979864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(eax, isolate()->factory()->undefined_value()); 1980864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ jmp(&l_next); 1981864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1982864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // catch (e) { receiver = iter; f = 'throw'; arg = e; goto l_call; } 1983864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&l_catch); 1984864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org handler_table()->set(expr->index(), Smi::FromInt(l_catch.pos())); 198558a725587734a6889c689668fd01f0157ed749a6machenbach@chromium.org __ mov(load_name, isolate()->factory()->throw_string()); // "throw" 198658a725587734a6889c689668fd01f0157ed749a6machenbach@chromium.org __ push(load_name); // "throw" 198758a725587734a6889c689668fd01f0157ed749a6machenbach@chromium.org __ push(Operand(esp, 2 * kPointerSize)); // iter 198858a725587734a6889c689668fd01f0157ed749a6machenbach@chromium.org __ push(eax); // exception 1989864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ jmp(&l_call); 1990864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1991864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // try { received = %yield result } 1992864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Shuffle the received result above a try handler and yield it without 1993864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // re-boxing. 1994864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&l_try); 1995864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ pop(eax); // result 1996864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ PushTryHandler(StackHandler::CATCH, expr->index()); 1997864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org const int handler_size = StackHandlerConstants::kSize; 1998864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(eax); // result 1999864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ jmp(&l_suspend); 2000864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&l_continuation); 2001864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ jmp(&l_resume); 2002864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&l_suspend); 2003864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org const int generator_object_depth = kPointerSize + handler_size; 2004864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(eax, Operand(esp, generator_object_depth)); 2005864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(eax); // g 2006e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(l_continuation.pos() > 0 && Smi::IsValid(l_continuation.pos())); 2007864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(FieldOperand(eax, JSGeneratorObject::kContinuationOffset), 2008864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Immediate(Smi::FromInt(l_continuation.pos()))); 2009864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(FieldOperand(eax, JSGeneratorObject::kContextOffset), esi); 2010864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(ecx, esi); 201106b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ RecordWriteField(eax, JSGeneratorObject::kContextOffset, ecx, edx, 201206b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org kDontSaveFPRegs); 201347390597afd6b17870f41dfb5dd8c057aea1f068machenbach@chromium.org __ CallRuntime(Runtime::kSuspendJSGeneratorObject, 1); 2014864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(context_register(), 2015864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Operand(ebp, StandardFrameConstants::kContextOffset)); 2016864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ pop(eax); // result 2017864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org EmitReturnSequence(); 2018864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&l_resume); // received in eax 2019864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ PopTryHandler(); 2020864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2021864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // receiver = iter; f = iter.next; arg = received; 2022864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&l_next); 2023248dd43badb99ffce44eae2d767cda3cefaad521machenbach@chromium.org 202458a725587734a6889c689668fd01f0157ed749a6machenbach@chromium.org __ mov(load_name, isolate()->factory()->next_string()); 202558a725587734a6889c689668fd01f0157ed749a6machenbach@chromium.org __ push(load_name); // "next" 202658a725587734a6889c689668fd01f0157ed749a6machenbach@chromium.org __ push(Operand(esp, 2 * kPointerSize)); // iter 202758a725587734a6889c689668fd01f0157ed749a6machenbach@chromium.org __ push(eax); // received 2028864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2029864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // result = receiver[f](arg); 2030864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&l_call); 203158a725587734a6889c689668fd01f0157ed749a6machenbach@chromium.org __ mov(load_receiver, Operand(esp, kPointerSize)); 20327c0666e15d1f68f0fef5db9e5c409fab010ed816machenbach@chromium.org if (FLAG_vector_ics) { 203342ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org __ mov(VectorLoadICDescriptor::SlotRegister(), 20347c0666e15d1f68f0fef5db9e5c409fab010ed816machenbach@chromium.org Immediate(Smi::FromInt(expr->KeyedLoadFeedbackSlot()))); 20357c0666e15d1f68f0fef5db9e5c409fab010ed816machenbach@chromium.org } 2036b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate()).code(); 2037864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org CallIC(ic, TypeFeedbackId::None()); 2038864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(edi, eax); 2039864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(Operand(esp, 2 * kPointerSize), edi); 2040864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org CallFunctionStub stub(isolate(), 1, CALL_AS_METHOD); 2041864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ CallStub(&stub); 2042864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2043864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); 2044864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ Drop(1); // The function is still on the stack; drop it. 2045864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2046864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // if (!result.done) goto l_try; 2047864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&l_loop); 2048864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(eax); // save result 204958a725587734a6889c689668fd01f0157ed749a6machenbach@chromium.org __ Move(load_receiver, eax); // result 2050248dd43badb99ffce44eae2d767cda3cefaad521machenbach@chromium.org __ mov(load_name, 2051248dd43badb99ffce44eae2d767cda3cefaad521machenbach@chromium.org isolate()->factory()->done_string()); // "done" 20527c0666e15d1f68f0fef5db9e5c409fab010ed816machenbach@chromium.org if (FLAG_vector_ics) { 205342ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org __ mov(VectorLoadICDescriptor::SlotRegister(), 20547c0666e15d1f68f0fef5db9e5c409fab010ed816machenbach@chromium.org Immediate(Smi::FromInt(expr->DoneFeedbackSlot()))); 20557c0666e15d1f68f0fef5db9e5c409fab010ed816machenbach@chromium.org } 2056864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org CallLoadIC(NOT_CONTEXTUAL); // result.done in eax 2057864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Handle<Code> bool_ic = ToBooleanStub::GetUninitialized(isolate()); 2058864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org CallIC(bool_ic); 2059864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ test(eax, eax); 2060864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(zero, &l_try); 2061864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2062864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // result.value 2063248dd43badb99ffce44eae2d767cda3cefaad521machenbach@chromium.org __ pop(load_receiver); // result 2064248dd43badb99ffce44eae2d767cda3cefaad521machenbach@chromium.org __ mov(load_name, 2065248dd43badb99ffce44eae2d767cda3cefaad521machenbach@chromium.org isolate()->factory()->value_string()); // "value" 20667c0666e15d1f68f0fef5db9e5c409fab010ed816machenbach@chromium.org if (FLAG_vector_ics) { 206742ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org __ mov(VectorLoadICDescriptor::SlotRegister(), 20687c0666e15d1f68f0fef5db9e5c409fab010ed816machenbach@chromium.org Immediate(Smi::FromInt(expr->ValueFeedbackSlot()))); 20697c0666e15d1f68f0fef5db9e5c409fab010ed816machenbach@chromium.org } 2070864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org CallLoadIC(NOT_CONTEXTUAL); // result.value in eax 2071864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org context()->DropAndPlug(2, eax); // drop iter and g 2072864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org break; 2073864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 2074864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 2075864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 2076864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2077864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2078864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid FullCodeGenerator::EmitGeneratorResume(Expression *generator, 2079864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Expression *value, 2080864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org JSGeneratorObject::ResumeMode resume_mode) { 2081864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // The value stays in eax, and is ultimately read by the resumed generator, as 208247390597afd6b17870f41dfb5dd8c057aea1f068machenbach@chromium.org // if CallRuntime(Runtime::kSuspendJSGeneratorObject) returned it. Or it 2083864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // is read to throw the value when the resumed generator is already closed. 2084864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // ebx will hold the generator object until the activation has been resumed. 2085864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org VisitForStackValue(generator); 2086864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org VisitForAccumulatorValue(value); 2087864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ pop(ebx); 2088864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2089864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Check generator state. 2090864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label wrong_state, closed_state, done; 2091864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org STATIC_ASSERT(JSGeneratorObject::kGeneratorExecuting < 0); 2092864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org STATIC_ASSERT(JSGeneratorObject::kGeneratorClosed == 0); 2093864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ cmp(FieldOperand(ebx, JSGeneratorObject::kContinuationOffset), 2094864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Immediate(Smi::FromInt(0))); 2095864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(equal, &closed_state); 2096864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(less, &wrong_state); 2097864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2098864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Load suspended function and context. 2099864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(esi, FieldOperand(ebx, JSGeneratorObject::kContextOffset)); 2100864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(edi, FieldOperand(ebx, JSGeneratorObject::kFunctionOffset)); 2101864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2102864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Push receiver. 2103864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(FieldOperand(ebx, JSGeneratorObject::kReceiverOffset)); 2104864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2105864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Push holes for arguments to generator function. 2106864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(edx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset)); 2107864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(edx, 2108864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org FieldOperand(edx, SharedFunctionInfo::kFormalParameterCountOffset)); 2109864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(ecx, isolate()->factory()->the_hole_value()); 2110864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label push_argument_holes, push_frame; 2111864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&push_argument_holes); 2112864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ sub(edx, Immediate(Smi::FromInt(1))); 2113864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(carry, &push_frame); 2114864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(ecx); 2115864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ jmp(&push_argument_holes); 2116864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2117864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Enter a new JavaScript frame, and initialize its slots as they were when 2118864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // the generator was suspended. 2119864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label resume_frame; 2120864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&push_frame); 2121864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ call(&resume_frame); 2122864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ jmp(&done); 2123864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&resume_frame); 2124864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(ebp); // Caller's frame pointer. 2125864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(ebp, esp); 2126864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(esi); // Callee's context. 2127864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(edi); // Callee's JS Function. 2128864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2129864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Load the operand stack size. 2130864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(edx, FieldOperand(ebx, JSGeneratorObject::kOperandStackOffset)); 2131864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(edx, FieldOperand(edx, FixedArray::kLengthOffset)); 2132864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ SmiUntag(edx); 2133864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2134864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // If we are sending a value and there is no operand stack, we can jump back 2135864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // in directly. 2136864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (resume_mode == JSGeneratorObject::NEXT) { 2137864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label slow_resume; 2138864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ cmp(edx, Immediate(0)); 2139864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(not_zero, &slow_resume); 2140864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(edx, FieldOperand(edi, JSFunction::kCodeEntryOffset)); 2141864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(ecx, FieldOperand(ebx, JSGeneratorObject::kContinuationOffset)); 2142864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ SmiUntag(ecx); 2143864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ add(edx, ecx); 2144864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(FieldOperand(ebx, JSGeneratorObject::kContinuationOffset), 2145864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Immediate(Smi::FromInt(JSGeneratorObject::kGeneratorExecuting))); 2146864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ jmp(edx); 2147864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&slow_resume); 2148864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 2149864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2150864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Otherwise, we push holes for the operand stack and call the runtime to fix 2151864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // up the stack and the handlers. 2152864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label push_operand_holes, call_resume; 2153864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&push_operand_holes); 2154864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ sub(edx, Immediate(1)); 2155864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(carry, &call_resume); 2156864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(ecx); 2157864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ jmp(&push_operand_holes); 2158864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&call_resume); 2159864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(ebx); 2160864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(result_register()); 2161864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ Push(Smi::FromInt(resume_mode)); 216247390597afd6b17870f41dfb5dd8c057aea1f068machenbach@chromium.org __ CallRuntime(Runtime::kResumeJSGeneratorObject, 3); 2163864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Not reached: the runtime call returns elsewhere. 2164864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ Abort(kGeneratorFailedToResume); 2165864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2166864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Reach here when generator is closed. 2167864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&closed_state); 2168864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (resume_mode == JSGeneratorObject::NEXT) { 2169864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Return completed iterator result when generator is closed. 2170864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(Immediate(isolate()->factory()->undefined_value())); 2171864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Pop value from top-of-stack slot; box result into result register. 2172864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org EmitCreateIteratorResult(true); 2173864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 2174864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Throw the provided value. 2175864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(eax); 217647390597afd6b17870f41dfb5dd8c057aea1f068machenbach@chromium.org __ CallRuntime(Runtime::kThrow, 1); 2177864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 2178864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ jmp(&done); 2179864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2180864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Throw error if we attempt to operate on a running generator. 2181864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&wrong_state); 2182864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(ebx); 218347390597afd6b17870f41dfb5dd8c057aea1f068machenbach@chromium.org __ CallRuntime(Runtime::kThrowGeneratorStateError, 1); 2184864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2185864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&done); 2186864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org context()->Plug(result_register()); 2187864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 2188864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2189864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2190864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid FullCodeGenerator::EmitCreateIteratorResult(bool done) { 2191864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label gc_required; 2192864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label allocated; 2193864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2194b1d9f4b46c9d3041103c0d47fada41ea1ee9c839weiliang.lin@intel.com const int instance_size = 5 * kPointerSize; 2195b1d9f4b46c9d3041103c0d47fada41ea1ee9c839weiliang.lin@intel.com DCHECK_EQ(isolate()->native_context()->iterator_result_map()->instance_size(), 2196b1d9f4b46c9d3041103c0d47fada41ea1ee9c839weiliang.lin@intel.com instance_size); 2197864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2198b1d9f4b46c9d3041103c0d47fada41ea1ee9c839weiliang.lin@intel.com __ Allocate(instance_size, eax, ecx, edx, &gc_required, TAG_OBJECT); 2199864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ jmp(&allocated); 2200864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2201864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&gc_required); 2202b1d9f4b46c9d3041103c0d47fada41ea1ee9c839weiliang.lin@intel.com __ Push(Smi::FromInt(instance_size)); 220347390597afd6b17870f41dfb5dd8c057aea1f068machenbach@chromium.org __ CallRuntime(Runtime::kAllocateInNewSpace, 1); 2204864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(context_register(), 2205864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Operand(ebp, StandardFrameConstants::kContextOffset)); 2206864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2207864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&allocated); 2208b1d9f4b46c9d3041103c0d47fada41ea1ee9c839weiliang.lin@intel.com __ mov(ebx, Operand(esi, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX))); 2209b1d9f4b46c9d3041103c0d47fada41ea1ee9c839weiliang.lin@intel.com __ mov(ebx, FieldOperand(ebx, GlobalObject::kNativeContextOffset)); 2210b1d9f4b46c9d3041103c0d47fada41ea1ee9c839weiliang.lin@intel.com __ mov(ebx, ContextOperand(ebx, Context::ITERATOR_RESULT_MAP_INDEX)); 2211864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ pop(ecx); 2212864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(edx, isolate()->factory()->ToBoolean(done)); 2213864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(FieldOperand(eax, HeapObject::kMapOffset), ebx); 2214864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(FieldOperand(eax, JSObject::kPropertiesOffset), 2215864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org isolate()->factory()->empty_fixed_array()); 2216864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(FieldOperand(eax, JSObject::kElementsOffset), 2217864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org isolate()->factory()->empty_fixed_array()); 2218864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(FieldOperand(eax, JSGeneratorObject::kResultValuePropertyOffset), ecx); 2219864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(FieldOperand(eax, JSGeneratorObject::kResultDonePropertyOffset), edx); 2220864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2221864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Only the value field needs a write barrier, as the other values are in the 2222864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // root set. 222306b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ RecordWriteField(eax, JSGeneratorObject::kResultValuePropertyOffset, ecx, 222406b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org edx, kDontSaveFPRegs); 2225864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 2226864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2227864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2228864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) { 2229864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org SetSourcePosition(prop->position()); 2230864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Literal* key = prop->key()->AsLiteral(); 2231e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!key->value()->IsSmi()); 223242ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org __ mov(LoadDescriptor::NameRegister(), Immediate(key->value())); 22337c0666e15d1f68f0fef5db9e5c409fab010ed816machenbach@chromium.org if (FLAG_vector_ics) { 223442ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org __ mov(VectorLoadICDescriptor::SlotRegister(), 22357c0666e15d1f68f0fef5db9e5c409fab010ed816machenbach@chromium.org Immediate(Smi::FromInt(prop->PropertyFeedbackSlot()))); 22367c0666e15d1f68f0fef5db9e5c409fab010ed816machenbach@chromium.org CallLoadIC(NOT_CONTEXTUAL); 22377c0666e15d1f68f0fef5db9e5c409fab010ed816machenbach@chromium.org } else { 22387c0666e15d1f68f0fef5db9e5c409fab010ed816machenbach@chromium.org CallLoadIC(NOT_CONTEXTUAL, prop->PropertyFeedbackId()); 22397c0666e15d1f68f0fef5db9e5c409fab010ed816machenbach@chromium.org } 2240864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 2241864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2242864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2243a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.orgvoid FullCodeGenerator::EmitNamedSuperPropertyLoad(Property* prop) { 2244a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org SetSourcePosition(prop->position()); 2245a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org Literal* key = prop->key()->AsLiteral(); 2246a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org DCHECK(!key->value()->IsSmi()); 2247a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org DCHECK(prop->IsSuperAccess()); 2248a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org 2249a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org SuperReference* super_ref = prop->obj()->AsSuperReference(); 2250a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org EmitLoadHomeObject(super_ref); 2251a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org __ push(eax); 2252a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org VisitForStackValue(super_ref->this_var()); 2253a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org __ push(Immediate(key->value())); 2254a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org __ CallRuntime(Runtime::kLoadFromSuper, 3); 2255a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org} 2256a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org 2257a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org 2258864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { 2259864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org SetSourcePosition(prop->position()); 2260b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate()).code(); 22617c0666e15d1f68f0fef5db9e5c409fab010ed816machenbach@chromium.org if (FLAG_vector_ics) { 226242ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org __ mov(VectorLoadICDescriptor::SlotRegister(), 22637c0666e15d1f68f0fef5db9e5c409fab010ed816machenbach@chromium.org Immediate(Smi::FromInt(prop->PropertyFeedbackSlot()))); 22647c0666e15d1f68f0fef5db9e5c409fab010ed816machenbach@chromium.org CallIC(ic); 22657c0666e15d1f68f0fef5db9e5c409fab010ed816machenbach@chromium.org } else { 22667c0666e15d1f68f0fef5db9e5c409fab010ed816machenbach@chromium.org CallIC(ic, prop->PropertyFeedbackId()); 22677c0666e15d1f68f0fef5db9e5c409fab010ed816machenbach@chromium.org } 2268864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 2269864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2270864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2271864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr, 2272864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Token::Value op, 2273864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org OverwriteMode mode, 2274864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Expression* left, 2275864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Expression* right) { 2276864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Do combined smi check of the operands. Left operand is on the 2277864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // stack. Right operand is in eax. 2278864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label smi_case, done, stub_call; 2279864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ pop(edx); 2280864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(ecx, eax); 2281864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ or_(eax, edx); 2282864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org JumpPatchSite patch_site(masm_); 2283864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org patch_site.EmitJumpIfSmi(eax, &smi_case, Label::kNear); 2284864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2285864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&stub_call); 2286864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(eax, ecx); 2287b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), op, mode).code(); 2288b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org CallIC(code, expr->BinaryOperationFeedbackId()); 2289864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org patch_site.EmitPatchInfo(); 2290864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ jmp(&done, Label::kNear); 2291864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2292864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Smi case. 2293864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&smi_case); 2294864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(eax, edx); // Copy left operand in case of a stub call. 2295864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2296864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org switch (op) { 2297864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case Token::SAR: 2298864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ SmiUntag(ecx); 2299864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ sar_cl(eax); // No checks of result necessary 2300864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ and_(eax, Immediate(~kSmiTagMask)); 2301864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org break; 2302864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case Token::SHL: { 2303864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label result_ok; 2304864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ SmiUntag(eax); 2305864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ SmiUntag(ecx); 2306864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ shl_cl(eax); 2307864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Check that the *signed* result fits in a smi. 2308864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ cmp(eax, 0xc0000000); 2309864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(positive, &result_ok); 2310864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ SmiTag(ecx); 2311864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ jmp(&stub_call); 2312864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&result_ok); 2313864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ SmiTag(eax); 2314864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org break; 2315864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 2316864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case Token::SHR: { 2317864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label result_ok; 2318864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ SmiUntag(eax); 2319864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ SmiUntag(ecx); 2320864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ shr_cl(eax); 2321864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ test(eax, Immediate(0xc0000000)); 2322864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(zero, &result_ok); 2323864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ SmiTag(ecx); 2324864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ jmp(&stub_call); 2325864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&result_ok); 2326864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ SmiTag(eax); 2327864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org break; 2328864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 2329864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case Token::ADD: 2330864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ add(eax, ecx); 2331864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(overflow, &stub_call); 2332864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org break; 2333864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case Token::SUB: 2334864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ sub(eax, ecx); 2335864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(overflow, &stub_call); 2336864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org break; 2337864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case Token::MUL: { 2338864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ SmiUntag(eax); 2339864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ imul(eax, ecx); 2340864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(overflow, &stub_call); 2341864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ test(eax, eax); 2342864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(not_zero, &done, Label::kNear); 2343864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(ebx, edx); 2344864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ or_(ebx, ecx); 2345864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(negative, &stub_call); 2346864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org break; 2347864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 2348864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case Token::BIT_OR: 2349864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ or_(eax, ecx); 2350864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org break; 2351864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case Token::BIT_AND: 2352864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ and_(eax, ecx); 2353864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org break; 2354864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case Token::BIT_XOR: 2355864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ xor_(eax, ecx); 2356864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org break; 2357864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org default: 2358864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org UNREACHABLE(); 2359864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 2360864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2361864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&done); 2362864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org context()->Plug(eax); 2363864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 2364864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2365864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2366864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr, 2367864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Token::Value op, 2368864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org OverwriteMode mode) { 2369864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ pop(edx); 2370b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), op, mode).code(); 2371864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code. 2372b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org CallIC(code, expr->BinaryOperationFeedbackId()); 2373864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org patch_site.EmitPatchInfo(); 2374864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org context()->Plug(eax); 2375864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 2376864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2377864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2378864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid FullCodeGenerator::EmitAssignment(Expression* expr) { 2379e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(expr->IsValidReferenceExpression()); 2380864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2381864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Left-hand side can only be a property, a global or a (parameter or local) 2382864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // slot. 2383864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org enum LhsKind { VARIABLE, NAMED_PROPERTY, KEYED_PROPERTY }; 2384864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org LhsKind assign_type = VARIABLE; 2385864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Property* prop = expr->AsProperty(); 2386864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (prop != NULL) { 2387864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org assign_type = (prop->key()->IsPropertyName()) 2388864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ? NAMED_PROPERTY 2389864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org : KEYED_PROPERTY; 2390864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 2391864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2392864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org switch (assign_type) { 2393864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case VARIABLE: { 2394864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Variable* var = expr->AsVariableProxy()->var(); 2395864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org EffectContext context(this); 2396864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org EmitVariableAssignment(var, Token::ASSIGN); 2397864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org break; 2398864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 2399864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case NAMED_PROPERTY: { 2400864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(eax); // Preserve value. 2401864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org VisitForAccumulatorValue(prop->obj()); 240242ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org __ Move(StoreDescriptor::ReceiverRegister(), eax); 240342ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org __ pop(StoreDescriptor::ValueRegister()); // Restore value. 240442ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org __ mov(StoreDescriptor::NameRegister(), 24057b6dc58d68c4315b99f5ec3faf6927db3d0db913machenbach@chromium.org prop->key()->AsLiteral()->value()); 2406864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org CallStoreIC(); 2407864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org break; 2408864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 2409864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case KEYED_PROPERTY: { 2410864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(eax); // Preserve value. 2411864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org VisitForStackValue(prop->obj()); 2412864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org VisitForAccumulatorValue(prop->key()); 241342ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org __ Move(StoreDescriptor::NameRegister(), eax); 241442ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org __ pop(StoreDescriptor::ReceiverRegister()); // Receiver. 241542ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org __ pop(StoreDescriptor::ValueRegister()); // Restore value. 2416b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org Handle<Code> ic = 2417b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org CodeFactory::KeyedStoreIC(isolate(), strict_mode()).code(); 2418864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org CallIC(ic); 2419864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org break; 2420864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 2421864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 2422864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org context()->Plug(eax); 2423864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 2424864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2425864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2426864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid FullCodeGenerator::EmitStoreToStackLocalOrContextSlot( 2427864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Variable* var, MemOperand location) { 2428864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(location, eax); 2429864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (var->IsContextSlot()) { 2430864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(edx, eax); 2431864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int offset = Context::SlotOffset(var->index()); 243206b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ RecordWriteContextSlot(ecx, offset, edx, ebx, kDontSaveFPRegs); 2433864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 2434864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 2435864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2436864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2437864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid FullCodeGenerator::EmitVariableAssignment(Variable* var, 2438864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Token::Value op) { 2439864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (var->IsUnallocated()) { 2440864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Global var, const, or let. 244142ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org __ mov(StoreDescriptor::NameRegister(), var->name()); 244242ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org __ mov(StoreDescriptor::ReceiverRegister(), GlobalObjectOperand()); 2443864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org CallStoreIC(); 2444864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2445864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else if (op == Token::INIT_CONST_LEGACY) { 2446864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Const initializers need a write barrier. 2447e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!var->IsParameter()); // No const parameters. 2448864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (var->IsLookupSlot()) { 2449864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(eax); 2450864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(esi); 2451864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(Immediate(var->name())); 2452d6472083da14af6fde0101cc78f95ababd7cc077machenbach@chromium.org __ CallRuntime(Runtime::kInitializeLegacyConstLookupSlot, 3); 2453864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 2454e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(var->IsStackLocal() || var->IsContextSlot()); 2455864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label skip; 2456864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org MemOperand location = VarOperand(var, ecx); 2457864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(edx, location); 2458864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ cmp(edx, isolate()->factory()->the_hole_value()); 2459864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(not_equal, &skip, Label::kNear); 2460864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org EmitStoreToStackLocalOrContextSlot(var, location); 2461864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&skip); 2462864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 2463864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2464864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else if (var->mode() == LET && op != Token::INIT_LET) { 2465864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Non-initializing assignment to let variable needs a write barrier. 2466e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!var->IsLookupSlot()); 2467e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(var->IsStackAllocated() || var->IsContextSlot()); 2468d6472083da14af6fde0101cc78f95ababd7cc077machenbach@chromium.org Label assign; 2469d6472083da14af6fde0101cc78f95ababd7cc077machenbach@chromium.org MemOperand location = VarOperand(var, ecx); 2470d6472083da14af6fde0101cc78f95ababd7cc077machenbach@chromium.org __ mov(edx, location); 2471d6472083da14af6fde0101cc78f95ababd7cc077machenbach@chromium.org __ cmp(edx, isolate()->factory()->the_hole_value()); 2472d6472083da14af6fde0101cc78f95ababd7cc077machenbach@chromium.org __ j(not_equal, &assign, Label::kNear); 2473d6472083da14af6fde0101cc78f95ababd7cc077machenbach@chromium.org __ push(Immediate(var->name())); 2474d6472083da14af6fde0101cc78f95ababd7cc077machenbach@chromium.org __ CallRuntime(Runtime::kThrowReferenceError, 1); 2475d6472083da14af6fde0101cc78f95ababd7cc077machenbach@chromium.org __ bind(&assign); 2476d6472083da14af6fde0101cc78f95ababd7cc077machenbach@chromium.org EmitStoreToStackLocalOrContextSlot(var, location); 2477864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2478864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else if (!var->is_const_mode() || op == Token::INIT_CONST) { 2479864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (var->IsLookupSlot()) { 2480d6472083da14af6fde0101cc78f95ababd7cc077machenbach@chromium.org // Assignment to var. 2481d6472083da14af6fde0101cc78f95ababd7cc077machenbach@chromium.org __ push(eax); // Value. 2482d6472083da14af6fde0101cc78f95ababd7cc077machenbach@chromium.org __ push(esi); // Context. 2483d6472083da14af6fde0101cc78f95ababd7cc077machenbach@chromium.org __ push(Immediate(var->name())); 2484d6472083da14af6fde0101cc78f95ababd7cc077machenbach@chromium.org __ push(Immediate(Smi::FromInt(strict_mode()))); 2485d6472083da14af6fde0101cc78f95ababd7cc077machenbach@chromium.org __ CallRuntime(Runtime::kStoreLookupSlot, 4); 2486864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 2487d6472083da14af6fde0101cc78f95ababd7cc077machenbach@chromium.org // Assignment to var or initializing assignment to let/const in harmony 2488d6472083da14af6fde0101cc78f95ababd7cc077machenbach@chromium.org // mode. 2489e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(var->IsStackAllocated() || var->IsContextSlot()); 2490864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org MemOperand location = VarOperand(var, ecx); 2491864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (generate_debug_code_ && op == Token::INIT_LET) { 2492864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Check for an uninitialized let binding. 2493864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(edx, location); 2494864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ cmp(edx, isolate()->factory()->the_hole_value()); 2495864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ Check(equal, kLetBindingReInitialization); 2496864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 2497864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org EmitStoreToStackLocalOrContextSlot(var, location); 2498864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 2499864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 2500864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Non-initializing assignments to consts are ignored. 2501864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 2502864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2503864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2504864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) { 2505864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Assignment to a property, using a named store IC. 2506864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // eax : value 2507864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // esp[0] : receiver 2508864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2509864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Property* prop = expr->target()->AsProperty(); 2510e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(prop != NULL); 2511e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(prop->key()->IsLiteral()); 2512864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2513864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Record source code position before IC call. 2514864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org SetSourcePosition(expr->position()); 251542ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org __ mov(StoreDescriptor::NameRegister(), prop->key()->AsLiteral()->value()); 251642ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org __ pop(StoreDescriptor::ReceiverRegister()); 2517864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org CallStoreIC(expr->AssignmentFeedbackId()); 2518864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 2519864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org context()->Plug(eax); 2520864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 2521864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2522864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2523864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) { 2524864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Assignment to a property, using a keyed store IC. 2525864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // eax : value 2526864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // esp[0] : key 2527864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // esp[kPointerSize] : receiver 2528864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 252942ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org __ pop(StoreDescriptor::NameRegister()); // Key. 253042ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org __ pop(StoreDescriptor::ReceiverRegister()); 253142ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org DCHECK(StoreDescriptor::ValueRegister().is(eax)); 2532864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Record source code position before IC call. 2533864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org SetSourcePosition(expr->position()); 2534b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org Handle<Code> ic = CodeFactory::KeyedStoreIC(isolate(), strict_mode()).code(); 2535864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org CallIC(ic, expr->AssignmentFeedbackId()); 2536864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2537864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 2538864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org context()->Plug(eax); 2539864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 2540864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2541864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2542864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid FullCodeGenerator::VisitProperty(Property* expr) { 2543864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Comment cmnt(masm_, "[ Property"); 2544864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Expression* key = expr->key(); 2545864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2546864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (key->IsPropertyName()) { 2547a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org if (!expr->IsSuperAccess()) { 2548a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org VisitForAccumulatorValue(expr->obj()); 2549a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org __ Move(LoadDescriptor::ReceiverRegister(), result_register()); 2550a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org EmitNamedPropertyLoad(expr); 2551a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org } else { 2552a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org EmitNamedSuperPropertyLoad(expr); 2553a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org } 2554864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org PrepareForBailoutForId(expr->LoadId(), TOS_REG); 2555864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org context()->Plug(eax); 2556864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 2557864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org VisitForStackValue(expr->obj()); 2558864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org VisitForAccumulatorValue(expr->key()); 255942ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org __ pop(LoadDescriptor::ReceiverRegister()); // Object. 256042ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org __ Move(LoadDescriptor::NameRegister(), result_register()); // Key. 2561864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org EmitKeyedPropertyLoad(expr); 2562864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org context()->Plug(eax); 2563864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 2564864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 2565864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2566864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2567864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid FullCodeGenerator::CallIC(Handle<Code> code, 2568864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org TypeFeedbackId ast_id) { 2569864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ic_total_count_++; 2570864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ call(code, RelocInfo::CODE_TARGET, ast_id); 2571864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 2572864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2573864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2574864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// Code common for calls using the IC. 2575864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid FullCodeGenerator::EmitCallWithLoadIC(Call* expr) { 2576864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Expression* callee = expr->expression(); 2577864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2578a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org CallICState::CallType call_type = 2579a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org callee->IsVariableProxy() ? CallICState::FUNCTION : CallICState::METHOD; 2580864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Get the target function. 2581a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org if (call_type == CallICState::FUNCTION) { 2582864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org { StackValueContext context(this); 2583864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org EmitVariableLoad(callee->AsVariableProxy()); 2584864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org PrepareForBailout(callee, NO_REGISTERS); 2585864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 2586864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Push undefined as receiver. This is patched in the method prologue if it 2587864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // is a sloppy mode method. 2588864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(Immediate(isolate()->factory()->undefined_value())); 2589864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 2590864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Load the function from the receiver. 2591e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(callee->IsProperty()); 2592a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org DCHECK(!callee->AsProperty()->IsSuperAccess()); 259342ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org __ mov(LoadDescriptor::ReceiverRegister(), Operand(esp, 0)); 2594864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org EmitNamedPropertyLoad(callee->AsProperty()); 2595864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); 2596864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Push the target function under the receiver. 2597864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(Operand(esp, 0)); 2598864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(Operand(esp, kPointerSize), eax); 2599864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 2600864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2601864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org EmitCall(expr, call_type); 2602864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 2603864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2604864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2605a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.orgvoid FullCodeGenerator::EmitSuperCallWithLoadIC(Call* expr) { 2606a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org Expression* callee = expr->expression(); 2607a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org DCHECK(callee->IsProperty()); 2608a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org Property* prop = callee->AsProperty(); 2609a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org DCHECK(prop->IsSuperAccess()); 2610a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org 2611a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org SetSourcePosition(prop->position()); 2612a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org Literal* key = prop->key()->AsLiteral(); 2613a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org DCHECK(!key->value()->IsSmi()); 2614a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org // Load the function from the receiver. 2615a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org SuperReference* super_ref = callee->AsProperty()->obj()->AsSuperReference(); 2616a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org EmitLoadHomeObject(super_ref); 2617a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org __ push(eax); 2618a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org VisitForAccumulatorValue(super_ref->this_var()); 2619a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org __ push(eax); 2620a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org __ push(Operand(esp, kPointerSize)); 2621a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org __ push(eax); 2622a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org __ push(Immediate(key->value())); 2623a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org // Stack here: 2624a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org // - home_object 2625a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org // - this (receiver) 2626a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org // - home_object <-- LoadFromSuper will pop here and below. 2627a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org // - this (receiver) 2628a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org // - key 2629a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org __ CallRuntime(Runtime::kLoadFromSuper, 3); 2630a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org 2631a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org // Replace home_object with target function. 2632a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org __ mov(Operand(esp, kPointerSize), eax); 2633a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org 2634a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org // Stack here: 2635a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org // - target function 2636a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org // - this (receiver) 2637a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org EmitCall(expr, CallICState::METHOD); 2638a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org} 2639a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org 2640a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org 2641864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// Code common for calls using the IC. 2642864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid FullCodeGenerator::EmitKeyedCallWithLoadIC(Call* expr, 2643864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Expression* key) { 2644864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Load the key. 2645864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org VisitForAccumulatorValue(key); 2646864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2647864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Expression* callee = expr->expression(); 2648864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2649864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Load the function from the receiver. 2650e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(callee->IsProperty()); 265142ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org __ mov(LoadDescriptor::ReceiverRegister(), Operand(esp, 0)); 265242ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org __ mov(LoadDescriptor::NameRegister(), eax); 2653864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org EmitKeyedPropertyLoad(callee->AsProperty()); 2654864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); 2655864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2656864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Push the target function under the receiver. 2657864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(Operand(esp, 0)); 2658864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(Operand(esp, kPointerSize), eax); 2659864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2660a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org EmitCall(expr, CallICState::METHOD); 2661864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 2662864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2663864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2664a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.orgvoid FullCodeGenerator::EmitCall(Call* expr, CallICState::CallType call_type) { 2665864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Load the arguments. 2666864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ZoneList<Expression*>* args = expr->arguments(); 2667864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int arg_count = args->length(); 2668864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org { PreservePositionScope scope(masm()->positions_recorder()); 2669864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org for (int i = 0; i < arg_count; i++) { 2670864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org VisitForStackValue(args->at(i)); 2671864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 2672864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 2673864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2674864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Record source position of the IC call. 2675864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org SetSourcePosition(expr->position()); 2676864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Handle<Code> ic = CallIC::initialize_stub( 2677864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org isolate(), arg_count, call_type); 2678864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ Move(edx, Immediate(Smi::FromInt(expr->CallFeedbackSlot()))); 2679864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(edi, Operand(esp, (arg_count + 1) * kPointerSize)); 2680864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Don't assign a type feedback id to the IC, since type feedback is provided 2681864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // by the vector above. 2682864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org CallIC(ic); 2683864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2684864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org RecordJSReturnSite(expr); 2685864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2686864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Restore context register. 2687864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); 2688864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2689864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org context()->DropAndPlug(1, eax); 2690864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 2691864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2692864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2693864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid FullCodeGenerator::EmitResolvePossiblyDirectEval(int arg_count) { 2694864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Push copy of the first argument or undefined if it doesn't exist. 2695864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (arg_count > 0) { 2696864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(Operand(esp, arg_count * kPointerSize)); 2697864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 2698864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(Immediate(isolate()->factory()->undefined_value())); 2699864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 2700864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2701b1d9f4b46c9d3041103c0d47fada41ea1ee9c839weiliang.lin@intel.com // Push the enclosing function. 2702b1d9f4b46c9d3041103c0d47fada41ea1ee9c839weiliang.lin@intel.com __ push(Operand(ebp, JavaScriptFrameConstants::kFunctionOffset)); 2703864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Push the receiver of the enclosing function. 2704864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(Operand(ebp, (2 + info_->scope()->num_parameters()) * kPointerSize)); 2705864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Push the language mode. 2706864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(Immediate(Smi::FromInt(strict_mode()))); 2707864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2708864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Push the start position of the scope the calls resides in. 2709864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(Immediate(Smi::FromInt(scope()->start_position()))); 2710864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2711864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Do the runtime call. 2712b1d9f4b46c9d3041103c0d47fada41ea1ee9c839weiliang.lin@intel.com __ CallRuntime(Runtime::kResolvePossiblyDirectEval, 6); 2713864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 2714864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2715864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2716864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid FullCodeGenerator::VisitCall(Call* expr) { 2717864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org#ifdef DEBUG 2718864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // We want to verify that RecordJSReturnSite gets called on all paths 2719864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // through this function. Avoid early returns. 2720864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org expr->return_is_recorded_ = false; 2721864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org#endif 2722864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2723864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Comment cmnt(masm_, "[ Call"); 2724864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Expression* callee = expr->expression(); 2725864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Call::CallType call_type = expr->GetCallType(isolate()); 2726864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2727864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (call_type == Call::POSSIBLY_EVAL_CALL) { 2728864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // In a call to eval, we first call RuntimeHidden_ResolvePossiblyDirectEval 2729864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // to resolve the function we need to call and the receiver of the call. 2730864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Then we call the resolved function using the given arguments. 2731864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ZoneList<Expression*>* args = expr->arguments(); 2732864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int arg_count = args->length(); 2733864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org { PreservePositionScope pos_scope(masm()->positions_recorder()); 2734864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org VisitForStackValue(callee); 2735864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Reserved receiver slot. 2736864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(Immediate(isolate()->factory()->undefined_value())); 2737864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Push the arguments. 2738864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org for (int i = 0; i < arg_count; i++) { 2739864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org VisitForStackValue(args->at(i)); 2740864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 2741864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2742864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Push a copy of the function (found below the arguments) and 2743864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // resolve eval. 2744864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(Operand(esp, (arg_count + 1) * kPointerSize)); 2745864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org EmitResolvePossiblyDirectEval(arg_count); 2746864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2747864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // The runtime call returns a pair of values in eax (function) and 2748864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // edx (receiver). Touch up the stack with the right values. 2749864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(Operand(esp, (arg_count + 0) * kPointerSize), edx); 2750864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(Operand(esp, (arg_count + 1) * kPointerSize), eax); 2751864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 2752864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Record source position for debugger. 2753864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org SetSourcePosition(expr->position()); 2754864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org CallFunctionStub stub(isolate(), arg_count, NO_CALL_FUNCTION_FLAGS); 2755864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(edi, Operand(esp, (arg_count + 1) * kPointerSize)); 2756864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ CallStub(&stub); 2757864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org RecordJSReturnSite(expr); 2758864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Restore context register. 2759864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); 2760864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org context()->DropAndPlug(1, eax); 2761864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2762864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else if (call_type == Call::GLOBAL_CALL) { 2763864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org EmitCallWithLoadIC(expr); 2764864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2765864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else if (call_type == Call::LOOKUP_SLOT_CALL) { 2766864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Call to a lookup slot (dynamically introduced variable). 2767864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org VariableProxy* proxy = callee->AsVariableProxy(); 2768864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label slow, done; 2769864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org { PreservePositionScope scope(masm()->positions_recorder()); 2770864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Generate code for loading from variables potentially shadowed by 2771864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // eval-introduced variables. 27727c0666e15d1f68f0fef5db9e5c409fab010ed816machenbach@chromium.org EmitDynamicLookupFastCase(proxy, NOT_INSIDE_TYPEOF, &slow, &done); 2773864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 2774864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&slow); 2775864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Call the runtime to find the function to call (returned in eax) and 2776864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // the object holding it (returned in edx). 2777864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(context_register()); 2778864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(Immediate(proxy->name())); 27794c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org __ CallRuntime(Runtime::kLoadLookupSlot, 2); 2780864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(eax); // Function. 2781864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(edx); // Receiver. 2782864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2783864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // If fast case code has been generated, emit code to push the function 2784864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // and receiver and have the slow path jump around this code. 2785864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (done.is_linked()) { 2786864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label call; 2787864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ jmp(&call, Label::kNear); 2788864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&done); 2789864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Push function. 2790864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(eax); 2791864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // The receiver is implicitly the global receiver. Indicate this by 2792864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // passing the hole to the call function stub. 2793864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(Immediate(isolate()->factory()->undefined_value())); 2794864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&call); 2795864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 2796864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2797864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // The receiver is either the global receiver or an object found by 2798864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // LoadContextSlot. 2799864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org EmitCall(expr); 2800864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2801864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else if (call_type == Call::PROPERTY_CALL) { 2802864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Property* property = callee->AsProperty(); 2803a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org bool is_named_call = property->key()->IsPropertyName(); 2804a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org // super.x() is handled in EmitCallWithLoadIC. 2805a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org if (property->IsSuperAccess() && is_named_call) { 2806a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org EmitSuperCallWithLoadIC(expr); 2807864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 2808a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org { 2809a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org PreservePositionScope scope(masm()->positions_recorder()); 2810a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org VisitForStackValue(property->obj()); 2811a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org } 2812a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org if (is_named_call) { 2813a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org EmitCallWithLoadIC(expr); 2814a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org } else { 2815a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org EmitKeyedCallWithLoadIC(expr, property->key()); 2816a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org } 2817864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 2818864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 2819e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(call_type == Call::OTHER_CALL); 2820864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Call to an arbitrary expression not handled specially above. 2821864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org { PreservePositionScope scope(masm()->positions_recorder()); 2822864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org VisitForStackValue(callee); 2823864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 2824864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(Immediate(isolate()->factory()->undefined_value())); 2825864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Emit function call. 2826864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org EmitCall(expr); 2827864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 2828864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2829864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org#ifdef DEBUG 2830864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // RecordJSReturnSite should have been called. 2831e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(expr->return_is_recorded_); 2832864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org#endif 2833864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 2834864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2835864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2836864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid FullCodeGenerator::VisitCallNew(CallNew* expr) { 2837864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Comment cmnt(masm_, "[ CallNew"); 2838864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // According to ECMA-262, section 11.2.2, page 44, the function 2839864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // expression in new calls must be evaluated before the 2840864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // arguments. 2841864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2842864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Push constructor on the stack. If it's not a function it's used as 2843864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // receiver for CALL_NON_FUNCTION, otherwise the value on the stack is 2844864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // ignored. 2845864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org VisitForStackValue(expr->expression()); 2846864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2847864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Push the arguments ("left-to-right") on the stack. 2848864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ZoneList<Expression*>* args = expr->arguments(); 2849864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int arg_count = args->length(); 2850864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org for (int i = 0; i < arg_count; i++) { 2851864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org VisitForStackValue(args->at(i)); 2852864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 2853864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2854864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Call the construct call builtin that handles allocation and 2855864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // constructor invocation. 2856864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org SetSourcePosition(expr->position()); 2857864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2858864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Load function and argument count into edi and eax. 2859864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ Move(eax, Immediate(arg_count)); 2860864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(edi, Operand(esp, arg_count * kPointerSize)); 2861864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2862864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Record call targets in unoptimized code. 2863864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (FLAG_pretenuring_call_new) { 2864864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org EnsureSlotContainsAllocationSite(expr->AllocationSiteFeedbackSlot()); 2865e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(expr->AllocationSiteFeedbackSlot() == 2866864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org expr->CallNewFeedbackSlot() + 1); 2867864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 2868864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2869864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ LoadHeapObject(ebx, FeedbackVector()); 2870864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(edx, Immediate(Smi::FromInt(expr->CallNewFeedbackSlot()))); 2871864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2872864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org CallConstructStub stub(isolate(), RECORD_CONSTRUCTOR_TARGET); 2873864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ call(stub.GetCode(), RelocInfo::CONSTRUCT_CALL); 2874864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org PrepareForBailoutForId(expr->ReturnId(), TOS_REG); 2875864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org context()->Plug(eax); 2876864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 2877864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2878864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2879864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid FullCodeGenerator::EmitIsSmi(CallRuntime* expr) { 2880864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ZoneList<Expression*>* args = expr->arguments(); 2881e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(args->length() == 1); 2882864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2883864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org VisitForAccumulatorValue(args->at(0)); 2884864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2885864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label materialize_true, materialize_false; 2886864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label* if_true = NULL; 2887864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label* if_false = NULL; 2888864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label* fall_through = NULL; 2889864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org context()->PrepareTest(&materialize_true, &materialize_false, 2890864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org &if_true, &if_false, &fall_through); 2891864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2892864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); 2893864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ test(eax, Immediate(kSmiTagMask)); 2894864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Split(zero, if_true, if_false, fall_through); 2895864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2896864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org context()->Plug(if_true, if_false); 2897864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 2898864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2899864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2900864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid FullCodeGenerator::EmitIsNonNegativeSmi(CallRuntime* expr) { 2901864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ZoneList<Expression*>* args = expr->arguments(); 2902e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(args->length() == 1); 2903864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2904864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org VisitForAccumulatorValue(args->at(0)); 2905864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2906864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label materialize_true, materialize_false; 2907864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label* if_true = NULL; 2908864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label* if_false = NULL; 2909864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label* fall_through = NULL; 2910864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org context()->PrepareTest(&materialize_true, &materialize_false, 2911864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org &if_true, &if_false, &fall_through); 2912864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2913864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); 2914864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ test(eax, Immediate(kSmiTagMask | 0x80000000)); 2915864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Split(zero, if_true, if_false, fall_through); 2916864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2917864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org context()->Plug(if_true, if_false); 2918864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 2919864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2920864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2921864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid FullCodeGenerator::EmitIsObject(CallRuntime* expr) { 2922864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ZoneList<Expression*>* args = expr->arguments(); 2923e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(args->length() == 1); 2924864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2925864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org VisitForAccumulatorValue(args->at(0)); 2926864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2927864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label materialize_true, materialize_false; 2928864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label* if_true = NULL; 2929864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label* if_false = NULL; 2930864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label* fall_through = NULL; 2931864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org context()->PrepareTest(&materialize_true, &materialize_false, 2932864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org &if_true, &if_false, &fall_through); 2933864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2934864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ JumpIfSmi(eax, if_false); 2935864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ cmp(eax, isolate()->factory()->null_value()); 2936864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(equal, if_true); 2937864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(ebx, FieldOperand(eax, HeapObject::kMapOffset)); 2938864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Undetectable objects behave like undefined when tested with typeof. 2939864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ movzx_b(ecx, FieldOperand(ebx, Map::kBitFieldOffset)); 2940864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ test(ecx, Immediate(1 << Map::kIsUndetectable)); 2941864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(not_zero, if_false); 2942864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ movzx_b(ecx, FieldOperand(ebx, Map::kInstanceTypeOffset)); 2943864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ cmp(ecx, FIRST_NONCALLABLE_SPEC_OBJECT_TYPE); 2944864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(below, if_false); 2945864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ cmp(ecx, LAST_NONCALLABLE_SPEC_OBJECT_TYPE); 2946864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); 2947864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Split(below_equal, if_true, if_false, fall_through); 2948864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2949864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org context()->Plug(if_true, if_false); 2950864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 2951864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2952864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2953864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid FullCodeGenerator::EmitIsSpecObject(CallRuntime* expr) { 2954864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ZoneList<Expression*>* args = expr->arguments(); 2955e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(args->length() == 1); 2956864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2957864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org VisitForAccumulatorValue(args->at(0)); 2958864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2959864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label materialize_true, materialize_false; 2960864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label* if_true = NULL; 2961864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label* if_false = NULL; 2962864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label* fall_through = NULL; 2963864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org context()->PrepareTest(&materialize_true, &materialize_false, 2964864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org &if_true, &if_false, &fall_through); 2965864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2966864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ JumpIfSmi(eax, if_false); 2967864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ CmpObjectType(eax, FIRST_SPEC_OBJECT_TYPE, ebx); 2968864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); 2969864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Split(above_equal, if_true, if_false, fall_through); 2970864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2971864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org context()->Plug(if_true, if_false); 2972864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 2973864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2974864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2975864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid FullCodeGenerator::EmitIsUndetectableObject(CallRuntime* expr) { 2976864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ZoneList<Expression*>* args = expr->arguments(); 2977e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(args->length() == 1); 2978864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2979864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org VisitForAccumulatorValue(args->at(0)); 2980864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2981864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label materialize_true, materialize_false; 2982864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label* if_true = NULL; 2983864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label* if_false = NULL; 2984864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label* fall_through = NULL; 2985864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org context()->PrepareTest(&materialize_true, &materialize_false, 2986864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org &if_true, &if_false, &fall_through); 2987864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2988864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ JumpIfSmi(eax, if_false); 2989864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(ebx, FieldOperand(eax, HeapObject::kMapOffset)); 2990864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ movzx_b(ebx, FieldOperand(ebx, Map::kBitFieldOffset)); 2991864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ test(ebx, Immediate(1 << Map::kIsUndetectable)); 2992864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); 2993864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Split(not_zero, if_true, if_false, fall_through); 2994864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2995864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org context()->Plug(if_true, if_false); 2996864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 2997864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2998864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 2999864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid FullCodeGenerator::EmitIsStringWrapperSafeForDefaultValueOf( 3000864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org CallRuntime* expr) { 3001864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ZoneList<Expression*>* args = expr->arguments(); 3002e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(args->length() == 1); 3003864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3004864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org VisitForAccumulatorValue(args->at(0)); 3005864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3006864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label materialize_true, materialize_false, skip_lookup; 3007864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label* if_true = NULL; 3008864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label* if_false = NULL; 3009864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label* fall_through = NULL; 3010864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org context()->PrepareTest(&materialize_true, &materialize_false, 3011864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org &if_true, &if_false, &fall_through); 3012864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3013864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ AssertNotSmi(eax); 3014864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3015864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Check whether this map has already been checked to be safe for default 3016864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // valueOf. 3017864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(ebx, FieldOperand(eax, HeapObject::kMapOffset)); 3018864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ test_b(FieldOperand(ebx, Map::kBitField2Offset), 3019864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1 << Map::kStringWrapperSafeForDefaultValueOf); 3020864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(not_zero, &skip_lookup); 3021864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3022864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Check for fast case object. Return false for slow case objects. 3023864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(ecx, FieldOperand(eax, JSObject::kPropertiesOffset)); 3024864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(ecx, FieldOperand(ecx, HeapObject::kMapOffset)); 3025864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ cmp(ecx, isolate()->factory()->hash_table_map()); 3026864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(equal, if_false); 3027864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3028864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Look for valueOf string in the descriptor array, and indicate false if 3029864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // found. Since we omit an enumeration index check, if it is added via a 3030864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // transition that shares its descriptor array, this is a false positive. 3031864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label entry, loop, done; 3032864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3033864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Skip loop if no descriptors are valid. 3034864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ NumberOfOwnDescriptors(ecx, ebx); 3035864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ cmp(ecx, 0); 3036864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(equal, &done); 3037864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3038864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ LoadInstanceDescriptors(ebx, ebx); 3039864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // ebx: descriptor array. 3040864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // ecx: valid entries in the descriptor array. 3041864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Calculate the end of the descriptor array. 3042864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org STATIC_ASSERT(kSmiTag == 0); 3043864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org STATIC_ASSERT(kSmiTagSize == 1); 3044864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org STATIC_ASSERT(kPointerSize == 4); 3045864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ imul(ecx, ecx, DescriptorArray::kDescriptorSize); 3046864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ lea(ecx, Operand(ebx, ecx, times_4, DescriptorArray::kFirstOffset)); 3047864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Calculate location of the first key name. 3048864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ add(ebx, Immediate(DescriptorArray::kFirstOffset)); 3049864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Loop through all the keys in the descriptor array. If one of these is the 3050864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // internalized string "valueOf" the result is false. 3051864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ jmp(&entry); 3052864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&loop); 3053864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(edx, FieldOperand(ebx, 0)); 3054864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ cmp(edx, isolate()->factory()->value_of_string()); 3055864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(equal, if_false); 3056864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ add(ebx, Immediate(DescriptorArray::kDescriptorSize * kPointerSize)); 3057864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&entry); 3058864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ cmp(ebx, ecx); 3059864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(not_equal, &loop); 3060864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3061864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&done); 3062864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3063864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Reload map as register ebx was used as temporary above. 3064864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(ebx, FieldOperand(eax, HeapObject::kMapOffset)); 3065864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3066864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Set the bit in the map to indicate that there is no local valueOf field. 3067864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ or_(FieldOperand(ebx, Map::kBitField2Offset), 3068864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Immediate(1 << Map::kStringWrapperSafeForDefaultValueOf)); 3069864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3070864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&skip_lookup); 3071864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3072864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // If a valueOf property is not found on the object check that its 3073864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // prototype is the un-modified String prototype. If not result is false. 3074864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(ecx, FieldOperand(ebx, Map::kPrototypeOffset)); 3075864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ JumpIfSmi(ecx, if_false); 3076864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(ecx, FieldOperand(ecx, HeapObject::kMapOffset)); 3077864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(edx, Operand(esi, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX))); 3078864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(edx, 3079864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org FieldOperand(edx, GlobalObject::kNativeContextOffset)); 3080864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ cmp(ecx, 3081864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ContextOperand(edx, 3082864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Context::STRING_FUNCTION_PROTOTYPE_MAP_INDEX)); 3083864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); 3084864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Split(equal, if_true, if_false, fall_through); 3085864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3086864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org context()->Plug(if_true, if_false); 3087864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 3088864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3089864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3090864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid FullCodeGenerator::EmitIsFunction(CallRuntime* expr) { 3091864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ZoneList<Expression*>* args = expr->arguments(); 3092e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(args->length() == 1); 3093864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3094864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org VisitForAccumulatorValue(args->at(0)); 3095864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3096864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label materialize_true, materialize_false; 3097864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label* if_true = NULL; 3098864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label* if_false = NULL; 3099864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label* fall_through = NULL; 3100864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org context()->PrepareTest(&materialize_true, &materialize_false, 3101864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org &if_true, &if_false, &fall_through); 3102864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3103864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ JumpIfSmi(eax, if_false); 3104864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ CmpObjectType(eax, JS_FUNCTION_TYPE, ebx); 3105864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); 3106864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Split(equal, if_true, if_false, fall_through); 3107864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3108864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org context()->Plug(if_true, if_false); 3109864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 3110864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3111864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3112864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid FullCodeGenerator::EmitIsMinusZero(CallRuntime* expr) { 3113864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ZoneList<Expression*>* args = expr->arguments(); 3114e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(args->length() == 1); 3115864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3116864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org VisitForAccumulatorValue(args->at(0)); 3117864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3118864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label materialize_true, materialize_false; 3119864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label* if_true = NULL; 3120864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label* if_false = NULL; 3121864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label* fall_through = NULL; 3122864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org context()->PrepareTest(&materialize_true, &materialize_false, 3123864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org &if_true, &if_false, &fall_through); 3124864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3125864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Handle<Map> map = masm()->isolate()->factory()->heap_number_map(); 3126864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ CheckMap(eax, map, if_false, DO_SMI_CHECK); 3127864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Check if the exponent half is 0x80000000. Comparing against 1 and 3128864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // checking for overflow is the shortest possible encoding. 3129864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ cmp(FieldOperand(eax, HeapNumber::kExponentOffset), Immediate(0x1)); 3130864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(no_overflow, if_false); 3131864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ cmp(FieldOperand(eax, HeapNumber::kMantissaOffset), Immediate(0x0)); 3132864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); 3133864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Split(equal, if_true, if_false, fall_through); 3134864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3135864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org context()->Plug(if_true, if_false); 3136864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 3137864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3138864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3139864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3140864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid FullCodeGenerator::EmitIsArray(CallRuntime* expr) { 3141864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ZoneList<Expression*>* args = expr->arguments(); 3142e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(args->length() == 1); 3143864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3144864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org VisitForAccumulatorValue(args->at(0)); 3145864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3146864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label materialize_true, materialize_false; 3147864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label* if_true = NULL; 3148864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label* if_false = NULL; 3149864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label* fall_through = NULL; 3150864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org context()->PrepareTest(&materialize_true, &materialize_false, 3151864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org &if_true, &if_false, &fall_through); 3152864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3153864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ JumpIfSmi(eax, if_false); 3154864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ CmpObjectType(eax, JS_ARRAY_TYPE, ebx); 3155864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); 3156864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Split(equal, if_true, if_false, fall_through); 3157864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3158864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org context()->Plug(if_true, if_false); 3159864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 3160864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3161864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3162864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid FullCodeGenerator::EmitIsRegExp(CallRuntime* expr) { 3163864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ZoneList<Expression*>* args = expr->arguments(); 3164e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(args->length() == 1); 3165864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3166864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org VisitForAccumulatorValue(args->at(0)); 3167864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3168864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label materialize_true, materialize_false; 3169864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label* if_true = NULL; 3170864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label* if_false = NULL; 3171864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label* fall_through = NULL; 3172864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org context()->PrepareTest(&materialize_true, &materialize_false, 3173864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org &if_true, &if_false, &fall_through); 3174864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3175864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ JumpIfSmi(eax, if_false); 3176864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ CmpObjectType(eax, JS_REGEXP_TYPE, ebx); 3177864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); 3178864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Split(equal, if_true, if_false, fall_through); 3179864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3180864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org context()->Plug(if_true, if_false); 3181864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 3182864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3183864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3184864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3185864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid FullCodeGenerator::EmitIsConstructCall(CallRuntime* expr) { 3186e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(expr->arguments()->length() == 0); 3187864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3188864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label materialize_true, materialize_false; 3189864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label* if_true = NULL; 3190864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label* if_false = NULL; 3191864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label* fall_through = NULL; 3192864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org context()->PrepareTest(&materialize_true, &materialize_false, 3193864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org &if_true, &if_false, &fall_through); 3194864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3195864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Get the frame pointer for the calling frame. 3196864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(eax, Operand(ebp, StandardFrameConstants::kCallerFPOffset)); 3197864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3198864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Skip the arguments adaptor frame if it exists. 3199864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label check_frame_marker; 3200864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ cmp(Operand(eax, StandardFrameConstants::kContextOffset), 3201864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Immediate(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR))); 3202864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(not_equal, &check_frame_marker); 3203864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(eax, Operand(eax, StandardFrameConstants::kCallerFPOffset)); 3204864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3205864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Check the marker in the calling frame. 3206864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&check_frame_marker); 3207864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ cmp(Operand(eax, StandardFrameConstants::kMarkerOffset), 3208864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Immediate(Smi::FromInt(StackFrame::CONSTRUCT))); 3209864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); 3210864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Split(equal, if_true, if_false, fall_through); 3211864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3212864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org context()->Plug(if_true, if_false); 3213864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 3214864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3215864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3216864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid FullCodeGenerator::EmitObjectEquals(CallRuntime* expr) { 3217864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ZoneList<Expression*>* args = expr->arguments(); 3218e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(args->length() == 2); 3219864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3220864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Load the two objects into registers and perform the comparison. 3221864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org VisitForStackValue(args->at(0)); 3222864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org VisitForAccumulatorValue(args->at(1)); 3223864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3224864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label materialize_true, materialize_false; 3225864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label* if_true = NULL; 3226864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label* if_false = NULL; 3227864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label* fall_through = NULL; 3228864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org context()->PrepareTest(&materialize_true, &materialize_false, 3229864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org &if_true, &if_false, &fall_through); 3230864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3231864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ pop(ebx); 3232864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ cmp(eax, ebx); 3233864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); 3234864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Split(equal, if_true, if_false, fall_through); 3235864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3236864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org context()->Plug(if_true, if_false); 3237864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 3238864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3239864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3240864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid FullCodeGenerator::EmitArguments(CallRuntime* expr) { 3241864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ZoneList<Expression*>* args = expr->arguments(); 3242e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(args->length() == 1); 3243864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3244864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // ArgumentsAccessStub expects the key in edx and the formal 3245864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // parameter count in eax. 3246864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org VisitForAccumulatorValue(args->at(0)); 3247864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(edx, eax); 3248864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ Move(eax, Immediate(Smi::FromInt(info_->scope()->num_parameters()))); 3249864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ArgumentsAccessStub stub(isolate(), ArgumentsAccessStub::READ_ELEMENT); 3250864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ CallStub(&stub); 3251864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org context()->Plug(eax); 3252864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 3253864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3254864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3255864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid FullCodeGenerator::EmitArgumentsLength(CallRuntime* expr) { 3256e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(expr->arguments()->length() == 0); 3257864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3258864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label exit; 3259864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Get the number of formal parameters. 3260864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ Move(eax, Immediate(Smi::FromInt(info_->scope()->num_parameters()))); 3261864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3262864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Check if the calling frame is an arguments adaptor frame. 3263864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(ebx, Operand(ebp, StandardFrameConstants::kCallerFPOffset)); 3264864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ cmp(Operand(ebx, StandardFrameConstants::kContextOffset), 3265864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Immediate(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR))); 3266864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(not_equal, &exit); 3267864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3268864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Arguments adaptor case: Read the arguments length from the 3269864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // adaptor frame. 3270864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(eax, Operand(ebx, ArgumentsAdaptorFrameConstants::kLengthOffset)); 3271864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3272864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&exit); 3273864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ AssertSmi(eax); 3274864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org context()->Plug(eax); 3275864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 3276864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3277864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3278864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid FullCodeGenerator::EmitClassOf(CallRuntime* expr) { 3279864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ZoneList<Expression*>* args = expr->arguments(); 3280e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(args->length() == 1); 3281864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label done, null, function, non_function_constructor; 3282864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3283864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org VisitForAccumulatorValue(args->at(0)); 3284864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3285864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // If the object is a smi, we return null. 3286864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ JumpIfSmi(eax, &null); 3287864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3288864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Check that the object is a JS object but take special care of JS 3289864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // functions to make sure they have 'Function' as their class. 3290864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Assume that there are only two callable types, and one of them is at 3291864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // either end of the type range for JS object types. Saves extra comparisons. 3292864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org STATIC_ASSERT(NUM_OF_CALLABLE_SPEC_OBJECT_TYPES == 2); 3293864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ CmpObjectType(eax, FIRST_SPEC_OBJECT_TYPE, eax); 3294864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Map is now in eax. 3295864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(below, &null); 3296864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org STATIC_ASSERT(FIRST_NONCALLABLE_SPEC_OBJECT_TYPE == 3297864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org FIRST_SPEC_OBJECT_TYPE + 1); 3298864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(equal, &function); 3299864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3300864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ CmpInstanceType(eax, LAST_SPEC_OBJECT_TYPE); 3301864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org STATIC_ASSERT(LAST_NONCALLABLE_SPEC_OBJECT_TYPE == 3302864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org LAST_SPEC_OBJECT_TYPE - 1); 3303864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(equal, &function); 3304864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Assume that there is no larger type. 3305864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org STATIC_ASSERT(LAST_NONCALLABLE_SPEC_OBJECT_TYPE == LAST_TYPE - 1); 3306864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3307864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Check if the constructor in the map is a JS function. 3308864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(eax, FieldOperand(eax, Map::kConstructorOffset)); 3309864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ CmpObjectType(eax, JS_FUNCTION_TYPE, ebx); 3310864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(not_equal, &non_function_constructor); 3311864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3312864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // eax now contains the constructor function. Grab the 3313864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // instance class name from there. 3314864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(eax, FieldOperand(eax, JSFunction::kSharedFunctionInfoOffset)); 3315864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(eax, FieldOperand(eax, SharedFunctionInfo::kInstanceClassNameOffset)); 3316864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ jmp(&done); 3317864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3318864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Functions have class 'Function'. 3319864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&function); 33205e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org __ mov(eax, isolate()->factory()->Function_string()); 3321864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ jmp(&done); 3322864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3323864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Objects with a non-function constructor have class 'Object'. 3324864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&non_function_constructor); 3325864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(eax, isolate()->factory()->Object_string()); 3326864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ jmp(&done); 3327864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3328864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Non-JS objects have class null. 3329864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&null); 3330864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(eax, isolate()->factory()->null_value()); 3331864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3332864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // All done. 3333864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&done); 3334864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3335864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org context()->Plug(eax); 3336864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 3337864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3338864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3339864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid FullCodeGenerator::EmitSubString(CallRuntime* expr) { 3340864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Load the arguments on the stack and call the stub. 3341864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org SubStringStub stub(isolate()); 3342864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ZoneList<Expression*>* args = expr->arguments(); 3343e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(args->length() == 3); 3344864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org VisitForStackValue(args->at(0)); 3345864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org VisitForStackValue(args->at(1)); 3346864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org VisitForStackValue(args->at(2)); 3347864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ CallStub(&stub); 3348864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org context()->Plug(eax); 3349864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 3350864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3351864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3352864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid FullCodeGenerator::EmitRegExpExec(CallRuntime* expr) { 3353864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Load the arguments on the stack and call the stub. 3354864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org RegExpExecStub stub(isolate()); 3355864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ZoneList<Expression*>* args = expr->arguments(); 3356e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(args->length() == 4); 3357864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org VisitForStackValue(args->at(0)); 3358864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org VisitForStackValue(args->at(1)); 3359864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org VisitForStackValue(args->at(2)); 3360864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org VisitForStackValue(args->at(3)); 3361864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ CallStub(&stub); 3362864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org context()->Plug(eax); 3363864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 3364864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3365864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3366864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid FullCodeGenerator::EmitValueOf(CallRuntime* expr) { 3367864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ZoneList<Expression*>* args = expr->arguments(); 3368e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(args->length() == 1); 3369864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3370864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org VisitForAccumulatorValue(args->at(0)); // Load the object. 3371864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3372864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label done; 3373864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // If the object is a smi return the object. 3374864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ JumpIfSmi(eax, &done, Label::kNear); 3375864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // If the object is not a value type, return the object. 3376864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ CmpObjectType(eax, JS_VALUE_TYPE, ebx); 3377864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(not_equal, &done, Label::kNear); 3378864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(eax, FieldOperand(eax, JSValue::kValueOffset)); 3379864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3380864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&done); 3381864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org context()->Plug(eax); 3382864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 3383864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3384864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3385864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid FullCodeGenerator::EmitDateField(CallRuntime* expr) { 3386864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ZoneList<Expression*>* args = expr->arguments(); 3387e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(args->length() == 2); 3388e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK_NE(NULL, args->at(1)->AsLiteral()); 3389864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Smi* index = Smi::cast(*(args->at(1)->AsLiteral()->value())); 3390864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3391864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org VisitForAccumulatorValue(args->at(0)); // Load the object. 3392864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3393864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label runtime, done, not_date_object; 3394864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register object = eax; 3395864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register result = eax; 3396864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register scratch = ecx; 3397864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3398864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ JumpIfSmi(object, ¬_date_object); 3399864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ CmpObjectType(object, JS_DATE_TYPE, scratch); 3400864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(not_equal, ¬_date_object); 3401864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3402864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (index->value() == 0) { 3403864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(result, FieldOperand(object, JSDate::kValueOffset)); 3404864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ jmp(&done); 3405864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 3406864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (index->value() < JSDate::kFirstUncachedField) { 3407864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ExternalReference stamp = ExternalReference::date_cache_stamp(isolate()); 3408864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(scratch, Operand::StaticVariable(stamp)); 3409864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ cmp(scratch, FieldOperand(object, JSDate::kCacheStampOffset)); 3410864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(not_equal, &runtime, Label::kNear); 3411864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(result, FieldOperand(object, JSDate::kValueOffset + 3412864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org kPointerSize * index->value())); 3413864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ jmp(&done); 3414864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 3415864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&runtime); 3416864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ PrepareCallCFunction(2, scratch); 3417864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(Operand(esp, 0), object); 3418864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(Operand(esp, 1 * kPointerSize), Immediate(index)); 3419864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ CallCFunction(ExternalReference::get_date_field_function(isolate()), 2); 3420864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ jmp(&done); 3421864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 3422864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3423864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(¬_date_object); 342447390597afd6b17870f41dfb5dd8c057aea1f068machenbach@chromium.org __ CallRuntime(Runtime::kThrowNotDateError, 0); 3425864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&done); 3426864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org context()->Plug(result); 3427864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 3428864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3429864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3430864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid FullCodeGenerator::EmitOneByteSeqStringSetChar(CallRuntime* expr) { 3431864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ZoneList<Expression*>* args = expr->arguments(); 3432e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK_EQ(3, args->length()); 3433864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3434864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register string = eax; 3435864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register index = ebx; 3436864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register value = ecx; 3437864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3438b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org VisitForStackValue(args->at(0)); // index 3439b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org VisitForStackValue(args->at(1)); // value 3440b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org VisitForAccumulatorValue(args->at(2)); // string 3441864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3442864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ pop(value); 3443864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ pop(index); 3444864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3445864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (FLAG_debug_code) { 3446864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ test(value, Immediate(kSmiTagMask)); 3447864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ Check(zero, kNonSmiValue); 3448864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ test(index, Immediate(kSmiTagMask)); 3449864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ Check(zero, kNonSmiValue); 3450864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 3451864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3452864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ SmiUntag(value); 3453864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ SmiUntag(index); 3454864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3455864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (FLAG_debug_code) { 3456864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org static const uint32_t one_byte_seq_type = kSeqStringTag | kOneByteStringTag; 3457864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ EmitSeqStringSetCharCheck(string, index, value, one_byte_seq_type); 3458864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 3459864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3460864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov_b(FieldOperand(string, index, times_1, SeqOneByteString::kHeaderSize), 3461864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org value); 3462864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org context()->Plug(string); 3463864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 3464864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3465864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3466864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid FullCodeGenerator::EmitTwoByteSeqStringSetChar(CallRuntime* expr) { 3467864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ZoneList<Expression*>* args = expr->arguments(); 3468e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK_EQ(3, args->length()); 3469864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3470864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register string = eax; 3471864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register index = ebx; 3472864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register value = ecx; 3473864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3474b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org VisitForStackValue(args->at(0)); // index 3475b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org VisitForStackValue(args->at(1)); // value 3476b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org VisitForAccumulatorValue(args->at(2)); // string 3477864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ pop(value); 3478864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ pop(index); 3479864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3480864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (FLAG_debug_code) { 3481864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ test(value, Immediate(kSmiTagMask)); 3482864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ Check(zero, kNonSmiValue); 3483864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ test(index, Immediate(kSmiTagMask)); 3484864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ Check(zero, kNonSmiValue); 3485864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ SmiUntag(index); 3486864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org static const uint32_t two_byte_seq_type = kSeqStringTag | kTwoByteStringTag; 3487864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ EmitSeqStringSetCharCheck(string, index, value, two_byte_seq_type); 3488864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ SmiTag(index); 3489864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 3490864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3491864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ SmiUntag(value); 3492864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // No need to untag a smi for two-byte addressing. 3493864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov_w(FieldOperand(string, index, times_1, SeqTwoByteString::kHeaderSize), 3494864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org value); 3495864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org context()->Plug(string); 3496864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 3497864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3498864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3499864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid FullCodeGenerator::EmitMathPow(CallRuntime* expr) { 3500864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Load the arguments on the stack and call the runtime function. 3501864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ZoneList<Expression*>* args = expr->arguments(); 3502e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(args->length() == 2); 3503864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org VisitForStackValue(args->at(0)); 3504864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org VisitForStackValue(args->at(1)); 3505864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 350647390597afd6b17870f41dfb5dd8c057aea1f068machenbach@chromium.org __ CallRuntime(Runtime::kMathPowSlow, 2); 3507864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org context()->Plug(eax); 3508864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 3509864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3510864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3511864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid FullCodeGenerator::EmitSetValueOf(CallRuntime* expr) { 3512864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ZoneList<Expression*>* args = expr->arguments(); 3513e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(args->length() == 2); 3514864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3515864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org VisitForStackValue(args->at(0)); // Load the object. 3516864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org VisitForAccumulatorValue(args->at(1)); // Load the value. 3517864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ pop(ebx); // eax = value. ebx = object. 3518864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3519864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label done; 3520864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // If the object is a smi, return the value. 3521864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ JumpIfSmi(ebx, &done, Label::kNear); 3522864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3523864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // If the object is not a value type, return the value. 3524864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ CmpObjectType(ebx, JS_VALUE_TYPE, ecx); 3525864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(not_equal, &done, Label::kNear); 3526864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3527864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Store the value. 3528864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(FieldOperand(ebx, JSValue::kValueOffset), eax); 3529864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3530864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Update the write barrier. Save the value as it will be 3531864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // overwritten by the write barrier code and is needed afterward. 3532864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(edx, eax); 353306b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org __ RecordWriteField(ebx, JSValue::kValueOffset, edx, ecx, kDontSaveFPRegs); 3534864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3535864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&done); 3536864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org context()->Plug(eax); 3537864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 3538864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3539864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3540864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid FullCodeGenerator::EmitNumberToString(CallRuntime* expr) { 3541864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ZoneList<Expression*>* args = expr->arguments(); 3542e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK_EQ(args->length(), 1); 3543864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3544864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Load the argument into eax and call the stub. 3545864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org VisitForAccumulatorValue(args->at(0)); 3546864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3547864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org NumberToStringStub stub(isolate()); 3548864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ CallStub(&stub); 3549864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org context()->Plug(eax); 3550864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 3551864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3552864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3553864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid FullCodeGenerator::EmitStringCharFromCode(CallRuntime* expr) { 3554864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ZoneList<Expression*>* args = expr->arguments(); 3555e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(args->length() == 1); 3556864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3557864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org VisitForAccumulatorValue(args->at(0)); 3558864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3559864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label done; 3560864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org StringCharFromCodeGenerator generator(eax, ebx); 3561864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org generator.GenerateFast(masm_); 3562864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ jmp(&done); 3563864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3564864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org NopRuntimeCallHelper call_helper; 3565864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org generator.GenerateSlow(masm_, call_helper); 3566864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3567864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&done); 3568864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org context()->Plug(ebx); 3569864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 3570864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3571864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3572864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid FullCodeGenerator::EmitStringCharCodeAt(CallRuntime* expr) { 3573864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ZoneList<Expression*>* args = expr->arguments(); 3574e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(args->length() == 2); 3575864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3576864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org VisitForStackValue(args->at(0)); 3577864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org VisitForAccumulatorValue(args->at(1)); 3578864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3579864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register object = ebx; 3580864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register index = eax; 3581864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register result = edx; 3582864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3583864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ pop(object); 3584864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3585864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label need_conversion; 3586864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label index_out_of_range; 3587864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label done; 3588864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org StringCharCodeAtGenerator generator(object, 3589864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org index, 3590864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org result, 3591864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org &need_conversion, 3592864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org &need_conversion, 3593864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org &index_out_of_range, 3594864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org STRING_INDEX_IS_NUMBER); 3595864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org generator.GenerateFast(masm_); 3596864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ jmp(&done); 3597864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3598864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&index_out_of_range); 3599864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // When the index is out of range, the spec requires us to return 3600864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // NaN. 3601864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ Move(result, Immediate(isolate()->factory()->nan_value())); 3602864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ jmp(&done); 3603864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3604864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&need_conversion); 3605864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Move the undefined value into the result register, which will 3606864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // trigger conversion. 3607864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ Move(result, Immediate(isolate()->factory()->undefined_value())); 3608864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ jmp(&done); 3609864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3610864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org NopRuntimeCallHelper call_helper; 3611864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org generator.GenerateSlow(masm_, call_helper); 3612864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3613864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&done); 3614864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org context()->Plug(result); 3615864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 3616864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3617864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3618864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid FullCodeGenerator::EmitStringCharAt(CallRuntime* expr) { 3619864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ZoneList<Expression*>* args = expr->arguments(); 3620e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(args->length() == 2); 3621864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3622864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org VisitForStackValue(args->at(0)); 3623864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org VisitForAccumulatorValue(args->at(1)); 3624864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3625864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register object = ebx; 3626864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register index = eax; 3627864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register scratch = edx; 3628864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register result = eax; 3629864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3630864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ pop(object); 3631864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3632864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label need_conversion; 3633864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label index_out_of_range; 3634864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label done; 3635864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org StringCharAtGenerator generator(object, 3636864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org index, 3637864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org scratch, 3638864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org result, 3639864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org &need_conversion, 3640864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org &need_conversion, 3641864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org &index_out_of_range, 3642864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org STRING_INDEX_IS_NUMBER); 3643864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org generator.GenerateFast(masm_); 3644864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ jmp(&done); 3645864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3646864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&index_out_of_range); 3647864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // When the index is out of range, the spec requires us to return 3648864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // the empty string. 3649864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ Move(result, Immediate(isolate()->factory()->empty_string())); 3650864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ jmp(&done); 3651864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3652864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&need_conversion); 3653864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Move smi zero into the result register, which will trigger 3654864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // conversion. 3655864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ Move(result, Immediate(Smi::FromInt(0))); 3656864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ jmp(&done); 3657864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3658864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org NopRuntimeCallHelper call_helper; 3659864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org generator.GenerateSlow(masm_, call_helper); 3660864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3661864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&done); 3662864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org context()->Plug(result); 3663864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 3664864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3665864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3666864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid FullCodeGenerator::EmitStringAdd(CallRuntime* expr) { 3667864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ZoneList<Expression*>* args = expr->arguments(); 3668e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK_EQ(2, args->length()); 3669864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org VisitForStackValue(args->at(0)); 3670864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org VisitForAccumulatorValue(args->at(1)); 3671864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3672864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ pop(edx); 3673864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org StringAddStub stub(isolate(), STRING_ADD_CHECK_BOTH, NOT_TENURED); 3674864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ CallStub(&stub); 3675864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org context()->Plug(eax); 3676864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 3677864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3678864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3679864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid FullCodeGenerator::EmitStringCompare(CallRuntime* expr) { 3680864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ZoneList<Expression*>* args = expr->arguments(); 3681e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK_EQ(2, args->length()); 3682864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3683864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org VisitForStackValue(args->at(0)); 3684864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org VisitForStackValue(args->at(1)); 3685864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3686864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org StringCompareStub stub(isolate()); 3687864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ CallStub(&stub); 3688864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org context()->Plug(eax); 3689864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 3690864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3691864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3692864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid FullCodeGenerator::EmitCallFunction(CallRuntime* expr) { 3693864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ZoneList<Expression*>* args = expr->arguments(); 3694e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(args->length() >= 2); 3695864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3696864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int arg_count = args->length() - 2; // 2 ~ receiver and function. 3697864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org for (int i = 0; i < arg_count + 1; ++i) { 3698864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org VisitForStackValue(args->at(i)); 3699864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 3700864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org VisitForAccumulatorValue(args->last()); // Function. 3701864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3702864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label runtime, done; 3703864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Check for non-function argument (including proxy). 3704864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ JumpIfSmi(eax, &runtime); 3705864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ CmpObjectType(eax, JS_FUNCTION_TYPE, ebx); 3706864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(not_equal, &runtime); 3707864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3708864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // InvokeFunction requires the function in edi. Move it in there. 3709864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(edi, result_register()); 3710864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ParameterCount count(arg_count); 3711864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ InvokeFunction(edi, count, CALL_FUNCTION, NullCallWrapper()); 3712864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); 3713864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ jmp(&done); 3714864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3715864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&runtime); 3716864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(eax); 3717864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ CallRuntime(Runtime::kCall, args->length()); 3718864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&done); 3719864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3720864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org context()->Plug(eax); 3721864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 3722864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3723864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3724864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid FullCodeGenerator::EmitRegExpConstructResult(CallRuntime* expr) { 3725864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Load the arguments on the stack and call the stub. 3726864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org RegExpConstructResultStub stub(isolate()); 3727864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ZoneList<Expression*>* args = expr->arguments(); 3728e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(args->length() == 3); 3729864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org VisitForStackValue(args->at(0)); 3730864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org VisitForStackValue(args->at(1)); 3731864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org VisitForAccumulatorValue(args->at(2)); 3732864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ pop(ebx); 3733864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ pop(ecx); 3734864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ CallStub(&stub); 3735864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org context()->Plug(eax); 3736864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 3737864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3738864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3739864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid FullCodeGenerator::EmitGetFromCache(CallRuntime* expr) { 3740864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ZoneList<Expression*>* args = expr->arguments(); 3741e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK_EQ(2, args->length()); 3742864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3743e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK_NE(NULL, args->at(0)->AsLiteral()); 3744864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int cache_id = Smi::cast(*(args->at(0)->AsLiteral()->value()))->value(); 3745864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3746864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Handle<FixedArray> jsfunction_result_caches( 3747864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org isolate()->native_context()->jsfunction_result_caches()); 3748864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (jsfunction_result_caches->length() <= cache_id) { 3749864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ Abort(kAttemptToUseUndefinedCache); 3750864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(eax, isolate()->factory()->undefined_value()); 3751864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org context()->Plug(eax); 3752864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return; 3753864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 3754864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3755864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org VisitForAccumulatorValue(args->at(1)); 3756864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3757864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register key = eax; 3758864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register cache = ebx; 3759864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register tmp = ecx; 3760864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(cache, ContextOperand(esi, Context::GLOBAL_OBJECT_INDEX)); 3761864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(cache, 3762864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org FieldOperand(cache, GlobalObject::kNativeContextOffset)); 3763864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(cache, ContextOperand(cache, Context::JSFUNCTION_RESULT_CACHES_INDEX)); 3764864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(cache, 3765864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org FieldOperand(cache, FixedArray::OffsetOfElementAt(cache_id))); 3766864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3767864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label done, not_found; 3768864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org STATIC_ASSERT(kSmiTag == 0 && kSmiTagSize == 1); 3769864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(tmp, FieldOperand(cache, JSFunctionResultCache::kFingerOffset)); 3770864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // tmp now holds finger offset as a smi. 3771864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ cmp(key, FixedArrayElementOperand(cache, tmp)); 3772864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(not_equal, ¬_found); 3773864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3774864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(eax, FixedArrayElementOperand(cache, tmp, 1)); 3775864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ jmp(&done); 3776864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3777864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(¬_found); 3778864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Call runtime to perform the lookup. 3779864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(cache); 3780864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(key); 378147390597afd6b17870f41dfb5dd8c057aea1f068machenbach@chromium.org __ CallRuntime(Runtime::kGetFromCache, 2); 3782864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3783864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&done); 3784864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org context()->Plug(eax); 3785864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 3786864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3787864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3788864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid FullCodeGenerator::EmitHasCachedArrayIndex(CallRuntime* expr) { 3789864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ZoneList<Expression*>* args = expr->arguments(); 3790e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(args->length() == 1); 3791864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3792864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org VisitForAccumulatorValue(args->at(0)); 3793864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3794864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ AssertString(eax); 3795864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3796864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label materialize_true, materialize_false; 3797864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label* if_true = NULL; 3798864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label* if_false = NULL; 3799864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label* fall_through = NULL; 3800864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org context()->PrepareTest(&materialize_true, &materialize_false, 3801864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org &if_true, &if_false, &fall_through); 3802864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3803864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ test(FieldOperand(eax, String::kHashFieldOffset), 3804864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Immediate(String::kContainsCachedArrayIndexMask)); 3805864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); 3806864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Split(zero, if_true, if_false, fall_through); 3807864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3808864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org context()->Plug(if_true, if_false); 3809864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 3810864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3811864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3812864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid FullCodeGenerator::EmitGetCachedArrayIndex(CallRuntime* expr) { 3813864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ZoneList<Expression*>* args = expr->arguments(); 3814e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(args->length() == 1); 3815864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org VisitForAccumulatorValue(args->at(0)); 3816864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3817864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ AssertString(eax); 3818864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3819864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(eax, FieldOperand(eax, String::kHashFieldOffset)); 3820864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ IndexFromHash(eax, eax); 3821864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3822864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org context()->Plug(eax); 3823864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 3824864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3825864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3826b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.orgvoid FullCodeGenerator::EmitFastOneByteArrayJoin(CallRuntime* expr) { 3827864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label bailout, done, one_char_separator, long_separator, 3828864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org non_trivial_array, not_size_one_array, loop, 3829864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org loop_1, loop_1_condition, loop_2, loop_2_entry, loop_3, loop_3_entry; 3830864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3831864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ZoneList<Expression*>* args = expr->arguments(); 3832e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(args->length() == 2); 3833864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // We will leave the separator on the stack until the end of the function. 3834864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org VisitForStackValue(args->at(1)); 3835864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Load this to eax (= array) 3836864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org VisitForAccumulatorValue(args->at(0)); 3837864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // All aliases of the same register have disjoint lifetimes. 3838864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register array = eax; 3839864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register elements = no_reg; // Will be eax. 3840864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3841864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register index = edx; 3842864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3843864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register string_length = ecx; 3844864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3845864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register string = esi; 3846864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3847864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register scratch = ebx; 3848864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3849864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register array_length = edi; 3850864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register result_pos = no_reg; // Will be edi. 3851864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3852864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Separator operand is already pushed. 3853864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Operand separator_operand = Operand(esp, 2 * kPointerSize); 3854864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Operand result_operand = Operand(esp, 1 * kPointerSize); 3855864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Operand array_length_operand = Operand(esp, 0); 3856864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ sub(esp, Immediate(2 * kPointerSize)); 3857864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ cld(); 3858864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Check that the array is a JSArray 3859864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ JumpIfSmi(array, &bailout); 3860864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ CmpObjectType(array, JS_ARRAY_TYPE, scratch); 3861864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(not_equal, &bailout); 3862864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3863864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Check that the array has fast elements. 3864864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ CheckFastElements(scratch, &bailout); 3865864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3866864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // If the array has length zero, return the empty string. 3867864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(array_length, FieldOperand(array, JSArray::kLengthOffset)); 3868864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ SmiUntag(array_length); 3869864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(not_zero, &non_trivial_array); 3870864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(result_operand, isolate()->factory()->empty_string()); 3871864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ jmp(&done); 3872864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3873864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Save the array length. 3874864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&non_trivial_array); 3875864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(array_length_operand, array_length); 3876864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3877864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Save the FixedArray containing array's elements. 3878864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // End of array's live range. 3879864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org elements = array; 3880864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(elements, FieldOperand(array, JSArray::kElementsOffset)); 3881864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org array = no_reg; 3882864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3883864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3884b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org // Check that all array elements are sequential one-byte strings, and 3885864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // accumulate the sum of their lengths, as a smi-encoded value. 3886864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ Move(index, Immediate(0)); 3887864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ Move(string_length, Immediate(0)); 3888864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Loop condition: while (index < length). 3889864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Live loop registers: index, array_length, string, 3890864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // scratch, string_length, elements. 3891864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (generate_debug_code_) { 3892864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ cmp(index, array_length); 3893b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org __ Assert(less, kNoEmptyArraysHereInEmitFastOneByteArrayJoin); 3894864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 3895864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&loop); 3896864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(string, FieldOperand(elements, 3897864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org index, 3898864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org times_pointer_size, 3899864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org FixedArray::kHeaderSize)); 3900864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ JumpIfSmi(string, &bailout); 3901864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(scratch, FieldOperand(string, HeapObject::kMapOffset)); 3902864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ movzx_b(scratch, FieldOperand(scratch, Map::kInstanceTypeOffset)); 3903864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ and_(scratch, Immediate( 3904864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org kIsNotStringMask | kStringEncodingMask | kStringRepresentationMask)); 3905864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ cmp(scratch, kStringTag | kOneByteStringTag | kSeqStringTag); 3906864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(not_equal, &bailout); 3907864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ add(string_length, 3908864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org FieldOperand(string, SeqOneByteString::kLengthOffset)); 3909864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(overflow, &bailout); 3910864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ add(index, Immediate(1)); 3911864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ cmp(index, array_length); 3912864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(less, &loop); 3913864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3914864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // If array_length is 1, return elements[0], a string. 3915864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ cmp(array_length, 1); 3916864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(not_equal, ¬_size_one_array); 3917864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(scratch, FieldOperand(elements, FixedArray::kHeaderSize)); 3918864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(result_operand, scratch); 3919864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ jmp(&done); 3920864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3921864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(¬_size_one_array); 3922864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3923864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // End of array_length live range. 3924864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org result_pos = array_length; 3925864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org array_length = no_reg; 3926864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3927864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Live registers: 3928864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // string_length: Sum of string lengths, as a smi. 3929864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // elements: FixedArray of strings. 3930864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3931b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org // Check that the separator is a flat one-byte string. 3932864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(string, separator_operand); 3933864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ JumpIfSmi(string, &bailout); 3934864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(scratch, FieldOperand(string, HeapObject::kMapOffset)); 3935864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ movzx_b(scratch, FieldOperand(scratch, Map::kInstanceTypeOffset)); 3936864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ and_(scratch, Immediate( 3937864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org kIsNotStringMask | kStringEncodingMask | kStringRepresentationMask)); 3938864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ cmp(scratch, kStringTag | kOneByteStringTag | kSeqStringTag); 3939864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(not_equal, &bailout); 3940864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3941864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Add (separator length times array_length) - separator length 3942864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // to string_length. 3943864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(scratch, separator_operand); 3944864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(scratch, FieldOperand(scratch, SeqOneByteString::kLengthOffset)); 3945864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ sub(string_length, scratch); // May be negative, temporarily. 3946864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ imul(scratch, array_length_operand); 3947864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(overflow, &bailout); 3948864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ add(string_length, scratch); 3949864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(overflow, &bailout); 3950864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3951864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ shr(string_length, 1); 3952864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Live registers and stack values: 3953864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // string_length 3954864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // elements 3955b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org __ AllocateOneByteString(result_pos, string_length, scratch, index, string, 3956b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org &bailout); 3957864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(result_operand, result_pos); 3958864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ lea(result_pos, FieldOperand(result_pos, SeqOneByteString::kHeaderSize)); 3959864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3960864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3961864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(string, separator_operand); 3962864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ cmp(FieldOperand(string, SeqOneByteString::kLengthOffset), 3963864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Immediate(Smi::FromInt(1))); 3964864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(equal, &one_char_separator); 3965864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(greater, &long_separator); 3966864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3967864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3968864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Empty separator case 3969864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(index, Immediate(0)); 3970864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ jmp(&loop_1_condition); 3971864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Loop condition: while (index < length). 3972864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&loop_1); 3973864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Each iteration of the loop concatenates one string to the result. 3974864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Live values in registers: 3975864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // index: which element of the elements array we are adding to the result. 3976864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // result_pos: the position to which we are currently copying characters. 3977864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // elements: the FixedArray of strings we are joining. 3978864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3979864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Get string = array[index]. 3980864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(string, FieldOperand(elements, index, 3981864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org times_pointer_size, 3982864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org FixedArray::kHeaderSize)); 3983864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(string_length, 3984864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org FieldOperand(string, String::kLengthOffset)); 3985864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ shr(string_length, 1); 3986864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ lea(string, 3987864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org FieldOperand(string, SeqOneByteString::kHeaderSize)); 3988864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ CopyBytes(string, result_pos, string_length, scratch); 3989864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ add(index, Immediate(1)); 3990864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&loop_1_condition); 3991864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ cmp(index, array_length_operand); 3992864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(less, &loop_1); // End while (index < length). 3993864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ jmp(&done); 3994864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3995864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3996864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3997864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // One-character separator case 3998864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&one_char_separator); 3999b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org // Replace separator with its one-byte character value. 4000864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov_b(scratch, FieldOperand(string, SeqOneByteString::kHeaderSize)); 4001864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov_b(separator_operand, scratch); 4002864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4003864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ Move(index, Immediate(0)); 4004864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Jump into the loop after the code that copies the separator, so the first 4005864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // element is not preceded by a separator 4006864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ jmp(&loop_2_entry); 4007864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Loop condition: while (index < length). 4008864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&loop_2); 4009864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Each iteration of the loop concatenates one string to the result. 4010864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Live values in registers: 4011864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // index: which element of the elements array we are adding to the result. 4012864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // result_pos: the position to which we are currently copying characters. 4013864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4014864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Copy the separator character to the result. 4015864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov_b(scratch, separator_operand); 4016864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov_b(Operand(result_pos, 0), scratch); 4017864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ inc(result_pos); 4018864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4019864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&loop_2_entry); 4020864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Get string = array[index]. 4021864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(string, FieldOperand(elements, index, 4022864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org times_pointer_size, 4023864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org FixedArray::kHeaderSize)); 4024864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(string_length, 4025864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org FieldOperand(string, String::kLengthOffset)); 4026864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ shr(string_length, 1); 4027864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ lea(string, 4028864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org FieldOperand(string, SeqOneByteString::kHeaderSize)); 4029864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ CopyBytes(string, result_pos, string_length, scratch); 4030864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ add(index, Immediate(1)); 4031864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4032864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ cmp(index, array_length_operand); 4033864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(less, &loop_2); // End while (index < length). 4034864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ jmp(&done); 4035864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4036864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4037864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Long separator case (separator is more than one character). 4038864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&long_separator); 4039864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4040864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ Move(index, Immediate(0)); 4041864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Jump into the loop after the code that copies the separator, so the first 4042864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // element is not preceded by a separator 4043864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ jmp(&loop_3_entry); 4044864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Loop condition: while (index < length). 4045864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&loop_3); 4046864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Each iteration of the loop concatenates one string to the result. 4047864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Live values in registers: 4048864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // index: which element of the elements array we are adding to the result. 4049864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // result_pos: the position to which we are currently copying characters. 4050864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4051864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Copy the separator to the result. 4052864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(string, separator_operand); 4053864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(string_length, 4054864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org FieldOperand(string, String::kLengthOffset)); 4055864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ shr(string_length, 1); 4056864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ lea(string, 4057864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org FieldOperand(string, SeqOneByteString::kHeaderSize)); 4058864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ CopyBytes(string, result_pos, string_length, scratch); 4059864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4060864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&loop_3_entry); 4061864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Get string = array[index]. 4062864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(string, FieldOperand(elements, index, 4063864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org times_pointer_size, 4064864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org FixedArray::kHeaderSize)); 4065864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(string_length, 4066864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org FieldOperand(string, String::kLengthOffset)); 4067864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ shr(string_length, 1); 4068864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ lea(string, 4069864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org FieldOperand(string, SeqOneByteString::kHeaderSize)); 4070864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ CopyBytes(string, result_pos, string_length, scratch); 4071864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ add(index, Immediate(1)); 4072864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4073864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ cmp(index, array_length_operand); 4074864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(less, &loop_3); // End while (index < length). 4075864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ jmp(&done); 4076864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4077864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4078864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&bailout); 4079864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(result_operand, isolate()->factory()->undefined_value()); 4080864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&done); 4081864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(eax, result_operand); 4082864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Drop temp values from the stack, and restore context register. 4083864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ add(esp, Immediate(3 * kPointerSize)); 4084864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4085864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); 4086864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org context()->Plug(eax); 4087864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 4088864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4089864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4090975b940441085887fc02bebf8877d5ec97e1e06cmachenbach@chromium.orgvoid FullCodeGenerator::EmitDebugIsActive(CallRuntime* expr) { 4091e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(expr->arguments()->length() == 0); 4092975b940441085887fc02bebf8877d5ec97e1e06cmachenbach@chromium.org ExternalReference debug_is_active = 4093975b940441085887fc02bebf8877d5ec97e1e06cmachenbach@chromium.org ExternalReference::debug_is_active_address(isolate()); 4094975b940441085887fc02bebf8877d5ec97e1e06cmachenbach@chromium.org __ movzx_b(eax, Operand::StaticVariable(debug_is_active)); 4095975b940441085887fc02bebf8877d5ec97e1e06cmachenbach@chromium.org __ SmiTag(eax); 4096975b940441085887fc02bebf8877d5ec97e1e06cmachenbach@chromium.org context()->Plug(eax); 4097975b940441085887fc02bebf8877d5ec97e1e06cmachenbach@chromium.org} 4098975b940441085887fc02bebf8877d5ec97e1e06cmachenbach@chromium.org 4099975b940441085887fc02bebf8877d5ec97e1e06cmachenbach@chromium.org 4100864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) { 4101864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (expr->function() != NULL && 4102864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org expr->function()->intrinsic_type == Runtime::INLINE) { 4103864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Comment cmnt(masm_, "[ InlineRuntimeCall"); 4104864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org EmitInlineRuntimeCall(expr); 4105864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return; 4106864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 4107864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4108864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Comment cmnt(masm_, "[ CallRuntime"); 4109864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ZoneList<Expression*>* args = expr->arguments(); 4110864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4111864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (expr->is_jsruntime()) { 4112864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Push the builtins object as receiver. 4113864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(eax, GlobalObjectOperand()); 4114864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(FieldOperand(eax, GlobalObject::kBuiltinsOffset)); 4115864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4116864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Load the function from the receiver. 411742ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org __ mov(LoadDescriptor::ReceiverRegister(), Operand(esp, 0)); 411842ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org __ mov(LoadDescriptor::NameRegister(), Immediate(expr->name())); 41197c0666e15d1f68f0fef5db9e5c409fab010ed816machenbach@chromium.org if (FLAG_vector_ics) { 412042ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org __ mov(VectorLoadICDescriptor::SlotRegister(), 41217c0666e15d1f68f0fef5db9e5c409fab010ed816machenbach@chromium.org Immediate(Smi::FromInt(expr->CallRuntimeFeedbackSlot()))); 41227c0666e15d1f68f0fef5db9e5c409fab010ed816machenbach@chromium.org CallLoadIC(NOT_CONTEXTUAL); 41237c0666e15d1f68f0fef5db9e5c409fab010ed816machenbach@chromium.org } else { 41247c0666e15d1f68f0fef5db9e5c409fab010ed816machenbach@chromium.org CallLoadIC(NOT_CONTEXTUAL, expr->CallRuntimeFeedbackId()); 41257c0666e15d1f68f0fef5db9e5c409fab010ed816machenbach@chromium.org } 4126864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4127864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Push the target function under the receiver. 4128864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(Operand(esp, 0)); 4129864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(Operand(esp, kPointerSize), eax); 4130864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4131864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Code common for calls using the IC. 4132864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ZoneList<Expression*>* args = expr->arguments(); 4133864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int arg_count = args->length(); 4134864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org for (int i = 0; i < arg_count; i++) { 4135864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org VisitForStackValue(args->at(i)); 4136864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 4137864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4138864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Record source position of the IC call. 4139864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org SetSourcePosition(expr->position()); 4140864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org CallFunctionStub stub(isolate(), arg_count, NO_CALL_FUNCTION_FLAGS); 4141864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(edi, Operand(esp, (arg_count + 1) * kPointerSize)); 4142864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ CallStub(&stub); 4143864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Restore context register. 4144864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); 4145864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org context()->DropAndPlug(1, eax); 4146864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4147864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 4148864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Push the arguments ("left-to-right"). 4149864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int arg_count = args->length(); 4150864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org for (int i = 0; i < arg_count; i++) { 4151864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org VisitForStackValue(args->at(i)); 4152864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 4153864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4154864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Call the C runtime function. 4155864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ CallRuntime(expr->function(), arg_count); 4156864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4157864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org context()->Plug(eax); 4158864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 4159864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 4160864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4161864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4162864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) { 4163864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org switch (expr->op()) { 4164864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case Token::DELETE: { 4165864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Comment cmnt(masm_, "[ UnaryOperation (DELETE)"); 4166864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Property* property = expr->expression()->AsProperty(); 4167864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org VariableProxy* proxy = expr->expression()->AsVariableProxy(); 4168864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4169864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (property != NULL) { 4170864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org VisitForStackValue(property->obj()); 4171864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org VisitForStackValue(property->key()); 4172864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(Immediate(Smi::FromInt(strict_mode()))); 4173864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION); 4174864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org context()->Plug(eax); 4175864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else if (proxy != NULL) { 4176864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Variable* var = proxy->var(); 4177864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Delete of an unqualified identifier is disallowed in strict mode 4178864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // but "delete this" is allowed. 4179e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(strict_mode() == SLOPPY || var->is_this()); 4180864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (var->IsUnallocated()) { 4181864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(GlobalObjectOperand()); 4182864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(Immediate(var->name())); 4183864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(Immediate(Smi::FromInt(SLOPPY))); 4184864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION); 4185864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org context()->Plug(eax); 4186864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else if (var->IsStackAllocated() || var->IsContextSlot()) { 4187864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Result of deleting non-global variables is false. 'this' is 4188864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // not really a variable, though we implement it as one. The 4189864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // subexpression does not have side effects. 4190864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org context()->Plug(var->is_this()); 4191864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 4192864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Non-global variable. Call the runtime to try to delete from the 4193864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // context where the variable was introduced. 4194864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(context_register()); 4195864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(Immediate(var->name())); 41964c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org __ CallRuntime(Runtime::kDeleteLookupSlot, 2); 4197864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org context()->Plug(eax); 4198864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 4199864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 4200864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Result of deleting non-property, non-variable reference is true. 4201864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // The subexpression may have side effects. 4202864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org VisitForEffect(expr->expression()); 4203864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org context()->Plug(true); 4204864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 4205864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org break; 4206864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 4207864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4208864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case Token::VOID: { 4209864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Comment cmnt(masm_, "[ UnaryOperation (VOID)"); 4210864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org VisitForEffect(expr->expression()); 4211864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org context()->Plug(isolate()->factory()->undefined_value()); 4212864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org break; 4213864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 4214864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4215864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case Token::NOT: { 4216864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Comment cmnt(masm_, "[ UnaryOperation (NOT)"); 4217864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (context()->IsEffect()) { 4218864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Unary NOT has no side effects so it's only necessary to visit the 4219864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // subexpression. Match the optimizing compiler by not branching. 4220864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org VisitForEffect(expr->expression()); 4221864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else if (context()->IsTest()) { 4222864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org const TestContext* test = TestContext::cast(context()); 4223864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // The labels are swapped for the recursive call. 4224864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org VisitForControl(expr->expression(), 4225864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org test->false_label(), 4226864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org test->true_label(), 4227864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org test->fall_through()); 4228864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org context()->Plug(test->true_label(), test->false_label()); 4229864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 4230864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // We handle value contexts explicitly rather than simply visiting 4231864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // for control and plugging the control flow into the context, 4232864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // because we need to prepare a pair of extra administrative AST ids 4233864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // for the optimizing compiler. 4234e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(context()->IsAccumulatorValue() || context()->IsStackValue()); 4235864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label materialize_true, materialize_false, done; 4236864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org VisitForControl(expr->expression(), 4237864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org &materialize_false, 4238864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org &materialize_true, 4239864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org &materialize_true); 4240864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&materialize_true); 4241864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org PrepareForBailoutForId(expr->MaterializeTrueId(), NO_REGISTERS); 4242864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (context()->IsAccumulatorValue()) { 4243864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(eax, isolate()->factory()->true_value()); 4244864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 4245864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ Push(isolate()->factory()->true_value()); 4246864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 4247864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ jmp(&done, Label::kNear); 4248864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&materialize_false); 4249864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org PrepareForBailoutForId(expr->MaterializeFalseId(), NO_REGISTERS); 4250864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (context()->IsAccumulatorValue()) { 4251864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(eax, isolate()->factory()->false_value()); 4252864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 4253864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ Push(isolate()->factory()->false_value()); 4254864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 4255864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&done); 4256864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 4257864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org break; 4258864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 4259864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4260864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case Token::TYPEOF: { 4261864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Comment cmnt(masm_, "[ UnaryOperation (TYPEOF)"); 4262864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org { StackValueContext context(this); 4263864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org VisitForTypeofValue(expr->expression()); 4264864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 4265864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ CallRuntime(Runtime::kTypeof, 1); 4266864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org context()->Plug(eax); 4267864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org break; 4268864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 4269864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4270864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org default: 4271864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org UNREACHABLE(); 4272864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 4273864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 4274864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4275864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4276864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid FullCodeGenerator::VisitCountOperation(CountOperation* expr) { 4277e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(expr->expression()->IsValidReferenceExpression()); 4278864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4279864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Comment cmnt(masm_, "[ CountOperation"); 4280864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org SetSourcePosition(expr->position()); 4281864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4282864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Expression can only be a property, a global or a (parameter or local) 4283864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // slot. 4284864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org enum LhsKind { VARIABLE, NAMED_PROPERTY, KEYED_PROPERTY }; 4285864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org LhsKind assign_type = VARIABLE; 4286864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Property* prop = expr->expression()->AsProperty(); 4287864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // In case of a property we use the uninitialized expression context 4288864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // of the key to detect a named property. 4289864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (prop != NULL) { 4290864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org assign_type = 4291864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org (prop->key()->IsPropertyName()) ? NAMED_PROPERTY : KEYED_PROPERTY; 4292864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 4293864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4294864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Evaluate expression and get value. 4295864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (assign_type == VARIABLE) { 4296e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(expr->expression()->AsVariableProxy()->var() != NULL); 4297864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org AccumulatorValueContext context(this); 4298864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org EmitVariableLoad(expr->expression()->AsVariableProxy()); 4299864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 4300864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Reserve space for result of postfix operation. 4301864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (expr->is_postfix() && !context()->IsEffect()) { 4302864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(Immediate(Smi::FromInt(0))); 4303864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 4304864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (assign_type == NAMED_PROPERTY) { 430558a725587734a6889c689668fd01f0157ed749a6machenbach@chromium.org // Put the object both on the stack and in the register. 430658a725587734a6889c689668fd01f0157ed749a6machenbach@chromium.org VisitForStackValue(prop->obj()); 430742ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org __ mov(LoadDescriptor::ReceiverRegister(), Operand(esp, 0)); 4308864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org EmitNamedPropertyLoad(prop); 4309864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 4310864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org VisitForStackValue(prop->obj()); 4311864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org VisitForStackValue(prop->key()); 431242ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org __ mov(LoadDescriptor::ReceiverRegister(), 43137b6dc58d68c4315b99f5ec3faf6927db3d0db913machenbach@chromium.org Operand(esp, kPointerSize)); // Object. 431442ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org __ mov(LoadDescriptor::NameRegister(), Operand(esp, 0)); // Key. 4315864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org EmitKeyedPropertyLoad(prop); 4316864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 4317864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 4318864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4319864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // We need a second deoptimization point after loading the value 4320864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // in case evaluating the property load my have a side effect. 4321864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (assign_type == VARIABLE) { 4322864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org PrepareForBailout(expr->expression(), TOS_REG); 4323864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 4324864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org PrepareForBailoutForId(prop->LoadId(), TOS_REG); 4325864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 4326864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4327864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Inline smi case if we are in a loop. 4328864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label done, stub_call; 4329864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org JumpPatchSite patch_site(masm_); 4330864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (ShouldInlineSmiCase(expr->op())) { 4331864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label slow; 4332864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org patch_site.EmitJumpIfNotSmi(eax, &slow, Label::kNear); 4333864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4334864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Save result for postfix expressions. 4335864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (expr->is_postfix()) { 4336864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (!context()->IsEffect()) { 4337864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Save the result on the stack. If we have a named or keyed property 4338864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // we store the result under the receiver that is currently on top 4339864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // of the stack. 4340864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org switch (assign_type) { 4341864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case VARIABLE: 4342864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(eax); 4343864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org break; 4344864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case NAMED_PROPERTY: 4345864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(Operand(esp, kPointerSize), eax); 4346864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org break; 4347864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case KEYED_PROPERTY: 4348864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(Operand(esp, 2 * kPointerSize), eax); 4349864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org break; 4350864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 4351864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 4352864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 4353864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4354864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (expr->op() == Token::INC) { 4355864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ add(eax, Immediate(Smi::FromInt(1))); 4356864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 4357864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ sub(eax, Immediate(Smi::FromInt(1))); 4358864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 4359864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(no_overflow, &done, Label::kNear); 4360864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Call stub. Undo operation first. 4361864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (expr->op() == Token::INC) { 4362864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ sub(eax, Immediate(Smi::FromInt(1))); 4363864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 4364864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ add(eax, Immediate(Smi::FromInt(1))); 4365864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 4366864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ jmp(&stub_call, Label::kNear); 4367864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&slow); 4368864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 4369864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ToNumberStub convert_stub(isolate()); 4370864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ CallStub(&convert_stub); 4371864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4372864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Save result for postfix expressions. 4373864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (expr->is_postfix()) { 4374864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (!context()->IsEffect()) { 4375864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Save the result on the stack. If we have a named or keyed property 4376864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // we store the result under the receiver that is currently on top 4377864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // of the stack. 4378864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org switch (assign_type) { 4379864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case VARIABLE: 4380864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(eax); 4381864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org break; 4382864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case NAMED_PROPERTY: 4383864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(Operand(esp, kPointerSize), eax); 4384864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org break; 4385864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case KEYED_PROPERTY: 4386864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(Operand(esp, 2 * kPointerSize), eax); 4387864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org break; 4388864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 4389864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 4390864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 4391864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4392864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Record position before stub call. 4393864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org SetSourcePosition(expr->position()); 4394864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4395864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Call stub for +1/-1. 4396864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&stub_call); 4397864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(edx, eax); 4398864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(eax, Immediate(Smi::FromInt(1))); 4399b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), expr->binary_op(), 4400b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org NO_OVERWRITE).code(); 4401b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org CallIC(code, expr->CountBinOpFeedbackId()); 4402864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org patch_site.EmitPatchInfo(); 4403864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&done); 4404864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4405864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Store the value returned in eax. 4406864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org switch (assign_type) { 4407864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case VARIABLE: 4408864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (expr->is_postfix()) { 4409864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Perform the assignment as if via '='. 4410864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org { EffectContext context(this); 4411864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), 4412864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Token::ASSIGN); 4413864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 4414864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org context.Plug(eax); 4415864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 4416864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // For all contexts except EffectContext We have the result on 4417864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // top of the stack. 4418864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (!context()->IsEffect()) { 4419864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org context()->PlugTOS(); 4420864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 4421864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 4422864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Perform the assignment as if via '='. 4423864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), 4424864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Token::ASSIGN); 4425864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 4426864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org context()->Plug(eax); 4427864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 4428864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org break; 4429864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case NAMED_PROPERTY: { 443042ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org __ mov(StoreDescriptor::NameRegister(), 44317b6dc58d68c4315b99f5ec3faf6927db3d0db913machenbach@chromium.org prop->key()->AsLiteral()->value()); 443242ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org __ pop(StoreDescriptor::ReceiverRegister()); 4433864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org CallStoreIC(expr->CountStoreFeedbackId()); 4434864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 4435864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (expr->is_postfix()) { 4436864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (!context()->IsEffect()) { 4437864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org context()->PlugTOS(); 4438864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 4439864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 4440864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org context()->Plug(eax); 4441864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 4442864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org break; 4443864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 4444864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case KEYED_PROPERTY: { 444542ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org __ pop(StoreDescriptor::NameRegister()); 444642ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org __ pop(StoreDescriptor::ReceiverRegister()); 4447b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org Handle<Code> ic = 4448b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org CodeFactory::KeyedStoreIC(isolate(), strict_mode()).code(); 4449864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org CallIC(ic, expr->CountStoreFeedbackId()); 4450864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 4451864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (expr->is_postfix()) { 4452864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Result is on the stack 4453864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (!context()->IsEffect()) { 4454864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org context()->PlugTOS(); 4455864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 4456864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 4457864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org context()->Plug(eax); 4458864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 4459864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org break; 4460864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 4461864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 4462864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 4463864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4464864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4465864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid FullCodeGenerator::VisitForTypeofValue(Expression* expr) { 4466864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org VariableProxy* proxy = expr->AsVariableProxy(); 4467e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!context()->IsEffect()); 4468e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!context()->IsTest()); 4469864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4470864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (proxy != NULL && proxy->var()->IsUnallocated()) { 4471864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Comment cmnt(masm_, "[ Global variable"); 447242ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org __ mov(LoadDescriptor::ReceiverRegister(), GlobalObjectOperand()); 447342ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org __ mov(LoadDescriptor::NameRegister(), Immediate(proxy->name())); 44747c0666e15d1f68f0fef5db9e5c409fab010ed816machenbach@chromium.org if (FLAG_vector_ics) { 447542ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org __ mov(VectorLoadICDescriptor::SlotRegister(), 44767c0666e15d1f68f0fef5db9e5c409fab010ed816machenbach@chromium.org Immediate(Smi::FromInt(proxy->VariableFeedbackSlot()))); 44777c0666e15d1f68f0fef5db9e5c409fab010ed816machenbach@chromium.org } 4478864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Use a regular load, not a contextual load, to avoid a reference 4479864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // error. 4480864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org CallLoadIC(NOT_CONTEXTUAL); 4481864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org PrepareForBailout(expr, TOS_REG); 4482864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org context()->Plug(eax); 4483864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else if (proxy != NULL && proxy->var()->IsLookupSlot()) { 4484864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Comment cmnt(masm_, "[ Lookup slot"); 4485864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label done, slow; 4486864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4487864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Generate code for loading from variables potentially shadowed 4488864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // by eval-introduced variables. 44897c0666e15d1f68f0fef5db9e5c409fab010ed816machenbach@chromium.org EmitDynamicLookupFastCase(proxy, INSIDE_TYPEOF, &slow, &done); 4490864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4491864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&slow); 4492864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(esi); 4493864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(Immediate(proxy->name())); 44944c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org __ CallRuntime(Runtime::kLoadLookupSlotNoReferenceError, 2); 4495864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org PrepareForBailout(expr, TOS_REG); 4496864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&done); 4497864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4498864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org context()->Plug(eax); 4499864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 4500864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // This expression cannot throw a reference error at the top level. 4501864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org VisitInDuplicateContext(expr); 4502864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 4503864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 4504864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4505864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4506864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid FullCodeGenerator::EmitLiteralCompareTypeof(Expression* expr, 4507864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Expression* sub_expr, 4508864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Handle<String> check) { 4509864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label materialize_true, materialize_false; 4510864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label* if_true = NULL; 4511864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label* if_false = NULL; 4512864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label* fall_through = NULL; 4513864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org context()->PrepareTest(&materialize_true, &materialize_false, 4514864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org &if_true, &if_false, &fall_through); 4515864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4516864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org { AccumulatorValueContext context(this); 4517864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org VisitForTypeofValue(sub_expr); 4518864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 4519864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); 4520864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4521864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Factory* factory = isolate()->factory(); 4522864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (String::Equals(check, factory->number_string())) { 4523864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ JumpIfSmi(eax, if_true); 4524864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ cmp(FieldOperand(eax, HeapObject::kMapOffset), 4525864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org isolate()->factory()->heap_number_map()); 4526864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Split(equal, if_true, if_false, fall_through); 4527864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else if (String::Equals(check, factory->string_string())) { 4528864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ JumpIfSmi(eax, if_false); 4529864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ CmpObjectType(eax, FIRST_NONSTRING_TYPE, edx); 4530864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(above_equal, if_false); 4531864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Check for undetectable objects => false. 4532864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ test_b(FieldOperand(edx, Map::kBitFieldOffset), 4533864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1 << Map::kIsUndetectable); 4534864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Split(zero, if_true, if_false, fall_through); 4535864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else if (String::Equals(check, factory->symbol_string())) { 4536864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ JumpIfSmi(eax, if_false); 4537864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ CmpObjectType(eax, SYMBOL_TYPE, edx); 4538864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Split(equal, if_true, if_false, fall_through); 4539864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else if (String::Equals(check, factory->boolean_string())) { 4540864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ cmp(eax, isolate()->factory()->true_value()); 4541864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(equal, if_true); 4542864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ cmp(eax, isolate()->factory()->false_value()); 4543864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Split(equal, if_true, if_false, fall_through); 4544864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else if (String::Equals(check, factory->undefined_string())) { 4545864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ cmp(eax, isolate()->factory()->undefined_value()); 4546864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(equal, if_true); 4547864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ JumpIfSmi(eax, if_false); 4548864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Check for undetectable objects => true. 4549864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(edx, FieldOperand(eax, HeapObject::kMapOffset)); 4550864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ movzx_b(ecx, FieldOperand(edx, Map::kBitFieldOffset)); 4551864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ test(ecx, Immediate(1 << Map::kIsUndetectable)); 4552864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Split(not_zero, if_true, if_false, fall_through); 4553864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else if (String::Equals(check, factory->function_string())) { 4554864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ JumpIfSmi(eax, if_false); 4555864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org STATIC_ASSERT(NUM_OF_CALLABLE_SPEC_OBJECT_TYPES == 2); 4556864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ CmpObjectType(eax, JS_FUNCTION_TYPE, edx); 4557864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(equal, if_true); 4558864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ CmpInstanceType(edx, JS_FUNCTION_PROXY_TYPE); 4559864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Split(equal, if_true, if_false, fall_through); 4560864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else if (String::Equals(check, factory->object_string())) { 4561864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ JumpIfSmi(eax, if_false); 45629d1a7a8cdb664730cf5703185e85a4716748c564machenbach@chromium.org __ cmp(eax, isolate()->factory()->null_value()); 45639d1a7a8cdb664730cf5703185e85a4716748c564machenbach@chromium.org __ j(equal, if_true); 4564864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ CmpObjectType(eax, FIRST_NONCALLABLE_SPEC_OBJECT_TYPE, edx); 4565864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(below, if_false); 4566864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ CmpInstanceType(edx, LAST_NONCALLABLE_SPEC_OBJECT_TYPE); 4567864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ j(above, if_false); 4568864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Check for undetectable objects => false. 4569864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ test_b(FieldOperand(edx, Map::kBitFieldOffset), 4570864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 1 << Map::kIsUndetectable); 4571864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Split(zero, if_true, if_false, fall_through); 4572864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 4573864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (if_false != fall_through) __ jmp(if_false); 4574864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 4575864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org context()->Plug(if_true, if_false); 4576864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 4577864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4578864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4579864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid FullCodeGenerator::VisitCompareOperation(CompareOperation* expr) { 4580864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Comment cmnt(masm_, "[ CompareOperation"); 4581864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org SetSourcePosition(expr->position()); 4582864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4583864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // First we try a fast inlined version of the compare when one of 4584864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // the operands is a literal. 4585864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (TryLiteralCompare(expr)) return; 4586864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4587864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Always perform the comparison for its control flow. Pack the result 4588864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // into the expression's context after the comparison is performed. 4589864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label materialize_true, materialize_false; 4590864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label* if_true = NULL; 4591864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label* if_false = NULL; 4592864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label* fall_through = NULL; 4593864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org context()->PrepareTest(&materialize_true, &materialize_false, 4594864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org &if_true, &if_false, &fall_through); 4595864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4596864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Token::Value op = expr->op(); 4597864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org VisitForStackValue(expr->left()); 4598864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org switch (op) { 4599864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case Token::IN: 4600864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org VisitForStackValue(expr->right()); 4601864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ InvokeBuiltin(Builtins::IN, CALL_FUNCTION); 4602864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org PrepareForBailoutBeforeSplit(expr, false, NULL, NULL); 4603864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ cmp(eax, isolate()->factory()->true_value()); 4604864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Split(equal, if_true, if_false, fall_through); 4605864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org break; 4606864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4607864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case Token::INSTANCEOF: { 4608864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org VisitForStackValue(expr->right()); 4609864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org InstanceofStub stub(isolate(), InstanceofStub::kNoFlags); 4610864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ CallStub(&stub); 4611864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); 4612864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ test(eax, eax); 4613864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // The stub returns 0 for true. 4614864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Split(zero, if_true, if_false, fall_through); 4615864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org break; 4616864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 4617864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4618864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org default: { 4619864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org VisitForAccumulatorValue(expr->right()); 4620864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Condition cc = CompareIC::ComputeCondition(op); 4621864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ pop(edx); 4622864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4623864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org bool inline_smi_code = ShouldInlineSmiCase(op); 4624864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org JumpPatchSite patch_site(masm_); 4625864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (inline_smi_code) { 4626864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label slow_case; 4627864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(ecx, edx); 4628864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ or_(ecx, eax); 4629864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org patch_site.EmitJumpIfNotSmi(ecx, &slow_case, Label::kNear); 4630864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ cmp(edx, eax); 4631864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Split(cc, if_true, if_false, NULL); 4632864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&slow_case); 4633864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 4634864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4635864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Record position and call the compare IC. 4636864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org SetSourcePosition(expr->position()); 4637b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org Handle<Code> ic = CodeFactory::CompareIC(isolate(), op).code(); 4638864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org CallIC(ic, expr->CompareOperationFeedbackId()); 4639864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org patch_site.EmitPatchInfo(); 4640864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4641864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); 4642864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ test(eax, eax); 4643864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Split(cc, if_true, if_false, fall_through); 4644864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 4645864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 4646864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4647864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Convert the result of the comparison into one expected for this 4648864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // expression's context. 4649864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org context()->Plug(if_true, if_false); 4650864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 4651864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4652864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4653864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid FullCodeGenerator::EmitLiteralCompareNil(CompareOperation* expr, 4654864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Expression* sub_expr, 4655864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org NilValue nil) { 4656864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label materialize_true, materialize_false; 4657864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label* if_true = NULL; 4658864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label* if_false = NULL; 4659864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label* fall_through = NULL; 4660864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org context()->PrepareTest(&materialize_true, &materialize_false, 4661864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org &if_true, &if_false, &fall_through); 4662864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4663864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org VisitForAccumulatorValue(sub_expr); 4664864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); 4665864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4666864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Handle<Object> nil_value = nil == kNullValue 4667864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ? isolate()->factory()->null_value() 4668864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org : isolate()->factory()->undefined_value(); 4669864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (expr->op() == Token::EQ_STRICT) { 4670864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ cmp(eax, nil_value); 4671864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Split(equal, if_true, if_false, fall_through); 4672864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 4673864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Handle<Code> ic = CompareNilICStub::GetUninitialized(isolate(), nil); 4674864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org CallIC(ic, expr->CompareOperationFeedbackId()); 4675864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ test(eax, eax); 4676864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Split(not_zero, if_true, if_false, fall_through); 4677864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 4678864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org context()->Plug(if_true, if_false); 4679864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 4680864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4681864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4682864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid FullCodeGenerator::VisitThisFunction(ThisFunction* expr) { 4683864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(eax, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset)); 4684864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org context()->Plug(eax); 4685864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 4686864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4687864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4688864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgRegister FullCodeGenerator::result_register() { 4689864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return eax; 4690864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 4691864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4692864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4693864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgRegister FullCodeGenerator::context_register() { 4694864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return esi; 4695864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 4696864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4697864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4698864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid FullCodeGenerator::StoreToFrameField(int frame_offset, Register value) { 4699e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK_EQ(POINTER_SIZE_ALIGN(frame_offset), frame_offset); 4700864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(Operand(ebp, frame_offset), value); 4701864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 4702864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4703864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4704864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid FullCodeGenerator::LoadContextField(Register dst, int context_index) { 4705864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(dst, ContextOperand(esi, context_index)); 4706864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 4707864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4708864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4709864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid FullCodeGenerator::PushFunctionArgumentForContextAllocation() { 4710864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Scope* declaration_scope = scope()->DeclarationScope(); 4711864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (declaration_scope->is_global_scope() || 4712864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org declaration_scope->is_module_scope()) { 4713864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Contexts nested in the native context have a canonical empty function 4714864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // as their closure, not the anonymous closure containing the global 4715864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // code. Pass a smi sentinel and let the runtime look up the empty 4716864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // function. 4717864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(Immediate(Smi::FromInt(0))); 4718864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else if (declaration_scope->is_eval_scope()) { 4719864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Contexts nested inside eval code have the same closure as the context 4720864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // calling eval, not the anonymous closure containing the eval code. 4721864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Fetch it from the context. 4722864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(ContextOperand(esi, Context::CLOSURE_INDEX)); 4723864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } else { 4724e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(declaration_scope->is_function_scope()); 4725864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(Operand(ebp, JavaScriptFrameConstants::kFunctionOffset)); 4726864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 4727864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 4728864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4729864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4730864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// ---------------------------------------------------------------------------- 4731864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// Non-local control flow support. 4732864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4733864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid FullCodeGenerator::EnterFinallyBlock() { 4734864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Cook return address on top of stack (smi encoded Code* delta) 4735e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!result_register().is(edx)); 4736864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ pop(edx); 4737864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ sub(edx, Immediate(masm_->CodeObject())); 4738864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org STATIC_ASSERT(kSmiTagSize + kSmiShiftSize == 1); 4739864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org STATIC_ASSERT(kSmiTag == 0); 4740864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ SmiTag(edx); 4741864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(edx); 4742864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4743864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Store result register while executing finally block. 4744864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(result_register()); 4745864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4746864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Store pending message while executing finally block. 4747864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ExternalReference pending_message_obj = 4748864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ExternalReference::address_of_pending_message_obj(isolate()); 4749864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(edx, Operand::StaticVariable(pending_message_obj)); 4750864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(edx); 4751864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4752864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ExternalReference has_pending_message = 4753864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ExternalReference::address_of_has_pending_message(isolate()); 4754864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(edx, Operand::StaticVariable(has_pending_message)); 4755864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ SmiTag(edx); 4756864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(edx); 4757864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4758864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ExternalReference pending_message_script = 4759864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ExternalReference::address_of_pending_message_script(isolate()); 4760864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(edx, Operand::StaticVariable(pending_message_script)); 4761864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(edx); 4762864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 4763864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4764864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4765864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid FullCodeGenerator::ExitFinallyBlock() { 4766e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!result_register().is(edx)); 4767864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Restore pending message from stack. 4768864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ pop(edx); 4769864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ExternalReference pending_message_script = 4770864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ExternalReference::address_of_pending_message_script(isolate()); 4771864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(Operand::StaticVariable(pending_message_script), edx); 4772864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4773864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ pop(edx); 4774864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ SmiUntag(edx); 4775864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ExternalReference has_pending_message = 4776864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ExternalReference::address_of_has_pending_message(isolate()); 4777864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(Operand::StaticVariable(has_pending_message), edx); 4778864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4779864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ pop(edx); 4780864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ExternalReference pending_message_obj = 4781864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ExternalReference::address_of_pending_message_obj(isolate()); 4782864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(Operand::StaticVariable(pending_message_obj), edx); 4783864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4784864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Restore result register from stack. 4785864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ pop(result_register()); 4786864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4787864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Uncook return address. 4788864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ pop(edx); 4789864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ SmiUntag(edx); 4790864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ add(edx, Immediate(masm_->CodeObject())); 4791864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ jmp(edx); 4792864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 4793864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4794864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4795864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org#undef __ 4796864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4797864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org#define __ ACCESS_MASM(masm()) 4798864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4799864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgFullCodeGenerator::NestedStatement* FullCodeGenerator::TryFinally::Exit( 4800864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int* stack_depth, 4801864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int* context_length) { 4802864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // The macros used here must preserve the result register. 4803864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4804864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Because the handler block contains the context of the finally 4805864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // code, we can restore it directly from there for the finally code 4806864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // rather than iteratively unwinding contexts via their previous 4807864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // links. 4808864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ Drop(*stack_depth); // Down to the handler block. 4809864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (*context_length > 0) { 4810864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Restore the context to its dedicated register and the stack. 4811864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(esi, Operand(esp, StackHandlerConstants::kContextOffset)); 4812864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(Operand(ebp, StandardFrameConstants::kContextOffset), esi); 4813864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 4814864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ PopTryHandler(); 4815864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ call(finally_entry_); 4816864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4817864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org *stack_depth = 0; 4818864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org *context_length = 0; 4819864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return previous_; 4820864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 4821864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4822864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org#undef __ 4823864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4824864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4825864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgstatic const byte kJnsInstruction = 0x79; 4826864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgstatic const byte kJnsOffset = 0x11; 4827864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgstatic const byte kNopByteOne = 0x66; 4828864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgstatic const byte kNopByteTwo = 0x90; 4829864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org#ifdef DEBUG 4830864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgstatic const byte kCallInstruction = 0xe8; 4831864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org#endif 4832864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4833864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4834864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid BackEdgeTable::PatchAt(Code* unoptimized_code, 4835864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Address pc, 4836864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org BackEdgeState target_state, 4837864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Code* replacement_code) { 4838864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Address call_target_address = pc - kIntSize; 4839864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Address jns_instr_address = call_target_address - 3; 4840864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Address jns_offset_address = call_target_address - 2; 4841864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4842864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org switch (target_state) { 4843864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case INTERRUPT: 4844864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // sub <profiling_counter>, <delta> ;; Not changed 4845864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // jns ok 4846864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // call <interrupt stub> 4847864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // ok: 4848864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org *jns_instr_address = kJnsInstruction; 4849864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org *jns_offset_address = kJnsOffset; 4850864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org break; 4851864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case ON_STACK_REPLACEMENT: 4852864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org case OSR_AFTER_STACK_CHECK: 4853864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // sub <profiling_counter>, <delta> ;; Not changed 4854864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // nop 4855864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // nop 4856864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // call <on-stack replacment> 4857864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // ok: 4858864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org *jns_instr_address = kNopByteOne; 4859864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org *jns_offset_address = kNopByteTwo; 4860864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org break; 4861864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 4862864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4863864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Assembler::set_target_address_at(call_target_address, 4864864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org unoptimized_code, 4865864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org replacement_code->entry()); 4866864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org unoptimized_code->GetHeap()->incremental_marking()->RecordCodeTargetPatch( 4867864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org unoptimized_code, call_target_address, replacement_code); 4868864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 4869864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4870864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4871864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgBackEdgeTable::BackEdgeState BackEdgeTable::GetBackEdgeState( 4872864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Isolate* isolate, 4873864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Code* unoptimized_code, 4874864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Address pc) { 4875864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Address call_target_address = pc - kIntSize; 4876864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Address jns_instr_address = call_target_address - 3; 4877e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK_EQ(kCallInstruction, *(call_target_address - 1)); 4878864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4879864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (*jns_instr_address == kJnsInstruction) { 4880e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK_EQ(kJnsOffset, *(call_target_address - 2)); 4881e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK_EQ(isolate->builtins()->InterruptCheck()->entry(), 4882864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Assembler::target_address_at(call_target_address, 4883864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org unoptimized_code)); 4884864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return INTERRUPT; 4885864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 4886864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4887e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK_EQ(kNopByteOne, *jns_instr_address); 4888e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK_EQ(kNopByteTwo, *(call_target_address - 2)); 4889864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4890864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (Assembler::target_address_at(call_target_address, unoptimized_code) == 4891864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org isolate->builtins()->OnStackReplacement()->entry()) { 4892864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return ON_STACK_REPLACEMENT; 4893864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 4894864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4895e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK_EQ(isolate->builtins()->OsrAfterStackCheck()->entry(), 4896864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Assembler::target_address_at(call_target_address, 4897864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org unoptimized_code)); 4898864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return OSR_AFTER_STACK_CHECK; 4899864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 4900864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4901864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4902864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} } // namespace v8::internal 4903864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 4904864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org#endif // V8_TARGET_ARCH_X87 4905