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