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