0a6d62910e186e76095eb43c621b9b2d4c09a60d
[WebKit-https.git] / JavaScriptCore / VM / CTI.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 "CTI.h"
28
29 #if ENABLE(CTI)
30
31 #include "CodeBlock.h"
32 #include "JSArray.h"
33 #include "Machine.h"
34 #include "wrec/WREC.h"
35
36 using namespace std;
37
38 namespace JSC {
39
40 #if COMPILER(GCC) && PLATFORM(X86)
41 asm(
42 ".globl _ctiTrampoline" "\n"
43 "_ctiTrampoline:" "\n"
44     "pushl %esi" "\n"
45     "pushl %edi" "\n"
46     "subl $0x24, %esp" "\n"
47     "movl $512, %esi" "\n"
48     "call *0x30(%esp)" "\n" //Ox30 = 0x0C * 4, 0x0C = CTI_ARGS_code
49     "addl $0x24, %esp" "\n"
50     "popl %edi" "\n"
51     "popl %esi" "\n"
52     "ret" "\n"
53 );
54
55 asm(
56 ".globl _ctiVMThrowTrampoline" "\n"
57 "_ctiVMThrowTrampoline:" "\n"
58 #ifndef NDEBUG
59     "movl 0x34(%esp), %ecx" "\n" //Ox34 = 0x0D * 4, 0x0D = CTI_ARGS_exec
60     "cmpl $0, 8(%ecx)" "\n"
61     "jne 1f" "\n"
62     "int3" "\n"
63     "1:" "\n"
64 #endif
65     "call __ZN3JSC7Machine12cti_vm_throwEPv" "\n"
66     "addl $0x24, %esp" "\n"
67     "popl %edi" "\n"
68     "popl %esi" "\n"
69     "ret" "\n"
70 );
71     
72 #elif COMPILER(MSVC)
73 extern "C"
74 {
75     
76     __declspec(naked) JSValue* ctiTrampoline(void* code, ExecState* exec, RegisterFile* registerFile, Register* r, ScopeChainNode* scopeChain, CodeBlock* codeBlock, JSValue** exception, Profiler**)
77     {
78         __asm {
79             push esi;
80             push edi;
81             sub esp, 0x24;
82             mov esi, 512;
83             mov [esp], esp;
84             call [esp + 0x30];
85             add esp, 0x24;
86             pop edi;
87             pop esi;
88             ret;
89         }
90     }
91     
92     __declspec(naked) void ctiVMThrowTrampoline()
93     {
94         __asm {
95            mov [esp], esp;
96             call JSC::Machine::cti_vm_throw;
97             add esp, 0x24;
98             pop edi;
99             pop esi;
100             ret;
101         }
102     }
103     
104 }
105
106 #endif
107
108
109 // get arg puts an arg from the SF register array into a h/w register
110 ALWAYS_INLINE void CTI::emitGetArg(unsigned src, X86Assembler::RegisterID dst)
111 {
112     // TODO: we want to reuse values that are already in registers if we can - add a register allocator!
113     if (src < m_codeBlock->constantRegisters.size()) {
114         JSValue* js = m_codeBlock->constantRegisters[src].jsValue(m_exec);
115         m_jit.movl_i32r(reinterpret_cast<unsigned>(js), dst);
116     } else
117         m_jit.movl_mr(src * sizeof(Register), X86::edi, dst);
118 }
119
120 // get arg puts an arg from the SF register array onto the stack, as an arg to a context threaded function.
121 ALWAYS_INLINE void CTI::emitGetPutArg(unsigned src, unsigned offset, X86Assembler::RegisterID scratch)
122 {
123     if (src < m_codeBlock->constantRegisters.size()) {
124         JSValue* js = m_codeBlock->constantRegisters[src].jsValue(m_exec);
125         m_jit.movl_i32m(reinterpret_cast<unsigned>(js), offset + sizeof(void*), X86::esp);
126     } else {
127         m_jit.movl_mr(src * sizeof(Register), X86::edi, scratch);
128         m_jit.movl_rm(scratch, offset + sizeof(void*), X86::esp);
129     }
130 }
131
132 // puts an arg onto the stack, as an arg to a context threaded function.
133 ALWAYS_INLINE void CTI::emitPutArg(X86Assembler::RegisterID src, unsigned offset)
134 {
135     m_jit.movl_rm(src, offset + sizeof(void*), X86::esp);
136 }
137
138 ALWAYS_INLINE void CTI::emitPutArgConstant(unsigned value, unsigned offset)
139 {
140     m_jit.movl_i32m(value, offset + sizeof(void*), X86::esp);
141 }
142
143 ALWAYS_INLINE JSValue* CTI::getConstantImmediateNumericArg(unsigned src)
144 {
145     if (src < m_codeBlock->constantRegisters.size()) {
146         JSValue* js = m_codeBlock->constantRegisters[src].jsValue(m_exec);
147         return JSImmediate::isNumber(js) ? js : 0;
148     }
149     return 0;
150 }
151
152 ALWAYS_INLINE void CTI::emitPutCTIParam(X86Assembler::RegisterID from, unsigned name)
153 {
154     m_jit.movl_rm(from, name * sizeof(void*), X86::esp);
155 }
156
157 ALWAYS_INLINE void CTI::emitGetCTIParam(unsigned name, X86Assembler::RegisterID to)
158 {
159     m_jit.movl_mr(name * sizeof(void*), X86::esp, to);
160 }
161
162 ALWAYS_INLINE void CTI::emitPutToCallFrameHeader(X86Assembler::RegisterID from, RegisterFile::CallFrameHeaderEntry entry)
163 {
164     m_jit.movl_rm(from, -((m_codeBlock->numLocals + RegisterFile::CallFrameHeaderSize) - entry) * sizeof(Register), X86::edi);
165 }
166
167 ALWAYS_INLINE void CTI::emitGetFromCallFrameHeader(RegisterFile::CallFrameHeaderEntry entry, X86Assembler::RegisterID to)
168 {
169     m_jit.movl_mr(-((m_codeBlock->numLocals + RegisterFile::CallFrameHeaderSize) - entry) * sizeof(Register), X86::edi, to);
170 }
171
172 ALWAYS_INLINE void CTI::emitPutResult(unsigned dst, X86Assembler::RegisterID from)
173 {
174     m_jit.movl_rm(from, dst * sizeof(Register), X86::edi);
175     // FIXME: #ifndef NDEBUG, Write the correct m_type to the register.
176 }
177
178 #if ENABLE(SAMPLING_TOOL)
179 unsigned incall = 0;
180 #endif
181
182 void ctiSetReturnAddress(void** where, void* what)
183 {
184     *where = what;
185 }
186
187 void ctiRepatchCallByReturnAddress(void* where, void* what)
188 {
189     (static_cast<void**>(where))[-1] = reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(what) - reinterpret_cast<uintptr_t>(where));
190 }
191
192 #ifdef NDEBUG
193
194 ALWAYS_INLINE void CTI::emitDebugExceptionCheck()
195 {
196 }
197
198 #else
199
200 ALWAYS_INLINE void CTI::emitDebugExceptionCheck()
201 {
202     emitGetCTIParam(CTI_ARGS_exec, X86::ecx);
203     m_jit.cmpl_i32m(0, OBJECT_OFFSET(ExecState, m_exception), X86::ecx);
204     X86Assembler::JmpSrc noException = m_jit.emitUnlinkedJe();
205     m_jit.emitInt3();
206     m_jit.link(noException, m_jit.label());
207 }
208
209 void CTI::printOpcodeOperandTypes(unsigned src1, unsigned src2)
210 {
211     char which1 = '*';
212     if (src1 < m_codeBlock->constantRegisters.size()) {
213         JSValue* js = m_codeBlock->constantRegisters[src1].jsValue(m_exec);
214         which1 = 
215             JSImmediate::isImmediate(js) ?
216                 (JSImmediate::isNumber(js) ? 'i' :
217                 JSImmediate::isBoolean(js) ? 'b' :
218                 js->isUndefined() ? 'u' :
219                 js->isNull() ? 'n' : '?')
220                 :
221             (js->isString() ? 's' :
222             js->isObject() ? 'o' :
223             'k');
224     }
225     char which2 = '*';
226     if (src2 < m_codeBlock->constantRegisters.size()) {
227         JSValue* js = m_codeBlock->constantRegisters[src2].jsValue(m_exec);
228         which2 = 
229             JSImmediate::isImmediate(js) ?
230                 (JSImmediate::isNumber(js) ? 'i' :
231                 JSImmediate::isBoolean(js) ? 'b' :
232                 js->isUndefined() ? 'u' :
233                 js->isNull() ? 'n' : '?')
234                 :
235             (js->isString() ? 's' :
236             js->isObject() ? 'o' :
237             'k');
238     }
239     if ((which1 != '*') | (which2 != '*'))
240         fprintf(stderr, "Types %c %c\n", which1, which2);
241 }
242
243 #endif
244
245 ALWAYS_INLINE void CTI::emitCall(unsigned opcodeIndex, CTIHelper_j helper)
246 {
247 #if ENABLE(SAMPLING_TOOL)
248     m_jit.movl_i32m(1, &incall);
249 #endif
250     m_calls.append(CallRecord(m_jit.emitCall(), helper, opcodeIndex));
251     emitDebugExceptionCheck();
252 #if ENABLE(SAMPLING_TOOL)
253     m_jit.movl_i32m(0, &incall);
254 #endif
255 }
256
257 ALWAYS_INLINE void CTI::emitCall(unsigned opcodeIndex, CTIHelper_p helper)
258 {
259 #if ENABLE(SAMPLING_TOOL)
260     m_jit.movl_i32m(1, &incall);
261 #endif
262     m_calls.append(CallRecord(m_jit.emitCall(), helper, opcodeIndex));
263     emitDebugExceptionCheck();
264 #if ENABLE(SAMPLING_TOOL)
265     m_jit.movl_i32m(0, &incall);
266 #endif
267 }
268
269 ALWAYS_INLINE void CTI::emitCall(unsigned opcodeIndex, CTIHelper_b helper)
270 {
271 #if ENABLE(SAMPLING_TOOL)
272     m_jit.movl_i32m(1, &incall);
273 #endif
274     m_calls.append(CallRecord(m_jit.emitCall(), helper, opcodeIndex));
275     emitDebugExceptionCheck();
276 #if ENABLE(SAMPLING_TOOL)
277     m_jit.movl_i32m(0, &incall);
278 #endif
279 }
280
281 ALWAYS_INLINE void CTI::emitCall(unsigned opcodeIndex, CTIHelper_v helper)
282 {
283 #if ENABLE(SAMPLING_TOOL)
284     m_jit.movl_i32m(1, &incall);
285 #endif
286     m_calls.append(CallRecord(m_jit.emitCall(), helper, opcodeIndex));
287     emitDebugExceptionCheck();
288 #if ENABLE(SAMPLING_TOOL)
289     m_jit.movl_i32m(0, &incall);
290 #endif
291 }
292
293 ALWAYS_INLINE void CTI::emitCall(unsigned opcodeIndex, CTIHelper_s helper)
294 {
295 #if ENABLE(SAMPLING_TOOL)
296     m_jit.movl_i32m(1, &incall);
297 #endif
298     m_calls.append(CallRecord(m_jit.emitCall(), helper, opcodeIndex));
299     emitDebugExceptionCheck();
300 #if ENABLE(SAMPLING_TOOL)
301     m_jit.movl_i32m(0, &incall);
302 #endif
303 }
304
305 ALWAYS_INLINE void CTI::emitJumpSlowCaseIfNotImm(X86Assembler::RegisterID reg, unsigned opcodeIndex)
306 {
307     m_jit.testl_i32r(JSImmediate::TagBitTypeInteger, reg);
308     m_slowCases.append(SlowCaseEntry(m_jit.emitUnlinkedJe(), opcodeIndex));
309 }
310
311 ALWAYS_INLINE void CTI::emitJumpSlowCaseIfNotImms(X86Assembler::RegisterID reg1, X86Assembler::RegisterID reg2, unsigned opcodeIndex)
312 {
313     m_jit.movl_rr(reg1, X86::ecx);
314     m_jit.andl_rr(reg2, X86::ecx);
315     emitJumpSlowCaseIfNotImm(X86::ecx, opcodeIndex);
316 }
317
318 ALWAYS_INLINE unsigned CTI::getDeTaggedConstantImmediate(JSValue* imm)
319 {
320     ASSERT(JSImmediate::isNumber(imm));
321     return reinterpret_cast<unsigned>(imm) & ~JSImmediate::TagBitTypeInteger;
322 }
323
324 ALWAYS_INLINE void CTI::emitFastArithDeTagImmediate(X86Assembler::RegisterID reg)
325 {
326     // op_mod relies on this being a sub - setting zf if result is 0.
327     m_jit.subl_i8r(JSImmediate::TagBitTypeInteger, reg);
328 }
329
330 ALWAYS_INLINE void CTI::emitFastArithReTagImmediate(X86Assembler::RegisterID reg)
331 {
332     m_jit.addl_i8r(JSImmediate::TagBitTypeInteger, reg);
333 }
334
335 ALWAYS_INLINE void CTI::emitFastArithPotentiallyReTagImmediate(X86Assembler::RegisterID reg)
336 {
337     m_jit.orl_i32r(JSImmediate::TagBitTypeInteger, reg);
338 }
339
340 ALWAYS_INLINE void CTI::emitFastArithImmToInt(X86Assembler::RegisterID reg)
341 {
342     m_jit.sarl_i8r(1, reg);
343 }
344
345 ALWAYS_INLINE void CTI::emitFastArithIntToImmOrSlowCase(X86Assembler::RegisterID reg, unsigned opcodeIndex)
346 {
347     m_jit.addl_rr(reg, reg);
348     m_slowCases.append(SlowCaseEntry(m_jit.emitUnlinkedJo(), opcodeIndex));
349     emitFastArithReTagImmediate(reg);
350 }
351
352 ALWAYS_INLINE void CTI::emitFastArithIntToImmNoCheck(X86Assembler::RegisterID reg)
353 {
354     m_jit.addl_rr(reg, reg);
355     emitFastArithReTagImmediate(reg);
356 }
357
358 CTI::CTI(Machine* machine, ExecState* exec, CodeBlock* codeBlock)
359     : m_jit(machine->jitCodeBuffer())
360     , m_machine(machine)
361     , m_exec(exec)
362     , m_codeBlock(codeBlock)
363     , m_labels(codeBlock ? codeBlock->instructions.size() : 0)
364 {
365 }
366
367 #define CTI_COMPILE_BINARY_OP(name) \
368     case name: { \
369         emitGetPutArg(instruction[i + 2].u.operand, 0, X86::ecx); \
370         emitGetPutArg(instruction[i + 3].u.operand, 4, X86::ecx); \
371         emitCall(i, Machine::cti_##name); \
372         emitPutResult(instruction[i + 1].u.operand); \
373         i += 4; \
374         break; \
375     }
376
377 #if ENABLE(SAMPLING_TOOL)
378 OpcodeID what = (OpcodeID)-1;
379 #endif
380
381 void CTI::compileOpCall(Instruction* instruction, unsigned i, CompileOpCallType type)
382 {
383     if (type == OpConstruct) {
384         emitPutArgConstant(reinterpret_cast<unsigned>(instruction + i), 12);
385         emitPutArgConstant(instruction[i + 4].u.operand, 8);
386         emitPutArgConstant(instruction[i + 3].u.operand, 4);
387     } else {
388         emitPutArgConstant(reinterpret_cast<unsigned>(instruction + i), 16);
389         emitPutArgConstant(instruction[i + 5].u.operand, 12);
390         emitPutArgConstant(instruction[i + 4].u.operand, 8);
391         // FIXME: should this be loaded dynamically off m_exec?
392         int thisVal = instruction[i + 3].u.operand;
393         if (thisVal == missingThisObjectMarker()) {
394             emitPutArgConstant(reinterpret_cast<unsigned>(m_exec->globalThisValue()), 4);
395         } else
396             emitGetPutArg(thisVal, 4, X86::ecx);
397     }
398
399     X86Assembler::JmpSrc wasEval;
400     if (type == OpCallEval) {
401         emitGetPutArg(instruction[i + 2].u.operand, 0, X86::ecx);
402         emitCall(i, Machine::cti_op_call_eval);
403         m_jit.emitRestoreArgumentReference();
404
405        emitGetCTIParam(CTI_ARGS_r, X86::edi); // edi := r
406
407         m_jit.cmpl_i32r(reinterpret_cast<unsigned>(JSImmediate::impossibleValue()), X86::eax);
408         wasEval = m_jit.emitUnlinkedJne();
409     
410         // this reloads the first arg into ecx (checked just below).
411         emitGetArg(instruction[i + 2].u.operand, X86::ecx);
412     } else {
413         // this sets up the first arg, and explicitly leaves the value in ecx (checked just below).
414         emitGetArg(instruction[i + 2].u.operand, X86::ecx);
415         emitPutArg(X86::ecx, 0);
416     }
417
418     // Fast check for JS function.
419     m_jit.testl_i32r(JSImmediate::TagMask, X86::ecx);
420     X86Assembler::JmpSrc isNotObject = m_jit.emitUnlinkedJne();
421     m_jit.cmpl_i32m(reinterpret_cast<unsigned>(m_machine->m_jsFunctionVptr), X86::ecx);
422     X86Assembler::JmpSrc isJSFunction = m_jit.emitUnlinkedJe();
423     m_jit.link(isNotObject, m_jit.label());
424
425     // This handles host functions
426     emitCall(i, ((type == OpConstruct) ? Machine::cti_op_construct_NotJSConstruct : Machine::cti_op_call_NotJSFunction));
427     emitGetCTIParam(CTI_ARGS_r, X86::edi); // edi := r
428     
429     X86Assembler::JmpSrc wasNotJSFunction = m_jit.emitUnlinkedJmp();
430     m_jit.link(isJSFunction, m_jit.label());
431
432     // This handles JSFunctions
433     emitCall(i, ((type == OpConstruct) ? Machine::cti_op_construct_JSConstruct : Machine::cti_op_call_JSFunction));
434     m_jit.call_r(X86::eax);
435     emitGetCTIParam(CTI_ARGS_r, X86::edi); // edi := r
436
437     X86Assembler::JmpDst end = m_jit.label();
438     m_jit.link(wasNotJSFunction, end);
439     if (type == OpCallEval)
440         m_jit.link(wasEval, end);
441
442     emitPutResult(instruction[i + 1].u.operand);
443 }
444
445 void CTI::emitSlowScriptCheck(unsigned opcodeIndex)
446 {
447     m_jit.subl_i8r(1, X86::esi);
448     X86Assembler::JmpSrc skipTimeout = m_jit.emitUnlinkedJne();
449     emitCall(opcodeIndex, Machine::cti_timeout_check);
450
451     emitGetCTIParam(CTI_ARGS_exec, X86::ecx);
452     m_jit.movl_mr(OBJECT_OFFSET(ExecState, m_globalData), X86::ecx, X86::ecx);
453     m_jit.movl_mr(OBJECT_OFFSET(JSGlobalData, machine), X86::ecx, X86::ecx);
454     m_jit.movl_mr(OBJECT_OFFSET(Machine, m_ticksUntilNextTimeoutCheck), X86::ecx, X86::esi);
455     m_jit.link(skipTimeout, m_jit.label());
456 }
457
458 void CTI::privateCompileMainPass()
459 {
460     Instruction* instruction = m_codeBlock->instructions.begin();
461     unsigned instructionCount = m_codeBlock->instructions.size();
462
463     for (unsigned i = 0; i < instructionCount; ) {
464         m_labels[i] = m_jit.label();
465
466 #if ENABLE(SAMPLING_TOOL)
467         m_jit.movl_i32m(m_machine->getOpcodeID(instruction[i].u.opcode), &what);
468 #endif
469
470         ASSERT_WITH_MESSAGE(m_machine->isOpcode(instruction[i].u.opcode), "privateCompileMainPass gone bad @ %d", i);
471         m_jit.emitRestoreArgumentReference();
472         switch (m_machine->getOpcodeID(instruction[i].u.opcode)) {
473         case op_mov: {
474             unsigned src = instruction[i + 2].u.operand;
475             if (src < m_codeBlock->constantRegisters.size())
476                 m_jit.movl_i32r(reinterpret_cast<unsigned>(m_codeBlock->constantRegisters[src].jsValue(m_exec)), X86::edx);
477             else
478                 emitGetArg(src, X86::edx);
479             emitPutResult(instruction[i + 1].u.operand, X86::edx);
480             i += 3;
481             break;
482         }
483         case op_add: {
484             unsigned dst = instruction[i + 1].u.operand;
485             unsigned src1 = instruction[i + 2].u.operand;
486             unsigned src2 = instruction[i + 3].u.operand;
487             if (src2 < m_codeBlock->constantRegisters.size()) {
488                 JSValue* value = m_codeBlock->constantRegisters[src2].jsValue(m_exec);
489                 if (JSImmediate::isNumber(value)) {
490                     emitGetArg(src1, X86::eax);
491                     emitJumpSlowCaseIfNotImm(X86::eax, i);
492                     m_jit.addl_i32r(getDeTaggedConstantImmediate(value), X86::eax);
493                     m_slowCases.append(SlowCaseEntry(m_jit.emitUnlinkedJo(), i));
494                     emitPutResult(dst);
495                     i += 4;
496                     break;
497                 }
498             } else if (!(src1 < m_codeBlock->constantRegisters.size())) {
499                 emitGetArg(src1, X86::eax);
500                 emitGetArg(src2, X86::edx);
501                 emitJumpSlowCaseIfNotImms(X86::eax, X86::edx, i);
502                 emitFastArithDeTagImmediate(X86::eax);
503                 m_jit.addl_rr(X86::edx, X86::eax);
504                 m_slowCases.append(SlowCaseEntry(m_jit.emitUnlinkedJo(), i));
505                 emitPutResult(dst);
506                 i += 4;
507                 break;
508             }
509             emitGetPutArg(instruction[i + 2].u.operand, 0, X86::ecx);
510             emitGetPutArg(instruction[i + 3].u.operand, 4, X86::ecx);
511             emitCall(i, Machine::cti_op_add);
512             emitPutResult(instruction[i + 1].u.operand);
513             i += 4;
514             break;
515         }
516         case op_end: {
517             if (m_codeBlock->needsFullScopeChain)
518                 emitCall(i, Machine::cti_op_end);
519             emitGetArg(instruction[i + 1].u.operand, X86::eax);
520 #if ENABLE(SAMPLING_TOOL)
521             m_jit.movl_i32m(-1, &what);
522 #endif
523             m_jit.pushl_m(-((m_codeBlock->numLocals + RegisterFile::CallFrameHeaderSize) - RegisterFile::CTIReturnEIP) * sizeof(Register), X86::edi);
524             m_jit.ret();
525             i += 2;
526             break;
527         }
528         case op_jmp: {
529             unsigned target = instruction[i + 1].u.operand;
530             m_jmpTable.append(JmpTable(m_jit.emitUnlinkedJmp(), i + 1 + target));
531             i += 2;
532             break;
533         }
534         case op_pre_inc: {
535             int srcDst = instruction[i + 1].u.operand;
536             emitGetArg(srcDst, X86::eax);
537             emitJumpSlowCaseIfNotImm(X86::eax, i);
538             m_jit.addl_i8r(getDeTaggedConstantImmediate(JSImmediate::oneImmediate()), X86::eax);
539             m_slowCases.append(SlowCaseEntry(m_jit.emitUnlinkedJo(), i));
540             emitPutResult(srcDst, X86::eax);
541             i += 2;
542             break;
543         }
544         case op_loop: {
545             emitSlowScriptCheck(i);
546
547             unsigned target = instruction[i + 1].u.operand;
548             m_jmpTable.append(JmpTable(m_jit.emitUnlinkedJmp(), i + 1 + target));
549             i += 2;
550             break;
551         }
552         case op_loop_if_less: {
553             emitSlowScriptCheck(i);
554
555             unsigned target = instruction[i + 3].u.operand;
556             JSValue* src2imm = getConstantImmediateNumericArg(instruction[i + 2].u.operand);
557             if (src2imm) {
558                 emitGetArg(instruction[i + 1].u.operand, X86::edx);
559                 emitJumpSlowCaseIfNotImm(X86::edx, i);
560                 m_jit.cmpl_i32r(reinterpret_cast<unsigned>(src2imm), X86::edx);
561                 m_jmpTable.append(JmpTable(m_jit.emitUnlinkedJl(), i + 3 + target));
562             } else {
563                 emitGetArg(instruction[i + 1].u.operand, X86::eax);
564                 emitGetArg(instruction[i + 2].u.operand, X86::edx);
565                 emitJumpSlowCaseIfNotImm(X86::eax, i);
566                 emitJumpSlowCaseIfNotImm(X86::edx, i);
567                 m_jit.cmpl_rr(X86::edx, X86::eax);
568                 m_jmpTable.append(JmpTable(m_jit.emitUnlinkedJl(), i + 3 + target));
569             }
570             i += 4;
571             break;
572         }
573         case op_new_object: {
574             emitCall(i, Machine::cti_op_new_object);
575             emitPutResult(instruction[i + 1].u.operand);
576             i += 2;
577             break;
578         }
579         case op_put_by_id: {
580             Identifier* ident = &(m_codeBlock->identifiers[instruction[i + 2].u.operand]);
581             emitPutArgConstant(reinterpret_cast<unsigned>(ident), 4);
582             emitGetArg(instruction[i + 1].u.operand, X86::eax);
583             emitGetArg(instruction[i + 3].u.operand, X86::edx);
584             emitPutArg(X86::eax, 0); // leave the base in eax
585             emitPutArg(X86::edx, 8); // leave the base in edx
586             emitCall(i, Machine::cti_op_put_by_id);
587             i += 6;
588             break;
589         }
590         case op_get_by_id: {
591             Identifier* ident = &(m_codeBlock->identifiers[instruction[i + 3].u.operand]);
592             emitPutArgConstant(reinterpret_cast<unsigned>(ident), 4);
593             emitGetArg(instruction[i + 2].u.operand, X86::eax);
594             emitPutArg(X86::eax, 0); // leave the base in eax
595             emitCall(i, Machine::cti_op_get_by_id);
596             emitPutResult(instruction[i + 1].u.operand);
597             i += 8;
598             break;
599         }
600         case op_instanceof: {
601             emitGetPutArg(instruction[i + 2].u.operand, 0, X86::ecx);
602             emitGetPutArg(instruction[i + 3].u.operand, 4, X86::ecx);
603             emitCall(i, Machine::cti_op_instanceof);
604             emitPutResult(instruction[i + 1].u.operand);
605             i += 4;
606             break;
607         }
608         case op_del_by_id: {
609             emitGetPutArg(instruction[i + 2].u.operand, 0, X86::ecx);
610             Identifier* ident = &(m_codeBlock->identifiers[instruction[i + 3].u.operand]);
611             emitPutArgConstant(reinterpret_cast<unsigned>(ident), 4);
612             emitCall(i, Machine::cti_op_del_by_id);
613             emitPutResult(instruction[i + 1].u.operand);
614             i += 4;
615             break;
616         }
617         case op_mul: {
618             unsigned dst = instruction[i + 1].u.operand;
619             unsigned src1 = instruction[i + 2].u.operand;
620             unsigned src2 = instruction[i + 3].u.operand;
621             if (src1 < m_codeBlock->constantRegisters.size() || src2 < m_codeBlock->constantRegisters.size()) {
622                 unsigned constant = src1;
623                 unsigned nonconstant = src2;
624                 if (!(src1 < m_codeBlock->constantRegisters.size())) {
625                     constant = src2;
626                     nonconstant = src1;
627                 }
628                 JSValue* value = m_codeBlock->constantRegisters[constant].jsValue(m_exec);
629                 if (JSImmediate::isNumber(value)) {
630                     emitGetArg(nonconstant, X86::eax);
631                     emitJumpSlowCaseIfNotImm(X86::eax, i);
632                     emitFastArithImmToInt(X86::eax);
633                     m_jit.imull_i32r( X86::eax, getDeTaggedConstantImmediate(value), X86::eax);
634                     m_slowCases.append(SlowCaseEntry(m_jit.emitUnlinkedJo(), i));
635                     emitFastArithPotentiallyReTagImmediate(X86::eax);
636                     emitPutResult(dst);
637                     i += 4;
638                     break;
639                 }
640             }
641
642             emitGetArg(src1, X86::eax);
643             emitGetArg(src2, X86::edx);
644             emitJumpSlowCaseIfNotImms(X86::eax, X86::edx, i);
645             emitFastArithDeTagImmediate(X86::eax);
646             emitFastArithImmToInt(X86::edx);
647             m_jit.imull_rr(X86::edx, X86::eax);
648             m_slowCases.append(SlowCaseEntry(m_jit.emitUnlinkedJo(), i));
649             emitFastArithPotentiallyReTagImmediate(X86::eax);
650             emitPutResult(dst);
651             i += 4;
652             break;
653         }
654         case op_new_func: {
655             FuncDeclNode* func = (m_codeBlock->functions[instruction[i + 2].u.operand]).get();
656             emitPutArgConstant(reinterpret_cast<unsigned>(func), 0);
657             emitCall(i, Machine::cti_op_new_func);
658             emitPutResult(instruction[i + 1].u.operand);
659             i += 3;
660             break;
661         }
662         case op_call: {
663             compileOpCall(instruction, i);
664             i += 6;
665             break;
666         }
667         case op_get_global_var: {
668             JSVariableObject* globalObject = static_cast<JSVariableObject*>(instruction[i + 2].u.jsCell);
669             m_jit.movl_i32r(reinterpret_cast<unsigned>(globalObject), X86::eax);
670             emitGetVariableObjectRegister(X86::eax, instruction[i + 3].u.operand, X86::eax);
671             emitPutResult(instruction[i + 1].u.operand, X86::eax);
672             i += 4;
673             break;
674         }
675         case op_put_global_var: {
676             JSVariableObject* globalObject = static_cast<JSVariableObject*>(instruction[i + 1].u.jsCell);
677             m_jit.movl_i32r(reinterpret_cast<unsigned>(globalObject), X86::eax);
678             emitGetArg(instruction[i + 3].u.operand, X86::edx);
679             emitPutVariableObjectRegister(X86::edx, X86::eax, instruction[i + 2].u.operand);
680             i += 4;
681             break;
682         }
683         case op_get_scoped_var: {
684             int skip = instruction[i + 3].u.operand + m_codeBlock->needsFullScopeChain;
685
686             emitGetCTIParam(CTI_ARGS_scopeChain, X86::eax);
687             while (skip--)
688                 m_jit.movl_mr(OBJECT_OFFSET(ScopeChainNode, next), X86::eax, X86::eax);
689
690             m_jit.movl_mr(OBJECT_OFFSET(ScopeChainNode, object), X86::eax, X86::eax);
691             emitGetVariableObjectRegister(X86::eax, instruction[i + 2].u.operand, X86::eax);
692             emitPutResult(instruction[i + 1].u.operand);
693             i += 4;
694             break;
695         }
696         case op_put_scoped_var: {
697             int skip = instruction[i + 2].u.operand + m_codeBlock->needsFullScopeChain;
698
699             emitGetCTIParam(CTI_ARGS_scopeChain, X86::edx);
700             emitGetArg(instruction[i + 3].u.operand, X86::eax);
701             while (skip--)
702                 m_jit.movl_mr(OBJECT_OFFSET(ScopeChainNode, next), X86::edx, X86::edx);
703
704             m_jit.movl_mr(OBJECT_OFFSET(ScopeChainNode, object), X86::edx, X86::edx);
705             emitPutVariableObjectRegister(X86::eax, X86::edx, instruction[i + 1].u.operand);
706             i += 4;
707             break;
708         }
709         case op_ret: {
710             emitGetPutArg(instruction[i + 1].u.operand, 0, X86::ecx);
711             emitCall(i, Machine::cti_op_ret);
712
713             m_jit.pushl_m(-((m_codeBlock->numLocals + RegisterFile::CallFrameHeaderSize) - RegisterFile::CTIReturnEIP) * sizeof(Register), X86::edi);
714             m_jit.ret();
715             i += 2;
716             break;
717         }
718         case op_new_array: {
719             m_jit.leal_mr(sizeof(Register) * instruction[i + 2].u.operand, X86::edi, X86::edx);
720             emitPutArg(X86::edx, 0);
721             emitPutArgConstant(instruction[i + 3].u.operand, 4);
722             emitCall(i, Machine::cti_op_new_array);
723             emitPutResult(instruction[i + 1].u.operand);
724             i += 4;
725             break;
726         }
727         case op_resolve: {
728             Identifier* ident = &(m_codeBlock->identifiers[instruction[i + 2].u.operand]);
729             emitPutArgConstant(reinterpret_cast<unsigned>(ident), 0);
730             emitCall(i, Machine::cti_op_resolve);
731             emitPutResult(instruction[i + 1].u.operand);
732             i += 3;
733             break;
734         }
735         case op_construct: {
736             compileOpCall(instruction, i, OpConstruct);
737             i += 5;
738             break;
739         }
740         case op_get_by_val: {
741             emitGetArg(instruction[i + 2].u.operand, X86::eax);
742             emitGetArg(instruction[i + 3].u.operand, X86::edx);
743             emitJumpSlowCaseIfNotImm(X86::edx, i);
744             emitFastArithImmToInt(X86::edx);
745             m_jit.testl_i32r(JSImmediate::TagMask, X86::eax);
746             m_slowCases.append(SlowCaseEntry(m_jit.emitUnlinkedJne(), i));
747             m_jit.cmpl_i32m(reinterpret_cast<unsigned>(m_machine->m_jsArrayVptr), X86::eax);
748             m_slowCases.append(SlowCaseEntry(m_jit.emitUnlinkedJne(), i));
749             m_jit.cmpl_rm(X86::edx, OBJECT_OFFSET(JSArray, m_fastAccessCutoff), X86::eax);
750             m_slowCases.append(SlowCaseEntry(m_jit.emitUnlinkedJbe(), i));
751
752             m_jit.movl_mr(OBJECT_OFFSET(JSArray, m_storage), X86::eax, X86::eax);
753             m_jit.movl_mr(OBJECT_OFFSET(ArrayStorage, m_vector[0]), X86::eax, X86::edx, sizeof(JSValue*), X86::eax);
754             emitPutResult(instruction[i + 1].u.operand);
755             i += 4;
756             break;
757         }
758         case op_resolve_func: {
759             Identifier* ident = &(m_codeBlock->identifiers[instruction[i + 3].u.operand]);
760             emitPutArgConstant(reinterpret_cast<unsigned>(ident), 0);
761             emitCall(i, Machine::cti_op_resolve_func);
762             emitPutResult(instruction[i + 1].u.operand);
763             emitGetCTIParam(CTI_ARGS_2ndResult, X86::eax);
764             emitPutResult(instruction[i + 2].u.operand);
765             i += 4;
766             break;
767         }
768         case op_sub: {
769             emitGetArg(instruction[i + 2].u.operand, X86::eax);
770             emitGetArg(instruction[i + 3].u.operand, X86::edx);
771             emitJumpSlowCaseIfNotImms(X86::eax, X86::edx, i);
772             m_jit.subl_rr(X86::edx, X86::eax);
773             m_slowCases.append(SlowCaseEntry(m_jit.emitUnlinkedJo(), i));
774             emitFastArithReTagImmediate(X86::eax);
775             emitPutResult(instruction[i + 1].u.operand);
776             i += 4;
777             break;
778         }
779         case op_put_by_val: {
780             emitGetArg(instruction[i + 1].u.operand, X86::eax);
781             emitGetArg(instruction[i + 2].u.operand, X86::edx);
782             emitGetArg(instruction[i + 3].u.operand, X86::ecx);
783             emitJumpSlowCaseIfNotImm(X86::edx, i);
784             emitFastArithImmToInt(X86::edx);
785             m_jit.testl_i32r(JSImmediate::TagMask, X86::eax);
786             m_slowCases.append(SlowCaseEntry(m_jit.emitUnlinkedJne(), i));
787             m_jit.cmpl_i32m(reinterpret_cast<unsigned>(m_machine->m_jsArrayVptr), X86::eax);
788             m_slowCases.append(SlowCaseEntry(m_jit.emitUnlinkedJne(), i));
789             m_jit.cmpl_rm(X86::edx, OBJECT_OFFSET(JSArray, m_fastAccessCutoff), X86::eax);
790             m_slowCases.append(SlowCaseEntry(m_jit.emitUnlinkedJbe(), i));
791
792             m_jit.movl_mr(OBJECT_OFFSET(JSArray, m_storage), X86::eax, X86::eax);
793             m_jit.movl_rm(X86::ecx, OBJECT_OFFSET(ArrayStorage, m_vector[0]), X86::eax, X86::edx, sizeof(JSValue*));
794             i += 4;
795             break;
796         }
797         CTI_COMPILE_BINARY_OP(op_lesseq)
798         case op_loop_if_true: {
799             emitSlowScriptCheck(i);
800
801             unsigned target = instruction[i + 2].u.operand;
802             emitGetArg(instruction[i + 1].u.operand, X86::eax);
803
804             m_jit.cmpl_i32r(reinterpret_cast<uint32_t>(JSImmediate::zeroImmediate()), X86::eax);
805             X86Assembler::JmpSrc isZero = m_jit.emitUnlinkedJe();
806             m_jit.testl_i32r(JSImmediate::TagBitTypeInteger, X86::eax);
807             m_jmpTable.append(JmpTable(m_jit.emitUnlinkedJne(), i + 2 + target));
808
809             m_jit.cmpl_i32r(reinterpret_cast<uint32_t>(JSImmediate::trueImmediate()), X86::eax);
810             m_jmpTable.append(JmpTable(m_jit.emitUnlinkedJe(), i + 2 + target));
811             m_jit.cmpl_i32r(reinterpret_cast<uint32_t>(JSImmediate::falseImmediate()), X86::eax);
812             m_slowCases.append(SlowCaseEntry(m_jit.emitUnlinkedJne(), i));
813
814             m_jit.link(isZero, m_jit.label());
815             i += 3;
816             break;
817         };
818         case op_resolve_base: {
819             Identifier* ident = &(m_codeBlock->identifiers[instruction[i + 2].u.operand]);
820             emitPutArgConstant(reinterpret_cast<unsigned>(ident), 0);
821             emitCall(i, Machine::cti_op_resolve_base);
822             emitPutResult(instruction[i + 1].u.operand);
823             i += 3;
824             break;
825         }
826         case op_negate: {
827             emitGetPutArg(instruction[i + 2].u.operand, 0, X86::ecx);
828             emitCall(i, Machine::cti_op_negate);
829             emitPutResult(instruction[i + 1].u.operand);
830             i += 3;
831             break;
832         }
833         case op_resolve_skip: {
834             Identifier* ident = &(m_codeBlock->identifiers[instruction[i + 2].u.operand]);
835             emitPutArgConstant(reinterpret_cast<unsigned>(ident), 0);
836             emitPutArgConstant(instruction[i + 3].u.operand + m_codeBlock->needsFullScopeChain, 4);
837             emitCall(i, Machine::cti_op_resolve_skip);
838             emitPutResult(instruction[i + 1].u.operand);
839             i += 4;
840             break;
841         }
842         CTI_COMPILE_BINARY_OP(op_div)
843         case op_pre_dec: {
844             int srcDst = instruction[i + 1].u.operand;
845             emitGetArg(srcDst, X86::eax);
846             emitJumpSlowCaseIfNotImm(X86::eax, i);
847             m_jit.subl_i8r(getDeTaggedConstantImmediate(JSImmediate::oneImmediate()), X86::eax);
848             m_slowCases.append(SlowCaseEntry(m_jit.emitUnlinkedJo(), i));
849             emitPutResult(srcDst, X86::eax);
850             i += 2;
851             break;
852         }
853         case op_jnless: {
854             unsigned target = instruction[i + 3].u.operand;
855             JSValue* src2imm = getConstantImmediateNumericArg(instruction[i + 2].u.operand);
856             if (src2imm) {
857                 emitGetArg(instruction[i + 1].u.operand, X86::edx);
858                 emitJumpSlowCaseIfNotImm(X86::edx, i);
859                 m_jit.cmpl_i32r(reinterpret_cast<unsigned>(src2imm), X86::edx);
860                 m_jmpTable.append(JmpTable(m_jit.emitUnlinkedJge(), i + 3 + target));
861             } else {
862                 emitGetArg(instruction[i + 1].u.operand, X86::eax);
863                 emitGetArg(instruction[i + 2].u.operand, X86::edx);
864                 emitJumpSlowCaseIfNotImm(X86::eax, i);
865                 emitJumpSlowCaseIfNotImm(X86::edx, i);
866                 m_jit.cmpl_rr(X86::edx, X86::eax);
867                 m_jmpTable.append(JmpTable(m_jit.emitUnlinkedJge(), i + 3 + target));
868             }
869             i += 4;
870             break;
871         }
872         case op_not: {
873             emitGetArg(instruction[i + 2].u.operand, X86::eax);
874             m_jit.xorl_i8r(JSImmediate::FullTagTypeBool, X86::eax);
875             m_jit.testl_i32r(JSImmediate::FullTagTypeMask, X86::eax); // i8?
876             m_slowCases.append(SlowCaseEntry(m_jit.emitUnlinkedJne(), i));
877             m_jit.xorl_i8r((JSImmediate::FullTagTypeBool | JSImmediate::ExtendedPayloadBitBoolValue), X86::eax);
878             emitPutResult(instruction[i + 1].u.operand);
879             i += 3;
880             break;
881         }
882         case op_jfalse: {
883             unsigned target = instruction[i + 2].u.operand;
884             emitGetArg(instruction[i + 1].u.operand, X86::eax);
885
886             m_jit.cmpl_i32r(reinterpret_cast<uint32_t>(JSImmediate::zeroImmediate()), X86::eax);
887             m_jmpTable.append(JmpTable(m_jit.emitUnlinkedJe(), i + 2 + target));
888             m_jit.testl_i32r(JSImmediate::TagBitTypeInteger, X86::eax);
889             X86Assembler::JmpSrc isNonZero = m_jit.emitUnlinkedJne();
890
891             m_jit.cmpl_i32r(reinterpret_cast<uint32_t>(JSImmediate::falseImmediate()), X86::eax);
892             m_jmpTable.append(JmpTable(m_jit.emitUnlinkedJe(), i + 2 + target));
893             m_jit.cmpl_i32r(reinterpret_cast<uint32_t>(JSImmediate::trueImmediate()), X86::eax);
894             m_slowCases.append(SlowCaseEntry(m_jit.emitUnlinkedJne(), i));
895
896             m_jit.link(isNonZero, m_jit.label());
897             i += 3;
898             break;
899         };
900         case op_post_inc: {
901             int srcDst = instruction[i + 2].u.operand;
902             emitGetArg(srcDst, X86::eax);
903             m_jit.movl_rr(X86::eax, X86::edx);
904             emitJumpSlowCaseIfNotImm(X86::eax, i);
905             m_jit.addl_i8r(getDeTaggedConstantImmediate(JSImmediate::oneImmediate()), X86::edx);
906             m_slowCases.append(SlowCaseEntry(m_jit.emitUnlinkedJo(), i));
907             emitPutResult(srcDst, X86::edx);
908             emitPutResult(instruction[i + 1].u.operand);
909             i += 3;
910             break;
911         }
912         case op_unexpected_load: {
913             JSValue* v = m_codeBlock->unexpectedConstants[instruction[i + 2].u.operand];
914             m_jit.movl_i32r(reinterpret_cast<unsigned>(v), X86::eax);
915             emitPutResult(instruction[i + 1].u.operand);
916             i += 3;
917             break;
918         }
919         case op_jsr: {
920             int retAddrDst = instruction[i + 1].u.operand;
921             int target = instruction[i + 2].u.operand;
922             m_jit.movl_i32m(0, sizeof(Register) * retAddrDst, X86::edi);
923             X86Assembler::JmpDst addrPosition = m_jit.label();
924             m_jmpTable.append(JmpTable(m_jit.emitUnlinkedJmp(), i + 2 + target));
925             X86Assembler::JmpDst sretTarget = m_jit.label();
926             m_jsrSites.append(JSRInfo(addrPosition, sretTarget));
927             i += 3;
928             break;
929         }
930         case op_sret: {
931             m_jit.jmp_m(sizeof(Register) * instruction[i + 1].u.operand, X86::edi);
932             i += 2;
933             break;
934         }
935         CTI_COMPILE_BINARY_OP(op_eq)
936         case op_lshift: {
937             emitGetArg(instruction[i + 2].u.operand, X86::eax);
938             emitGetArg(instruction[i + 3].u.operand, X86::ecx);
939             emitJumpSlowCaseIfNotImm(X86::eax, i);
940             emitJumpSlowCaseIfNotImm(X86::ecx, i);
941             emitFastArithImmToInt(X86::eax);
942             emitFastArithImmToInt(X86::ecx);
943             m_jit.shll_CLr(X86::eax);
944             emitFastArithIntToImmOrSlowCase(X86::eax, i);
945             emitPutResult(instruction[i + 1].u.operand);
946             i += 4;
947             break;
948         }
949         case op_bitand: {
950             unsigned src1 = instruction[i + 2].u.operand;
951             unsigned src2 = instruction[i + 3].u.operand;
952             unsigned dst = instruction[i + 1].u.operand;
953             if (JSValue* value = getConstantImmediateNumericArg(src1)) {
954                 emitGetArg(src2, X86::eax);
955                 emitJumpSlowCaseIfNotImm(X86::eax, i);
956                 m_jit.andl_i32r(reinterpret_cast<unsigned>(value), X86::eax); // FIXME: make it more obvious this is relying on the format of JSImmediate
957                 emitPutResult(dst);
958             } else if (JSValue* value = getConstantImmediateNumericArg(src2)) {
959                 emitGetArg(src1, X86::eax);
960                 emitJumpSlowCaseIfNotImm(X86::eax, i);
961                 m_jit.andl_i32r(reinterpret_cast<unsigned>(value), X86::eax);
962                 emitPutResult(dst);
963             } else {
964                 emitGetArg(src1, X86::eax);
965                 emitGetArg(src2, X86::edx);
966                 m_jit.andl_rr(X86::edx, X86::eax);
967                 emitJumpSlowCaseIfNotImm(X86::eax, i);
968                 emitPutResult(dst);
969             }
970             i += 4;
971             break;
972         }
973         case op_rshift: {
974             emitGetArg(instruction[i + 2].u.operand, X86::eax);
975             emitGetArg(instruction[i + 3].u.operand, X86::ecx);
976             emitJumpSlowCaseIfNotImm(X86::eax, i);
977             emitJumpSlowCaseIfNotImm(X86::ecx, i);
978             emitFastArithImmToInt(X86::ecx);
979             m_jit.sarl_CLr(X86::eax);
980             emitFastArithPotentiallyReTagImmediate(X86::eax);
981             emitPutResult(instruction[i + 1].u.operand);
982             i += 4;
983             break;
984         }
985         case op_bitnot: {
986             emitGetArg(instruction[i + 2].u.operand, X86::eax);
987             emitJumpSlowCaseIfNotImm(X86::eax, i);
988             m_jit.xorl_i8r(~JSImmediate::TagBitTypeInteger, X86::eax);
989             emitPutResult(instruction[i + 1].u.operand);
990             i += 3;
991             break;
992         }
993         case op_resolve_with_base: {
994             Identifier* ident = &(m_codeBlock->identifiers[instruction[i + 3].u.operand]);
995             emitPutArgConstant(reinterpret_cast<unsigned>(ident), 0);
996             emitCall(i, Machine::cti_op_resolve_with_base);
997             emitPutResult(instruction[i + 1].u.operand);
998             emitGetCTIParam(CTI_ARGS_2ndResult, X86::eax);
999             emitPutResult(instruction[i + 2].u.operand);
1000             i += 4;
1001             break;
1002         }
1003         case op_new_func_exp: {
1004             FuncExprNode* func = (m_codeBlock->functionExpressions[instruction[i + 2].u.operand]).get();
1005             emitPutArgConstant(reinterpret_cast<unsigned>(func), 0);
1006             emitCall(i, Machine::cti_op_new_func_exp);
1007             emitPutResult(instruction[i + 1].u.operand);
1008             i += 3;
1009             break;
1010         }
1011         case op_mod: {
1012             emitGetArg(instruction[i + 2].u.operand, X86::eax);
1013             emitGetArg(instruction[i + 3].u.operand, X86::ecx);
1014             emitJumpSlowCaseIfNotImm(X86::eax, i);
1015             emitJumpSlowCaseIfNotImm(X86::ecx, i);
1016             emitFastArithDeTagImmediate(X86::eax);
1017             emitFastArithDeTagImmediate(X86::ecx);
1018             m_slowCases.append(SlowCaseEntry(m_jit.emitUnlinkedJe(), i)); // This is checking if the last detag resulted in a value 0.
1019             m_jit.cdq();
1020             m_jit.idivl_r(X86::ecx);
1021             emitFastArithReTagImmediate(X86::edx);
1022             m_jit.movl_rr(X86::edx, X86::eax);
1023             emitPutResult(instruction[i + 1].u.operand);
1024             i += 4;
1025             break;
1026         }
1027         case op_jtrue: {
1028             unsigned target = instruction[i + 2].u.operand;
1029             emitGetArg(instruction[i + 1].u.operand, X86::eax);
1030
1031             m_jit.cmpl_i32r(reinterpret_cast<uint32_t>(JSImmediate::zeroImmediate()), X86::eax);
1032             X86Assembler::JmpSrc isZero = m_jit.emitUnlinkedJe();
1033             m_jit.testl_i32r(JSImmediate::TagBitTypeInteger, X86::eax);
1034             m_jmpTable.append(JmpTable(m_jit.emitUnlinkedJne(), i + 2 + target));
1035
1036             m_jit.cmpl_i32r(reinterpret_cast<uint32_t>(JSImmediate::trueImmediate()), X86::eax);
1037             m_jmpTable.append(JmpTable(m_jit.emitUnlinkedJe(), i + 2 + target));
1038             m_jit.cmpl_i32r(reinterpret_cast<uint32_t>(JSImmediate::falseImmediate()), X86::eax);
1039             m_slowCases.append(SlowCaseEntry(m_jit.emitUnlinkedJne(), i));
1040
1041             m_jit.link(isZero, m_jit.label());
1042             i += 3;
1043             break;
1044         }
1045         CTI_COMPILE_BINARY_OP(op_less)
1046         CTI_COMPILE_BINARY_OP(op_neq)
1047         case op_post_dec: {
1048             int srcDst = instruction[i + 2].u.operand;
1049             emitGetArg(srcDst, X86::eax);
1050             m_jit.movl_rr(X86::eax, X86::edx);
1051             emitJumpSlowCaseIfNotImm(X86::eax, i);
1052             m_jit.subl_i8r(getDeTaggedConstantImmediate(JSImmediate::oneImmediate()), X86::edx);
1053             m_slowCases.append(SlowCaseEntry(m_jit.emitUnlinkedJo(), i));
1054             emitPutResult(srcDst, X86::edx);
1055             emitPutResult(instruction[i + 1].u.operand);
1056             i += 3;
1057             break;
1058         }
1059         CTI_COMPILE_BINARY_OP(op_urshift)
1060         case op_bitxor: {
1061             emitGetArg(instruction[i + 2].u.operand, X86::eax);
1062             emitGetArg(instruction[i + 3].u.operand, X86::edx);
1063             emitJumpSlowCaseIfNotImms(X86::eax, X86::edx, i);
1064             m_jit.xorl_rr(X86::edx, X86::eax);
1065             emitFastArithReTagImmediate(X86::eax);
1066             emitPutResult(instruction[i + 1].u.operand);
1067             i += 4;
1068             break;
1069         }
1070         case op_new_regexp: {
1071             RegExp* regExp = m_codeBlock->regexps[instruction[i + 2].u.operand].get();
1072             emitPutArgConstant(reinterpret_cast<unsigned>(regExp), 0);
1073             emitCall(i, Machine::cti_op_new_regexp);
1074             emitPutResult(instruction[i + 1].u.operand);
1075             i += 3;
1076             break;
1077         }
1078         case op_bitor: {
1079             emitGetArg(instruction[i + 2].u.operand, X86::eax);
1080             emitGetArg(instruction[i + 3].u.operand, X86::edx);
1081             emitJumpSlowCaseIfNotImms(X86::eax, X86::edx, i);
1082             m_jit.orl_rr(X86::edx, X86::eax);
1083             emitPutResult(instruction[i + 1].u.operand);
1084             i += 4;
1085             break;
1086         }
1087         case op_call_eval: {
1088             compileOpCall(instruction, i, OpCallEval);
1089             i += 6;
1090             break;
1091         }
1092         case op_throw: {
1093             emitGetPutArg(instruction[i + 1].u.operand, 0, X86::ecx);
1094             emitCall(i, Machine::cti_op_throw);
1095             m_jit.addl_i8r(0x24, X86::esp);
1096             m_jit.popl_r(X86::edi);
1097             m_jit.popl_r(X86::esi);
1098             m_jit.ret();
1099             i += 2;
1100             break;
1101         }
1102         case op_get_pnames: {
1103             emitGetPutArg(instruction[i + 2].u.operand, 0, X86::ecx);
1104             emitCall(i, Machine::cti_op_get_pnames);
1105             emitPutResult(instruction[i + 1].u.operand);
1106             i += 3;
1107             break;
1108         }
1109         case op_next_pname: {
1110             emitGetPutArg(instruction[i + 2].u.operand, 0, X86::ecx);
1111             unsigned target = instruction[i + 3].u.operand;
1112             emitCall(i, Machine::cti_op_next_pname);
1113             m_jit.testl_rr(X86::eax, X86::eax);
1114             X86Assembler::JmpSrc endOfIter = m_jit.emitUnlinkedJe();
1115             emitPutResult(instruction[i + 1].u.operand);
1116             m_jmpTable.append(JmpTable(m_jit.emitUnlinkedJmp(), i + 3 + target));
1117             m_jit.link(endOfIter, m_jit.label());
1118             i += 4;
1119             break;
1120         }
1121         case op_push_scope: {
1122             emitGetPutArg(instruction[i + 1].u.operand, 0, X86::ecx);
1123             emitCall(i, Machine::cti_op_push_scope);
1124             i += 2;
1125             break;
1126         }
1127         case op_pop_scope: {
1128             emitCall(i, Machine::cti_op_pop_scope);
1129             i += 1;
1130             break;
1131         }
1132         case op_typeof: {
1133             emitGetPutArg(instruction[i + 2].u.operand, 0, X86::ecx);
1134             emitCall(i, Machine::cti_op_typeof);
1135             emitPutResult(instruction[i + 1].u.operand);
1136             i += 3;
1137             break;
1138         }
1139         CTI_COMPILE_BINARY_OP(op_stricteq)
1140         CTI_COMPILE_BINARY_OP(op_nstricteq)
1141         case op_to_jsnumber: {
1142             emitGetPutArg(instruction[i + 2].u.operand, 0, X86::ecx);
1143             emitCall(i, Machine::cti_op_to_jsnumber);
1144             emitPutResult(instruction[i + 1].u.operand);
1145             i += 3;
1146             break;
1147         }
1148         case op_in: {
1149             emitGetPutArg(instruction[i + 2].u.operand, 0, X86::ecx);
1150             emitGetPutArg(instruction[i + 3].u.operand, 4, X86::ecx);
1151             emitCall(i, Machine::cti_op_in);
1152             emitPutResult(instruction[i + 1].u.operand);
1153             i += 4;
1154             break;
1155         }
1156         case op_push_new_scope: {
1157             Identifier* ident = &(m_codeBlock->identifiers[instruction[i + 2].u.operand]);
1158             emitPutArgConstant(reinterpret_cast<unsigned>(ident), 0);
1159             emitGetPutArg(instruction[i + 3].u.operand, 4, X86::ecx);
1160             emitCall(i, Machine::cti_op_push_new_scope);
1161             emitPutResult(instruction[i + 1].u.operand);
1162             i += 4;
1163             break;
1164         }
1165         case op_catch: {
1166             emitGetCTIParam(CTI_ARGS_r, X86::edi); // edi := r
1167             emitGetCTIParam(CTI_ARGS_exec, X86::ecx);
1168             m_jit.movl_mr(OBJECT_OFFSET(ExecState, m_exception), X86::ecx, X86::eax);
1169             m_jit.movl_i32m(0, OBJECT_OFFSET(ExecState, m_exception), X86::ecx);
1170             emitPutResult(instruction[i + 1].u.operand);
1171             i += 2;
1172             break;
1173         }
1174         case op_jmp_scopes: {
1175             unsigned count = instruction[i + 1].u.operand;
1176             emitPutArgConstant(count, 0);
1177             emitCall(i, Machine::cti_op_jmp_scopes);
1178             unsigned target = instruction[i + 2].u.operand;
1179             m_jmpTable.append(JmpTable(m_jit.emitUnlinkedJmp(), i + 2 + target));
1180             i += 3;
1181             break;
1182         }
1183         case op_put_by_index: {
1184             emitGetPutArg(instruction[i + 1].u.operand, 0, X86::ecx);
1185             emitPutArgConstant(instruction[i + 2].u.operand, 4);
1186             emitGetPutArg(instruction[i + 3].u.operand, 8, X86::ecx);
1187             emitCall(i, Machine::cti_op_put_by_index);
1188             i += 4;
1189             break;
1190         }
1191         case op_switch_imm: {
1192             unsigned tableIndex = instruction[i + 1].u.operand;
1193             unsigned defaultOffset = instruction[i + 2].u.operand;
1194             unsigned scrutinee = instruction[i + 3].u.operand;
1195
1196             // create jump table for switch destinations, track this switch statement.
1197             SimpleJumpTable* jumpTable = &m_codeBlock->immediateSwitchJumpTables[tableIndex];
1198             m_switches.append(SwitchRecord(jumpTable, i, defaultOffset, SwitchRecord::Immediate));
1199             jumpTable->ctiOffsets.grow(jumpTable->branchOffsets.size());
1200
1201             emitGetPutArg(scrutinee, 0, X86::ecx);
1202             emitPutArgConstant(tableIndex, 4);
1203             emitCall(i, Machine::cti_op_switch_imm);
1204             m_jit.jmp_r(X86::eax);
1205             i += 4;
1206             break;
1207         }
1208         case op_switch_char: {
1209             unsigned tableIndex = instruction[i + 1].u.operand;
1210             unsigned defaultOffset = instruction[i + 2].u.operand;
1211             unsigned scrutinee = instruction[i + 3].u.operand;
1212
1213             // create jump table for switch destinations, track this switch statement.
1214             SimpleJumpTable* jumpTable = &m_codeBlock->characterSwitchJumpTables[tableIndex];
1215             m_switches.append(SwitchRecord(jumpTable, i, defaultOffset, SwitchRecord::Character));
1216             jumpTable->ctiOffsets.grow(jumpTable->branchOffsets.size());
1217
1218             emitGetPutArg(scrutinee, 0, X86::ecx);
1219             emitPutArgConstant(tableIndex, 4);
1220             emitCall(i, Machine::cti_op_switch_char);
1221             m_jit.jmp_r(X86::eax);
1222             i += 4;
1223             break;
1224         }
1225         case op_switch_string: {
1226             unsigned tableIndex = instruction[i + 1].u.operand;
1227             unsigned defaultOffset = instruction[i + 2].u.operand;
1228             unsigned scrutinee = instruction[i + 3].u.operand;
1229
1230             // create jump table for switch destinations, track this switch statement.
1231             StringJumpTable* jumpTable = &m_codeBlock->stringSwitchJumpTables[tableIndex];
1232             m_switches.append(SwitchRecord(jumpTable, i, defaultOffset));
1233
1234             emitGetPutArg(scrutinee, 0, X86::ecx);
1235             emitPutArgConstant(tableIndex, 4);
1236             emitCall(i, Machine::cti_op_switch_string);
1237             m_jit.jmp_r(X86::eax);
1238             i += 4;
1239             break;
1240         }
1241         case op_del_by_val: {
1242             emitGetPutArg(instruction[i + 2].u.operand, 0, X86::ecx);
1243             emitGetPutArg(instruction[i + 3].u.operand, 4, X86::ecx);
1244             emitCall(i, Machine::cti_op_del_by_val);
1245             emitPutResult(instruction[i + 1].u.operand);
1246             i += 4;
1247             break;
1248         }
1249         case op_put_getter: {
1250             emitGetPutArg(instruction[i + 1].u.operand, 0, X86::ecx);
1251             Identifier* ident = &(m_codeBlock->identifiers[instruction[i + 2].u.operand]);
1252             emitPutArgConstant(reinterpret_cast<unsigned>(ident), 4);
1253             emitGetPutArg(instruction[i + 3].u.operand, 8, X86::ecx);
1254             emitCall(i, Machine::cti_op_put_getter);
1255             i += 4;
1256             break;
1257         }
1258         case op_put_setter: {
1259             emitGetPutArg(instruction[i + 1].u.operand, 0, X86::ecx);
1260             Identifier* ident = &(m_codeBlock->identifiers[instruction[i + 2].u.operand]);
1261             emitPutArgConstant(reinterpret_cast<unsigned>(ident), 4);
1262             emitGetPutArg(instruction[i + 3].u.operand, 8, X86::ecx);
1263             emitCall(i, Machine::cti_op_put_setter);
1264             i += 4;
1265             break;
1266         }
1267         case op_new_error: {
1268             JSValue* message = m_codeBlock->unexpectedConstants[instruction[i + 3].u.operand];
1269             emitPutArgConstant(instruction[i + 2].u.operand, 0);
1270             emitPutArgConstant(reinterpret_cast<unsigned>(message), 4);
1271             emitPutArgConstant(m_codeBlock->lineNumberForVPC(&instruction[i]), 8);
1272             emitCall(i, Machine::cti_op_new_error);
1273             emitPutResult(instruction[i + 1].u.operand);
1274             i += 4;
1275             break;
1276         }
1277         case op_debug: {
1278             emitPutArgConstant(instruction[i + 1].u.operand, 0);
1279             emitPutArgConstant(instruction[i + 2].u.operand, 4);
1280             emitPutArgConstant(instruction[i + 3].u.operand, 8);
1281             emitCall(i, Machine::cti_op_debug);
1282             i += 4;
1283             break;
1284         }
1285         case op_eq_null: {
1286             emitGetPutArg(instruction[i + 2].u.operand, 0, X86::ecx);
1287             emitCall(i, Machine::cti_op_eq_null);
1288             emitPutResult(instruction[i + 1].u.operand);
1289             i += 3;
1290             break;
1291         }
1292         case op_neq_null: {
1293             emitGetPutArg(instruction[i + 2].u.operand, 0, X86::ecx);
1294             emitCall(i, Machine::cti_op_neq_null);
1295             emitPutResult(instruction[i + 1].u.operand);
1296             i += 3;
1297             break;
1298         }
1299         case op_get_array_length:
1300         case op_get_by_id_chain:
1301         case op_get_by_id_generic:
1302         case op_get_by_id_proto:
1303         case op_get_by_id_self:
1304         case op_get_string_length:
1305         case op_put_by_id_generic:
1306         case op_put_by_id_replace:
1307             ASSERT_NOT_REACHED();
1308         }
1309     }
1310 }
1311
1312
1313 void CTI::privateCompileLinkPass()
1314 {
1315     unsigned jmpTableCount = m_jmpTable.size();
1316     for (unsigned i = 0; i < jmpTableCount; ++i)
1317         m_jit.link(m_jmpTable[i].from, m_labels[m_jmpTable[i].to]);
1318     m_jmpTable.clear();
1319 }
1320
1321 #define CTI_COMPILE_BINARY_OP_SLOW_CASE(name) \
1322     case name: { \
1323         m_jit.link(iter->from, m_jit.label()); \
1324         emitGetPutArg(instruction[i + 2].u.operand, 0, X86::ecx); \
1325         emitGetPutArg(instruction[i + 3].u.operand, 4, X86::ecx); \
1326         emitCall(i, Machine::cti_##name); \
1327         emitPutResult(instruction[i + 1].u.operand); \
1328         i += 4; \
1329         break; \
1330     }
1331     
1332 void CTI::privateCompileSlowCases()
1333 {
1334     Instruction* instruction = m_codeBlock->instructions.begin();
1335     for (Vector<SlowCaseEntry>::iterator iter = m_slowCases.begin(); iter != m_slowCases.end(); ++iter) {
1336         int i = iter->to;
1337         m_jit.emitRestoreArgumentReference();
1338         switch (m_machine->getOpcodeID(instruction[i].u.opcode)) {
1339         case op_add: {
1340             unsigned dst = instruction[i + 1].u.operand;
1341             unsigned src2 = instruction[i + 3].u.operand;
1342             if (src2 < m_codeBlock->constantRegisters.size()) {
1343                 JSValue* value = m_codeBlock->constantRegisters[src2].jsValue(m_exec);
1344                 if (JSImmediate::isNumber(value)) {
1345                     X86Assembler::JmpSrc notImm = iter->from;
1346                     m_jit.link((++iter)->from, m_jit.label());
1347                     m_jit.subl_i32r(getDeTaggedConstantImmediate(value), X86::eax);
1348                     m_jit.link(notImm, m_jit.label());
1349                     emitPutArg(X86::eax, 0);
1350                     emitGetPutArg(src2, 4, X86::ecx);
1351                     emitCall(i, Machine::cti_op_add);
1352                     emitPutResult(dst);
1353                     i += 4;
1354                     break;
1355                 }
1356             }
1357
1358             ASSERT(!(static_cast<unsigned>(instruction[i + 2].u.operand) < m_codeBlock->constantRegisters.size()));
1359
1360             X86Assembler::JmpSrc notImm = iter->from;
1361             m_jit.link((++iter)->from, m_jit.label());
1362             m_jit.subl_rr(X86::edx, X86::eax);
1363             emitFastArithReTagImmediate(X86::eax);
1364             m_jit.link(notImm, m_jit.label());
1365             emitPutArg(X86::eax, 0);
1366             emitPutArg(X86::edx, 4);
1367             emitCall(i, Machine::cti_op_add);
1368             emitPutResult(dst);
1369             i += 4;
1370             break;
1371         }
1372         case op_get_by_val: {
1373             X86Assembler::JmpSrc notImm = iter->from;
1374             m_jit.link((++iter)->from, m_jit.label());
1375             m_jit.link((++iter)->from, m_jit.label());
1376             m_jit.link((++iter)->from, m_jit.label());
1377             emitFastArithIntToImmNoCheck(X86::edx);
1378             m_jit.link(notImm, m_jit.label());
1379             emitPutArg(X86::eax, 0);
1380             emitPutArg(X86::edx, 4);
1381             emitCall(i, Machine::cti_op_get_by_val);
1382             emitPutResult(instruction[i + 1].u.operand);
1383             i += 4;
1384             break;
1385         }
1386         case op_sub: {
1387             X86Assembler::JmpSrc notImm = iter->from;
1388             m_jit.link((++iter)->from, m_jit.label());
1389             m_jit.addl_rr(X86::edx, X86::eax);
1390             m_jit.link(notImm, m_jit.label());
1391             emitPutArg(X86::eax, 0);
1392             emitPutArg(X86::edx, 4);
1393             emitCall(i, Machine::cti_op_sub);
1394             emitPutResult(instruction[i + 1].u.operand);
1395             i += 4;
1396             break;
1397         }
1398         case op_rshift: {
1399             m_jit.link(iter->from, m_jit.label());
1400             m_jit.link((++iter)->from, m_jit.label());
1401             emitPutArg(X86::eax, 0);
1402             emitPutArg(X86::ecx, 4);
1403             emitCall(i, Machine::cti_op_rshift);
1404             emitPutResult(instruction[i + 1].u.operand);
1405             i += 4;
1406             break;
1407         }
1408         case op_lshift: {
1409             X86Assembler::JmpSrc notImm1 = iter->from;
1410             X86Assembler::JmpSrc notImm2 = (++iter)->from;
1411             m_jit.link((++iter)->from, m_jit.label());
1412             emitGetArg(instruction[i + 2].u.operand, X86::eax);
1413             emitGetArg(instruction[i + 3].u.operand, X86::ecx);
1414             m_jit.link(notImm1, m_jit.label());
1415             m_jit.link(notImm2, m_jit.label());
1416             emitPutArg(X86::eax, 0);
1417             emitPutArg(X86::ecx, 4);
1418             emitCall(i, Machine::cti_op_lshift);
1419             emitPutResult(instruction[i + 1].u.operand);
1420             i += 4;
1421             break;
1422         }
1423         case op_loop_if_less: {
1424             emitSlowScriptCheck(i);
1425
1426             unsigned target = instruction[i + 3].u.operand;
1427             JSValue* src2imm = getConstantImmediateNumericArg(instruction[i + 2].u.operand);
1428             if (src2imm) {
1429                 m_jit.link(iter->from, m_jit.label());
1430                 emitPutArg(X86::edx, 0);
1431                 emitGetPutArg(instruction[i + 2].u.operand, 4, X86::ecx);
1432                 emitCall(i, Machine::cti_op_loop_if_less);
1433                 m_jit.testl_rr(X86::eax, X86::eax);
1434                 m_jit.link(m_jit.emitUnlinkedJne(), m_labels[i + 3 + target]);
1435             } else {
1436                 m_jit.link(iter->from, m_jit.label());
1437                 m_jit.link((++iter)->from, m_jit.label());
1438                 emitPutArg(X86::eax, 0);
1439                 emitPutArg(X86::edx, 4);
1440                 emitCall(i, Machine::cti_op_loop_if_less);
1441                 m_jit.testl_rr(X86::eax, X86::eax);
1442                 m_jit.link(m_jit.emitUnlinkedJne(), m_labels[i + 3 + target]);
1443             }
1444             i += 4;
1445             break;
1446         }
1447         case op_pre_inc: {
1448             unsigned srcDst = instruction[i + 1].u.operand;
1449             X86Assembler::JmpSrc notImm = iter->from;
1450             m_jit.link((++iter)->from, m_jit.label());
1451             m_jit.subl_i8r(getDeTaggedConstantImmediate(JSImmediate::oneImmediate()), X86::eax);
1452             m_jit.link(notImm, m_jit.label());
1453             emitPutArg(X86::eax, 0);
1454             emitCall(i, Machine::cti_op_pre_inc);
1455             emitPutResult(srcDst);
1456             i += 2;
1457             break;
1458         }
1459         case op_put_by_val: {
1460             X86Assembler::JmpSrc notImm = iter->from;
1461             m_jit.link((++iter)->from, m_jit.label());
1462             m_jit.link((++iter)->from, m_jit.label());
1463             m_jit.link((++iter)->from, m_jit.label());
1464             emitFastArithIntToImmNoCheck(X86::edx);
1465             m_jit.link(notImm, m_jit.label());
1466             emitPutArg(X86::eax, 0);
1467             emitPutArg(X86::edx, 4);
1468             emitPutArg(X86::ecx, 8);
1469             emitCall(i, Machine::cti_op_put_by_val);
1470             i += 4;
1471             break;
1472         }
1473         case op_loop_if_true: {
1474             emitSlowScriptCheck(i);
1475
1476             m_jit.link(iter->from, m_jit.label());
1477             emitPutArg(X86::eax, 0);
1478             emitCall(i, Machine::cti_op_jtrue);
1479             m_jit.testl_rr(X86::eax, X86::eax);
1480             unsigned target = instruction[i + 2].u.operand;
1481             m_jit.link(m_jit.emitUnlinkedJne(), m_labels[i + 2 + target]);
1482             i += 3;
1483             break;
1484         }
1485         case op_pre_dec: {
1486             unsigned srcDst = instruction[i + 1].u.operand;
1487             X86Assembler::JmpSrc notImm = iter->from;
1488             m_jit.link((++iter)->from, m_jit.label());
1489             m_jit.addl_i8r(getDeTaggedConstantImmediate(JSImmediate::oneImmediate()), X86::eax);
1490             m_jit.link(notImm, m_jit.label());
1491             emitPutArg(X86::eax, 0);
1492             emitCall(i, Machine::cti_op_pre_dec);
1493             emitPutResult(srcDst);
1494             i += 2;
1495             break;
1496         }
1497         case op_jnless: {
1498             unsigned target = instruction[i + 3].u.operand;
1499             JSValue* src2imm = getConstantImmediateNumericArg(instruction[i + 2].u.operand);
1500             if (src2imm) {
1501                 m_jit.link(iter->from, m_jit.label());
1502                 emitPutArg(X86::edx, 0);
1503                 emitGetPutArg(instruction[i + 2].u.operand, 4, X86::ecx);
1504                 emitCall(i, Machine::cti_op_jless);
1505                 m_jit.testl_rr(X86::eax, X86::eax);
1506                 m_jit.link(m_jit.emitUnlinkedJe(), m_labels[i + 3 + target]);
1507             } else {
1508                 m_jit.link(iter->from, m_jit.label());
1509                 m_jit.link((++iter)->from, m_jit.label());
1510                 emitPutArg(X86::eax, 0);
1511                 emitPutArg(X86::edx, 4);
1512                 emitCall(i, Machine::cti_op_jless);
1513                 m_jit.testl_rr(X86::eax, X86::eax);
1514                 m_jit.link(m_jit.emitUnlinkedJe(), m_labels[i + 3 + target]);
1515             }
1516             i += 4;
1517             break;
1518         }
1519         case op_not: {
1520             m_jit.link(iter->from, m_jit.label());
1521             m_jit.xorl_i8r(JSImmediate::FullTagTypeBool, X86::eax);
1522             emitPutArg(X86::eax, 0);
1523             emitCall(i, Machine::cti_op_not);
1524             emitPutResult(instruction[i + 1].u.operand);
1525             i += 3;
1526             break;
1527         }
1528         case op_jfalse: {
1529             m_jit.link(iter->from, m_jit.label());
1530             emitPutArg(X86::eax, 0);
1531             emitCall(i, Machine::cti_op_jtrue);
1532             m_jit.testl_rr(X86::eax, X86::eax);
1533             unsigned target = instruction[i + 2].u.operand;
1534             m_jit.link(m_jit.emitUnlinkedJe(), m_labels[i + 2 + target]); // inverted!
1535             i += 3;
1536             break;
1537         }
1538         case op_post_inc: {
1539             unsigned srcDst = instruction[i + 2].u.operand;
1540             m_jit.link(iter->from, m_jit.label());
1541             m_jit.link((++iter)->from, m_jit.label());
1542             emitPutArg(X86::eax, 0);
1543             emitCall(i, Machine::cti_op_post_inc);
1544             emitPutResult(instruction[i + 1].u.operand);
1545             emitGetCTIParam(CTI_ARGS_2ndResult, X86::eax);
1546             emitPutResult(srcDst);
1547             i += 3;
1548             break;
1549         }
1550         case op_bitnot: {
1551             m_jit.link(iter->from, m_jit.label());
1552             emitPutArg(X86::eax, 0);
1553             emitCall(i, Machine::cti_op_bitnot);
1554             emitPutResult(instruction[i + 1].u.operand);
1555             i += 3;
1556             break;
1557         }
1558         case op_bitand: {
1559             unsigned src1 = instruction[i + 2].u.operand;
1560             unsigned src2 = instruction[i + 3].u.operand;
1561             unsigned dst = instruction[i + 1].u.operand;
1562             if (getConstantImmediateNumericArg(src1)) {
1563                 m_jit.link(iter->from, m_jit.label());
1564                 emitGetPutArg(src1, 0, X86::ecx);
1565                 emitPutArg(X86::eax, 4);
1566                 emitCall(i, Machine::cti_op_bitand);
1567                 emitPutResult(dst);
1568             } else if (getConstantImmediateNumericArg(src2)) {
1569                 m_jit.link(iter->from, m_jit.label());
1570                 emitPutArg(X86::eax, 0);
1571                 emitGetPutArg(src2, 4, X86::ecx);
1572                 emitCall(i, Machine::cti_op_bitand);
1573                 emitPutResult(dst);
1574             } else {
1575                 m_jit.link(iter->from, m_jit.label());
1576                 emitGetPutArg(src1, 0, X86::ecx);
1577                 emitPutArg(X86::edx, 4);
1578                 emitCall(i, Machine::cti_op_bitand);
1579                 emitPutResult(dst);
1580             }
1581             i += 4;
1582             break;
1583         }
1584         case op_jtrue: {
1585             m_jit.link(iter->from, m_jit.label());
1586             emitPutArg(X86::eax, 0);
1587             emitCall(i, Machine::cti_op_jtrue);
1588             m_jit.testl_rr(X86::eax, X86::eax);
1589             unsigned target = instruction[i + 2].u.operand;
1590             m_jit.link(m_jit.emitUnlinkedJne(), m_labels[i + 2 + target]);
1591             i += 3;
1592             break;
1593         }
1594         case op_post_dec: {
1595             unsigned srcDst = instruction[i + 2].u.operand;
1596             m_jit.link(iter->from, m_jit.label());
1597             m_jit.link((++iter)->from, m_jit.label());
1598             emitPutArg(X86::eax, 0);
1599             emitCall(i, Machine::cti_op_post_dec);
1600             emitPutResult(instruction[i + 1].u.operand);
1601             emitGetCTIParam(CTI_ARGS_2ndResult, X86::eax);
1602             emitPutResult(srcDst);
1603             i += 3;
1604             break;
1605         }
1606         case op_bitxor: {
1607             m_jit.link(iter->from, m_jit.label());
1608             emitPutArg(X86::eax, 0);
1609             emitPutArg(X86::edx, 4);
1610             emitCall(i, Machine::cti_op_bitxor);
1611             emitPutResult(instruction[i + 1].u.operand);
1612             i += 4;
1613             break;
1614         }
1615         case op_bitor: {
1616             m_jit.link(iter->from, m_jit.label());
1617             emitPutArg(X86::eax, 0);
1618             emitPutArg(X86::edx, 4);
1619             emitCall(i, Machine::cti_op_bitor);
1620             emitPutResult(instruction[i + 1].u.operand);
1621             i += 4;
1622             break;
1623         }
1624         case op_mod: {
1625             X86Assembler::JmpSrc notImm1 = iter->from;
1626             X86Assembler::JmpSrc notImm2 = (++iter)->from;
1627             m_jit.link((++iter)->from, m_jit.label());
1628             emitFastArithReTagImmediate(X86::eax);
1629             emitFastArithReTagImmediate(X86::ecx);
1630             m_jit.link(notImm1, m_jit.label());
1631             m_jit.link(notImm2, m_jit.label());
1632             emitPutArg(X86::eax, 0);
1633             emitPutArg(X86::ecx, 4);
1634             emitCall(i, Machine::cti_op_mod);
1635             emitPutResult(instruction[i + 1].u.operand);
1636             i += 4;
1637             break;
1638         }
1639         CTI_COMPILE_BINARY_OP_SLOW_CASE(op_mul);
1640         default:
1641             ASSERT_NOT_REACHED();
1642             break;
1643         }
1644
1645         m_jit.link(m_jit.emitUnlinkedJmp(), m_labels[i]);
1646     }
1647 }
1648
1649 void CTI::privateCompile()
1650 {
1651     // Could use a popl_m, but would need to offset the following instruction if so.
1652     m_jit.popl_r(X86::ecx);
1653     emitGetCTIParam(CTI_ARGS_r, X86::edi); // edi := r
1654     emitPutToCallFrameHeader(X86::ecx, RegisterFile::CTIReturnEIP);
1655
1656     privateCompileMainPass();
1657     privateCompileLinkPass();
1658     privateCompileSlowCases();
1659
1660     ASSERT(m_jmpTable.isEmpty());
1661
1662     void* code = m_jit.copy();
1663     ASSERT(code);
1664
1665     // Translate vPC offsets into addresses in JIT generated code, for switch tables.
1666     for (unsigned i = 0; i < m_switches.size(); ++i) {
1667         SwitchRecord record = m_switches[i];
1668         unsigned opcodeIndex = record.m_opcodeIndex;
1669
1670         if (record.m_type != SwitchRecord::String) {
1671             ASSERT(record.m_type == SwitchRecord::Immediate || record.m_type == SwitchRecord::Character); 
1672             ASSERT(record.m_jumpTable.m_simpleJumpTable->branchOffsets.size() == record.m_jumpTable.m_simpleJumpTable->ctiOffsets.size());
1673
1674             record.m_jumpTable.m_simpleJumpTable->ctiDefault = m_jit.getRelocatedAddress(code, m_labels[opcodeIndex + 3 + record.m_defaultOffset]);
1675
1676             for (unsigned j = 0; j < record.m_jumpTable.m_simpleJumpTable->branchOffsets.size(); ++j) {
1677                 unsigned offset = record.m_jumpTable.m_simpleJumpTable->branchOffsets[j];
1678                 record.m_jumpTable.m_simpleJumpTable->ctiOffsets[j] = offset ? m_jit.getRelocatedAddress(code, m_labels[opcodeIndex + 3 + offset]) : record.m_jumpTable.m_simpleJumpTable->ctiDefault;
1679             }
1680         } else {
1681             ASSERT(record.m_type == SwitchRecord::String);
1682
1683             record.m_jumpTable.m_stringJumpTable->ctiDefault = m_jit.getRelocatedAddress(code, m_labels[opcodeIndex + 3 + record.m_defaultOffset]);
1684
1685             StringJumpTable::StringOffsetTable::iterator end = record.m_jumpTable.m_stringJumpTable->offsetTable.end();            
1686             for (StringJumpTable::StringOffsetTable::iterator it = record.m_jumpTable.m_stringJumpTable->offsetTable.begin(); it != end; ++it) {
1687                 unsigned offset = it->second.branchOffset;
1688                 it->second.ctiOffset = offset ? m_jit.getRelocatedAddress(code, m_labels[opcodeIndex + 3 + offset]) : record.m_jumpTable.m_stringJumpTable->ctiDefault;
1689             }
1690         }
1691     }
1692
1693     for (Vector<HandlerInfo>::iterator iter = m_codeBlock->exceptionHandlers.begin(); iter != m_codeBlock->exceptionHandlers.end(); ++iter)
1694          iter->nativeCode = m_jit.getRelocatedAddress(code, m_labels[iter->target]);
1695
1696     // FIXME: There doesn't seem to be a way to hint to a hashmap that it should make a certain capacity available;
1697     // could be faster if we could do something like this:
1698     // m_codeBlock->ctiReturnAddressVPCMap.grow(m_calls.size());
1699     for (Vector<CallRecord>::iterator iter = m_calls.begin(); iter != m_calls.end(); ++iter) {
1700         X86Assembler::link(code, iter->from, iter->to);
1701         m_codeBlock->ctiReturnAddressVPCMap.add(m_jit.getRelocatedAddress(code, iter->from), iter->opcodeIndex);
1702     }
1703
1704     // Link absolute addresses for jsr
1705     for (Vector<JSRInfo>::iterator iter = m_jsrSites.begin(); iter != m_jsrSites.end(); ++iter)
1706         X86Assembler::linkAbsoluteAddress(code, iter->addrPosition, iter->target);
1707
1708     m_codeBlock->ctiCode = code;
1709 }
1710
1711 void* CTI::privateCompileGetByIdSelf(StructureID* structureID, size_t cachedOffset)
1712 {
1713     // Check eax is an object of the right StructureID.
1714     m_jit.testl_i32r(JSImmediate::TagMask, X86::eax);
1715     X86Assembler::JmpSrc failureCases1 = m_jit.emitUnlinkedJne();
1716     m_jit.cmpl_i32m(reinterpret_cast<uint32_t>(structureID), OBJECT_OFFSET(JSCell, m_structureID), X86::eax);
1717     X86Assembler::JmpSrc failureCases2 = m_jit.emitUnlinkedJne();
1718
1719     // Checks out okay! - getDirectOffset
1720     m_jit.movl_mr(OBJECT_OFFSET(JSObject, m_propertyStorage), X86::eax, X86::eax);
1721     m_jit.movl_mr(cachedOffset * sizeof(JSValue*), X86::eax, X86::eax);
1722     m_jit.ret();
1723
1724     void* code = m_jit.copy();
1725     ASSERT(code);
1726
1727     X86Assembler::link(code, failureCases1, reinterpret_cast<void*>(Machine::cti_op_get_by_id_fail));
1728     X86Assembler::link(code, failureCases2, reinterpret_cast<void*>(Machine::cti_op_get_by_id_fail));
1729     
1730     m_codeBlock->structureIDAccessStubs.append(code);
1731     
1732     return code;
1733 }
1734
1735 void* CTI::privateCompileGetByIdProto(ExecState* exec, StructureID* structureID, StructureID* prototypeStructureID, size_t cachedOffset)
1736 {
1737     // The prototype object definitely exists (if this stub exists the CodeBlock is referencing a StructureID that is
1738     // referencing the prototype object - let's speculatively load it's table nice and early!)
1739     JSObject* protoObject = static_cast<JSObject*>(structureID->prototypeForLookup(exec));
1740     PropertyStorage* protoPropertyStorage = &protoObject->m_propertyStorage;
1741     m_jit.movl_mr(static_cast<void*>(protoPropertyStorage), X86::edx);
1742
1743     // check eax is an object of the right StructureID.
1744     m_jit.testl_i32r(JSImmediate::TagMask, X86::eax);
1745     X86Assembler::JmpSrc failureCases1 = m_jit.emitUnlinkedJne();
1746     m_jit.cmpl_i32m(reinterpret_cast<uint32_t>(structureID), OBJECT_OFFSET(JSCell, m_structureID), X86::eax);
1747     X86Assembler::JmpSrc failureCases2 = m_jit.emitUnlinkedJne();
1748
1749     // Check the prototype object's StructureID had not changed.
1750     StructureID** protoStructureIDAddress = &(protoObject->m_structureID);
1751     m_jit.cmpl_i32m(reinterpret_cast<uint32_t>(prototypeStructureID), static_cast<void*>(protoStructureIDAddress));
1752     X86Assembler::JmpSrc failureCases3 = m_jit.emitUnlinkedJne();
1753
1754     // Checks out okay! - getDirectOffset
1755     m_jit.movl_mr(cachedOffset * sizeof(JSValue*), X86::edx, X86::eax);
1756
1757     m_jit.ret();
1758
1759     void* code = m_jit.copy();
1760     ASSERT(code);
1761
1762     X86Assembler::link(code, failureCases1, reinterpret_cast<void*>(Machine::cti_op_get_by_id_fail));
1763     X86Assembler::link(code, failureCases2, reinterpret_cast<void*>(Machine::cti_op_get_by_id_fail));
1764     X86Assembler::link(code, failureCases3, reinterpret_cast<void*>(Machine::cti_op_get_by_id_fail));
1765
1766     m_codeBlock->structureIDAccessStubs.append(code);
1767
1768     return code;
1769 }
1770
1771 void* CTI::privateCompileGetByIdChain(ExecState* exec, StructureID* structureID, StructureIDChain* chain, size_t count, size_t cachedOffset)
1772 {
1773     ASSERT(count);
1774     
1775     Vector<X86Assembler::JmpSrc> bucketsOfFail;
1776
1777     // Check eax is an object of the right StructureID.
1778     m_jit.testl_i32r(JSImmediate::TagMask, X86::eax);
1779     bucketsOfFail.append(m_jit.emitUnlinkedJne());
1780     m_jit.cmpl_i32m(reinterpret_cast<uint32_t>(structureID), OBJECT_OFFSET(JSCell, m_structureID), X86::eax);
1781     bucketsOfFail.append(m_jit.emitUnlinkedJne());
1782
1783     StructureID* currStructureID = structureID;
1784     RefPtr<StructureID>* chainEntries = chain->head();
1785     JSObject* protoObject = 0;
1786     for (unsigned i = 0; i<count; ++i) {
1787         protoObject = static_cast<JSObject*>(currStructureID->prototypeForLookup(exec));
1788         currStructureID = chainEntries[i].get();
1789
1790         // Check the prototype object's StructureID had not changed.
1791         StructureID** protoStructureIDAddress = &(protoObject->m_structureID);
1792         m_jit.cmpl_i32m(reinterpret_cast<uint32_t>(currStructureID), static_cast<void*>(protoStructureIDAddress));
1793         bucketsOfFail.append(m_jit.emitUnlinkedJne());
1794     }
1795     ASSERT(protoObject);
1796
1797     PropertyStorage* protoPropertyStorage = &protoObject->m_propertyStorage;
1798     m_jit.movl_mr(static_cast<void*>(protoPropertyStorage), X86::edx);
1799     m_jit.movl_mr(cachedOffset * sizeof(JSValue*), X86::edx, X86::eax);
1800     m_jit.ret();
1801
1802     bucketsOfFail.append(m_jit.emitUnlinkedJmp());
1803
1804     void* code = m_jit.copy();
1805     ASSERT(code);
1806
1807     for (unsigned i = 0; i < bucketsOfFail.size(); ++i)
1808         X86Assembler::link(code, bucketsOfFail[i], reinterpret_cast<void*>(Machine::cti_op_get_by_id_fail));
1809     m_codeBlock->structureIDAccessStubs.append(code);
1810     return code;
1811 }
1812
1813 void* CTI::privateCompilePutByIdReplace(StructureID* structureID, size_t cachedOffset)
1814 {
1815     // check eax is an object of the right StructureID.
1816     m_jit.testl_i32r(JSImmediate::TagMask, X86::eax);
1817     X86Assembler::JmpSrc failureCases1 = m_jit.emitUnlinkedJne();
1818     m_jit.cmpl_i32m(reinterpret_cast<uint32_t>(structureID), OBJECT_OFFSET(JSCell, m_structureID), X86::eax);
1819     X86Assembler::JmpSrc failureCases2 = m_jit.emitUnlinkedJne();
1820
1821     // checks out okay! - putDirectOffset
1822     m_jit.movl_mr(OBJECT_OFFSET(JSObject, m_propertyStorage), X86::eax, X86::eax);
1823     m_jit.movl_rm(X86::edx, cachedOffset * sizeof(JSValue*), X86::eax);
1824     m_jit.ret();
1825
1826     void* code = m_jit.copy();
1827     ASSERT(code);
1828     
1829     X86Assembler::link(code, failureCases1, reinterpret_cast<void*>(Machine::cti_op_put_by_id_fail));
1830     X86Assembler::link(code, failureCases2, reinterpret_cast<void*>(Machine::cti_op_put_by_id_fail));
1831
1832     m_codeBlock->structureIDAccessStubs.append(code);
1833     
1834     return code;
1835 }
1836
1837 void* CTI::privateArrayLengthTrampoline()
1838 {
1839     // Check eax is an array
1840     m_jit.testl_i32r(JSImmediate::TagMask, X86::eax);
1841     X86Assembler::JmpSrc failureCases1 = m_jit.emitUnlinkedJne();
1842     m_jit.cmpl_i32m(reinterpret_cast<unsigned>(m_machine->m_jsArrayVptr), X86::eax);
1843     X86Assembler::JmpSrc failureCases2 = m_jit.emitUnlinkedJne();
1844
1845     // Checks out okay! - get the length from the storage
1846     m_jit.movl_mr(OBJECT_OFFSET(JSArray, m_storage), X86::eax, X86::eax);
1847     m_jit.movl_mr(OBJECT_OFFSET(ArrayStorage, m_length), X86::eax, X86::eax);
1848
1849     m_jit.addl_rr(X86::eax, X86::eax);
1850     X86Assembler::JmpSrc failureCases3 = m_jit.emitUnlinkedJo();
1851     m_jit.addl_i8r(1, X86::eax);
1852     
1853     m_jit.ret();
1854
1855     void* code = m_jit.copy();
1856     ASSERT(code);
1857
1858     X86Assembler::link(code, failureCases1, reinterpret_cast<void*>(Machine::cti_op_get_by_id_fail));
1859     X86Assembler::link(code, failureCases2, reinterpret_cast<void*>(Machine::cti_op_get_by_id_fail));
1860     X86Assembler::link(code, failureCases3, reinterpret_cast<void*>(Machine::cti_op_get_by_id_fail));
1861     
1862     return code;
1863 }
1864
1865 void* CTI::privateStringLengthTrampoline()
1866 {
1867     // Check eax is a string
1868     m_jit.testl_i32r(JSImmediate::TagMask, X86::eax);
1869     X86Assembler::JmpSrc failureCases1 = m_jit.emitUnlinkedJne();
1870     m_jit.cmpl_i32m(reinterpret_cast<unsigned>(m_machine->m_jsStringVptr), X86::eax);
1871     X86Assembler::JmpSrc failureCases2 = m_jit.emitUnlinkedJne();
1872
1873     // Checks out okay! - get the length from the Ustring.
1874     m_jit.movl_mr(OBJECT_OFFSET(JSString, m_value) + OBJECT_OFFSET(UString, m_rep), X86::eax, X86::eax);
1875     m_jit.movl_mr(OBJECT_OFFSET(UString::Rep, len), X86::eax, X86::eax);
1876
1877     m_jit.addl_rr(X86::eax, X86::eax);
1878     X86Assembler::JmpSrc failureCases3 = m_jit.emitUnlinkedJo();
1879     m_jit.addl_i8r(1, X86::eax);
1880     
1881     m_jit.ret();
1882
1883     void* code = m_jit.copy();
1884     ASSERT(code);
1885
1886     X86Assembler::link(code, failureCases1, reinterpret_cast<void*>(Machine::cti_op_get_by_id_fail));
1887     X86Assembler::link(code, failureCases2, reinterpret_cast<void*>(Machine::cti_op_get_by_id_fail));
1888     X86Assembler::link(code, failureCases3, reinterpret_cast<void*>(Machine::cti_op_get_by_id_fail));
1889
1890     return code;
1891 }
1892
1893 void CTI::emitGetVariableObjectRegister(X86Assembler::RegisterID variableObject, int index, X86Assembler::RegisterID dst)
1894 {
1895     m_jit.movl_mr(JSVariableObject::offsetOf_d(), variableObject, dst);
1896     m_jit.movl_mr(JSVariableObject::offsetOf_Data_registers(), dst, dst);
1897     m_jit.movl_mr(index * sizeof(Register), dst, dst);
1898 }
1899
1900 void CTI::emitPutVariableObjectRegister(X86Assembler::RegisterID src, X86Assembler::RegisterID variableObject, int index)
1901 {
1902     m_jit.movl_mr(JSVariableObject::offsetOf_d(), variableObject, variableObject);
1903     m_jit.movl_mr(JSVariableObject::offsetOf_Data_registers(), variableObject, variableObject);
1904     m_jit.movl_rm(src, index * sizeof(Register), variableObject);
1905 }
1906
1907 #if ENABLE(WREC)
1908
1909 void* CTI::compileRegExp(ExecState* exec, const UString& pattern, unsigned* numSubpatterns_ptr, const char** error_ptr, bool ignoreCase, bool multiline)
1910 {
1911     // TODO: better error messages
1912     if (pattern.size() > MaxPatternSize) {
1913         *error_ptr = "regular expression too large";
1914         return 0;
1915     }
1916
1917     X86Assembler jit(exec->machine()->jitCodeBuffer());
1918     WRECParser parser(pattern, ignoreCase, multiline, jit);
1919     
1920     jit.emitConvertToFastCall();
1921     // (0) Setup:
1922     //     Preserve regs & initialize outputRegister.
1923     jit.pushl_r(WRECGenerator::outputRegister);
1924     jit.pushl_r(WRECGenerator::currentValueRegister);
1925     // push pos onto the stack, both to preserve and as a parameter available to parseDisjunction
1926     jit.pushl_r(WRECGenerator::currentPositionRegister);
1927     // load output pointer
1928     jit.movl_mr(16
1929 #if COMPILER(MSVC)
1930                     + 3 * sizeof(void*)
1931 #endif
1932                     , X86::esp, WRECGenerator::outputRegister);
1933     
1934     // restart point on match fail.
1935     WRECGenerator::JmpDst nextLabel = jit.label();
1936
1937     // (1) Parse Disjunction:
1938     
1939     //     Parsing the disjunction should fully consume the pattern.
1940     JmpSrcVector failures;
1941     parser.parseDisjunction(failures);
1942     if (parser.isEndOfPattern()) {
1943         parser.m_err = WRECParser::Error_malformedPattern;
1944     }
1945     if (parser.m_err) {
1946         // TODO: better error messages
1947         *error_ptr = "TODO: better error messages";
1948         return 0;
1949     }
1950
1951     // (2) Success:
1952     //     Set return value & pop registers from the stack.
1953
1954     jit.testl_rr(WRECGenerator::outputRegister, WRECGenerator::outputRegister);
1955     WRECGenerator::JmpSrc noOutput = jit.emitUnlinkedJe();
1956
1957     jit.movl_rm(WRECGenerator::currentPositionRegister, 4, WRECGenerator::outputRegister);
1958     jit.popl_r(X86::eax);
1959     jit.movl_rm(X86::eax, WRECGenerator::outputRegister);
1960     jit.popl_r(WRECGenerator::currentValueRegister);
1961     jit.popl_r(WRECGenerator::outputRegister);
1962     jit.ret();
1963     
1964     jit.link(noOutput, jit.label());
1965     
1966     jit.popl_r(X86::eax);
1967     jit.movl_rm(X86::eax, WRECGenerator::outputRegister);
1968     jit.popl_r(WRECGenerator::currentValueRegister);
1969     jit.popl_r(WRECGenerator::outputRegister);
1970     jit.ret();
1971
1972     // (3) Failure:
1973     //     All fails link to here.  Progress the start point & if it is within scope, loop.
1974     //     Otherwise, return fail value.
1975     WRECGenerator::JmpDst here = jit.label();
1976     for (unsigned i = 0; i < failures.size(); ++i)
1977         jit.link(failures[i], here);
1978     failures.clear();
1979
1980     jit.movl_mr(X86::esp, WRECGenerator::currentPositionRegister);
1981     jit.addl_i8r(1, WRECGenerator::currentPositionRegister);
1982     jit.movl_rm(WRECGenerator::currentPositionRegister, X86::esp);
1983     jit.cmpl_rr(WRECGenerator::lengthRegister, WRECGenerator::currentPositionRegister);
1984     jit.link(jit.emitUnlinkedJle(), nextLabel);
1985
1986     jit.addl_i8r(4, X86::esp);
1987
1988     jit.movl_i32r(-1, X86::eax);
1989     jit.popl_r(WRECGenerator::currentValueRegister);
1990     jit.popl_r(WRECGenerator::outputRegister);
1991     jit.ret();
1992
1993     *numSubpatterns_ptr = parser.m_numSubpatterns;
1994
1995     void* code = jit.copy();
1996     ASSERT(code);
1997     return code;
1998 }
1999
2000 #endif // ENABLE(WREC)
2001
2002 } // namespace JSC
2003
2004 #endif // ENABLE(CTI)