bab7a03dccaf08fcc5402e6942494e38345ff84e
[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     JSGlobalData& globalData = *stackFrame.globalData;
1496     PropertyStorage newStorage = base->growPropertyStorage(globalData, oldSize, newSize);
1497     base->setPropertyStorage(globalData, newStorage, newStructure);
1498
1499     return base;
1500 }
1501
1502 DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_id_method_check)
1503 {
1504     STUB_INIT_STACK_FRAME(stackFrame);
1505
1506     CallFrame* callFrame = stackFrame.callFrame;
1507     Identifier& ident = stackFrame.args[1].identifier();
1508
1509     JSValue baseValue = stackFrame.args[0].jsValue();
1510     PropertySlot slot(baseValue);
1511     JSValue result = baseValue.get(callFrame, ident, slot);
1512     CHECK_FOR_EXCEPTION();
1513
1514     CodeBlock* codeBlock = stackFrame.callFrame->codeBlock();
1515     MethodCallLinkInfo& methodCallLinkInfo = codeBlock->getMethodCallLinkInfo(STUB_RETURN_ADDRESS);
1516     StructureStubInfo& stubInfo = codeBlock->getStubInfo(STUB_RETURN_ADDRESS);
1517
1518     if (!methodCallLinkInfo.seenOnce()) {
1519         methodCallLinkInfo.setSeen();
1520         return JSValue::encode(result);
1521     }
1522
1523     // If we successfully got something, then the base from which it is being accessed must
1524     // be an object.  (Assertion to ensure asObject() call below is safe, which comes after
1525     // an isCacheable() chceck.
1526     ASSERT(!slot.isCacheableValue() || slot.slotBase().isObject());
1527
1528     // Check that:
1529     //   * We're dealing with a JSCell,
1530     //   * the property is cachable,
1531     //   * it's not a dictionary
1532     //   * there is a function cached.
1533     Structure* structure;
1534     JSCell* specific;
1535     JSObject* slotBaseObject;
1536     if (baseValue.isCell()
1537         && slot.isCacheableValue()
1538         && !(structure = baseValue.asCell()->structure())->isUncacheableDictionary()
1539         && (slotBaseObject = asObject(slot.slotBase()))->getPropertySpecificValue(callFrame, ident, specific)
1540         && specific
1541         ) {
1542
1543         JSObject* callee = asObject(specific);
1544
1545         // Since we're accessing a prototype in a loop, it's a good bet that it
1546         // should not be treated as a dictionary.
1547         if (slotBaseObject->structure()->isDictionary())
1548             slotBaseObject->flattenDictionaryObject(callFrame->globalData());
1549
1550         // The result fetched should always be the callee!
1551         ASSERT(result == JSValue(callee));
1552
1553         // Check to see if the function is on the object's prototype.  Patch up the code to optimize.
1554         if (slot.slotBase() == structure->prototypeForLookup(callFrame)) {
1555             JIT::patchMethodCallProto(callFrame->globalData(), codeBlock, methodCallLinkInfo, stubInfo, callee, structure, slotBaseObject, STUB_RETURN_ADDRESS);
1556             return JSValue::encode(result);
1557         }
1558
1559         // Check to see if the function is on the object itself.
1560         // Since we generate the method-check to check both the structure and a prototype-structure (since this
1561         // is the common case) we have a problem - we need to patch the prototype structure check to do something
1562         // useful.  We could try to nop it out altogether, but that's a little messy, so lets do something simpler
1563         // for now.  For now it performs a check on a special object on the global object only used for this
1564         // purpose.  The object is in no way exposed, and as such the check will always pass.
1565         if (slot.slotBase() == baseValue) {
1566             JIT::patchMethodCallProto(callFrame->globalData(), codeBlock, methodCallLinkInfo, stubInfo, callee, structure, callFrame->scopeChain()->globalObject->methodCallDummy(), STUB_RETURN_ADDRESS);
1567             return JSValue::encode(result);
1568         }
1569     }
1570
1571     // Revert the get_by_id op back to being a regular get_by_id - allow it to cache like normal, if it needs to.
1572     ctiPatchCallByReturnAddress(codeBlock, STUB_RETURN_ADDRESS, FunctionPtr(cti_op_get_by_id));
1573     return JSValue::encode(result);
1574 }
1575
1576 DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_id_method_check_update)
1577 {
1578     STUB_INIT_STACK_FRAME(stackFrame);
1579
1580     CallFrame* callFrame = stackFrame.callFrame;
1581     Identifier& ident = stackFrame.args[1].identifier();
1582
1583     JSValue baseValue = stackFrame.args[0].jsValue();
1584     PropertySlot slot(baseValue);
1585     JSValue result = baseValue.get(callFrame, ident, slot);
1586     CHECK_FOR_EXCEPTION();
1587
1588     CodeBlock* codeBlock = stackFrame.callFrame->codeBlock();
1589     MethodCallLinkInfo& methodCallLinkInfo = codeBlock->getMethodCallLinkInfo(STUB_RETURN_ADDRESS);
1590     StructureStubInfo& stubInfo = codeBlock->getStubInfo(STUB_RETURN_ADDRESS);
1591
1592     ASSERT(methodCallLinkInfo.seenOnce());
1593
1594     // If we successfully got something, then the base from which it is being accessed must
1595     // be an object.  (Assertion to ensure asObject() call below is safe, which comes after
1596     // an isCacheable() chceck.
1597     ASSERT(!slot.isCacheableValue() || slot.slotBase().isObject());
1598
1599     // Check that:
1600     //   * We're dealing with a JSCell,
1601     //   * the property is cachable,
1602     //   * it's not a dictionary
1603     //   * there is a function cached.
1604     Structure* structure;
1605     JSCell* specific;
1606     JSObject* slotBaseObject;
1607     if (!(baseValue.isCell()
1608           && slot.isCacheableValue()
1609           && !(structure = baseValue.asCell()->structure())->isUncacheableDictionary()
1610           && (slotBaseObject = asObject(slot.slotBase()))->getPropertySpecificValue(callFrame, ident, specific)
1611           && specific
1612           )
1613         || (slot.slotBase() != structure->prototypeForLookup(callFrame)
1614             && slot.slotBase() != baseValue)) {
1615         // Revert the get_by_id op back to being a regular get_by_id - allow it to cache like normal, if it needs to.
1616         ctiPatchCallByReturnAddress(codeBlock, STUB_RETURN_ADDRESS, FunctionPtr(cti_op_get_by_id));
1617         return JSValue::encode(result);
1618     }
1619     
1620     // Now check if the situation has changed sufficiently that we should bail out of
1621     // doing method_check optimizations entirely, or if it changed only slightly, in
1622     // which case we can just repatch.
1623     
1624     JSValue proto = structure->prototypeForLookup(callFrame);
1625     
1626     bool previousWasProto = methodCallLinkInfo.cachedPrototype.get() != codeBlock->globalObject()->methodCallDummy();
1627     bool currentIsProto = slot.slotBase() == proto;
1628     
1629     JSObject* callee = asObject(specific);
1630     
1631     if (previousWasProto != currentIsProto
1632         || !structure->transitivelyTransitionedFrom(methodCallLinkInfo.cachedStructure.get())
1633         || (previousWasProto && !slotBaseObject->structure()->transitivelyTransitionedFrom(methodCallLinkInfo.cachedPrototypeStructure.get()))
1634         || specific != methodCallLinkInfo.cachedFunction.get()) {
1635         ctiPatchCallByReturnAddress(codeBlock, STUB_RETURN_ADDRESS, FunctionPtr(cti_op_get_by_id));
1636         return JSValue::encode(result);
1637     }
1638     
1639     // It makes sense to simply repatch the method_check.
1640     
1641     // Since we're accessing a prototype in a loop, it's a good bet that it
1642     // should not be treated as a dictionary.
1643     if (slotBaseObject->structure()->isDictionary())
1644         slotBaseObject->flattenDictionaryObject(callFrame->globalData());
1645     
1646     // The result fetched should always be the callee!
1647     ASSERT(result == JSValue(callee));
1648     
1649     // Check to see if the function is on the object's prototype. Patch up the code to optimize.
1650     if (slot.slotBase() == proto) {
1651         JIT::patchMethodCallProto(callFrame->globalData(), codeBlock, methodCallLinkInfo, stubInfo, callee, structure, slotBaseObject, STUB_RETURN_ADDRESS);
1652         return JSValue::encode(result);
1653     }
1654     
1655     ASSERT(slot.slotBase() == baseValue);
1656     
1657     // Since we generate the method-check to check both the structure and a prototype-structure (since this
1658     // is the common case) we have a problem - we need to patch the prototype structure check to do something
1659     // useful. We could try to nop it out altogether, but that's a little messy, so lets do something simpler
1660     // for now. For now it performs a check on a special object on the global object only used for this
1661     // purpose. The object is in no way exposed, and as such the check will always pass.
1662     JIT::patchMethodCallProto(callFrame->globalData(), codeBlock, methodCallLinkInfo, stubInfo, callee, structure, callFrame->scopeChain()->globalObject->methodCallDummy(), STUB_RETURN_ADDRESS);
1663     return JSValue::encode(result);
1664 }
1665
1666 DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_id)
1667 {
1668     STUB_INIT_STACK_FRAME(stackFrame);
1669     CallFrame* callFrame = stackFrame.callFrame;
1670     Identifier& ident = stackFrame.args[1].identifier();
1671
1672     JSValue baseValue = stackFrame.args[0].jsValue();
1673     PropertySlot slot(baseValue);
1674     JSValue result = baseValue.get(callFrame, ident, slot);
1675
1676     CodeBlock* codeBlock = stackFrame.callFrame->codeBlock();
1677     StructureStubInfo* stubInfo = &codeBlock->getStubInfo(STUB_RETURN_ADDRESS);
1678     if (!stubInfo->seenOnce())
1679         stubInfo->setSeen();
1680     else
1681         JITThunks::tryCacheGetByID(callFrame, codeBlock, STUB_RETURN_ADDRESS, baseValue, ident, slot, stubInfo);
1682
1683     CHECK_FOR_EXCEPTION_AT_END();
1684     return JSValue::encode(result);
1685 }
1686
1687 DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_id_self_fail)
1688 {
1689     STUB_INIT_STACK_FRAME(stackFrame);
1690
1691     CallFrame* callFrame = stackFrame.callFrame;
1692     Identifier& ident = stackFrame.args[1].identifier();
1693
1694     JSValue baseValue = stackFrame.args[0].jsValue();
1695     PropertySlot slot(baseValue);
1696     JSValue result = baseValue.get(callFrame, ident, slot);
1697
1698     CHECK_FOR_EXCEPTION();
1699
1700     if (baseValue.isCell()
1701         && slot.isCacheable()
1702         && !baseValue.asCell()->structure()->isUncacheableDictionary()
1703         && slot.slotBase() == baseValue) {
1704
1705         CodeBlock* codeBlock = callFrame->codeBlock();
1706         StructureStubInfo* stubInfo = &codeBlock->getStubInfo(STUB_RETURN_ADDRESS);
1707
1708         ASSERT(slot.slotBase().isObject());
1709
1710         PolymorphicAccessStructureList* polymorphicStructureList;
1711         int listIndex = 1;
1712
1713         if (stubInfo->accessType == access_get_by_id_self) {
1714             ASSERT(!stubInfo->stubRoutine);
1715             polymorphicStructureList = new PolymorphicAccessStructureList(callFrame->globalData(), codeBlock->ownerExecutable(), MacroAssemblerCodeRef(), stubInfo->u.getByIdSelf.baseObjectStructure.get(), true);
1716             stubInfo->initGetByIdSelfList(polymorphicStructureList, 1);
1717         } else {
1718             polymorphicStructureList = stubInfo->u.getByIdSelfList.structureList;
1719             listIndex = stubInfo->u.getByIdSelfList.listSize;
1720         }
1721         if (listIndex < POLYMORPHIC_LIST_CACHE_SIZE) {
1722             stubInfo->u.getByIdSelfList.listSize++;
1723             JIT::compileGetByIdSelfList(callFrame->scopeChain()->globalData, codeBlock, stubInfo, polymorphicStructureList, listIndex, baseValue.asCell()->structure(), ident, slot, slot.cachedOffset());
1724
1725             if (listIndex == (POLYMORPHIC_LIST_CACHE_SIZE - 1))
1726                 ctiPatchCallByReturnAddress(codeBlock, STUB_RETURN_ADDRESS, FunctionPtr(cti_op_get_by_id_generic));
1727         }
1728     } else
1729         ctiPatchCallByReturnAddress(callFrame->codeBlock(), STUB_RETURN_ADDRESS, FunctionPtr(cti_op_get_by_id_generic));
1730     return JSValue::encode(result);
1731 }
1732
1733 static PolymorphicAccessStructureList* getPolymorphicAccessStructureListSlot(JSGlobalData& globalData, ScriptExecutable* owner, StructureStubInfo* stubInfo, int& listIndex)
1734 {
1735     PolymorphicAccessStructureList* prototypeStructureList = 0;
1736     listIndex = 1;
1737
1738     switch (stubInfo->accessType) {
1739     case access_get_by_id_proto:
1740         prototypeStructureList = new PolymorphicAccessStructureList(globalData, owner, stubInfo->stubRoutine, stubInfo->u.getByIdProto.baseObjectStructure.get(), stubInfo->u.getByIdProto.prototypeStructure.get(), true);
1741         stubInfo->stubRoutine = MacroAssemblerCodeRef();
1742         stubInfo->initGetByIdProtoList(prototypeStructureList, 2);
1743         break;
1744     case access_get_by_id_chain:
1745         prototypeStructureList = new PolymorphicAccessStructureList(globalData, owner, stubInfo->stubRoutine, stubInfo->u.getByIdChain.baseObjectStructure.get(), stubInfo->u.getByIdChain.chain.get(), true);
1746         stubInfo->stubRoutine = MacroAssemblerCodeRef();
1747         stubInfo->initGetByIdProtoList(prototypeStructureList, 2);
1748         break;
1749     case access_get_by_id_proto_list:
1750         prototypeStructureList = stubInfo->u.getByIdProtoList.structureList;
1751         listIndex = stubInfo->u.getByIdProtoList.listSize;
1752         if (listIndex < POLYMORPHIC_LIST_CACHE_SIZE)
1753             stubInfo->u.getByIdProtoList.listSize++;
1754         break;
1755     default:
1756         ASSERT_NOT_REACHED();
1757     }
1758     
1759     ASSERT(listIndex <= POLYMORPHIC_LIST_CACHE_SIZE);
1760     return prototypeStructureList;
1761 }
1762
1763 DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_id_getter_stub)
1764 {
1765     STUB_INIT_STACK_FRAME(stackFrame);
1766     CallFrame* callFrame = stackFrame.callFrame;
1767     GetterSetter* getterSetter = asGetterSetter(stackFrame.args[0].jsObject());
1768     if (!getterSetter->getter())
1769         return JSValue::encode(jsUndefined());
1770     JSObject* getter = asObject(getterSetter->getter());
1771     CallData callData;
1772     CallType callType = getter->methodTable()->getCallData(getter, callData);
1773     JSValue result = call(callFrame, getter, callType, callData, stackFrame.args[1].jsObject(), ArgList());
1774     if (callFrame->hadException())
1775         returnToThrowTrampoline(&callFrame->globalData(), stackFrame.args[2].returnAddress(), STUB_RETURN_ADDRESS);
1776
1777     return JSValue::encode(result);
1778 }
1779
1780 DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_id_custom_stub)
1781 {
1782     STUB_INIT_STACK_FRAME(stackFrame);
1783     CallFrame* callFrame = stackFrame.callFrame;
1784     JSObject* slotBase = stackFrame.args[0].jsObject();
1785     PropertySlot::GetValueFunc getter = reinterpret_cast<PropertySlot::GetValueFunc>(stackFrame.args[1].asPointer);
1786     const Identifier& ident = stackFrame.args[2].identifier();
1787     JSValue result = getter(callFrame, slotBase, ident);
1788     if (callFrame->hadException())
1789         returnToThrowTrampoline(&callFrame->globalData(), stackFrame.args[3].returnAddress(), STUB_RETURN_ADDRESS);
1790     
1791     return JSValue::encode(result);
1792 }
1793
1794 DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_id_proto_list)
1795 {
1796     STUB_INIT_STACK_FRAME(stackFrame);
1797
1798     CallFrame* callFrame = stackFrame.callFrame;
1799     const Identifier& propertyName = stackFrame.args[1].identifier();
1800
1801     JSValue baseValue = stackFrame.args[0].jsValue();
1802     PropertySlot slot(baseValue);
1803     JSValue result = baseValue.get(callFrame, propertyName, slot);
1804
1805     CHECK_FOR_EXCEPTION();
1806
1807     if (!baseValue.isCell() || !slot.isCacheable() || baseValue.asCell()->structure()->isDictionary() || baseValue.asCell()->structure()->typeInfo().prohibitsPropertyCaching()) {
1808         ctiPatchCallByReturnAddress(callFrame->codeBlock(), STUB_RETURN_ADDRESS, FunctionPtr(cti_op_get_by_id_proto_fail));
1809         return JSValue::encode(result);
1810     }
1811
1812     Structure* structure = baseValue.asCell()->structure();
1813     CodeBlock* codeBlock = callFrame->codeBlock();
1814     StructureStubInfo* stubInfo = &codeBlock->getStubInfo(STUB_RETURN_ADDRESS);
1815
1816     ASSERT(slot.slotBase().isObject());
1817     JSObject* slotBaseObject = asObject(slot.slotBase());
1818     
1819     size_t offset = slot.cachedOffset();
1820
1821     if (slot.slotBase() == baseValue)
1822         ctiPatchCallByReturnAddress(codeBlock, STUB_RETURN_ADDRESS, FunctionPtr(cti_op_get_by_id_proto_fail));
1823     else if (slot.slotBase() == baseValue.asCell()->structure()->prototypeForLookup(callFrame)) {
1824         ASSERT(!baseValue.asCell()->structure()->isDictionary());
1825         // Since we're accessing a prototype in a loop, it's a good bet that it
1826         // should not be treated as a dictionary.
1827         if (slotBaseObject->structure()->isDictionary()) {
1828             slotBaseObject->flattenDictionaryObject(callFrame->globalData());
1829             offset = slotBaseObject->structure()->get(callFrame->globalData(), propertyName);
1830         }
1831
1832         int listIndex;
1833         PolymorphicAccessStructureList* prototypeStructureList = getPolymorphicAccessStructureListSlot(callFrame->globalData(), codeBlock->ownerExecutable(), stubInfo, listIndex);
1834         if (listIndex < POLYMORPHIC_LIST_CACHE_SIZE) {
1835             JIT::compileGetByIdProtoList(callFrame->scopeChain()->globalData, callFrame, codeBlock, stubInfo, prototypeStructureList, listIndex, structure, slotBaseObject->structure(), propertyName, slot, offset);
1836
1837             if (listIndex == (POLYMORPHIC_LIST_CACHE_SIZE - 1))
1838                 ctiPatchCallByReturnAddress(codeBlock, STUB_RETURN_ADDRESS, FunctionPtr(cti_op_get_by_id_proto_list_full));
1839         }
1840     } else if (size_t count = normalizePrototypeChain(callFrame, baseValue, slot.slotBase(), propertyName, offset)) {
1841         ASSERT(!baseValue.asCell()->structure()->isDictionary());
1842         int listIndex;
1843         PolymorphicAccessStructureList* prototypeStructureList = getPolymorphicAccessStructureListSlot(callFrame->globalData(), codeBlock->ownerExecutable(), stubInfo, listIndex);
1844         
1845         if (listIndex < POLYMORPHIC_LIST_CACHE_SIZE) {
1846             StructureChain* protoChain = structure->prototypeChain(callFrame);
1847             JIT::compileGetByIdChainList(callFrame->scopeChain()->globalData, callFrame, codeBlock, stubInfo, prototypeStructureList, listIndex, structure, protoChain, count, propertyName, slot, offset);
1848
1849             if (listIndex == (POLYMORPHIC_LIST_CACHE_SIZE - 1))
1850                 ctiPatchCallByReturnAddress(codeBlock, STUB_RETURN_ADDRESS, FunctionPtr(cti_op_get_by_id_proto_list_full));
1851         }
1852     } else
1853         ctiPatchCallByReturnAddress(codeBlock, STUB_RETURN_ADDRESS, FunctionPtr(cti_op_get_by_id_proto_fail));
1854
1855     return JSValue::encode(result);
1856 }
1857
1858 DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_id_proto_list_full)
1859 {
1860     STUB_INIT_STACK_FRAME(stackFrame);
1861
1862     JSValue baseValue = stackFrame.args[0].jsValue();
1863     PropertySlot slot(baseValue);
1864     JSValue result = baseValue.get(stackFrame.callFrame, stackFrame.args[1].identifier(), slot);
1865
1866     CHECK_FOR_EXCEPTION_AT_END();
1867     return JSValue::encode(result);
1868 }
1869
1870 DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_id_proto_fail)
1871 {
1872     STUB_INIT_STACK_FRAME(stackFrame);
1873
1874     JSValue baseValue = stackFrame.args[0].jsValue();
1875     PropertySlot slot(baseValue);
1876     JSValue result = baseValue.get(stackFrame.callFrame, stackFrame.args[1].identifier(), slot);
1877
1878     CHECK_FOR_EXCEPTION_AT_END();
1879     return JSValue::encode(result);
1880 }
1881
1882 DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_id_array_fail)
1883 {
1884     STUB_INIT_STACK_FRAME(stackFrame);
1885
1886     JSValue baseValue = stackFrame.args[0].jsValue();
1887     PropertySlot slot(baseValue);
1888     JSValue result = baseValue.get(stackFrame.callFrame, stackFrame.args[1].identifier(), slot);
1889
1890     CHECK_FOR_EXCEPTION_AT_END();
1891     return JSValue::encode(result);
1892 }
1893
1894 DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_id_string_fail)
1895 {
1896     STUB_INIT_STACK_FRAME(stackFrame);
1897
1898     JSValue baseValue = stackFrame.args[0].jsValue();
1899     PropertySlot slot(baseValue);
1900     JSValue result = baseValue.get(stackFrame.callFrame, stackFrame.args[1].identifier(), slot);
1901
1902     CHECK_FOR_EXCEPTION_AT_END();
1903     return JSValue::encode(result);
1904 }
1905
1906 DEFINE_STUB_FUNCTION(void, op_check_has_instance)
1907 {
1908     STUB_INIT_STACK_FRAME(stackFrame);
1909
1910     CallFrame* callFrame = stackFrame.callFrame;
1911     JSValue baseVal = stackFrame.args[0].jsValue();
1912
1913     // ECMA-262 15.3.5.3:
1914     // Throw an exception either if baseVal is not an object, or if it does not implement 'HasInstance' (i.e. is a function).
1915 #ifndef NDEBUG
1916     TypeInfo typeInfo(UnspecifiedType);
1917     ASSERT(!baseVal.isObject() || !(typeInfo = asObject(baseVal)->structure()->typeInfo()).implementsHasInstance());
1918 #endif
1919     stackFrame.globalData->exception = createInvalidParamError(callFrame, "instanceof", baseVal);
1920     VM_THROW_EXCEPTION_AT_END();
1921 }
1922
1923 #if ENABLE(DFG_JIT)
1924 DEFINE_STUB_FUNCTION(void, optimize_from_loop)
1925 {
1926     STUB_INIT_STACK_FRAME(stackFrame);
1927     
1928     CallFrame* callFrame = stackFrame.callFrame;
1929     CodeBlock* codeBlock = callFrame->codeBlock();
1930
1931     unsigned bytecodeIndex = stackFrame.args[0].int32();
1932     
1933 #if ENABLE(JIT_VERBOSE_OSR)
1934     dataLog("%p: Entered optimize_from_loop with executeCounter = %d, reoptimizationRetryCounter = %u, optimizationDelayCounter = %u\n", codeBlock, codeBlock->jitExecuteCounter(), codeBlock->reoptimizationRetryCounter(), codeBlock->optimizationDelayCounter());
1935 #endif
1936
1937     if (!codeBlock->checkIfOptimizationThresholdReached())
1938         return;
1939
1940     if (codeBlock->hasOptimizedReplacement()) {
1941 #if ENABLE(JIT_VERBOSE_OSR)
1942         dataLog("Considering loop OSR into %p(%p) with success/fail %u/%u.\n", codeBlock, codeBlock->replacement(), codeBlock->replacement()->speculativeSuccessCounter(), codeBlock->replacement()->speculativeFailCounter());
1943 #endif
1944         if (codeBlock->replacement()->shouldReoptimizeFromLoopNow()) {
1945 #if ENABLE(JIT_VERBOSE_OSR)
1946             dataLog("Triggering reoptimization of %p(%p) (in loop).\n", codeBlock, codeBlock->replacement());
1947 #endif
1948             codeBlock->reoptimize();
1949             return;
1950         }
1951     } else {
1952         if (!codeBlock->shouldOptimizeNow()) {
1953 #if ENABLE(JIT_VERBOSE_OSR)
1954             dataLog("Delaying optimization for %p (in loop) because of insufficient profiling.\n", codeBlock);
1955 #endif
1956             return;
1957         }
1958         
1959         ScopeChainNode* scopeChain = callFrame->scopeChain();
1960         
1961         JSObject* error = codeBlock->compileOptimized(callFrame, scopeChain);
1962 #if ENABLE(JIT_VERBOSE_OSR)
1963         if (error)
1964             dataLog("WARNING: optimized compilation from loop failed.\n");
1965 #else
1966         UNUSED_PARAM(error);
1967 #endif
1968         
1969         if (codeBlock->replacement() == codeBlock) {
1970 #if ENABLE(JIT_VERBOSE_OSR)
1971             dataLog("Optimizing %p from loop failed.\n", codeBlock);
1972 #endif
1973             
1974             ASSERT(codeBlock->getJITType() == JITCode::BaselineJIT);
1975             codeBlock->dontOptimizeAnytimeSoon();
1976             return;
1977         }
1978     }
1979     
1980     CodeBlock* optimizedCodeBlock = codeBlock->replacement();
1981     ASSERT(optimizedCodeBlock->getJITType() == JITCode::DFGJIT);
1982     
1983     if (void* address = DFG::prepareOSREntry(callFrame, optimizedCodeBlock, bytecodeIndex)) {
1984 #if ENABLE(JIT_VERBOSE_OSR)
1985         dataLog("Optimizing %p from loop succeeded, performing OSR after a delay of %u.\n", codeBlock, codeBlock->optimizationDelayCounter());
1986 #endif
1987
1988         codeBlock->optimizeSoon();
1989         optimizedCodeBlock->countSpeculationSuccess();
1990         STUB_SET_RETURN_ADDRESS(address);
1991         return;
1992     }
1993     
1994 #if ENABLE(JIT_VERBOSE_OSR)
1995     dataLog("Optimizing %p from loop succeeded, OSR failed, after a delay of %u.\n", codeBlock, codeBlock->optimizationDelayCounter());
1996 #endif
1997
1998     // Count the OSR failure as a speculation failure. If this happens a lot, then
1999     // reoptimize.
2000     optimizedCodeBlock->countSpeculationFailure();
2001     
2002 #if ENABLE(JIT_VERBOSE_OSR)
2003     dataLog("Encountered loop OSR failure into %p(%p) with success/fail %u/%u.\n", codeBlock, codeBlock->replacement(), codeBlock->replacement()->speculativeSuccessCounter(), codeBlock->replacement()->speculativeFailCounter());
2004 #endif
2005
2006     // We are a lot more conservative about triggering reoptimization after OSR failure than
2007     // before it. If we enter the optimize_from_loop trigger with a bucket full of fail
2008     // already, then we really would like to reoptimize immediately. But this case covers
2009     // something else: there weren't many (or any) speculation failures before, but we just
2010     // failed to enter the speculative code because some variable had the wrong value or
2011     // because the OSR code decided for any spurious reason that it did not want to OSR
2012     // right now. So, we only trigger reoptimization only upon the more conservative (non-loop)
2013     // reoptimization trigger.
2014     if (optimizedCodeBlock->shouldReoptimizeNow()) {
2015 #if ENABLE(JIT_VERBOSE_OSR)
2016         dataLog("Triggering reoptimization of %p(%p) (in loop after OSR fail).\n", codeBlock, codeBlock->replacement());
2017 #endif
2018         codeBlock->reoptimize();
2019         return;
2020     }
2021
2022     // OSR failed this time, but it might succeed next time! Let the code run a bit
2023     // longer and then try again.
2024     codeBlock->optimizeAfterWarmUp();
2025 }
2026
2027 DEFINE_STUB_FUNCTION(void, optimize_from_ret)
2028 {
2029     STUB_INIT_STACK_FRAME(stackFrame);
2030     
2031     CallFrame* callFrame = stackFrame.callFrame;
2032     CodeBlock* codeBlock = callFrame->codeBlock();
2033     
2034 #if ENABLE(JIT_VERBOSE_OSR)
2035     dataLog("Entered optimize_from_ret with executeCounter = %d, reoptimizationRetryCounter = %u, optimizationDelayCounter = %u\n", codeBlock->jitExecuteCounter(), codeBlock->reoptimizationRetryCounter(), codeBlock->optimizationDelayCounter());
2036 #endif
2037
2038     if (!codeBlock->checkIfOptimizationThresholdReached())
2039         return;
2040
2041     if (codeBlock->hasOptimizedReplacement()) {
2042 #if ENABLE(JIT_VERBOSE_OSR)
2043         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());
2044         CallFrame* callerFrame = callFrame->callerFrame();
2045         if (callerFrame)
2046             dataLog(", callerFrame = %p, returnPC = %p, caller code block = %p", callerFrame, callFrame->returnPC().value(), callerFrame->codeBlock());
2047         dataLog("\n");
2048 #endif
2049         if (codeBlock->replacement()->shouldReoptimizeNow()) {
2050 #if ENABLE(JIT_VERBOSE_OSR)
2051             dataLog("Triggering reoptimization of %p(%p) (in return).\n", codeBlock, codeBlock->replacement());
2052 #endif
2053             codeBlock->reoptimize();
2054         }
2055         
2056         codeBlock->optimizeSoon();
2057         return;
2058     }
2059     
2060     if (!codeBlock->shouldOptimizeNow()) {
2061 #if ENABLE(JIT_VERBOSE_OSR)
2062         dataLog("Delaying optimization for %p (in return) because of insufficient profiling.\n", codeBlock);
2063 #endif
2064         return;
2065     }
2066     
2067     ScopeChainNode* scopeChain = callFrame->scopeChain();
2068
2069     JSObject* error = codeBlock->compileOptimized(callFrame, scopeChain);
2070     if (error)
2071         dataLog("WARNING: optimized compilation from ret failed.\n");
2072     
2073     if (codeBlock->replacement() == codeBlock) {
2074 #if ENABLE(JIT_VERBOSE_OSR)
2075         dataLog("Optimizing %p from return failed.\n", codeBlock);
2076 #endif
2077
2078         ASSERT(codeBlock->getJITType() == JITCode::BaselineJIT);
2079         codeBlock->dontOptimizeAnytimeSoon();
2080         return;
2081     }
2082     
2083     ASSERT(codeBlock->replacement()->getJITType() == JITCode::DFGJIT);
2084
2085 #if ENABLE(JIT_VERBOSE_OSR)
2086     dataLog("Optimizing %p from return succeeded after a delay of %u.\n", codeBlock, codeBlock->optimizationDelayCounter());
2087 #endif
2088     
2089     codeBlock->optimizeSoon();
2090 }
2091 #endif // ENABLE(DFG_JIT)
2092
2093 DEFINE_STUB_FUNCTION(EncodedJSValue, op_instanceof)
2094 {
2095     STUB_INIT_STACK_FRAME(stackFrame);
2096
2097     CallFrame* callFrame = stackFrame.callFrame;
2098     JSValue value = stackFrame.args[0].jsValue();
2099     JSValue baseVal = stackFrame.args[1].jsValue();
2100     JSValue proto = stackFrame.args[2].jsValue();
2101     
2102     bool result = CommonSlowPaths::opInstanceOfSlow(callFrame, value, baseVal, proto);
2103     CHECK_FOR_EXCEPTION_AT_END();
2104     return JSValue::encode(jsBoolean(result));
2105 }
2106
2107 DEFINE_STUB_FUNCTION(EncodedJSValue, op_del_by_id)
2108 {
2109     STUB_INIT_STACK_FRAME(stackFrame);
2110
2111     CallFrame* callFrame = stackFrame.callFrame;
2112     
2113     JSObject* baseObj = stackFrame.args[0].jsValue().toObject(callFrame);
2114
2115     bool couldDelete = baseObj->methodTable()->deleteProperty(baseObj, callFrame, stackFrame.args[1].identifier());
2116     JSValue result = jsBoolean(couldDelete);
2117     if (!couldDelete && callFrame->codeBlock()->isStrictMode())
2118         stackFrame.globalData->exception = createTypeError(stackFrame.callFrame, "Unable to delete property.");
2119
2120     CHECK_FOR_EXCEPTION_AT_END();
2121     return JSValue::encode(result);
2122 }
2123
2124 DEFINE_STUB_FUNCTION(EncodedJSValue, op_mul)
2125 {
2126     STUB_INIT_STACK_FRAME(stackFrame);
2127
2128     JSValue src1 = stackFrame.args[0].jsValue();
2129     JSValue src2 = stackFrame.args[1].jsValue();
2130
2131     if (src1.isNumber() && src2.isNumber())
2132         return JSValue::encode(jsNumber(src1.asNumber() * src2.asNumber()));
2133
2134     CallFrame* callFrame = stackFrame.callFrame;
2135     JSValue result = jsNumber(src1.toNumber(callFrame) * src2.toNumber(callFrame));
2136     CHECK_FOR_EXCEPTION_AT_END();
2137     return JSValue::encode(result);
2138 }
2139
2140 DEFINE_STUB_FUNCTION(JSObject*, op_new_func)
2141 {
2142     STUB_INIT_STACK_FRAME(stackFrame);
2143     
2144     ASSERT(stackFrame.callFrame->codeBlock()->codeType() != FunctionCode || !stackFrame.callFrame->codeBlock()->needsFullScopeChain() || stackFrame.callFrame->uncheckedR(stackFrame.callFrame->codeBlock()->activationRegister()).jsValue());
2145     return stackFrame.args[0].function()->make(stackFrame.callFrame, stackFrame.callFrame->scopeChain());
2146 }
2147
2148 inline void* jitCompileFor(CallFrame* callFrame, CodeSpecializationKind kind)
2149 {
2150     JSFunction* function = jsCast<JSFunction*>(callFrame->callee());
2151     ASSERT(!function->isHostFunction());
2152     FunctionExecutable* executable = function->jsExecutable();
2153     ScopeChainNode* callDataScopeChain = function->scope();
2154     JSObject* error = executable->compileFor(callFrame, callDataScopeChain, kind);
2155     if (!error)
2156         return function;
2157     callFrame->globalData().exception = error;
2158     return 0;
2159 }
2160
2161 DEFINE_STUB_FUNCTION(void*, op_call_jitCompile)
2162 {
2163     STUB_INIT_STACK_FRAME(stackFrame);
2164
2165 #if !ASSERT_DISABLED
2166     CallData callData;
2167     ASSERT(stackFrame.callFrame->callee()->methodTable()->getCallData(stackFrame.callFrame->callee(), callData) == CallTypeJS);
2168 #endif
2169     
2170     CallFrame* callFrame = stackFrame.callFrame;
2171     void* result = jitCompileFor(callFrame, CodeForCall);
2172     if (!result)
2173         return throwExceptionFromOpCall<void*>(stackFrame, callFrame, STUB_RETURN_ADDRESS);
2174
2175     return result;
2176 }
2177
2178 DEFINE_STUB_FUNCTION(void*, op_construct_jitCompile)
2179 {
2180     STUB_INIT_STACK_FRAME(stackFrame);
2181
2182 #if !ASSERT_DISABLED
2183     ConstructData constructData;
2184     ASSERT(jsCast<JSFunction*>(stackFrame.callFrame->callee())->methodTable()->getConstructData(stackFrame.callFrame->callee(), constructData) == ConstructTypeJS);
2185 #endif
2186
2187     CallFrame* callFrame = stackFrame.callFrame;    
2188     void* result = jitCompileFor(callFrame, CodeForConstruct);
2189     if (!result)
2190         return throwExceptionFromOpCall<void*>(stackFrame, callFrame, STUB_RETURN_ADDRESS);
2191
2192     return result;
2193 }
2194
2195 DEFINE_STUB_FUNCTION(void*, op_call_arityCheck)
2196 {
2197     STUB_INIT_STACK_FRAME(stackFrame);
2198
2199     CallFrame* callFrame = stackFrame.callFrame;
2200
2201     CallFrame* newCallFrame = CommonSlowPaths::arityCheckFor(callFrame, stackFrame.registerFile, CodeForCall);
2202     if (!newCallFrame)
2203         return throwExceptionFromOpCall<void*>(stackFrame, callFrame, STUB_RETURN_ADDRESS, createStackOverflowError(callFrame->callerFrame()));
2204
2205     return newCallFrame;
2206 }
2207
2208 DEFINE_STUB_FUNCTION(void*, op_construct_arityCheck)
2209 {
2210     STUB_INIT_STACK_FRAME(stackFrame);
2211
2212     CallFrame* callFrame = stackFrame.callFrame;
2213
2214     CallFrame* newCallFrame = CommonSlowPaths::arityCheckFor(callFrame, stackFrame.registerFile, CodeForConstruct);
2215     if (!newCallFrame)
2216         return throwExceptionFromOpCall<void*>(stackFrame, callFrame, STUB_RETURN_ADDRESS, createStackOverflowError(callFrame->callerFrame()));
2217
2218     return newCallFrame;
2219 }
2220
2221 inline void* lazyLinkFor(CallFrame* callFrame, CodeSpecializationKind kind)
2222 {
2223     JSFunction* callee = jsCast<JSFunction*>(callFrame->callee());
2224     ExecutableBase* executable = callee->executable();
2225
2226     MacroAssemblerCodePtr codePtr;
2227     CodeBlock* codeBlock = 0;
2228     CallLinkInfo* callLinkInfo = &callFrame->callerFrame()->codeBlock()->getCallLinkInfo(callFrame->returnPC());
2229
2230     if (executable->isHostFunction())
2231         codePtr = executable->generatedJITCodeFor(kind).addressForCall();
2232     else {
2233         FunctionExecutable* functionExecutable = static_cast<FunctionExecutable*>(executable);
2234         if (JSObject* error = functionExecutable->compileFor(callFrame, callee->scope(), kind)) {
2235             callFrame->globalData().exception = error;
2236             return 0;
2237         }
2238         codeBlock = &functionExecutable->generatedBytecodeFor(kind);
2239         if (callFrame->argumentCountIncludingThis() < static_cast<size_t>(codeBlock->numParameters())
2240             || callLinkInfo->callType == CallLinkInfo::CallVarargs)
2241             codePtr = functionExecutable->generatedJITCodeWithArityCheckFor(kind);
2242         else
2243             codePtr = functionExecutable->generatedJITCodeFor(kind).addressForCall();
2244     }
2245
2246     if (!callLinkInfo->seenOnce())
2247         callLinkInfo->setSeen();
2248     else
2249         JIT::linkFor(callee, callFrame->callerFrame()->codeBlock(), codeBlock, codePtr, callLinkInfo, &callFrame->globalData(), kind);
2250
2251     return codePtr.executableAddress();
2252 }
2253
2254 DEFINE_STUB_FUNCTION(void*, vm_lazyLinkCall)
2255 {
2256     STUB_INIT_STACK_FRAME(stackFrame);
2257
2258     CallFrame* callFrame = stackFrame.callFrame;
2259     void* result = lazyLinkFor(callFrame, CodeForCall);
2260     if (!result)
2261         return throwExceptionFromOpCall<void*>(stackFrame, callFrame, STUB_RETURN_ADDRESS);
2262
2263     return result;
2264 }
2265
2266 DEFINE_STUB_FUNCTION(void*, vm_lazyLinkConstruct)
2267 {
2268     STUB_INIT_STACK_FRAME(stackFrame);
2269
2270     CallFrame* callFrame = stackFrame.callFrame;
2271     void* result = lazyLinkFor(callFrame, CodeForConstruct);
2272     if (!result)
2273         return throwExceptionFromOpCall<void*>(stackFrame, callFrame, STUB_RETURN_ADDRESS);
2274
2275     return result;
2276 }
2277
2278 DEFINE_STUB_FUNCTION(JSObject*, op_push_activation)
2279 {
2280     STUB_INIT_STACK_FRAME(stackFrame);
2281
2282     JSActivation* activation = JSActivation::create(stackFrame.callFrame->globalData(), stackFrame.callFrame, static_cast<FunctionExecutable*>(stackFrame.callFrame->codeBlock()->ownerExecutable()));
2283     stackFrame.callFrame->setScopeChain(stackFrame.callFrame->scopeChain()->push(activation));
2284     return activation;
2285 }
2286
2287 DEFINE_STUB_FUNCTION(EncodedJSValue, op_call_NotJSFunction)
2288 {
2289     STUB_INIT_STACK_FRAME(stackFrame);
2290
2291     CallFrame* callFrame = stackFrame.callFrame;
2292     
2293     JSValue callee = callFrame->calleeAsValue();
2294
2295     CallData callData;
2296     CallType callType = getCallData(callee, callData);
2297
2298     ASSERT(callType != CallTypeJS);
2299     if (callType != CallTypeHost) {
2300         ASSERT(callType == CallTypeNone);
2301         return throwExceptionFromOpCall<EncodedJSValue>(stackFrame, callFrame, STUB_RETURN_ADDRESS, createNotAFunctionError(callFrame->callerFrame(), callee));
2302     }
2303
2304     EncodedJSValue returnValue;
2305     {
2306         SamplingTool::HostCallRecord callRecord(CTI_SAMPLER);
2307         returnValue = callData.native.function(callFrame);
2308     }
2309
2310     if (stackFrame.globalData->exception)
2311         return throwExceptionFromOpCall<EncodedJSValue>(stackFrame, callFrame, STUB_RETURN_ADDRESS);
2312
2313     return returnValue;
2314 }
2315
2316 DEFINE_STUB_FUNCTION(EncodedJSValue, op_create_arguments)
2317 {
2318     STUB_INIT_STACK_FRAME(stackFrame);
2319
2320     Arguments* arguments = Arguments::create(*stackFrame.globalData, stackFrame.callFrame);
2321     return JSValue::encode(JSValue(arguments));
2322 }
2323
2324 DEFINE_STUB_FUNCTION(void, op_tear_off_activation)
2325 {
2326     STUB_INIT_STACK_FRAME(stackFrame);
2327
2328     CallFrame* callFrame = stackFrame.callFrame;
2329     ASSERT(callFrame->codeBlock()->needsFullScopeChain());
2330     JSValue activationValue = stackFrame.args[0].jsValue();
2331     if (!activationValue) {
2332         if (JSValue v = stackFrame.args[1].jsValue()) {
2333             if (!callFrame->codeBlock()->isStrictMode())
2334                 asArguments(v)->tearOff(callFrame);
2335         }
2336         return;
2337     }
2338     JSActivation* activation = asActivation(stackFrame.args[0].jsValue());
2339     activation->tearOff(*stackFrame.globalData);
2340     if (JSValue v = stackFrame.args[1].jsValue())
2341         asArguments(v)->didTearOffActivation(*stackFrame.globalData, activation);
2342 }
2343
2344 DEFINE_STUB_FUNCTION(void, op_tear_off_arguments)
2345 {
2346     STUB_INIT_STACK_FRAME(stackFrame);
2347
2348     CallFrame* callFrame = stackFrame.callFrame;
2349     ASSERT(callFrame->codeBlock()->usesArguments() && !callFrame->codeBlock()->needsFullScopeChain());
2350     asArguments(stackFrame.args[0].jsValue())->tearOff(callFrame);
2351 }
2352
2353 DEFINE_STUB_FUNCTION(void, op_profile_will_call)
2354 {
2355     STUB_INIT_STACK_FRAME(stackFrame);
2356
2357     ASSERT(*stackFrame.enabledProfilerReference);
2358     (*stackFrame.enabledProfilerReference)->willExecute(stackFrame.callFrame, stackFrame.args[0].jsValue());
2359 }
2360
2361 DEFINE_STUB_FUNCTION(void, op_profile_did_call)
2362 {
2363     STUB_INIT_STACK_FRAME(stackFrame);
2364
2365     ASSERT(*stackFrame.enabledProfilerReference);
2366     (*stackFrame.enabledProfilerReference)->didExecute(stackFrame.callFrame, stackFrame.args[0].jsValue());
2367 }
2368
2369 DEFINE_STUB_FUNCTION(JSObject*, op_new_array)
2370 {
2371     STUB_INIT_STACK_FRAME(stackFrame);
2372
2373     return constructArray(stackFrame.callFrame, reinterpret_cast<JSValue*>(&stackFrame.callFrame->registers()[stackFrame.args[0].int32()]), stackFrame.args[1].int32());
2374 }
2375
2376 DEFINE_STUB_FUNCTION(JSObject*, op_new_array_buffer)
2377 {
2378     STUB_INIT_STACK_FRAME(stackFrame);
2379     
2380     return constructArray(stackFrame.callFrame, stackFrame.callFrame->codeBlock()->constantBuffer(stackFrame.args[0].int32()), stackFrame.args[1].int32());
2381 }
2382
2383 DEFINE_STUB_FUNCTION(EncodedJSValue, op_resolve)
2384 {
2385     STUB_INIT_STACK_FRAME(stackFrame);
2386
2387     CallFrame* callFrame = stackFrame.callFrame;
2388
2389     JSValue result = CommonSlowPaths::opResolve(callFrame, stackFrame.args[0].identifier());
2390     CHECK_FOR_EXCEPTION_AT_END();
2391     return JSValue::encode(result);
2392 }
2393
2394 DEFINE_STUB_FUNCTION(EncodedJSValue, op_construct_NotJSConstruct)
2395 {
2396     STUB_INIT_STACK_FRAME(stackFrame);
2397
2398     CallFrame* callFrame = stackFrame.callFrame;
2399     JSValue callee = callFrame->calleeAsValue();
2400
2401     ConstructData constructData;
2402     ConstructType constructType = getConstructData(callee, constructData);
2403
2404     ASSERT(constructType != ConstructTypeJS);
2405     if (constructType != ConstructTypeHost) {
2406         ASSERT(constructType == ConstructTypeNone);
2407         return throwExceptionFromOpCall<EncodedJSValue>(stackFrame, callFrame, STUB_RETURN_ADDRESS, createNotAConstructorError(callFrame->callerFrame(), callee));
2408     }
2409
2410     EncodedJSValue returnValue;
2411     {
2412         SamplingTool::HostCallRecord callRecord(CTI_SAMPLER);
2413         returnValue = constructData.native.function(callFrame);
2414     }
2415
2416     if (stackFrame.globalData->exception)
2417         return throwExceptionFromOpCall<EncodedJSValue>(stackFrame, callFrame, STUB_RETURN_ADDRESS);
2418
2419     return returnValue;
2420 }
2421
2422 DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_val)
2423 {
2424     STUB_INIT_STACK_FRAME(stackFrame);
2425
2426     CallFrame* callFrame = stackFrame.callFrame;
2427
2428     JSValue baseValue = stackFrame.args[0].jsValue();
2429     JSValue subscript = stackFrame.args[1].jsValue();
2430
2431     if (LIKELY(baseValue.isCell() && subscript.isString())) {
2432         if (JSValue result = baseValue.asCell()->fastGetOwnProperty(callFrame, asString(subscript)->value(callFrame))) {
2433             CHECK_FOR_EXCEPTION();
2434             return JSValue::encode(result);
2435         }
2436     }
2437
2438     if (subscript.isUInt32()) {
2439         uint32_t i = subscript.asUInt32();
2440         if (isJSString(baseValue) && asString(baseValue)->canGetIndex(i)) {
2441             ctiPatchCallByReturnAddress(callFrame->codeBlock(), STUB_RETURN_ADDRESS, FunctionPtr(cti_op_get_by_val_string));
2442             JSValue result = asString(baseValue)->getIndex(callFrame, i);
2443             CHECK_FOR_EXCEPTION();
2444             return JSValue::encode(result);
2445         }
2446         JSValue result = baseValue.get(callFrame, i);
2447         CHECK_FOR_EXCEPTION();
2448         return JSValue::encode(result);
2449     }
2450     
2451     Identifier property(callFrame, subscript.toString(callFrame)->value(callFrame));
2452     JSValue result = baseValue.get(callFrame, property);
2453     CHECK_FOR_EXCEPTION_AT_END();
2454     return JSValue::encode(result);
2455 }
2456     
2457 DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_val_string)
2458 {
2459     STUB_INIT_STACK_FRAME(stackFrame);
2460     
2461     CallFrame* callFrame = stackFrame.callFrame;
2462     
2463     JSValue baseValue = stackFrame.args[0].jsValue();
2464     JSValue subscript = stackFrame.args[1].jsValue();
2465     
2466     JSValue result;
2467     
2468     if (LIKELY(subscript.isUInt32())) {
2469         uint32_t i = subscript.asUInt32();
2470         if (isJSString(baseValue) && asString(baseValue)->canGetIndex(i))
2471             result = asString(baseValue)->getIndex(callFrame, i);
2472         else {
2473             result = baseValue.get(callFrame, i);
2474             if (!isJSString(baseValue))
2475                 ctiPatchCallByReturnAddress(callFrame->codeBlock(), STUB_RETURN_ADDRESS, FunctionPtr(cti_op_get_by_val));
2476         }
2477     } else {
2478         Identifier property(callFrame, subscript.toString(callFrame)->value(callFrame));
2479         result = baseValue.get(callFrame, property);
2480     }
2481     
2482     CHECK_FOR_EXCEPTION_AT_END();
2483     return JSValue::encode(result);
2484 }
2485     
2486 DEFINE_STUB_FUNCTION(EncodedJSValue, op_sub)
2487 {
2488     STUB_INIT_STACK_FRAME(stackFrame);
2489
2490     JSValue src1 = stackFrame.args[0].jsValue();
2491     JSValue src2 = stackFrame.args[1].jsValue();
2492
2493     if (src1.isNumber() && src2.isNumber())
2494         return JSValue::encode(jsNumber(src1.asNumber() - src2.asNumber()));
2495
2496     CallFrame* callFrame = stackFrame.callFrame;
2497     JSValue result = jsNumber(src1.toNumber(callFrame) - src2.toNumber(callFrame));
2498     CHECK_FOR_EXCEPTION_AT_END();
2499     return JSValue::encode(result);
2500 }
2501
2502 DEFINE_STUB_FUNCTION(void, op_put_by_val)
2503 {
2504     STUB_INIT_STACK_FRAME(stackFrame);
2505
2506     CallFrame* callFrame = stackFrame.callFrame;
2507     JSGlobalData* globalData = stackFrame.globalData;
2508
2509     JSValue baseValue = stackFrame.args[0].jsValue();
2510     JSValue subscript = stackFrame.args[1].jsValue();
2511     JSValue value = stackFrame.args[2].jsValue();
2512
2513     if (LIKELY(subscript.isUInt32())) {
2514         uint32_t i = subscript.asUInt32();
2515         if (isJSArray(baseValue)) {
2516             JSArray* jsArray = asArray(baseValue);
2517             if (jsArray->canSetIndex(i))
2518                 jsArray->setIndex(*globalData, i, value);
2519             else
2520                 JSArray::putByIndex(jsArray, callFrame, i, value, callFrame->codeBlock()->isStrictMode());
2521         } else
2522             baseValue.putByIndex(callFrame, i, value, callFrame->codeBlock()->isStrictMode());
2523     } else {
2524         Identifier property(callFrame, subscript.toString(callFrame)->value(callFrame));
2525         if (!stackFrame.globalData->exception) { // Don't put to an object if toString threw an exception.
2526             PutPropertySlot slot(callFrame->codeBlock()->isStrictMode());
2527             baseValue.put(callFrame, property, value, slot);
2528         }
2529     }
2530
2531     CHECK_FOR_EXCEPTION_AT_END();
2532 }
2533
2534 DEFINE_STUB_FUNCTION(EncodedJSValue, op_less)
2535 {
2536     STUB_INIT_STACK_FRAME(stackFrame);
2537
2538     CallFrame* callFrame = stackFrame.callFrame;
2539     JSValue result = jsBoolean(jsLess<true>(callFrame, stackFrame.args[0].jsValue(), stackFrame.args[1].jsValue()));
2540     CHECK_FOR_EXCEPTION_AT_END();
2541     return JSValue::encode(result);
2542 }
2543
2544 DEFINE_STUB_FUNCTION(EncodedJSValue, op_lesseq)
2545 {
2546     STUB_INIT_STACK_FRAME(stackFrame);
2547
2548     CallFrame* callFrame = stackFrame.callFrame;
2549     JSValue result = jsBoolean(jsLessEq<true>(callFrame, stackFrame.args[0].jsValue(), stackFrame.args[1].jsValue()));
2550     CHECK_FOR_EXCEPTION_AT_END();
2551     return JSValue::encode(result);
2552 }
2553
2554 DEFINE_STUB_FUNCTION(EncodedJSValue, op_greater)
2555 {
2556     STUB_INIT_STACK_FRAME(stackFrame);
2557
2558     CallFrame* callFrame = stackFrame.callFrame;
2559     JSValue result = jsBoolean(jsLess<false>(callFrame, stackFrame.args[1].jsValue(), stackFrame.args[0].jsValue()));
2560     CHECK_FOR_EXCEPTION_AT_END();
2561     return JSValue::encode(result);
2562 }
2563
2564 DEFINE_STUB_FUNCTION(EncodedJSValue, op_greatereq)
2565 {
2566     STUB_INIT_STACK_FRAME(stackFrame);
2567
2568     CallFrame* callFrame = stackFrame.callFrame;
2569     JSValue result = jsBoolean(jsLessEq<false>(callFrame, stackFrame.args[1].jsValue(), stackFrame.args[0].jsValue()));
2570     CHECK_FOR_EXCEPTION_AT_END();
2571     return JSValue::encode(result);
2572 }
2573
2574 DEFINE_STUB_FUNCTION(void*, op_load_varargs)
2575 {
2576     STUB_INIT_STACK_FRAME(stackFrame);
2577
2578     CallFrame* callFrame = stackFrame.callFrame;
2579     RegisterFile* registerFile = stackFrame.registerFile;
2580     JSValue thisValue = stackFrame.args[0].jsValue();
2581     JSValue arguments = stackFrame.args[1].jsValue();
2582     int firstFreeRegister = stackFrame.args[2].int32();
2583
2584     CallFrame* newCallFrame = loadVarargs(callFrame, registerFile, thisValue, arguments, firstFreeRegister);
2585     if (!newCallFrame)
2586         VM_THROW_EXCEPTION();
2587     return newCallFrame;
2588 }
2589
2590 DEFINE_STUB_FUNCTION(EncodedJSValue, op_negate)
2591 {
2592     STUB_INIT_STACK_FRAME(stackFrame);
2593
2594     JSValue src = stackFrame.args[0].jsValue();
2595
2596     if (src.isNumber())
2597         return JSValue::encode(jsNumber(-src.asNumber()));
2598
2599     CallFrame* callFrame = stackFrame.callFrame;
2600     JSValue result = jsNumber(-src.toNumber(callFrame));
2601     CHECK_FOR_EXCEPTION_AT_END();
2602     return JSValue::encode(result);
2603 }
2604
2605 DEFINE_STUB_FUNCTION(EncodedJSValue, op_resolve_base)
2606 {
2607     STUB_INIT_STACK_FRAME(stackFrame);
2608
2609     return JSValue::encode(JSC::resolveBase(stackFrame.callFrame, stackFrame.args[0].identifier(), stackFrame.callFrame->scopeChain(), false));
2610 }
2611
2612 DEFINE_STUB_FUNCTION(EncodedJSValue, op_resolve_base_strict_put)
2613 {
2614     STUB_INIT_STACK_FRAME(stackFrame);
2615     JSValue base = JSC::resolveBase(stackFrame.callFrame, stackFrame.args[0].identifier(), stackFrame.callFrame->scopeChain(), true);
2616     if (!base) {
2617         stackFrame.globalData->exception = createErrorForInvalidGlobalAssignment(stackFrame.callFrame, stackFrame.args[0].identifier().ustring());
2618         VM_THROW_EXCEPTION();
2619     }
2620     return JSValue::encode(base);
2621 }
2622
2623 DEFINE_STUB_FUNCTION(EncodedJSValue, op_ensure_property_exists)
2624 {
2625     STUB_INIT_STACK_FRAME(stackFrame);
2626     JSValue base = stackFrame.callFrame->r(stackFrame.args[0].int32()).jsValue();
2627     JSObject* object = asObject(base);
2628     PropertySlot slot(object);
2629     ASSERT(stackFrame.callFrame->codeBlock()->isStrictMode());
2630     if (!object->getPropertySlot(stackFrame.callFrame, stackFrame.args[1].identifier(), slot)) {
2631         stackFrame.globalData->exception = createErrorForInvalidGlobalAssignment(stackFrame.callFrame, stackFrame.args[1].identifier().ustring());
2632         VM_THROW_EXCEPTION();
2633     }
2634
2635     return JSValue::encode(base);
2636 }
2637     
2638 DEFINE_STUB_FUNCTION(EncodedJSValue, op_resolve_skip)
2639 {
2640     STUB_INIT_STACK_FRAME(stackFrame);
2641
2642     JSValue result = CommonSlowPaths::opResolveSkip(stackFrame.callFrame, stackFrame.args[0].identifier(), stackFrame.args[1].int32());
2643     CHECK_FOR_EXCEPTION_AT_END();
2644     return JSValue::encode(result);
2645 }
2646
2647 DEFINE_STUB_FUNCTION(EncodedJSValue, op_resolve_global)
2648 {
2649     STUB_INIT_STACK_FRAME(stackFrame);
2650
2651     CallFrame* callFrame = stackFrame.callFrame;
2652     CodeBlock* codeBlock = callFrame->codeBlock();
2653     JSGlobalObject* globalObject = codeBlock->globalObject();
2654     Identifier& ident = stackFrame.args[0].identifier();
2655     unsigned globalResolveInfoIndex = stackFrame.args[1].int32();
2656     ASSERT(globalObject->isGlobalObject());
2657
2658     PropertySlot slot(globalObject);
2659     if (globalObject->getPropertySlot(callFrame, ident, slot)) {
2660         JSValue result = slot.getValue(callFrame, ident);
2661         if (slot.isCacheableValue() && !globalObject->structure()->isUncacheableDictionary() && slot.slotBase() == globalObject) {
2662             GlobalResolveInfo& globalResolveInfo = codeBlock->globalResolveInfo(globalResolveInfoIndex);
2663             globalResolveInfo.structure.set(callFrame->globalData(), codeBlock->ownerExecutable(), globalObject->structure());
2664             globalResolveInfo.offset = slot.cachedOffset();
2665             return JSValue::encode(result);
2666         }
2667
2668         CHECK_FOR_EXCEPTION_AT_END();
2669         return JSValue::encode(result);
2670     }
2671
2672     stackFrame.globalData->exception = createUndefinedVariableError(callFrame, ident);
2673     VM_THROW_EXCEPTION();
2674 }
2675
2676 DEFINE_STUB_FUNCTION(EncodedJSValue, op_div)
2677 {
2678     STUB_INIT_STACK_FRAME(stackFrame);
2679
2680     JSValue src1 = stackFrame.args[0].jsValue();
2681     JSValue src2 = stackFrame.args[1].jsValue();
2682
2683     if (src1.isNumber() && src2.isNumber())
2684         return JSValue::encode(jsNumber(src1.asNumber() / src2.asNumber()));
2685
2686     CallFrame* callFrame = stackFrame.callFrame;
2687     JSValue result = jsNumber(src1.toNumber(callFrame) / src2.toNumber(callFrame));
2688     CHECK_FOR_EXCEPTION_AT_END();
2689     return JSValue::encode(result);
2690 }
2691
2692 DEFINE_STUB_FUNCTION(EncodedJSValue, op_pre_dec)
2693 {
2694     STUB_INIT_STACK_FRAME(stackFrame);
2695
2696     JSValue v = stackFrame.args[0].jsValue();
2697
2698     CallFrame* callFrame = stackFrame.callFrame;
2699     JSValue result = jsNumber(v.toNumber(callFrame) - 1);
2700     CHECK_FOR_EXCEPTION_AT_END();
2701     return JSValue::encode(result);
2702 }
2703
2704 DEFINE_STUB_FUNCTION(int, op_jless)
2705 {
2706     STUB_INIT_STACK_FRAME(stackFrame);
2707
2708     JSValue src1 = stackFrame.args[0].jsValue();
2709     JSValue src2 = stackFrame.args[1].jsValue();
2710     CallFrame* callFrame = stackFrame.callFrame;
2711
2712     bool result = jsLess<true>(callFrame, src1, src2);
2713     CHECK_FOR_EXCEPTION_AT_END();
2714     return result;
2715 }
2716
2717 DEFINE_STUB_FUNCTION(int, op_jlesseq)
2718 {
2719     STUB_INIT_STACK_FRAME(stackFrame);
2720
2721     JSValue src1 = stackFrame.args[0].jsValue();
2722     JSValue src2 = stackFrame.args[1].jsValue();
2723     CallFrame* callFrame = stackFrame.callFrame;
2724
2725     bool result = jsLessEq<true>(callFrame, src1, src2);
2726     CHECK_FOR_EXCEPTION_AT_END();
2727     return result;
2728 }
2729
2730 DEFINE_STUB_FUNCTION(int, op_jgreater)
2731 {
2732     STUB_INIT_STACK_FRAME(stackFrame);
2733
2734     JSValue src1 = stackFrame.args[0].jsValue();
2735     JSValue src2 = stackFrame.args[1].jsValue();
2736     CallFrame* callFrame = stackFrame.callFrame;
2737
2738     bool result = jsLess<false>(callFrame, src2, src1);
2739     CHECK_FOR_EXCEPTION_AT_END();
2740     return result;
2741 }
2742
2743 DEFINE_STUB_FUNCTION(int, op_jgreatereq)
2744 {
2745     STUB_INIT_STACK_FRAME(stackFrame);
2746
2747     JSValue src1 = stackFrame.args[0].jsValue();
2748     JSValue src2 = stackFrame.args[1].jsValue();
2749     CallFrame* callFrame = stackFrame.callFrame;
2750
2751     bool result = jsLessEq<false>(callFrame, src2, src1);
2752     CHECK_FOR_EXCEPTION_AT_END();
2753     return result;
2754 }
2755
2756 DEFINE_STUB_FUNCTION(EncodedJSValue, op_not)
2757 {
2758     STUB_INIT_STACK_FRAME(stackFrame);
2759
2760     JSValue src = stackFrame.args[0].jsValue();
2761
2762     JSValue result = jsBoolean(!src.toBoolean());
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     bool result = src1.toBoolean();
2774     CHECK_FOR_EXCEPTION_AT_END();
2775     return result;
2776 }
2777
2778 DEFINE_STUB_FUNCTION(EncodedJSValue, op_post_inc)
2779 {
2780     STUB_INIT_STACK_FRAME(stackFrame);
2781
2782     JSValue v = stackFrame.args[0].jsValue();
2783
2784     CallFrame* callFrame = stackFrame.callFrame;
2785
2786     double number = v.toNumber(callFrame);
2787     CHECK_FOR_EXCEPTION_AT_END();
2788
2789     callFrame->registers()[stackFrame.args[1].int32()] = jsNumber(number + 1);
2790     return JSValue::encode(jsNumber(number));
2791 }
2792
2793 DEFINE_STUB_FUNCTION(int, op_eq)
2794 {
2795     STUB_INIT_STACK_FRAME(stackFrame);
2796
2797     JSValue src1 = stackFrame.args[0].jsValue();
2798     JSValue src2 = stackFrame.args[1].jsValue();
2799
2800 #if USE(JSVALUE32_64)
2801     start:
2802     if (src2.isUndefined()) {
2803         return src1.isNull() || 
2804                (src1.isCell() && src1.asCell()->structure()->typeInfo().masqueradesAsUndefined())
2805                || src1.isUndefined();
2806     }
2807     
2808     if (src2.isNull()) {
2809         return src1.isUndefined() || 
2810                (src1.isCell() && src1.asCell()->structure()->typeInfo().masqueradesAsUndefined())
2811                || src1.isNull();
2812     }
2813
2814     if (src1.isInt32()) {
2815         if (src2.isDouble())
2816             return src1.asInt32() == src2.asDouble();
2817         double d = src2.toNumber(stackFrame.callFrame);
2818         CHECK_FOR_EXCEPTION();
2819         return src1.asInt32() == d;
2820     }
2821
2822     if (src1.isDouble()) {
2823         if (src2.isInt32())
2824             return src1.asDouble() == src2.asInt32();
2825         double d = src2.toNumber(stackFrame.callFrame);
2826         CHECK_FOR_EXCEPTION();
2827         return src1.asDouble() == d;
2828     }
2829
2830     if (src1.isTrue()) {
2831         if (src2.isFalse())
2832             return false;
2833         double d = src2.toNumber(stackFrame.callFrame);
2834         CHECK_FOR_EXCEPTION();
2835         return d == 1.0;
2836     }
2837
2838     if (src1.isFalse()) {
2839         if (src2.isTrue())
2840             return false;
2841         double d = src2.toNumber(stackFrame.callFrame);
2842         CHECK_FOR_EXCEPTION();
2843         return d == 0.0;
2844     }
2845     
2846     if (src1.isUndefined())
2847         return src2.isCell() && src2.asCell()->structure()->typeInfo().masqueradesAsUndefined();
2848     
2849     if (src1.isNull())
2850         return src2.isCell() && src2.asCell()->structure()->typeInfo().masqueradesAsUndefined();
2851
2852     JSCell* cell1 = src1.asCell();
2853
2854     if (cell1->isString()) {
2855         if (src2.isInt32())
2856             return jsToNumber(jsCast<JSString*>(cell1)->value(stackFrame.callFrame)) == src2.asInt32();
2857             
2858         if (src2.isDouble())
2859             return jsToNumber(jsCast<JSString*>(cell1)->value(stackFrame.callFrame)) == src2.asDouble();
2860
2861         if (src2.isTrue())
2862             return jsToNumber(jsCast<JSString*>(cell1)->value(stackFrame.callFrame)) == 1.0;
2863
2864         if (src2.isFalse())
2865             return jsToNumber(jsCast<JSString*>(cell1)->value(stackFrame.callFrame)) == 0.0;
2866
2867         JSCell* cell2 = src2.asCell();
2868         if (cell2->isString())
2869             return jsCast<JSString*>(cell1)->value(stackFrame.callFrame) == jsCast<JSString*>(cell2)->value(stackFrame.callFrame);
2870
2871         src2 = asObject(cell2)->toPrimitive(stackFrame.callFrame);
2872         CHECK_FOR_EXCEPTION();
2873         goto start;
2874     }
2875
2876     if (src2.isObject())
2877         return asObject(cell1) == asObject(src2);
2878     src1 = asObject(cell1)->toPrimitive(stackFrame.callFrame);
2879     CHECK_FOR_EXCEPTION();
2880     goto start;
2881     
2882 #else // USE(JSVALUE32_64)
2883     CallFrame* callFrame = stackFrame.callFrame;
2884     
2885     bool result = JSValue::equalSlowCaseInline(callFrame, src1, src2);
2886     CHECK_FOR_EXCEPTION_AT_END();
2887     return result;
2888 #endif // USE(JSVALUE32_64)
2889 }
2890
2891 DEFINE_STUB_FUNCTION(int, op_eq_strings)
2892 {
2893 #if USE(JSVALUE32_64)
2894     STUB_INIT_STACK_FRAME(stackFrame);
2895
2896     JSString* string1 = stackFrame.args[0].jsString();
2897     JSString* string2 = stackFrame.args[1].jsString();
2898
2899     ASSERT(string1->isString());
2900     ASSERT(string2->isString());
2901     return string1->value(stackFrame.callFrame) == string2->value(stackFrame.callFrame);
2902 #else
2903     UNUSED_PARAM(args);
2904     ASSERT_NOT_REACHED();
2905     return 0;
2906 #endif
2907 }
2908
2909 DEFINE_STUB_FUNCTION(EncodedJSValue, op_lshift)
2910 {
2911     STUB_INIT_STACK_FRAME(stackFrame);
2912
2913     JSValue val = stackFrame.args[0].jsValue();
2914     JSValue shift = stackFrame.args[1].jsValue();
2915
2916     CallFrame* callFrame = stackFrame.callFrame;
2917     JSValue result = jsNumber((val.toInt32(callFrame)) << (shift.toUInt32(callFrame) & 0x1f));
2918     CHECK_FOR_EXCEPTION_AT_END();
2919     return JSValue::encode(result);
2920 }
2921
2922 DEFINE_STUB_FUNCTION(EncodedJSValue, op_bitand)
2923 {
2924     STUB_INIT_STACK_FRAME(stackFrame);
2925
2926     JSValue src1 = stackFrame.args[0].jsValue();
2927     JSValue src2 = stackFrame.args[1].jsValue();
2928
2929     ASSERT(!src1.isInt32() || !src2.isInt32());
2930     CallFrame* callFrame = stackFrame.callFrame;
2931     JSValue result = jsNumber(src1.toInt32(callFrame) & src2.toInt32(callFrame));
2932     CHECK_FOR_EXCEPTION_AT_END();
2933     return JSValue::encode(result);
2934 }
2935
2936 DEFINE_STUB_FUNCTION(EncodedJSValue, op_rshift)
2937 {
2938     STUB_INIT_STACK_FRAME(stackFrame);
2939
2940     JSValue val = stackFrame.args[0].jsValue();
2941     JSValue shift = stackFrame.args[1].jsValue();
2942
2943     CallFrame* callFrame = stackFrame.callFrame;
2944     JSValue result = jsNumber((val.toInt32(callFrame)) >> (shift.toUInt32(callFrame) & 0x1f));
2945
2946     CHECK_FOR_EXCEPTION_AT_END();
2947     return JSValue::encode(result);
2948 }
2949
2950 DEFINE_STUB_FUNCTION(EncodedJSValue, op_resolve_with_base)
2951 {
2952     STUB_INIT_STACK_FRAME(stackFrame);
2953
2954     CallFrame* callFrame = stackFrame.callFrame;
2955     JSValue result = CommonSlowPaths::opResolveWithBase(callFrame, stackFrame.args[0].identifier(), callFrame->registers()[stackFrame.args[1].int32()]);
2956     CHECK_FOR_EXCEPTION_AT_END();
2957     return JSValue::encode(result);
2958 }
2959
2960 DEFINE_STUB_FUNCTION(EncodedJSValue, op_resolve_with_this)
2961 {
2962     STUB_INIT_STACK_FRAME(stackFrame);
2963
2964     CallFrame* callFrame = stackFrame.callFrame;
2965     JSValue result = CommonSlowPaths::opResolveWithThis(callFrame, stackFrame.args[0].identifier(), callFrame->registers()[stackFrame.args[1].int32()]);
2966     CHECK_FOR_EXCEPTION_AT_END();
2967     return JSValue::encode(result);
2968 }
2969
2970 DEFINE_STUB_FUNCTION(JSObject*, op_new_func_exp)
2971 {
2972     STUB_INIT_STACK_FRAME(stackFrame);
2973     CallFrame* callFrame = stackFrame.callFrame;
2974
2975     FunctionExecutable* function = stackFrame.args[0].function();
2976     JSFunction* func = function->make(callFrame, callFrame->scopeChain());
2977     ASSERT(callFrame->codeBlock()->codeType() != FunctionCode || !callFrame->codeBlock()->needsFullScopeChain() || callFrame->uncheckedR(callFrame->codeBlock()->activationRegister()).jsValue());
2978
2979     /* 
2980         The Identifier in a FunctionExpression can be referenced from inside
2981         the FunctionExpression's FunctionBody to allow the function to call
2982         itself recursively. However, unlike in a FunctionDeclaration, the
2983         Identifier in a FunctionExpression cannot be referenced from and
2984         does not affect the scope enclosing the FunctionExpression.
2985      */
2986     if (!function->name().isNull()) {
2987         JSStaticScopeObject* functionScopeObject = JSStaticScopeObject::create(callFrame, function->name(), func, ReadOnly | DontDelete);
2988         func->setScope(callFrame->globalData(), func->scope()->push(functionScopeObject));
2989     }
2990
2991     return func;
2992 }
2993
2994 DEFINE_STUB_FUNCTION(EncodedJSValue, op_mod)
2995 {
2996     STUB_INIT_STACK_FRAME(stackFrame);
2997
2998     JSValue dividendValue = stackFrame.args[0].jsValue();
2999     JSValue divisorValue = stackFrame.args[1].jsValue();
3000
3001     CallFrame* callFrame = stackFrame.callFrame;
3002     double d = dividendValue.toNumber(callFrame);
3003     JSValue result = jsNumber(fmod(d, divisorValue.toNumber(callFrame)));
3004     CHECK_FOR_EXCEPTION_AT_END();
3005     return JSValue::encode(result);
3006 }
3007
3008 DEFINE_STUB_FUNCTION(EncodedJSValue, op_post_dec)
3009 {
3010     STUB_INIT_STACK_FRAME(stackFrame);
3011
3012     JSValue v = stackFrame.args[0].jsValue();
3013
3014     CallFrame* callFrame = stackFrame.callFrame;
3015
3016     double number = v.toNumber(callFrame);
3017     CHECK_FOR_EXCEPTION_AT_END();
3018
3019     callFrame->registers()[stackFrame.args[1].int32()] = jsNumber(number - 1);
3020     return JSValue::encode(jsNumber(number));
3021 }
3022
3023 DEFINE_STUB_FUNCTION(EncodedJSValue, op_urshift)
3024 {
3025     STUB_INIT_STACK_FRAME(stackFrame);
3026
3027     JSValue val = stackFrame.args[0].jsValue();
3028     JSValue shift = stackFrame.args[1].jsValue();
3029
3030     CallFrame* callFrame = stackFrame.callFrame;
3031     JSValue result = jsNumber((val.toUInt32(callFrame)) >> (shift.toUInt32(callFrame) & 0x1f));
3032     CHECK_FOR_EXCEPTION_AT_END();
3033     return JSValue::encode(result);
3034 }
3035
3036 DEFINE_STUB_FUNCTION(EncodedJSValue, op_bitxor)
3037 {
3038     STUB_INIT_STACK_FRAME(stackFrame);
3039
3040     JSValue src1 = stackFrame.args[0].jsValue();
3041     JSValue src2 = stackFrame.args[1].jsValue();
3042
3043     CallFrame* callFrame = stackFrame.callFrame;
3044
3045     JSValue result = jsNumber(src1.toInt32(callFrame) ^ src2.toInt32(callFrame));
3046     CHECK_FOR_EXCEPTION_AT_END();
3047     return JSValue::encode(result);
3048 }
3049
3050 DEFINE_STUB_FUNCTION(JSObject*, op_new_regexp)
3051 {
3052     STUB_INIT_STACK_FRAME(stackFrame);
3053
3054     CallFrame* callFrame = stackFrame.callFrame;
3055
3056     RegExp* regExp = stackFrame.args[0].regExp();
3057     if (!regExp->isValid()) {
3058         stackFrame.globalData->exception = createSyntaxError(callFrame, "Invalid flags supplied to RegExp constructor.");
3059         VM_THROW_EXCEPTION();
3060     }
3061
3062     return RegExpObject::create(*stackFrame.globalData, stackFrame.callFrame->lexicalGlobalObject(), stackFrame.callFrame->lexicalGlobalObject()->regExpStructure(), regExp);
3063 }
3064
3065 DEFINE_STUB_FUNCTION(EncodedJSValue, op_bitor)
3066 {
3067     STUB_INIT_STACK_FRAME(stackFrame);
3068
3069     JSValue src1 = stackFrame.args[0].jsValue();
3070     JSValue src2 = stackFrame.args[1].jsValue();
3071
3072     CallFrame* callFrame = stackFrame.callFrame;
3073
3074     JSValue result = jsNumber(src1.toInt32(callFrame) | src2.toInt32(callFrame));
3075     CHECK_FOR_EXCEPTION_AT_END();
3076     return JSValue::encode(result);
3077 }
3078
3079 DEFINE_STUB_FUNCTION(EncodedJSValue, op_call_eval)
3080 {
3081     STUB_INIT_STACK_FRAME(stackFrame);
3082
3083     CallFrame* callFrame = stackFrame.callFrame;
3084     CallFrame* callerFrame = callFrame->callerFrame();
3085     ASSERT(callFrame->callerFrame()->codeBlock()->codeType() != FunctionCode
3086         || !callFrame->callerFrame()->codeBlock()->needsFullScopeChain()
3087         || callFrame->callerFrame()->uncheckedR(callFrame->callerFrame()->codeBlock()->activationRegister()).jsValue());
3088
3089     callFrame->setScopeChain(callerFrame->scopeChain());
3090     callFrame->setReturnPC(static_cast<Instruction*>((STUB_RETURN_ADDRESS).value()));
3091     callFrame->setCodeBlock(0);
3092
3093     if (!isHostFunction(callFrame->calleeAsValue(), globalFuncEval))
3094         return JSValue::encode(JSValue());
3095
3096     JSValue result = eval(callFrame);
3097     if (stackFrame.globalData->exception)
3098         return throwExceptionFromOpCall<EncodedJSValue>(stackFrame, callFrame, STUB_RETURN_ADDRESS);
3099
3100     return JSValue::encode(result);
3101 }
3102
3103 DEFINE_STUB_FUNCTION(void*, op_throw)
3104 {
3105     STUB_INIT_STACK_FRAME(stackFrame);
3106     ExceptionHandler handler = jitThrow(stackFrame.globalData, stackFrame.callFrame, stackFrame.args[0].jsValue(), STUB_RETURN_ADDRESS);
3107     STUB_SET_RETURN_ADDRESS(handler.catchRoutine);
3108     return handler.callFrame;
3109 }
3110
3111 DEFINE_STUB_FUNCTION(JSPropertyNameIterator*, op_get_pnames)
3112 {
3113     STUB_INIT_STACK_FRAME(stackFrame);
3114
3115     CallFrame* callFrame = stackFrame.callFrame;
3116     JSObject* o = stackFrame.args[0].jsObject();
3117     Structure* structure = o->structure();
3118     JSPropertyNameIterator* jsPropertyNameIterator = structure->enumerationCache();
3119     if (!jsPropertyNameIterator || jsPropertyNameIterator->cachedPrototypeChain() != structure->prototypeChain(callFrame))
3120         jsPropertyNameIterator = JSPropertyNameIterator::create(callFrame, o);
3121     return jsPropertyNameIterator;
3122 }
3123
3124 DEFINE_STUB_FUNCTION(int, has_property)
3125 {
3126     STUB_INIT_STACK_FRAME(stackFrame);
3127
3128     JSObject* base = stackFrame.args[0].jsObject();
3129     JSString* property = stackFrame.args[1].jsString();
3130     int result = base->hasProperty(stackFrame.callFrame, Identifier(stackFrame.callFrame, property->value(stackFrame.callFrame)));
3131     CHECK_FOR_EXCEPTION_AT_END();
3132     return result;
3133 }
3134
3135 DEFINE_STUB_FUNCTION(JSObject*, op_push_scope)
3136 {
3137     STUB_INIT_STACK_FRAME(stackFrame);
3138
3139     JSObject* o = stackFrame.args[0].jsValue().toObject(stackFrame.callFrame);
3140     CHECK_FOR_EXCEPTION();
3141     stackFrame.callFrame->setScopeChain(stackFrame.callFrame->scopeChain()->push(o));
3142     return o;
3143 }
3144
3145 DEFINE_STUB_FUNCTION(void, op_pop_scope)
3146 {
3147     STUB_INIT_STACK_FRAME(stackFrame);
3148
3149     stackFrame.callFrame->setScopeChain(stackFrame.callFrame->scopeChain()->pop());
3150 }
3151
3152 DEFINE_STUB_FUNCTION(EncodedJSValue, op_typeof)
3153 {
3154     STUB_INIT_STACK_FRAME(stackFrame);
3155
3156     return JSValue::encode(jsTypeStringForValue(stackFrame.callFrame, stackFrame.args[0].jsValue()));
3157 }
3158
3159 DEFINE_STUB_FUNCTION(EncodedJSValue, op_is_object)
3160 {
3161     STUB_INIT_STACK_FRAME(stackFrame);
3162
3163     return JSValue::encode(jsBoolean(jsIsObjectType(stackFrame.args[0].jsValue())));
3164 }
3165
3166 DEFINE_STUB_FUNCTION(EncodedJSValue, op_is_function)
3167 {
3168     STUB_INIT_STACK_FRAME(stackFrame);
3169
3170     return JSValue::encode(jsBoolean(jsIsFunctionType(stackFrame.args[0].jsValue())));
3171 }
3172
3173 DEFINE_STUB_FUNCTION(EncodedJSValue, op_stricteq)
3174 {
3175     STUB_INIT_STACK_FRAME(stackFrame);
3176
3177     JSValue src1 = stackFrame.args[0].jsValue();
3178     JSValue src2 = stackFrame.args[1].jsValue();
3179     
3180     bool result = JSValue::strictEqual(stackFrame.callFrame, src1, src2);
3181     CHECK_FOR_EXCEPTION_AT_END();
3182     return JSValue::encode(jsBoolean(result));
3183 }
3184
3185 DEFINE_STUB_FUNCTION(EncodedJSValue, op_to_primitive)
3186 {
3187     STUB_INIT_STACK_FRAME(stackFrame);
3188
3189     return JSValue::encode(stackFrame.args[0].jsValue().toPrimitive(stackFrame.callFrame));
3190 }
3191
3192 DEFINE_STUB_FUNCTION(EncodedJSValue, op_strcat)
3193 {
3194     STUB_INIT_STACK_FRAME(stackFrame);
3195
3196     JSValue result = jsString(stackFrame.callFrame, &stackFrame.callFrame->registers()[stackFrame.args[0].int32()], stackFrame.args[1].int32());
3197     CHECK_FOR_EXCEPTION_AT_END();
3198     return JSValue::encode(result);
3199 }
3200
3201 DEFINE_STUB_FUNCTION(EncodedJSValue, op_nstricteq)
3202 {
3203     STUB_INIT_STACK_FRAME(stackFrame);
3204
3205     JSValue src1 = stackFrame.args[0].jsValue();
3206     JSValue src2 = stackFrame.args[1].jsValue();
3207
3208     bool result = !JSValue::strictEqual(stackFrame.callFrame, src1, src2);
3209     CHECK_FOR_EXCEPTION_AT_END();
3210     return JSValue::encode(jsBoolean(result));
3211 }
3212
3213 DEFINE_STUB_FUNCTION(EncodedJSValue, op_to_jsnumber)
3214 {
3215     STUB_INIT_STACK_FRAME(stackFrame);
3216
3217     JSValue src = stackFrame.args[0].jsValue();
3218     CallFrame* callFrame = stackFrame.callFrame;
3219
3220     double number = src.toNumber(callFrame);
3221     CHECK_FOR_EXCEPTION_AT_END();
3222     return JSValue::encode(jsNumber(number));
3223 }
3224
3225 DEFINE_STUB_FUNCTION(EncodedJSValue, op_in)
3226 {
3227     STUB_INIT_STACK_FRAME(stackFrame);
3228
3229     CallFrame* callFrame = stackFrame.callFrame;
3230     JSValue baseVal = stackFrame.args[1].jsValue();
3231
3232     if (!baseVal.isObject()) {
3233         stackFrame.globalData->exception = createInvalidParamError(stackFrame.callFrame, "in", baseVal);
3234         VM_THROW_EXCEPTION();
3235     }
3236
3237     JSValue propName = stackFrame.args[0].jsValue();
3238     JSObject* baseObj = asObject(baseVal);
3239
3240     uint32_t i;
3241     if (propName.getUInt32(i))
3242         return JSValue::encode(jsBoolean(baseObj->hasProperty(callFrame, i)));
3243
3244     Identifier property(callFrame, propName.toString(callFrame)->value(callFrame));
3245     CHECK_FOR_EXCEPTION();
3246     return JSValue::encode(jsBoolean(baseObj->hasProperty(callFrame, property)));
3247 }
3248
3249 DEFINE_STUB_FUNCTION(JSObject*, op_push_new_scope)
3250 {
3251     STUB_INIT_STACK_FRAME(stackFrame);
3252
3253     JSObject* scope = JSStaticScopeObject::create(stackFrame.callFrame, stackFrame.args[0].identifier(), stackFrame.args[1].jsValue(), DontDelete);
3254
3255     CallFrame* callFrame = stackFrame.callFrame;
3256     callFrame->setScopeChain(callFrame->scopeChain()->push(scope));
3257     return scope;
3258 }
3259
3260 DEFINE_STUB_FUNCTION(void, op_jmp_scopes)
3261 {
3262     STUB_INIT_STACK_FRAME(stackFrame);
3263
3264     unsigned count = stackFrame.args[0].int32();
3265     CallFrame* callFrame = stackFrame.callFrame;
3266
3267     ScopeChainNode* tmp = callFrame->scopeChain();
3268     while (count--)
3269         tmp = tmp->pop();
3270     callFrame->setScopeChain(tmp);
3271 }
3272
3273 DEFINE_STUB_FUNCTION(void, op_put_by_index)
3274 {
3275     STUB_INIT_STACK_FRAME(stackFrame);
3276
3277     CallFrame* callFrame = stackFrame.callFrame;
3278     unsigned property = stackFrame.args[1].int32();
3279
3280     JSValue arrayValue = stackFrame.args[0].jsValue();
3281     ASSERT(isJSArray(arrayValue));
3282     asArray(arrayValue)->putDirectIndex(callFrame, property, stackFrame.args[2].jsValue(), false);
3283 }
3284
3285 DEFINE_STUB_FUNCTION(void*, op_switch_imm)
3286 {
3287     STUB_INIT_STACK_FRAME(stackFrame);
3288
3289     JSValue scrutinee = stackFrame.args[0].jsValue();
3290     unsigned tableIndex = stackFrame.args[1].int32();
3291     CallFrame* callFrame = stackFrame.callFrame;
3292     CodeBlock* codeBlock = callFrame->codeBlock();
3293
3294     if (scrutinee.isInt32())
3295         return codeBlock->immediateSwitchJumpTable(tableIndex).ctiForValue(scrutinee.asInt32()).executableAddress();
3296     if (scrutinee.isDouble() && scrutinee.asDouble() == static_cast<int32_t>(scrutinee.asDouble()))
3297             return codeBlock->immediateSwitchJumpTable(tableIndex).ctiForValue(static_cast<int32_t>(scrutinee.asDouble())).executableAddress();
3298     return codeBlock->immediateSwitchJumpTable(tableIndex).ctiDefault.executableAddress();
3299 }
3300
3301 DEFINE_STUB_FUNCTION(void*, op_switch_char)
3302 {
3303     STUB_INIT_STACK_FRAME(stackFrame);
3304
3305     JSValue scrutinee = stackFrame.args[0].jsValue();
3306     unsigned tableIndex = stackFrame.args[1].int32();
3307     CallFrame* callFrame = stackFrame.callFrame;
3308     CodeBlock* codeBlock = callFrame->codeBlock();
3309
3310     void* result = codeBlock->characterSwitchJumpTable(tableIndex).ctiDefault.executableAddress();
3311
3312     if (scrutinee.isString()) {
3313         StringImpl* value = asString(scrutinee)->value(callFrame).impl();
3314         if (value->length() == 1)
3315             result = codeBlock->characterSwitchJumpTable(tableIndex).ctiForValue((*value)[0]).executableAddress();
3316     }
3317
3318     CHECK_FOR_EXCEPTION_AT_END();
3319     return result;
3320 }
3321
3322 DEFINE_STUB_FUNCTION(void*, op_switch_string)
3323 {
3324     STUB_INIT_STACK_FRAME(stackFrame);
3325
3326     JSValue scrutinee = stackFrame.args[0].jsValue();
3327     unsigned tableIndex = stackFrame.args[1].int32();
3328     CallFrame* callFrame = stackFrame.callFrame;
3329     CodeBlock* codeBlock = callFrame->codeBlock();
3330
3331     void* result = codeBlock->stringSwitchJumpTable(tableIndex).ctiDefault.executableAddress();
3332
3333     if (scrutinee.isString()) {
3334         StringImpl* value = asString(scrutinee)->value(callFrame).impl();
3335         result = codeBlock->stringSwitchJumpTable(tableIndex).ctiForValue(value).executableAddress();
3336     }
3337
3338     CHECK_FOR_EXCEPTION_AT_END();
3339     return result;
3340 }
3341
3342 DEFINE_STUB_FUNCTION(EncodedJSValue, op_del_by_val)
3343 {
3344     STUB_INIT_STACK_FRAME(stackFrame);
3345
3346     CallFrame* callFrame = stackFrame.callFrame;
3347
3348     JSValue baseValue = stackFrame.args[0].jsValue();
3349     JSObject* baseObj = baseValue.toObject(callFrame); // may throw
3350
3351     JSValue subscript = stackFrame.args[1].jsValue();
3352     bool result;
3353     uint32_t i;
3354     if (subscript.getUInt32(i))
3355         result = baseObj->methodTable()->deletePropertyByIndex(baseObj, callFrame, i);
3356     else {
3357         CHECK_FOR_EXCEPTION();
3358         Identifier property(callFrame, subscript.toString(callFrame)->value(callFrame));
3359         CHECK_FOR_EXCEPTION();
3360         result = baseObj->methodTable()->deleteProperty(baseObj, callFrame, property);
3361     }
3362
3363     if (!result && callFrame->codeBlock()->isStrictMode())
3364         stackFrame.globalData->exception = createTypeError(stackFrame.callFrame, "Unable to delete property.");
3365
3366     CHECK_FOR_EXCEPTION_AT_END();
3367     return JSValue::encode(jsBoolean(result));
3368 }
3369
3370 DEFINE_STUB_FUNCTION(void, op_put_getter_setter)
3371 {
3372     STUB_INIT_STACK_FRAME(stackFrame);
3373
3374     CallFrame* callFrame = stackFrame.callFrame;
3375
3376     ASSERT(stackFrame.args[0].jsValue().isObject());
3377     JSObject* baseObj = asObject(stackFrame.args[0].jsValue());
3378
3379     GetterSetter* accessor = GetterSetter::create(callFrame);
3380
3381     JSValue getter = stackFrame.args[2].jsValue();
3382     JSValue setter = stackFrame.args[3].jsValue();
3383     ASSERT(getter.isObject() || getter.isUndefined());
3384     ASSERT(setter.isObject() || setter.isUndefined());
3385     ASSERT(getter.isObject() || setter.isObject());
3386
3387     if (!getter.isUndefined())
3388         accessor->setGetter(callFrame->globalData(), asObject(getter));
3389     if (!setter.isUndefined())
3390         accessor->setSetter(callFrame->globalData(), asObject(setter));
3391     baseObj->putDirectAccessor(callFrame->globalData(), stackFrame.args[1].identifier(), accessor, Accessor);
3392 }
3393
3394 DEFINE_STUB_FUNCTION(void, op_throw_reference_error)
3395 {
3396     STUB_INIT_STACK_FRAME(stackFrame);
3397
3398     CallFrame* callFrame = stackFrame.callFrame;
3399     UString message = stackFrame.args[0].jsValue().toString(callFrame)->value(callFrame);
3400     stackFrame.globalData->exception = createReferenceError(callFrame, message);
3401     VM_THROW_EXCEPTION_AT_END();
3402 }
3403
3404 DEFINE_STUB_FUNCTION(void, op_debug)
3405 {
3406     STUB_INIT_STACK_FRAME(stackFrame);
3407
3408     CallFrame* callFrame = stackFrame.callFrame;
3409
3410     int debugHookID = stackFrame.args[0].int32();
3411     int firstLine = stackFrame.args[1].int32();
3412     int lastLine = stackFrame.args[2].int32();
3413
3414     stackFrame.globalData->interpreter->debug(callFrame, static_cast<DebugHookID>(debugHookID), firstLine, lastLine);
3415 }
3416
3417 DEFINE_STUB_FUNCTION(void*, vm_throw)
3418 {
3419     STUB_INIT_STACK_FRAME(stackFrame);
3420     JSGlobalData* globalData = stackFrame.globalData;
3421     ExceptionHandler handler = jitThrow(globalData, stackFrame.callFrame, globalData->exception, globalData->exceptionLocation);
3422     STUB_SET_RETURN_ADDRESS(handler.catchRoutine);
3423     return handler.callFrame;
3424 }
3425
3426 DEFINE_STUB_FUNCTION(EncodedJSValue, to_object)
3427 {
3428     STUB_INIT_STACK_FRAME(stackFrame);
3429
3430     CallFrame* callFrame = stackFrame.callFrame;
3431     return JSValue::encode(stackFrame.args[0].jsValue().toObject(callFrame));
3432 }
3433
3434 MacroAssemblerCodeRef JITThunks::ctiStub(JSGlobalData* globalData, ThunkGenerator generator)
3435 {
3436     CTIStubMap::AddResult entry = m_ctiStubMap.add(generator, MacroAssemblerCodeRef());
3437     if (entry.isNewEntry)
3438         entry.iterator->second = generator(globalData);
3439     return entry.iterator->second;
3440 }
3441
3442 NativeExecutable* JITThunks::hostFunctionStub(JSGlobalData* globalData, NativeFunction function, NativeFunction constructor)
3443 {
3444     HostFunctionStubMap::AddResult result = m_hostFunctionStubMap->add(function, PassWeak<NativeExecutable>());
3445     if (!result.iterator->second)
3446         result.iterator->second = PassWeak<NativeExecutable>(NativeExecutable::create(*globalData, JIT::compileCTINativeCall(globalData, function), function, MacroAssemblerCodeRef::createSelfManagedCodeRef(ctiNativeConstruct()), constructor, NoIntrinsic));
3447     return result.iterator->second.get();
3448 }
3449
3450 NativeExecutable* JITThunks::hostFunctionStub(JSGlobalData* globalData, NativeFunction function, ThunkGenerator generator, Intrinsic intrinsic)
3451 {
3452     HostFunctionStubMap::AddResult entry = m_hostFunctionStubMap->add(function, PassWeak<NativeExecutable>());
3453     if (!entry.iterator->second) {
3454         MacroAssemblerCodeRef code;
3455         if (generator) {
3456             if (globalData->canUseJIT())
3457                 code = generator(globalData);
3458             else
3459                 code = MacroAssemblerCodeRef();
3460         } else
3461             code = JIT::compileCTINativeCall(globalData, function);
3462         entry.iterator->second = PassWeak<NativeExecutable>(NativeExecutable::create(*globalData, code, function, MacroAssemblerCodeRef::createSelfManagedCodeRef(ctiNativeConstruct()), callHostFunctionAsConstructor, intrinsic));
3463     }
3464     return entry.iterator->second.get();
3465 }
3466
3467 void JITThunks::clearHostFunctionStubs()
3468 {
3469     m_hostFunctionStubMap.clear();
3470 }
3471
3472 } // namespace JSC
3473
3474 #endif // ENABLE(JIT)