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