fourthTier: JITCode should abstract exactly how the JIT code is structured and where...
[WebKit-https.git] / Source / JavaScriptCore / jit / JITStubs.cpp
1 /*
2  * Copyright (C) 2008, 2009, 2013 Apple Inc. All rights reserved.
3  * Copyright (C) 2008 Cameron Zwarich <cwzwarich@uwaterloo.ca>
4  * Copyright (C) Research In Motion Limited 2010, 2011. All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  *
10  * 1.  Redistributions of source code must retain the above copyright
11  *     notice, this list of conditions and the following disclaimer.
12  * 2.  Redistributions in binary form must reproduce the above copyright
13  *     notice, this list of conditions and the following disclaimer in the
14  *     documentation and/or other materials provided with the distribution.
15  * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
16  *     its contributors may be used to endorse or promote products derived
17  *     from this software without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
20  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22  * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
23  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
26  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  */
30
31 #include "config.h"
32
33 #if ENABLE(JIT)
34 #include "JITStubs.h"
35
36 #include "CommonSlowPaths.h"
37 #include "Arguments.h"
38 #include "ArrayConstructor.h"
39 #include "CallFrame.h"
40 #include "CodeBlock.h"
41 #include "CodeProfiling.h"
42 #include "DFGOSREntry.h"
43 #include "Debugger.h"
44 #include "ExceptionHelpers.h"
45 #include "GetterSetter.h"
46 #include "Heap.h"
47 #include <wtf/InlineASM.h>
48 #include "JIT.h"
49 #include "JITExceptions.h"
50 #include "JSActivation.h"
51 #include "JSArray.h"
52 #include "JSFunction.h"
53 #include "JSGlobalObjectFunctions.h"
54 #include "JSNameScope.h"
55 #include "JSNotAnObject.h"
56 #include "JSPropertyNameIterator.h"
57 #include "JSString.h"
58 #include "JSWithScope.h"
59 #include "LegacyProfiler.h"
60 #include "NameInstance.h"
61 #include "ObjectConstructor.h"
62 #include "ObjectPrototype.h"
63 #include "Operations.h"
64 #include "Parser.h"
65 #include "RegExpObject.h"
66 #include "RegExpPrototype.h"
67 #include "Register.h"
68 #include "RepatchBuffer.h"
69 #include "SamplingTool.h"
70 #include "Strong.h"
71 #include "StructureRareDataInlines.h"
72 #include <wtf/StdLibExtras.h>
73 #include <stdarg.h>
74 #include <stdio.h>
75
76 using namespace std;
77
78 namespace JSC {
79
80 #if USE(JSVALUE32_64)
81
82 #if COMPILER(GCC) && CPU(X86)
83
84 // These ASSERTs remind you that, if you change the layout of JITStackFrame, you
85 // need to change the assembly trampolines below to match.
86 COMPILE_ASSERT(offsetof(struct JITStackFrame, code) % 16 == 0x0, JITStackFrame_maintains_16byte_stack_alignment);
87 COMPILE_ASSERT(offsetof(struct JITStackFrame, savedEBX) == 0x3c, JITStackFrame_stub_argument_space_matches_ctiTrampoline);
88 COMPILE_ASSERT(offsetof(struct JITStackFrame, callFrame) == 0x58, JITStackFrame_callFrame_offset_matches_ctiTrampoline);
89 COMPILE_ASSERT(offsetof(struct JITStackFrame, code) == 0x50, JITStackFrame_code_offset_matches_ctiTrampoline);
90
91 asm (
92 ".text\n"
93 ".globl " SYMBOL_STRING(ctiTrampoline) "\n"
94 HIDE_SYMBOL(ctiTrampoline) "\n"
95 SYMBOL_STRING(ctiTrampoline) ":" "\n"
96     "pushl %ebp" "\n"
97     "movl %esp, %ebp" "\n"
98     "pushl %esi" "\n"
99     "pushl %edi" "\n"
100     "pushl %ebx" "\n"
101     "subl $0x3c, %esp" "\n"
102     "movw $0x02FF, %bx" "\n"
103     "movw %bx, 0(%esp)" "\n"
104     "fldcw 0(%esp)" "\n"
105     "movl 0x58(%esp), %edi" "\n"
106     "call *0x50(%esp)" "\n"
107     "addl $0x3c, %esp" "\n"
108     "popl %ebx" "\n"
109     "popl %edi" "\n"
110     "popl %esi" "\n"
111     "popl %ebp" "\n"
112     "ffree %st(1)" "\n"
113     "ret" "\n"
114 ".globl " SYMBOL_STRING(ctiTrampolineEnd) "\n"
115 HIDE_SYMBOL(ctiTrampolineEnd) "\n"
116 SYMBOL_STRING(ctiTrampolineEnd) ":" "\n"
117 );
118
119 asm (
120 ".globl " SYMBOL_STRING(ctiVMThrowTrampoline) "\n"
121 HIDE_SYMBOL(ctiVMThrowTrampoline) "\n"
122 SYMBOL_STRING(ctiVMThrowTrampoline) ":" "\n"
123     "movl %esp, %ecx" "\n"
124     "call " LOCAL_REFERENCE(cti_vm_throw) "\n"
125     "int3" "\n"
126 );
127     
128 asm (
129 ".globl " SYMBOL_STRING(ctiOpThrowNotCaught) "\n"
130 HIDE_SYMBOL(ctiOpThrowNotCaught) "\n"
131 SYMBOL_STRING(ctiOpThrowNotCaught) ":" "\n"
132     "addl $0x3c, %esp" "\n"
133     "popl %ebx" "\n"
134     "popl %edi" "\n"
135     "popl %esi" "\n"
136     "popl %ebp" "\n"
137     "ret" "\n"
138 );
139     
140 #elif COMPILER(GCC) && CPU(X86_64)
141
142 // These ASSERTs remind you that, if you change the layout of JITStackFrame, you
143 // need to change the assembly trampolines below to match.
144 COMPILE_ASSERT(offsetof(struct JITStackFrame, code) % 32 == 0x0, JITStackFrame_maintains_32byte_stack_alignment);
145 COMPILE_ASSERT(offsetof(struct JITStackFrame, savedRBX) == 0x48, JITStackFrame_stub_argument_space_matches_ctiTrampoline);
146 COMPILE_ASSERT(offsetof(struct JITStackFrame, callFrame) == 0x90, JITStackFrame_callFrame_offset_matches_ctiTrampoline);
147 COMPILE_ASSERT(offsetof(struct JITStackFrame, code) == 0x80, JITStackFrame_code_offset_matches_ctiTrampoline);
148
149 asm (
150 ".globl " SYMBOL_STRING(ctiTrampoline) "\n"
151 HIDE_SYMBOL(ctiTrampoline) "\n"
152 SYMBOL_STRING(ctiTrampoline) ":" "\n"
153     "pushq %rbp" "\n"
154     "movq %rsp, %rbp" "\n"
155     "pushq %r12" "\n"
156     "pushq %r13" "\n"
157     "pushq %r14" "\n"
158     "pushq %r15" "\n"
159     "pushq %rbx" "\n"
160     "subq $0x48, %rsp" "\n"
161     "movq $512, %r12" "\n"
162     "movq $0xFFFF000000000000, %r14" "\n"
163     "movq $0xFFFF000000000002, %r15" "\n"
164     "movq 0x90(%rsp), %r13" "\n"
165     "call *0x80(%rsp)" "\n"
166     "addq $0x48, %rsp" "\n"
167     "popq %rbx" "\n"
168     "popq %r15" "\n"
169     "popq %r14" "\n"
170     "popq %r13" "\n"
171     "popq %r12" "\n"
172     "popq %rbp" "\n"
173     "ret" "\n"
174 ".globl " SYMBOL_STRING(ctiTrampolineEnd) "\n"
175 HIDE_SYMBOL(ctiTrampolineEnd) "\n"
176 SYMBOL_STRING(ctiTrampolineEnd) ":" "\n"
177 );
178
179 asm (
180 ".globl " SYMBOL_STRING(ctiVMThrowTrampoline) "\n"
181 HIDE_SYMBOL(ctiVMThrowTrampoline) "\n"
182 SYMBOL_STRING(ctiVMThrowTrampoline) ":" "\n"
183     "movq %rsp, %rdi" "\n"
184     "call " LOCAL_REFERENCE(cti_vm_throw) "\n"
185     "int3" "\n"
186 );
187
188 asm (
189 ".globl " SYMBOL_STRING(ctiOpThrowNotCaught) "\n"
190 HIDE_SYMBOL(ctiOpThrowNotCaught) "\n"
191 SYMBOL_STRING(ctiOpThrowNotCaught) ":" "\n"
192     "addq $0x48, %rsp" "\n"
193     "popq %rbx" "\n"
194     "popq %r15" "\n"
195     "popq %r14" "\n"
196     "popq %r13" "\n"
197     "popq %r12" "\n"
198     "popq %rbp" "\n"
199     "ret" "\n"
200 );
201
202 #elif (COMPILER(GCC) || COMPILER(RVCT)) && CPU(ARM_THUMB2)
203
204 #define THUNK_RETURN_ADDRESS_OFFSET      0x38
205 #define PRESERVED_RETURN_ADDRESS_OFFSET  0x3C
206 #define PRESERVED_R4_OFFSET              0x40
207 #define PRESERVED_R5_OFFSET              0x44
208 #define PRESERVED_R6_OFFSET              0x48
209 #define PRESERVED_R7_OFFSET              0x4C
210 #define PRESERVED_R8_OFFSET              0x50
211 #define PRESERVED_R9_OFFSET              0x54
212 #define PRESERVED_R10_OFFSET             0x58
213 #define PRESERVED_R11_OFFSET             0x5C
214 #define REGISTER_FILE_OFFSET             0x60
215 #define FIRST_STACK_ARGUMENT             0x68
216
217 #elif (COMPILER(GCC) || COMPILER(MSVC) || COMPILER(RVCT)) && CPU(ARM_TRADITIONAL)
218
219 // Also update the MSVC section (defined at DEFINE_STUB_FUNCTION)
220 // when changing one of the following values.
221 #define THUNK_RETURN_ADDRESS_OFFSET 64
222 #define PRESERVEDR4_OFFSET          68
223
224 #elif COMPILER(MSVC) && CPU(X86)
225
226 // These ASSERTs remind you that, if you change the layout of JITStackFrame, you
227 // need to change the assembly trampolines below to match.
228 COMPILE_ASSERT(offsetof(struct JITStackFrame, code) % 16 == 0x0, JITStackFrame_maintains_16byte_stack_alignment);
229 COMPILE_ASSERT(offsetof(struct JITStackFrame, savedEBX) == 0x3c, JITStackFrame_stub_argument_space_matches_ctiTrampoline);
230 COMPILE_ASSERT(offsetof(struct JITStackFrame, callFrame) == 0x58, JITStackFrame_callFrame_offset_matches_ctiTrampoline);
231 COMPILE_ASSERT(offsetof(struct JITStackFrame, code) == 0x50, JITStackFrame_code_offset_matches_ctiTrampoline);
232
233 extern "C" {
234
235     __declspec(naked) EncodedJSValue ctiTrampoline(void* code, JSStack*, CallFrame*, void* /*unused1*/, void* /*unused2*/, VM*)
236     {
237         __asm {
238             push ebp;
239             mov ebp, esp;
240             push esi;
241             push edi;
242             push ebx;
243             sub esp, 0x3c;
244             mov ecx, esp;
245             mov edi, [esp + 0x58];
246             call [esp + 0x50];
247             add esp, 0x3c;
248             pop ebx;
249             pop edi;
250             pop esi;
251             pop ebp;
252             ret;
253         }
254     }
255
256     __declspec(naked) void ctiVMThrowTrampoline()
257     {
258         __asm {
259             mov ecx, esp;
260             call cti_vm_throw;
261             add esp, 0x3c;
262             pop ebx;
263             pop edi;
264             pop esi;
265             pop ebp;
266             ret;
267         }
268     }
269
270     __declspec(naked) void ctiOpThrowNotCaught()
271     {
272         __asm {
273             add esp, 0x3c;
274             pop ebx;
275             pop edi;
276             pop esi;
277             pop ebp;
278             ret;
279         }
280     }
281 }
282
283 #elif CPU(MIPS)
284
285 #define PRESERVED_GP_OFFSET         60
286 #define PRESERVED_S0_OFFSET         64
287 #define PRESERVED_S1_OFFSET         68
288 #define PRESERVED_S2_OFFSET         72
289 #define PRESERVED_S3_OFFSET         76
290 #define PRESERVED_S4_OFFSET         80
291 #define PRESERVED_RETURN_ADDRESS_OFFSET 84
292 #define THUNK_RETURN_ADDRESS_OFFSET 88
293 #define REGISTER_FILE_OFFSET        92
294 #define GLOBAL_DATA_OFFSET         108
295 #define STACK_LENGTH               112
296 #elif CPU(SH4)
297 #define SYMBOL_STRING(name) #name
298 /* code (r4), JSStack* (r5), CallFrame* (r6), void* unused1 (r7), void* unused2(sp), VM (sp)*/
299
300 asm volatile (
301 ".text\n"
302 ".globl " SYMBOL_STRING(ctiTrampoline) "\n"
303 HIDE_SYMBOL(ctiTrampoline) "\n"
304 SYMBOL_STRING(ctiTrampoline) ":" "\n"
305     "mov.l r7, @-r15" "\n"
306     "mov.l r6, @-r15" "\n"
307     "mov.l r5, @-r15" "\n"
308     "mov.l r14, @-r15" "\n"
309     "sts.l pr, @-r15" "\n"
310     "mov.l r13, @-r15" "\n"
311     "mov.l r11, @-r15" "\n"
312     "mov.l r10, @-r15" "\n"
313     "add #-60, r15" "\n"
314     "mov r6, r14" "\n"
315     "jsr @r4" "\n"
316     "nop" "\n"
317     "add #60, r15" "\n"
318     "mov.l @r15+,r10" "\n"
319     "mov.l @r15+,r11" "\n"
320     "mov.l @r15+,r13" "\n"
321     "lds.l @r15+,pr" "\n"
322     "mov.l @r15+,r14" "\n"
323     "add #12, r15" "\n"
324     "rts" "\n"
325     "nop" "\n"
326 ".globl " SYMBOL_STRING(ctiTrampolineEnd) "\n"
327 HIDE_SYMBOL(ctiTrampolineEnd) "\n"
328 SYMBOL_STRING(ctiTrampolineEnd) ":" "\n"
329 );
330
331 asm volatile (
332 ".globl " SYMBOL_STRING(ctiVMThrowTrampoline) "\n"
333 HIDE_SYMBOL(ctiVMThrowTrampoline) "\n"
334 SYMBOL_STRING(ctiVMThrowTrampoline) ":" "\n"
335     "mov.l .L2"SYMBOL_STRING(cti_vm_throw)",r0" "\n"
336     "mov r15, r4" "\n"
337     "mov.l @(r0,r12),r11" "\n"
338     "jsr @r11" "\n"
339     "nop" "\n"
340     "add #60, r15" "\n"
341     "mov.l @r15+,r10" "\n"
342     "mov.l @r15+,r11" "\n"
343     "mov.l @r15+,r13" "\n"
344     "lds.l @r15+,pr" "\n"
345     "mov.l @r15+,r14" "\n"
346     "add #12, r15" "\n"
347     "rts" "\n"
348     "nop" "\n"
349     ".align 2" "\n"
350     ".L2"SYMBOL_STRING(cti_vm_throw)":.long " SYMBOL_STRING(cti_vm_throw)"@GOT \n"
351 );
352
353 asm volatile (
354 ".globl " SYMBOL_STRING(ctiOpThrowNotCaught) "\n"
355 HIDE_SYMBOL(ctiOpThrowNotCaught) "\n"
356 SYMBOL_STRING(ctiOpThrowNotCaught) ":" "\n"
357     "add #60, r15" "\n"
358     "mov.l @r15+,r10" "\n"
359     "mov.l @r15+,r11" "\n"
360     "mov.l @r15+,r13" "\n"
361     "lds.l @r15+,pr" "\n"
362     "mov.l @r15+,r14" "\n"
363     "add #12, r15" "\n"
364     "rts" "\n"
365     "nop" "\n"
366 );
367 #else
368     #error "JIT not supported on this platform."
369 #endif
370
371 #else // USE(JSVALUE32_64)
372
373 #if COMPILER(GCC) && CPU(X86_64) && !OS(WINDOWS)
374
375 // These ASSERTs remind you that, if you change the layout of JITStackFrame, you
376 // need to change the assembly trampolines below to match.
377 COMPILE_ASSERT(offsetof(struct JITStackFrame, callFrame) == 0x58, JITStackFrame_callFrame_offset_matches_ctiTrampoline);
378 COMPILE_ASSERT(offsetof(struct JITStackFrame, code) == 0x48, JITStackFrame_code_offset_matches_ctiTrampoline);
379 COMPILE_ASSERT(offsetof(struct JITStackFrame, savedRBX) == 0x78, JITStackFrame_stub_argument_space_matches_ctiTrampoline);
380
381 asm (
382 ".text\n"
383 ".globl " SYMBOL_STRING(ctiTrampoline) "\n"
384 HIDE_SYMBOL(ctiTrampoline) "\n"
385 SYMBOL_STRING(ctiTrampoline) ":" "\n"
386     "pushq %rbp" "\n"
387     "movq %rsp, %rbp" "\n"
388     "pushq %r12" "\n"
389     "pushq %r13" "\n"
390     "pushq %r14" "\n"
391     "pushq %r15" "\n"
392     "pushq %rbx" "\n"
393     // Form the JIT stubs area
394     "pushq %r9" "\n"
395     "pushq %r8" "\n"
396     "pushq %rcx" "\n"
397     "pushq %rdx" "\n"
398     "pushq %rsi" "\n"
399     "pushq %rdi" "\n"
400     "subq $0x48, %rsp" "\n"
401     "movq $512, %r12" "\n"
402     "movq $0xFFFF000000000000, %r14" "\n"
403     "movq $0xFFFF000000000002, %r15" "\n"
404     "movq %rdx, %r13" "\n"
405     "call *%rdi" "\n"
406     "addq $0x78, %rsp" "\n"
407     "popq %rbx" "\n"
408     "popq %r15" "\n"
409     "popq %r14" "\n"
410     "popq %r13" "\n"
411     "popq %r12" "\n"
412     "popq %rbp" "\n"
413     "ret" "\n"
414 ".globl " SYMBOL_STRING(ctiTrampolineEnd) "\n"
415 HIDE_SYMBOL(ctiTrampolineEnd) "\n"
416 SYMBOL_STRING(ctiTrampolineEnd) ":" "\n"
417 );
418
419 asm (
420 ".globl " SYMBOL_STRING(ctiVMThrowTrampoline) "\n"
421 HIDE_SYMBOL(ctiVMThrowTrampoline) "\n"
422 SYMBOL_STRING(ctiVMThrowTrampoline) ":" "\n"
423     "movq %rsp, %rdi" "\n"
424     "call " LOCAL_REFERENCE(cti_vm_throw) "\n"
425     "int3" "\n"
426 );
427
428 asm (
429 ".globl " SYMBOL_STRING(ctiOpThrowNotCaught) "\n"
430 HIDE_SYMBOL(ctiOpThrowNotCaught) "\n"
431 SYMBOL_STRING(ctiOpThrowNotCaught) ":" "\n"
432     "addq $0x78, %rsp" "\n"
433     "popq %rbx" "\n"
434     "popq %r15" "\n"
435     "popq %r14" "\n"
436     "popq %r13" "\n"
437     "popq %r12" "\n"
438     "popq %rbp" "\n"
439     "ret" "\n"
440 );
441
442 #elif COMPILER(GCC) && CPU(X86_64) && OS(WINDOWS)
443
444 // These ASSERTs remind you that, if you change the layout of JITStackFrame, you
445 // need to change the assembly trampolines below to match.
446 COMPILE_ASSERT(offsetof(struct JITStackFrame, code) % 16 == 0x0, JITStackFrame_maintains_16byte_stack_alignment);
447 COMPILE_ASSERT(offsetof(struct JITStackFrame, savedRBX) == 0x58, JITStackFrame_stub_argument_space_matches_ctiTrampoline);
448
449 asm (
450 ".text\n"
451 ".globl " SYMBOL_STRING(ctiTrampoline) "\n"
452 HIDE_SYMBOL(ctiTrampoline) "\n"
453 SYMBOL_STRING(ctiTrampoline) ":" "\n"
454     // Dump register parameters to their home address
455     "movq %r9, 0x20(%rsp)" "\n"
456     "movq %r8, 0x18(%rsp)" "\n"
457     "movq %rdx, 0x10(%rsp)" "\n"
458     "movq %rcx, 0x8(%rsp)" "\n"
459
460     "pushq %rbp" "\n"
461     "movq %rsp, %rbp" "\n"
462     "pushq %r12" "\n"
463     "pushq %r13" "\n"
464     "pushq %r14" "\n"
465     "pushq %r15" "\n"
466     "pushq %rbx" "\n"
467
468     // Decrease rsp to point to the start of our JITStackFrame
469     "subq $0x58, %rsp" "\n"
470     "movq $512, %r12" "\n"
471     "movq $0xFFFF000000000000, %r14" "\n"
472     "movq $0xFFFF000000000002, %r15" "\n"
473     "movq %r8, %r13" "\n"
474     "call *%rcx" "\n"
475     "addq $0x58, %rsp" "\n"
476     "popq %rbx" "\n"
477     "popq %r15" "\n"
478     "popq %r14" "\n"
479     "popq %r13" "\n"
480     "popq %r12" "\n"
481     "popq %rbp" "\n"
482     "ret" "\n"
483 ".globl " SYMBOL_STRING(ctiTrampolineEnd) "\n"
484 HIDE_SYMBOL(ctiTrampolineEnd) "\n"
485 SYMBOL_STRING(ctiTrampolineEnd) ":" "\n"
486 );
487
488 asm (
489 ".globl " SYMBOL_STRING(ctiVMThrowTrampoline) "\n"
490 HIDE_SYMBOL(ctiVMThrowTrampoline) "\n"
491 SYMBOL_STRING(ctiVMThrowTrampoline) ":" "\n"
492     "movq %rsp, %rcx" "\n"
493     "call " LOCAL_REFERENCE(cti_vm_throw) "\n"
494     "int3" "\n"
495 );
496
497 asm (
498 ".globl " SYMBOL_STRING(ctiOpThrowNotCaught) "\n"
499 HIDE_SYMBOL(ctiOpThrowNotCaught) "\n"
500 SYMBOL_STRING(ctiOpThrowNotCaught) ":" "\n"
501     "addq $0x58, %rsp" "\n"
502     "popq %rbx" "\n"
503     "popq %r15" "\n"
504     "popq %r14" "\n"
505     "popq %r13" "\n"
506     "popq %r12" "\n"
507     "popq %rbp" "\n"
508     "ret" "\n"
509 );
510
511 #elif COMPILER(MSVC) && CPU(X86_64)
512
513 // These ASSERTs remind you that, if you change the layout of JITStackFrame, you
514 // need to change the assembly trampolines in JITStubsMSVC64.asm to match.
515 COMPILE_ASSERT(offsetof(struct JITStackFrame, code) % 16 == 0x0, JITStackFrame_maintains_16byte_stack_alignment);
516 COMPILE_ASSERT(offsetof(struct JITStackFrame, savedRBX) == 0x58, JITStackFrame_stub_argument_space_matches_ctiTrampoline);
517
518 #else
519     #error "JIT not supported on this platform."
520 #endif
521
522 #endif // USE(JSVALUE32_64)
523
524 #if CPU(MIPS)
525 asm (
526 ".text" "\n"
527 ".align 2" "\n"
528 ".set noreorder" "\n"
529 ".set nomacro" "\n"
530 ".set nomips16" "\n"
531 ".globl " SYMBOL_STRING(ctiTrampoline) "\n"
532 ".ent " SYMBOL_STRING(ctiTrampoline) "\n"
533 SYMBOL_STRING(ctiTrampoline) ":" "\n"
534     "addiu $29,$29,-" STRINGIZE_VALUE_OF(STACK_LENGTH) "\n"
535     "sw    $31," STRINGIZE_VALUE_OF(PRESERVED_RETURN_ADDRESS_OFFSET) "($29)" "\n"
536     "sw    $20," STRINGIZE_VALUE_OF(PRESERVED_S4_OFFSET) "($29)" "\n"
537     "sw    $19," STRINGIZE_VALUE_OF(PRESERVED_S3_OFFSET) "($29)" "\n"
538     "sw    $18," STRINGIZE_VALUE_OF(PRESERVED_S2_OFFSET) "($29)" "\n"
539     "sw    $17," STRINGIZE_VALUE_OF(PRESERVED_S1_OFFSET) "($29)" "\n"
540     "sw    $16," STRINGIZE_VALUE_OF(PRESERVED_S0_OFFSET) "($29)" "\n"
541 #if WTF_MIPS_PIC
542     "sw    $28," STRINGIZE_VALUE_OF(PRESERVED_GP_OFFSET) "($29)" "\n"
543 #endif
544     "move  $16,$6       # set callFrameRegister" "\n"
545     "move  $25,$4       # move executableAddress to t9" "\n"
546     "sw    $5," STRINGIZE_VALUE_OF(REGISTER_FILE_OFFSET) "($29) # store JSStack to current stack" "\n"
547     "lw    $9," STRINGIZE_VALUE_OF(STACK_LENGTH + 20) "($29)    # load vm from previous stack" "\n"
548     "jalr  $25" "\n"
549     "sw    $9," STRINGIZE_VALUE_OF(GLOBAL_DATA_OFFSET) "($29)   # store vm to current stack" "\n"
550     "lw    $16," STRINGIZE_VALUE_OF(PRESERVED_S0_OFFSET) "($29)" "\n"
551     "lw    $17," STRINGIZE_VALUE_OF(PRESERVED_S1_OFFSET) "($29)" "\n"
552     "lw    $18," STRINGIZE_VALUE_OF(PRESERVED_S2_OFFSET) "($29)" "\n"
553     "lw    $19," STRINGIZE_VALUE_OF(PRESERVED_S3_OFFSET) "($29)" "\n"
554     "lw    $20," STRINGIZE_VALUE_OF(PRESERVED_S4_OFFSET) "($29)" "\n"
555     "lw    $31," STRINGIZE_VALUE_OF(PRESERVED_RETURN_ADDRESS_OFFSET) "($29)" "\n"
556     "jr    $31" "\n"
557     "addiu $29,$29," STRINGIZE_VALUE_OF(STACK_LENGTH) "\n"
558 ".set reorder" "\n"
559 ".set macro" "\n"
560 ".end " SYMBOL_STRING(ctiTrampoline) "\n"
561 ".globl " SYMBOL_STRING(ctiTrampolineEnd) "\n"
562 HIDE_SYMBOL(ctiTrampolineEnd) "\n"
563 SYMBOL_STRING(ctiTrampolineEnd) ":" "\n"
564 );
565
566 asm (
567 ".text" "\n"
568 ".align 2" "\n"
569 ".set noreorder" "\n"
570 ".set nomacro" "\n"
571 ".set nomips16" "\n"
572 ".globl " SYMBOL_STRING(ctiVMThrowTrampoline) "\n"
573 ".ent " SYMBOL_STRING(ctiVMThrowTrampoline) "\n"
574 SYMBOL_STRING(ctiVMThrowTrampoline) ":" "\n"
575 #if WTF_MIPS_PIC
576 ".set macro" "\n"
577 ".cpload $31" "\n"
578     "la    $25," SYMBOL_STRING(cti_vm_throw) "\n"
579 ".set nomacro" "\n"
580     "bal " SYMBOL_STRING(cti_vm_throw) "\n"
581     "move  $4,$29" "\n"
582 #else
583     "jal " SYMBOL_STRING(cti_vm_throw) "\n"
584     "move  $4,$29" "\n"
585 #endif
586     "lw    $16," STRINGIZE_VALUE_OF(PRESERVED_S0_OFFSET) "($29)" "\n"
587     "lw    $17," STRINGIZE_VALUE_OF(PRESERVED_S1_OFFSET) "($29)" "\n"
588     "lw    $18," STRINGIZE_VALUE_OF(PRESERVED_S2_OFFSET) "($29)" "\n"
589     "lw    $19," STRINGIZE_VALUE_OF(PRESERVED_S3_OFFSET) "($29)" "\n"
590     "lw    $20," STRINGIZE_VALUE_OF(PRESERVED_S4_OFFSET) "($29)" "\n"
591     "lw    $31," STRINGIZE_VALUE_OF(PRESERVED_RETURN_ADDRESS_OFFSET) "($29)" "\n"
592     "jr    $31" "\n"
593     "addiu $29,$29," STRINGIZE_VALUE_OF(STACK_LENGTH) "\n"
594 ".set reorder" "\n"
595 ".set macro" "\n"
596 ".end " SYMBOL_STRING(ctiVMThrowTrampoline) "\n"
597 );
598
599 asm (
600 ".text" "\n"
601 ".align 2" "\n"
602 ".set noreorder" "\n"
603 ".set nomacro" "\n"
604 ".set nomips16" "\n"
605 ".globl " SYMBOL_STRING(ctiOpThrowNotCaught) "\n"
606 ".ent " SYMBOL_STRING(ctiOpThrowNotCaught) "\n"
607 SYMBOL_STRING(ctiOpThrowNotCaught) ":" "\n"
608     "lw    $16," STRINGIZE_VALUE_OF(PRESERVED_S0_OFFSET) "($29)" "\n"
609     "lw    $17," STRINGIZE_VALUE_OF(PRESERVED_S1_OFFSET) "($29)" "\n"
610     "lw    $18," STRINGIZE_VALUE_OF(PRESERVED_S2_OFFSET) "($29)" "\n"
611     "lw    $19," STRINGIZE_VALUE_OF(PRESERVED_S3_OFFSET) "($29)" "\n"
612     "lw    $20," STRINGIZE_VALUE_OF(PRESERVED_S4_OFFSET) "($29)" "\n"
613     "lw    $31," STRINGIZE_VALUE_OF(PRESERVED_RETURN_ADDRESS_OFFSET) "($29)" "\n"
614     "jr    $31" "\n"
615     "addiu $29,$29," STRINGIZE_VALUE_OF(STACK_LENGTH) "\n"
616 ".set reorder" "\n"
617 ".set macro" "\n"
618 ".end " SYMBOL_STRING(ctiOpThrowNotCaught) "\n"
619 );
620 #endif
621
622 #if COMPILER(GCC) && CPU(ARM_THUMB2)
623
624 asm (
625 ".text" "\n"
626 ".align 2" "\n"
627 ".globl " SYMBOL_STRING(ctiTrampoline) "\n"
628 HIDE_SYMBOL(ctiTrampoline) "\n"
629 ".thumb" "\n"
630 ".thumb_func " THUMB_FUNC_PARAM(ctiTrampoline) "\n"
631 SYMBOL_STRING(ctiTrampoline) ":" "\n"
632     "sub sp, sp, #" STRINGIZE_VALUE_OF(FIRST_STACK_ARGUMENT) "\n"
633     "str lr, [sp, #" STRINGIZE_VALUE_OF(PRESERVED_RETURN_ADDRESS_OFFSET) "]" "\n"
634     "str r4, [sp, #" STRINGIZE_VALUE_OF(PRESERVED_R4_OFFSET) "]" "\n"
635     "str r5, [sp, #" STRINGIZE_VALUE_OF(PRESERVED_R5_OFFSET) "]" "\n"
636     "str r6, [sp, #" STRINGIZE_VALUE_OF(PRESERVED_R6_OFFSET) "]" "\n"
637     "str r7, [sp, #" STRINGIZE_VALUE_OF(PRESERVED_R7_OFFSET) "]" "\n"
638     "str r8, [sp, #" STRINGIZE_VALUE_OF(PRESERVED_R8_OFFSET) "]" "\n"
639     "str r9, [sp, #" STRINGIZE_VALUE_OF(PRESERVED_R9_OFFSET) "]" "\n"
640     "str r10, [sp, #" STRINGIZE_VALUE_OF(PRESERVED_R10_OFFSET) "]" "\n"
641     "str r11, [sp, #" STRINGIZE_VALUE_OF(PRESERVED_R11_OFFSET) "]" "\n"
642     "str r1, [sp, #" STRINGIZE_VALUE_OF(REGISTER_FILE_OFFSET) "]" "\n"
643     "mov r5, r2" "\n"
644     "mov r6, #512" "\n"
645     "blx r0" "\n"
646     "ldr r11, [sp, #" STRINGIZE_VALUE_OF(PRESERVED_R11_OFFSET) "]" "\n"
647     "ldr r10, [sp, #" STRINGIZE_VALUE_OF(PRESERVED_R10_OFFSET) "]" "\n"
648     "ldr r9, [sp, #" STRINGIZE_VALUE_OF(PRESERVED_R9_OFFSET) "]" "\n"
649     "ldr r8, [sp, #" STRINGIZE_VALUE_OF(PRESERVED_R8_OFFSET) "]" "\n"
650     "ldr r7, [sp, #" STRINGIZE_VALUE_OF(PRESERVED_R7_OFFSET) "]" "\n"
651     "ldr r6, [sp, #" STRINGIZE_VALUE_OF(PRESERVED_R6_OFFSET) "]" "\n"
652     "ldr r5, [sp, #" STRINGIZE_VALUE_OF(PRESERVED_R5_OFFSET) "]" "\n"
653     "ldr r4, [sp, #" STRINGIZE_VALUE_OF(PRESERVED_R4_OFFSET) "]" "\n"
654     "ldr lr, [sp, #" STRINGIZE_VALUE_OF(PRESERVED_RETURN_ADDRESS_OFFSET) "]" "\n"
655     "add sp, sp, #" STRINGIZE_VALUE_OF(FIRST_STACK_ARGUMENT) "\n"
656     "bx lr" "\n"
657 ".align 2" "\n"
658 ".globl " SYMBOL_STRING(ctiTrampolineEnd) "\n"
659 HIDE_SYMBOL(ctiTrampolineEnd) "\n"
660 ".thumb" "\n"
661 ".thumb_func " THUMB_FUNC_PARAM(ctiTrampolineEnd) "\n"
662 SYMBOL_STRING(ctiTrampolineEnd) ":" "\n"
663 );
664
665 asm (
666 ".text" "\n"
667 ".align 2" "\n"
668 ".globl " SYMBOL_STRING(ctiVMThrowTrampoline) "\n"
669 HIDE_SYMBOL(ctiVMThrowTrampoline) "\n"
670 ".thumb" "\n"
671 ".thumb_func " THUMB_FUNC_PARAM(ctiVMThrowTrampoline) "\n"
672 SYMBOL_STRING(ctiVMThrowTrampoline) ":" "\n"
673     "mov r0, sp" "\n"
674     "bl " LOCAL_REFERENCE(cti_vm_throw) "\n"
675     "ldr r11, [sp, #" STRINGIZE_VALUE_OF(PRESERVED_R11_OFFSET) "]" "\n"
676     "ldr r10, [sp, #" STRINGIZE_VALUE_OF(PRESERVED_R10_OFFSET) "]" "\n"
677     "ldr r9, [sp, #" STRINGIZE_VALUE_OF(PRESERVED_R9_OFFSET) "]" "\n"
678     "ldr r8, [sp, #" STRINGIZE_VALUE_OF(PRESERVED_R8_OFFSET) "]" "\n"
679     "ldr r7, [sp, #" STRINGIZE_VALUE_OF(PRESERVED_R7_OFFSET) "]" "\n"
680     "ldr r6, [sp, #" STRINGIZE_VALUE_OF(PRESERVED_R6_OFFSET) "]" "\n"
681     "ldr r5, [sp, #" STRINGIZE_VALUE_OF(PRESERVED_R5_OFFSET) "]" "\n"
682     "ldr r4, [sp, #" STRINGIZE_VALUE_OF(PRESERVED_R4_OFFSET) "]" "\n"
683     "ldr lr, [sp, #" STRINGIZE_VALUE_OF(PRESERVED_RETURN_ADDRESS_OFFSET) "]" "\n"
684     "add sp, sp, #" STRINGIZE_VALUE_OF(FIRST_STACK_ARGUMENT) "\n"
685     "bx lr" "\n"
686 );
687
688 asm (
689 ".text" "\n"
690 ".align 2" "\n"
691 ".globl " SYMBOL_STRING(ctiOpThrowNotCaught) "\n"
692 HIDE_SYMBOL(ctiOpThrowNotCaught) "\n"
693 ".thumb" "\n"
694 ".thumb_func " THUMB_FUNC_PARAM(ctiOpThrowNotCaught) "\n"
695 SYMBOL_STRING(ctiOpThrowNotCaught) ":" "\n"
696     "ldr r11, [sp, #" STRINGIZE_VALUE_OF(PRESERVED_R11_OFFSET) "]" "\n"
697     "ldr r10, [sp, #" STRINGIZE_VALUE_OF(PRESERVED_R10_OFFSET) "]" "\n"
698     "ldr r9, [sp, #" STRINGIZE_VALUE_OF(PRESERVED_R9_OFFSET) "]" "\n"
699     "ldr r8, [sp, #" STRINGIZE_VALUE_OF(PRESERVED_R8_OFFSET) "]" "\n"
700     "ldr r7, [sp, #" STRINGIZE_VALUE_OF(PRESERVED_R7_OFFSET) "]" "\n"
701     "ldr r6, [sp, #" STRINGIZE_VALUE_OF(PRESERVED_R6_OFFSET) "]" "\n"
702     "ldr r5, [sp, #" STRINGIZE_VALUE_OF(PRESERVED_R5_OFFSET) "]" "\n"
703     "ldr r4, [sp, #" STRINGIZE_VALUE_OF(PRESERVED_R4_OFFSET) "]" "\n"
704     "ldr lr, [sp, #" STRINGIZE_VALUE_OF(PRESERVED_RETURN_ADDRESS_OFFSET) "]" "\n"
705     "add sp, sp, #" STRINGIZE_VALUE_OF(FIRST_STACK_ARGUMENT) "\n"
706     "bx lr" "\n"
707 );
708
709 #elif COMPILER(GCC) && CPU(ARM_TRADITIONAL)
710
711 asm (
712 ".text" "\n"
713 ".globl " SYMBOL_STRING(ctiTrampoline) "\n"
714 HIDE_SYMBOL(ctiTrampoline) "\n"
715 INLINE_ARM_FUNCTION(ctiTrampoline)
716 SYMBOL_STRING(ctiTrampoline) ":" "\n"
717     "stmdb sp!, {r1-r3}" "\n"
718     "stmdb sp!, {r4-r6, r8-r11, lr}" "\n"
719     "sub sp, sp, #" STRINGIZE_VALUE_OF(PRESERVEDR4_OFFSET) "\n"
720     "mov r5, r2" "\n"
721     "mov r6, #512" "\n"
722     // r0 contains the code
723     "blx r0" "\n"
724     "add sp, sp, #" STRINGIZE_VALUE_OF(PRESERVEDR4_OFFSET) "\n"
725     "ldmia sp!, {r4-r6, r8-r11, lr}" "\n"
726     "add sp, sp, #12" "\n"
727     "bx lr" "\n"
728 ".globl " SYMBOL_STRING(ctiTrampolineEnd) "\n"
729 HIDE_SYMBOL(ctiTrampolineEnd) "\n"
730 SYMBOL_STRING(ctiTrampolineEnd) ":" "\n"
731 );
732
733 asm (
734 ".text" "\n"
735 ".globl " SYMBOL_STRING(ctiVMThrowTrampoline) "\n"
736 HIDE_SYMBOL(ctiVMThrowTrampoline) "\n"
737 INLINE_ARM_FUNCTION(ctiVMThrowTrampoline)
738 SYMBOL_STRING(ctiVMThrowTrampoline) ":" "\n"
739     "mov r0, sp" "\n"
740     "bl " SYMBOL_STRING(cti_vm_throw) "\n"
741
742 // Both has the same return sequence
743 ".text" "\n"
744 ".globl " SYMBOL_STRING(ctiOpThrowNotCaught) "\n"
745 HIDE_SYMBOL(ctiOpThrowNotCaught) "\n"
746 INLINE_ARM_FUNCTION(ctiOpThrowNotCaught)
747 SYMBOL_STRING(ctiOpThrowNotCaught) ":" "\n"
748     "add sp, sp, #" STRINGIZE_VALUE_OF(PRESERVEDR4_OFFSET) "\n"
749     "ldmia sp!, {r4-r6, r8-r11, lr}" "\n"
750     "add sp, sp, #12" "\n"
751     "bx lr" "\n"
752 );
753
754 #elif COMPILER(RVCT) && CPU(ARM_THUMB2)
755
756 __asm EncodedJSValue ctiTrampoline(void*, JSStack*, CallFrame*, void* /*unused1*/, void* /*unused2*/, VM*)
757 {
758     PRESERVE8
759     sub sp, sp, # FIRST_STACK_ARGUMENT
760     str lr, [sp, # PRESERVED_RETURN_ADDRESS_OFFSET ]
761     str r4, [sp, # PRESERVED_R4_OFFSET ]
762     str r5, [sp, # PRESERVED_R5_OFFSET ]
763     str r6, [sp, # PRESERVED_R6_OFFSET ]
764     str r7, [sp, # PRESERVED_R7_OFFSET ]
765     str r8, [sp, # PRESERVED_R8_OFFSET ]
766     str r9, [sp, # PRESERVED_R9_OFFSET ]
767     str r10, [sp, # PRESERVED_R10_OFFSET ]
768     str r11, [sp, # PRESERVED_R11_OFFSET ]
769     str r1, [sp, # REGISTER_FILE_OFFSET ]
770     mov r5, r2
771     mov r6, #512
772     blx r0
773     ldr r11, [sp, # PRESERVED_R11_OFFSET ]
774     ldr r10, [sp, # PRESERVED_R10_OFFSET ]
775     ldr r9, [sp, # PRESERVED_R9_OFFSET ]
776     ldr r8, [sp, # PRESERVED_R8_OFFSET ]
777     ldr r7, [sp, # PRESERVED_R7_OFFSET ]
778     ldr r6, [sp, # PRESERVED_R6_OFFSET ]
779     ldr r5, [sp, # PRESERVED_R5_OFFSET ]
780     ldr r4, [sp, # PRESERVED_R4_OFFSET ]
781     ldr lr, [sp, # PRESERVED_RETURN_ADDRESS_OFFSET ]
782     add sp, sp, # FIRST_STACK_ARGUMENT
783     bx lr
784 }
785
786 __asm void ctiVMThrowTrampoline()
787 {
788     PRESERVE8
789     mov r0, sp
790     bl cti_vm_throw
791     ldr r11, [sp, # PRESERVED_R11_OFFSET ]
792     ldr r10, [sp, # PRESERVED_R10_OFFSET ]
793     ldr r9, [sp, # PRESERVED_R9_OFFSET ]
794     ldr r8, [sp, # PRESERVED_R8_OFFSET ]
795     ldr r7, [sp, # PRESERVED_R7_OFFSET ]
796     ldr r6, [sp, # PRESERVED_R6_OFFSET ]
797     ldr r6, [sp, # PRESERVED_R6_OFFSET ]
798     ldr r5, [sp, # PRESERVED_R5_OFFSET ]
799     ldr r4, [sp, # PRESERVED_R4_OFFSET ]
800     ldr lr, [sp, # PRESERVED_RETURN_ADDRESS_OFFSET ]
801     add sp, sp, # FIRST_STACK_ARGUMENT
802     bx lr
803 }
804
805 __asm void ctiOpThrowNotCaught()
806 {
807     PRESERVE8
808     ldr r11, [sp, # PRESERVED_R11_OFFSET ]
809     ldr r10, [sp, # PRESERVED_R10_OFFSET ]
810     ldr r9, [sp, # PRESERVED_R9_OFFSET ]
811     ldr r8, [sp, # PRESERVED_R8_OFFSET ]
812     ldr r7, [sp, # PRESERVED_R7_OFFSET ]
813     ldr r6, [sp, # PRESERVED_R6_OFFSET ]
814     ldr r6, [sp, # PRESERVED_R6_OFFSET ]
815     ldr r5, [sp, # PRESERVED_R5_OFFSET ]
816     ldr r4, [sp, # PRESERVED_R4_OFFSET ]
817     ldr lr, [sp, # PRESERVED_RETURN_ADDRESS_OFFSET ]
818     add sp, sp, # FIRST_STACK_ARGUMENT
819     bx lr
820 }
821
822 #elif COMPILER(RVCT) && CPU(ARM_TRADITIONAL)
823
824 __asm EncodedJSValue ctiTrampoline(void*, JSStack*, CallFrame*, void* /*unused1*/, void* /*unused2*/, VM*)
825 {
826     ARM
827     stmdb sp!, {r1-r3}
828     stmdb sp!, {r4-r6, r8-r11, lr}
829     sub sp, sp, # PRESERVEDR4_OFFSET
830     mov r5, r2
831     mov r6, #512
832     mov lr, pc
833     bx r0
834     add sp, sp, # PRESERVEDR4_OFFSET
835     ldmia sp!, {r4-r6, r8-r11, lr}
836     add sp, sp, #12
837     bx lr
838 }
839 __asm void ctiTrampolineEnd()
840 {
841 }
842
843 __asm void ctiVMThrowTrampoline()
844 {
845     ARM
846     PRESERVE8
847     mov r0, sp
848     bl cti_vm_throw
849     add sp, sp, # PRESERVEDR4_OFFSET
850     ldmia sp!, {r4-r6, r8-r11, lr}
851     add sp, sp, #12
852     bx lr
853 }
854
855 __asm void ctiOpThrowNotCaught()
856 {
857     ARM
858     add sp, sp, # PRESERVEDR4_OFFSET
859     ldmia sp!, {r4-r8, lr}
860     add sp, sp, #12
861     bx lr
862 }
863 #endif
864
865 #if ENABLE(OPCODE_SAMPLING)
866     #define CTI_SAMPLER stackFrame.vm->interpreter->sampler()
867 #else
868     #define CTI_SAMPLER 0
869 #endif
870
871 void performPlatformSpecificJITAssertions(VM* vm)
872 {
873     if (!vm->canUseJIT())
874         return;
875
876 #if CPU(ARM_THUMB2)
877     // Unfortunate the arm compiler does not like the use of offsetof on JITStackFrame (since it contains non POD types),
878     // and the OBJECT_OFFSETOF macro does not appear constantish enough for it to be happy with its use in COMPILE_ASSERT
879     // macros.
880     ASSERT(OBJECT_OFFSETOF(struct JITStackFrame, preservedReturnAddress) == PRESERVED_RETURN_ADDRESS_OFFSET);
881     ASSERT(OBJECT_OFFSETOF(struct JITStackFrame, preservedR4) == PRESERVED_R4_OFFSET);
882     ASSERT(OBJECT_OFFSETOF(struct JITStackFrame, preservedR5) == PRESERVED_R5_OFFSET);
883     ASSERT(OBJECT_OFFSETOF(struct JITStackFrame, preservedR6) == PRESERVED_R6_OFFSET);
884     ASSERT(OBJECT_OFFSETOF(struct JITStackFrame, preservedR7) == PRESERVED_R7_OFFSET);
885     ASSERT(OBJECT_OFFSETOF(struct JITStackFrame, preservedR8) == PRESERVED_R8_OFFSET);
886     ASSERT(OBJECT_OFFSETOF(struct JITStackFrame, preservedR9) == PRESERVED_R9_OFFSET);
887     ASSERT(OBJECT_OFFSETOF(struct JITStackFrame, preservedR10) == PRESERVED_R10_OFFSET);
888     ASSERT(OBJECT_OFFSETOF(struct JITStackFrame, preservedR11) == PRESERVED_R11_OFFSET);
889
890     ASSERT(OBJECT_OFFSETOF(struct JITStackFrame, stack) == REGISTER_FILE_OFFSET);
891     // The fifth argument is the first item already on the stack.
892     ASSERT(OBJECT_OFFSETOF(struct JITStackFrame, unused1) == FIRST_STACK_ARGUMENT);
893
894     ASSERT(OBJECT_OFFSETOF(struct JITStackFrame, thunkReturnAddress) == THUNK_RETURN_ADDRESS_OFFSET);
895
896 #elif CPU(ARM_TRADITIONAL)
897
898     ASSERT(OBJECT_OFFSETOF(struct JITStackFrame, thunkReturnAddress) == THUNK_RETURN_ADDRESS_OFFSET);
899     ASSERT(OBJECT_OFFSETOF(struct JITStackFrame, preservedR4) == PRESERVEDR4_OFFSET);
900
901
902 #elif CPU(MIPS)
903     ASSERT(OBJECT_OFFSETOF(struct JITStackFrame, preservedGP) == PRESERVED_GP_OFFSET);
904     ASSERT(OBJECT_OFFSETOF(struct JITStackFrame, preservedS0) == PRESERVED_S0_OFFSET);
905     ASSERT(OBJECT_OFFSETOF(struct JITStackFrame, preservedS1) == PRESERVED_S1_OFFSET);
906     ASSERT(OBJECT_OFFSETOF(struct JITStackFrame, preservedS2) == PRESERVED_S2_OFFSET);
907     ASSERT(OBJECT_OFFSETOF(struct JITStackFrame, preservedReturnAddress) == PRESERVED_RETURN_ADDRESS_OFFSET);
908     ASSERT(OBJECT_OFFSETOF(struct JITStackFrame, thunkReturnAddress) == THUNK_RETURN_ADDRESS_OFFSET);
909     ASSERT(OBJECT_OFFSETOF(struct JITStackFrame, stack) == REGISTER_FILE_OFFSET);
910     ASSERT(OBJECT_OFFSETOF(struct JITStackFrame, vm) == GLOBAL_DATA_OFFSET);
911
912 #endif
913 }
914
915 NEVER_INLINE static void tryCachePutByID(CallFrame* callFrame, CodeBlock* codeBlock, ReturnAddressPtr returnAddress, JSValue baseValue, const PutPropertySlot& slot, StructureStubInfo* stubInfo, bool direct)
916 {
917     // The interpreter checks for recursion here; I do not believe this can occur in CTI.
918
919     if (!baseValue.isCell())
920         return;
921
922     // Uncacheable: give up.
923     if (!slot.isCacheable()) {
924         ctiPatchCallByReturnAddress(codeBlock, returnAddress, FunctionPtr(direct ? cti_op_put_by_id_direct_generic : cti_op_put_by_id_generic));
925         return;
926     }
927     
928     JSCell* baseCell = baseValue.asCell();
929     Structure* structure = baseCell->structure();
930
931     if (structure->isUncacheableDictionary() || structure->typeInfo().prohibitsPropertyCaching()) {
932         ctiPatchCallByReturnAddress(codeBlock, returnAddress, FunctionPtr(direct ? cti_op_put_by_id_direct_generic : cti_op_put_by_id_generic));
933         return;
934     }
935
936     // If baseCell != base, then baseCell must be a proxy for another object.
937     if (baseCell != slot.base()) {
938         ctiPatchCallByReturnAddress(codeBlock, returnAddress, FunctionPtr(direct ? cti_op_put_by_id_direct_generic : cti_op_put_by_id_generic));
939         return;
940     }
941
942     // Cache hit: Specialize instruction and ref Structures.
943
944     // Structure transition, cache transition info
945     if (slot.type() == PutPropertySlot::NewProperty) {
946         if (structure->isDictionary()) {
947             ctiPatchCallByReturnAddress(codeBlock, returnAddress, FunctionPtr(direct ? cti_op_put_by_id_direct_generic : cti_op_put_by_id_generic));
948             return;
949         }
950
951         // put_by_id_transition checks the prototype chain for setters.
952         if (normalizePrototypeChain(callFrame, baseCell) == InvalidPrototypeChain) {
953             ctiPatchCallByReturnAddress(codeBlock, returnAddress, FunctionPtr(direct ? cti_op_put_by_id_direct_generic : cti_op_put_by_id_generic));
954             return;
955         }
956
957         StructureChain* prototypeChain = structure->prototypeChain(callFrame);
958         ASSERT(structure->previousID()->transitionWatchpointSetHasBeenInvalidated());
959         stubInfo->initPutByIdTransition(callFrame->vm(), codeBlock->ownerExecutable(), structure->previousID(), structure, prototypeChain, direct);
960         JIT::compilePutByIdTransition(callFrame->scope()->vm(), codeBlock, stubInfo, structure->previousID(), structure, slot.cachedOffset(), prototypeChain, returnAddress, direct);
961         return;
962     }
963     
964     stubInfo->initPutByIdReplace(callFrame->vm(), codeBlock->ownerExecutable(), structure);
965
966     JIT::patchPutByIdReplace(codeBlock, stubInfo, structure, slot.cachedOffset(), returnAddress, direct);
967 }
968
969 NEVER_INLINE static void tryCacheGetByID(CallFrame* callFrame, CodeBlock* codeBlock, ReturnAddressPtr returnAddress, JSValue baseValue, const Identifier& propertyName, const PropertySlot& slot, StructureStubInfo* stubInfo)
970 {
971     // FIXME: Write a test that proves we need to check for recursion here just
972     // like the interpreter does, then add a check for recursion.
973
974     // FIXME: Cache property access for immediates.
975     if (!baseValue.isCell()) {
976         ctiPatchCallByReturnAddress(codeBlock, returnAddress, FunctionPtr(cti_op_get_by_id_generic));
977         return;
978     }
979     
980     VM* vm = &callFrame->vm();
981
982     if (isJSArray(baseValue) && propertyName == callFrame->propertyNames().length) {
983         JIT::compilePatchGetArrayLength(callFrame->scope()->vm(), codeBlock, returnAddress);
984         return;
985     }
986     
987     if (isJSString(baseValue) && propertyName == callFrame->propertyNames().length) {
988         // The tradeoff of compiling an patched inline string length access routine does not seem
989         // to pay off, so we currently only do this for arrays.
990         ctiPatchCallByReturnAddress(codeBlock, returnAddress, vm->getCTIStub(stringLengthTrampolineGenerator).code());
991         return;
992     }
993
994     // Uncacheable: give up.
995     if (!slot.isCacheable()) {
996         stubInfo->accessType = access_get_by_id_generic;
997         ctiPatchCallByReturnAddress(codeBlock, returnAddress, FunctionPtr(cti_op_get_by_id_generic));
998         return;
999     }
1000
1001     JSCell* baseCell = baseValue.asCell();
1002     Structure* structure = baseCell->structure();
1003
1004     if (structure->isUncacheableDictionary() || structure->typeInfo().prohibitsPropertyCaching()) {
1005         stubInfo->accessType = access_get_by_id_generic;
1006         ctiPatchCallByReturnAddress(codeBlock, returnAddress, FunctionPtr(cti_op_get_by_id_generic));
1007         return;
1008     }
1009
1010     // Cache hit: Specialize instruction and ref Structures.
1011
1012     if (slot.slotBase() == baseValue) {
1013         RELEASE_ASSERT(stubInfo->accessType == access_unset);
1014         if ((slot.cachedPropertyType() != PropertySlot::Value)
1015             || !MacroAssembler::isCompactPtrAlignedAddressOffset(maxOffsetRelativeToPatchedStorage(slot.cachedOffset())))
1016             ctiPatchCallByReturnAddress(codeBlock, returnAddress, FunctionPtr(cti_op_get_by_id_self_fail));
1017         else {
1018             JIT::patchGetByIdSelf(codeBlock, stubInfo, structure, slot.cachedOffset(), returnAddress);
1019             stubInfo->initGetByIdSelf(callFrame->vm(), codeBlock->ownerExecutable(), structure);
1020         }
1021         return;
1022     }
1023
1024     if (structure->isDictionary()) {
1025         stubInfo->accessType = access_get_by_id_generic;
1026         ctiPatchCallByReturnAddress(codeBlock, returnAddress, FunctionPtr(cti_op_get_by_id_generic));
1027         return;
1028     }
1029
1030     if (slot.slotBase() == structure->prototypeForLookup(callFrame)) {
1031         ASSERT(slot.slotBase().isObject());
1032         
1033         JSObject* slotBaseObject = asObject(slot.slotBase());
1034         size_t offset = slot.cachedOffset();
1035
1036         if (structure->typeInfo().hasImpureGetOwnPropertySlot()) {
1037             stubInfo->accessType = access_get_by_id_generic;
1038             ctiPatchCallByReturnAddress(codeBlock, returnAddress, FunctionPtr(cti_op_get_by_id_generic));
1039             return;
1040         }
1041         
1042         // Since we're accessing a prototype in a loop, it's a good bet that it
1043         // should not be treated as a dictionary.
1044         if (slotBaseObject->structure()->isDictionary()) {
1045             slotBaseObject->flattenDictionaryObject(callFrame->vm());
1046             offset = slotBaseObject->structure()->get(callFrame->vm(), propertyName);
1047         }
1048         
1049         stubInfo->initGetByIdProto(callFrame->vm(), codeBlock->ownerExecutable(), structure, slotBaseObject->structure(), slot.cachedPropertyType() == PropertySlot::Value);
1050
1051         ASSERT(!structure->isDictionary());
1052         ASSERT(!slotBaseObject->structure()->isDictionary());
1053         JIT::compileGetByIdProto(callFrame->scope()->vm(), callFrame, codeBlock, stubInfo, structure, slotBaseObject->structure(), propertyName, slot, offset, returnAddress);
1054         return;
1055     }
1056
1057     PropertyOffset offset = slot.cachedOffset();
1058     size_t count = normalizePrototypeChainForChainAccess(callFrame, baseValue, slot.slotBase(), propertyName, offset);
1059     if (count == InvalidPrototypeChain) {
1060         stubInfo->accessType = access_get_by_id_generic;
1061         ctiPatchCallByReturnAddress(codeBlock, returnAddress, FunctionPtr(cti_op_get_by_id_generic));
1062         return;
1063     }
1064
1065     StructureChain* prototypeChain = structure->prototypeChain(callFrame);
1066     stubInfo->initGetByIdChain(callFrame->vm(), codeBlock->ownerExecutable(), structure, prototypeChain, count, slot.cachedPropertyType() == PropertySlot::Value);
1067     JIT::compileGetByIdChain(callFrame->scope()->vm(), callFrame, codeBlock, stubInfo, structure, prototypeChain, count, propertyName, slot, offset, returnAddress);
1068 }
1069
1070 #if !defined(NDEBUG)
1071
1072 extern "C" {
1073
1074 static void jscGeneratedNativeCode() 
1075 {
1076     // When executing a JIT stub function (which might do an allocation), we hack the return address
1077     // to pretend to be executing this function, to keep stack logging tools from blowing out
1078     // memory.
1079 }
1080
1081 }
1082
1083 struct StackHack {
1084     ALWAYS_INLINE StackHack(JITStackFrame& stackFrame) 
1085         : stackFrame(stackFrame)
1086         , savedReturnAddress(*stackFrame.returnAddressSlot())
1087     {
1088         if (!CodeProfiling::enabled())
1089             *stackFrame.returnAddressSlot() = ReturnAddressPtr(FunctionPtr(jscGeneratedNativeCode));
1090     }
1091
1092     ALWAYS_INLINE ~StackHack() 
1093     { 
1094         *stackFrame.returnAddressSlot() = savedReturnAddress;
1095     }
1096
1097     JITStackFrame& stackFrame;
1098     ReturnAddressPtr savedReturnAddress;
1099 };
1100
1101 #define STUB_INIT_STACK_FRAME(stackFrame) JITStackFrame& stackFrame = *reinterpret_cast_ptr<JITStackFrame*>(STUB_ARGS); StackHack stackHack(stackFrame)
1102 #define STUB_SET_RETURN_ADDRESS(returnAddress) stackHack.savedReturnAddress = ReturnAddressPtr(returnAddress)
1103 #define STUB_RETURN_ADDRESS stackHack.savedReturnAddress
1104
1105 #else
1106
1107 #define STUB_INIT_STACK_FRAME(stackFrame) JITStackFrame& stackFrame = *reinterpret_cast_ptr<JITStackFrame*>(STUB_ARGS)
1108 #define STUB_SET_RETURN_ADDRESS(returnAddress) *stackFrame.returnAddressSlot() = ReturnAddressPtr(returnAddress)
1109 #define STUB_RETURN_ADDRESS *stackFrame.returnAddressSlot()
1110
1111 #endif
1112
1113 // The reason this is not inlined is to avoid having to do a PIC branch
1114 // to get the address of the ctiVMThrowTrampoline function. It's also
1115 // good to keep the code size down by leaving as much of the exception
1116 // handling code out of line as possible.
1117 static NEVER_INLINE void returnToThrowTrampoline(VM* vm, ReturnAddressPtr exceptionLocation, ReturnAddressPtr& returnAddressSlot)
1118 {
1119     RELEASE_ASSERT(vm->exception);
1120     vm->exceptionLocation = exceptionLocation;
1121     returnAddressSlot = ReturnAddressPtr(FunctionPtr(ctiVMThrowTrampoline));
1122 }
1123
1124 #define VM_THROW_EXCEPTION() \
1125     do { \
1126         VM_THROW_EXCEPTION_AT_END(); \
1127         return 0; \
1128     } while (0)
1129 #define VM_THROW_EXCEPTION_AT_END() \
1130     do {\
1131         returnToThrowTrampoline(stackFrame.vm, STUB_RETURN_ADDRESS, STUB_RETURN_ADDRESS);\
1132     } while (0)
1133
1134 #define CHECK_FOR_EXCEPTION() \
1135     do { \
1136         if (UNLIKELY(stackFrame.vm->exception)) \
1137             VM_THROW_EXCEPTION(); \
1138     } while (0)
1139 #define CHECK_FOR_EXCEPTION_AT_END() \
1140     do { \
1141         if (UNLIKELY(stackFrame.vm->exception)) \
1142             VM_THROW_EXCEPTION_AT_END(); \
1143     } while (0)
1144 #define CHECK_FOR_EXCEPTION_VOID() \
1145     do { \
1146         if (UNLIKELY(stackFrame.vm->exception)) { \
1147             VM_THROW_EXCEPTION_AT_END(); \
1148             return; \
1149         } \
1150     } while (0)
1151
1152 class ErrorFunctor {
1153 public:
1154     virtual ~ErrorFunctor() { }
1155     virtual JSValue operator()(ExecState*) = 0;
1156 };
1157
1158 class ErrorWithExecFunctor : public ErrorFunctor {
1159 public:
1160     typedef JSObject* (*Factory)(ExecState* exec);
1161     
1162     ErrorWithExecFunctor(Factory factory)
1163         : m_factory(factory)
1164     {
1165     }
1166     JSValue operator()(ExecState* exec)
1167     {
1168         return m_factory(exec);
1169     }
1170
1171 private:
1172     Factory m_factory;
1173 };
1174
1175 class ErrorWithExecAndCalleeFunctor : public ErrorFunctor {
1176 public:
1177     typedef JSObject* (*Factory)(ExecState* exec, JSValue callee);
1178
1179     ErrorWithExecAndCalleeFunctor(Factory factory, JSValue callee)
1180         : m_factory(factory), m_callee(callee)
1181     {
1182     }
1183     JSValue operator()(ExecState* exec)
1184     {
1185         return m_factory(exec, m_callee);
1186     }
1187 private:
1188     Factory m_factory;
1189     JSValue m_callee;
1190 };
1191
1192 class ErrorWithExceptionFunctor : public ErrorFunctor {
1193     public:
1194     ErrorWithExceptionFunctor(JSValue exception)
1195         : m_exception(exception)
1196     {
1197     }
1198     JSValue operator()(ExecState*)
1199     {
1200     return m_exception;
1201     }
1202
1203 private:
1204     JSValue m_exception;
1205 };
1206
1207 // Helper function for JIT stubs that may throw an exception in the middle of
1208 // processing a function call. This function rolls back the stack to
1209 // our caller, so exception processing can proceed from a valid state.
1210 template<typename T> static T throwExceptionFromOpCall(JITStackFrame& jitStackFrame, CallFrame* newCallFrame, ReturnAddressPtr& returnAddressSlot, ErrorFunctor& createError )
1211 {
1212     CallFrame* callFrame = newCallFrame->callerFrame();
1213     jitStackFrame.callFrame = callFrame;
1214     callFrame->vm().topCallFrame = callFrame;
1215     callFrame->vm().exception = createError(callFrame);
1216     ASSERT(callFrame->vm().exception);
1217     returnToThrowTrampoline(&callFrame->vm(), ReturnAddressPtr(newCallFrame->returnPC()), returnAddressSlot);
1218     return T();
1219 }
1220
1221 template<typename T> static T throwExceptionFromOpCall(JITStackFrame& jitStackFrame, CallFrame* newCallFrame, ReturnAddressPtr& returnAddressSlot)
1222 {
1223     CallFrame* callFrame = newCallFrame->callerFrame();
1224     ASSERT(callFrame->vm().exception);
1225     ErrorWithExceptionFunctor functor = ErrorWithExceptionFunctor(callFrame->vm().exception);
1226     return throwExceptionFromOpCall<T>(jitStackFrame, newCallFrame, returnAddressSlot, functor);
1227 }
1228
1229 #if CPU(ARM_THUMB2) && COMPILER(GCC)
1230
1231 #define DEFINE_STUB_FUNCTION(rtype, op) \
1232     extern "C" { \
1233         rtype JITStubThunked_##op(STUB_ARGS_DECLARATION); \
1234     }; \
1235     asm ( \
1236         ".text" "\n" \
1237         ".align 2" "\n" \
1238         ".globl " SYMBOL_STRING(cti_##op) "\n" \
1239         HIDE_SYMBOL(cti_##op) "\n"             \
1240         ".thumb" "\n" \
1241         ".thumb_func " THUMB_FUNC_PARAM(cti_##op) "\n" \
1242         SYMBOL_STRING(cti_##op) ":" "\n" \
1243         "str lr, [sp, #" STRINGIZE_VALUE_OF(THUNK_RETURN_ADDRESS_OFFSET) "]" "\n" \
1244         "bl " SYMBOL_STRING(JITStubThunked_##op) "\n" \
1245         "ldr lr, [sp, #" STRINGIZE_VALUE_OF(THUNK_RETURN_ADDRESS_OFFSET) "]" "\n" \
1246         "bx lr" "\n" \
1247         ); \
1248     rtype JITStubThunked_##op(STUB_ARGS_DECLARATION) \
1249
1250 #elif CPU(MIPS)
1251 #if WTF_MIPS_PIC
1252 #define DEFINE_STUB_FUNCTION(rtype, op) \
1253     extern "C" { \
1254         rtype JITStubThunked_##op(STUB_ARGS_DECLARATION); \
1255     }; \
1256     asm ( \
1257         ".text" "\n" \
1258         ".align 2" "\n" \
1259         ".set noreorder" "\n" \
1260         ".set nomacro" "\n" \
1261         ".set nomips16" "\n" \
1262         ".globl " SYMBOL_STRING(cti_##op) "\n" \
1263         ".ent " SYMBOL_STRING(cti_##op) "\n" \
1264         SYMBOL_STRING(cti_##op) ":" "\n" \
1265         ".set macro" "\n" \
1266         ".cpload $25" "\n" \
1267         "sw    $31," STRINGIZE_VALUE_OF(THUNK_RETURN_ADDRESS_OFFSET) "($29)" "\n" \
1268         "la    $25," SYMBOL_STRING(JITStubThunked_##op) "\n" \
1269         ".set nomacro" "\n" \
1270         ".reloc 1f,R_MIPS_JALR," SYMBOL_STRING(JITStubThunked_##op) "\n" \
1271         "1: jalr $25" "\n" \
1272         "nop" "\n" \
1273         "lw    $31," STRINGIZE_VALUE_OF(THUNK_RETURN_ADDRESS_OFFSET) "($29)" "\n" \
1274         "jr    $31" "\n" \
1275         "nop" "\n" \
1276         ".set reorder" "\n" \
1277         ".set macro" "\n" \
1278         ".end " SYMBOL_STRING(cti_##op) "\n" \
1279         ); \
1280     rtype JITStubThunked_##op(STUB_ARGS_DECLARATION)
1281
1282 #else // WTF_MIPS_PIC
1283 #define DEFINE_STUB_FUNCTION(rtype, op) \
1284     extern "C" { \
1285         rtype JITStubThunked_##op(STUB_ARGS_DECLARATION); \
1286     }; \
1287     asm ( \
1288         ".text" "\n" \
1289         ".align 2" "\n" \
1290         ".set noreorder" "\n" \
1291         ".set nomacro" "\n" \
1292         ".set nomips16" "\n" \
1293         ".globl " SYMBOL_STRING(cti_##op) "\n" \
1294         ".ent " SYMBOL_STRING(cti_##op) "\n" \
1295         SYMBOL_STRING(cti_##op) ":" "\n" \
1296         "sw    $31," STRINGIZE_VALUE_OF(THUNK_RETURN_ADDRESS_OFFSET) "($29)" "\n" \
1297         "jal " SYMBOL_STRING(JITStubThunked_##op) "\n" \
1298         "nop" "\n" \
1299         "lw    $31," STRINGIZE_VALUE_OF(THUNK_RETURN_ADDRESS_OFFSET) "($29)" "\n" \
1300         "jr    $31" "\n" \
1301         "nop" "\n" \
1302         ".set reorder" "\n" \
1303         ".set macro" "\n" \
1304         ".end " SYMBOL_STRING(cti_##op) "\n" \
1305         ); \
1306     rtype JITStubThunked_##op(STUB_ARGS_DECLARATION)
1307
1308 #endif
1309
1310 #elif CPU(ARM_TRADITIONAL) && COMPILER(GCC)
1311
1312 #define DEFINE_STUB_FUNCTION(rtype, op) \
1313     extern "C" { \
1314         rtype JITStubThunked_##op(STUB_ARGS_DECLARATION); \
1315     }; \
1316     asm ( \
1317         ".globl " SYMBOL_STRING(cti_##op) "\n" \
1318         INLINE_ARM_FUNCTION(cti_##op) \
1319         SYMBOL_STRING(cti_##op) ":" "\n" \
1320         "str lr, [sp, #" STRINGIZE_VALUE_OF(THUNK_RETURN_ADDRESS_OFFSET) "]" "\n" \
1321         "bl " SYMBOL_STRING(JITStubThunked_##op) "\n" \
1322         "ldr lr, [sp, #" STRINGIZE_VALUE_OF(THUNK_RETURN_ADDRESS_OFFSET) "]" "\n" \
1323         "bx lr" "\n" \
1324         ); \
1325     rtype JITStubThunked_##op(STUB_ARGS_DECLARATION)
1326
1327 #elif (CPU(ARM_THUMB2) || CPU(ARM_TRADITIONAL)) && COMPILER(RVCT)
1328
1329 #define DEFINE_STUB_FUNCTION(rtype, op) rtype JITStubThunked_##op(STUB_ARGS_DECLARATION)
1330
1331 /* The following is a workaround for RVCT toolchain; precompiler macros are not expanded before the code is passed to the assembler */
1332
1333 /* The following section is a template to generate code for GeneratedJITStubs_RVCT.h */
1334 /* The pattern "#xxx#" will be replaced with "xxx" */
1335
1336 /*
1337 RVCT(extern "C" #rtype# JITStubThunked_#op#(STUB_ARGS_DECLARATION);)
1338 RVCT(__asm #rtype# cti_#op#(STUB_ARGS_DECLARATION))
1339 RVCT({)
1340 RVCT(    PRESERVE8)
1341 RVCT(    IMPORT JITStubThunked_#op#)
1342 RVCT(    str lr, [sp, # THUNK_RETURN_ADDRESS_OFFSET])
1343 RVCT(    bl JITStubThunked_#op#)
1344 RVCT(    ldr lr, [sp, # THUNK_RETURN_ADDRESS_OFFSET])
1345 RVCT(    bx lr)
1346 RVCT(})
1347 RVCT()
1348 */
1349
1350 /* Include the generated file */
1351 #include "GeneratedJITStubs_RVCT.h"
1352
1353 #elif CPU(ARM_TRADITIONAL) && COMPILER(MSVC)
1354
1355 #define DEFINE_STUB_FUNCTION(rtype, op) extern "C" rtype JITStubThunked_##op(STUB_ARGS_DECLARATION)
1356
1357 /* The following is a workaround for MSVC toolchain; inline assembler is not supported */
1358
1359 /* The following section is a template to generate code for GeneratedJITStubs_MSVC.asm */
1360 /* The pattern "#xxx#" will be replaced with "xxx" */
1361
1362 /*
1363 MSVC_BEGIN(    AREA Trampoline, CODE)
1364 MSVC_BEGIN()
1365 MSVC_BEGIN(    EXPORT ctiTrampoline)
1366 MSVC_BEGIN(    EXPORT ctiTrampolineEnd)
1367 MSVC_BEGIN(    EXPORT ctiVMThrowTrampoline)
1368 MSVC_BEGIN(    EXPORT ctiOpThrowNotCaught)
1369 MSVC_BEGIN()
1370 MSVC_BEGIN(ctiTrampoline PROC)
1371 MSVC_BEGIN(    stmdb sp!, {r1-r3})
1372 MSVC_BEGIN(    stmdb sp!, {r4-r6, r8-r11, lr})
1373 MSVC_BEGIN(    sub sp, sp, #68 ; sync with PRESERVEDR4_OFFSET)
1374 MSVC_BEGIN(    mov r5, r2)
1375 MSVC_BEGIN(    mov r6, #512)
1376 MSVC_BEGIN(    ; r0 contains the code)
1377 MSVC_BEGIN(    mov lr, pc)
1378 MSVC_BEGIN(    bx r0)
1379 MSVC_BEGIN(    add sp, sp, #68 ; sync with PRESERVEDR4_OFFSET)
1380 MSVC_BEGIN(    ldmia sp!, {r4-r6, r8-r11, lr})
1381 MSVC_BEGIN(    add sp, sp, #12)
1382 MSVC_BEGIN(    bx lr)
1383 MSVC_BEGIN(ctiTrampolineEnd)
1384 MSVC_BEGIN(ctiTrampoline ENDP)
1385 MSVC_BEGIN()
1386 MSVC_BEGIN(ctiVMThrowTrampoline PROC)
1387 MSVC_BEGIN(    mov r0, sp)
1388 MSVC_BEGIN(    bl cti_vm_throw)
1389 MSVC_BEGIN(ctiOpThrowNotCaught)
1390 MSVC_BEGIN(    add sp, sp, #68 ; sync with PRESERVEDR4_OFFSET)
1391 MSVC_BEGIN(    ldmia sp!, {r4-r6, r8-r11, lr})
1392 MSVC_BEGIN(    add sp, sp, #12)
1393 MSVC_BEGIN(    bx lr)
1394 MSVC_BEGIN(ctiVMThrowTrampoline ENDP)
1395 MSVC_BEGIN()
1396
1397 MSVC(    EXPORT cti_#op#)
1398 MSVC(    IMPORT JITStubThunked_#op#)
1399 MSVC(cti_#op# PROC)
1400 MSVC(    str lr, [sp, #64] ; sync with THUNK_RETURN_ADDRESS_OFFSET)
1401 MSVC(    bl JITStubThunked_#op#)
1402 MSVC(    ldr lr, [sp, #64] ; sync with THUNK_RETURN_ADDRESS_OFFSET)
1403 MSVC(    bx lr)
1404 MSVC(cti_#op# ENDP)
1405 MSVC()
1406
1407 MSVC_END(    END)
1408 */
1409
1410 #elif CPU(SH4)
1411 #define DEFINE_STUB_FUNCTION(rtype, op) \
1412     extern "C" { \
1413         rtype JITStubThunked_##op(STUB_ARGS_DECLARATION); \
1414     }; \
1415     asm volatile( \
1416     ".align 2" "\n" \
1417     ".globl " SYMBOL_STRING(cti_##op) "\n" \
1418     SYMBOL_STRING(cti_##op) ":" "\n" \
1419     "sts pr, r11" "\n" \
1420     "mov.l r11, @(0x38, r15)" "\n" \
1421     "mov.l .L2"SYMBOL_STRING(JITStubThunked_##op)",r0" "\n" \
1422     "mov.l @(r0,r12),r11" "\n" \
1423     "jsr @r11" "\n" \
1424     "nop" "\n" \
1425     "mov.l @(0x38, r15), r11 " "\n" \
1426     "lds r11, pr " "\n" \
1427     "rts" "\n" \
1428     "nop" "\n" \
1429     ".align 2" "\n" \
1430     ".L2"SYMBOL_STRING(JITStubThunked_##op)":.long " SYMBOL_STRING(JITStubThunked_##op)"@GOT \n" \
1431     ); \
1432     rtype JITStubThunked_##op(STUB_ARGS_DECLARATION)
1433 #else
1434 #define DEFINE_STUB_FUNCTION(rtype, op) rtype JIT_STUB cti_##op(STUB_ARGS_DECLARATION)
1435 #endif
1436
1437 DEFINE_STUB_FUNCTION(EncodedJSValue, op_create_this)
1438 {
1439     STUB_INIT_STACK_FRAME(stackFrame);
1440     CallFrame* callFrame = stackFrame.callFrame;
1441     size_t inlineCapacity = stackFrame.args[0].int32();
1442
1443     JSFunction* constructor = jsCast<JSFunction*>(callFrame->callee());
1444 #if !ASSERT_DISABLED
1445     ConstructData constructData;
1446     ASSERT(constructor->methodTable()->getConstructData(constructor, constructData) == ConstructTypeJS);
1447 #endif
1448
1449     Structure* structure = constructor->allocationProfile(callFrame, inlineCapacity)->structure();
1450     JSValue result = constructEmptyObject(callFrame, structure);
1451
1452     return JSValue::encode(result);
1453 }
1454
1455 DEFINE_STUB_FUNCTION(EncodedJSValue, op_convert_this)
1456 {
1457     STUB_INIT_STACK_FRAME(stackFrame);
1458
1459     JSValue v1 = stackFrame.args[0].jsValue();
1460     CallFrame* callFrame = stackFrame.callFrame;
1461
1462     ASSERT(v1.isPrimitive());
1463
1464     JSObject* result = v1.toThisObject(callFrame);
1465     CHECK_FOR_EXCEPTION_AT_END();
1466     return JSValue::encode(result);
1467 }
1468
1469 DEFINE_STUB_FUNCTION(EncodedJSValue, op_add)
1470 {
1471     STUB_INIT_STACK_FRAME(stackFrame);
1472
1473     JSValue v1 = stackFrame.args[0].jsValue();
1474     JSValue v2 = stackFrame.args[1].jsValue();
1475     CallFrame* callFrame = stackFrame.callFrame;
1476
1477     if (v1.isString() && !v2.isObject()) {
1478         JSValue result = jsString(callFrame, asString(v1), v2.toString(callFrame));
1479         CHECK_FOR_EXCEPTION_AT_END();
1480         return JSValue::encode(result);
1481     }
1482
1483     if (v1.isNumber() && v2.isNumber())
1484         return JSValue::encode(jsNumber(v1.asNumber() + v2.asNumber()));
1485
1486     // All other cases are pretty uncommon
1487     JSValue result = jsAddSlowCase(callFrame, v1, v2);
1488     CHECK_FOR_EXCEPTION_AT_END();
1489     return JSValue::encode(result);
1490 }
1491
1492 DEFINE_STUB_FUNCTION(EncodedJSValue, op_inc)
1493 {
1494     STUB_INIT_STACK_FRAME(stackFrame);
1495
1496     JSValue v = stackFrame.args[0].jsValue();
1497
1498     CallFrame* callFrame = stackFrame.callFrame;
1499     JSValue result = jsNumber(v.toNumber(callFrame) + 1);
1500     CHECK_FOR_EXCEPTION_AT_END();
1501     return JSValue::encode(result);
1502 }
1503
1504 DEFINE_STUB_FUNCTION(void, handle_watchdog_timer)
1505 {
1506     STUB_INIT_STACK_FRAME(stackFrame);
1507     CallFrame* callFrame = stackFrame.callFrame;
1508     VM* vm = stackFrame.vm;
1509     if (UNLIKELY(vm->watchdog.didFire(callFrame))) {
1510         vm->exception = createTerminatedExecutionException(vm);
1511         VM_THROW_EXCEPTION_AT_END();
1512         return;
1513     }
1514 }
1515
1516 DEFINE_STUB_FUNCTION(void*, stack_check)
1517 {
1518     STUB_INIT_STACK_FRAME(stackFrame);
1519     CallFrame* callFrame = stackFrame.callFrame;
1520
1521     if (UNLIKELY(!stackFrame.stack->grow(&callFrame->registers()[callFrame->codeBlock()->m_numCalleeRegisters]))) {
1522         ErrorWithExecFunctor functor = ErrorWithExecFunctor(createStackOverflowError);
1523         return throwExceptionFromOpCall<void*>(stackFrame, callFrame, STUB_RETURN_ADDRESS, functor);
1524     }
1525
1526     return callFrame;
1527 }
1528
1529 DEFINE_STUB_FUNCTION(JSObject*, op_new_object)
1530 {
1531     STUB_INIT_STACK_FRAME(stackFrame);
1532
1533     return constructEmptyObject(stackFrame.callFrame, stackFrame.args[0].structure());
1534 }
1535
1536 DEFINE_STUB_FUNCTION(void, op_put_by_id_generic)
1537 {
1538     STUB_INIT_STACK_FRAME(stackFrame);
1539
1540     PutPropertySlot slot(stackFrame.callFrame->codeBlock()->isStrictMode());
1541     stackFrame.args[0].jsValue().put(stackFrame.callFrame, stackFrame.args[1].identifier(), stackFrame.args[2].jsValue(), slot);
1542     CHECK_FOR_EXCEPTION_AT_END();
1543 }
1544
1545 DEFINE_STUB_FUNCTION(void, op_put_by_id_direct_generic)
1546 {
1547     STUB_INIT_STACK_FRAME(stackFrame);
1548     
1549     PutPropertySlot slot(stackFrame.callFrame->codeBlock()->isStrictMode());
1550     JSValue baseValue = stackFrame.args[0].jsValue();
1551     ASSERT(baseValue.isObject());
1552     asObject(baseValue)->putDirect(stackFrame.callFrame->vm(), stackFrame.args[1].identifier(), stackFrame.args[2].jsValue(), slot);
1553     CHECK_FOR_EXCEPTION_AT_END();
1554 }
1555
1556 DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_id_generic)
1557 {
1558     STUB_INIT_STACK_FRAME(stackFrame);
1559
1560     CallFrame* callFrame = stackFrame.callFrame;
1561     Identifier& ident = stackFrame.args[1].identifier();
1562
1563     JSValue baseValue = stackFrame.args[0].jsValue();
1564     PropertySlot slot(baseValue);
1565     JSValue result = baseValue.get(callFrame, ident, slot);
1566
1567     CHECK_FOR_EXCEPTION_AT_END();
1568     return JSValue::encode(result);
1569 }
1570
1571 DEFINE_STUB_FUNCTION(void, op_put_by_id)
1572 {
1573     STUB_INIT_STACK_FRAME(stackFrame);
1574     CallFrame* callFrame = stackFrame.callFrame;
1575     Identifier& ident = stackFrame.args[1].identifier();
1576     
1577     CodeBlock* codeBlock = stackFrame.callFrame->codeBlock();
1578     StructureStubInfo* stubInfo = &codeBlock->getStubInfo(STUB_RETURN_ADDRESS);
1579     AccessType accessType = static_cast<AccessType>(stubInfo->accessType);
1580
1581     PutPropertySlot slot(callFrame->codeBlock()->isStrictMode());
1582     stackFrame.args[0].jsValue().put(callFrame, ident, stackFrame.args[2].jsValue(), slot);
1583     
1584     if (accessType == static_cast<AccessType>(stubInfo->accessType)) {
1585         stubInfo->setSeen();
1586         tryCachePutByID(callFrame, codeBlock, STUB_RETURN_ADDRESS, stackFrame.args[0].jsValue(), slot, stubInfo, false);
1587     }
1588     
1589     CHECK_FOR_EXCEPTION_AT_END();
1590 }
1591
1592 DEFINE_STUB_FUNCTION(void, op_put_by_id_direct)
1593 {
1594     STUB_INIT_STACK_FRAME(stackFrame);
1595     CallFrame* callFrame = stackFrame.callFrame;
1596     Identifier& ident = stackFrame.args[1].identifier();
1597     
1598     CodeBlock* codeBlock = stackFrame.callFrame->codeBlock();
1599     StructureStubInfo* stubInfo = &codeBlock->getStubInfo(STUB_RETURN_ADDRESS);
1600     AccessType accessType = static_cast<AccessType>(stubInfo->accessType);
1601
1602     PutPropertySlot slot(callFrame->codeBlock()->isStrictMode());
1603     JSValue baseValue = stackFrame.args[0].jsValue();
1604     ASSERT(baseValue.isObject());
1605     
1606     asObject(baseValue)->putDirect(callFrame->vm(), ident, stackFrame.args[2].jsValue(), slot);
1607     
1608     if (accessType == static_cast<AccessType>(stubInfo->accessType)) {
1609         stubInfo->setSeen();
1610         tryCachePutByID(callFrame, codeBlock, STUB_RETURN_ADDRESS, stackFrame.args[0].jsValue(), slot, stubInfo, true);
1611     }
1612     
1613     CHECK_FOR_EXCEPTION_AT_END();
1614 }
1615
1616 DEFINE_STUB_FUNCTION(void, op_put_by_id_fail)
1617 {
1618     STUB_INIT_STACK_FRAME(stackFrame);
1619
1620     CallFrame* callFrame = stackFrame.callFrame;
1621     Identifier& ident = stackFrame.args[1].identifier();
1622     
1623     PutPropertySlot slot(callFrame->codeBlock()->isStrictMode());
1624     stackFrame.args[0].jsValue().put(callFrame, ident, stackFrame.args[2].jsValue(), slot);
1625
1626     CHECK_FOR_EXCEPTION_AT_END();
1627 }
1628
1629 DEFINE_STUB_FUNCTION(void, op_put_by_id_direct_fail)
1630 {
1631     STUB_INIT_STACK_FRAME(stackFrame);
1632     
1633     CallFrame* callFrame = stackFrame.callFrame;
1634     Identifier& ident = stackFrame.args[1].identifier();
1635     
1636     PutPropertySlot slot(callFrame->codeBlock()->isStrictMode());
1637     JSValue baseValue = stackFrame.args[0].jsValue();
1638     ASSERT(baseValue.isObject());
1639     asObject(baseValue)->putDirect(callFrame->vm(), ident, stackFrame.args[2].jsValue(), slot);
1640     
1641     CHECK_FOR_EXCEPTION_AT_END();
1642 }
1643
1644 DEFINE_STUB_FUNCTION(JSObject*, op_put_by_id_transition_realloc)
1645 {
1646     STUB_INIT_STACK_FRAME(stackFrame);
1647
1648     JSValue baseValue = stackFrame.args[0].jsValue();
1649     int32_t oldSize = stackFrame.args[3].int32();
1650     Structure* newStructure = stackFrame.args[4].structure();
1651     int32_t newSize = newStructure->outOfLineCapacity();
1652     
1653     ASSERT(oldSize >= 0);
1654     ASSERT(newSize > oldSize);
1655
1656     ASSERT(baseValue.isObject());
1657     JSObject* base = asObject(baseValue);
1658     VM& vm = *stackFrame.vm;
1659     Butterfly* butterfly = base->growOutOfLineStorage(vm, oldSize, newSize);
1660     base->setButterfly(vm, butterfly, newStructure);
1661
1662     return base;
1663 }
1664
1665 DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_id)
1666 {
1667     STUB_INIT_STACK_FRAME(stackFrame);
1668     CallFrame* callFrame = stackFrame.callFrame;
1669     Identifier& ident = stackFrame.args[1].identifier();
1670
1671     CodeBlock* codeBlock = stackFrame.callFrame->codeBlock();
1672     StructureStubInfo* stubInfo = &codeBlock->getStubInfo(STUB_RETURN_ADDRESS);
1673     AccessType accessType = static_cast<AccessType>(stubInfo->accessType);
1674
1675     JSValue baseValue = stackFrame.args[0].jsValue();
1676     PropertySlot slot(baseValue);
1677     JSValue result = baseValue.get(callFrame, ident, slot);
1678     
1679     if (accessType != static_cast<AccessType>(stubInfo->accessType))
1680         return JSValue::encode(result);
1681
1682     if (!stubInfo->seenOnce())
1683         stubInfo->setSeen();
1684     else
1685         tryCacheGetByID(callFrame, codeBlock, STUB_RETURN_ADDRESS, baseValue, ident, slot, stubInfo);
1686
1687     CHECK_FOR_EXCEPTION_AT_END();
1688     return JSValue::encode(result);
1689 }
1690
1691 DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_id_self_fail)
1692 {
1693     STUB_INIT_STACK_FRAME(stackFrame);
1694
1695     CallFrame* callFrame = stackFrame.callFrame;
1696     Identifier& ident = stackFrame.args[1].identifier();
1697
1698     CodeBlock* codeBlock = callFrame->codeBlock();
1699     StructureStubInfo* stubInfo = &codeBlock->getStubInfo(STUB_RETURN_ADDRESS);
1700     AccessType accessType = static_cast<AccessType>(stubInfo->accessType);
1701
1702     JSValue baseValue = stackFrame.args[0].jsValue();
1703     PropertySlot slot(baseValue);
1704     JSValue result = baseValue.get(callFrame, ident, slot);
1705     
1706     if (accessType != static_cast<AccessType>(stubInfo->accessType))
1707         return JSValue::encode(result);
1708
1709     CHECK_FOR_EXCEPTION();
1710
1711     if (baseValue.isCell()
1712         && slot.isCacheable()
1713         && !baseValue.asCell()->structure()->isUncacheableDictionary()
1714         && slot.slotBase() == baseValue) {
1715
1716         ASSERT(slot.slotBase().isObject());
1717
1718         PolymorphicAccessStructureList* polymorphicStructureList;
1719         int listIndex = 1;
1720
1721         if (stubInfo->accessType == access_unset)
1722             stubInfo->initGetByIdSelf(callFrame->vm(), codeBlock->ownerExecutable(), baseValue.asCell()->structure());
1723
1724         if (stubInfo->accessType == access_get_by_id_self) {
1725             ASSERT(!stubInfo->stubRoutine);
1726             polymorphicStructureList = new PolymorphicAccessStructureList(callFrame->vm(), codeBlock->ownerExecutable(), 0, stubInfo->u.getByIdSelf.baseObjectStructure.get(), true);
1727             stubInfo->initGetByIdSelfList(polymorphicStructureList, 1);
1728         } else {
1729             polymorphicStructureList = stubInfo->u.getByIdSelfList.structureList;
1730             listIndex = stubInfo->u.getByIdSelfList.listSize;
1731         }
1732         if (listIndex < POLYMORPHIC_LIST_CACHE_SIZE) {
1733             stubInfo->u.getByIdSelfList.listSize++;
1734             JIT::compileGetByIdSelfList(callFrame->scope()->vm(), codeBlock, stubInfo, polymorphicStructureList, listIndex, baseValue.asCell()->structure(), ident, slot, slot.cachedOffset());
1735
1736             if (listIndex == (POLYMORPHIC_LIST_CACHE_SIZE - 1))
1737                 ctiPatchCallByReturnAddress(codeBlock, STUB_RETURN_ADDRESS, FunctionPtr(cti_op_get_by_id_generic));
1738         }
1739     } else
1740         ctiPatchCallByReturnAddress(callFrame->codeBlock(), STUB_RETURN_ADDRESS, FunctionPtr(cti_op_get_by_id_generic));
1741     return JSValue::encode(result);
1742 }
1743
1744 static PolymorphicAccessStructureList* getPolymorphicAccessStructureListSlot(VM& vm, ScriptExecutable* owner, StructureStubInfo* stubInfo, int& listIndex)
1745 {
1746     PolymorphicAccessStructureList* prototypeStructureList = 0;
1747     listIndex = 1;
1748
1749     switch (stubInfo->accessType) {
1750     case access_get_by_id_proto:
1751         prototypeStructureList = new PolymorphicAccessStructureList(vm, owner, stubInfo->stubRoutine, stubInfo->u.getByIdProto.baseObjectStructure.get(), stubInfo->u.getByIdProto.prototypeStructure.get(), true);
1752         stubInfo->stubRoutine.clear();
1753         stubInfo->initGetByIdProtoList(prototypeStructureList, 2);
1754         break;
1755     case access_get_by_id_chain:
1756         prototypeStructureList = new PolymorphicAccessStructureList(vm, owner, stubInfo->stubRoutine, stubInfo->u.getByIdChain.baseObjectStructure.get(), stubInfo->u.getByIdChain.chain.get(), true);
1757         stubInfo->stubRoutine.clear();
1758         stubInfo->initGetByIdProtoList(prototypeStructureList, 2);
1759         break;
1760     case access_get_by_id_proto_list:
1761         prototypeStructureList = stubInfo->u.getByIdProtoList.structureList;
1762         listIndex = stubInfo->u.getByIdProtoList.listSize;
1763         if (listIndex < POLYMORPHIC_LIST_CACHE_SIZE)
1764             stubInfo->u.getByIdProtoList.listSize++;
1765         break;
1766     default:
1767         RELEASE_ASSERT_NOT_REACHED();
1768     }
1769     
1770     ASSERT(listIndex <= POLYMORPHIC_LIST_CACHE_SIZE);
1771     return prototypeStructureList;
1772 }
1773
1774 DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_id_getter_stub)
1775 {
1776     STUB_INIT_STACK_FRAME(stackFrame);
1777     CallFrame* callFrame = stackFrame.callFrame;
1778     GetterSetter* getterSetter = asGetterSetter(stackFrame.args[0].jsObject());
1779     if (!getterSetter->getter())
1780         return JSValue::encode(jsUndefined());
1781     JSObject* getter = asObject(getterSetter->getter());
1782     CallData callData;
1783     CallType callType = getter->methodTable()->getCallData(getter, callData);
1784     JSValue result = call(callFrame, getter, callType, callData, stackFrame.args[1].jsObject(), ArgList());
1785     if (callFrame->hadException())
1786         returnToThrowTrampoline(&callFrame->vm(), stackFrame.args[2].returnAddress(), STUB_RETURN_ADDRESS);
1787
1788     return JSValue::encode(result);
1789 }
1790
1791 DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_id_custom_stub)
1792 {
1793     STUB_INIT_STACK_FRAME(stackFrame);
1794     CallFrame* callFrame = stackFrame.callFrame;
1795     JSObject* slotBase = stackFrame.args[0].jsObject();
1796     PropertySlot::GetValueFunc getter = reinterpret_cast<PropertySlot::GetValueFunc>(stackFrame.args[1].asPointer);
1797     const Identifier& ident = stackFrame.args[2].identifier();
1798     JSValue result = getter(callFrame, slotBase, ident);
1799     if (callFrame->hadException())
1800         returnToThrowTrampoline(&callFrame->vm(), stackFrame.args[3].returnAddress(), STUB_RETURN_ADDRESS);
1801     
1802     return JSValue::encode(result);
1803 }
1804
1805 DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_id_proto_list)
1806 {
1807     STUB_INIT_STACK_FRAME(stackFrame);
1808
1809     CallFrame* callFrame = stackFrame.callFrame;
1810     const Identifier& propertyName = stackFrame.args[1].identifier();
1811
1812     CodeBlock* codeBlock = callFrame->codeBlock();
1813     StructureStubInfo* stubInfo = &codeBlock->getStubInfo(STUB_RETURN_ADDRESS);
1814     AccessType accessType = static_cast<AccessType>(stubInfo->accessType);
1815
1816     JSValue baseValue = stackFrame.args[0].jsValue();
1817     PropertySlot slot(baseValue);
1818     JSValue result = baseValue.get(callFrame, propertyName, slot);
1819
1820     CHECK_FOR_EXCEPTION();
1821
1822     if (accessType != static_cast<AccessType>(stubInfo->accessType)
1823         || !baseValue.isCell()
1824         || !slot.isCacheable()
1825         || baseValue.asCell()->structure()->isDictionary()
1826         || baseValue.asCell()->structure()->typeInfo().prohibitsPropertyCaching()) {
1827         ctiPatchCallByReturnAddress(callFrame->codeBlock(), STUB_RETURN_ADDRESS, FunctionPtr(cti_op_get_by_id_proto_fail));
1828         return JSValue::encode(result);
1829     }
1830
1831     Structure* structure = baseValue.asCell()->structure();
1832
1833     ASSERT(slot.slotBase().isObject());
1834     JSObject* slotBaseObject = asObject(slot.slotBase());
1835     
1836     PropertyOffset offset = slot.cachedOffset();
1837
1838     if (slot.slotBase() == baseValue)
1839         ctiPatchCallByReturnAddress(codeBlock, STUB_RETURN_ADDRESS, FunctionPtr(cti_op_get_by_id_proto_fail));
1840     else if (slot.slotBase() == baseValue.asCell()->structure()->prototypeForLookup(callFrame)) {
1841         ASSERT(!baseValue.asCell()->structure()->isDictionary());
1842         
1843         if (baseValue.asCell()->structure()->typeInfo().hasImpureGetOwnPropertySlot()) {
1844             ctiPatchCallByReturnAddress(codeBlock, STUB_RETURN_ADDRESS, FunctionPtr(cti_op_get_by_id_proto_fail));
1845             return JSValue::encode(result);
1846         }
1847         
1848         // Since we're accessing a prototype in a loop, it's a good bet that it
1849         // should not be treated as a dictionary.
1850         if (slotBaseObject->structure()->isDictionary()) {
1851             slotBaseObject->flattenDictionaryObject(callFrame->vm());
1852             offset = slotBaseObject->structure()->get(callFrame->vm(), propertyName);
1853         }
1854
1855         int listIndex;
1856         PolymorphicAccessStructureList* prototypeStructureList = getPolymorphicAccessStructureListSlot(callFrame->vm(), codeBlock->ownerExecutable(), stubInfo, listIndex);
1857         if (listIndex < POLYMORPHIC_LIST_CACHE_SIZE) {
1858             JIT::compileGetByIdProtoList(callFrame->scope()->vm(), callFrame, codeBlock, stubInfo, prototypeStructureList, listIndex, structure, slotBaseObject->structure(), propertyName, slot, offset);
1859
1860             if (listIndex == (POLYMORPHIC_LIST_CACHE_SIZE - 1))
1861                 ctiPatchCallByReturnAddress(codeBlock, STUB_RETURN_ADDRESS, FunctionPtr(cti_op_get_by_id_proto_list_full));
1862         }
1863     } else {
1864         size_t count = normalizePrototypeChainForChainAccess(callFrame, baseValue, slot.slotBase(), propertyName, offset);
1865         if (count == InvalidPrototypeChain) {
1866             ctiPatchCallByReturnAddress(codeBlock, STUB_RETURN_ADDRESS, FunctionPtr(cti_op_get_by_id_proto_fail));
1867             return JSValue::encode(result);
1868         }
1869         
1870         ASSERT(!baseValue.asCell()->structure()->isDictionary());
1871         int listIndex;
1872         PolymorphicAccessStructureList* prototypeStructureList = getPolymorphicAccessStructureListSlot(callFrame->vm(), codeBlock->ownerExecutable(), stubInfo, listIndex);
1873         
1874         if (listIndex < POLYMORPHIC_LIST_CACHE_SIZE) {
1875             StructureChain* protoChain = structure->prototypeChain(callFrame);
1876             JIT::compileGetByIdChainList(callFrame->scope()->vm(), callFrame, codeBlock, stubInfo, prototypeStructureList, listIndex, structure, protoChain, count, propertyName, slot, offset);
1877
1878             if (listIndex == (POLYMORPHIC_LIST_CACHE_SIZE - 1))
1879                 ctiPatchCallByReturnAddress(codeBlock, STUB_RETURN_ADDRESS, FunctionPtr(cti_op_get_by_id_proto_list_full));
1880         }
1881     }
1882
1883     return JSValue::encode(result);
1884 }
1885
1886 DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_id_proto_list_full)
1887 {
1888     STUB_INIT_STACK_FRAME(stackFrame);
1889
1890     JSValue baseValue = stackFrame.args[0].jsValue();
1891     PropertySlot slot(baseValue);
1892     JSValue result = baseValue.get(stackFrame.callFrame, stackFrame.args[1].identifier(), slot);
1893
1894     CHECK_FOR_EXCEPTION_AT_END();
1895     return JSValue::encode(result);
1896 }
1897
1898 DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_id_proto_fail)
1899 {
1900     STUB_INIT_STACK_FRAME(stackFrame);
1901
1902     JSValue baseValue = stackFrame.args[0].jsValue();
1903     PropertySlot slot(baseValue);
1904     JSValue result = baseValue.get(stackFrame.callFrame, stackFrame.args[1].identifier(), slot);
1905
1906     CHECK_FOR_EXCEPTION_AT_END();
1907     return JSValue::encode(result);
1908 }
1909
1910 DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_id_array_fail)
1911 {
1912     STUB_INIT_STACK_FRAME(stackFrame);
1913
1914     JSValue baseValue = stackFrame.args[0].jsValue();
1915     PropertySlot slot(baseValue);
1916     JSValue result = baseValue.get(stackFrame.callFrame, stackFrame.args[1].identifier(), slot);
1917
1918     CHECK_FOR_EXCEPTION_AT_END();
1919     return JSValue::encode(result);
1920 }
1921
1922 DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_id_string_fail)
1923 {
1924     STUB_INIT_STACK_FRAME(stackFrame);
1925
1926     JSValue baseValue = stackFrame.args[0].jsValue();
1927     PropertySlot slot(baseValue);
1928     JSValue result = baseValue.get(stackFrame.callFrame, stackFrame.args[1].identifier(), slot);
1929
1930     CHECK_FOR_EXCEPTION_AT_END();
1931     return JSValue::encode(result);
1932 }
1933
1934 DEFINE_STUB_FUNCTION(EncodedJSValue, op_check_has_instance)
1935 {
1936     STUB_INIT_STACK_FRAME(stackFrame);
1937
1938     CallFrame* callFrame = stackFrame.callFrame;
1939     JSValue value = stackFrame.args[0].jsValue();
1940     JSValue baseVal = stackFrame.args[1].jsValue();
1941
1942     if (baseVal.isObject()) {
1943         JSObject* baseObject = asObject(baseVal);
1944         ASSERT(!baseObject->structure()->typeInfo().implementsDefaultHasInstance());
1945         if (baseObject->structure()->typeInfo().implementsHasInstance()) {
1946             bool result = baseObject->methodTable()->customHasInstance(baseObject, callFrame, value);
1947             CHECK_FOR_EXCEPTION_AT_END();
1948             return JSValue::encode(jsBoolean(result));
1949         }
1950     }
1951
1952     stackFrame.vm->exception = createInvalidParameterError(callFrame, "instanceof", baseVal);
1953     VM_THROW_EXCEPTION_AT_END();
1954     return JSValue::encode(JSValue());
1955 }
1956
1957 #if ENABLE(DFG_JIT)
1958 DEFINE_STUB_FUNCTION(void, optimize)
1959 {
1960     STUB_INIT_STACK_FRAME(stackFrame);
1961     
1962     CallFrame* callFrame = stackFrame.callFrame;
1963     CodeBlock* codeBlock = callFrame->codeBlock();
1964     unsigned bytecodeIndex = stackFrame.args[0].int32();
1965
1966 #if ENABLE(JIT_VERBOSE_OSR)
1967     dataLog(
1968         *codeBlock, ": Entered optimize with bytecodeIndex = ", bytecodeIndex,
1969         ", executeCounter = ", codeBlock->jitExecuteCounter(),
1970         ", optimizationDelayCounter = ", codeBlock->reoptimizationRetryCounter(),
1971         ", exitCounter = ");
1972     if (codeBlock->hasOptimizedReplacement())
1973         dataLog(codeBlock->replacement()->osrExitCounter());
1974     else
1975         dataLog("N/A");
1976     dataLog("\n");
1977 #endif
1978
1979     if (!codeBlock->checkIfOptimizationThresholdReached()) {
1980         codeBlock->updateAllPredictions();
1981 #if ENABLE(JIT_VERBOSE_OSR)
1982         dataLog("Choosing not to optimize ", *codeBlock, " yet.\n");
1983 #endif
1984         return;
1985     }
1986
1987     if (codeBlock->hasOptimizedReplacement()) {
1988 #if ENABLE(JIT_VERBOSE_OSR)
1989         dataLog("Considering OSR ", *codeBlock, " -> ", *codeBlock->replacement(), ".\n");
1990 #endif
1991         // If we have an optimized replacement, then it must be the case that we entered
1992         // cti_optimize from a loop. That's because is there's an optimized replacement,
1993         // then all calls to this function will be relinked to the replacement and so
1994         // the prologue OSR will never fire.
1995         
1996         // This is an interesting threshold check. Consider that a function OSR exits
1997         // in the middle of a loop, while having a relatively low exit count. The exit
1998         // will reset the execution counter to some target threshold, meaning that this
1999         // code won't be reached until that loop heats up for >=1000 executions. But then
2000         // we do a second check here, to see if we should either reoptimize, or just
2001         // attempt OSR entry. Hence it might even be correct for
2002         // shouldReoptimizeFromLoopNow() to always return true. But we make it do some
2003         // additional checking anyway, to reduce the amount of recompilation thrashing.
2004         if (codeBlock->replacement()->shouldReoptimizeFromLoopNow()) {
2005 #if ENABLE(JIT_VERBOSE_OSR)
2006             dataLog("Triggering reoptimization of ", *codeBlock, "(", *codeBlock->replacement(), ") (in loop).\n");
2007 #endif
2008             codeBlock->reoptimize();
2009             return;
2010         }
2011     } else {
2012         if (!codeBlock->shouldOptimizeNow()) {
2013 #if ENABLE(JIT_VERBOSE_OSR)
2014             dataLog("Delaying optimization for ", *codeBlock, " (in loop) because of insufficient profiling.\n");
2015 #endif
2016             return;
2017         }
2018         
2019 #if ENABLE(JIT_VERBOSE_OSR)
2020         dataLog("Triggering optimized compilation of ", *codeBlock, "\n");
2021 #endif
2022         
2023         JSScope* scope = callFrame->scope();
2024         JSObject* error = codeBlock->compileOptimized(callFrame, scope, bytecodeIndex);
2025 #if ENABLE(JIT_VERBOSE_OSR)
2026         if (error)
2027             dataLog("WARNING: optimized compilation failed.\n");
2028 #else
2029         UNUSED_PARAM(error);
2030 #endif
2031         
2032         if (codeBlock->replacement() == codeBlock) {
2033 #if ENABLE(JIT_VERBOSE_OSR)
2034             dataLog("Optimizing ", *codeBlock, " failed.\n");
2035 #endif
2036             
2037             ASSERT(codeBlock->getJITType() == JITCode::BaselineJIT);
2038             codeBlock->dontOptimizeAnytimeSoon();
2039             return;
2040         }
2041     }
2042     
2043     CodeBlock* optimizedCodeBlock = codeBlock->replacement();
2044     ASSERT(optimizedCodeBlock->getJITType() == JITCode::DFGJIT);
2045     
2046     if (void* address = DFG::prepareOSREntry(callFrame, optimizedCodeBlock, bytecodeIndex)) {
2047         if (Options::showDFGDisassembly()) {
2048             dataLog(
2049                 "Performing OSR ", *codeBlock, " -> ", *optimizedCodeBlock, ", address ",
2050                 RawPointer((STUB_RETURN_ADDRESS).value()), " -> ", RawPointer(address), ".\n");
2051         }
2052 #if ENABLE(JIT_VERBOSE_OSR)
2053         dataLog("Optimizing ", *codeBlock, " succeeded, performing OSR after a delay of ", codeBlock->optimizationDelayCounter(), ".\n");
2054 #endif
2055
2056         codeBlock->optimizeSoon();
2057         STUB_SET_RETURN_ADDRESS(address);
2058         return;
2059     }
2060     
2061 #if ENABLE(JIT_VERBOSE_OSR)
2062     dataLog("Optimizing ", *codeBlock, " succeeded, OSR failed, after a delay of ", codeBlock->optimizationDelayCounter(), ".\n");
2063 #endif
2064
2065     // Count the OSR failure as a speculation failure. If this happens a lot, then
2066     // reoptimize.
2067     optimizedCodeBlock->countOSRExit();
2068     
2069 #if ENABLE(JIT_VERBOSE_OSR)
2070     dataLog("Encountered OSR failure ", *codeBlock, " -> ", *codeBlock->replacement(), ".\n");
2071 #endif
2072
2073     // We are a lot more conservative about triggering reoptimization after OSR failure than
2074     // before it. If we enter the optimize_from_loop trigger with a bucket full of fail
2075     // already, then we really would like to reoptimize immediately. But this case covers
2076     // something else: there weren't many (or any) speculation failures before, but we just
2077     // failed to enter the speculative code because some variable had the wrong value or
2078     // because the OSR code decided for any spurious reason that it did not want to OSR
2079     // right now. So, we only trigger reoptimization only upon the more conservative (non-loop)
2080     // reoptimization trigger.
2081     if (optimizedCodeBlock->shouldReoptimizeNow()) {
2082 #if ENABLE(JIT_VERBOSE_OSR)
2083         dataLog("Triggering reoptimization of ", *codeBlock, " -> ", *codeBlock->replacement(), " (after OSR fail).\n");
2084 #endif
2085         codeBlock->reoptimize();
2086         return;
2087     }
2088
2089     // OSR failed this time, but it might succeed next time! Let the code run a bit
2090     // longer and then try again.
2091     codeBlock->optimizeAfterWarmUp();
2092 }
2093 #endif // ENABLE(DFG_JIT)
2094
2095 DEFINE_STUB_FUNCTION(EncodedJSValue, op_instanceof)
2096 {
2097     STUB_INIT_STACK_FRAME(stackFrame);
2098
2099     CallFrame* callFrame = stackFrame.callFrame;
2100     JSValue value = stackFrame.args[0].jsValue();
2101     JSValue proto = stackFrame.args[1].jsValue();
2102     
2103     ASSERT(!value.isObject() || !proto.isObject());
2104
2105     bool result = JSObject::defaultHasInstance(callFrame, value, proto);
2106     CHECK_FOR_EXCEPTION_AT_END();
2107     return JSValue::encode(jsBoolean(result));
2108 }
2109
2110 DEFINE_STUB_FUNCTION(EncodedJSValue, op_del_by_id)
2111 {
2112     STUB_INIT_STACK_FRAME(stackFrame);
2113
2114     CallFrame* callFrame = stackFrame.callFrame;
2115     
2116     JSObject* baseObj = stackFrame.args[0].jsValue().toObject(callFrame);
2117
2118     bool couldDelete = baseObj->methodTable()->deleteProperty(baseObj, callFrame, stackFrame.args[1].identifier());
2119     JSValue result = jsBoolean(couldDelete);
2120     if (!couldDelete && callFrame->codeBlock()->isStrictMode())
2121         stackFrame.vm->exception = createTypeError(stackFrame.callFrame, "Unable to delete property.");
2122
2123     CHECK_FOR_EXCEPTION_AT_END();
2124     return JSValue::encode(result);
2125 }
2126
2127 DEFINE_STUB_FUNCTION(EncodedJSValue, op_mul)
2128 {
2129     STUB_INIT_STACK_FRAME(stackFrame);
2130
2131     JSValue src1 = stackFrame.args[0].jsValue();
2132     JSValue src2 = stackFrame.args[1].jsValue();
2133
2134     if (src1.isNumber() && src2.isNumber())
2135         return JSValue::encode(jsNumber(src1.asNumber() * src2.asNumber()));
2136
2137     CallFrame* callFrame = stackFrame.callFrame;
2138     JSValue result = jsNumber(src1.toNumber(callFrame) * src2.toNumber(callFrame));
2139     CHECK_FOR_EXCEPTION_AT_END();
2140     return JSValue::encode(result);
2141 }
2142
2143 DEFINE_STUB_FUNCTION(JSObject*, op_new_func)
2144 {
2145     STUB_INIT_STACK_FRAME(stackFrame);
2146     
2147     ASSERT(stackFrame.callFrame->codeBlock()->codeType() != FunctionCode || !stackFrame.callFrame->codeBlock()->needsFullScopeChain() || stackFrame.callFrame->uncheckedR(stackFrame.callFrame->codeBlock()->activationRegister()).jsValue());
2148     return JSFunction::create(stackFrame.callFrame, stackFrame.args[0].function(), stackFrame.callFrame->scope());
2149 }
2150
2151 inline void* jitCompileFor(CallFrame* callFrame, CodeSpecializationKind kind)
2152 {
2153     // This function is called by cti_op_call_jitCompile() and
2154     // cti_op_construct_jitCompile() JIT glue trampolines to compile the
2155     // callee function that we want to call. Both cti glue trampolines are
2156     // called by JIT'ed code which has pushed a frame and initialized most of
2157     // the frame content except for the codeBlock.
2158     //
2159     // Normally, the prologue of the callee is supposed to set the frame's cb
2160     // pointer to the cb of the callee. But in this case, the callee code does
2161     // not exist yet until it is compiled below. The compilation process will
2162     // allocate memory which may trigger a GC. The GC, in turn, will scan the
2163     // JSStack, and will expect the frame's cb to either be valid or 0. If
2164     // we don't initialize it, the GC will be accessing invalid memory and may
2165     // crash.
2166     //
2167     // Hence, we should nullify it here before proceeding with the compilation.
2168     callFrame->setCodeBlock(0);
2169
2170     JSFunction* function = jsCast<JSFunction*>(callFrame->callee());
2171     ASSERT(!function->isHostFunction());
2172     FunctionExecutable* executable = function->jsExecutable();
2173     JSScope* callDataScopeChain = function->scope();
2174     JSObject* error = executable->compileFor(callFrame, callDataScopeChain, kind);
2175     if (!error)
2176         return function;
2177     callFrame->vm().exception = error;
2178     return 0;
2179 }
2180
2181 DEFINE_STUB_FUNCTION(void*, op_call_jitCompile)
2182 {
2183     STUB_INIT_STACK_FRAME(stackFrame);
2184
2185 #if !ASSERT_DISABLED
2186     CallData callData;
2187     ASSERT(stackFrame.callFrame->callee()->methodTable()->getCallData(stackFrame.callFrame->callee(), callData) == CallTypeJS);
2188 #endif
2189     
2190     CallFrame* callFrame = stackFrame.callFrame;
2191     void* result = jitCompileFor(callFrame, CodeForCall);
2192     if (!result)
2193         return throwExceptionFromOpCall<void*>(stackFrame, callFrame, STUB_RETURN_ADDRESS);
2194
2195     return result;
2196 }
2197
2198 DEFINE_STUB_FUNCTION(void*, op_construct_jitCompile)
2199 {
2200     STUB_INIT_STACK_FRAME(stackFrame);
2201
2202 #if !ASSERT_DISABLED
2203     ConstructData constructData;
2204     ASSERT(jsCast<JSFunction*>(stackFrame.callFrame->callee())->methodTable()->getConstructData(stackFrame.callFrame->callee(), constructData) == ConstructTypeJS);
2205 #endif
2206
2207     CallFrame* callFrame = stackFrame.callFrame;    
2208     void* result = jitCompileFor(callFrame, CodeForConstruct);
2209     if (!result)
2210         return throwExceptionFromOpCall<void*>(stackFrame, callFrame, STUB_RETURN_ADDRESS);
2211
2212     return result;
2213 }
2214
2215 DEFINE_STUB_FUNCTION(void*, op_call_arityCheck)
2216 {
2217     STUB_INIT_STACK_FRAME(stackFrame);
2218
2219     CallFrame* callFrame = stackFrame.callFrame;
2220
2221     CallFrame* newCallFrame = CommonSlowPaths::arityCheckFor(callFrame, stackFrame.stack, CodeForCall);
2222     if (!newCallFrame) {
2223         ErrorWithExecFunctor functor = ErrorWithExecFunctor(createStackOverflowError);
2224         return throwExceptionFromOpCall<void*>(stackFrame, callFrame, STUB_RETURN_ADDRESS, functor);
2225     }
2226     return newCallFrame;
2227 }
2228
2229 DEFINE_STUB_FUNCTION(void*, op_construct_arityCheck)
2230 {
2231     STUB_INIT_STACK_FRAME(stackFrame);
2232
2233     CallFrame* callFrame = stackFrame.callFrame;
2234
2235     CallFrame* newCallFrame = CommonSlowPaths::arityCheckFor(callFrame, stackFrame.stack, CodeForConstruct);
2236     if (!newCallFrame) {
2237         ErrorWithExecFunctor functor = ErrorWithExecFunctor(createStackOverflowError);
2238         return throwExceptionFromOpCall<void*>(stackFrame, callFrame, STUB_RETURN_ADDRESS, functor);
2239     }
2240     return newCallFrame;
2241 }
2242
2243 inline void* lazyLinkFor(CallFrame* callFrame, CodeSpecializationKind kind)
2244 {
2245     JSFunction* callee = jsCast<JSFunction*>(callFrame->callee());
2246     ExecutableBase* executable = callee->executable();
2247
2248     MacroAssemblerCodePtr codePtr;
2249     CodeBlock* codeBlock = 0;
2250     CallLinkInfo* callLinkInfo = &callFrame->callerFrame()->codeBlock()->getCallLinkInfo(callFrame->returnPC());
2251
2252     // This function is called by cti_vm_lazyLinkCall() and
2253     // cti_lazyLinkConstruct JIT glue trampolines to link the callee function
2254     // that we want to call. Both cti glue trampolines are called by JIT'ed
2255     // code which has pushed a frame and initialized most of the frame content
2256     // except for the codeBlock.
2257     //
2258     // Normally, the prologue of the callee is supposed to set the frame's cb
2259     // field to the cb of the callee. But in this case, the callee may not
2260     // exist yet, and if not, it will be generated in the compilation below.
2261     // The compilation will allocate memory which may trigger a GC. The GC, in
2262     // turn, will scan the JSStack, and will expect the frame's cb to be valid
2263     // or 0. If we don't initialize it, the GC will be accessing invalid
2264     // memory and may crash.
2265     //
2266     // Hence, we should nullify it here before proceeding with the compilation.
2267     callFrame->setCodeBlock(0);
2268
2269     if (executable->isHostFunction())
2270         codePtr = executable->generatedJITCodeFor(kind)->addressForCall();
2271     else {
2272         FunctionExecutable* functionExecutable = static_cast<FunctionExecutable*>(executable);
2273         if (JSObject* error = functionExecutable->compileFor(callFrame, callee->scope(), kind)) {
2274             callFrame->vm().exception = error;
2275             return 0;
2276         }
2277         codeBlock = &functionExecutable->generatedBytecodeFor(kind);
2278         if (callFrame->argumentCountIncludingThis() < static_cast<size_t>(codeBlock->numParameters())
2279             || callLinkInfo->callType == CallLinkInfo::CallVarargs)
2280             codePtr = functionExecutable->generatedJITCodeWithArityCheckFor(kind);
2281         else
2282             codePtr = functionExecutable->generatedJITCodeFor(kind)->addressForCall();
2283     }
2284
2285     if (!callLinkInfo->seenOnce())
2286         callLinkInfo->setSeen();
2287     else
2288         JIT::linkFor(callee, callFrame->callerFrame()->codeBlock(), codeBlock, codePtr, callLinkInfo, &callFrame->vm(), kind);
2289
2290     return codePtr.executableAddress();
2291 }
2292
2293 DEFINE_STUB_FUNCTION(void*, vm_lazyLinkCall)
2294 {
2295     STUB_INIT_STACK_FRAME(stackFrame);
2296
2297     CallFrame* callFrame = stackFrame.callFrame;
2298     void* result = lazyLinkFor(callFrame, CodeForCall);
2299     if (!result)
2300         return throwExceptionFromOpCall<void*>(stackFrame, callFrame, STUB_RETURN_ADDRESS);
2301
2302     return result;
2303 }
2304
2305 DEFINE_STUB_FUNCTION(void*, vm_lazyLinkClosureCall)
2306 {
2307     STUB_INIT_STACK_FRAME(stackFrame);
2308
2309     CallFrame* callFrame = stackFrame.callFrame;
2310     
2311     CodeBlock* callerCodeBlock = callFrame->callerFrame()->codeBlock();
2312     VM* vm = callerCodeBlock->vm();
2313     CallLinkInfo* callLinkInfo = &callerCodeBlock->getCallLinkInfo(callFrame->returnPC());
2314     JSFunction* callee = jsCast<JSFunction*>(callFrame->callee());
2315     ExecutableBase* executable = callee->executable();
2316     Structure* structure = callee->structure();
2317     
2318     ASSERT(callLinkInfo->callType == CallLinkInfo::Call);
2319     ASSERT(callLinkInfo->isLinked());
2320     ASSERT(callLinkInfo->callee);
2321     ASSERT(callee != callLinkInfo->callee.get());
2322     
2323     bool shouldLink = false;
2324     CodeBlock* calleeCodeBlock = 0;
2325     MacroAssemblerCodePtr codePtr;
2326     
2327     if (executable == callLinkInfo->callee.get()->executable()
2328         && structure == callLinkInfo->callee.get()->structure()) {
2329         
2330         shouldLink = true;
2331         
2332         ASSERT(executable->hasJITCodeForCall());
2333         codePtr = executable->generatedJITCodeForCall()->addressForCall();
2334         if (!callee->executable()->isHostFunction()) {
2335             calleeCodeBlock = &jsCast<FunctionExecutable*>(executable)->generatedBytecodeForCall();
2336             if (callFrame->argumentCountIncludingThis() < static_cast<size_t>(calleeCodeBlock->numParameters())) {
2337                 shouldLink = false;
2338                 codePtr = executable->generatedJITCodeWithArityCheckFor(CodeForCall);
2339             }
2340         }
2341     } else if (callee->isHostFunction())
2342         codePtr = executable->generatedJITCodeForCall()->addressForCall();
2343     else {
2344         // Need to clear the code block before compilation, because compilation can GC.
2345         callFrame->setCodeBlock(0);
2346         
2347         FunctionExecutable* functionExecutable = jsCast<FunctionExecutable*>(executable);
2348         JSScope* scopeChain = callee->scope();
2349         JSObject* error = functionExecutable->compileFor(callFrame, scopeChain, CodeForCall);
2350         if (error) {
2351             callFrame->vm().exception = error;
2352             return 0;
2353         }
2354         
2355         codePtr = functionExecutable->generatedJITCodeWithArityCheckFor(CodeForCall);
2356     }
2357     
2358     if (shouldLink) {
2359         ASSERT(codePtr);
2360         JIT::compileClosureCall(vm, callLinkInfo, callerCodeBlock, calleeCodeBlock, structure, executable, codePtr);
2361         callLinkInfo->hasSeenClosure = true;
2362     } else
2363         JIT::linkSlowCall(callerCodeBlock, callLinkInfo);
2364
2365     return codePtr.executableAddress();
2366 }
2367
2368 DEFINE_STUB_FUNCTION(void*, vm_lazyLinkConstruct)
2369 {
2370     STUB_INIT_STACK_FRAME(stackFrame);
2371
2372     CallFrame* callFrame = stackFrame.callFrame;
2373     void* result = lazyLinkFor(callFrame, CodeForConstruct);
2374     if (!result)
2375         return throwExceptionFromOpCall<void*>(stackFrame, callFrame, STUB_RETURN_ADDRESS);
2376
2377     return result;
2378 }
2379
2380 DEFINE_STUB_FUNCTION(JSObject*, op_push_activation)
2381 {
2382     STUB_INIT_STACK_FRAME(stackFrame);
2383
2384     JSActivation* activation = JSActivation::create(stackFrame.callFrame->vm(), stackFrame.callFrame, stackFrame.callFrame->codeBlock());
2385     stackFrame.callFrame->setScope(activation);
2386     return activation;
2387 }
2388
2389 DEFINE_STUB_FUNCTION(EncodedJSValue, op_call_NotJSFunction)
2390 {
2391     STUB_INIT_STACK_FRAME(stackFrame);
2392
2393     CallFrame* callFrame = stackFrame.callFrame;
2394     
2395     JSValue callee = callFrame->calleeAsValue();
2396
2397     CallData callData;
2398     CallType callType = getCallData(callee, callData);
2399
2400     ASSERT(callType != CallTypeJS);
2401     if (callType != CallTypeHost) {
2402         ASSERT(callType == CallTypeNone);
2403         ErrorWithExecAndCalleeFunctor functor = ErrorWithExecAndCalleeFunctor(createNotAConstructorError, callee);
2404         return throwExceptionFromOpCall<EncodedJSValue>(stackFrame, callFrame, STUB_RETURN_ADDRESS, functor);
2405     }
2406
2407     EncodedJSValue returnValue;
2408     {
2409         SamplingTool::CallRecord callRecord(CTI_SAMPLER, true);
2410         returnValue = callData.native.function(callFrame);
2411     }
2412
2413     if (stackFrame.vm->exception)
2414         return throwExceptionFromOpCall<EncodedJSValue>(stackFrame, callFrame, STUB_RETURN_ADDRESS);
2415
2416     return returnValue;
2417 }
2418
2419 DEFINE_STUB_FUNCTION(EncodedJSValue, op_create_arguments)
2420 {
2421     STUB_INIT_STACK_FRAME(stackFrame);
2422
2423     Arguments* arguments = Arguments::create(*stackFrame.vm, stackFrame.callFrame);
2424     return JSValue::encode(JSValue(arguments));
2425 }
2426
2427 DEFINE_STUB_FUNCTION(void, op_tear_off_activation)
2428 {
2429     STUB_INIT_STACK_FRAME(stackFrame);
2430
2431     ASSERT(stackFrame.callFrame->codeBlock()->needsFullScopeChain());
2432     jsCast<JSActivation*>(stackFrame.args[0].jsValue())->tearOff(*stackFrame.vm);
2433 }
2434
2435 DEFINE_STUB_FUNCTION(void, op_tear_off_arguments)
2436 {
2437     STUB_INIT_STACK_FRAME(stackFrame);
2438
2439     CallFrame* callFrame = stackFrame.callFrame;
2440     ASSERT(callFrame->codeBlock()->usesArguments());
2441     Arguments* arguments = jsCast<Arguments*>(stackFrame.args[0].jsValue());
2442     if (JSValue activationValue = stackFrame.args[1].jsValue()) {
2443         arguments->didTearOffActivation(callFrame, jsCast<JSActivation*>(activationValue));
2444         return;
2445     }
2446     arguments->tearOff(callFrame);
2447 }
2448
2449 DEFINE_STUB_FUNCTION(void, op_profile_will_call)
2450 {
2451     STUB_INIT_STACK_FRAME(stackFrame);
2452
2453     if (LegacyProfiler* profiler = stackFrame.vm->enabledProfiler())
2454         profiler->willExecute(stackFrame.callFrame, stackFrame.args[0].jsValue());
2455 }
2456
2457 DEFINE_STUB_FUNCTION(void, op_profile_did_call)
2458 {
2459     STUB_INIT_STACK_FRAME(stackFrame);
2460
2461     if (LegacyProfiler* profiler = stackFrame.vm->enabledProfiler())
2462         profiler->didExecute(stackFrame.callFrame, stackFrame.args[0].jsValue());
2463 }
2464
2465 DEFINE_STUB_FUNCTION(JSObject*, op_new_array)
2466 {
2467     STUB_INIT_STACK_FRAME(stackFrame);
2468
2469     return constructArray(stackFrame.callFrame, stackFrame.args[2].arrayAllocationProfile(), reinterpret_cast<JSValue*>(&stackFrame.callFrame->registers()[stackFrame.args[0].int32()]), stackFrame.args[1].int32());
2470 }
2471
2472 DEFINE_STUB_FUNCTION(JSObject*, op_new_array_with_size)
2473 {
2474     STUB_INIT_STACK_FRAME(stackFrame);
2475     
2476     return constructArrayWithSizeQuirk(stackFrame.callFrame, stackFrame.args[1].arrayAllocationProfile(), stackFrame.callFrame->lexicalGlobalObject(), stackFrame.args[0].jsValue());
2477 }
2478
2479 DEFINE_STUB_FUNCTION(JSObject*, op_new_array_buffer)
2480 {
2481     STUB_INIT_STACK_FRAME(stackFrame);
2482     
2483     return constructArray(stackFrame.callFrame, stackFrame.args[2].arrayAllocationProfile(), stackFrame.callFrame->codeBlock()->constantBuffer(stackFrame.args[0].int32()), stackFrame.args[1].int32());
2484 }
2485
2486 DEFINE_STUB_FUNCTION(void, op_init_global_const_check)
2487 {
2488     STUB_INIT_STACK_FRAME(stackFrame);
2489     
2490     CallFrame* callFrame = stackFrame.callFrame;
2491     CodeBlock* codeBlock = callFrame->codeBlock();
2492     symbolTablePut(codeBlock->globalObject(), callFrame, codeBlock->identifier(stackFrame.args[1].int32()), stackFrame.args[0].jsValue(), true);
2493 }
2494
2495 DEFINE_STUB_FUNCTION(EncodedJSValue, op_resolve)
2496 {
2497     STUB_INIT_STACK_FRAME(stackFrame);
2498
2499     CallFrame* callFrame = stackFrame.callFrame;
2500
2501     JSValue result = JSScope::resolve(callFrame, stackFrame.args[0].identifier(), stackFrame.args[1].resolveOperations());
2502     CHECK_FOR_EXCEPTION_AT_END();
2503     return JSValue::encode(result);
2504 }
2505
2506 DEFINE_STUB_FUNCTION(void, op_put_to_base)
2507 {
2508     STUB_INIT_STACK_FRAME(stackFrame);
2509
2510     CallFrame* callFrame = stackFrame.callFrame;
2511     JSValue base = callFrame->r(stackFrame.args[0].int32()).jsValue();
2512     JSValue value = callFrame->r(stackFrame.args[2].int32()).jsValue();
2513     JSScope::resolvePut(callFrame, base, stackFrame.args[1].identifier(), value, stackFrame.args[3].putToBaseOperation());
2514     CHECK_FOR_EXCEPTION_AT_END();
2515 }
2516
2517 DEFINE_STUB_FUNCTION(EncodedJSValue, op_construct_NotJSConstruct)
2518 {
2519     STUB_INIT_STACK_FRAME(stackFrame);
2520
2521     CallFrame* callFrame = stackFrame.callFrame;
2522     JSValue callee = callFrame->calleeAsValue();
2523
2524     ConstructData constructData;
2525     ConstructType constructType = getConstructData(callee, constructData);
2526
2527     ASSERT(constructType != ConstructTypeJS);
2528     if (constructType != ConstructTypeHost) {
2529         ASSERT(constructType == ConstructTypeNone);
2530         ErrorWithExecAndCalleeFunctor functor = ErrorWithExecAndCalleeFunctor(createNotAConstructorError, callee);
2531         return throwExceptionFromOpCall<EncodedJSValue>(stackFrame, callFrame, STUB_RETURN_ADDRESS, functor);
2532     }
2533
2534     EncodedJSValue returnValue;
2535     {
2536         SamplingTool::CallRecord callRecord(CTI_SAMPLER, true);
2537         returnValue = constructData.native.function(callFrame);
2538     }
2539
2540     if (stackFrame.vm->exception)
2541         return throwExceptionFromOpCall<EncodedJSValue>(stackFrame, callFrame, STUB_RETURN_ADDRESS);
2542
2543     return returnValue;
2544 }
2545
2546 static JSValue getByVal(
2547     CallFrame* callFrame, JSValue baseValue, JSValue subscript, ReturnAddressPtr returnAddress)
2548 {
2549     if (LIKELY(baseValue.isCell() && subscript.isString())) {
2550         if (JSValue result = baseValue.asCell()->fastGetOwnProperty(callFrame, asString(subscript)->value(callFrame)))
2551             return result;
2552     }
2553
2554     if (subscript.isUInt32()) {
2555         uint32_t i = subscript.asUInt32();
2556         if (isJSString(baseValue) && asString(baseValue)->canGetIndex(i)) {
2557             ctiPatchCallByReturnAddress(callFrame->codeBlock(), returnAddress, FunctionPtr(cti_op_get_by_val_string));
2558             return asString(baseValue)->getIndex(callFrame, i);
2559         }
2560         return baseValue.get(callFrame, i);
2561     }
2562
2563     if (isName(subscript))
2564         return baseValue.get(callFrame, jsCast<NameInstance*>(subscript.asCell())->privateName());
2565
2566     Identifier property(callFrame, subscript.toString(callFrame)->value(callFrame));
2567     return baseValue.get(callFrame, property);
2568 }
2569
2570 DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_val)
2571 {
2572     STUB_INIT_STACK_FRAME(stackFrame);
2573
2574     CallFrame* callFrame = stackFrame.callFrame;
2575
2576     JSValue baseValue = stackFrame.args[0].jsValue();
2577     JSValue subscript = stackFrame.args[1].jsValue();
2578     
2579     if (baseValue.isObject() && subscript.isInt32()) {
2580         // See if it's worth optimizing this at all.
2581         JSObject* object = asObject(baseValue);
2582         bool didOptimize = false;
2583
2584         unsigned bytecodeOffset = callFrame->bytecodeOffsetForNonDFGCode();
2585         ASSERT(bytecodeOffset);
2586         ByValInfo& byValInfo = callFrame->codeBlock()->getByValInfo(bytecodeOffset - 1);
2587         ASSERT(!byValInfo.stubRoutine);
2588         
2589         if (hasOptimizableIndexing(object->structure())) {
2590             // Attempt to optimize.
2591             JITArrayMode arrayMode = jitArrayModeForStructure(object->structure());
2592             if (arrayMode != byValInfo.arrayMode) {
2593                 JIT::compileGetByVal(&callFrame->vm(), callFrame->codeBlock(), &byValInfo, STUB_RETURN_ADDRESS, arrayMode);
2594                 didOptimize = true;
2595             }
2596         }
2597         
2598         if (!didOptimize) {
2599             // If we take slow path more than 10 times without patching then make sure we
2600             // never make that mistake again. Or, if we failed to patch and we have some object
2601             // that intercepts indexed get, then don't even wait until 10 times. For cases
2602             // where we see non-index-intercepting objects, this gives 10 iterations worth of
2603             // opportunity for us to observe that the get_by_val may be polymorphic.
2604             if (++byValInfo.slowPathCount >= 10
2605                 || object->structure()->typeInfo().interceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero()) {
2606                 // Don't ever try to optimize.
2607                 RepatchBuffer repatchBuffer(callFrame->codeBlock());
2608                 repatchBuffer.relinkCallerToFunction(STUB_RETURN_ADDRESS, FunctionPtr(cti_op_get_by_val_generic));
2609             }
2610         }
2611     }
2612     
2613     JSValue result = getByVal(callFrame, baseValue, subscript, STUB_RETURN_ADDRESS);
2614     CHECK_FOR_EXCEPTION();
2615     return JSValue::encode(result);
2616 }
2617     
2618 DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_val_generic)
2619 {
2620     STUB_INIT_STACK_FRAME(stackFrame);
2621
2622     CallFrame* callFrame = stackFrame.callFrame;
2623
2624     JSValue baseValue = stackFrame.args[0].jsValue();
2625     JSValue subscript = stackFrame.args[1].jsValue();
2626     
2627     JSValue result = getByVal(callFrame, baseValue, subscript, STUB_RETURN_ADDRESS);
2628     CHECK_FOR_EXCEPTION();
2629     return JSValue::encode(result);
2630 }
2631     
2632 DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_val_string)
2633 {
2634     STUB_INIT_STACK_FRAME(stackFrame);
2635     
2636     CallFrame* callFrame = stackFrame.callFrame;
2637     
2638     JSValue baseValue = stackFrame.args[0].jsValue();
2639     JSValue subscript = stackFrame.args[1].jsValue();
2640     
2641     JSValue result;
2642     
2643     if (LIKELY(subscript.isUInt32())) {
2644         uint32_t i = subscript.asUInt32();
2645         if (isJSString(baseValue) && asString(baseValue)->canGetIndex(i))
2646             result = asString(baseValue)->getIndex(callFrame, i);
2647         else {
2648             result = baseValue.get(callFrame, i);
2649             if (!isJSString(baseValue))
2650                 ctiPatchCallByReturnAddress(callFrame->codeBlock(), STUB_RETURN_ADDRESS, FunctionPtr(cti_op_get_by_val));
2651         }
2652     } else if (isName(subscript))
2653         result = baseValue.get(callFrame, jsCast<NameInstance*>(subscript.asCell())->privateName());
2654     else {
2655         Identifier property(callFrame, subscript.toString(callFrame)->value(callFrame));
2656         result = baseValue.get(callFrame, property);
2657     }
2658     
2659     CHECK_FOR_EXCEPTION_AT_END();
2660     return JSValue::encode(result);
2661 }
2662     
2663 DEFINE_STUB_FUNCTION(EncodedJSValue, op_sub)
2664 {
2665     STUB_INIT_STACK_FRAME(stackFrame);
2666
2667     JSValue src1 = stackFrame.args[0].jsValue();
2668     JSValue src2 = stackFrame.args[1].jsValue();
2669
2670     if (src1.isNumber() && src2.isNumber())
2671         return JSValue::encode(jsNumber(src1.asNumber() - src2.asNumber()));
2672
2673     CallFrame* callFrame = stackFrame.callFrame;
2674     JSValue result = jsNumber(src1.toNumber(callFrame) - src2.toNumber(callFrame));
2675     CHECK_FOR_EXCEPTION_AT_END();
2676     return JSValue::encode(result);
2677 }
2678
2679 static void putByVal(CallFrame* callFrame, JSValue baseValue, JSValue subscript, JSValue value)
2680 {
2681     if (LIKELY(subscript.isUInt32())) {
2682         uint32_t i = subscript.asUInt32();
2683         if (baseValue.isObject()) {
2684             JSObject* object = asObject(baseValue);
2685             if (object->canSetIndexQuickly(i))
2686                 object->setIndexQuickly(callFrame->vm(), i, value);
2687             else
2688                 object->methodTable()->putByIndex(object, callFrame, i, value, callFrame->codeBlock()->isStrictMode());
2689         } else
2690             baseValue.putByIndex(callFrame, i, value, callFrame->codeBlock()->isStrictMode());
2691     } else if (isName(subscript)) {
2692         PutPropertySlot slot(callFrame->codeBlock()->isStrictMode());
2693         baseValue.put(callFrame, jsCast<NameInstance*>(subscript.asCell())->privateName(), value, slot);
2694     } else {
2695         Identifier property(callFrame, subscript.toString(callFrame)->value(callFrame));
2696         if (!callFrame->vm().exception) { // Don't put to an object if toString threw an exception.
2697             PutPropertySlot slot(callFrame->codeBlock()->isStrictMode());
2698             baseValue.put(callFrame, property, value, slot);
2699         }
2700     }
2701 }
2702
2703 DEFINE_STUB_FUNCTION(void, op_put_by_val)
2704 {
2705     STUB_INIT_STACK_FRAME(stackFrame);
2706
2707     CallFrame* callFrame = stackFrame.callFrame;
2708
2709     JSValue baseValue = stackFrame.args[0].jsValue();
2710     JSValue subscript = stackFrame.args[1].jsValue();
2711     JSValue value = stackFrame.args[2].jsValue();
2712     
2713     if (baseValue.isObject() && subscript.isInt32()) {
2714         // See if it's worth optimizing at all.
2715         JSObject* object = asObject(baseValue);
2716         bool didOptimize = false;
2717
2718         unsigned bytecodeOffset = callFrame->bytecodeOffsetForNonDFGCode();
2719         ASSERT(bytecodeOffset);
2720         ByValInfo& byValInfo = callFrame->codeBlock()->getByValInfo(bytecodeOffset - 1);
2721         ASSERT(!byValInfo.stubRoutine);
2722         
2723         if (hasOptimizableIndexing(object->structure())) {
2724             // Attempt to optimize.
2725             JITArrayMode arrayMode = jitArrayModeForStructure(object->structure());
2726             if (arrayMode != byValInfo.arrayMode) {
2727                 JIT::compilePutByVal(&callFrame->vm(), callFrame->codeBlock(), &byValInfo, STUB_RETURN_ADDRESS, arrayMode);
2728                 didOptimize = true;
2729             }
2730         }
2731
2732         if (!didOptimize) {
2733             // If we take slow path more than 10 times without patching then make sure we
2734             // never make that mistake again. Or, if we failed to patch and we have some object
2735             // that intercepts indexed get, then don't even wait until 10 times. For cases
2736             // where we see non-index-intercepting objects, this gives 10 iterations worth of
2737             // opportunity for us to observe that the get_by_val may be polymorphic.
2738             if (++byValInfo.slowPathCount >= 10
2739                 || object->structure()->typeInfo().interceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero()) {
2740                 // Don't ever try to optimize.
2741                 RepatchBuffer repatchBuffer(callFrame->codeBlock());
2742                 repatchBuffer.relinkCallerToFunction(STUB_RETURN_ADDRESS, FunctionPtr(cti_op_put_by_val_generic));
2743             }
2744         }
2745     }
2746     
2747     putByVal(callFrame, baseValue, subscript, value);
2748
2749     CHECK_FOR_EXCEPTION_AT_END();
2750 }
2751
2752 DEFINE_STUB_FUNCTION(void, op_put_by_val_generic)
2753 {
2754     STUB_INIT_STACK_FRAME(stackFrame);
2755
2756     CallFrame* callFrame = stackFrame.callFrame;
2757
2758     JSValue baseValue = stackFrame.args[0].jsValue();
2759     JSValue subscript = stackFrame.args[1].jsValue();
2760     JSValue value = stackFrame.args[2].jsValue();
2761     
2762     putByVal(callFrame, baseValue, subscript, value);
2763
2764     CHECK_FOR_EXCEPTION_AT_END();
2765 }
2766
2767 DEFINE_STUB_FUNCTION(EncodedJSValue, op_less)
2768 {
2769     STUB_INIT_STACK_FRAME(stackFrame);
2770
2771     CallFrame* callFrame = stackFrame.callFrame;
2772     JSValue result = jsBoolean(jsLess<true>(callFrame, stackFrame.args[0].jsValue(), stackFrame.args[1].jsValue()));
2773     CHECK_FOR_EXCEPTION_AT_END();
2774     return JSValue::encode(result);
2775 }
2776
2777 DEFINE_STUB_FUNCTION(EncodedJSValue, op_lesseq)
2778 {
2779     STUB_INIT_STACK_FRAME(stackFrame);
2780
2781     CallFrame* callFrame = stackFrame.callFrame;
2782     JSValue result = jsBoolean(jsLessEq<true>(callFrame, stackFrame.args[0].jsValue(), stackFrame.args[1].jsValue()));
2783     CHECK_FOR_EXCEPTION_AT_END();
2784     return JSValue::encode(result);
2785 }
2786
2787 DEFINE_STUB_FUNCTION(EncodedJSValue, op_greater)
2788 {
2789     STUB_INIT_STACK_FRAME(stackFrame);
2790
2791     CallFrame* callFrame = stackFrame.callFrame;
2792     JSValue result = jsBoolean(jsLess<false>(callFrame, stackFrame.args[1].jsValue(), stackFrame.args[0].jsValue()));
2793     CHECK_FOR_EXCEPTION_AT_END();
2794     return JSValue::encode(result);
2795 }
2796
2797 DEFINE_STUB_FUNCTION(EncodedJSValue, op_greatereq)
2798 {
2799     STUB_INIT_STACK_FRAME(stackFrame);
2800
2801     CallFrame* callFrame = stackFrame.callFrame;
2802     JSValue result = jsBoolean(jsLessEq<false>(callFrame, stackFrame.args[1].jsValue(), stackFrame.args[0].jsValue()));
2803     CHECK_FOR_EXCEPTION_AT_END();
2804     return JSValue::encode(result);
2805 }
2806
2807 DEFINE_STUB_FUNCTION(void*, op_load_varargs)
2808 {
2809     STUB_INIT_STACK_FRAME(stackFrame);
2810
2811     CallFrame* callFrame = stackFrame.callFrame;
2812     JSStack* stack = stackFrame.stack;
2813     JSValue thisValue = stackFrame.args[0].jsValue();
2814     JSValue arguments = stackFrame.args[1].jsValue();
2815     int firstFreeRegister = stackFrame.args[2].int32();
2816
2817     CallFrame* newCallFrame = loadVarargs(callFrame, stack, thisValue, arguments, firstFreeRegister);
2818     if (!newCallFrame)
2819         VM_THROW_EXCEPTION();
2820     return newCallFrame;
2821 }
2822
2823 DEFINE_STUB_FUNCTION(EncodedJSValue, op_negate)
2824 {
2825     STUB_INIT_STACK_FRAME(stackFrame);
2826
2827     JSValue src = stackFrame.args[0].jsValue();
2828
2829     if (src.isNumber())
2830         return JSValue::encode(jsNumber(-src.asNumber()));
2831
2832     CallFrame* callFrame = stackFrame.callFrame;
2833     JSValue result = jsNumber(-src.toNumber(callFrame));
2834     CHECK_FOR_EXCEPTION_AT_END();
2835     return JSValue::encode(result);
2836 }
2837
2838 DEFINE_STUB_FUNCTION(EncodedJSValue, op_resolve_base)
2839 {
2840     STUB_INIT_STACK_FRAME(stackFrame);
2841
2842     return JSValue::encode(JSScope::resolveBase(stackFrame.callFrame, stackFrame.args[0].identifier(), false, stackFrame.args[1].resolveOperations(), stackFrame.args[2].putToBaseOperation()));
2843 }
2844
2845 DEFINE_STUB_FUNCTION(EncodedJSValue, op_resolve_base_strict_put)
2846 {
2847     STUB_INIT_STACK_FRAME(stackFrame);
2848
2849     if (JSValue result = JSScope::resolveBase(stackFrame.callFrame, stackFrame.args[0].identifier(), true, stackFrame.args[1].resolveOperations(), stackFrame.args[2].putToBaseOperation()))
2850         return JSValue::encode(result);
2851     VM_THROW_EXCEPTION();
2852 }
2853
2854 DEFINE_STUB_FUNCTION(EncodedJSValue, op_div)
2855 {
2856     STUB_INIT_STACK_FRAME(stackFrame);
2857
2858     JSValue src1 = stackFrame.args[0].jsValue();
2859     JSValue src2 = stackFrame.args[1].jsValue();
2860
2861     if (src1.isNumber() && src2.isNumber())
2862         return JSValue::encode(jsNumber(src1.asNumber() / src2.asNumber()));
2863
2864     CallFrame* callFrame = stackFrame.callFrame;
2865     JSValue result = jsNumber(src1.toNumber(callFrame) / src2.toNumber(callFrame));
2866     CHECK_FOR_EXCEPTION_AT_END();
2867     return JSValue::encode(result);
2868 }
2869
2870 DEFINE_STUB_FUNCTION(EncodedJSValue, op_dec)
2871 {
2872     STUB_INIT_STACK_FRAME(stackFrame);
2873
2874     JSValue v = stackFrame.args[0].jsValue();
2875
2876     CallFrame* callFrame = stackFrame.callFrame;
2877     JSValue result = jsNumber(v.toNumber(callFrame) - 1);
2878     CHECK_FOR_EXCEPTION_AT_END();
2879     return JSValue::encode(result);
2880 }
2881
2882 DEFINE_STUB_FUNCTION(int, op_jless)
2883 {
2884     STUB_INIT_STACK_FRAME(stackFrame);
2885
2886     JSValue src1 = stackFrame.args[0].jsValue();
2887     JSValue src2 = stackFrame.args[1].jsValue();
2888     CallFrame* callFrame = stackFrame.callFrame;
2889
2890     bool result = jsLess<true>(callFrame, src1, src2);
2891     CHECK_FOR_EXCEPTION_AT_END();
2892     return result;
2893 }
2894
2895 DEFINE_STUB_FUNCTION(int, op_jlesseq)
2896 {
2897     STUB_INIT_STACK_FRAME(stackFrame);
2898
2899     JSValue src1 = stackFrame.args[0].jsValue();
2900     JSValue src2 = stackFrame.args[1].jsValue();
2901     CallFrame* callFrame = stackFrame.callFrame;
2902
2903     bool result = jsLessEq<true>(callFrame, src1, src2);
2904     CHECK_FOR_EXCEPTION_AT_END();
2905     return result;
2906 }
2907
2908 DEFINE_STUB_FUNCTION(int, op_jgreater)
2909 {
2910     STUB_INIT_STACK_FRAME(stackFrame);
2911
2912     JSValue src1 = stackFrame.args[0].jsValue();
2913     JSValue src2 = stackFrame.args[1].jsValue();
2914     CallFrame* callFrame = stackFrame.callFrame;
2915
2916     bool result = jsLess<false>(callFrame, src2, src1);
2917     CHECK_FOR_EXCEPTION_AT_END();
2918     return result;
2919 }
2920
2921 DEFINE_STUB_FUNCTION(int, op_jgreatereq)
2922 {
2923     STUB_INIT_STACK_FRAME(stackFrame);
2924
2925     JSValue src1 = stackFrame.args[0].jsValue();
2926     JSValue src2 = stackFrame.args[1].jsValue();
2927     CallFrame* callFrame = stackFrame.callFrame;
2928
2929     bool result = jsLessEq<false>(callFrame, src2, src1);
2930     CHECK_FOR_EXCEPTION_AT_END();
2931     return result;
2932 }
2933
2934 DEFINE_STUB_FUNCTION(EncodedJSValue, op_not)
2935 {
2936     STUB_INIT_STACK_FRAME(stackFrame);
2937
2938     JSValue src = stackFrame.args[0].jsValue();
2939
2940     JSValue result = jsBoolean(!src.toBoolean(stackFrame.callFrame));
2941     CHECK_FOR_EXCEPTION_AT_END();
2942     return JSValue::encode(result);
2943 }
2944
2945 DEFINE_STUB_FUNCTION(int, op_jtrue)
2946 {
2947     STUB_INIT_STACK_FRAME(stackFrame);
2948
2949     JSValue src1 = stackFrame.args[0].jsValue();
2950
2951     bool result = src1.toBoolean(stackFrame.callFrame);
2952     CHECK_FOR_EXCEPTION_AT_END();
2953     return result;
2954 }
2955
2956 DEFINE_STUB_FUNCTION(int, op_eq)
2957 {
2958     STUB_INIT_STACK_FRAME(stackFrame);
2959
2960     JSValue src1 = stackFrame.args[0].jsValue();
2961     JSValue src2 = stackFrame.args[1].jsValue();
2962
2963 #if USE(JSVALUE32_64)
2964     start:
2965     if (src2.isUndefined()) {
2966         return src1.isNull() || 
2967                (src1.isCell() && src1.asCell()->structure()->masqueradesAsUndefined(stackFrame.callFrame->lexicalGlobalObject()))
2968                || src1.isUndefined();
2969     }
2970     
2971     if (src2.isNull()) {
2972         return src1.isUndefined() || 
2973                (src1.isCell() && src1.asCell()->structure()->masqueradesAsUndefined(stackFrame.callFrame->lexicalGlobalObject()))
2974                || src1.isNull();
2975     }
2976
2977     if (src1.isInt32()) {
2978         if (src2.isDouble())
2979             return src1.asInt32() == src2.asDouble();
2980         double d = src2.toNumber(stackFrame.callFrame);
2981         CHECK_FOR_EXCEPTION();
2982         return src1.asInt32() == d;
2983     }
2984
2985     if (src1.isDouble()) {
2986         if (src2.isInt32())
2987             return src1.asDouble() == src2.asInt32();
2988         double d = src2.toNumber(stackFrame.callFrame);
2989         CHECK_FOR_EXCEPTION();
2990         return src1.asDouble() == d;
2991     }
2992
2993     if (src1.isTrue()) {
2994         if (src2.isFalse())
2995             return false;
2996         double d = src2.toNumber(stackFrame.callFrame);
2997         CHECK_FOR_EXCEPTION();
2998         return d == 1.0;
2999     }
3000
3001     if (src1.isFalse()) {
3002         if (src2.isTrue())
3003             return false;
3004         double d = src2.toNumber(stackFrame.callFrame);
3005         CHECK_FOR_EXCEPTION();
3006         return d == 0.0;
3007     }
3008     
3009     if (src1.isUndefined())
3010         return src2.isCell() && src2.asCell()->structure()->masqueradesAsUndefined(stackFrame.callFrame->lexicalGlobalObject());
3011     
3012     if (src1.isNull())
3013         return src2.isCell() && src2.asCell()->structure()->masqueradesAsUndefined(stackFrame.callFrame->lexicalGlobalObject());
3014
3015     JSCell* cell1 = src1.asCell();
3016
3017     if (cell1->isString()) {
3018         if (src2.isInt32())
3019             return jsToNumber(jsCast<JSString*>(cell1)->value(stackFrame.callFrame)) == src2.asInt32();
3020             
3021         if (src2.isDouble())
3022             return jsToNumber(jsCast<JSString*>(cell1)->value(stackFrame.callFrame)) == src2.asDouble();
3023
3024         if (src2.isTrue())
3025             return jsToNumber(jsCast<JSString*>(cell1)->value(stackFrame.callFrame)) == 1.0;
3026
3027         if (src2.isFalse())
3028             return jsToNumber(jsCast<JSString*>(cell1)->value(stackFrame.callFrame)) == 0.0;
3029
3030         JSCell* cell2 = src2.asCell();
3031         if (cell2->isString())
3032             return jsCast<JSString*>(cell1)->value(stackFrame.callFrame) == jsCast<JSString*>(cell2)->value(stackFrame.callFrame);
3033
3034         src2 = asObject(cell2)->toPrimitive(stackFrame.callFrame);
3035         CHECK_FOR_EXCEPTION();
3036         goto start;
3037     }
3038
3039     if (src2.isObject())
3040         return asObject(cell1) == asObject(src2);
3041     src1 = asObject(cell1)->toPrimitive(stackFrame.callFrame);
3042     CHECK_FOR_EXCEPTION();
3043     goto start;
3044     
3045 #else // USE(JSVALUE32_64)
3046     CallFrame* callFrame = stackFrame.callFrame;
3047     
3048     bool result = JSValue::equalSlowCaseInline(callFrame, src1, src2);
3049     CHECK_FOR_EXCEPTION_AT_END();
3050     return result;
3051 #endif // USE(JSVALUE32_64)
3052 }
3053
3054 DEFINE_STUB_FUNCTION(int, op_eq_strings)
3055 {
3056 #if USE(JSVALUE32_64)
3057     STUB_INIT_STACK_FRAME(stackFrame);
3058
3059     JSString* string1 = stackFrame.args[0].jsString();
3060     JSString* string2 = stackFrame.args[1].jsString();
3061
3062     ASSERT(string1->isString());
3063     ASSERT(string2->isString());
3064     return string1->value(stackFrame.callFrame) == string2->value(stackFrame.callFrame);
3065 #else
3066     UNUSED_PARAM(args);
3067     RELEASE_ASSERT_NOT_REACHED();
3068     return 0;
3069 #endif
3070 }
3071
3072 DEFINE_STUB_FUNCTION(EncodedJSValue, op_lshift)
3073 {
3074     STUB_INIT_STACK_FRAME(stackFrame);
3075
3076     JSValue val = stackFrame.args[0].jsValue();
3077     JSValue shift = stackFrame.args[1].jsValue();
3078
3079     CallFrame* callFrame = stackFrame.callFrame;
3080     JSValue result = jsNumber((val.toInt32(callFrame)) << (shift.toUInt32(callFrame) & 0x1f));
3081     CHECK_FOR_EXCEPTION_AT_END();
3082     return JSValue::encode(result);
3083 }
3084
3085 DEFINE_STUB_FUNCTION(EncodedJSValue, op_bitand)
3086 {
3087     STUB_INIT_STACK_FRAME(stackFrame);
3088
3089     JSValue src1 = stackFrame.args[0].jsValue();
3090     JSValue src2 = stackFrame.args[1].jsValue();
3091
3092     ASSERT(!src1.isInt32() || !src2.isInt32());
3093     CallFrame* callFrame = stackFrame.callFrame;
3094     JSValue result = jsNumber(src1.toInt32(callFrame) & src2.toInt32(callFrame));
3095     CHECK_FOR_EXCEPTION_AT_END();
3096     return JSValue::encode(result);
3097 }
3098
3099 DEFINE_STUB_FUNCTION(EncodedJSValue, op_rshift)
3100 {
3101     STUB_INIT_STACK_FRAME(stackFrame);
3102
3103     JSValue val = stackFrame.args[0].jsValue();
3104     JSValue shift = stackFrame.args[1].jsValue();
3105
3106     CallFrame* callFrame = stackFrame.callFrame;
3107     JSValue result = jsNumber((val.toInt32(callFrame)) >> (shift.toUInt32(callFrame) & 0x1f));
3108
3109     CHECK_FOR_EXCEPTION_AT_END();
3110     return JSValue::encode(result);
3111 }
3112
3113 DEFINE_STUB_FUNCTION(EncodedJSValue, op_resolve_with_base)
3114 {
3115     STUB_INIT_STACK_FRAME(stackFrame);
3116
3117     CallFrame* callFrame = stackFrame.callFrame;
3118     JSValue result = JSScope::resolveWithBase(callFrame, stackFrame.args[0].identifier(), &callFrame->registers()[stackFrame.args[1].int32()], stackFrame.args[2].resolveOperations(), stackFrame.args[3].putToBaseOperation());
3119     CHECK_FOR_EXCEPTION_AT_END();
3120     return JSValue::encode(result);
3121 }
3122
3123 DEFINE_STUB_FUNCTION(EncodedJSValue, op_resolve_with_this)
3124 {
3125     STUB_INIT_STACK_FRAME(stackFrame);
3126
3127     CallFrame* callFrame = stackFrame.callFrame;
3128     JSValue result = JSScope::resolveWithThis(callFrame, stackFrame.args[0].identifier(), &callFrame->registers()[stackFrame.args[1].int32()], stackFrame.args[2].resolveOperations());
3129     CHECK_FOR_EXCEPTION_AT_END();
3130     return JSValue::encode(result);
3131 }
3132
3133 DEFINE_STUB_FUNCTION(JSObject*, op_new_func_exp)
3134 {
3135     STUB_INIT_STACK_FRAME(stackFrame);
3136     CallFrame* callFrame = stackFrame.callFrame;
3137
3138     FunctionExecutable* function = stackFrame.args[0].function();
3139     JSFunction* func = JSFunction::create(callFrame, function, callFrame->scope());
3140     ASSERT(callFrame->codeBlock()->codeType() != FunctionCode || !callFrame->codeBlock()->needsFullScopeChain() || callFrame->uncheckedR(callFrame->codeBlock()->activationRegister()).jsValue());
3141
3142     return func;
3143 }
3144
3145 DEFINE_STUB_FUNCTION(EncodedJSValue, op_mod)
3146 {
3147     STUB_INIT_STACK_FRAME(stackFrame);
3148
3149     JSValue dividendValue = stackFrame.args[0].jsValue();
3150     JSValue divisorValue = stackFrame.args[1].jsValue();
3151
3152     CallFrame* callFrame = stackFrame.callFrame;
3153     double d = dividendValue.toNumber(callFrame);
3154     JSValue result = jsNumber(fmod(d, divisorValue.toNumber(callFrame)));
3155     CHECK_FOR_EXCEPTION_AT_END();
3156     return JSValue::encode(result);
3157 }
3158
3159 DEFINE_STUB_FUNCTION(EncodedJSValue, op_urshift)
3160 {
3161     STUB_INIT_STACK_FRAME(stackFrame);
3162
3163     JSValue val = stackFrame.args[0].jsValue();
3164     JSValue shift = stackFrame.args[1].jsValue();
3165
3166     CallFrame* callFrame = stackFrame.callFrame;
3167     JSValue result = jsNumber((val.toUInt32(callFrame)) >> (shift.toUInt32(callFrame) & 0x1f));
3168     CHECK_FOR_EXCEPTION_AT_END();
3169     return JSValue::encode(result);
3170 }
3171
3172 DEFINE_STUB_FUNCTION(EncodedJSValue, op_bitxor)
3173 {
3174     STUB_INIT_STACK_FRAME(stackFrame);
3175
3176     JSValue src1 = stackFrame.args[0].jsValue();
3177     JSValue src2 = stackFrame.args[1].jsValue();
3178
3179     CallFrame* callFrame = stackFrame.callFrame;
3180
3181     JSValue result = jsNumber(src1.toInt32(callFrame) ^ src2.toInt32(callFrame));
3182     CHECK_FOR_EXCEPTION_AT_END();
3183     return JSValue::encode(result);
3184 }
3185
3186 DEFINE_STUB_FUNCTION(JSObject*, op_new_regexp)
3187 {
3188     STUB_INIT_STACK_FRAME(stackFrame);
3189
3190     CallFrame* callFrame = stackFrame.callFrame;
3191
3192     RegExp* regExp = stackFrame.args[0].regExp();
3193     if (!regExp->isValid()) {
3194         stackFrame.vm->exception = createSyntaxError(callFrame, "Invalid flags supplied to RegExp constructor.");
3195         VM_THROW_EXCEPTION();
3196     }
3197
3198     return RegExpObject::create(*stackFrame.vm, stackFrame.callFrame->lexicalGlobalObject(), stackFrame.callFrame->lexicalGlobalObject()->regExpStructure(), regExp);
3199 }
3200
3201 DEFINE_STUB_FUNCTION(EncodedJSValue, op_bitor)
3202 {
3203     STUB_INIT_STACK_FRAME(stackFrame);
3204
3205     JSValue src1 = stackFrame.args[0].jsValue();
3206     JSValue src2 = stackFrame.args[1].jsValue();
3207
3208     CallFrame* callFrame = stackFrame.callFrame;
3209
3210     JSValue result = jsNumber(src1.toInt32(callFrame) | src2.toInt32(callFrame));
3211     CHECK_FOR_EXCEPTION_AT_END();
3212     return JSValue::encode(result);
3213 }
3214
3215 DEFINE_STUB_FUNCTION(EncodedJSValue, op_call_eval)
3216 {
3217     STUB_INIT_STACK_FRAME(stackFrame);
3218
3219     CallFrame* callFrame = stackFrame.callFrame;
3220     CallFrame* callerFrame = callFrame->callerFrame();
3221     ASSERT(callFrame->callerFrame()->codeBlock()->codeType() != FunctionCode
3222         || !callFrame->callerFrame()->codeBlock()->needsFullScopeChain()
3223         || callFrame->callerFrame()->uncheckedR(callFrame->callerFrame()->codeBlock()->activationRegister()).jsValue());
3224
3225     callFrame->setScope(callerFrame->scope());
3226     callFrame->setReturnPC(static_cast<Instruction*>((STUB_RETURN_ADDRESS).value()));
3227     callFrame->setCodeBlock(0);
3228
3229     if (!isHostFunction(callFrame->calleeAsValue(), globalFuncEval))
3230         return JSValue::encode(JSValue());
3231
3232     JSValue result = eval(callFrame);
3233     if (stackFrame.vm->exception)
3234         return throwExceptionFromOpCall<EncodedJSValue>(stackFrame, callFrame, STUB_RETURN_ADDRESS);
3235
3236     return JSValue::encode(result);
3237 }
3238
3239 DEFINE_STUB_FUNCTION(void*, op_throw)
3240 {
3241     STUB_INIT_STACK_FRAME(stackFrame);
3242     ExceptionHandler handler = jitThrow(stackFrame.vm, stackFrame.callFrame, stackFrame.args[0].jsValue(), STUB_RETURN_ADDRESS);
3243     STUB_SET_RETURN_ADDRESS(handler.catchRoutine);
3244     return handler.callFrame;
3245 }
3246
3247 DEFINE_STUB_FUNCTION(JSPropertyNameIterator*, op_get_pnames)
3248 {
3249     STUB_INIT_STACK_FRAME(stackFrame);
3250
3251     CallFrame* callFrame = stackFrame.callFrame;
3252     JSObject* o = stackFrame.args[0].jsObject();
3253     Structure* structure = o->structure();
3254     JSPropertyNameIterator* jsPropertyNameIterator = structure->enumerationCache();
3255     if (!jsPropertyNameIterator || jsPropertyNameIterator->cachedPrototypeChain() != structure->prototypeChain(callFrame))
3256         jsPropertyNameIterator = JSPropertyNameIterator::create(callFrame, o);
3257     return jsPropertyNameIterator;
3258 }
3259
3260 DEFINE_STUB_FUNCTION(int, has_property)
3261 {
3262     STUB_INIT_STACK_FRAME(stackFrame);
3263
3264     JSObject* base = stackFrame.args[0].jsObject();
3265     JSString* property = stackFrame.args[1].jsString();
3266     int result = base->hasProperty(stackFrame.callFrame, Identifier(stackFrame.callFrame, property->value(stackFrame.callFrame)));
3267     CHECK_FOR_EXCEPTION_AT_END();
3268     return result;
3269 }
3270
3271 DEFINE_STUB_FUNCTION(void, op_push_with_scope)
3272 {
3273     STUB_INIT_STACK_FRAME(stackFrame);
3274
3275     JSObject* o = stackFrame.args[0].jsValue().toObject(stackFrame.callFrame);
3276     CHECK_FOR_EXCEPTION_VOID();
3277     stackFrame.callFrame->setScope(JSWithScope::create(stackFrame.callFrame, o));
3278 }
3279
3280 DEFINE_STUB_FUNCTION(void, op_pop_scope)
3281 {
3282     STUB_INIT_STACK_FRAME(stackFrame);
3283
3284     stackFrame.callFrame->setScope(stackFrame.callFrame->scope()->next());
3285 }
3286
3287 DEFINE_STUB_FUNCTION(EncodedJSValue, op_typeof)
3288 {
3289     STUB_INIT_STACK_FRAME(stackFrame);
3290
3291     return JSValue::encode(jsTypeStringForValue(stackFrame.callFrame, stackFrame.args[0].jsValue()));
3292 }
3293
3294 DEFINE_STUB_FUNCTION(EncodedJSValue, op_is_object)
3295 {
3296     STUB_INIT_STACK_FRAME(stackFrame);
3297
3298     return JSValue::encode(jsBoolean(jsIsObjectType(stackFrame.callFrame, stackFrame.args[0].jsValue())));
3299 }
3300
3301 DEFINE_STUB_FUNCTION(EncodedJSValue, op_is_function)
3302 {
3303     STUB_INIT_STACK_FRAME(stackFrame);
3304
3305     return JSValue::encode(jsBoolean(jsIsFunctionType(stackFrame.args[0].jsValue())));
3306 }
3307
3308 DEFINE_STUB_FUNCTION(EncodedJSValue, op_stricteq)
3309 {
3310     STUB_INIT_STACK_FRAME(stackFrame);
3311
3312     JSValue src1 = stackFrame.args[0].jsValue();
3313     JSValue src2 = stackFrame.args[1].jsValue();
3314     
3315     bool result = JSValue::strictEqual(stackFrame.callFrame, src1, src2);
3316     CHECK_FOR_EXCEPTION_AT_END();
3317     return JSValue::encode(jsBoolean(result));
3318 }
3319
3320 DEFINE_STUB_FUNCTION(EncodedJSValue, op_to_primitive)
3321 {
3322     STUB_INIT_STACK_FRAME(stackFrame);
3323
3324     return JSValue::encode(stackFrame.args[0].jsValue().toPrimitive(stackFrame.callFrame));
3325 }
3326
3327 DEFINE_STUB_FUNCTION(EncodedJSValue, op_strcat)
3328 {
3329     STUB_INIT_STACK_FRAME(stackFrame);
3330
3331     JSValue result = jsString(stackFrame.callFrame, &stackFrame.callFrame->registers()[stackFrame.args[0].int32()], stackFrame.args[1].int32());
3332     CHECK_FOR_EXCEPTION_AT_END();
3333     return JSValue::encode(result);
3334 }
3335
3336 DEFINE_STUB_FUNCTION(EncodedJSValue, op_nstricteq)
3337 {
3338     STUB_INIT_STACK_FRAME(stackFrame);
3339
3340     JSValue src1 = stackFrame.args[0].jsValue();
3341     JSValue src2 = stackFrame.args[1].jsValue();
3342
3343     bool result = !JSValue::strictEqual(stackFrame.callFrame, src1, src2);
3344     CHECK_FOR_EXCEPTION_AT_END();
3345     return JSValue::encode(jsBoolean(result));
3346 }
3347
3348 DEFINE_STUB_FUNCTION(EncodedJSValue, op_to_number)
3349 {
3350     STUB_INIT_STACK_FRAME(stackFrame);
3351
3352     JSValue src = stackFrame.args[0].jsValue();
3353     CallFrame* callFrame = stackFrame.callFrame;
3354
3355     double number = src.toNumber(callFrame);
3356     CHECK_FOR_EXCEPTION_AT_END();
3357     return JSValue::encode(jsNumber(number));
3358 }
3359
3360 DEFINE_STUB_FUNCTION(EncodedJSValue, op_in)
3361 {
3362     STUB_INIT_STACK_FRAME(stackFrame);
3363
3364     CallFrame* callFrame = stackFrame.callFrame;
3365     JSValue baseVal = stackFrame.args[1].jsValue();
3366
3367     if (!baseVal.isObject()) {
3368         stackFrame.vm->exception = createInvalidParameterError(stackFrame.callFrame, "in", baseVal);
3369         VM_THROW_EXCEPTION();
3370     }
3371
3372     JSValue propName = stackFrame.args[0].jsValue();
3373     JSObject* baseObj = asObject(baseVal);
3374
3375     uint32_t i;
3376     if (propName.getUInt32(i))
3377         return JSValue::encode(jsBoolean(baseObj->hasProperty(callFrame, i)));
3378
3379     if (isName(propName))
3380         return JSValue::encode(jsBoolean(baseObj->hasProperty(callFrame, jsCast<NameInstance*>(propName.asCell())->privateName())));
3381
3382     Identifier property(callFrame, propName.toString(callFrame)->value(callFrame));
3383     CHECK_FOR_EXCEPTION();
3384     return JSValue::encode(jsBoolean(baseObj->hasProperty(callFrame, property)));
3385 }
3386
3387 DEFINE_STUB_FUNCTION(void, op_push_name_scope)
3388 {
3389     STUB_INIT_STACK_FRAME(stackFrame);
3390
3391     JSNameScope* scope = JSNameScope::create(stackFrame.callFrame, stackFrame.args[0].identifier(), stackFrame.args[1].jsValue(), stackFrame.args[2].int32());
3392
3393     CallFrame* callFrame = stackFrame.callFrame;
3394     callFrame->setScope(scope);
3395 }
3396
3397 DEFINE_STUB_FUNCTION(void, op_put_by_index)
3398 {
3399     STUB_INIT_STACK_FRAME(stackFrame);
3400
3401     CallFrame* callFrame = stackFrame.callFrame;
3402     unsigned property = stackFrame.args[1].int32();
3403
3404     JSValue arrayValue = stackFrame.args[0].jsValue();
3405     ASSERT(isJSArray(arrayValue));
3406     asArray(arrayValue)->putDirectIndex(callFrame, property, stackFrame.args[2].jsValue());
3407 }
3408
3409 DEFINE_STUB_FUNCTION(void*, op_switch_imm)
3410 {
3411     STUB_INIT_STACK_FRAME(stackFrame);
3412
3413     JSValue scrutinee = stackFrame.args[0].jsValue();
3414     unsigned tableIndex = stackFrame.args[1].int32();
3415     CallFrame* callFrame = stackFrame.callFrame;
3416     CodeBlock* codeBlock = callFrame->codeBlock();
3417
3418     if (scrutinee.isInt32())
3419         return codeBlock->immediateSwitchJumpTable(tableIndex).ctiForValue(scrutinee.asInt32()).executableAddress();
3420     if (scrutinee.isDouble() && scrutinee.asDouble() == static_cast<int32_t>(scrutinee.asDouble()))
3421             return codeBlock->immediateSwitchJumpTable(tableIndex).ctiForValue(static_cast<int32_t>(scrutinee.asDouble())).executableAddress();
3422     return codeBlock->immediateSwitchJumpTable(tableIndex).ctiDefault.executableAddress();
3423 }
3424
3425 DEFINE_STUB_FUNCTION(void*, op_switch_char)
3426 {
3427     STUB_INIT_STACK_FRAME(stackFrame);
3428
3429     JSValue scrutinee = stackFrame.args[0].jsValue();
3430     unsigned tableIndex = stackFrame.args[1].int32();
3431     CallFrame* callFrame = stackFrame.callFrame;
3432     CodeBlock* codeBlock = callFrame->codeBlock();
3433
3434     void* result = codeBlock->characterSwitchJumpTable(tableIndex).ctiDefault.executableAddress();
3435
3436     if (scrutinee.isString()) {
3437         StringImpl* value = asString(scrutinee)->value(callFrame).impl();
3438         if (value->length() == 1)
3439             result = codeBlock->characterSwitchJumpTable(tableIndex).ctiForValue((*value)[0]).executableAddress();
3440     }
3441
3442     CHECK_FOR_EXCEPTION_AT_END();
3443     return result;
3444 }
3445
3446 DEFINE_STUB_FUNCTION(void*, op_switch_string)
3447 {
3448     STUB_INIT_STACK_FRAME(stackFrame);
3449
3450     JSValue scrutinee = stackFrame.args[0].jsValue();
3451     unsigned tableIndex = stackFrame.args[1].int32();
3452     CallFrame* callFrame = stackFrame.callFrame;
3453     CodeBlock* codeBlock = callFrame->codeBlock();
3454
3455     void* result = codeBlock->stringSwitchJumpTable(tableIndex).ctiDefault.executableAddress();
3456
3457     if (scrutinee.isString()) {
3458         StringImpl* value = asString(scrutinee)->value(callFrame).impl();
3459         result = codeBlock->stringSwitchJumpTable(tableIndex).ctiForValue(value).executableAddress();
3460     }
3461
3462     CHECK_FOR_EXCEPTION_AT_END();
3463     return result;
3464 }
3465
3466 DEFINE_STUB_FUNCTION(EncodedJSValue, op_del_by_val)
3467 {
3468     STUB_INIT_STACK_FRAME(stackFrame);
3469
3470     CallFrame* callFrame = stackFrame.callFrame;
3471
3472     JSValue baseValue = stackFrame.args[0].jsValue();
3473     JSObject* baseObj = baseValue.toObject(callFrame); // may throw
3474
3475     JSValue subscript = stackFrame.args[1].jsValue();
3476     bool result;
3477     uint32_t i;
3478     if (subscript.getUInt32(i))
3479         result = baseObj->methodTable()->deletePropertyByIndex(baseObj, callFrame, i);
3480     else if (isName(subscript))
3481         result = baseObj->methodTable()->deleteProperty(baseObj, callFrame, jsCast<NameInstance*>(subscript.asCell())->privateName());
3482     else {
3483         CHECK_FOR_EXCEPTION();
3484         Identifier property(callFrame, subscript.toString(callFrame)->value(callFrame));
3485         CHECK_FOR_EXCEPTION();
3486         result = baseObj->methodTable()->deleteProperty(baseObj, callFrame, property);
3487     }
3488
3489     if (!result && callFrame->codeBlock()->isStrictMode())
3490         stackFrame.vm->exception = createTypeError(stackFrame.callFrame, "Unable to delete property.");
3491
3492     CHECK_FOR_EXCEPTION_AT_END();
3493     return JSValue::encode(jsBoolean(result));
3494 }
3495
3496 DEFINE_STUB_FUNCTION(void, op_put_getter_setter)
3497 {
3498     STUB_INIT_STACK_FRAME(stackFrame);
3499
3500     CallFrame* callFrame = stackFrame.callFrame;
3501
3502     ASSERT(stackFrame.args[0].jsValue().isObject());
3503     JSObject* baseObj = asObject(stackFrame.args[0].jsValue());
3504
3505     GetterSetter* accessor = GetterSetter::create(callFrame);
3506
3507     JSValue getter = stackFrame.args[2].jsValue();
3508     JSValue setter = stackFrame.args[3].jsValue();
3509     ASSERT(getter.isObject() || getter.isUndefined());
3510     ASSERT(setter.isObject() || setter.isUndefined());
3511     ASSERT(getter.isObject() || setter.isObject());
3512
3513     if (!getter.isUndefined())
3514         accessor->setGetter(callFrame->vm(), asObject(getter));
3515     if (!setter.isUndefined())
3516         accessor->setSetter(callFrame->vm(), asObject(setter));
3517     baseObj->putDirectAccessor(callFrame, stackFrame.args[1].identifier(), accessor, Accessor);