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