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