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