1ed844489b3f05bb6dc574eced606b865f3126bb
[WebKit-https.git] / JavaScriptCore / jit / JIT.cpp
1 /*
2  * Copyright (C) 2008 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
24  */
25
26 #include "config.h"
27 #include "JIT.h"
28
29 #if ENABLE(JIT)
30
31 #include "CodeBlock.h"
32 #include "JITInlineMethods.h"
33 #include "JSArray.h"
34 #include "JSFunction.h"
35 #include "Interpreter.h"
36 #include "ResultType.h"
37 #include "SamplingTool.h"
38
39 #ifndef NDEBUG
40 #include <stdio.h>
41 #endif
42
43 using namespace std;
44
45 namespace JSC {
46
47 COMPILE_ASSERT(CTI_ARGS_code == 0xC, CTI_ARGS_code_is_C);
48 COMPILE_ASSERT(CTI_ARGS_callFrame == 0xE, CTI_ARGS_callFrame_is_E);
49
50 #if COMPILER(GCC) && PLATFORM(X86)
51
52 #if PLATFORM(DARWIN)
53 #define SYMBOL_STRING(name) "_" #name
54 #else
55 #define SYMBOL_STRING(name) #name
56 #endif
57
58 asm(
59 ".globl " SYMBOL_STRING(ctiTrampoline) "\n"
60 SYMBOL_STRING(ctiTrampoline) ":" "\n"
61     "pushl %esi" "\n"
62     "pushl %edi" "\n"
63     "pushl %ebx" "\n"
64     "subl $0x20, %esp" "\n"
65     "movl $512, %esi" "\n"
66     "movl 0x38(%esp), %edi" "\n" // Ox38 = 0x0E * 4, 0x0E = CTI_ARGS_callFrame (see assertion above)
67     "call *0x30(%esp)" "\n" // Ox30 = 0x0C * 4, 0x0C = CTI_ARGS_code (see assertion above)
68     "addl $0x20, %esp" "\n"
69     "popl %ebx" "\n"
70     "popl %edi" "\n"
71     "popl %esi" "\n"
72     "ret" "\n"
73 );
74
75 asm(
76 ".globl " SYMBOL_STRING(ctiVMThrowTrampoline) "\n"
77 SYMBOL_STRING(ctiVMThrowTrampoline) ":" "\n"
78 #if USE(CTI_ARGUMENT)
79 #if USE(FAST_CALL_CTI_ARGUMENT)
80     "movl %esp, %ecx" "\n"
81 #else
82     "movl %esp, 0(%esp)" "\n"
83 #endif
84     "call " SYMBOL_STRING(_ZN3JSC11Interpreter12cti_vm_throwEPPv) "\n"
85 #else
86     "call " SYMBOL_STRING(_ZN3JSC11Interpreter12cti_vm_throwEPvz) "\n"
87 #endif
88     "addl $0x20, %esp" "\n"
89     "popl %ebx" "\n"
90     "popl %edi" "\n"
91     "popl %esi" "\n"
92     "ret" "\n"
93 );
94     
95 #elif COMPILER(MSVC)
96
97 extern "C" {
98     
99     __declspec(naked) JSValue* ctiTrampoline(void* code, RegisterFile*, CallFrame*, JSValue** exception, Profiler**, JSGlobalData*)
100     {
101         __asm {
102             push esi;
103             push edi;
104             push ebx;
105             sub esp, 0x20;
106             mov esi, 512;
107             mov ecx, esp;
108             mov edi, [esp + 0x38];
109             call [esp + 0x30]; // Ox30 = 0x0C * 4, 0x0C = CTI_ARGS_code (see assertion above)
110             add esp, 0x20;
111             pop ebx;
112             pop edi;
113             pop esi;
114             ret;
115         }
116     }
117     
118     __declspec(naked) void ctiVMThrowTrampoline()
119     {
120         __asm {
121             mov ecx, esp;
122             call JSC::Interpreter::cti_vm_throw;
123             add esp, 0x20;
124             pop ebx;
125             pop edi;
126             pop esi;
127             ret;
128         }
129     }
130     
131 }
132
133 #endif
134
135 void ctiSetReturnAddress(void** where, void* what)
136 {
137     *where = what;
138 }
139
140 void ctiRepatchCallByReturnAddress(void* where, void* what)
141 {
142     (static_cast<void**>(where))[-1] = reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(what) - reinterpret_cast<uintptr_t>(where));
143 }
144
145 #ifndef NDEBUG
146
147 void JIT::printBytecodeOperandTypes(unsigned src1, unsigned src2)
148 {
149     char which1 = '*';
150     if (m_codeBlock->isConstantRegisterIndex(src1)) {
151         JSValue* value = m_codeBlock->getConstant(src1);
152         which1 = 
153             JSImmediate::isImmediate(value) ?
154                 (JSImmediate::isNumber(value) ? 'i' :
155                 JSImmediate::isBoolean(value) ? 'b' :
156                 value->isUndefined() ? 'u' :
157                 value->isNull() ? 'n' : '?')
158                 :
159             (value->isString() ? 's' :
160             value->isObject() ? 'o' :
161             'k');
162     }
163     char which2 = '*';
164     if (m_codeBlock->isConstantRegisterIndex(src2)) {
165         JSValue* value = m_codeBlock->getConstant(src2);
166         which2 = 
167             JSImmediate::isImmediate(value) ?
168                 (JSImmediate::isNumber(value) ? 'i' :
169                 JSImmediate::isBoolean(value) ? 'b' :
170                 value->isUndefined() ? 'u' :
171                 value->isNull() ? 'n' : '?')
172                 :
173             (value->isString() ? 's' :
174             value->isObject() ? 'o' :
175             'k');
176     }
177     if ((which1 != '*') | (which2 != '*'))
178         fprintf(stderr, "Types %c %c\n", which1, which2);
179 }
180
181 #endif
182
183 JIT::JIT(JSGlobalData* globalData, CodeBlock* codeBlock)
184     : m_interpreter(globalData->interpreter)
185     , m_globalData(globalData)
186     , m_codeBlock(codeBlock)
187     , m_labels(codeBlock ? codeBlock->instructions().size() : 0)
188     , m_propertyAccessCompilationInfo(codeBlock ? codeBlock->numberOfPropertyAccessInstructions() : 0)
189     , m_callStructureStubCompilationInfo(codeBlock ? codeBlock->numberOfCallLinkInfos() : 0)
190     , m_lastResultBytecodeRegister(std::numeric_limits<int>::max())
191     , m_jumpTargetsPosition(0)
192 {
193 }
194
195 #define CTI_COMPILE_BINARY_OP(name) \
196     case name: { \
197         emitPutCTIArgFromVirtualRegister(instruction[i + 2].u.operand, 0, X86::ecx); \
198         emitPutCTIArgFromVirtualRegister(instruction[i + 3].u.operand, 4, X86::ecx); \
199         emitCTICall(i, Interpreter::cti_##name); \
200         emitPutVirtualRegister(instruction[i + 1].u.operand); \
201         i += 4; \
202         break; \
203     }
204
205 #define CTI_COMPILE_UNARY_OP(name) \
206     case name: { \
207         emitPutCTIArgFromVirtualRegister(instruction[i + 2].u.operand, 0, X86::ecx); \
208         emitCTICall(i, Interpreter::cti_##name); \
209         emitPutVirtualRegister(instruction[i + 1].u.operand); \
210         i += 3; \
211         break; \
212     }
213
214 void JIT::compileOpStrictEq(Instruction* instruction, unsigned i, CompileOpStrictEqType type)
215 {
216     bool negated = (type == OpNStrictEq);
217
218     unsigned dst = instruction[1].u.operand;
219     unsigned src1 = instruction[2].u.operand;
220     unsigned src2 = instruction[3].u.operand;
221
222     emitGetVirtualRegisters(src1, X86::eax, src2, X86::edx, i);
223
224     // Check that bot are immediates, if so check if they're equal
225     Jump firstNotImmediate = emitJumpIfJSCell(X86::eax);
226     Jump secondNotImmediate = emitJumpIfJSCell(X86::edx);
227     Jump bothWereImmediatesButNotEqual = jne32(X86::edx, X86::eax);
228
229     // They are equal - set the result to true. (Or false, if negated).
230     move(Imm32(asInteger(jsBoolean(!negated))), X86::eax);
231     Jump bothWereImmediatesAndEqual = jump();
232
233     // eax was not an immediate, we haven't yet checked edx.
234     // If edx is also a JSCell, or is 0, then jump to a slow case,
235     // otherwise these values are not equal.
236     firstNotImmediate.link(this);
237     emitJumpSlowCaseIfJSCell(X86::edx, i);
238     m_slowCases.append(SlowCaseEntry(je32(X86::edx, Imm32(asInteger(JSImmediate::zeroImmediate()))), i));
239     Jump firstWasNotImmediate = jump();
240
241     // eax was an immediate, but edx wasn't.
242     // If eax is 0 jump to a slow case, otherwise these values are not equal.
243     secondNotImmediate.link(this);
244     m_slowCases.append(SlowCaseEntry(je32(X86::eax, Imm32(asInteger(JSImmediate::zeroImmediate()))), i));
245
246     // We get here if the two values are different immediates, or one is 0 and the other is a JSCell.
247     // Vaelues are not equal, set the result to false.
248     bothWereImmediatesButNotEqual.link(this);
249     firstWasNotImmediate.link(this);
250     move(Imm32(asInteger(jsBoolean(negated))), X86::eax);
251     
252     bothWereImmediatesAndEqual.link(this);
253     emitPutVirtualRegister(dst);
254 }
255
256 void JIT::emitSlowScriptCheck(unsigned bytecodeIndex)
257 {
258     Jump skipTimeout = jnzSub32(Imm32(1), X86::esi);
259     emitCTICall(bytecodeIndex, Interpreter::cti_timeout_check);
260     move(X86::eax, X86::esi);
261     skipTimeout.link(this);
262
263     killLastResultRegister();
264 }
265
266 void JIT::privateCompileMainPass()
267 {
268     Instruction* instruction = m_codeBlock->instructions().begin();
269     unsigned instructionCount = m_codeBlock->instructions().size();
270
271     unsigned propertyAccessInstructionIndex = 0;
272     unsigned callLinkInfoIndex = 0;
273
274     for (unsigned i = 0; i < instructionCount; ) {
275         ASSERT_WITH_MESSAGE(m_interpreter->isOpcode(instruction[i].u.opcode), "privateCompileMainPass gone bad @ %d", i);
276
277 #if ENABLE(OPCODE_SAMPLING)
278         if (i > 0) // Avoid the overhead of sampling op_enter twice.
279             store32(m_interpreter->sampler()->encodeSample(instruction + i), m_interpreter->sampler()->sampleSlot());
280 #endif
281
282         m_labels[i] = __ label();
283         OpcodeID opcodeID = m_interpreter->getOpcodeID(instruction[i].u.opcode);
284         switch (opcodeID) {
285         case op_mov: {
286             emitGetVirtualRegister(instruction[i + 2].u.operand, X86::eax, i);
287             emitPutVirtualRegister(instruction[i + 1].u.operand);
288             i += OPCODE_LENGTH(op_mov);
289             break;
290         }
291         case op_add: {
292             unsigned dst = instruction[i + 1].u.operand;
293             unsigned src1 = instruction[i + 2].u.operand;
294             unsigned src2 = instruction[i + 3].u.operand;
295
296             if (JSValue* value = getConstantImmediateNumericArg(src1)) {
297                 emitGetVirtualRegister(src2, X86::eax, i);
298                 emitJumpSlowCaseIfNotImmNum(X86::eax, i);
299                 m_slowCases.append(SlowCaseEntry(joAdd32(Imm32(getDeTaggedConstantImmediate(value)), X86::eax), i));
300                 emitPutVirtualRegister(dst);
301             } else if (JSValue* value = getConstantImmediateNumericArg(src2)) {
302                 emitGetVirtualRegister(src1, X86::eax, i);
303                 emitJumpSlowCaseIfNotImmNum(X86::eax, i);
304                 m_slowCases.append(SlowCaseEntry(joAdd32(Imm32(getDeTaggedConstantImmediate(value)), X86::eax), i));
305                 emitPutVirtualRegister(dst);
306             } else {
307                 OperandTypes types = OperandTypes::fromInt(instruction[i + 4].u.operand);
308                 if (types.first().mightBeNumber() && types.second().mightBeNumber())
309                     compileBinaryArithOp(op_add, instruction[i + 1].u.operand, instruction[i + 2].u.operand, instruction[i + 3].u.operand, OperandTypes::fromInt(instruction[i + 4].u.operand), i);
310                 else {
311                     emitPutCTIArgFromVirtualRegister(instruction[i + 2].u.operand, 0, X86::ecx);
312                     emitPutCTIArgFromVirtualRegister(instruction[i + 3].u.operand, 4, X86::ecx);
313                     emitCTICall(i, Interpreter::cti_op_add);
314                     emitPutVirtualRegister(instruction[i + 1].u.operand);
315                 }
316             }
317
318             i += OPCODE_LENGTH(op_add);
319             break;
320         }
321         case op_end: {
322             if (m_codeBlock->needsFullScopeChain())
323                 emitCTICall(i, Interpreter::cti_op_end);
324             emitGetVirtualRegister(instruction[i + 1].u.operand, X86::eax, i);
325             __ pushl_m(RegisterFile::ReturnPC * static_cast<int>(sizeof(Register)), X86::edi);
326             __ ret();
327             i += OPCODE_LENGTH(op_end);
328             break;
329         }
330         case op_jmp: {
331             unsigned target = instruction[i + 1].u.operand;
332             m_jmpTable.append(JmpTable(jump(), i + 1 + target));
333             i += OPCODE_LENGTH(op_jmp);
334             break;
335         }
336         case op_pre_inc: {
337             int srcDst = instruction[i + 1].u.operand;
338             emitGetVirtualRegister(srcDst, X86::eax, i);
339             emitJumpSlowCaseIfNotImmNum(X86::eax, i);
340             m_slowCases.append(SlowCaseEntry(joAdd32(Imm32(getDeTaggedConstantImmediate(JSImmediate::oneImmediate())), X86::eax), i));
341             emitPutVirtualRegister(srcDst);
342             i += OPCODE_LENGTH(op_pre_inc);
343             break;
344         }
345         case op_loop: {
346             emitSlowScriptCheck(i);
347
348             unsigned target = instruction[i + 1].u.operand;
349             m_jmpTable.append(JmpTable(jump(), i + 1 + target));
350             i += OPCODE_LENGTH(op_end);
351             break;
352         }
353         case op_loop_if_less: {
354             emitSlowScriptCheck(i);
355
356             unsigned target = instruction[i + 3].u.operand;
357             JSValue* src2imm = getConstantImmediateNumericArg(instruction[i + 2].u.operand);
358             if (src2imm) {
359                 emitGetVirtualRegister(instruction[i + 1].u.operand, X86::eax, i);
360                 emitJumpSlowCaseIfNotImmNum(X86::eax, i);
361                 m_jmpTable.append(JmpTable(jl32(X86::eax, Imm32(asInteger(src2imm))), i + 3 + target));
362             } else {
363                 emitGetVirtualRegisters(instruction[i + 1].u.operand, X86::eax, instruction[i + 2].u.operand, X86::edx, i);
364                 emitJumpSlowCaseIfNotImmNum(X86::eax, i);
365                 emitJumpSlowCaseIfNotImmNum(X86::edx, i);
366                 m_jmpTable.append(JmpTable(jl32(X86::eax, X86::edx), i + 3 + target));
367             }
368             i += OPCODE_LENGTH(op_loop_if_less);
369             break;
370         }
371         case op_loop_if_lesseq: {
372             emitSlowScriptCheck(i);
373
374             unsigned target = instruction[i + 3].u.operand;
375             JSValue* src2imm = getConstantImmediateNumericArg(instruction[i + 2].u.operand);
376             if (src2imm) {
377                 emitGetVirtualRegister(instruction[i + 1].u.operand, X86::eax, i);
378                 emitJumpSlowCaseIfNotImmNum(X86::eax, i);
379                 m_jmpTable.append(JmpTable(jle32(X86::eax, Imm32(asInteger(src2imm))), i + 3 + target));
380             } else {
381                 emitGetVirtualRegisters(instruction[i + 1].u.operand, X86::eax, instruction[i + 2].u.operand, X86::edx, i);
382                 emitJumpSlowCaseIfNotImmNum(X86::eax, i);
383                 emitJumpSlowCaseIfNotImmNum(X86::edx, i);
384                 m_jmpTable.append(JmpTable(jle32(X86::eax, X86::edx), i + 3 + target));
385             }
386             i += OPCODE_LENGTH(op_loop_if_lesseq);
387             break;
388         }
389         case op_new_object: {
390             emitCTICall(i, Interpreter::cti_op_new_object);
391             emitPutVirtualRegister(instruction[i + 1].u.operand);
392             i += OPCODE_LENGTH(op_new_object);
393             break;
394         }
395         case op_put_by_id: {
396             compilePutByIdHotPath(instruction[i + 1].u.operand, &(m_codeBlock->identifier(instruction[i + 2].u.operand)), instruction[i + 3].u.operand, i, propertyAccessInstructionIndex++);
397             i += OPCODE_LENGTH(op_put_by_id);
398             break;
399         }
400         case op_get_by_id: {
401             compileGetByIdHotPath(instruction[i + 1].u.operand, instruction[i + 2].u.operand, &(m_codeBlock->identifier(instruction[i + 3].u.operand)), i, propertyAccessInstructionIndex++);
402             i += OPCODE_LENGTH(op_get_by_id);
403             break;
404         }
405         case op_instanceof: {
406             emitGetVirtualRegister(instruction[i + 2].u.operand, X86::eax, i); // value
407             emitGetVirtualRegister(instruction[i + 3].u.operand, X86::ecx, i); // baseVal
408             emitGetVirtualRegister(instruction[i + 4].u.operand, X86::edx, i); // proto
409
410             // check if any are immediates
411             move(X86::eax, X86::ebx);
412             or32(X86::ecx, X86::ebx);
413             or32(X86::edx, X86::ebx);
414             emitJumpSlowCaseIfNotJSCell(X86::ebx, i);
415
416             // check that all are object type - this is a bit of a bithack to avoid excess branching;
417             // we check that the sum of the three type codes from Structures is exactly 3 * ObjectType,
418             // this works because NumberType and StringType are smaller
419             move(Imm32(3 * ObjectType), X86::ebx);
420             loadPtr(Address(X86::eax, FIELD_OFFSET(JSCell, m_structure)), X86::eax);
421             loadPtr(Address(X86::ecx, FIELD_OFFSET(JSCell, m_structure)), X86::ecx);
422             loadPtr(Address(X86::edx, FIELD_OFFSET(JSCell, m_structure)), X86::edx);
423             sub32(Address(X86::eax, FIELD_OFFSET(Structure, m_typeInfo.m_type)), X86::ebx);
424             sub32(Address(X86::ecx, FIELD_OFFSET(Structure, m_typeInfo.m_type)), X86::ebx);
425             m_slowCases.append(SlowCaseEntry(jne32(Address(X86::edx, FIELD_OFFSET(Structure, m_typeInfo.m_type)), X86::ebx), i));
426
427             // check that baseVal's flags include ImplementsHasInstance but not OverridesHasInstance
428             load32(Address(X86::ecx, FIELD_OFFSET(Structure, m_typeInfo.m_flags)), X86::ecx);
429             and32(Imm32(ImplementsHasInstance | OverridesHasInstance), X86::ecx);
430             m_slowCases.append(SlowCaseEntry(jne32(X86::ecx, Imm32(ImplementsHasInstance)), i));
431
432             emitGetVirtualRegister(instruction[i + 2].u.operand, X86::ecx, i); // reload value
433             emitGetVirtualRegister(instruction[i + 4].u.operand, X86::edx, i); // reload proto
434
435             // optimistically load true result
436             move(Imm32(asInteger(jsBoolean(true))), X86::eax);
437
438             Label loop(this);
439
440             // load value's prototype
441             loadPtr(Address(X86::ecx, FIELD_OFFSET(JSCell, m_structure)), X86::ecx);
442             loadPtr(Address(X86::ecx, FIELD_OFFSET(Structure, m_prototype)), X86::ecx);
443
444             Jump exit = jePtr(X86::ecx, X86::edx);
445
446             jne32(X86::ecx, Imm32(asInteger(jsNull())), loop);
447
448             move(Imm32(asInteger(jsBoolean(false))), X86::eax);
449
450             exit.link(this);
451
452             emitPutVirtualRegister(instruction[i + 1].u.operand);
453
454             i += OPCODE_LENGTH(op_instanceof);
455             break;
456         }
457         case op_del_by_id: {
458             emitPutCTIArgFromVirtualRegister(instruction[i + 2].u.operand, 0, X86::ecx);
459             Identifier* ident = &(m_codeBlock->identifier(instruction[i + 3].u.operand));
460             emitPutCTIArgConstant(reinterpret_cast<unsigned>(ident), 4);
461             emitCTICall(i, Interpreter::cti_op_del_by_id);
462             emitPutVirtualRegister(instruction[i + 1].u.operand);
463             i += OPCODE_LENGTH(op_del_by_id);
464             break;
465         }
466         case op_mul: {
467             unsigned dst = instruction[i + 1].u.operand;
468             unsigned src1 = instruction[i + 2].u.operand;
469             unsigned src2 = instruction[i + 3].u.operand;
470
471             // For now, only plant a fast int case if the constant operand is greater than zero.
472             JSValue* src1Value = getConstantImmediateNumericArg(src1);
473             JSValue* src2Value = getConstantImmediateNumericArg(src2);
474             int32_t value;
475             if (src1Value && ((value = JSImmediate::intValue(src1Value)) > 0)) {
476                 emitGetVirtualRegister(src2, X86::eax, i);
477                 emitJumpSlowCaseIfNotImmNum(X86::eax, i);
478                 emitFastArithDeTagImmediate(X86::eax);
479                 m_slowCases.append(SlowCaseEntry(joMul32(Imm32(value), X86::eax, X86::eax), i));
480                 emitFastArithReTagImmediate(X86::eax);
481                 emitPutVirtualRegister(dst);
482             } else if (src2Value && ((value = JSImmediate::intValue(src2Value)) > 0)) {
483                 emitGetVirtualRegister(src1, X86::eax, i);
484                 emitJumpSlowCaseIfNotImmNum(X86::eax, i);
485                 emitFastArithDeTagImmediate(X86::eax);
486                 m_slowCases.append(SlowCaseEntry(joMul32(Imm32(value), X86::eax, X86::eax), i));
487                 emitFastArithReTagImmediate(X86::eax);
488                 emitPutVirtualRegister(dst);
489             } else
490                 compileBinaryArithOp(op_mul, instruction[i + 1].u.operand, instruction[i + 2].u.operand, instruction[i + 3].u.operand, OperandTypes::fromInt(instruction[i + 4].u.operand), i);
491
492             i += OPCODE_LENGTH(op_mul);
493             break;
494         }
495         case op_new_func: {
496             FuncDeclNode* func = m_codeBlock->function(instruction[i + 2].u.operand);
497             emitPutCTIArgConstant(reinterpret_cast<unsigned>(func), 0);
498             emitCTICall(i, Interpreter::cti_op_new_func);
499             emitPutVirtualRegister(instruction[i + 1].u.operand);
500             i += OPCODE_LENGTH(op_new_func);
501             break;
502         }
503         case op_call:
504         case op_call_eval:
505         case op_construct: {
506             compileOpCall(opcodeID, instruction + i, i, callLinkInfoIndex++);
507             i += (opcodeID == op_construct ? OPCODE_LENGTH(op_construct) : OPCODE_LENGTH(op_call));
508             break;
509         }
510         case op_get_global_var: {
511             JSVariableObject* globalObject = static_cast<JSVariableObject*>(instruction[i + 2].u.jsCell);
512             move(ImmPtr(globalObject), X86::eax);
513             emitGetVariableObjectRegister(X86::eax, instruction[i + 3].u.operand, X86::eax);
514             emitPutVirtualRegister(instruction[i + 1].u.operand);
515             i += OPCODE_LENGTH(op_get_global_var);
516             break;
517         }
518         case op_put_global_var: {
519             emitGetVirtualRegister(instruction[i + 3].u.operand, X86::edx, i);
520             JSVariableObject* globalObject = static_cast<JSVariableObject*>(instruction[i + 1].u.jsCell);
521             move(ImmPtr(globalObject), X86::eax);
522             emitPutVariableObjectRegister(X86::edx, X86::eax, instruction[i + 2].u.operand);
523             i += OPCODE_LENGTH(op_put_global_var);
524             break;
525         }
526         case op_get_scoped_var: {
527             int skip = instruction[i + 3].u.operand + m_codeBlock->needsFullScopeChain();
528
529             emitGetFromCallFrameHeader(RegisterFile::ScopeChain, X86::eax);
530             while (skip--)
531                 loadPtr(Address(X86::eax, FIELD_OFFSET(ScopeChainNode, next)), X86::eax);
532
533             loadPtr(Address(X86::eax, FIELD_OFFSET(ScopeChainNode, object)), X86::eax);
534             emitGetVariableObjectRegister(X86::eax, instruction[i + 2].u.operand, X86::eax);
535             emitPutVirtualRegister(instruction[i + 1].u.operand);
536             i += OPCODE_LENGTH(op_get_scoped_var);
537             break;
538         }
539         case op_put_scoped_var: {
540             int skip = instruction[i + 2].u.operand + m_codeBlock->needsFullScopeChain();
541
542             emitGetFromCallFrameHeader(RegisterFile::ScopeChain, X86::edx);
543             emitGetVirtualRegister(instruction[i + 3].u.operand, X86::eax, i);
544             while (skip--)
545                 loadPtr(Address(X86::edx, FIELD_OFFSET(ScopeChainNode, next)), X86::edx);
546
547             loadPtr(Address(X86::edx, FIELD_OFFSET(ScopeChainNode, object)), X86::edx);
548             emitPutVariableObjectRegister(X86::eax, X86::edx, instruction[i + 1].u.operand);
549             i += OPCODE_LENGTH(op_put_scoped_var);
550             break;
551         }
552         case op_tear_off_activation: {
553             emitPutCTIArgFromVirtualRegister(instruction[i + 1].u.operand, 0, X86::ecx);
554             emitCTICall(i, Interpreter::cti_op_tear_off_activation);
555             i += OPCODE_LENGTH(op_tear_off_activation);
556             break;
557         }
558         case op_tear_off_arguments: {
559             emitCTICall(i, Interpreter::cti_op_tear_off_arguments);
560             i += OPCODE_LENGTH(op_tear_off_arguments);
561             break;
562         }
563         case op_ret: {
564             // We could JIT generate the deref, only calling out to C when the refcount hits zero.
565             if (m_codeBlock->needsFullScopeChain())
566                 emitCTICall(i, Interpreter::cti_op_ret_scopeChain);
567
568             // Return the result in %eax.
569             emitGetVirtualRegister(instruction[i + 1].u.operand, X86::eax, i);
570
571             // Grab the return address.
572             emitGetFromCallFrameHeader(RegisterFile::ReturnPC, X86::edx);
573
574             // Restore our caller's "r".
575             emitGetFromCallFrameHeader(RegisterFile::CallerFrame, X86::edi);
576
577             // Return.
578             __ pushl_r(X86::edx);
579             __ ret();
580
581             i += OPCODE_LENGTH(op_ret);
582             break;
583         }
584         case op_new_array: {
585             emitPutCTIArgConstant(instruction[i + 2].u.operand, 0);
586             emitPutCTIArgConstant(instruction[i + 3].u.operand, 4);
587             emitCTICall(i, Interpreter::cti_op_new_array);
588             emitPutVirtualRegister(instruction[i + 1].u.operand);
589             i += OPCODE_LENGTH(op_new_array);
590             break;
591         }
592         case op_resolve: {
593             Identifier* ident = &(m_codeBlock->identifier(instruction[i + 2].u.operand));
594             emitPutCTIArgConstant(reinterpret_cast<unsigned>(ident), 0);
595             emitCTICall(i, Interpreter::cti_op_resolve);
596             emitPutVirtualRegister(instruction[i + 1].u.operand);
597             i += OPCODE_LENGTH(op_resolve);
598             break;
599         }
600         case op_construct_verify: {
601             emitGetVirtualRegister(instruction[i + 1].u.operand, X86::eax, i);
602
603             emitJumpSlowCaseIfNotJSCell(X86::eax, i);
604             loadPtr(Address(X86::eax, FIELD_OFFSET(JSCell, m_structure)), X86::ecx);
605             m_slowCases.append(SlowCaseEntry(jne32(Address(X86::ecx, FIELD_OFFSET(Structure, m_typeInfo) + FIELD_OFFSET(TypeInfo, m_type)), Imm32(ObjectType)), i));
606
607             i += OPCODE_LENGTH(op_construct_verify);
608             break;
609         }
610         case op_get_by_val: {
611             emitGetVirtualRegisters(instruction[i + 2].u.operand, X86::eax, instruction[i + 3].u.operand, X86::edx, i);
612             emitJumpSlowCaseIfNotImmNum(X86::edx, i);
613             emitFastArithImmToInt(X86::edx);
614             emitJumpSlowCaseIfNotJSCell(X86::eax, i);
615             m_slowCases.append(SlowCaseEntry(jnePtr(Address(X86::eax), ImmPtr(m_interpreter->m_jsArrayVptr)), i));
616
617             // This is an array; get the m_storage pointer into ecx, then check if the index is below the fast cutoff
618             loadPtr(Address(X86::eax, FIELD_OFFSET(JSArray, m_storage)), X86::ecx);
619             m_slowCases.append(SlowCaseEntry(jae32(X86::edx, Address(X86::eax, FIELD_OFFSET(JSArray, m_fastAccessCutoff))), i));
620
621             // Get the value from the vector
622             loadPtr(BaseIndex(X86::ecx, X86::edx, ScalePtr, FIELD_OFFSET(ArrayStorage, m_vector[0])), X86::eax);
623             emitPutVirtualRegister(instruction[i + 1].u.operand);
624             i += OPCODE_LENGTH(op_get_by_val);
625             break;
626         }
627         case op_resolve_func: {
628             Identifier* ident = &(m_codeBlock->identifier(instruction[i + 3].u.operand));
629             emitPutCTIArgConstant(reinterpret_cast<unsigned>(ident), 0);
630             emitCTICall(i, Interpreter::cti_op_resolve_func);
631             emitPutVirtualRegister(instruction[i + 2].u.operand, X86::edx);
632             emitPutVirtualRegister(instruction[i + 1].u.operand);
633             i += OPCODE_LENGTH(op_resolve_func);
634             break;
635         }
636         case op_sub: {
637             compileBinaryArithOp(op_sub, instruction[i + 1].u.operand, instruction[i + 2].u.operand, instruction[i + 3].u.operand, OperandTypes::fromInt(instruction[i + 4].u.operand), i);
638             i += OPCODE_LENGTH(op_sub);
639             break;
640         }
641         case op_put_by_val: {
642             emitGetVirtualRegisters(instruction[i + 1].u.operand, X86::eax, instruction[i + 2].u.operand, X86::edx, i);
643             emitJumpSlowCaseIfNotImmNum(X86::edx, i);
644             emitFastArithImmToInt(X86::edx);
645             emitJumpSlowCaseIfNotJSCell(X86::eax, i);
646             m_slowCases.append(SlowCaseEntry(jnePtr(Address(X86::eax), ImmPtr(m_interpreter->m_jsArrayVptr)), i));
647
648             // This is an array; get the m_storage pointer into ecx, then check if the index is below the fast cutoff
649             loadPtr(Address(X86::eax, FIELD_OFFSET(JSArray, m_storage)), X86::ecx);
650             Jump inFastVector = jb32(X86::edx, Address(X86::eax, FIELD_OFFSET(JSArray, m_fastAccessCutoff)));
651             // No; oh well, check if the access if within the vector - if so, we may still be okay.
652             m_slowCases.append(SlowCaseEntry(jae32(X86::edx, Address(X86::ecx, FIELD_OFFSET(ArrayStorage, m_vectorLength))), i));
653
654             // This is a write to the slow part of the vector; first, we have to check if this would be the first write to this location.
655             // FIXME: should be able to handle initial write to array; increment the the number of items in the array, and potentially update fast access cutoff. 
656             m_slowCases.append(SlowCaseEntry(jzPtr(BaseIndex(X86::ecx, X86::edx, ScalePtr, FIELD_OFFSET(ArrayStorage, m_vector[0]))), i));
657
658             // All good - put the value into the array.
659             inFastVector.link(this);
660             emitGetVirtualRegister(instruction[i + 3].u.operand, X86::eax, i);
661             storePtr(X86::eax, BaseIndex(X86::ecx, X86::edx, ScalePtr, FIELD_OFFSET(ArrayStorage, m_vector[0])));
662             i += OPCODE_LENGTH(op_put_by_val);
663             break;
664         }
665         CTI_COMPILE_BINARY_OP(op_lesseq)
666         case op_loop_if_true: {
667             emitSlowScriptCheck(i);
668
669             unsigned target = instruction[i + 2].u.operand;
670             emitGetVirtualRegister(instruction[i + 1].u.operand, X86::eax, i);
671
672             Jump isZero = je32(X86::eax, Imm32(asInteger(JSImmediate::zeroImmediate())));
673             m_jmpTable.append(JmpTable(jnz32(X86::eax, Imm32(JSImmediate::TagBitTypeInteger)), i + 2 + target));
674
675             m_jmpTable.append(JmpTable(je32(X86::eax, Imm32(asInteger(JSImmediate::trueImmediate()))), i + 2 + target));
676             m_slowCases.append(SlowCaseEntry(jne32(X86::eax, Imm32(asInteger(JSImmediate::falseImmediate()))), i));
677
678             isZero.link(this);
679             i += OPCODE_LENGTH(op_loop_if_true);
680             break;
681         };
682         case op_resolve_base: {
683             Identifier* ident = &(m_codeBlock->identifier(instruction[i + 2].u.operand));
684             emitPutCTIArgConstant(reinterpret_cast<unsigned>(ident), 0);
685             emitCTICall(i, Interpreter::cti_op_resolve_base);
686             emitPutVirtualRegister(instruction[i + 1].u.operand);
687             i += OPCODE_LENGTH(op_resolve_base);
688             break;
689         }
690         case op_negate: {
691             emitPutCTIArgFromVirtualRegister(instruction[i + 2].u.operand, 0, X86::ecx);
692             emitCTICall(i, Interpreter::cti_op_negate);
693             emitPutVirtualRegister(instruction[i + 1].u.operand);
694             i += OPCODE_LENGTH(op_negate);
695             break;
696         }
697         case op_resolve_skip: {
698             Identifier* ident = &(m_codeBlock->identifier(instruction[i + 2].u.operand));
699             emitPutCTIArgConstant(reinterpret_cast<unsigned>(ident), 0);
700             emitPutCTIArgConstant(instruction[i + 3].u.operand + m_codeBlock->needsFullScopeChain(), 4);
701             emitCTICall(i, Interpreter::cti_op_resolve_skip);
702             emitPutVirtualRegister(instruction[i + 1].u.operand);
703             i += OPCODE_LENGTH(op_resolve_skip);
704             break;
705         }
706         case op_resolve_global: {
707             // Fast case
708             void* globalObject = instruction[i + 2].u.jsCell;
709             Identifier* ident = &(m_codeBlock->identifier(instruction[i + 3].u.operand));
710             void* structureAddress = reinterpret_cast<void*>(instruction + i + 4);
711             void* offsetAddr = reinterpret_cast<void*>(instruction + i + 5);
712
713             // Check Structure of global object
714             move(ImmPtr(globalObject), X86::eax);
715             loadPtr(structureAddress, X86::edx);
716             Jump noMatch = jnePtr(X86::edx, Address(X86::eax, FIELD_OFFSET(JSCell, m_structure))); // Structures don't match
717
718             // Load cached property
719             loadPtr(Address(X86::eax, FIELD_OFFSET(JSGlobalObject, m_propertyStorage)), X86::eax);
720             load32(offsetAddr, X86::edx);
721             loadPtr(BaseIndex(X86::eax, X86::edx, ScalePtr), X86::eax);
722             emitPutVirtualRegister(instruction[i + 1].u.operand);
723             Jump end = jump();
724
725             // Slow case
726             noMatch.link(this);
727             emitPutCTIArgConstant(globalObject, 0);
728             emitPutCTIArgConstant(reinterpret_cast<unsigned>(ident), 4);
729             emitPutCTIArgConstant(reinterpret_cast<unsigned>(instruction + i), 8);
730             emitCTICall(i, Interpreter::cti_op_resolve_global);
731             emitPutVirtualRegister(instruction[i + 1].u.operand);
732             end.link(this);
733             i += OPCODE_LENGTH(op_resolve_global);
734             break;
735         }
736         CTI_COMPILE_BINARY_OP(op_div)
737         case op_pre_dec: {
738             int srcDst = instruction[i + 1].u.operand;
739             emitGetVirtualRegister(srcDst, X86::eax, i);
740             emitJumpSlowCaseIfNotImmNum(X86::eax, i);
741             m_slowCases.append(SlowCaseEntry(joSub32(Imm32(getDeTaggedConstantImmediate(JSImmediate::oneImmediate())), X86::eax), i));
742             emitPutVirtualRegister(srcDst);
743             i += OPCODE_LENGTH(op_pre_dec);
744             break;
745         }
746         case op_jnless: {
747             unsigned target = instruction[i + 3].u.operand;
748             JSValue* src2imm = getConstantImmediateNumericArg(instruction[i + 2].u.operand);
749             if (src2imm) {
750                 emitGetVirtualRegister(instruction[i + 1].u.operand, X86::edx, i);
751                 emitJumpSlowCaseIfNotImmNum(X86::edx, i);
752                 m_jmpTable.append(JmpTable(jge32(X86::edx, Imm32(asInteger(src2imm))), i + 3 + target));
753             } else {
754                 emitGetVirtualRegisters(instruction[i + 1].u.operand, X86::eax, instruction[i + 2].u.operand, X86::edx, i);
755                 emitJumpSlowCaseIfNotImmNum(X86::eax, i);
756                 emitJumpSlowCaseIfNotImmNum(X86::edx, i);
757                 m_jmpTable.append(JmpTable(jge32(X86::eax, X86::edx), i + 3 + target));
758             }
759             i += OPCODE_LENGTH(op_jnless);
760             break;
761         }
762         case op_not: {
763             emitGetVirtualRegister(instruction[i + 2].u.operand, X86::eax, i);
764             xor32(Imm32(JSImmediate::FullTagTypeBool), X86::eax);
765             m_slowCases.append(SlowCaseEntry(jnz32(X86::eax, Imm32(JSImmediate::FullTagTypeMask)), i));
766             xor32(Imm32(JSImmediate::FullTagTypeBool | JSImmediate::ExtendedPayloadBitBoolValue), X86::eax);
767             emitPutVirtualRegister(instruction[i + 1].u.operand);
768             i += OPCODE_LENGTH(op_not);
769             break;
770         }
771         case op_jfalse: {
772             unsigned target = instruction[i + 2].u.operand;
773             emitGetVirtualRegister(instruction[i + 1].u.operand, X86::eax, i);
774
775             m_jmpTable.append(JmpTable(je32(X86::eax, Imm32(asInteger(JSImmediate::zeroImmediate()))), i + 2 + target));
776             Jump isNonZero = jnz32(X86::eax, Imm32(JSImmediate::TagBitTypeInteger));
777
778             m_jmpTable.append(JmpTable(je32(X86::eax, Imm32(asInteger(JSImmediate::falseImmediate()))), i + 2 + target));
779             m_slowCases.append(SlowCaseEntry(jne32(X86::eax, Imm32(asInteger(JSImmediate::trueImmediate()))), i));
780
781             isNonZero.link(this);
782             i += OPCODE_LENGTH(op_jfalse);
783             break;
784         };
785         case op_jeq_null: {
786             unsigned src = instruction[i + 1].u.operand;
787             unsigned target = instruction[i + 2].u.operand;
788
789             emitGetVirtualRegister(src, X86::eax, i);
790             Jump isImmediate = emitJumpIfNotJSCell(X86::eax);
791
792             // First, handle JSCell cases - check MasqueradesAsUndefined bit on the structure.
793             loadPtr(Address(X86::eax, FIELD_OFFSET(JSCell, m_structure)), X86::ecx);
794             m_jmpTable.append(JmpTable(jnz32(Address(X86::ecx, FIELD_OFFSET(Structure, m_typeInfo.m_flags)), Imm32(MasqueradesAsUndefined)), i + 2 + target));
795             Jump wasNotImmediate = jump();
796
797             // Now handle the immediate cases - undefined & null
798             isImmediate.link(this);
799             and32(Imm32(~JSImmediate::ExtendedTagBitUndefined), X86::eax);
800             m_jmpTable.append(JmpTable(je32(X86::eax, Imm32(asInteger(jsNull()))), i + 2 + target));            
801
802             wasNotImmediate.link(this);
803             i += OPCODE_LENGTH(op_jeq_null);
804             break;
805         };
806         case op_jneq_null: {
807             unsigned src = instruction[i + 1].u.operand;
808             unsigned target = instruction[i + 2].u.operand;
809
810             emitGetVirtualRegister(src, X86::eax, i);
811             Jump isImmediate = emitJumpIfNotJSCell(X86::eax);
812
813             // First, handle JSCell cases - check MasqueradesAsUndefined bit on the structure.
814             loadPtr(Address(X86::eax, FIELD_OFFSET(JSCell, m_structure)), X86::ecx);
815             m_jmpTable.append(JmpTable(jz32(Address(X86::ecx, FIELD_OFFSET(Structure, m_typeInfo.m_flags)), Imm32(MasqueradesAsUndefined)), i + 2 + target));
816             Jump wasNotImmediate = jump();
817
818             // Now handle the immediate cases - undefined & null
819             isImmediate.link(this);
820             and32(Imm32(~JSImmediate::ExtendedTagBitUndefined), X86::eax);
821             m_jmpTable.append(JmpTable(jne32(X86::eax, Imm32(asInteger(jsNull()))), i + 2 + target));            
822
823             wasNotImmediate.link(this);
824             i += OPCODE_LENGTH(op_jneq_null);
825             break;
826         }
827         case op_post_inc: {
828             int srcDst = instruction[i + 2].u.operand;
829             emitGetVirtualRegister(srcDst, X86::eax, i);
830             move(X86::eax, X86::edx);
831             emitJumpSlowCaseIfNotImmNum(X86::eax, i);
832             m_slowCases.append(SlowCaseEntry(joAdd32(Imm32(getDeTaggedConstantImmediate(JSImmediate::oneImmediate())), X86::edx), i));
833             emitPutVirtualRegister(srcDst, X86::edx);
834             emitPutVirtualRegister(instruction[i + 1].u.operand);
835             i += OPCODE_LENGTH(op_post_inc);
836             break;
837         }
838         case op_unexpected_load: {
839             JSValue* v = m_codeBlock->unexpectedConstant(instruction[i + 2].u.operand);
840             move(ImmPtr(v), X86::eax);
841             emitPutVirtualRegister(instruction[i + 1].u.operand);
842             i += OPCODE_LENGTH(op_unexpected_load);
843             break;
844         }
845         case op_jsr: {
846             int retAddrDst = instruction[i + 1].u.operand;
847             int target = instruction[i + 2].u.operand;
848             __ movl_i32m(0, sizeof(Register) * retAddrDst, X86::edi);
849             JmpDst addrPosition = __ label();
850             m_jmpTable.append(JmpTable(__ jmp(), i + 2 + target));
851             JmpDst sretTarget = __ label();
852             m_jsrSites.append(JSRInfo(addrPosition, sretTarget));
853             i += OPCODE_LENGTH(op_jsr);
854             break;
855         }
856         case op_sret: {
857             __ jmp_m(sizeof(Register) * instruction[i + 1].u.operand, X86::edi);
858             i += OPCODE_LENGTH(op_sret);
859             break;
860         }
861         case op_eq: {
862             emitGetVirtualRegisters(instruction[i + 2].u.operand, X86::eax, instruction[i + 3].u.operand, X86::edx, i);
863             emitJumpSlowCaseIfNotImmNums(X86::eax, X86::edx, X86::ecx, i);
864             sete32(X86::edx, X86::eax);
865             emitTagAsBoolImmediate(X86::eax);
866             emitPutVirtualRegister(instruction[i + 1].u.operand);
867             i += OPCODE_LENGTH(op_eq);
868             break;
869         }
870         case op_lshift: {
871             emitGetVirtualRegisters(instruction[i + 2].u.operand, X86::eax, instruction[i + 3].u.operand, X86::ecx, i);
872             emitJumpSlowCaseIfNotImmNum(X86::eax, i);
873             emitJumpSlowCaseIfNotImmNum(X86::ecx, i);
874             emitFastArithImmToInt(X86::eax);
875             emitFastArithImmToInt(X86::ecx);
876             __ shll_CLr(X86::eax);
877             emitFastArithIntToImmOrSlowCase(X86::eax, i);
878             emitPutVirtualRegister(instruction[i + 1].u.operand);
879             i += OPCODE_LENGTH(op_lshift);
880             break;
881         }
882         case op_bitand: {
883             unsigned src1 = instruction[i + 2].u.operand;
884             unsigned src2 = instruction[i + 3].u.operand;
885             unsigned dst = instruction[i + 1].u.operand;
886             if (JSValue* value = getConstantImmediateNumericArg(src1)) {
887                 emitGetVirtualRegister(src2, X86::eax, i);
888                 emitJumpSlowCaseIfNotImmNum(X86::eax, i);
889                 and32(Imm32(asInteger(value)), X86::eax); // FIXME: make it more obvious this is relying on the format of JSImmediate
890                 emitPutVirtualRegister(dst);
891             } else if (JSValue* value = getConstantImmediateNumericArg(src2)) {
892                 emitGetVirtualRegister(src1, X86::eax, i);
893                 emitJumpSlowCaseIfNotImmNum(X86::eax, i);
894                 and32(Imm32(asInteger(value)), X86::eax);
895                 emitPutVirtualRegister(dst);
896             } else {
897                 emitGetVirtualRegisters(src1, X86::eax, src2, X86::edx, i);
898                 and32(X86::edx, X86::eax);
899                 emitJumpSlowCaseIfNotImmNum(X86::eax, i);
900                 emitPutVirtualRegister(dst);
901             }
902             i += OPCODE_LENGTH(op_bitand);
903             break;
904         }
905         case op_rshift: {
906             unsigned src1 = instruction[i + 2].u.operand;
907             unsigned src2 = instruction[i + 3].u.operand;
908             if (JSValue* value = getConstantImmediateNumericArg(src2)) {
909                 emitGetVirtualRegister(src1, X86::eax, i);
910                 emitJumpSlowCaseIfNotImmNum(X86::eax, i);
911                 // Mask with 0x1f as per ecma-262 11.7.2 step 7.
912                 rshift32(Imm32(JSImmediate::getTruncatedUInt32(value) & 0x1f), X86::eax);
913             } else {
914                 emitGetVirtualRegisters(src1, X86::eax, src2, X86::ecx, i);
915                 emitJumpSlowCaseIfNotImmNum(X86::eax, i);
916                 emitJumpSlowCaseIfNotImmNum(X86::ecx, i);
917                 emitFastArithImmToInt(X86::ecx);
918                 __ sarl_CLr(X86::eax);
919             }
920             emitFastArithPotentiallyReTagImmediate(X86::eax);
921             emitPutVirtualRegister(instruction[i + 1].u.operand);
922             i += OPCODE_LENGTH(op_rshift);
923             break;
924         }
925         case op_bitnot: {
926             emitGetVirtualRegister(instruction[i + 2].u.operand, X86::eax, i);
927             emitJumpSlowCaseIfNotImmNum(X86::eax, i);
928             xor32(Imm32(~JSImmediate::TagBitTypeInteger), X86::eax);
929             emitPutVirtualRegister(instruction[i + 1].u.operand);
930             i += OPCODE_LENGTH(op_bitnot);
931             break;
932         }
933         case op_resolve_with_base: {
934             Identifier* ident = &(m_codeBlock->identifier(instruction[i + 3].u.operand));
935             emitPutCTIArgConstant(reinterpret_cast<unsigned>(ident), 0);
936             emitCTICall(i, Interpreter::cti_op_resolve_with_base);
937             emitPutVirtualRegister(instruction[i + 2].u.operand, X86::edx);
938             emitPutVirtualRegister(instruction[i + 1].u.operand);
939             i += OPCODE_LENGTH(op_resolve_with_base);
940             break;
941         }
942         case op_new_func_exp: {
943             FuncExprNode* func = m_codeBlock->functionExpression(instruction[i + 2].u.operand);
944             emitPutCTIArgConstant(reinterpret_cast<unsigned>(func), 0);
945             emitCTICall(i, Interpreter::cti_op_new_func_exp);
946             emitPutVirtualRegister(instruction[i + 1].u.operand);
947             i += OPCODE_LENGTH(op_new_func_exp);
948             break;
949         }
950         case op_mod: {
951             emitGetVirtualRegisters(instruction[i + 2].u.operand, X86::eax, instruction[i + 3].u.operand, X86::ecx, i);
952             emitJumpSlowCaseIfNotImmNum(X86::eax, i);
953             emitJumpSlowCaseIfNotImmNum(X86::ecx, i);
954             emitFastArithDeTagImmediate(X86::eax);
955             m_slowCases.append(SlowCaseEntry(emitFastArithDeTagImmediateJumpIfZero(X86::ecx), i));
956             __ cdq();
957             __ idivl_r(X86::ecx);
958             emitFastArithReTagImmediate(X86::edx);
959             move(X86::edx, X86::eax);
960             emitPutVirtualRegister(instruction[i + 1].u.operand);
961             i += OPCODE_LENGTH(op_mod);
962             break;
963         }
964         case op_jtrue: {
965             unsigned target = instruction[i + 2].u.operand;
966             emitGetVirtualRegister(instruction[i + 1].u.operand, X86::eax, i);
967
968             Jump isZero = je32(X86::eax, Imm32(asInteger(JSImmediate::zeroImmediate())));
969             m_jmpTable.append(JmpTable(jnz32(X86::eax, Imm32(JSImmediate::TagBitTypeInteger)), i + 2 + target));
970
971             m_jmpTable.append(JmpTable(je32(X86::eax, Imm32(asInteger(JSImmediate::trueImmediate()))), i + 2 + target));
972             m_slowCases.append(SlowCaseEntry(jne32(X86::eax, Imm32(asInteger(JSImmediate::falseImmediate()))), i));
973
974             isZero.link(this);
975             i += OPCODE_LENGTH(op_jtrue);
976             break;
977         }
978         CTI_COMPILE_BINARY_OP(op_less)
979         case op_neq: {
980             emitGetVirtualRegisters(instruction[i + 2].u.operand, X86::eax, instruction[i + 3].u.operand, X86::edx, i);
981             emitJumpSlowCaseIfNotImmNums(X86::eax, X86::edx, X86::ecx, i);
982             setne32(X86::edx, X86::eax);
983             emitTagAsBoolImmediate(X86::eax);
984
985             emitPutVirtualRegister(instruction[i + 1].u.operand);
986
987             i += OPCODE_LENGTH(op_neq);
988             break;
989         }
990         case op_post_dec: {
991             int srcDst = instruction[i + 2].u.operand;
992             emitGetVirtualRegister(srcDst, X86::eax, i);
993             move(X86::eax, X86::edx);
994             emitJumpSlowCaseIfNotImmNum(X86::eax, i);
995             m_slowCases.append(SlowCaseEntry(joSub32(Imm32(getDeTaggedConstantImmediate(JSImmediate::oneImmediate())), X86::edx), i));
996             emitPutVirtualRegister(srcDst, X86::edx);
997             emitPutVirtualRegister(instruction[i + 1].u.operand);
998             i += OPCODE_LENGTH(op_post_dec);
999             break;
1000         }
1001         CTI_COMPILE_BINARY_OP(op_urshift)
1002         case op_bitxor: {
1003             emitGetVirtualRegisters(instruction[i + 2].u.operand, X86::eax, instruction[i + 3].u.operand, X86::edx, i);
1004             emitJumpSlowCaseIfNotImmNums(X86::eax, X86::edx, X86::ecx, i);
1005             xor32(X86::edx, X86::eax);
1006             emitFastArithReTagImmediate(X86::eax);
1007             emitPutVirtualRegister(instruction[i + 1].u.operand);
1008             i += OPCODE_LENGTH(op_bitxor);
1009             break;
1010         }
1011         case op_new_regexp: {
1012             RegExp* regExp = m_codeBlock->regexp(instruction[i + 2].u.operand);
1013             emitPutCTIArgConstant(reinterpret_cast<unsigned>(regExp), 0);
1014             emitCTICall(i, Interpreter::cti_op_new_regexp);
1015             emitPutVirtualRegister(instruction[i + 1].u.operand);
1016             i += OPCODE_LENGTH(op_new_regexp);
1017             break;
1018         }
1019         case op_bitor: {
1020             emitGetVirtualRegisters(instruction[i + 2].u.operand, X86::eax, instruction[i + 3].u.operand, X86::edx, i);
1021             emitJumpSlowCaseIfNotImmNums(X86::eax, X86::edx, X86::ecx, i);
1022             or32(X86::edx, X86::eax);
1023             emitPutVirtualRegister(instruction[i + 1].u.operand);
1024             i += OPCODE_LENGTH(op_bitor);
1025             break;
1026         }
1027         case op_throw: {
1028             emitPutCTIArgFromVirtualRegister(instruction[i + 1].u.operand, 0, X86::ecx);
1029             emitCTICall(i, Interpreter::cti_op_throw);
1030             __ addl_i8r(0x20, X86::esp);
1031             __ popl_r(X86::ebx);
1032             __ popl_r(X86::edi);
1033             __ popl_r(X86::esi);
1034             __ ret();
1035             i += OPCODE_LENGTH(op_throw);
1036             break;
1037         }
1038         case op_get_pnames: {
1039             emitPutCTIArgFromVirtualRegister(instruction[i + 2].u.operand, 0, X86::ecx);
1040             emitCTICall(i, Interpreter::cti_op_get_pnames);
1041             emitPutVirtualRegister(instruction[i + 1].u.operand);
1042             i += OPCODE_LENGTH(op_get_pnames);
1043             break;
1044         }
1045         case op_next_pname: {
1046             emitPutCTIArgFromVirtualRegister(instruction[i + 2].u.operand, 0, X86::ecx);
1047             unsigned target = instruction[i + 3].u.operand;
1048             emitCTICall(i, Interpreter::cti_op_next_pname);
1049             Jump endOfIter = jzPtr(X86::eax);
1050             emitPutVirtualRegister(instruction[i + 1].u.operand);
1051             m_jmpTable.append(JmpTable(jump(), i + 3 + target));
1052             endOfIter.link(this);
1053             i += OPCODE_LENGTH(op_next_pname);
1054             break;
1055         }
1056         case op_push_scope: {
1057             emitPutCTIArgFromVirtualRegister(instruction[i + 1].u.operand, 0, X86::ecx);
1058             emitCTICall(i, Interpreter::cti_op_push_scope);
1059             i += OPCODE_LENGTH(op_push_scope);
1060             break;
1061         }
1062         case op_pop_scope: {
1063             emitCTICall(i, Interpreter::cti_op_pop_scope);
1064             i += OPCODE_LENGTH(op_pop_scope);
1065             break;
1066         }
1067         CTI_COMPILE_UNARY_OP(op_typeof)
1068         CTI_COMPILE_UNARY_OP(op_is_undefined)
1069         CTI_COMPILE_UNARY_OP(op_is_boolean)
1070         CTI_COMPILE_UNARY_OP(op_is_number)
1071         CTI_COMPILE_UNARY_OP(op_is_string)
1072         CTI_COMPILE_UNARY_OP(op_is_object)
1073         CTI_COMPILE_UNARY_OP(op_is_function)
1074         case op_stricteq: {
1075             compileOpStrictEq(instruction + i, i, OpStrictEq);
1076             i += OPCODE_LENGTH(op_stricteq);
1077             break;
1078         }
1079         case op_nstricteq: {
1080             compileOpStrictEq(instruction + i, i, OpNStrictEq);
1081             i += OPCODE_LENGTH(op_nstricteq);
1082             break;
1083         }
1084         case op_to_jsnumber: {
1085             int srcVReg = instruction[i + 2].u.operand;
1086             emitGetVirtualRegister(srcVReg, X86::eax, i);
1087             
1088             Jump wasImmediate = jnz32(X86::eax, Imm32(JSImmediate::TagBitTypeInteger));
1089
1090             emitJumpSlowCaseIfNotJSCell(X86::eax, i, srcVReg);
1091             loadPtr(Address(X86::eax, FIELD_OFFSET(JSCell, m_structure)), X86::ecx);
1092             m_slowCases.append(SlowCaseEntry(jne32(Address(X86::ecx, FIELD_OFFSET(Structure, m_typeInfo.m_type)), Imm32(NumberType)), i));
1093             
1094             wasImmediate.link(this);
1095
1096             emitPutVirtualRegister(instruction[i + 1].u.operand);
1097             i += OPCODE_LENGTH(op_to_jsnumber);
1098             break;
1099         }
1100         case op_in: {
1101             emitPutCTIArgFromVirtualRegister(instruction[i + 2].u.operand, 0, X86::ecx);
1102             emitPutCTIArgFromVirtualRegister(instruction[i + 3].u.operand, 4, X86::ecx);
1103             emitCTICall(i, Interpreter::cti_op_in);
1104             emitPutVirtualRegister(instruction[i + 1].u.operand);
1105             i += OPCODE_LENGTH(op_in);
1106             break;
1107         }
1108         case op_push_new_scope: {
1109             Identifier* ident = &(m_codeBlock->identifier(instruction[i + 2].u.operand));
1110             emitPutCTIArgConstant(reinterpret_cast<unsigned>(ident), 0);
1111             emitPutCTIArgFromVirtualRegister(instruction[i + 3].u.operand, 4, X86::ecx);
1112             emitCTICall(i, Interpreter::cti_op_push_new_scope);
1113             emitPutVirtualRegister(instruction[i + 1].u.operand);
1114             i += OPCODE_LENGTH(op_push_new_scope);
1115             break;
1116         }
1117         case op_catch: {
1118             emitGetCTIParam(CTI_ARGS_callFrame, X86::edi); // edi := r
1119             emitPutVirtualRegister(instruction[i + 1].u.operand);
1120             i += OPCODE_LENGTH(op_catch);
1121             break;
1122         }
1123         case op_jmp_scopes: {
1124             unsigned count = instruction[i + 1].u.operand;
1125             emitPutCTIArgConstant(count, 0);
1126             emitCTICall(i, Interpreter::cti_op_jmp_scopes);
1127             unsigned target = instruction[i + 2].u.operand;
1128             m_jmpTable.append(JmpTable(jump(), i + 2 + target));
1129             i += OPCODE_LENGTH(op_jmp_scopes);
1130             break;
1131         }
1132         case op_put_by_index: {
1133             emitPutCTIArgFromVirtualRegister(instruction[i + 1].u.operand, 0, X86::ecx);
1134             emitPutCTIArgConstant(instruction[i + 2].u.operand, 4);
1135             emitPutCTIArgFromVirtualRegister(instruction[i + 3].u.operand, 8, X86::ecx);
1136             emitCTICall(i, Interpreter::cti_op_put_by_index);
1137             i += OPCODE_LENGTH(op_put_by_index);
1138             break;
1139         }
1140         case op_switch_imm: {
1141             unsigned tableIndex = instruction[i + 1].u.operand;
1142             unsigned defaultOffset = instruction[i + 2].u.operand;
1143             unsigned scrutinee = instruction[i + 3].u.operand;
1144
1145             // create jump table for switch destinations, track this switch statement.
1146             SimpleJumpTable* jumpTable = &m_codeBlock->immediateSwitchJumpTable(tableIndex);
1147             m_switches.append(SwitchRecord(jumpTable, i, defaultOffset, SwitchRecord::Immediate));
1148             jumpTable->ctiOffsets.grow(jumpTable->branchOffsets.size());
1149
1150             emitPutCTIArgFromVirtualRegister(scrutinee, 0, X86::ecx);
1151             emitPutCTIArgConstant(tableIndex, 4);
1152             emitCTICall(i, Interpreter::cti_op_switch_imm);
1153             jump(X86::eax);
1154             i += OPCODE_LENGTH(op_switch_imm);
1155             break;
1156         }
1157         case op_switch_char: {
1158             unsigned tableIndex = instruction[i + 1].u.operand;
1159             unsigned defaultOffset = instruction[i + 2].u.operand;
1160             unsigned scrutinee = instruction[i + 3].u.operand;
1161
1162             // create jump table for switch destinations, track this switch statement.
1163             SimpleJumpTable* jumpTable = &m_codeBlock->characterSwitchJumpTable(tableIndex);
1164             m_switches.append(SwitchRecord(jumpTable, i, defaultOffset, SwitchRecord::Character));
1165             jumpTable->ctiOffsets.grow(jumpTable->branchOffsets.size());
1166
1167             emitPutCTIArgFromVirtualRegister(scrutinee, 0, X86::ecx);
1168             emitPutCTIArgConstant(tableIndex, 4);
1169             emitCTICall(i, Interpreter::cti_op_switch_char);
1170             jump(X86::eax);
1171             i += OPCODE_LENGTH(op_switch_char);
1172             break;
1173         }
1174         case op_switch_string: {
1175             unsigned tableIndex = instruction[i + 1].u.operand;
1176             unsigned defaultOffset = instruction[i + 2].u.operand;
1177             unsigned scrutinee = instruction[i + 3].u.operand;
1178
1179             // create jump table for switch destinations, track this switch statement.
1180             StringJumpTable* jumpTable = &m_codeBlock->stringSwitchJumpTable(tableIndex);
1181             m_switches.append(SwitchRecord(jumpTable, i, defaultOffset));
1182
1183             emitPutCTIArgFromVirtualRegister(scrutinee, 0, X86::ecx);
1184             emitPutCTIArgConstant(tableIndex, 4);
1185             emitCTICall(i, Interpreter::cti_op_switch_string);
1186             jump(X86::eax);
1187             i += OPCODE_LENGTH(op_switch_string);
1188             break;
1189         }
1190         case op_del_by_val: {
1191             emitPutCTIArgFromVirtualRegister(instruction[i + 2].u.operand, 0, X86::ecx);
1192             emitPutCTIArgFromVirtualRegister(instruction[i + 3].u.operand, 4, X86::ecx);
1193             emitCTICall(i, Interpreter::cti_op_del_by_val);
1194             emitPutVirtualRegister(instruction[i + 1].u.operand);
1195             i += OPCODE_LENGTH(op_del_by_val);
1196             break;
1197         }
1198         case op_put_getter: {
1199             emitPutCTIArgFromVirtualRegister(instruction[i + 1].u.operand, 0, X86::ecx);
1200             Identifier* ident = &(m_codeBlock->identifier(instruction[i + 2].u.operand));
1201             emitPutCTIArgConstant(reinterpret_cast<unsigned>(ident), 4);
1202             emitPutCTIArgFromVirtualRegister(instruction[i + 3].u.operand, 8, X86::ecx);
1203             emitCTICall(i, Interpreter::cti_op_put_getter);
1204             i += OPCODE_LENGTH(op_put_getter);
1205             break;
1206         }
1207         case op_put_setter: {
1208             emitPutCTIArgFromVirtualRegister(instruction[i + 1].u.operand, 0, X86::ecx);
1209             Identifier* ident = &(m_codeBlock->identifier(instruction[i + 2].u.operand));
1210             emitPutCTIArgConstant(reinterpret_cast<unsigned>(ident), 4);
1211             emitPutCTIArgFromVirtualRegister(instruction[i + 3].u.operand, 8, X86::ecx);
1212             emitCTICall(i, Interpreter::cti_op_put_setter);
1213             i += OPCODE_LENGTH(op_put_setter);
1214             break;
1215         }
1216         case op_new_error: {
1217             JSValue* message = m_codeBlock->unexpectedConstant(instruction[i + 3].u.operand);
1218             emitPutCTIArgConstant(instruction[i + 2].u.operand, 0);
1219             emitPutCTIArgConstant(asInteger(message), 4);
1220             emitPutCTIArgConstant(m_codeBlock->lineNumberForVPC(&instruction[i]), 8);
1221             emitCTICall(i, Interpreter::cti_op_new_error);
1222             emitPutVirtualRegister(instruction[i + 1].u.operand);
1223             i += OPCODE_LENGTH(op_new_error);
1224             break;
1225         }
1226         case op_debug: {
1227             emitPutCTIArgConstant(instruction[i + 1].u.operand, 0);
1228             emitPutCTIArgConstant(instruction[i + 2].u.operand, 4);
1229             emitPutCTIArgConstant(instruction[i + 3].u.operand, 8);
1230             emitCTICall(i, Interpreter::cti_op_debug);
1231             i += OPCODE_LENGTH(op_debug);
1232             break;
1233         }
1234         case op_eq_null: {
1235             unsigned dst = instruction[i + 1].u.operand;
1236             unsigned src1 = instruction[i + 2].u.operand;
1237
1238             emitGetVirtualRegister(src1, X86::eax, i);
1239             Jump isImmediate = emitJumpIfNotJSCell(X86::eax);
1240
1241             loadPtr(Address(X86::eax, FIELD_OFFSET(JSCell, m_structure)), X86::ecx);
1242             setnz32(Address(X86::ecx, FIELD_OFFSET(Structure, m_typeInfo.m_flags)), Imm32(MasqueradesAsUndefined), X86::eax);
1243
1244             Jump wasNotImmediate = jump();
1245
1246             isImmediate.link(this);
1247
1248             and32(Imm32(~JSImmediate::ExtendedTagBitUndefined), X86::eax);
1249             sete32(Imm32(JSImmediate::FullTagTypeNull), X86::eax);
1250
1251             wasNotImmediate.link(this);
1252
1253             emitTagAsBoolImmediate(X86::eax);
1254             emitPutVirtualRegister(dst);
1255
1256             i += OPCODE_LENGTH(op_eq_null);
1257             break;
1258         }
1259         case op_neq_null: {
1260             unsigned dst = instruction[i + 1].u.operand;
1261             unsigned src1 = instruction[i + 2].u.operand;
1262
1263             emitGetVirtualRegister(src1, X86::eax, i);
1264             Jump isImmediate = emitJumpIfNotJSCell(X86::eax);
1265
1266             loadPtr(Address(X86::eax, FIELD_OFFSET(JSCell, m_structure)), X86::ecx);
1267             setz32(Address(X86::ecx, FIELD_OFFSET(Structure, m_typeInfo.m_flags)), Imm32(MasqueradesAsUndefined), X86::eax);
1268
1269             Jump wasNotImmediate = jump();
1270
1271             isImmediate.link(this);
1272
1273             and32(Imm32(~JSImmediate::ExtendedTagBitUndefined), X86::eax);
1274             setne32(Imm32(JSImmediate::FullTagTypeNull), X86::eax);
1275
1276             wasNotImmediate.link(this);
1277
1278             emitTagAsBoolImmediate(X86::eax);
1279             emitPutVirtualRegister(dst);
1280
1281             i += OPCODE_LENGTH(op_neq_null);
1282             break;
1283         }
1284         case op_enter: {
1285             // Even though CTI doesn't use them, we initialize our constant
1286             // registers to zap stale pointers, to avoid unnecessarily prolonging
1287             // object lifetime and increasing GC pressure.
1288             size_t count = m_codeBlock->m_numVars + m_codeBlock->numberOfConstantRegisters();
1289             for (size_t j = 0; j < count; ++j)
1290                 emitInitRegister(j);
1291
1292             i += OPCODE_LENGTH(op_enter);
1293             break;
1294         }
1295         case op_enter_with_activation: {
1296             // Even though CTI doesn't use them, we initialize our constant
1297             // registers to zap stale pointers, to avoid unnecessarily prolonging
1298             // object lifetime and increasing GC pressure.
1299             size_t count = m_codeBlock->m_numVars + m_codeBlock->numberOfConstantRegisters();
1300             for (size_t j = 0; j < count; ++j)
1301                 emitInitRegister(j);
1302
1303             emitCTICall(i, Interpreter::cti_op_push_activation);
1304             emitPutVirtualRegister(instruction[i + 1].u.operand);
1305
1306             i += OPCODE_LENGTH(op_enter_with_activation);
1307             break;
1308         }
1309         case op_create_arguments: {
1310             emitCTICall(i, (m_codeBlock->m_numParameters == 1) ? Interpreter::cti_op_create_arguments_no_params : Interpreter::cti_op_create_arguments);
1311             i += OPCODE_LENGTH(op_create_arguments);
1312             break;
1313         }
1314         case op_convert_this: {
1315             emitGetVirtualRegister(instruction[i + 1].u.operand, X86::eax, i);
1316
1317             emitJumpSlowCaseIfNotJSCell(X86::eax, i);
1318             loadPtr(Address(X86::eax, FIELD_OFFSET(JSCell, m_structure)), X86::edx);
1319             m_slowCases.append(SlowCaseEntry(jnz32(Address(X86::edx, FIELD_OFFSET(Structure, m_typeInfo.m_flags)), Imm32(NeedsThisConversion)), i));
1320
1321             i += OPCODE_LENGTH(op_convert_this);
1322             break;
1323         }
1324         case op_profile_will_call: {
1325             emitGetCTIParam(CTI_ARGS_profilerReference, X86::eax);
1326             __ cmpl_i32m(0, X86::eax);
1327             JmpSrc noProfiler = __ je();
1328             emitPutCTIArgFromVirtualRegister(instruction[i + 1].u.operand, 0, X86::eax);
1329             emitCTICall(i, Interpreter::cti_op_profile_will_call);
1330             __ link(noProfiler, __ label());
1331
1332             i += OPCODE_LENGTH(op_profile_will_call);
1333             break;
1334         }
1335         case op_profile_did_call: {
1336             emitGetCTIParam(CTI_ARGS_profilerReference, X86::eax);
1337             __ cmpl_i32m(0, X86::eax);
1338             JmpSrc noProfiler = __ je();
1339             emitPutCTIArgFromVirtualRegister(instruction[i + 1].u.operand, 0, X86::eax);
1340             emitCTICall(i, Interpreter::cti_op_profile_did_call);
1341             __ link(noProfiler, __ label());
1342
1343             i += OPCODE_LENGTH(op_profile_did_call);
1344             break;
1345         }
1346         case op_get_array_length:
1347         case op_get_by_id_chain:
1348         case op_get_by_id_generic:
1349         case op_get_by_id_proto:
1350         case op_get_by_id_proto_list:
1351         case op_get_by_id_self:
1352         case op_get_by_id_self_list:
1353         case op_get_string_length:
1354         case op_put_by_id_generic:
1355         case op_put_by_id_replace:
1356         case op_put_by_id_transition:
1357             ASSERT_NOT_REACHED();
1358         }
1359     }
1360
1361     ASSERT(propertyAccessInstructionIndex == m_codeBlock->numberOfPropertyAccessInstructions());
1362     ASSERT(callLinkInfoIndex == m_codeBlock->numberOfCallLinkInfos());
1363 }
1364
1365
1366 void JIT::privateCompileLinkPass()
1367 {
1368     unsigned jmpTableCount = m_jmpTable.size();
1369     for (unsigned i = 0; i < jmpTableCount; ++i)
1370         __ link(m_jmpTable[i].from, m_labels[m_jmpTable[i].to]);
1371     m_jmpTable.clear();
1372 }
1373
1374 #define CTI_COMPILE_BINARY_OP_SLOW_CASE(name) \
1375     case name: { \
1376         __ link(iter->from, __ label()); \
1377         emitPutCTIArgFromVirtualRegister(instruction[i + 2].u.operand, 0, X86::ecx); \
1378         emitPutCTIArgFromVirtualRegister(instruction[i + 3].u.operand, 4, X86::ecx); \
1379         emitCTICall(i, Interpreter::cti_##name); \
1380         emitPutVirtualRegister(instruction[i + 1].u.operand); \
1381         i += 4; \
1382         break; \
1383     }
1384     
1385 void JIT::privateCompileSlowCases()
1386 {
1387     unsigned propertyAccessInstructionIndex = 0;
1388     unsigned callLinkInfoIndex = 0;
1389
1390     Instruction* instruction = m_codeBlock->instructions().begin();
1391     for (Vector<SlowCaseEntry>::iterator iter = m_slowCases.begin(); iter != m_slowCases.end(); ++iter) {
1392         // FIXME: enable peephole optimizations for slow cases when applicable
1393         killLastResultRegister();
1394
1395         unsigned i = iter->to;
1396 #ifndef NDEBUG
1397         unsigned firstTo = i;
1398 #endif
1399
1400         switch (OpcodeID opcodeID = m_interpreter->getOpcodeID(instruction[i].u.opcode)) {
1401         case op_convert_this: {
1402             __ link(iter->from, __ label());
1403             __ link((++iter)->from, __ label());
1404             emitPutCTIArg(X86::eax, 0);
1405             emitCTICall(i, Interpreter::cti_op_convert_this);
1406             emitPutVirtualRegister(instruction[i + 1].u.operand);
1407             i += OPCODE_LENGTH(op_convert_this);
1408             break;
1409         }
1410         case op_add: {
1411             unsigned dst = instruction[i + 1].u.operand;
1412             unsigned src1 = instruction[i + 2].u.operand;
1413             unsigned src2 = instruction[i + 3].u.operand;
1414             if (JSValue* value = getConstantImmediateNumericArg(src1)) {
1415                 JmpSrc notImm = iter->from;
1416                 __ link((++iter)->from, __ label());
1417                 __ subl_i32r(getDeTaggedConstantImmediate(value), X86::eax);
1418                 __ link(notImm, __ label());
1419                 emitPutCTIArgFromVirtualRegister(src1, 0, X86::ecx);
1420                 emitPutCTIArg(X86::eax, 4);
1421                 emitCTICall(i, Interpreter::cti_op_add);
1422                 emitPutVirtualRegister(dst);
1423             } else if (JSValue* value = getConstantImmediateNumericArg(src2)) {
1424                 JmpSrc notImm = iter->from;
1425                 __ link((++iter)->from, __ label());
1426                 __ subl_i32r(getDeTaggedConstantImmediate(value), X86::eax);
1427                 __ link(notImm, __ label());
1428                 emitPutCTIArg(X86::eax, 0);
1429                 emitPutCTIArgFromVirtualRegister(src2, 4, X86::ecx);
1430                 emitCTICall(i, Interpreter::cti_op_add);
1431                 emitPutVirtualRegister(dst);
1432             } else {
1433                 OperandTypes types = OperandTypes::fromInt(instruction[i + 4].u.operand);
1434                 if (types.first().mightBeNumber() && types.second().mightBeNumber())
1435                     compileBinaryArithOpSlowCase(op_add, iter, dst, src1, src2, types, i);
1436                 else
1437                     ASSERT_NOT_REACHED();
1438             }
1439
1440             i += OPCODE_LENGTH(op_add);
1441             break;
1442         }
1443         case op_construct_verify: {
1444             __ link(iter->from, __ label());
1445             __ link((++iter)->from, __ label());
1446             emitGetVirtualRegister(instruction[i + 2].u.operand, X86::eax, i);
1447             emitPutVirtualRegister(instruction[i + 1].u.operand);
1448
1449             i += OPCODE_LENGTH(op_construct_verify);
1450             break;
1451         }
1452         case op_get_by_val: {
1453             // The slow case that handles accesses to arrays (below) may jump back up to here. 
1454             JmpDst beginGetByValSlow = __ label();
1455
1456             JmpSrc notImm = iter->from;
1457             __ link((++iter)->from, __ label());
1458             __ link((++iter)->from, __ label());
1459             emitFastArithIntToImmNoCheck(X86::edx);
1460             __ link(notImm, __ label());
1461             emitPutCTIArg(X86::eax, 0);
1462             emitPutCTIArg(X86::edx, 4);
1463             emitCTICall(i, Interpreter::cti_op_get_by_val);
1464             emitPutVirtualRegister(instruction[i + 1].u.operand);
1465             __ link(__ jmp(), m_labels[i + 4]);
1466
1467             // This is slow case that handles accesses to arrays above the fast cut-off.
1468             // First, check if this is an access to the vector
1469             __ link((++iter)->from, __ label());
1470             __ cmpl_rm(X86::edx, FIELD_OFFSET(ArrayStorage, m_vectorLength), X86::ecx);
1471             __ link(__ jbe(), beginGetByValSlow);
1472
1473             // okay, missed the fast region, but it is still in the vector.  Get the value.
1474             __ movl_mr(FIELD_OFFSET(ArrayStorage, m_vector[0]), X86::ecx, X86::edx, sizeof(JSValue*), X86::ecx);
1475             // Check whether the value loaded is zero; if so we need to return undefined.
1476             __ testl_rr(X86::ecx, X86::ecx);
1477             __ link(__ je(), beginGetByValSlow);
1478             __ movl_rr(X86::ecx, X86::eax);
1479             emitPutVirtualRegister(instruction[i + 1].u.operand, X86::eax);
1480
1481             i += OPCODE_LENGTH(op_get_by_val);
1482             break;
1483         }
1484         case op_sub: {
1485             compileBinaryArithOpSlowCase(op_sub, iter, instruction[i + 1].u.operand, instruction[i + 2].u.operand, instruction[i + 3].u.operand, OperandTypes::fromInt(instruction[i + 4].u.operand), i);
1486             i += OPCODE_LENGTH(op_sub);
1487             break;
1488         }
1489         case op_rshift: {
1490             unsigned src2 = instruction[i + 3].u.operand;
1491             __ link(iter->from, __ label());
1492             if (getConstantImmediateNumericArg(src2))
1493                 emitPutCTIArgFromVirtualRegister(src2, 4, X86::ecx);
1494             else {
1495                 __ link((++iter)->from, __ label());
1496                 emitPutCTIArg(X86::ecx, 4);
1497             }
1498
1499             emitPutCTIArg(X86::eax, 0);
1500             emitCTICall(i, Interpreter::cti_op_rshift);
1501             emitPutVirtualRegister(instruction[i + 1].u.operand);
1502             i += OPCODE_LENGTH(op_rshift);
1503             break;
1504         }
1505         case op_lshift: {
1506             JmpSrc notImm1 = iter->from;
1507             JmpSrc notImm2 = (++iter)->from;
1508             __ link((++iter)->from, __ label());
1509             emitGetVirtualRegisters(instruction[i + 2].u.operand, X86::eax, instruction[i + 3].u.operand, X86::ecx, i);
1510             __ link(notImm1, __ label());
1511             __ link(notImm2, __ label());
1512             emitPutCTIArg(X86::eax, 0);
1513             emitPutCTIArg(X86::ecx, 4);
1514             emitCTICall(i, Interpreter::cti_op_lshift);
1515             emitPutVirtualRegister(instruction[i + 1].u.operand);
1516             i += OPCODE_LENGTH(op_lshift);
1517             break;
1518         }
1519         case op_loop_if_less: {
1520             unsigned target = instruction[i + 3].u.operand;
1521             JSValue* src2imm = getConstantImmediateNumericArg(instruction[i + 2].u.operand);
1522             if (src2imm) {
1523                 __ link(iter->from, __ label());
1524                 emitPutCTIArg(X86::eax, 0);
1525                 emitPutCTIArgFromVirtualRegister(instruction[i + 2].u.operand, 4, X86::ecx);
1526                 emitCTICall(i, Interpreter::cti_op_loop_if_less);
1527                 __ testl_rr(X86::eax, X86::eax);
1528                 __ link(__ jne(), m_labels[i + 3 + target]);
1529             } else {
1530                 __ link(iter->from, __ label());
1531                 __ link((++iter)->from, __ label());
1532                 emitPutCTIArg(X86::eax, 0);
1533                 emitPutCTIArg(X86::edx, 4);
1534                 emitCTICall(i, Interpreter::cti_op_loop_if_less);
1535                 __ testl_rr(X86::eax, X86::eax);
1536                 __ link(__ jne(), m_labels[i + 3 + target]);
1537             }
1538             i += OPCODE_LENGTH(op_loop_if_less);
1539             break;
1540         }
1541         case op_put_by_id: {
1542             compilePutByIdSlowCase(instruction[i + 1].u.operand, &(m_codeBlock->identifier(instruction[i + 2].u.operand)), instruction[i + 3].u.operand, i, iter, propertyAccessInstructionIndex++);
1543             i += OPCODE_LENGTH(op_put_by_id);
1544             break;
1545         }
1546         case op_get_by_id: {
1547             compileGetByIdSlowCase(instruction[i + 1].u.operand, instruction[i + 2].u.operand, &(m_codeBlock->identifier(instruction[i + 3].u.operand)), i, iter, propertyAccessInstructionIndex++);
1548             i += OPCODE_LENGTH(op_get_by_id);
1549             break;
1550         }
1551         case op_loop_if_lesseq: {
1552             unsigned target = instruction[i + 3].u.operand;
1553             JSValue* src2imm = getConstantImmediateNumericArg(instruction[i + 2].u.operand);
1554             if (src2imm) {
1555                 __ link(iter->from, __ label());
1556                 emitPutCTIArg(X86::eax, 0);
1557                 emitPutCTIArgFromVirtualRegister(instruction[i + 2].u.operand, 4, X86::ecx);
1558                 emitCTICall(i, Interpreter::cti_op_loop_if_lesseq);
1559                 __ testl_rr(X86::eax, X86::eax);
1560                 __ link(__ jne(), m_labels[i + 3 + target]);
1561             } else {
1562                 __ link(iter->from, __ label());
1563                 __ link((++iter)->from, __ label());
1564                 emitPutCTIArg(X86::eax, 0);
1565                 emitPutCTIArg(X86::edx, 4);
1566                 emitCTICall(i, Interpreter::cti_op_loop_if_lesseq);
1567                 __ testl_rr(X86::eax, X86::eax);
1568                 __ link(__ jne(), m_labels[i + 3 + target]);
1569             }
1570             i += OPCODE_LENGTH(op_loop_if_lesseq);
1571             break;
1572         }
1573         case op_pre_inc: {
1574             unsigned srcDst = instruction[i + 1].u.operand;
1575             JmpSrc notImm = iter->from;
1576             __ link((++iter)->from, __ label());
1577             __ subl_i8r(getDeTaggedConstantImmediate(JSImmediate::oneImmediate()), X86::eax);
1578             __ link(notImm, __ label());
1579             emitPutCTIArg(X86::eax, 0);
1580             emitCTICall(i, Interpreter::cti_op_pre_inc);
1581             emitPutVirtualRegister(srcDst);
1582             i += OPCODE_LENGTH(op_pre_inc);
1583             break;
1584         }
1585         case op_put_by_val: {
1586             // Normal slow cases - either is not an immediate imm, or is an array.
1587             JmpSrc notImm = iter->from;
1588             __ link((++iter)->from, __ label());
1589             __ link((++iter)->from, __ label());
1590             emitFastArithIntToImmNoCheck(X86::edx);
1591             __ link(notImm, __ label());
1592             emitGetVirtualRegister(instruction[i + 3].u.operand, X86::ecx, i);
1593             emitPutCTIArg(X86::eax, 0);
1594             emitPutCTIArg(X86::edx, 4);
1595             emitPutCTIArg(X86::ecx, 8);
1596             emitCTICall(i, Interpreter::cti_op_put_by_val);
1597             __ link(__ jmp(), m_labels[i + 4]);
1598
1599             // slow cases for immediate int accesses to arrays
1600             __ link((++iter)->from, __ label());
1601             __ link((++iter)->from, __ label());
1602             emitGetVirtualRegister(instruction[i + 3].u.operand, X86::ecx, i);
1603             emitPutCTIArg(X86::eax, 0);
1604             emitPutCTIArg(X86::edx, 4);
1605             emitPutCTIArg(X86::ecx, 8);
1606             emitCTICall(i, Interpreter::cti_op_put_by_val_array);
1607
1608             i += OPCODE_LENGTH(op_put_by_val);
1609             break;
1610         }
1611         case op_loop_if_true: {
1612             __ link(iter->from, __ label());
1613             emitPutCTIArg(X86::eax, 0);
1614             emitCTICall(i, Interpreter::cti_op_jtrue);
1615             __ testl_rr(X86::eax, X86::eax);
1616             unsigned target = instruction[i + 2].u.operand;
1617             __ link(__ jne(), m_labels[i + 2 + target]);
1618             i += OPCODE_LENGTH(op_loop_if_true);
1619             break;
1620         }
1621         case op_pre_dec: {
1622             unsigned srcDst = instruction[i + 1].u.operand;
1623             JmpSrc notImm = iter->from;
1624             __ link((++iter)->from, __ label());
1625             __ addl_i8r(getDeTaggedConstantImmediate(JSImmediate::oneImmediate()), X86::eax);
1626             __ link(notImm, __ label());
1627             emitPutCTIArg(X86::eax, 0);
1628             emitCTICall(i, Interpreter::cti_op_pre_dec);
1629             emitPutVirtualRegister(srcDst);
1630             i += OPCODE_LENGTH(op_pre_dec);
1631             break;
1632         }
1633         case op_jnless: {
1634             unsigned target = instruction[i + 3].u.operand;
1635             JSValue* src2imm = getConstantImmediateNumericArg(instruction[i + 2].u.operand);
1636             if (src2imm) {
1637                 __ link(iter->from, __ label());
1638                 emitPutCTIArg(X86::edx, 0);
1639                 emitPutCTIArgFromVirtualRegister(instruction[i + 2].u.operand, 4, X86::ecx);
1640                 emitCTICall(i, Interpreter::cti_op_jless);
1641                 __ testl_rr(X86::eax, X86::eax);
1642                 __ link(__ je(), m_labels[i + 3 + target]);
1643             } else {
1644                 __ link(iter->from, __ label());
1645                 __ link((++iter)->from, __ label());
1646                 emitPutCTIArg(X86::eax, 0);
1647                 emitPutCTIArg(X86::edx, 4);
1648                 emitCTICall(i, Interpreter::cti_op_jless);
1649                 __ testl_rr(X86::eax, X86::eax);
1650                 __ link(__ je(), m_labels[i + 3 + target]);
1651             }
1652             i += OPCODE_LENGTH(op_jnless);
1653             break;
1654         }
1655         case op_not: {
1656             __ link(iter->from, __ label());
1657             __ xorl_i8r(JSImmediate::FullTagTypeBool, X86::eax);
1658             emitPutCTIArg(X86::eax, 0);
1659             emitCTICall(i, Interpreter::cti_op_not);
1660             emitPutVirtualRegister(instruction[i + 1].u.operand);
1661             i += OPCODE_LENGTH(op_not);
1662             break;
1663         }
1664         case op_jfalse: {
1665             __ link(iter->from, __ label());
1666             emitPutCTIArg(X86::eax, 0);
1667             emitCTICall(i, Interpreter::cti_op_jtrue);
1668             __ testl_rr(X86::eax, X86::eax);
1669             unsigned target = instruction[i + 2].u.operand;
1670             __ link(__ je(), m_labels[i + 2 + target]); // inverted!
1671             i += OPCODE_LENGTH(op_jfalse);
1672             break;
1673         }
1674         case op_post_inc: {
1675             unsigned srcDst = instruction[i + 2].u.operand;
1676             __ link(iter->from, __ label());
1677             __ link((++iter)->from, __ label());
1678             emitPutCTIArg(X86::eax, 0);
1679             emitCTICall(i, Interpreter::cti_op_post_inc);
1680             emitPutVirtualRegister(srcDst, X86::edx);
1681             emitPutVirtualRegister(instruction[i + 1].u.operand);
1682             i += OPCODE_LENGTH(op_post_inc);
1683             break;
1684         }
1685         case op_bitnot: {
1686             __ link(iter->from, __ label());
1687             emitPutCTIArg(X86::eax, 0);
1688             emitCTICall(i, Interpreter::cti_op_bitnot);
1689             emitPutVirtualRegister(instruction[i + 1].u.operand);
1690             i += OPCODE_LENGTH(op_bitnot);
1691             break;
1692         }
1693         case op_bitand: {
1694             unsigned src1 = instruction[i + 2].u.operand;
1695             unsigned src2 = instruction[i + 3].u.operand;
1696             unsigned dst = instruction[i + 1].u.operand;
1697             if (getConstantImmediateNumericArg(src1)) {
1698                 __ link(iter->from, __ label());
1699                 emitPutCTIArgFromVirtualRegister(src1, 0, X86::ecx);
1700                 emitPutCTIArg(X86::eax, 4);
1701                 emitCTICall(i, Interpreter::cti_op_bitand);
1702                 emitPutVirtualRegister(dst);
1703             } else if (getConstantImmediateNumericArg(src2)) {
1704                 __ link(iter->from, __ label());
1705                 emitPutCTIArg(X86::eax, 0);
1706                 emitPutCTIArgFromVirtualRegister(src2, 4, X86::ecx);
1707                 emitCTICall(i, Interpreter::cti_op_bitand);
1708                 emitPutVirtualRegister(dst);
1709             } else {
1710                 __ link(iter->from, __ label());
1711                 emitPutCTIArgFromVirtualRegister(src1, 0, X86::ecx);
1712                 emitPutCTIArg(X86::edx, 4);
1713                 emitCTICall(i, Interpreter::cti_op_bitand);
1714                 emitPutVirtualRegister(dst);
1715             }
1716             i += OPCODE_LENGTH(op_bitand);
1717             break;
1718         }
1719         case op_jtrue: {
1720             __ link(iter->from, __ label());
1721             emitPutCTIArg(X86::eax, 0);
1722             emitCTICall(i, Interpreter::cti_op_jtrue);
1723             __ testl_rr(X86::eax, X86::eax);
1724             unsigned target = instruction[i + 2].u.operand;
1725             __ link(__ jne(), m_labels[i + 2 + target]);
1726             i += OPCODE_LENGTH(op_jtrue);
1727             break;
1728         }
1729         case op_post_dec: {
1730             unsigned srcDst = instruction[i + 2].u.operand;
1731             __ link(iter->from, __ label());
1732             __ link((++iter)->from, __ label());
1733             emitPutCTIArg(X86::eax, 0);
1734             emitCTICall(i, Interpreter::cti_op_post_dec);
1735             emitPutVirtualRegister(srcDst, X86::edx);
1736             emitPutVirtualRegister(instruction[i + 1].u.operand);
1737             i += OPCODE_LENGTH(op_post_dec);
1738             break;
1739         }
1740         case op_bitxor: {
1741             __ link(iter->from, __ label());
1742             emitPutCTIArg(X86::eax, 0);
1743             emitPutCTIArg(X86::edx, 4);
1744             emitCTICall(i, Interpreter::cti_op_bitxor);
1745             emitPutVirtualRegister(instruction[i + 1].u.operand);
1746             i += OPCODE_LENGTH(op_bitxor);
1747             break;
1748         }
1749         case op_bitor: {
1750             __ link(iter->from, __ label());
1751             emitPutCTIArg(X86::eax, 0);
1752             emitPutCTIArg(X86::edx, 4);
1753             emitCTICall(i, Interpreter::cti_op_bitor);
1754             emitPutVirtualRegister(instruction[i + 1].u.operand);
1755             i += OPCODE_LENGTH(op_bitor);
1756             break;
1757         }
1758         case op_eq: {
1759             __ link(iter->from, __ label());
1760             emitPutCTIArg(X86::eax, 0);
1761             emitPutCTIArg(X86::edx, 4);
1762             emitCTICall(i, Interpreter::cti_op_eq);
1763             emitPutVirtualRegister(instruction[i + 1].u.operand);
1764             i += OPCODE_LENGTH(op_eq);
1765             break;
1766         }
1767         case op_neq: {
1768             __ link(iter->from, __ label());
1769             emitPutCTIArg(X86::eax, 0);
1770             emitPutCTIArg(X86::edx, 4);
1771             emitCTICall(i, Interpreter::cti_op_neq);
1772             emitPutVirtualRegister(instruction[i + 1].u.operand);
1773             i += OPCODE_LENGTH(op_neq);
1774             break;
1775         }
1776         case op_stricteq: {
1777             __ link(iter->from, __ label());
1778             __ link((++iter)->from, __ label());
1779             __ link((++iter)->from, __ label());
1780             emitPutCTIArg(X86::eax, 0);
1781             emitPutCTIArg(X86::edx, 4);
1782             emitCTICall(i, Interpreter::cti_op_stricteq);
1783             emitPutVirtualRegister(instruction[i + 1].u.operand);
1784             i += OPCODE_LENGTH(op_stricteq);
1785             break;
1786         }
1787         case op_nstricteq: {
1788             __ link(iter->from, __ label());
1789             __ link((++iter)->from, __ label());
1790             __ link((++iter)->from, __ label());
1791             emitPutCTIArg(X86::eax, 0);
1792             emitPutCTIArg(X86::edx, 4);
1793             emitCTICall(i, Interpreter::cti_op_nstricteq);
1794             emitPutVirtualRegister(instruction[i + 1].u.operand);
1795             i += OPCODE_LENGTH(op_nstricteq);
1796             break;
1797         }
1798         case op_instanceof: {
1799             __ link(iter->from, __ label());
1800             __ link((++iter)->from, __ label());
1801             __ link((++iter)->from, __ label());
1802             emitPutCTIArgFromVirtualRegister(instruction[i + 2].u.operand, 0, X86::ecx);
1803             emitPutCTIArgFromVirtualRegister(instruction[i + 3].u.operand, 4, X86::ecx);
1804             emitPutCTIArgFromVirtualRegister(instruction[i + 4].u.operand, 8, X86::ecx);
1805             emitCTICall(i, Interpreter::cti_op_instanceof);
1806             emitPutVirtualRegister(instruction[i + 1].u.operand);
1807             i += OPCODE_LENGTH(op_instanceof);
1808             break;
1809         }
1810         case op_mod: {
1811             JmpSrc notImm1 = iter->from;
1812             JmpSrc notImm2 = (++iter)->from;
1813             __ link((++iter)->from, __ label());
1814             emitFastArithReTagImmediate(X86::eax);
1815             emitFastArithReTagImmediate(X86::ecx);
1816             __ link(notImm1, __ label());
1817             __ link(notImm2, __ label());
1818             emitPutCTIArg(X86::eax, 0);
1819             emitPutCTIArg(X86::ecx, 4);
1820             emitCTICall(i, Interpreter::cti_op_mod);
1821             emitPutVirtualRegister(instruction[i + 1].u.operand);
1822             i += OPCODE_LENGTH(op_mod);
1823             break;
1824         }
1825         case op_mul: {
1826             int dst = instruction[i + 1].u.operand;
1827             int src1 = instruction[i + 2].u.operand;
1828             int src2 = instruction[i + 3].u.operand;
1829             JSValue* src1Value = getConstantImmediateNumericArg(src1);
1830             JSValue* src2Value = getConstantImmediateNumericArg(src2);
1831             int32_t value;
1832             if (src1Value && ((value = JSImmediate::intValue(src1Value)) > 0)) {
1833                 __ link(iter->from, __ label());
1834                 __ link((++iter)->from, __ label());
1835                 // There is an extra slow case for (op1 * -N) or (-N * op2), to check for 0 since this should produce a result of -0.
1836                 emitPutCTIArgFromVirtualRegister(src1, 0, X86::ecx);
1837                 emitPutCTIArgFromVirtualRegister(src2, 4, X86::ecx);
1838                 emitCTICall(i, Interpreter::cti_op_mul);
1839                 emitPutVirtualRegister(dst);
1840             } else if (src2Value && ((value = JSImmediate::intValue(src2Value)) > 0)) {
1841                 __ link(iter->from, __ label());
1842                 __ link((++iter)->from, __ label());
1843                 // There is an extra slow case for (op1 * -N) or (-N * op2), to check for 0 since this should produce a result of -0.
1844                 emitPutCTIArgFromVirtualRegister(src1, 0, X86::ecx);
1845                 emitPutCTIArgFromVirtualRegister(src2, 4, X86::ecx);
1846                 emitCTICall(i, Interpreter::cti_op_mul);
1847                 emitPutVirtualRegister(dst);
1848             } else
1849                 compileBinaryArithOpSlowCase(op_mul, iter, dst, src1, src2, OperandTypes::fromInt(instruction[i + 4].u.operand), i);
1850             i += OPCODE_LENGTH(op_mul);
1851             break;
1852         }
1853
1854         case op_call:
1855         case op_call_eval:
1856         case op_construct: {
1857             compileOpCallSlowCase(instruction + i, i, iter, callLinkInfoIndex++, opcodeID);
1858             i += (opcodeID == op_construct ? OPCODE_LENGTH(op_construct) : OPCODE_LENGTH(op_call));
1859             break;
1860         }
1861         case op_to_jsnumber: {
1862             if (linkSlowCaseIfNotJSCell(iter, instruction[i + 2].u.operand))
1863                 ++iter;
1864             __ link(iter->from, __ label());
1865
1866             emitPutCTIArg(X86::eax, 0);
1867             emitCTICall(i, Interpreter::cti_op_to_jsnumber);
1868
1869             emitPutVirtualRegister(instruction[i + 1].u.operand);
1870             i += OPCODE_LENGTH(op_to_jsnumber);
1871             break;
1872         }
1873
1874         default:
1875             ASSERT_NOT_REACHED();
1876             break;
1877         }
1878
1879         ASSERT_WITH_MESSAGE((iter + 1) == m_slowCases.end() || firstTo != (iter + 1)->to,"Not enough jumps linked in slow case codegen.");
1880         ASSERT_WITH_MESSAGE(firstTo == iter->to, "Too many jumps linked in slow case codegen.");
1881
1882         __ link(__ jmp(), m_labels[i]);
1883     }
1884
1885     ASSERT(propertyAccessInstructionIndex == m_codeBlock->numberOfPropertyAccessInstructions());
1886     ASSERT(callLinkInfoIndex == m_codeBlock->numberOfCallLinkInfos());
1887 }
1888
1889 void JIT::privateCompile()
1890 {
1891 #if ENABLE(CODEBLOCK_SAMPLING)
1892         __ movl_i32m(reinterpret_cast<unsigned>(m_codeBlock), m_interpreter->sampler()->codeBlockSlot());
1893 #endif
1894 #if ENABLE(OPCODE_SAMPLING)
1895         __ movl_i32m(m_interpreter->sampler()->encodeSample(m_codeBlock->instructions().begin()), m_interpreter->sampler()->sampleSlot());
1896 #endif
1897
1898     // Could use a popl_m, but would need to offset the following instruction if so.
1899     __ popl_r(X86::ecx);
1900     emitPutToCallFrameHeader(X86::ecx, RegisterFile::ReturnPC);
1901
1902     JmpSrc slowRegisterFileCheck;
1903     JmpDst afterRegisterFileCheck;
1904     if (m_codeBlock->codeType() == FunctionCode) {
1905         // In the case of a fast linked call, we do not set this up in the caller.
1906         emitPutImmediateToCallFrameHeader(m_codeBlock, RegisterFile::CodeBlock);
1907
1908         emitGetCTIParam(CTI_ARGS_registerFile, X86::eax);
1909         __ leal_mr(m_codeBlock->m_numCalleeRegisters * sizeof(Register), X86::edi, X86::edx);
1910         __ cmpl_mr(FIELD_OFFSET(RegisterFile, m_end), X86::eax, X86::edx);
1911         slowRegisterFileCheck = __ jg();
1912         afterRegisterFileCheck = __ label();
1913     }
1914
1915     privateCompileMainPass();
1916     privateCompileLinkPass();
1917     privateCompileSlowCases();
1918
1919     if (m_codeBlock->codeType() == FunctionCode) {
1920         __ link(slowRegisterFileCheck, __ label());
1921         emitCTICall(0, Interpreter::cti_register_file_check);
1922         JmpSrc backToBody = __ jmp();
1923         __ link(backToBody, afterRegisterFileCheck);
1924     }
1925
1926     ASSERT(m_jmpTable.isEmpty());
1927
1928     RefPtr<ExecutablePool> allocator = m_globalData->poolForSize(__ size());
1929     m_codeBlock->setExecutablePool(allocator.get());
1930     void* code = __ executableCopy(allocator.get());
1931
1932     // Translate vPC offsets into addresses in JIT generated code, for switch tables.
1933     for (unsigned i = 0; i < m_switches.size(); ++i) {
1934         SwitchRecord record = m_switches[i];
1935         unsigned bytecodeIndex = record.bytecodeIndex;
1936
1937         if (record.type != SwitchRecord::String) {
1938             ASSERT(record.type == SwitchRecord::Immediate || record.type == SwitchRecord::Character); 
1939             ASSERT(record.jumpTable.simpleJumpTable->branchOffsets.size() == record.jumpTable.simpleJumpTable->ctiOffsets.size());
1940
1941             record.jumpTable.simpleJumpTable->ctiDefault = __ getRelocatedAddress(code, m_labels[bytecodeIndex + 3 + record.defaultOffset]);
1942
1943             for (unsigned j = 0; j < record.jumpTable.simpleJumpTable->branchOffsets.size(); ++j) {
1944                 unsigned offset = record.jumpTable.simpleJumpTable->branchOffsets[j];
1945                 record.jumpTable.simpleJumpTable->ctiOffsets[j] = offset ? __ getRelocatedAddress(code, m_labels[bytecodeIndex + 3 + offset]) : record.jumpTable.simpleJumpTable->ctiDefault;
1946             }
1947         } else {
1948             ASSERT(record.type == SwitchRecord::String);
1949
1950             record.jumpTable.stringJumpTable->ctiDefault = __ getRelocatedAddress(code, m_labels[bytecodeIndex + 3 + record.defaultOffset]);
1951
1952             StringJumpTable::StringOffsetTable::iterator end = record.jumpTable.stringJumpTable->offsetTable.end();            
1953             for (StringJumpTable::StringOffsetTable::iterator it = record.jumpTable.stringJumpTable->offsetTable.begin(); it != end; ++it) {
1954                 unsigned offset = it->second.branchOffset;
1955                 it->second.ctiOffset = offset ? __ getRelocatedAddress(code, m_labels[bytecodeIndex + 3 + offset]) : record.jumpTable.stringJumpTable->ctiDefault;
1956             }
1957         }
1958     }
1959
1960     for (size_t i = 0; i < m_codeBlock->numberOfExceptionHandlers(); ++i) {
1961         HandlerInfo& handler = m_codeBlock->exceptionHandler(i);
1962         handler.nativeCode = __ getRelocatedAddress(code, m_labels[handler.target]);
1963     }
1964
1965     m_codeBlock->pcVector().reserveCapacity(m_calls.size());
1966     for (Vector<CallRecord>::iterator iter = m_calls.begin(); iter != m_calls.end(); ++iter) {
1967         if (iter->to)
1968             X86Assembler::link(code, iter->from, iter->to);
1969         m_codeBlock->pcVector().append(PC(__ getRelocatedAddress(code, iter->from), iter->bytecodeIndex));
1970     }
1971
1972     // Link absolute addresses for jsr
1973     for (Vector<JSRInfo>::iterator iter = m_jsrSites.begin(); iter != m_jsrSites.end(); ++iter)
1974         X86Assembler::linkAbsoluteAddress(code, iter->addrPosition, iter->target);
1975
1976     for (unsigned i = 0; i < m_codeBlock->numberOfPropertyAccessInstructions(); ++i) {
1977         StructureStubInfo& info = m_codeBlock->propertyAccessInstruction(i);
1978         info.callReturnLocation = X86Assembler::getRelocatedAddress(code, m_propertyAccessCompilationInfo[i].callReturnLocation);
1979         info.hotPathBegin = X86Assembler::getRelocatedAddress(code, m_propertyAccessCompilationInfo[i].hotPathBegin);
1980     }
1981     for (unsigned i = 0; i < m_codeBlock->numberOfCallLinkInfos(); ++i) {
1982         CallLinkInfo& info = m_codeBlock->callLinkInfo(i);
1983         info.callReturnLocation = X86Assembler::getRelocatedAddress(code, m_callStructureStubCompilationInfo[i].callReturnLocation);
1984         info.hotPathBegin = X86Assembler::getRelocatedAddress(code, m_callStructureStubCompilationInfo[i].hotPathBegin);
1985         info.hotPathOther = X86Assembler::getRelocatedAddress(code, m_callStructureStubCompilationInfo[i].hotPathOther);
1986         info.coldPathOther = X86Assembler::getRelocatedAddress(code, m_callStructureStubCompilationInfo[i].coldPathOther);
1987     }
1988
1989     m_codeBlock->setJITCode(code);
1990 }
1991
1992 void JIT::privateCompileCTIMachineTrampolines()
1993 {
1994     // (1) The first function provides fast property access for array length
1995     
1996     // Check eax is an array
1997     JmpSrc array_failureCases1 = emitJumpIfNotJSCell(X86::eax);
1998     __ cmpl_i32m(reinterpret_cast<unsigned>(m_interpreter->m_jsArrayVptr), X86::eax);
1999     JmpSrc array_failureCases2 = __ jne();
2000
2001     // Checks out okay! - get the length from the storage
2002     __ movl_mr(FIELD_OFFSET(JSArray, m_storage), X86::eax, X86::eax);
2003     __ movl_mr(FIELD_OFFSET(ArrayStorage, m_length), X86::eax, X86::eax);
2004
2005     __ cmpl_i32r(JSImmediate::maxImmediateInt, X86::eax);
2006     JmpSrc array_failureCases3 = __ ja();
2007
2008     __ addl_rr(X86::eax, X86::eax);
2009     __ addl_i8r(1, X86::eax);
2010     
2011     __ ret();
2012
2013     // (2) The second function provides fast property access for string length
2014     
2015     JmpDst stringLengthBegin = __ align(16);
2016
2017     // Check eax is a string
2018     JmpSrc string_failureCases1 = emitJumpIfNotJSCell(X86::eax);
2019     __ cmpl_i32m(reinterpret_cast<unsigned>(m_interpreter->m_jsStringVptr), X86::eax);
2020     JmpSrc string_failureCases2 = __ jne();
2021
2022     // Checks out okay! - get the length from the Ustring.
2023     __ movl_mr(FIELD_OFFSET(JSString, m_value) + FIELD_OFFSET(UString, m_rep), X86::eax, X86::eax);
2024     __ movl_mr(FIELD_OFFSET(UString::Rep, len), X86::eax, X86::eax);
2025
2026     __ cmpl_i32r(JSImmediate::maxImmediateInt, X86::eax);
2027     JmpSrc string_failureCases3 = __ ja();
2028
2029     __ addl_rr(X86::eax, X86::eax);
2030     __ addl_i8r(1, X86::eax);
2031     
2032     __ ret();
2033
2034     // (3) Trampolines for the slow cases of op_call / op_call_eval / op_construct.
2035     
2036     JmpDst virtualCallPreLinkBegin = __ align(16);
2037
2038     // Load the callee CodeBlock* into eax
2039     __ movl_mr(FIELD_OFFSET(JSFunction, m_body), X86::ecx, X86::eax);
2040     __ movl_mr(FIELD_OFFSET(FunctionBodyNode, m_code), X86::eax, X86::eax);
2041     __ testl_rr(X86::eax, X86::eax);
2042     JmpSrc hasCodeBlock1 = __ jne();
2043     __ popl_r(X86::ebx);
2044     restoreArgumentReference();
2045     emitPutCTIParam(X86::edi, CTI_ARGS_callFrame);
2046     JmpSrc callJSFunction1 = __ call();
2047     emitGetCTIArg(0, X86::ecx);
2048     emitGetCTIArg(8, X86::edx);
2049     __ pushl_r(X86::ebx);
2050     __ link(hasCodeBlock1, __ label());
2051
2052     // Check argCount matches callee arity.
2053     __ cmpl_rm(X86::edx, FIELD_OFFSET(CodeBlock, m_numParameters), X86::eax);
2054     JmpSrc arityCheckOkay1 = __ je();
2055     __ popl_r(X86::ebx);
2056     emitPutCTIArg(X86::ebx, 4);
2057     emitPutCTIArg(X86::eax, 12);
2058     restoreArgumentReference();
2059     emitPutCTIParam(X86::edi, CTI_ARGS_callFrame);
2060     JmpSrc callArityCheck1 = __ call();
2061     __ movl_rr(X86::edx, X86::edi);
2062     emitGetCTIArg(0, X86::ecx);
2063     emitGetCTIArg(8, X86::edx);
2064     __ pushl_r(X86::ebx);
2065     __ link(arityCheckOkay1, __ label());
2066
2067     compileOpCallInitializeCallFrame();
2068
2069     __ popl_r(X86::ebx);
2070     emitPutCTIArg(X86::ebx, 4);
2071     restoreArgumentReference();
2072     emitPutCTIParam(X86::edi, CTI_ARGS_callFrame);
2073     JmpSrc callDontLazyLinkCall = __ call();
2074     __ pushl_r(X86::ebx);
2075
2076     __ jmp_r(X86::eax);
2077
2078     JmpDst virtualCallLinkBegin = __ align(16);
2079
2080     // Load the callee CodeBlock* into eax
2081     __ movl_mr(FIELD_OFFSET(JSFunction, m_body), X86::ecx, X86::eax);
2082     __ movl_mr(FIELD_OFFSET(FunctionBodyNode, m_code), X86::eax, X86::eax);
2083     __ testl_rr(X86::eax, X86::eax);
2084     JmpSrc hasCodeBlock2 = __ jne();
2085     __ popl_r(X86::ebx);
2086     restoreArgumentReference();
2087     emitPutCTIParam(X86::edi, CTI_ARGS_callFrame);
2088     JmpSrc callJSFunction2 = __ call();
2089     emitGetCTIArg(0, X86::ecx);
2090     emitGetCTIArg(8, X86::edx);
2091     __ pushl_r(X86::ebx);
2092     __ link(hasCodeBlock2, __ label());
2093
2094     // Check argCount matches callee arity.
2095     __ cmpl_rm(X86::edx, FIELD_OFFSET(CodeBlock, m_numParameters), X86::eax);
2096     JmpSrc arityCheckOkay2 = __ je();
2097     __ popl_r(X86::ebx);
2098     emitPutCTIArg(X86::ebx, 4);
2099     emitPutCTIArg(X86::eax, 12);
2100     restoreArgumentReference();
2101     emitPutCTIParam(X86::edi, CTI_ARGS_callFrame);
2102     JmpSrc callArityCheck2 = __ call();
2103     __ movl_rr(X86::edx, X86::edi);
2104     emitGetCTIArg(0, X86::ecx);
2105     emitGetCTIArg(8, X86::edx);
2106     __ pushl_r(X86::ebx);
2107     __ link(arityCheckOkay2, __ label());
2108
2109     compileOpCallInitializeCallFrame();
2110
2111     __ popl_r(X86::ebx);
2112     emitPutCTIArg(X86::ebx, 4);
2113     restoreArgumentReference();
2114     emitPutCTIParam(X86::edi, CTI_ARGS_callFrame);
2115     JmpSrc callLazyLinkCall = __ call();
2116     __ pushl_r(X86::ebx);
2117
2118     __ jmp_r(X86::eax);
2119
2120     JmpDst virtualCallBegin = __ align(16);
2121
2122     // Load the callee CodeBlock* into eax
2123     __ movl_mr(FIELD_OFFSET(JSFunction, m_body), X86::ecx, X86::eax);
2124     __ movl_mr(FIELD_OFFSET(FunctionBodyNode, m_code), X86::eax, X86::eax);
2125     __ testl_rr(X86::eax, X86::eax);
2126     JmpSrc hasCodeBlock3 = __ jne();
2127     __ popl_r(X86::ebx);
2128     restoreArgumentReference();
2129     emitPutCTIParam(X86::edi, CTI_ARGS_callFrame);
2130     JmpSrc callJSFunction3 = __ call();
2131     emitGetCTIArg(0, X86::ecx);
2132     emitGetCTIArg(8, X86::edx);
2133     __ pushl_r(X86::ebx);
2134     __ link(hasCodeBlock3, __ label());
2135
2136     // Check argCount matches callee arity.
2137     __ cmpl_rm(X86::edx, FIELD_OFFSET(CodeBlock, m_numParameters), X86::eax);
2138     JmpSrc arityCheckOkay3 = __ je();
2139     __ popl_r(X86::ebx);
2140     emitPutCTIArg(X86::ebx, 4);
2141     emitPutCTIArg(X86::eax, 12);
2142     restoreArgumentReference();
2143     emitPutCTIParam(X86::edi, CTI_ARGS_callFrame);
2144     JmpSrc callArityCheck3 = __ call();
2145     __ movl_rr(X86::edx, X86::edi);
2146     emitGetCTIArg(0, X86::ecx);
2147     emitGetCTIArg(8, X86::edx);
2148     __ pushl_r(X86::ebx);
2149     __ link(arityCheckOkay3, __ label());
2150
2151     compileOpCallInitializeCallFrame();
2152
2153     // load ctiCode from the new codeBlock.
2154     __ movl_mr(FIELD_OFFSET(CodeBlock, m_jitCode), X86::eax, X86::eax);
2155
2156     __ jmp_r(X86::eax);
2157
2158     // All trampolines constructed! copy the code, link up calls, and set the pointers on the Machine object.
2159     m_interpreter->m_executablePool = m_globalData->poolForSize(__ size());
2160     void* code = __ executableCopy(m_interpreter->m_executablePool.get());
2161
2162     X86Assembler::link(code, array_failureCases1, reinterpret_cast<void*>(Interpreter::cti_op_get_by_id_array_fail));
2163     X86Assembler::link(code, array_failureCases2, reinterpret_cast<void*>(Interpreter::cti_op_get_by_id_array_fail));
2164     X86Assembler::link(code, array_failureCases3, reinterpret_cast<void*>(Interpreter::cti_op_get_by_id_array_fail));
2165     X86Assembler::link(code, string_failureCases1, reinterpret_cast<void*>(Interpreter::cti_op_get_by_id_string_fail));
2166     X86Assembler::link(code, string_failureCases2, reinterpret_cast<void*>(Interpreter::cti_op_get_by_id_string_fail));
2167     X86Assembler::link(code, string_failureCases3, reinterpret_cast<void*>(Interpreter::cti_op_get_by_id_string_fail));
2168     X86Assembler::link(code, callArityCheck1, reinterpret_cast<void*>(Interpreter::cti_op_call_arityCheck));
2169     X86Assembler::link(code, callArityCheck2, reinterpret_cast<void*>(Interpreter::cti_op_call_arityCheck));
2170     X86Assembler::link(code, callArityCheck3, reinterpret_cast<void*>(Interpreter::cti_op_call_arityCheck));
2171     X86Assembler::link(code, callJSFunction1, reinterpret_cast<void*>(Interpreter::cti_op_call_JSFunction));
2172     X86Assembler::link(code, callJSFunction2, reinterpret_cast<void*>(Interpreter::cti_op_call_JSFunction));
2173     X86Assembler::link(code, callJSFunction3, reinterpret_cast<void*>(Interpreter::cti_op_call_JSFunction));
2174     X86Assembler::link(code, callDontLazyLinkCall, reinterpret_cast<void*>(Interpreter::cti_vm_dontLazyLinkCall));
2175     X86Assembler::link(code, callLazyLinkCall, reinterpret_cast<void*>(Interpreter::cti_vm_lazyLinkCall));
2176
2177     m_interpreter->m_ctiArrayLengthTrampoline = code;
2178     m_interpreter->m_ctiStringLengthTrampoline = X86Assembler::getRelocatedAddress(code, stringLengthBegin);
2179     m_interpreter->m_ctiVirtualCallPreLink = X86Assembler::getRelocatedAddress(code, virtualCallPreLinkBegin);
2180     m_interpreter->m_ctiVirtualCallLink = X86Assembler::getRelocatedAddress(code, virtualCallLinkBegin);
2181     m_interpreter->m_ctiVirtualCall = X86Assembler::getRelocatedAddress(code, virtualCallBegin);
2182 }
2183
2184 void JIT::emitGetVariableObjectRegister(RegisterID variableObject, int index, RegisterID dst)
2185 {
2186     __ movl_mr(FIELD_OFFSET(JSVariableObject, d), variableObject, dst);
2187     __ movl_mr(FIELD_OFFSET(JSVariableObject::JSVariableObjectData, registers), dst, dst);
2188     __ movl_mr(index * sizeof(Register), dst, dst);
2189 }
2190
2191 void JIT::emitPutVariableObjectRegister(RegisterID src, RegisterID variableObject, int index)
2192 {
2193     __ movl_mr(FIELD_OFFSET(JSVariableObject, d), variableObject, variableObject);
2194     __ movl_mr(FIELD_OFFSET(JSVariableObject::JSVariableObjectData, registers), variableObject, variableObject);
2195     __ movl_rm(src, index * sizeof(Register), variableObject);
2196 }
2197
2198 } // namespace JSC
2199
2200 #endif // ENABLE(JIT)