c69a8289af41f3fc8c95d30c3fbbf0e4897f405a
[WebKit-https.git] / 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. 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 "Collector.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 volatile(
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 volatile(
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 volatile(
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 volatile(
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 volatile(
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 volatile(
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 volatile(
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 volatile(
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_TRADITIONAL)
741
742 __asm EncodedJSValue ctiTrampoline(void*, RegisterFile*, CallFrame*, void* /*unused1*/, Profiler**, JSGlobalData*)
743 {
744     ARM
745     stmdb sp!, {r1-r3}
746     stmdb sp!, {r4-r8, lr}
747     sub sp, sp, # PRESERVEDR4_OFFSET
748     mov r4, r2
749     mov r5, #512
750     mov lr, pc
751     bx r0
752     add sp, sp, # PRESERVEDR4_OFFSET
753     ldmia sp!, {r4-r8, lr}
754     add sp, sp, #12
755     bx lr
756 }
757
758 __asm void ctiVMThrowTrampoline()
759 {
760     ARM
761     PRESERVE8
762     mov r0, sp
763     bl cti_vm_throw
764     add sp, sp, # PRESERVEDR4_OFFSET
765     ldmia sp!, {r4-r8, lr}
766     add sp, sp, #12
767     bx lr
768 }
769
770 __asm void ctiOpThrowNotCaught()
771 {
772     ARM
773     add sp, sp, # PRESERVEDR4_OFFSET
774     ldmia sp!, {r4-r8, lr}
775     add sp, sp, #12
776     bx lr
777 }
778 #endif
779
780 #if ENABLE(OPCODE_SAMPLING)
781     #define CTI_SAMPLER stackFrame.globalData->interpreter->sampler()
782 #else
783     #define CTI_SAMPLER 0
784 #endif
785
786 JITThunks::JITThunks(JSGlobalData* globalData)
787 {
788     if (!globalData->executableAllocator.isValid())
789         return;
790
791     JIT::compileCTIMachineTrampolines(globalData, &m_executablePool, &m_trampolineStructure);
792     ASSERT(m_executablePool);
793 #if CPU(ARM_THUMB2)
794     // Unfortunate the arm compiler does not like the use of offsetof on JITStackFrame (since it contains non POD types),
795     // and the OBJECT_OFFSETOF macro does not appear constantish enough for it to be happy with its use in COMPILE_ASSERT
796     // macros.
797     ASSERT(OBJECT_OFFSETOF(struct JITStackFrame, preservedReturnAddress) == PRESERVED_RETURN_ADDRESS_OFFSET);
798     ASSERT(OBJECT_OFFSETOF(struct JITStackFrame, preservedR4) == PRESERVED_R4_OFFSET);
799     ASSERT(OBJECT_OFFSETOF(struct JITStackFrame, preservedR5) == PRESERVED_R5_OFFSET);
800     ASSERT(OBJECT_OFFSETOF(struct JITStackFrame, preservedR6) == PRESERVED_R6_OFFSET);
801
802     ASSERT(OBJECT_OFFSETOF(struct JITStackFrame, registerFile) == REGISTER_FILE_OFFSET);
803     ASSERT(OBJECT_OFFSETOF(struct JITStackFrame, callFrame) == CALLFRAME_OFFSET);
804     ASSERT(OBJECT_OFFSETOF(struct JITStackFrame, exception) == EXCEPTION_OFFSET);
805     // The fifth argument is the first item already on the stack.
806     ASSERT(OBJECT_OFFSETOF(struct JITStackFrame, enabledProfilerReference) == ENABLE_PROFILER_REFERENCE_OFFSET);
807
808     ASSERT(OBJECT_OFFSETOF(struct JITStackFrame, thunkReturnAddress) == THUNK_RETURN_ADDRESS_OFFSET);
809
810 #elif CPU(ARM_TRADITIONAL)
811
812     ASSERT(OBJECT_OFFSETOF(struct JITStackFrame, thunkReturnAddress) == THUNK_RETURN_ADDRESS_OFFSET);
813     ASSERT(OBJECT_OFFSETOF(struct JITStackFrame, preservedR4) == PRESERVEDR4_OFFSET);
814
815
816 #elif CPU(MIPS)
817     ASSERT(OBJECT_OFFSETOF(struct JITStackFrame, preservedGP) == PRESERVED_GP_OFFSET);
818     ASSERT(OBJECT_OFFSETOF(struct JITStackFrame, preservedS0) == PRESERVED_S0_OFFSET);
819     ASSERT(OBJECT_OFFSETOF(struct JITStackFrame, preservedS1) == PRESERVED_S1_OFFSET);
820     ASSERT(OBJECT_OFFSETOF(struct JITStackFrame, preservedS2) == PRESERVED_S2_OFFSET);
821     ASSERT(OBJECT_OFFSETOF(struct JITStackFrame, preservedReturnAddress) == PRESERVED_RETURN_ADDRESS_OFFSET);
822     ASSERT(OBJECT_OFFSETOF(struct JITStackFrame, thunkReturnAddress) == THUNK_RETURN_ADDRESS_OFFSET);
823     ASSERT(OBJECT_OFFSETOF(struct JITStackFrame, registerFile) == REGISTER_FILE_OFFSET);
824     ASSERT(OBJECT_OFFSETOF(struct JITStackFrame, callFrame) == CALLFRAME_OFFSET);
825     ASSERT(OBJECT_OFFSETOF(struct JITStackFrame, exception) == EXCEPTION_OFFSET);
826     ASSERT(OBJECT_OFFSETOF(struct JITStackFrame, enabledProfilerReference) == ENABLE_PROFILER_REFERENCE_OFFSET);
827     ASSERT(OBJECT_OFFSETOF(struct JITStackFrame, globalData) == GLOBAL_DATA_OFFSET);
828
829 #endif
830 }
831
832 JITThunks::~JITThunks()
833 {
834 }
835
836 #if ENABLE(JIT_OPTIMIZE_PROPERTY_ACCESS)
837
838 NEVER_INLINE void JITThunks::tryCachePutByID(CallFrame* callFrame, CodeBlock* codeBlock, ReturnAddressPtr returnAddress, JSValue baseValue, const PutPropertySlot& slot, StructureStubInfo* stubInfo, bool direct)
839 {
840     // The interpreter checks for recursion here; I do not believe this can occur in CTI.
841
842     if (!baseValue.isCell())
843         return;
844
845     // Uncacheable: give up.
846     if (!slot.isCacheable()) {
847         ctiPatchCallByReturnAddress(codeBlock, returnAddress, FunctionPtr(direct ? cti_op_put_by_id_direct_generic : cti_op_put_by_id_generic));
848         return;
849     }
850     
851     JSCell* baseCell = baseValue.asCell();
852     Structure* structure = baseCell->structure();
853
854     if (structure->isUncacheableDictionary()) {
855         ctiPatchCallByReturnAddress(codeBlock, returnAddress, FunctionPtr(direct ? cti_op_put_by_id_direct_generic : cti_op_put_by_id_generic));
856         return;
857     }
858
859     // If baseCell != base, then baseCell must be a proxy for another object.
860     if (baseCell != slot.base()) {
861         ctiPatchCallByReturnAddress(codeBlock, returnAddress, FunctionPtr(direct ? cti_op_put_by_id_direct_generic : cti_op_put_by_id_generic));
862         return;
863     }
864
865     // Cache hit: Specialize instruction and ref Structures.
866
867     // Structure transition, cache transition info
868     if (slot.type() == PutPropertySlot::NewProperty) {
869         if (structure->isDictionary()) {
870             ctiPatchCallByReturnAddress(codeBlock, returnAddress, FunctionPtr(direct ? cti_op_put_by_id_direct_generic : cti_op_put_by_id_generic));
871             return;
872         }
873
874         // put_by_id_transition checks the prototype chain for setters.
875         normalizePrototypeChain(callFrame, baseCell);
876
877         StructureChain* prototypeChain = structure->prototypeChain(callFrame);
878         stubInfo->initPutByIdTransition(structure->previousID(), structure, prototypeChain);
879         JIT::compilePutByIdTransition(callFrame->scopeChain()->globalData, codeBlock, stubInfo, structure->previousID(), structure, slot.cachedOffset(), prototypeChain, returnAddress, direct);
880         return;
881     }
882     
883     stubInfo->initPutByIdReplace(structure);
884
885     JIT::patchPutByIdReplace(codeBlock, stubInfo, structure, slot.cachedOffset(), returnAddress, direct);
886 }
887
888 NEVER_INLINE void JITThunks::tryCacheGetByID(CallFrame* callFrame, CodeBlock* codeBlock, ReturnAddressPtr returnAddress, JSValue baseValue, const Identifier& propertyName, const PropertySlot& slot, StructureStubInfo* stubInfo)
889 {
890     // FIXME: Write a test that proves we need to check for recursion here just
891     // like the interpreter does, then add a check for recursion.
892
893     // FIXME: Cache property access for immediates.
894     if (!baseValue.isCell()) {
895         ctiPatchCallByReturnAddress(codeBlock, returnAddress, FunctionPtr(cti_op_get_by_id_generic));
896         return;
897     }
898     
899     JSGlobalData* globalData = &callFrame->globalData();
900
901     if (isJSArray(globalData, baseValue) && propertyName == callFrame->propertyNames().length) {
902         JIT::compilePatchGetArrayLength(callFrame->scopeChain()->globalData, codeBlock, returnAddress);
903         return;
904     }
905     
906     if (isJSString(globalData, baseValue) && propertyName == callFrame->propertyNames().length) {
907         // The tradeoff of compiling an patched inline string length access routine does not seem
908         // to pay off, so we currently only do this for arrays.
909         ctiPatchCallByReturnAddress(codeBlock, returnAddress, globalData->jitStubs->ctiStringLengthTrampoline());
910         return;
911     }
912
913     // Uncacheable: give up.
914     if (!slot.isCacheable()) {
915         ctiPatchCallByReturnAddress(codeBlock, returnAddress, FunctionPtr(cti_op_get_by_id_generic));
916         return;
917     }
918
919     JSCell* baseCell = baseValue.asCell();
920     Structure* structure = baseCell->structure();
921
922     if (structure->isUncacheableDictionary()) {
923         ctiPatchCallByReturnAddress(codeBlock, returnAddress, FunctionPtr(cti_op_get_by_id_generic));
924         return;
925     }
926
927     // Cache hit: Specialize instruction and ref Structures.
928
929     if (slot.slotBase() == baseValue) {
930         // set this up, so derefStructures can do it's job.
931         stubInfo->initGetByIdSelf(structure);
932         if (slot.cachedPropertyType() != PropertySlot::Value)
933             ctiPatchCallByReturnAddress(codeBlock, returnAddress, FunctionPtr(cti_op_get_by_id_self_fail));
934         else
935             JIT::patchGetByIdSelf(codeBlock, stubInfo, structure, slot.cachedOffset(), returnAddress);
936         return;
937     }
938
939     if (structure->isDictionary()) {
940         ctiPatchCallByReturnAddress(codeBlock, returnAddress, FunctionPtr(cti_op_get_by_id_generic));
941         return;
942     }
943
944     if (slot.slotBase() == structure->prototypeForLookup(callFrame)) {
945         ASSERT(slot.slotBase().isObject());
946
947         JSObject* slotBaseObject = asObject(slot.slotBase());
948         size_t offset = slot.cachedOffset();
949         
950         // Since we're accessing a prototype in a loop, it's a good bet that it
951         // should not be treated as a dictionary.
952         if (slotBaseObject->structure()->isDictionary()) {
953             slotBaseObject->flattenDictionaryObject();
954             offset = slotBaseObject->structure()->get(propertyName);
955         }
956         
957         stubInfo->initGetByIdProto(structure, slotBaseObject->structure());
958
959         ASSERT(!structure->isDictionary());
960         ASSERT(!slotBaseObject->structure()->isDictionary());
961         JIT::compileGetByIdProto(callFrame->scopeChain()->globalData, callFrame, codeBlock, stubInfo, structure, slotBaseObject->structure(), propertyName, slot, offset, returnAddress);
962         return;
963     }
964
965     size_t offset = slot.cachedOffset();
966     size_t count = normalizePrototypeChain(callFrame, baseValue, slot.slotBase(), propertyName, offset);
967     if (!count) {
968         stubInfo->accessType = access_get_by_id_generic;
969         return;
970     }
971
972     StructureChain* prototypeChain = structure->prototypeChain(callFrame);
973     stubInfo->initGetByIdChain(structure, prototypeChain);
974     JIT::compileGetByIdChain(callFrame->scopeChain()->globalData, callFrame, codeBlock, stubInfo, structure, prototypeChain, count, propertyName, slot, offset, returnAddress);
975 }
976
977 #endif // ENABLE(JIT_OPTIMIZE_PROPERTY_ACCESS)
978
979 #ifndef NDEBUG
980
981 extern "C" {
982
983 static void jscGeneratedNativeCode() 
984 {
985     // When executing a JIT stub function (which might do an allocation), we hack the return address
986     // to pretend to be executing this function, to keep stack logging tools from blowing out
987     // memory.
988 }
989
990 }
991
992 struct StackHack {
993     ALWAYS_INLINE StackHack(JITStackFrame& stackFrame) 
994         : stackFrame(stackFrame)
995         , savedReturnAddress(*stackFrame.returnAddressSlot())
996     {
997         *stackFrame.returnAddressSlot() = ReturnAddressPtr(FunctionPtr(jscGeneratedNativeCode));
998     }
999
1000     ALWAYS_INLINE ~StackHack() 
1001     { 
1002         *stackFrame.returnAddressSlot() = savedReturnAddress;
1003     }
1004
1005     JITStackFrame& stackFrame;
1006     ReturnAddressPtr savedReturnAddress;
1007 };
1008
1009 #define STUB_INIT_STACK_FRAME(stackFrame) JITStackFrame& stackFrame = *reinterpret_cast_ptr<JITStackFrame*>(STUB_ARGS); StackHack stackHack(stackFrame)
1010 #define STUB_SET_RETURN_ADDRESS(returnAddress) stackHack.savedReturnAddress = ReturnAddressPtr(returnAddress)
1011 #define STUB_RETURN_ADDRESS stackHack.savedReturnAddress
1012
1013 #else
1014
1015 #define STUB_INIT_STACK_FRAME(stackFrame) JITStackFrame& stackFrame = *reinterpret_cast_ptr<JITStackFrame*>(STUB_ARGS)
1016 #define STUB_SET_RETURN_ADDRESS(returnAddress) *stackFrame.returnAddressSlot() = ReturnAddressPtr(returnAddress)
1017 #define STUB_RETURN_ADDRESS *stackFrame.returnAddressSlot()
1018
1019 #endif
1020
1021 // The reason this is not inlined is to avoid having to do a PIC branch
1022 // to get the address of the ctiVMThrowTrampoline function. It's also
1023 // good to keep the code size down by leaving as much of the exception
1024 // handling code out of line as possible.
1025 static NEVER_INLINE void returnToThrowTrampoline(JSGlobalData* globalData, ReturnAddressPtr exceptionLocation, ReturnAddressPtr& returnAddressSlot)
1026 {
1027     ASSERT(globalData->exception);
1028     globalData->exceptionLocation = exceptionLocation;
1029     returnAddressSlot = ReturnAddressPtr(FunctionPtr(ctiVMThrowTrampoline));
1030 }
1031
1032 static NEVER_INLINE void throwStackOverflowError(CallFrame* callFrame, JSGlobalData* globalData, ReturnAddressPtr exceptionLocation, ReturnAddressPtr& returnAddressSlot)
1033 {
1034     globalData->exception = createStackOverflowError(callFrame);
1035     returnToThrowTrampoline(globalData, exceptionLocation, returnAddressSlot);
1036 }
1037
1038 #define VM_THROW_EXCEPTION() \
1039     do { \
1040         VM_THROW_EXCEPTION_AT_END(); \
1041         return 0; \
1042     } while (0)
1043 #define VM_THROW_EXCEPTION_AT_END() \
1044     do {\
1045         returnToThrowTrampoline(stackFrame.globalData, STUB_RETURN_ADDRESS, STUB_RETURN_ADDRESS);\
1046     } while (0)
1047
1048 #define CHECK_FOR_EXCEPTION() \
1049     do { \
1050         if (UNLIKELY(stackFrame.globalData->exception)) \
1051             VM_THROW_EXCEPTION(); \
1052     } while (0)
1053 #define CHECK_FOR_EXCEPTION_AT_END() \
1054     do { \
1055         if (UNLIKELY(stackFrame.globalData->exception)) \
1056             VM_THROW_EXCEPTION_AT_END(); \
1057     } while (0)
1058 #define CHECK_FOR_EXCEPTION_VOID() \
1059     do { \
1060         if (UNLIKELY(stackFrame.globalData->exception)) { \
1061             VM_THROW_EXCEPTION_AT_END(); \
1062             return; \
1063         } \
1064     } while (0)
1065
1066 struct ExceptionHandler {
1067     void* catchRoutine;
1068     CallFrame* callFrame;
1069 };
1070 static ExceptionHandler jitThrow(JSGlobalData* globalData, CallFrame* callFrame, JSValue exceptionValue, ReturnAddressPtr faultLocation, bool explicitThrow)
1071 {
1072     ASSERT(exceptionValue);
1073
1074     unsigned vPCIndex = callFrame->codeBlock()->bytecodeOffset(callFrame, faultLocation);
1075     globalData->exception = JSValue();
1076     HandlerInfo* handler = globalData->interpreter->throwException(callFrame, exceptionValue, vPCIndex, explicitThrow); // This may update callFrame & exceptionValue!
1077     globalData->exception = exceptionValue;
1078
1079     void* catchRoutine = handler ? handler->nativeCode.executableAddress() : FunctionPtr(ctiOpThrowNotCaught).value();
1080     ASSERT(catchRoutine);
1081     ExceptionHandler exceptionHandler = { catchRoutine, callFrame };
1082     return exceptionHandler;
1083 }
1084
1085 #if CPU(ARM_THUMB2)
1086
1087 #define DEFINE_STUB_FUNCTION(rtype, op) \
1088     extern "C" { \
1089         rtype JITStubThunked_##op(STUB_ARGS_DECLARATION); \
1090     }; \
1091     asm ( \
1092         ".text" "\n" \
1093         ".align 2" "\n" \
1094         ".globl " SYMBOL_STRING(cti_##op) "\n" \
1095         HIDE_SYMBOL(cti_##op) "\n"             \
1096         ".thumb" "\n" \
1097         ".thumb_func " THUMB_FUNC_PARAM(cti_##op) "\n" \
1098         SYMBOL_STRING(cti_##op) ":" "\n" \
1099         "str lr, [sp, #" STRINGIZE_VALUE_OF(THUNK_RETURN_ADDRESS_OFFSET) "]" "\n" \
1100         "bl " SYMBOL_STRING(JITStubThunked_##op) "\n" \
1101         "ldr lr, [sp, #" STRINGIZE_VALUE_OF(THUNK_RETURN_ADDRESS_OFFSET) "]" "\n" \
1102         "bx lr" "\n" \
1103         ); \
1104     rtype JITStubThunked_##op(STUB_ARGS_DECLARATION) \
1105
1106 #elif CPU(MIPS)
1107 #if WTF_MIPS_PIC
1108 #define DEFINE_STUB_FUNCTION(rtype, op) \
1109     extern "C" { \
1110         rtype JITStubThunked_##op(STUB_ARGS_DECLARATION); \
1111     }; \
1112     asm volatile( \
1113         ".text" "\n" \
1114         ".align 2" "\n" \
1115         ".set noreorder" "\n" \
1116         ".set nomacro" "\n" \
1117         ".set nomips16" "\n" \
1118         ".globl " SYMBOL_STRING(cti_##op) "\n" \
1119         ".ent " SYMBOL_STRING(cti_##op) "\n" \
1120         SYMBOL_STRING(cti_##op) ":" "\n" \
1121         "lw    $28," STRINGIZE_VALUE_OF(PRESERVED_GP_OFFSET) "($29)" "\n" \
1122         "sw    $31," STRINGIZE_VALUE_OF(THUNK_RETURN_ADDRESS_OFFSET) "($29)" "\n" \
1123         ".set macro" "\n" \
1124         "la    $25," SYMBOL_STRING(JITStubThunked_##op) "\n" \
1125         ".set nomacro" "\n" \
1126         "bal " SYMBOL_STRING(JITStubThunked_##op) "\n" \
1127         "nop" "\n" \
1128         "lw    $31," STRINGIZE_VALUE_OF(THUNK_RETURN_ADDRESS_OFFSET) "($29)" "\n" \
1129         "jr    $31" "\n" \
1130         "nop" "\n" \
1131         ".set reorder" "\n" \
1132         ".set macro" "\n" \
1133         ".end " SYMBOL_STRING(cti_##op) "\n" \
1134         ); \
1135     rtype JITStubThunked_##op(STUB_ARGS_DECLARATION)
1136
1137 #else // WTF_MIPS_PIC
1138 #define DEFINE_STUB_FUNCTION(rtype, op) \
1139     extern "C" { \
1140         rtype JITStubThunked_##op(STUB_ARGS_DECLARATION); \
1141     }; \
1142     asm volatile( \
1143         ".text" "\n" \
1144         ".align 2" "\n" \
1145         ".set noreorder" "\n" \
1146         ".set nomacro" "\n" \
1147         ".set nomips16" "\n" \
1148         ".globl " SYMBOL_STRING(cti_##op) "\n" \
1149         ".ent " SYMBOL_STRING(cti_##op) "\n" \
1150         SYMBOL_STRING(cti_##op) ":" "\n" \
1151         "sw    $31," STRINGIZE_VALUE_OF(THUNK_RETURN_ADDRESS_OFFSET) "($29)" "\n" \
1152         "jal " SYMBOL_STRING(JITStubThunked_##op) "\n" \
1153         "nop" "\n" \
1154         "lw    $31," STRINGIZE_VALUE_OF(THUNK_RETURN_ADDRESS_OFFSET) "($29)" "\n" \
1155         "jr    $31" "\n" \
1156         "nop" "\n" \
1157         ".set reorder" "\n" \
1158         ".set macro" "\n" \
1159         ".end " SYMBOL_STRING(cti_##op) "\n" \
1160         ); \
1161     rtype JITStubThunked_##op(STUB_ARGS_DECLARATION)
1162
1163 #endif
1164
1165 #elif CPU(ARM_TRADITIONAL) && COMPILER(GCC)
1166
1167 #define DEFINE_STUB_FUNCTION(rtype, op) \
1168     extern "C" { \
1169         rtype JITStubThunked_##op(STUB_ARGS_DECLARATION); \
1170     }; \
1171     asm ( \
1172         ".globl " SYMBOL_STRING(cti_##op) "\n" \
1173         SYMBOL_STRING(cti_##op) ":" "\n" \
1174         "str lr, [sp, #" STRINGIZE_VALUE_OF(THUNK_RETURN_ADDRESS_OFFSET) "]" "\n" \
1175         "bl " SYMBOL_STRING(JITStubThunked_##op) "\n" \
1176         "ldr lr, [sp, #" STRINGIZE_VALUE_OF(THUNK_RETURN_ADDRESS_OFFSET) "]" "\n" \
1177         "mov pc, lr" "\n" \
1178         ); \
1179     rtype JITStubThunked_##op(STUB_ARGS_DECLARATION)
1180
1181 #elif CPU(ARM_TRADITIONAL) && COMPILER(RVCT)
1182
1183 #define DEFINE_STUB_FUNCTION(rtype, op) rtype JITStubThunked_##op(STUB_ARGS_DECLARATION)
1184
1185 /* The following is a workaround for RVCT toolchain; precompiler macros are not expanded before the code is passed to the assembler */
1186
1187 /* The following section is a template to generate code for GeneratedJITStubs_RVCT.h */
1188 /* The pattern "#xxx#" will be replaced with "xxx" */
1189
1190 /*
1191 RVCT(extern "C" #rtype# JITStubThunked_#op#(STUB_ARGS_DECLARATION);)
1192 RVCT(__asm #rtype# cti_#op#(STUB_ARGS_DECLARATION))
1193 RVCT({)
1194 RVCT(    ARM)
1195 RVCT(    IMPORT JITStubThunked_#op#)
1196 RVCT(    str lr, [sp, # THUNK_RETURN_ADDRESS_OFFSET])
1197 RVCT(    bl JITStubThunked_#op#)
1198 RVCT(    ldr lr, [sp, # THUNK_RETURN_ADDRESS_OFFSET])
1199 RVCT(    bx lr)
1200 RVCT(})
1201 RVCT()
1202 */
1203
1204 /* Include the generated file */
1205 #include "GeneratedJITStubs_RVCT.h"
1206
1207 #elif CPU(ARM_TRADITIONAL) && COMPILER(MSVC)
1208
1209 #define DEFINE_STUB_FUNCTION(rtype, op) extern "C" rtype JITStubThunked_##op(STUB_ARGS_DECLARATION)
1210
1211 /* The following is a workaround for MSVC toolchain; inline assembler is not supported */
1212
1213 /* The following section is a template to generate code for GeneratedJITStubs_MSVC.asm */
1214 /* The pattern "#xxx#" will be replaced with "xxx" */
1215
1216 /*
1217 MSVC_BEGIN(    AREA Trampoline, CODE)
1218 MSVC_BEGIN()
1219 MSVC_BEGIN(    EXPORT ctiTrampoline)
1220 MSVC_BEGIN(    EXPORT ctiVMThrowTrampoline)
1221 MSVC_BEGIN(    EXPORT ctiOpThrowNotCaught)
1222 MSVC_BEGIN()
1223 MSVC_BEGIN(ctiTrampoline PROC)
1224 MSVC_BEGIN(    stmdb sp!, {r1-r3})
1225 MSVC_BEGIN(    stmdb sp!, {r4-r8, lr})
1226 MSVC_BEGIN(    sub sp, sp, # THUNK_RETURN_ADDRESS_OFFSET + 4)
1227 MSVC_BEGIN(    mov r4, r2)
1228 MSVC_BEGIN(    mov r5, #512)
1229 MSVC_BEGIN(    ; r0 contains the code)
1230 MSVC_BEGIN(    mov lr, pc)
1231 MSVC_BEGIN(    bx r0)
1232 MSVC_BEGIN(    add sp, sp, # THUNK_RETURN_ADDRESS_OFFSET + 4)
1233 MSVC_BEGIN(    ldmia sp!, {r4-r8, lr})
1234 MSVC_BEGIN(    add sp, sp, #12)
1235 MSVC_BEGIN(    bx lr)
1236 MSVC_BEGIN(ctiTrampoline ENDP)
1237 MSVC_BEGIN()
1238 MSVC_BEGIN(ctiVMThrowTrampoline PROC)
1239 MSVC_BEGIN(    mov r0, sp)
1240 MSVC_BEGIN(    mov lr, pc)
1241 MSVC_BEGIN(    bl cti_vm_throw)
1242 MSVC_BEGIN(ctiOpThrowNotCaught)
1243 MSVC_BEGIN(    add sp, sp, # THUNK_RETURN_ADDRESS_OFFSET + 4)
1244 MSVC_BEGIN(    ldmia sp!, {r4-r8, lr})
1245 MSVC_BEGIN(    add sp, sp, #12)
1246 MSVC_BEGIN(    bx lr)
1247 MSVC_BEGIN(ctiVMThrowTrampoline ENDP)
1248 MSVC_BEGIN()
1249
1250 MSVC(    EXPORT cti_#op#)
1251 MSVC(    IMPORT JITStubThunked_#op#)
1252 MSVC(cti_#op# PROC)
1253 MSVC(    str lr, [sp, # THUNK_RETURN_ADDRESS_OFFSET])
1254 MSVC(    bl JITStubThunked_#op#)
1255 MSVC(    ldr lr, [sp, # THUNK_RETURN_ADDRESS_OFFSET])
1256 MSVC(    bx lr)
1257 MSVC(cti_#op# ENDP)
1258 MSVC()
1259
1260 MSVC_END(    END)
1261 */
1262
1263 #else
1264 #define DEFINE_STUB_FUNCTION(rtype, op) rtype JIT_STUB cti_##op(STUB_ARGS_DECLARATION)
1265 #endif
1266
1267 DEFINE_STUB_FUNCTION(EncodedJSValue, op_create_this)
1268 {
1269     STUB_INIT_STACK_FRAME(stackFrame);
1270     CallFrame* callFrame = stackFrame.callFrame;
1271
1272     JSFunction* constructor = asFunction(callFrame->callee());
1273 #if !ASSERT_DISABLED
1274     ConstructData constructData;
1275     ASSERT(constructor->getConstructData(constructData) == ConstructTypeJS);
1276 #endif
1277
1278     Structure* structure;
1279     JSValue proto = stackFrame.args[0].jsValue();
1280     if (proto.isObject())
1281         structure = asObject(proto)->inheritorID();
1282     else
1283         structure = constructor->scope().node()->globalObject->emptyObjectStructure();
1284     JSValue result = new (&callFrame->globalData()) JSObject(structure);
1285
1286     return JSValue::encode(result);
1287 }
1288
1289 DEFINE_STUB_FUNCTION(EncodedJSValue, op_convert_this)
1290 {
1291     STUB_INIT_STACK_FRAME(stackFrame);
1292
1293     JSValue v1 = stackFrame.args[0].jsValue();
1294     CallFrame* callFrame = stackFrame.callFrame;
1295
1296     JSObject* result = v1.toThisObject(callFrame);
1297     CHECK_FOR_EXCEPTION_AT_END();
1298     return JSValue::encode(result);
1299 }
1300
1301 DEFINE_STUB_FUNCTION(EncodedJSValue, op_convert_this_strict)
1302 {
1303     STUB_INIT_STACK_FRAME(stackFrame);
1304     
1305     JSValue v1 = stackFrame.args[0].jsValue();
1306     CallFrame* callFrame = stackFrame.callFrame;
1307
1308     JSValue result = v1.toStrictThisObject(callFrame);
1309     CHECK_FOR_EXCEPTION_AT_END();
1310     return JSValue::encode(result);
1311 }
1312
1313 DEFINE_STUB_FUNCTION(void, op_end)
1314 {
1315     STUB_INIT_STACK_FRAME(stackFrame);
1316
1317     ScopeChainNode* scopeChain = stackFrame.callFrame->scopeChain();
1318     ASSERT(scopeChain->refCount > 1);
1319     scopeChain->deref();
1320 }
1321
1322 DEFINE_STUB_FUNCTION(EncodedJSValue, op_add)
1323 {
1324     STUB_INIT_STACK_FRAME(stackFrame);
1325
1326     JSValue v1 = stackFrame.args[0].jsValue();
1327     JSValue v2 = stackFrame.args[1].jsValue();
1328     CallFrame* callFrame = stackFrame.callFrame;
1329
1330     if (v1.isString()) {
1331         JSValue result = v2.isString()
1332             ? jsString(callFrame, asString(v1), asString(v2))
1333             : jsString(callFrame, asString(v1), v2.toPrimitiveString(callFrame));
1334         CHECK_FOR_EXCEPTION_AT_END();
1335         return JSValue::encode(result);
1336     }
1337
1338     double left = 0.0, right;
1339     if (v1.getNumber(left) && v2.getNumber(right))
1340         return JSValue::encode(jsNumber(left + right));
1341
1342     // All other cases are pretty uncommon
1343     JSValue result = jsAddSlowCase(callFrame, v1, v2);
1344     CHECK_FOR_EXCEPTION_AT_END();
1345     return JSValue::encode(result);
1346 }
1347
1348 DEFINE_STUB_FUNCTION(EncodedJSValue, op_pre_inc)
1349 {
1350     STUB_INIT_STACK_FRAME(stackFrame);
1351
1352     JSValue v = stackFrame.args[0].jsValue();
1353
1354     CallFrame* callFrame = stackFrame.callFrame;
1355     JSValue result = jsNumber(v.toNumber(callFrame) + 1);
1356     CHECK_FOR_EXCEPTION_AT_END();
1357     return JSValue::encode(result);
1358 }
1359
1360 DEFINE_STUB_FUNCTION(int, timeout_check)
1361 {
1362     STUB_INIT_STACK_FRAME(stackFrame);
1363
1364     JSGlobalData* globalData = stackFrame.globalData;
1365     TimeoutChecker& timeoutChecker = globalData->timeoutChecker;
1366
1367     if (globalData->terminator.shouldTerminate()) {
1368         globalData->exception = createTerminatedExecutionException(globalData);
1369         VM_THROW_EXCEPTION_AT_END();
1370     } else if (timeoutChecker.didTimeOut(stackFrame.callFrame)) {
1371         globalData->exception = createInterruptedExecutionException(globalData);
1372         VM_THROW_EXCEPTION_AT_END();
1373     }
1374
1375     return timeoutChecker.ticksUntilNextCheck();
1376 }
1377
1378 DEFINE_STUB_FUNCTION(void*, register_file_check)
1379 {
1380     STUB_INIT_STACK_FRAME(stackFrame);
1381     CallFrame* callFrame = stackFrame.callFrame;
1382
1383     if (UNLIKELY(!stackFrame.registerFile->grow(&callFrame->registers()[callFrame->codeBlock()->m_numCalleeRegisters]))) {
1384         // Rewind to the previous call frame because op_call already optimistically
1385         // moved the call frame forward.
1386         CallFrame* oldCallFrame = callFrame->callerFrame();
1387         ExceptionHandler handler = jitThrow(stackFrame.globalData, oldCallFrame, createStackOverflowError(oldCallFrame), ReturnAddressPtr(oldCallFrame->returnPC()), false);
1388         STUB_SET_RETURN_ADDRESS(handler.catchRoutine);
1389         callFrame = handler.callFrame;
1390     }
1391
1392     return callFrame;
1393 }
1394
1395 DEFINE_STUB_FUNCTION(int, op_loop_if_lesseq)
1396 {
1397     STUB_INIT_STACK_FRAME(stackFrame);
1398
1399     JSValue src1 = stackFrame.args[0].jsValue();
1400     JSValue src2 = stackFrame.args[1].jsValue();
1401     CallFrame* callFrame = stackFrame.callFrame;
1402
1403     bool result = jsLessEq(callFrame, src1, src2);
1404     CHECK_FOR_EXCEPTION_AT_END();
1405     return result;
1406 }
1407
1408 DEFINE_STUB_FUNCTION(JSObject*, op_new_object)
1409 {
1410     STUB_INIT_STACK_FRAME(stackFrame);
1411
1412     return constructEmptyObject(stackFrame.callFrame);
1413 }
1414
1415 DEFINE_STUB_FUNCTION(void, op_put_by_id_generic)
1416 {
1417     STUB_INIT_STACK_FRAME(stackFrame);
1418
1419     PutPropertySlot slot(stackFrame.callFrame->codeBlock()->isStrictMode());
1420     stackFrame.args[0].jsValue().put(stackFrame.callFrame, stackFrame.args[1].identifier(), stackFrame.args[2].jsValue(), slot);
1421     CHECK_FOR_EXCEPTION_AT_END();
1422 }
1423
1424 DEFINE_STUB_FUNCTION(void, op_put_by_id_direct_generic)
1425 {
1426     STUB_INIT_STACK_FRAME(stackFrame);
1427     
1428     PutPropertySlot slot(stackFrame.callFrame->codeBlock()->isStrictMode());
1429     stackFrame.args[0].jsValue().putDirect(stackFrame.callFrame, stackFrame.args[1].identifier(), stackFrame.args[2].jsValue(), slot);
1430     CHECK_FOR_EXCEPTION_AT_END();
1431 }
1432
1433 DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_id_generic)
1434 {
1435     STUB_INIT_STACK_FRAME(stackFrame);
1436
1437     CallFrame* callFrame = stackFrame.callFrame;
1438     Identifier& ident = stackFrame.args[1].identifier();
1439
1440     JSValue baseValue = stackFrame.args[0].jsValue();
1441     PropertySlot slot(baseValue);
1442     JSValue result = baseValue.get(callFrame, ident, slot);
1443
1444     CHECK_FOR_EXCEPTION_AT_END();
1445     return JSValue::encode(result);
1446 }
1447
1448 #if ENABLE(JIT_OPTIMIZE_PROPERTY_ACCESS)
1449
1450 DEFINE_STUB_FUNCTION(void, op_put_by_id)
1451 {
1452     STUB_INIT_STACK_FRAME(stackFrame);
1453     CallFrame* callFrame = stackFrame.callFrame;
1454     Identifier& ident = stackFrame.args[1].identifier();
1455     
1456     PutPropertySlot slot(callFrame->codeBlock()->isStrictMode());
1457     stackFrame.args[0].jsValue().put(callFrame, ident, stackFrame.args[2].jsValue(), slot);
1458     
1459     CodeBlock* codeBlock = stackFrame.callFrame->codeBlock();
1460     StructureStubInfo* stubInfo = &codeBlock->getStubInfo(STUB_RETURN_ADDRESS);
1461     if (!stubInfo->seenOnce())
1462         stubInfo->setSeen();
1463     else
1464         JITThunks::tryCachePutByID(callFrame, codeBlock, STUB_RETURN_ADDRESS, stackFrame.args[0].jsValue(), slot, stubInfo, false);
1465     
1466     CHECK_FOR_EXCEPTION_AT_END();
1467 }
1468
1469 DEFINE_STUB_FUNCTION(void, op_put_by_id_direct)
1470 {
1471     STUB_INIT_STACK_FRAME(stackFrame);
1472     CallFrame* callFrame = stackFrame.callFrame;
1473     Identifier& ident = stackFrame.args[1].identifier();
1474     
1475     PutPropertySlot slot(callFrame->codeBlock()->isStrictMode());
1476     stackFrame.args[0].jsValue().putDirect(callFrame, ident, stackFrame.args[2].jsValue(), slot);
1477     
1478     CodeBlock* codeBlock = stackFrame.callFrame->codeBlock();
1479     StructureStubInfo* stubInfo = &codeBlock->getStubInfo(STUB_RETURN_ADDRESS);
1480     if (!stubInfo->seenOnce())
1481         stubInfo->setSeen();
1482     else
1483         JITThunks::tryCachePutByID(callFrame, codeBlock, STUB_RETURN_ADDRESS, stackFrame.args[0].jsValue(), slot, stubInfo, true);
1484     
1485     CHECK_FOR_EXCEPTION_AT_END();
1486 }
1487
1488 DEFINE_STUB_FUNCTION(void, op_put_by_id_fail)
1489 {
1490     STUB_INIT_STACK_FRAME(stackFrame);
1491
1492     CallFrame* callFrame = stackFrame.callFrame;
1493     Identifier& ident = stackFrame.args[1].identifier();
1494     
1495     PutPropertySlot slot(callFrame->codeBlock()->isStrictMode());
1496     stackFrame.args[0].jsValue().put(callFrame, ident, stackFrame.args[2].jsValue(), slot);
1497
1498     CHECK_FOR_EXCEPTION_AT_END();
1499 }
1500
1501 DEFINE_STUB_FUNCTION(void, op_put_by_id_direct_fail)
1502 {
1503     STUB_INIT_STACK_FRAME(stackFrame);
1504     
1505     CallFrame* callFrame = stackFrame.callFrame;
1506     Identifier& ident = stackFrame.args[1].identifier();
1507     
1508     PutPropertySlot slot(callFrame->codeBlock()->isStrictMode());
1509     stackFrame.args[0].jsValue().putDirect(callFrame, ident, stackFrame.args[2].jsValue(), slot);
1510     
1511     CHECK_FOR_EXCEPTION_AT_END();
1512 }
1513
1514 DEFINE_STUB_FUNCTION(JSObject*, op_put_by_id_transition_realloc)
1515 {
1516     STUB_INIT_STACK_FRAME(stackFrame);
1517
1518     JSValue baseValue = stackFrame.args[0].jsValue();
1519     int32_t oldSize = stackFrame.args[3].int32();
1520     int32_t newSize = stackFrame.args[4].int32();
1521
1522     ASSERT(baseValue.isObject());
1523     JSObject* base = asObject(baseValue);
1524     base->allocatePropertyStorage(oldSize, newSize);
1525
1526     return base;
1527 }
1528
1529 DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_id_method_check)
1530 {
1531     STUB_INIT_STACK_FRAME(stackFrame);
1532
1533     CallFrame* callFrame = stackFrame.callFrame;
1534     Identifier& ident = stackFrame.args[1].identifier();
1535
1536     JSValue baseValue = stackFrame.args[0].jsValue();
1537     PropertySlot slot(baseValue);
1538     JSValue result = baseValue.get(callFrame, ident, slot);
1539     CHECK_FOR_EXCEPTION();
1540
1541     CodeBlock* codeBlock = stackFrame.callFrame->codeBlock();
1542     MethodCallLinkInfo& methodCallLinkInfo = codeBlock->getMethodCallLinkInfo(STUB_RETURN_ADDRESS);
1543
1544     if (!methodCallLinkInfo.seenOnce()) {
1545         methodCallLinkInfo.setSeen();
1546         return JSValue::encode(result);
1547     }
1548
1549     // If we successfully got something, then the base from which it is being accessed must
1550     // be an object.  (Assertion to ensure asObject() call below is safe, which comes after
1551     // an isCacheable() chceck.
1552     ASSERT(!slot.isCacheableValue() || slot.slotBase().isObject());
1553
1554     // Check that:
1555     //   * We're dealing with a JSCell,
1556     //   * the property is cachable,
1557     //   * it's not a dictionary
1558     //   * there is a function cached.
1559     Structure* structure;
1560     JSCell* specific;
1561     JSObject* slotBaseObject;
1562     if (baseValue.isCell()
1563         && slot.isCacheableValue()
1564         && !(structure = baseValue.asCell()->structure())->isUncacheableDictionary()
1565         && (slotBaseObject = asObject(slot.slotBase()))->getPropertySpecificValue(callFrame, ident, specific)
1566         && specific
1567         ) {
1568
1569         JSFunction* callee = (JSFunction*)specific;
1570
1571         // Since we're accessing a prototype in a loop, it's a good bet that it
1572         // should not be treated as a dictionary.
1573         if (slotBaseObject->structure()->isDictionary())
1574             slotBaseObject->flattenDictionaryObject();
1575
1576         // The result fetched should always be the callee!
1577         ASSERT(result == JSValue(callee));
1578
1579         // Check to see if the function is on the object's prototype.  Patch up the code to optimize.
1580         if (slot.slotBase() == structure->prototypeForLookup(callFrame)) {
1581             JIT::patchMethodCallProto(codeBlock, methodCallLinkInfo, callee, structure, slotBaseObject, STUB_RETURN_ADDRESS);
1582             return JSValue::encode(result);
1583         }
1584
1585         // Check to see if the function is on the object itself.
1586         // Since we generate the method-check to check both the structure and a prototype-structure (since this
1587         // is the common case) we have a problem - we need to patch the prototype structure check to do something
1588         // useful.  We could try to nop it out altogether, but that's a little messy, so lets do something simpler
1589         // for now.  For now it performs a check on a special object on the global object only used for this
1590         // purpose.  The object is in no way exposed, and as such the check will always pass.
1591         if (slot.slotBase() == baseValue) {
1592             JIT::patchMethodCallProto(codeBlock, methodCallLinkInfo, callee, structure, callFrame->scopeChain()->globalObject->methodCallDummy(), STUB_RETURN_ADDRESS);
1593             return JSValue::encode(result);
1594         }
1595     }
1596
1597     // Revert the get_by_id op back to being a regular get_by_id - allow it to cache like normal, if it needs to.
1598     ctiPatchCallByReturnAddress(codeBlock, STUB_RETURN_ADDRESS, FunctionPtr(cti_op_get_by_id));
1599     return JSValue::encode(result);
1600 }
1601
1602 DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_id)
1603 {
1604     STUB_INIT_STACK_FRAME(stackFrame);
1605     CallFrame* callFrame = stackFrame.callFrame;
1606     Identifier& ident = stackFrame.args[1].identifier();
1607
1608     JSValue baseValue = stackFrame.args[0].jsValue();
1609     PropertySlot slot(baseValue);
1610     JSValue result = baseValue.get(callFrame, ident, slot);
1611
1612     CodeBlock* codeBlock = stackFrame.callFrame->codeBlock();
1613     StructureStubInfo* stubInfo = &codeBlock->getStubInfo(STUB_RETURN_ADDRESS);
1614     if (!stubInfo->seenOnce())
1615         stubInfo->setSeen();
1616     else
1617         JITThunks::tryCacheGetByID(callFrame, codeBlock, STUB_RETURN_ADDRESS, baseValue, ident, slot, stubInfo);
1618
1619     CHECK_FOR_EXCEPTION_AT_END();
1620     return JSValue::encode(result);
1621 }
1622
1623 DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_id_self_fail)
1624 {
1625     STUB_INIT_STACK_FRAME(stackFrame);
1626
1627     CallFrame* callFrame = stackFrame.callFrame;
1628     Identifier& ident = stackFrame.args[1].identifier();
1629
1630     JSValue baseValue = stackFrame.args[0].jsValue();
1631     PropertySlot slot(baseValue);
1632     JSValue result = baseValue.get(callFrame, ident, slot);
1633
1634     CHECK_FOR_EXCEPTION();
1635
1636     if (baseValue.isCell()
1637         && slot.isCacheable()
1638         && !baseValue.asCell()->structure()->isUncacheableDictionary()
1639         && slot.slotBase() == baseValue) {
1640
1641         CodeBlock* codeBlock = callFrame->codeBlock();
1642         StructureStubInfo* stubInfo = &codeBlock->getStubInfo(STUB_RETURN_ADDRESS);
1643
1644         ASSERT(slot.slotBase().isObject());
1645
1646         PolymorphicAccessStructureList* polymorphicStructureList;
1647         int listIndex = 1;
1648
1649         if (stubInfo->accessType == access_get_by_id_self) {
1650             ASSERT(!stubInfo->stubRoutine);
1651             polymorphicStructureList = new PolymorphicAccessStructureList(CodeLocationLabel(), stubInfo->u.getByIdSelf.baseObjectStructure);
1652             stubInfo->initGetByIdSelfList(polymorphicStructureList, 1);
1653         } else {
1654             polymorphicStructureList = stubInfo->u.getByIdSelfList.structureList;
1655             listIndex = stubInfo->u.getByIdSelfList.listSize;
1656         }
1657         if (listIndex < POLYMORPHIC_LIST_CACHE_SIZE) {
1658             stubInfo->u.getByIdSelfList.listSize++;
1659             JIT::compileGetByIdSelfList(callFrame->scopeChain()->globalData, codeBlock, stubInfo, polymorphicStructureList, listIndex, baseValue.asCell()->structure(), ident, slot, slot.cachedOffset());
1660
1661             if (listIndex == (POLYMORPHIC_LIST_CACHE_SIZE - 1))
1662                 ctiPatchCallByReturnAddress(codeBlock, STUB_RETURN_ADDRESS, FunctionPtr(cti_op_get_by_id_generic));
1663         }
1664     } else
1665         ctiPatchCallByReturnAddress(callFrame->codeBlock(), STUB_RETURN_ADDRESS, FunctionPtr(cti_op_get_by_id_generic));
1666     return JSValue::encode(result);
1667 }
1668
1669 static PolymorphicAccessStructureList* getPolymorphicAccessStructureListSlot(StructureStubInfo* stubInfo, int& listIndex)
1670 {
1671     PolymorphicAccessStructureList* prototypeStructureList = 0;
1672     listIndex = 1;
1673
1674     switch (stubInfo->accessType) {
1675     case access_get_by_id_proto:
1676         prototypeStructureList = new PolymorphicAccessStructureList(stubInfo->stubRoutine, stubInfo->u.getByIdProto.baseObjectStructure, stubInfo->u.getByIdProto.prototypeStructure);
1677         stubInfo->stubRoutine = CodeLocationLabel();
1678         stubInfo->initGetByIdProtoList(prototypeStructureList, 2);
1679         break;
1680     case access_get_by_id_chain:
1681         prototypeStructureList = new PolymorphicAccessStructureList(stubInfo->stubRoutine, stubInfo->u.getByIdChain.baseObjectStructure, stubInfo->u.getByIdChain.chain);
1682         stubInfo->stubRoutine = CodeLocationLabel();
1683         stubInfo->initGetByIdProtoList(prototypeStructureList, 2);
1684         break;
1685     case access_get_by_id_proto_list:
1686         prototypeStructureList = stubInfo->u.getByIdProtoList.structureList;
1687         listIndex = stubInfo->u.getByIdProtoList.listSize;
1688         if (listIndex < POLYMORPHIC_LIST_CACHE_SIZE)
1689             stubInfo->u.getByIdProtoList.listSize++;
1690         break;
1691     default:
1692         ASSERT_NOT_REACHED();
1693     }
1694     
1695     ASSERT(listIndex <= POLYMORPHIC_LIST_CACHE_SIZE);
1696     return prototypeStructureList;
1697 }
1698
1699 DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_id_getter_stub)
1700 {
1701     STUB_INIT_STACK_FRAME(stackFrame);
1702     CallFrame* callFrame = stackFrame.callFrame;
1703     GetterSetter* getterSetter = asGetterSetter(stackFrame.args[0].jsObject());
1704     if (!getterSetter->getter())
1705         return JSValue::encode(jsUndefined());
1706     JSObject* getter = asObject(getterSetter->getter());
1707     CallData callData;
1708     CallType callType = getter->getCallData(callData);
1709     JSValue result = call(callFrame, getter, callType, callData, stackFrame.args[1].jsObject(), ArgList());
1710     if (callFrame->hadException())
1711         returnToThrowTrampoline(&callFrame->globalData(), stackFrame.args[2].returnAddress(), STUB_RETURN_ADDRESS);
1712
1713     return JSValue::encode(result);
1714 }
1715
1716 DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_id_custom_stub)
1717 {
1718     STUB_INIT_STACK_FRAME(stackFrame);
1719     CallFrame* callFrame = stackFrame.callFrame;
1720     JSObject* slotBase = stackFrame.args[0].jsObject();
1721     PropertySlot::GetValueFunc getter = reinterpret_cast<PropertySlot::GetValueFunc>(stackFrame.args[1].asPointer);
1722     const Identifier& ident = stackFrame.args[2].identifier();
1723     JSValue result = getter(callFrame, slotBase, ident);
1724     if (callFrame->hadException())
1725         returnToThrowTrampoline(&callFrame->globalData(), stackFrame.args[3].returnAddress(), STUB_RETURN_ADDRESS);
1726     
1727     return JSValue::encode(result);
1728 }
1729
1730 DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_id_proto_list)
1731 {
1732     STUB_INIT_STACK_FRAME(stackFrame);
1733
1734     CallFrame* callFrame = stackFrame.callFrame;
1735     const Identifier& propertyName = stackFrame.args[1].identifier();
1736
1737     JSValue baseValue = stackFrame.args[0].jsValue();
1738     PropertySlot slot(baseValue);
1739     JSValue result = baseValue.get(callFrame, propertyName, slot);
1740
1741     CHECK_FOR_EXCEPTION();
1742
1743     if (!baseValue.isCell() || !slot.isCacheable() || baseValue.asCell()->structure()->isDictionary()) {
1744         ctiPatchCallByReturnAddress(callFrame->codeBlock(), STUB_RETURN_ADDRESS, FunctionPtr(cti_op_get_by_id_proto_fail));
1745         return JSValue::encode(result);
1746     }
1747
1748     Structure* structure = baseValue.asCell()->structure();
1749     CodeBlock* codeBlock = callFrame->codeBlock();
1750     StructureStubInfo* stubInfo = &codeBlock->getStubInfo(STUB_RETURN_ADDRESS);
1751
1752     ASSERT(slot.slotBase().isObject());
1753     JSObject* slotBaseObject = asObject(slot.slotBase());
1754     
1755     size_t offset = slot.cachedOffset();
1756
1757     if (slot.slotBase() == baseValue)
1758         ctiPatchCallByReturnAddress(codeBlock, STUB_RETURN_ADDRESS, FunctionPtr(cti_op_get_by_id_proto_fail));
1759     else if (slot.slotBase() == baseValue.asCell()->structure()->prototypeForLookup(callFrame)) {
1760         ASSERT(!baseValue.asCell()->structure()->isDictionary());
1761         // Since we're accessing a prototype in a loop, it's a good bet that it
1762         // should not be treated as a dictionary.
1763         if (slotBaseObject->structure()->isDictionary()) {
1764             slotBaseObject->flattenDictionaryObject();
1765             offset = slotBaseObject->structure()->get(propertyName);
1766         }
1767
1768         int listIndex;
1769         PolymorphicAccessStructureList* prototypeStructureList = getPolymorphicAccessStructureListSlot(stubInfo, listIndex);
1770         if (listIndex < POLYMORPHIC_LIST_CACHE_SIZE) {
1771             JIT::compileGetByIdProtoList(callFrame->scopeChain()->globalData, callFrame, codeBlock, stubInfo, prototypeStructureList, listIndex, structure, slotBaseObject->structure(), propertyName, slot, offset);
1772
1773             if (listIndex == (POLYMORPHIC_LIST_CACHE_SIZE - 1))
1774                 ctiPatchCallByReturnAddress(codeBlock, STUB_RETURN_ADDRESS, FunctionPtr(cti_op_get_by_id_proto_list_full));
1775         }
1776     } else if (size_t count = normalizePrototypeChain(callFrame, baseValue, slot.slotBase(), propertyName, offset)) {
1777         ASSERT(!baseValue.asCell()->structure()->isDictionary());
1778         int listIndex;
1779         PolymorphicAccessStructureList* prototypeStructureList = getPolymorphicAccessStructureListSlot(stubInfo, listIndex);
1780         
1781         if (listIndex < POLYMORPHIC_LIST_CACHE_SIZE) {
1782             StructureChain* protoChain = structure->prototypeChain(callFrame);
1783             JIT::compileGetByIdChainList(callFrame->scopeChain()->globalData, callFrame, codeBlock, stubInfo, prototypeStructureList, listIndex, structure, protoChain, count, propertyName, slot, offset);
1784
1785             if (listIndex == (POLYMORPHIC_LIST_CACHE_SIZE - 1))
1786                 ctiPatchCallByReturnAddress(codeBlock, STUB_RETURN_ADDRESS, FunctionPtr(cti_op_get_by_id_proto_list_full));
1787         }
1788     } else
1789         ctiPatchCallByReturnAddress(codeBlock, STUB_RETURN_ADDRESS, FunctionPtr(cti_op_get_by_id_proto_fail));
1790
1791     return JSValue::encode(result);
1792 }
1793
1794 DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_id_proto_list_full)
1795 {
1796     STUB_INIT_STACK_FRAME(stackFrame);
1797
1798     JSValue baseValue = stackFrame.args[0].jsValue();
1799     PropertySlot slot(baseValue);
1800     JSValue result = baseValue.get(stackFrame.callFrame, stackFrame.args[1].identifier(), slot);
1801
1802     CHECK_FOR_EXCEPTION_AT_END();
1803     return JSValue::encode(result);
1804 }
1805
1806 DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_id_proto_fail)
1807 {
1808     STUB_INIT_STACK_FRAME(stackFrame);
1809
1810     JSValue baseValue = stackFrame.args[0].jsValue();
1811     PropertySlot slot(baseValue);
1812     JSValue result = baseValue.get(stackFrame.callFrame, stackFrame.args[1].identifier(), slot);
1813
1814     CHECK_FOR_EXCEPTION_AT_END();
1815     return JSValue::encode(result);
1816 }
1817
1818 DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_id_array_fail)
1819 {
1820     STUB_INIT_STACK_FRAME(stackFrame);
1821
1822     JSValue baseValue = stackFrame.args[0].jsValue();
1823     PropertySlot slot(baseValue);
1824     JSValue result = baseValue.get(stackFrame.callFrame, stackFrame.args[1].identifier(), slot);
1825
1826     CHECK_FOR_EXCEPTION_AT_END();
1827     return JSValue::encode(result);
1828 }
1829
1830 DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_id_string_fail)
1831 {
1832     STUB_INIT_STACK_FRAME(stackFrame);
1833
1834     JSValue baseValue = stackFrame.args[0].jsValue();
1835     PropertySlot slot(baseValue);
1836     JSValue result = baseValue.get(stackFrame.callFrame, stackFrame.args[1].identifier(), slot);
1837
1838     CHECK_FOR_EXCEPTION_AT_END();
1839     return JSValue::encode(result);
1840 }
1841
1842 #endif // ENABLE(JIT_OPTIMIZE_PROPERTY_ACCESS)
1843
1844 DEFINE_STUB_FUNCTION(EncodedJSValue, op_instanceof)
1845 {
1846     STUB_INIT_STACK_FRAME(stackFrame);
1847
1848     CallFrame* callFrame = stackFrame.callFrame;
1849     JSValue value = stackFrame.args[0].jsValue();
1850     JSValue baseVal = stackFrame.args[1].jsValue();
1851     JSValue proto = stackFrame.args[2].jsValue();
1852
1853     // At least one of these checks must have failed to get to the slow case.
1854     ASSERT(!value.isCell() || !baseVal.isCell() || !proto.isCell()
1855            || !value.isObject() || !baseVal.isObject() || !proto.isObject() 
1856            || (asObject(baseVal)->structure()->typeInfo().flags() & (ImplementsHasInstance | OverridesHasInstance)) != ImplementsHasInstance);
1857
1858
1859     // ECMA-262 15.3.5.3:
1860     // Throw an exception either if baseVal is not an object, or if it does not implement 'HasInstance' (i.e. is a function).
1861     TypeInfo typeInfo(UnspecifiedType);
1862     if (!baseVal.isObject() || !(typeInfo = asObject(baseVal)->structure()->typeInfo()).implementsHasInstance()) {
1863         CallFrame* callFrame = stackFrame.callFrame;
1864         CodeBlock* codeBlock = callFrame->codeBlock();
1865         unsigned vPCIndex = codeBlock->bytecodeOffset(callFrame, STUB_RETURN_ADDRESS);
1866         stackFrame.globalData->exception = createInvalidParamError(callFrame, "instanceof", baseVal, vPCIndex, codeBlock);
1867         VM_THROW_EXCEPTION();
1868     }
1869     ASSERT(typeInfo.type() != UnspecifiedType);
1870
1871     if (!typeInfo.overridesHasInstance()) {
1872         if (!value.isObject())
1873             return JSValue::encode(jsBoolean(false));
1874
1875         if (!proto.isObject()) {
1876             throwError(callFrame, createTypeError(callFrame, "instanceof called on an object with an invalid prototype property."));
1877             VM_THROW_EXCEPTION();
1878         }
1879     }
1880
1881     JSValue result = jsBoolean(asObject(baseVal)->hasInstance(callFrame, value, proto));
1882     CHECK_FOR_EXCEPTION_AT_END();
1883
1884     return JSValue::encode(result);
1885 }
1886
1887 DEFINE_STUB_FUNCTION(EncodedJSValue, op_del_by_id)
1888 {
1889     STUB_INIT_STACK_FRAME(stackFrame);
1890
1891     CallFrame* callFrame = stackFrame.callFrame;
1892     
1893     JSObject* baseObj = stackFrame.args[0].jsValue().toObject(callFrame);
1894
1895     bool couldDelete = baseObj->deleteProperty(callFrame, stackFrame.args[1].identifier());
1896     JSValue result = jsBoolean(couldDelete);
1897     if (!couldDelete && callFrame->codeBlock()->isStrictMode())
1898         stackFrame.globalData->exception = createTypeError(stackFrame.callFrame, "Unable to delete property.");
1899
1900     CHECK_FOR_EXCEPTION_AT_END();
1901     return JSValue::encode(result);
1902 }
1903
1904 DEFINE_STUB_FUNCTION(EncodedJSValue, op_mul)
1905 {
1906     STUB_INIT_STACK_FRAME(stackFrame);
1907
1908     JSValue src1 = stackFrame.args[0].jsValue();
1909     JSValue src2 = stackFrame.args[1].jsValue();
1910
1911     double left;
1912     double right;
1913     if (src1.getNumber(left) && src2.getNumber(right))
1914         return JSValue::encode(jsNumber(left * right));
1915
1916     CallFrame* callFrame = stackFrame.callFrame;
1917     JSValue result = jsNumber(src1.toNumber(callFrame) * src2.toNumber(callFrame));
1918     CHECK_FOR_EXCEPTION_AT_END();
1919     return JSValue::encode(result);
1920 }
1921
1922 DEFINE_STUB_FUNCTION(JSObject*, op_new_func)
1923 {
1924     STUB_INIT_STACK_FRAME(stackFrame);
1925     
1926     ASSERT(stackFrame.callFrame->codeBlock()->codeType() != FunctionCode || !stackFrame.callFrame->codeBlock()->needsFullScopeChain() || stackFrame.callFrame->r(stackFrame.callFrame->codeBlock()->activationRegister()).jsValue());
1927     return stackFrame.args[0].function()->make(stackFrame.callFrame, stackFrame.callFrame->scopeChain());
1928 }
1929
1930 DEFINE_STUB_FUNCTION(void*, op_call_jitCompile)
1931 {
1932     STUB_INIT_STACK_FRAME(stackFrame);
1933
1934 #if !ASSERT_DISABLED
1935     CallData callData;
1936     ASSERT(stackFrame.callFrame->callee()->getCallData(callData) == CallTypeJS);
1937 #endif
1938
1939     JSFunction* function = asFunction(stackFrame.callFrame->callee());
1940     ASSERT(!function->isHostFunction());
1941     FunctionExecutable* executable = function->jsExecutable();
1942     ScopeChainNode* callDataScopeChain = function->scope().node();
1943     JSObject* error = executable->compileForCall(stackFrame.callFrame, callDataScopeChain);
1944     if (error) {
1945         stackFrame.callFrame->globalData().exception = error;
1946         return 0;
1947     }
1948     return function;
1949 }
1950
1951 DEFINE_STUB_FUNCTION(void*, op_construct_jitCompile)
1952 {
1953     STUB_INIT_STACK_FRAME(stackFrame);
1954
1955 #if !ASSERT_DISABLED
1956     ConstructData constructData;
1957     ASSERT(asFunction(stackFrame.callFrame->callee())->getConstructData(constructData) == ConstructTypeJS);
1958 #endif
1959
1960     JSFunction* function = asFunction(stackFrame.callFrame->callee());
1961     ASSERT(!function->isHostFunction());
1962     FunctionExecutable* executable = function->jsExecutable();
1963     ScopeChainNode* callDataScopeChain = function->scope().node();
1964     JSObject* error = executable->compileForConstruct(stackFrame.callFrame, callDataScopeChain);
1965     if (error) {
1966         stackFrame.callFrame->globalData().exception = error;
1967         return 0;
1968     }
1969     return function;
1970 }
1971
1972 DEFINE_STUB_FUNCTION(void*, op_call_arityCheck)
1973 {
1974     STUB_INIT_STACK_FRAME(stackFrame);
1975
1976     CallFrame* callFrame = stackFrame.callFrame;
1977     JSFunction* callee = asFunction(callFrame->callee());
1978     ASSERT(!callee->isHostFunction());
1979     CodeBlock* newCodeBlock = &callee->jsExecutable()->generatedBytecodeForCall();
1980     int argCount = callFrame->argumentCountIncludingThis();
1981     ReturnAddressPtr pc = callFrame->returnPC();
1982
1983     ASSERT(argCount != newCodeBlock->m_numParameters);
1984
1985     CallFrame* oldCallFrame = callFrame->callerFrame();
1986
1987     Register* r;
1988     if (argCount > newCodeBlock->m_numParameters) {
1989         size_t numParameters = newCodeBlock->m_numParameters;
1990         r = callFrame->registers() + numParameters;
1991         Register* newEnd = r + newCodeBlock->m_numCalleeRegisters;
1992         if (!stackFrame.registerFile->grow(newEnd)) {
1993             // Rewind to the previous call frame because op_call already optimistically
1994             // moved the call frame forward.
1995             ExceptionHandler handler = jitThrow(stackFrame.globalData, oldCallFrame, createStackOverflowError(oldCallFrame), pc, false);
1996             STUB_SET_RETURN_ADDRESS(handler.catchRoutine);
1997             return handler.callFrame;
1998         }
1999
2000         Register* argv = r - RegisterFile::CallFrameHeaderSize - numParameters - argCount;
2001         for (size_t i = 0; i < numParameters; ++i)
2002             argv[i + argCount] = argv[i];
2003     } else {
2004         size_t omittedArgCount = newCodeBlock->m_numParameters - argCount;
2005         r = callFrame->registers() + omittedArgCount;
2006         Register* newEnd = r + newCodeBlock->m_numCalleeRegisters;
2007         if (!stackFrame.registerFile->grow(newEnd)) {
2008             // Rewind to the previous call frame because op_call already optimistically
2009             // moved the call frame forward.
2010             ExceptionHandler handler = jitThrow(stackFrame.globalData, oldCallFrame, createStackOverflowError(oldCallFrame), pc, false);
2011             STUB_SET_RETURN_ADDRESS(handler.catchRoutine);
2012             return handler.callFrame;
2013         }
2014
2015         Register* argv = r - RegisterFile::CallFrameHeaderSize - omittedArgCount;
2016         for (size_t i = 0; i < omittedArgCount; ++i)
2017             argv[i] = jsUndefined();
2018     }
2019
2020     callFrame = CallFrame::create(r);
2021     callFrame->setCallerFrame(oldCallFrame);
2022     callFrame->setArgumentCountIncludingThis(argCount);
2023     callFrame->setCallee(callee);
2024     callFrame->setScopeChain(callee->scope().node());
2025     callFrame->setReturnPC(pc.value());
2026
2027     ASSERT((void*)callFrame <= stackFrame.registerFile->end());
2028     return callFrame;
2029 }
2030
2031 DEFINE_STUB_FUNCTION(void*, op_construct_arityCheck)
2032 {
2033     STUB_INIT_STACK_FRAME(stackFrame);
2034
2035     CallFrame* callFrame = stackFrame.callFrame;
2036     JSFunction* callee = asFunction(callFrame->callee());
2037     ASSERT(!callee->isHostFunction());
2038     CodeBlock* newCodeBlock = &callee->jsExecutable()->generatedBytecodeForConstruct();
2039     int argCount = callFrame->argumentCountIncludingThis();
2040     ReturnAddressPtr pc = callFrame->returnPC();
2041
2042     ASSERT(argCount != newCodeBlock->m_numParameters);
2043
2044     CallFrame* oldCallFrame = callFrame->callerFrame();
2045
2046     Register* r;
2047     if (argCount > newCodeBlock->m_numParameters) {
2048         size_t numParameters = newCodeBlock->m_numParameters;
2049         r = callFrame->registers() + numParameters;
2050         Register* newEnd = r + newCodeBlock->m_numCalleeRegisters;
2051         if (!stackFrame.registerFile->grow(newEnd)) {
2052             // Rewind to the previous call frame because op_call already optimistically
2053             // moved the call frame forward.
2054             ExceptionHandler handler = jitThrow(stackFrame.globalData, oldCallFrame, createStackOverflowError(oldCallFrame), pc, false);
2055             STUB_SET_RETURN_ADDRESS(handler.catchRoutine);
2056             return handler.callFrame;
2057         }
2058
2059         Register* argv = r - RegisterFile::CallFrameHeaderSize - numParameters - argCount;
2060         for (size_t i = 0; i < numParameters; ++i)
2061             argv[i + argCount] = argv[i];
2062     } else {
2063         size_t omittedArgCount = newCodeBlock->m_numParameters - argCount;
2064         r = callFrame->registers() + omittedArgCount;
2065         Register* newEnd = r + newCodeBlock->m_numCalleeRegisters;
2066         if (!stackFrame.registerFile->grow(newEnd)) {
2067             // Rewind to the previous call frame because op_call already optimistically
2068             // moved the call frame forward.
2069             ExceptionHandler handler = jitThrow(stackFrame.globalData, oldCallFrame, createStackOverflowError(oldCallFrame), pc, false);
2070             STUB_SET_RETURN_ADDRESS(handler.catchRoutine);
2071             return handler.callFrame;
2072         }
2073
2074         Register* argv = r - RegisterFile::CallFrameHeaderSize - omittedArgCount;
2075         for (size_t i = 0; i < omittedArgCount; ++i)
2076             argv[i] = jsUndefined();
2077     }
2078
2079     callFrame = CallFrame::create(r);
2080     callFrame->setCallerFrame(oldCallFrame);
2081     callFrame->setArgumentCountIncludingThis(argCount);
2082     callFrame->setCallee(callee);
2083     callFrame->setScopeChain(callee->scope().node());
2084     callFrame->setReturnPC(pc.value());
2085
2086     ASSERT((void*)callFrame <= stackFrame.registerFile->end());
2087     return callFrame;
2088 }
2089
2090 #if ENABLE(JIT_OPTIMIZE_CALL)
2091 DEFINE_STUB_FUNCTION(void*, vm_lazyLinkCall)
2092 {
2093     STUB_INIT_STACK_FRAME(stackFrame);
2094     CallFrame* callFrame = stackFrame.callFrame;
2095     JSFunction* callee = asFunction(callFrame->callee());
2096     ExecutableBase* executable = callee->executable();
2097
2098     MacroAssemblerCodePtr codePtr;
2099     CodeBlock* codeBlock = 0;
2100     if (executable->isHostFunction())
2101         codePtr = executable->generatedJITCodeForCall().addressForCall();
2102     else {
2103         FunctionExecutable* functionExecutable = static_cast<FunctionExecutable*>(executable);
2104         JSObject* error = functionExecutable->compileForCall(callFrame, callee->scope().node());
2105         if (error) {
2106             callFrame->globalData().exception = createStackOverflowError(callFrame);
2107             return 0;
2108         }
2109         codeBlock = &functionExecutable->generatedBytecodeForCall();
2110         if (callFrame->argumentCountIncludingThis() == static_cast<size_t>(codeBlock->m_numParameters))
2111             codePtr = functionExecutable->generatedJITCodeForCall().addressForCall();
2112         else
2113             codePtr = functionExecutable->generatedJITCodeForCallWithArityCheck();
2114     }
2115     CallLinkInfo* callLinkInfo = &stackFrame.callFrame->callerFrame()->codeBlock()->getCallLinkInfo(callFrame->returnPC());
2116
2117     if (!callLinkInfo->seenOnce())
2118         callLinkInfo->setSeen();
2119     else
2120         JIT::linkCall(callee, stackFrame.callFrame->callerFrame()->codeBlock(), codeBlock, codePtr, callLinkInfo, callFrame->argumentCountIncludingThis(), stackFrame.globalData);
2121
2122     return codePtr.executableAddress();
2123 }
2124
2125 DEFINE_STUB_FUNCTION(void*, vm_lazyLinkConstruct)
2126 {
2127     STUB_INIT_STACK_FRAME(stackFrame);
2128     CallFrame* callFrame = stackFrame.callFrame;
2129     JSFunction* callee = asFunction(callFrame->callee());
2130     ExecutableBase* executable = callee->executable();
2131
2132     MacroAssemblerCodePtr codePtr;
2133     CodeBlock* codeBlock = 0;
2134     if (executable->isHostFunction())
2135         codePtr = executable->generatedJITCodeForConstruct().addressForCall();
2136     else {
2137         FunctionExecutable* functionExecutable = static_cast<FunctionExecutable*>(executable);
2138         JSObject* error = functionExecutable->compileForConstruct(callFrame, callee->scope().node());
2139         if (error) {
2140             throwStackOverflowError(callFrame, stackFrame.globalData, ReturnAddressPtr(callFrame->returnPC()), STUB_RETURN_ADDRESS);
2141             return 0;
2142         }
2143         codeBlock = &functionExecutable->generatedBytecodeForConstruct();
2144         if (callFrame->argumentCountIncludingThis() == static_cast<size_t>(codeBlock->m_numParameters))
2145             codePtr = functionExecutable->generatedJITCodeForConstruct().addressForCall();
2146         else
2147             codePtr = functionExecutable->generatedJITCodeForConstructWithArityCheck();
2148     }
2149     CallLinkInfo* callLinkInfo = &stackFrame.callFrame->callerFrame()->codeBlock()->getCallLinkInfo(callFrame->returnPC());
2150
2151     if (!callLinkInfo->seenOnce())
2152         callLinkInfo->setSeen();
2153     else
2154         JIT::linkConstruct(callee, stackFrame.callFrame->callerFrame()->codeBlock(), codeBlock, codePtr, callLinkInfo, callFrame->argumentCountIncludingThis(), stackFrame.globalData);
2155
2156     return codePtr.executableAddress();
2157 }
2158 #endif // !ENABLE(JIT_OPTIMIZE_CALL)
2159
2160 DEFINE_STUB_FUNCTION(JSObject*, op_push_activation)
2161 {
2162     STUB_INIT_STACK_FRAME(stackFrame);
2163
2164     JSActivation* activation = new (stackFrame.globalData) JSActivation(stackFrame.callFrame, static_cast<FunctionExecutable*>(stackFrame.callFrame->codeBlock()->ownerExecutable()));
2165     stackFrame.callFrame->setScopeChain(stackFrame.callFrame->scopeChain()->copy()->push(activation));
2166     return activation;
2167 }
2168
2169 DEFINE_STUB_FUNCTION(EncodedJSValue, op_call_NotJSFunction)
2170 {
2171     STUB_INIT_STACK_FRAME(stackFrame);
2172
2173     JSValue funcVal = stackFrame.args[0].jsValue();
2174
2175     CallData callData;
2176     CallType callType = getCallData(funcVal, callData);
2177
2178     ASSERT(callType != CallTypeJS);
2179
2180     if (callType == CallTypeHost) {
2181         int registerOffset = stackFrame.args[1].int32();
2182         int argCount = stackFrame.args[2].int32();
2183         CallFrame* previousCallFrame = stackFrame.callFrame;
2184         CallFrame* callFrame = CallFrame::create(previousCallFrame->registers() + registerOffset);
2185         if (!stackFrame.registerFile->grow(callFrame->registers())) {
2186             throwStackOverflowError(previousCallFrame, stackFrame.globalData, callFrame->returnPC(), STUB_RETURN_ADDRESS);
2187             VM_THROW_EXCEPTION();
2188         }
2189
2190         callFrame->init(0, static_cast<Instruction*>((STUB_RETURN_ADDRESS).value()), previousCallFrame->scopeChain(), previousCallFrame, argCount, asObject(funcVal));
2191
2192         EncodedJSValue returnValue;
2193         {
2194             SamplingTool::HostCallRecord callRecord(CTI_SAMPLER);
2195             returnValue = callData.native.function(callFrame);
2196         }
2197
2198         CHECK_FOR_EXCEPTION_AT_END();
2199         return returnValue;
2200     }
2201
2202     ASSERT(callType == CallTypeNone);
2203
2204     CallFrame* callFrame = stackFrame.callFrame;
2205     CodeBlock* codeBlock = callFrame->codeBlock();
2206     unsigned vPCIndex = codeBlock->bytecodeOffset(callFrame, STUB_RETURN_ADDRESS);
2207     stackFrame.globalData->exception = createNotAFunctionError(stackFrame.callFrame, funcVal, vPCIndex, codeBlock);
2208     VM_THROW_EXCEPTION();
2209 }
2210
2211 DEFINE_STUB_FUNCTION(EncodedJSValue, op_create_arguments)
2212 {
2213     STUB_INIT_STACK_FRAME(stackFrame);
2214
2215     Arguments* arguments = new (stackFrame.globalData) Arguments(stackFrame.callFrame);
2216     return JSValue::encode(JSValue(arguments));
2217 }
2218
2219 DEFINE_STUB_FUNCTION(EncodedJSValue, op_create_arguments_no_params)
2220 {
2221     STUB_INIT_STACK_FRAME(stackFrame);
2222
2223     Arguments* arguments = new (stackFrame.globalData) Arguments(stackFrame.callFrame, Arguments::NoParameters);
2224     return JSValue::encode(JSValue(arguments));
2225 }
2226
2227 DEFINE_STUB_FUNCTION(void, op_tear_off_activation)
2228 {
2229     STUB_INIT_STACK_FRAME(stackFrame);
2230
2231     ASSERT(stackFrame.callFrame->codeBlock()->needsFullScopeChain());
2232     JSValue activationValue = stackFrame.args[0].jsValue();
2233     if (!activationValue) {
2234         if (JSValue v = stackFrame.args[1].jsValue()) {
2235             if (!stackFrame.callFrame->codeBlock()->isStrictMode())
2236                 asArguments(v)->copyRegisters();
2237         }
2238         return;
2239     }
2240     JSActivation* activation = asActivation(stackFrame.args[0].jsValue());
2241     activation->copyRegisters();
2242     if (JSValue v = stackFrame.args[1].jsValue()) {
2243         if (!stackFrame.callFrame->codeBlock()->isStrictMode())
2244             asArguments(v)->setActivation(activation);
2245     }
2246 }
2247
2248 DEFINE_STUB_FUNCTION(void, op_tear_off_arguments)
2249 {
2250     STUB_INIT_STACK_FRAME(stackFrame);
2251
2252     ASSERT(stackFrame.callFrame->codeBlock()->usesArguments() && !stackFrame.callFrame->codeBlock()->needsFullScopeChain());
2253     asArguments(stackFrame.args[0].jsValue())->copyRegisters();
2254 }
2255
2256 DEFINE_STUB_FUNCTION(void, op_profile_will_call)
2257 {
2258     STUB_INIT_STACK_FRAME(stackFrame);
2259
2260     ASSERT(*stackFrame.enabledProfilerReference);
2261     (*stackFrame.enabledProfilerReference)->willExecute(stackFrame.callFrame, stackFrame.args[0].jsValue());
2262 }
2263
2264 DEFINE_STUB_FUNCTION(void, op_profile_did_call)
2265 {
2266     STUB_INIT_STACK_FRAME(stackFrame);
2267
2268     ASSERT(*stackFrame.enabledProfilerReference);
2269     (*stackFrame.enabledProfilerReference)->didExecute(stackFrame.callFrame, stackFrame.args[0].jsValue());
2270 }
2271
2272 DEFINE_STUB_FUNCTION(void, op_ret_scopeChain)
2273 {
2274     STUB_INIT_STACK_FRAME(stackFrame);
2275
2276     ASSERT(stackFrame.callFrame->codeBlock()->needsFullScopeChain());
2277     stackFrame.callFrame->scopeChain()->deref();
2278 }
2279
2280 DEFINE_STUB_FUNCTION(JSObject*, op_new_array)
2281 {
2282     STUB_INIT_STACK_FRAME(stackFrame);
2283
2284     ArgList argList(&stackFrame.callFrame->registers()[stackFrame.args[0].int32()], stackFrame.args[1].int32());
2285     return constructArray(stackFrame.callFrame, argList);
2286 }
2287
2288 DEFINE_STUB_FUNCTION(EncodedJSValue, op_resolve)
2289 {
2290     STUB_INIT_STACK_FRAME(stackFrame);
2291
2292     CallFrame* callFrame = stackFrame.callFrame;
2293     ScopeChainNode* scopeChain = callFrame->scopeChain();
2294
2295     ScopeChainIterator iter = scopeChain->begin();
2296     ScopeChainIterator end = scopeChain->end();
2297     ASSERT(iter != end);
2298
2299     Identifier& ident = stackFrame.args[0].identifier();
2300     do {
2301         JSObject* o = *iter;
2302         PropertySlot slot(o);
2303         if (o->getPropertySlot(callFrame, ident, slot)) {
2304             JSValue result = slot.getValue(callFrame, ident);
2305             CHECK_FOR_EXCEPTION_AT_END();
2306             return JSValue::encode(result);
2307         }
2308     } while (++iter != end);
2309
2310     CodeBlock* codeBlock = callFrame->codeBlock();
2311     unsigned vPCIndex = codeBlock->bytecodeOffset(callFrame, STUB_RETURN_ADDRESS);
2312     stackFrame.globalData->exception = createUndefinedVariableError(callFrame, ident, vPCIndex, codeBlock);
2313     VM_THROW_EXCEPTION();
2314 }
2315
2316 DEFINE_STUB_FUNCTION(EncodedJSValue, op_construct_NotJSConstruct)
2317 {
2318     STUB_INIT_STACK_FRAME(stackFrame);
2319
2320     JSValue constrVal = stackFrame.args[0].jsValue();
2321
2322     ConstructData constructData;
2323     ConstructType constructType = getConstructData(constrVal, constructData);
2324
2325     ASSERT(constructType != ConstructTypeJS);
2326
2327     if (constructType == ConstructTypeHost) {
2328         int registerOffset = stackFrame.args[1].int32();
2329         int argCount = stackFrame.args[2].int32();
2330         CallFrame* previousCallFrame = stackFrame.callFrame;
2331         CallFrame* callFrame = CallFrame::create(previousCallFrame->registers() + registerOffset);
2332         if (!stackFrame.registerFile->grow(callFrame->registers())) {
2333             throwStackOverflowError(previousCallFrame, stackFrame.globalData, callFrame->returnPC(), STUB_RETURN_ADDRESS);
2334             VM_THROW_EXCEPTION();
2335         }
2336
2337         callFrame->init(0, static_cast<Instruction*>((STUB_RETURN_ADDRESS).value()), previousCallFrame->scopeChain(), previousCallFrame, argCount, asObject(constrVal));
2338
2339         EncodedJSValue returnValue;
2340         {
2341             SamplingTool::HostCallRecord callRecord(CTI_SAMPLER);
2342             returnValue = constructData.native.function(callFrame);
2343         }
2344
2345         CHECK_FOR_EXCEPTION_AT_END();
2346         return returnValue;
2347     }
2348
2349     ASSERT(constructType == ConstructTypeNone);
2350
2351     CallFrame* callFrame = stackFrame.callFrame;
2352     CodeBlock* codeBlock = callFrame->codeBlock();
2353     unsigned vPCIndex = codeBlock->bytecodeOffset(callFrame, STUB_RETURN_ADDRESS);
2354     stackFrame.globalData->exception = createNotAConstructorError(callFrame, constrVal, vPCIndex, codeBlock);
2355     VM_THROW_EXCEPTION();
2356 }
2357
2358 DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_val)
2359 {
2360     STUB_INIT_STACK_FRAME(stackFrame);
2361
2362     CallFrame* callFrame = stackFrame.callFrame;
2363     JSGlobalData* globalData = stackFrame.globalData;
2364
2365     JSValue baseValue = stackFrame.args[0].jsValue();
2366     JSValue subscript = stackFrame.args[1].jsValue();
2367
2368     if (LIKELY(baseValue.isCell() && subscript.isString())) {
2369         Identifier propertyName(callFrame, asString(subscript)->value(callFrame));
2370         PropertySlot slot(baseValue.asCell());
2371         // JSString::value may have thrown, but we shouldn't find a property with a null identifier,
2372         // so we should miss this case and wind up in the CHECK_FOR_EXCEPTION_AT_END, below.
2373         if (baseValue.asCell()->fastGetOwnPropertySlot(callFrame, propertyName, slot)) {
2374             JSValue result = slot.getValue(callFrame, propertyName);
2375             CHECK_FOR_EXCEPTION();
2376             return JSValue::encode(result);
2377         }
2378     }
2379
2380     if (subscript.isUInt32()) {
2381         uint32_t i = subscript.asUInt32();
2382         if (isJSString(globalData, baseValue) && asString(baseValue)->canGetIndex(i)) {
2383             ctiPatchCallByReturnAddress(callFrame->codeBlock(), STUB_RETURN_ADDRESS, FunctionPtr(cti_op_get_by_val_string));
2384             JSValue result = asString(baseValue)->getIndex(callFrame, i);
2385             CHECK_FOR_EXCEPTION();
2386             return JSValue::encode(result);
2387         }
2388         if (isJSByteArray(globalData, baseValue) && asByteArray(baseValue)->canAccessIndex(i)) {
2389             // All fast byte array accesses are safe from exceptions so return immediately to avoid exception checks.
2390             ctiPatchCallByReturnAddress(callFrame->codeBlock(), STUB_RETURN_ADDRESS, FunctionPtr(cti_op_get_by_val_byte_array));
2391             return JSValue::encode(asByteArray(baseValue)->getIndex(callFrame, i));
2392         }
2393         JSValue result = baseValue.get(callFrame, i);
2394         CHECK_FOR_EXCEPTION();
2395         return JSValue::encode(result);
2396     }
2397     
2398     Identifier property(callFrame, subscript.toString(callFrame));
2399     JSValue result = baseValue.get(callFrame, property);
2400     CHECK_FOR_EXCEPTION_AT_END();
2401     return JSValue::encode(result);
2402 }
2403     
2404 DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_val_string)
2405 {
2406     STUB_INIT_STACK_FRAME(stackFrame);
2407     
2408     CallFrame* callFrame = stackFrame.callFrame;
2409     JSGlobalData* globalData = stackFrame.globalData;
2410     
2411     JSValue baseValue = stackFrame.args[0].jsValue();
2412     JSValue subscript = stackFrame.args[1].jsValue();
2413     
2414     JSValue result;
2415     
2416     if (LIKELY(subscript.isUInt32())) {
2417         uint32_t i = subscript.asUInt32();
2418         if (isJSString(globalData, baseValue) && asString(baseValue)->canGetIndex(i))
2419             result = asString(baseValue)->getIndex(callFrame, i);
2420         else {
2421             result = baseValue.get(callFrame, i);
2422             if (!isJSString(globalData, baseValue))
2423                 ctiPatchCallByReturnAddress(callFrame->codeBlock(), STUB_RETURN_ADDRESS, FunctionPtr(cti_op_get_by_val));
2424         }
2425     } else {
2426         Identifier property(callFrame, subscript.toString(callFrame));
2427         result = baseValue.get(callFrame, property);
2428     }
2429     
2430     CHECK_FOR_EXCEPTION_AT_END();
2431     return JSValue::encode(result);
2432 }
2433     
2434 DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_val_byte_array)
2435 {
2436     STUB_INIT_STACK_FRAME(stackFrame);
2437     
2438     CallFrame* callFrame = stackFrame.callFrame;
2439     JSGlobalData* globalData = stackFrame.globalData;
2440     
2441     JSValue baseValue = stackFrame.args[0].jsValue();
2442     JSValue subscript = stackFrame.args[1].jsValue();
2443     
2444     JSValue result;
2445
2446     if (LIKELY(subscript.isUInt32())) {
2447         uint32_t i = subscript.asUInt32();
2448         if (isJSByteArray(globalData, baseValue) && asByteArray(baseValue)->canAccessIndex(i)) {
2449             // All fast byte array accesses are safe from exceptions so return immediately to avoid exception checks.
2450             return JSValue::encode(asByteArray(baseValue)->getIndex(callFrame, i));
2451         }
2452
2453         result = baseValue.get(callFrame, i);
2454         if (!isJSByteArray(globalData, baseValue))
2455             ctiPatchCallByReturnAddress(callFrame->codeBlock(), STUB_RETURN_ADDRESS, FunctionPtr(cti_op_get_by_val));
2456     } else {
2457         Identifier property(callFrame, subscript.toString(callFrame));
2458         result = baseValue.get(callFrame, property);
2459     }
2460     
2461     CHECK_FOR_EXCEPTION_AT_END();
2462     return JSValue::encode(result);
2463 }
2464
2465 DEFINE_STUB_FUNCTION(EncodedJSValue, op_sub)
2466 {
2467     STUB_INIT_STACK_FRAME(stackFrame);
2468
2469     JSValue src1 = stackFrame.args[0].jsValue();
2470     JSValue src2 = stackFrame.args[1].jsValue();
2471
2472     double left;
2473     double right;
2474     if (src1.getNumber(left) && src2.getNumber(right))
2475         return JSValue::encode(jsNumber(left - right));
2476
2477     CallFrame* callFrame = stackFrame.callFrame;
2478     JSValue result = jsNumber(src1.toNumber(callFrame) - src2.toNumber(callFrame));
2479     CHECK_FOR_EXCEPTION_AT_END();
2480     return JSValue::encode(result);
2481 }
2482
2483 DEFINE_STUB_FUNCTION(void, op_put_by_val)
2484 {
2485     STUB_INIT_STACK_FRAME(stackFrame);
2486
2487     CallFrame* callFrame = stackFrame.callFrame;
2488     JSGlobalData* globalData = stackFrame.globalData;
2489
2490     JSValue baseValue = stackFrame.args[0].jsValue();
2491     JSValue subscript = stackFrame.args[1].jsValue();
2492     JSValue value = stackFrame.args[2].jsValue();
2493
2494     if (LIKELY(subscript.isUInt32())) {
2495         uint32_t i = subscript.asUInt32();
2496         if (isJSArray(globalData, baseValue)) {
2497             JSArray* jsArray = asArray(baseValue);
2498             if (jsArray->canSetIndex(i))
2499                 jsArray->setIndex(i, value);
2500             else
2501                 jsArray->JSArray::put(callFrame, i, value);
2502         } else if (isJSByteArray(globalData, baseValue) && asByteArray(baseValue)->canAccessIndex(i)) {
2503             JSByteArray* jsByteArray = asByteArray(baseValue);
2504             ctiPatchCallByReturnAddress(callFrame->codeBlock(), STUB_RETURN_ADDRESS, FunctionPtr(cti_op_put_by_val_byte_array));
2505             // All fast byte array accesses are safe from exceptions so return immediately to avoid exception checks.
2506             if (value.isInt32()) {
2507                 jsByteArray->setIndex(i, value.asInt32());
2508                 return;
2509             } else {
2510                 double dValue = 0;
2511                 if (value.getNumber(dValue)) {
2512                     jsByteArray->setIndex(i, dValue);
2513                     return;
2514                 }
2515             }
2516
2517             baseValue.put(callFrame, i, value);
2518         } else
2519             baseValue.put(callFrame, i, value);
2520     } else {
2521         Identifier property(callFrame, subscript.toString(callFrame));
2522         if (!stackFrame.globalData->exception) { // Don't put to an object if toString threw an exception.
2523             PutPropertySlot slot(callFrame->codeBlock()->isStrictMode());
2524             baseValue.put(callFrame, property, value, slot);
2525         }
2526     }
2527
2528     CHECK_FOR_EXCEPTION_AT_END();
2529 }
2530
2531 DEFINE_STUB_FUNCTION(void, op_put_by_val_byte_array)
2532 {
2533     STUB_INIT_STACK_FRAME(stackFrame);
2534     
2535     CallFrame* callFrame = stackFrame.callFrame;
2536     JSGlobalData* globalData = stackFrame.globalData;
2537     
2538     JSValue baseValue = stackFrame.args[0].jsValue();
2539     JSValue subscript = stackFrame.args[1].jsValue();
2540     JSValue value = stackFrame.args[2].jsValue();
2541     
2542     if (LIKELY(subscript.isUInt32())) {
2543         uint32_t i = subscript.asUInt32();
2544         if (isJSByteArray(globalData, baseValue) && asByteArray(baseValue)->canAccessIndex(i)) {
2545             JSByteArray* jsByteArray = asByteArray(baseValue);
2546             
2547             // All fast byte array accesses are safe from exceptions so return immediately to avoid exception checks.
2548             if (value.isInt32()) {
2549                 jsByteArray->setIndex(i, value.asInt32());
2550                 return;
2551             } else {
2552                 double dValue = 0;                
2553                 if (value.getNumber(dValue)) {
2554                     jsByteArray->setIndex(i, dValue);
2555                     return;
2556                 }
2557             }
2558         }
2559
2560         if (!isJSByteArray(globalData, baseValue))
2561             ctiPatchCallByReturnAddress(callFrame->codeBlock(), STUB_RETURN_ADDRESS, FunctionPtr(cti_op_put_by_val));
2562         baseValue.put(callFrame, i, value);
2563     } else {
2564         Identifier property(callFrame, subscript.toString(callFrame));
2565         if (!stackFrame.globalData->exception) { // Don't put to an object if toString threw an exception.
2566             PutPropertySlot slot(callFrame->codeBlock()->isStrictMode());
2567             baseValue.put(callFrame, property, value, slot);
2568         }
2569     }
2570     
2571     CHECK_FOR_EXCEPTION_AT_END();
2572 }
2573
2574 DEFINE_STUB_FUNCTION(EncodedJSValue, op_lesseq)
2575 {
2576     STUB_INIT_STACK_FRAME(stackFrame);
2577
2578     CallFrame* callFrame = stackFrame.callFrame;
2579     JSValue result = jsBoolean(jsLessEq(callFrame, stackFrame.args[0].jsValue(), stackFrame.args[1].jsValue()));
2580     CHECK_FOR_EXCEPTION_AT_END();
2581     return JSValue::encode(result);
2582 }
2583
2584 DEFINE_STUB_FUNCTION(int, op_load_varargs)
2585 {
2586     STUB_INIT_STACK_FRAME(stackFrame);
2587
2588     CallFrame* callFrame = stackFrame.callFrame;
2589     RegisterFile* registerFile = stackFrame.registerFile;
2590     int argsOffset = stackFrame.args[0].int32();
2591     JSValue arguments = callFrame->registers()[argsOffset].jsValue();
2592     uint32_t argCount = 0;
2593     if (!arguments) {
2594         int providedParams = callFrame->registers()[RegisterFile::ArgumentCount].i() - 1;
2595         argCount = providedParams;
2596         argCount = min(argCount, static_cast<uint32_t>(Arguments::MaxArguments));
2597         int32_t sizeDelta = argsOffset + argCount + RegisterFile::CallFrameHeaderSize;
2598         Register* newEnd = callFrame->registers() + sizeDelta;
2599         if (!registerFile->grow(newEnd) || ((newEnd - callFrame->registers()) != sizeDelta)) {
2600             stackFrame.globalData->exception = createStackOverflowError(callFrame);
2601             VM_THROW_EXCEPTION();
2602         }
2603         int32_t expectedParams = asFunction(callFrame->callee())->jsExecutable()->parameterCount();
2604         int32_t inplaceArgs = min(providedParams, expectedParams);
2605         
2606         Register* inplaceArgsDst = callFrame->registers() + argsOffset;
2607
2608         Register* inplaceArgsEnd = inplaceArgsDst + inplaceArgs;
2609         Register* inplaceArgsEnd2 = inplaceArgsDst + providedParams;
2610
2611         Register* inplaceArgsSrc = callFrame->registers() - RegisterFile::CallFrameHeaderSize - expectedParams;
2612         Register* inplaceArgsSrc2 = inplaceArgsSrc - providedParams - 1 + inplaceArgs;
2613  
2614         // First step is to copy the "expected" parameters from their normal location relative to the callframe
2615         while (inplaceArgsDst < inplaceArgsEnd)
2616             *inplaceArgsDst++ = *inplaceArgsSrc++;
2617
2618         // Then we copy any additional arguments that may be further up the stack ('-1' to account for 'this')
2619         while (inplaceArgsDst < inplaceArgsEnd2)
2620             *inplaceArgsDst++ = *inplaceArgsSrc2++;
2621
2622     } else if (!arguments.isUndefinedOrNull()) {
2623         if (!arguments.isObject()) {
2624             CodeBlock* codeBlock = callFrame->codeBlock();
2625             unsigned vPCIndex = codeBlock->bytecodeOffset(callFrame, STUB_RETURN_ADDRESS);
2626             stackFrame.globalData->exception = createInvalidParamError(callFrame, "Function.prototype.apply", arguments, vPCIndex, codeBlock);
2627             VM_THROW_EXCEPTION();
2628         }
2629         if (asObject(arguments)->classInfo() == &Arguments::info) {
2630             Arguments* argsObject = asArguments(arguments);
2631             argCount = argsObject->numProvidedArguments(callFrame);
2632             argCount = min(argCount, static_cast<uint32_t>(Arguments::MaxArguments));
2633             int32_t sizeDelta = argsOffset + argCount + RegisterFile::CallFrameHeaderSize;
2634             Register* newEnd = callFrame->registers() + sizeDelta;
2635             if (!registerFile->grow(newEnd) || ((newEnd - callFrame->registers()) != sizeDelta)) {
2636                 stackFrame.globalData->exception = createStackOverflowError(callFrame);
2637                 VM_THROW_EXCEPTION();
2638             }
2639             argsObject->copyToRegisters(callFrame, callFrame->registers() + argsOffset, argCount);
2640         } else if (isJSArray(&callFrame->globalData(), arguments)) {
2641             JSArray* array = asArray(arguments);
2642             argCount = array->length();
2643             argCount = min(argCount, static_cast<uint32_t>(Arguments::MaxArguments));
2644             int32_t sizeDelta = argsOffset + argCount + RegisterFile::CallFrameHeaderSize;
2645             Register* newEnd = callFrame->registers() + sizeDelta;
2646             if (!registerFile->grow(newEnd) || ((newEnd - callFrame->registers()) != sizeDelta)) {
2647                 stackFrame.globalData->exception = createStackOverflowError(callFrame);
2648                 VM_THROW_EXCEPTION();
2649             }
2650             array->copyToRegisters(callFrame, callFrame->registers() + argsOffset, argCount);
2651         } else if (asObject(arguments)->inherits(&JSArray::info)) {
2652             JSObject* argObject = asObject(arguments);
2653             argCount = argObject->get(callFrame, callFrame->propertyNames().length).toUInt32(callFrame);
2654             argCount = min(argCount, static_cast<uint32_t>(Arguments::MaxArguments));
2655             int32_t sizeDelta = argsOffset + argCount + RegisterFile::CallFrameHeaderSize;
2656             Register* newEnd = callFrame->registers() + sizeDelta;
2657             if (!registerFile->grow(newEnd) || ((newEnd - callFrame->registers()) != sizeDelta)) {
2658                 stackFrame.globalData->exception = createStackOverflowError(callFrame);
2659                 VM_THROW_EXCEPTION();
2660             }
2661             Register* argsBuffer = callFrame->registers() + argsOffset;
2662             for (unsigned i = 0; i < argCount; ++i) {
2663                 argsBuffer[i] = asObject(arguments)->get(callFrame, i);
2664                 CHECK_FOR_EXCEPTION();
2665             }
2666         } else {
2667             CodeBlock* codeBlock = callFrame->codeBlock();
2668             unsigned vPCIndex = codeBlock->bytecodeOffset(callFrame, STUB_RETURN_ADDRESS);
2669             stackFrame.globalData->exception = createInvalidParamError(callFrame, "Function.prototype.apply", arguments, vPCIndex, codeBlock);
2670             VM_THROW_EXCEPTION();
2671         }
2672     }
2673
2674     return argCount + 1;
2675 }
2676
2677 DEFINE_STUB_FUNCTION(EncodedJSValue, op_negate)
2678 {
2679     STUB_INIT_STACK_FRAME(stackFrame);
2680
2681     JSValue src = stackFrame.args[0].jsValue();
2682
2683     double v;
2684     if (src.getNumber(v))
2685         return JSValue::encode(jsNumber(-v));
2686
2687     CallFrame* callFrame = stackFrame.callFrame;
2688     JSValue result = jsNumber(-src.toNumber(callFrame));
2689     CHECK_FOR_EXCEPTION_AT_END();
2690     return JSValue::encode(result);
2691 }
2692
2693 DEFINE_STUB_FUNCTION(EncodedJSValue, op_resolve_base)
2694 {
2695     STUB_INIT_STACK_FRAME(stackFrame);
2696
2697     return JSValue::encode(JSC::resolveBase(stackFrame.callFrame, stackFrame.args[0].identifier(), stackFrame.callFrame->scopeChain(), false));
2698 }
2699
2700 DEFINE_STUB_FUNCTION(EncodedJSValue, op_resolve_base_strict_put)
2701 {
2702     STUB_INIT_STACK_FRAME(stackFrame);
2703     JSValue base = JSC::resolveBase(stackFrame.callFrame, stackFrame.args[0].identifier(), stackFrame.callFrame->scopeChain(), true);
2704     if (!base) {
2705         stackFrame.globalData->exception = createErrorForInvalidGlobalAssignment(stackFrame.callFrame, stackFrame.args[0].identifier().ustring());
2706         VM_THROW_EXCEPTION();
2707     }
2708     return JSValue::encode(base);
2709 }
2710
2711 DEFINE_STUB_FUNCTION(EncodedJSValue, op_ensure_property_exists)
2712 {
2713     STUB_INIT_STACK_FRAME(stackFrame);
2714     JSValue base = stackFrame.callFrame->r(stackFrame.args[0].int32()).jsValue();
2715     JSObject* object = asObject(base);
2716     PropertySlot slot(object);
2717     ASSERT(stackFrame.callFrame->codeBlock()->isStrictMode());
2718     if (!object->getPropertySlot(stackFrame.callFrame, stackFrame.args[1].identifier(), slot)) {
2719         stackFrame.globalData->exception = createErrorForInvalidGlobalAssignment(stackFrame.callFrame, stackFrame.args[1].identifier().ustring());
2720         VM_THROW_EXCEPTION();
2721     }
2722
2723     return JSValue::encode(base);
2724 }
2725     
2726 DEFINE_STUB_FUNCTION(EncodedJSValue, op_resolve_skip)
2727 {
2728     STUB_INIT_STACK_FRAME(stackFrame);
2729
2730     CallFrame* callFrame = stackFrame.callFrame;
2731     ScopeChainNode* scopeChain = callFrame->scopeChain();
2732
2733     int skip = stackFrame.args[1].int32();
2734
2735     ScopeChainIterator iter = scopeChain->begin();
2736     ScopeChainIterator end = scopeChain->end();
2737     ASSERT(iter != end);
2738     CodeBlock* codeBlock = callFrame->codeBlock();
2739     bool checkTopLevel = codeBlock->codeType() == FunctionCode && codeBlock->needsFullScopeChain();
2740     ASSERT(skip || !checkTopLevel);
2741     if (checkTopLevel && skip--) {
2742         if (callFrame->r(codeBlock->activationRegister()).jsValue())
2743             ++iter;
2744     }
2745     while (skip--) {
2746         ++iter;
2747         ASSERT(iter != end);
2748     }
2749     Identifier& ident = stackFrame.args[0].identifier();
2750     do {
2751         JSObject* o = *iter;
2752         PropertySlot slot(o);
2753         if (o->getPropertySlot(callFrame, ident, slot)) {
2754             JSValue result = slot.getValue(callFrame, ident);
2755             CHECK_FOR_EXCEPTION_AT_END();
2756             return JSValue::encode(result);
2757         }
2758     } while (++iter != end);
2759
2760     unsigned vPCIndex = codeBlock->bytecodeOffset(callFrame, STUB_RETURN_ADDRESS);
2761     stackFrame.globalData->exception = createUndefinedVariableError(callFrame, ident, vPCIndex, codeBlock);
2762     VM_THROW_EXCEPTION();
2763 }
2764
2765 DEFINE_STUB_FUNCTION(EncodedJSValue, op_resolve_global)
2766 {
2767     STUB_INIT_STACK_FRAME(stackFrame);
2768
2769     CallFrame* callFrame = stackFrame.callFrame;
2770     CodeBlock* codeBlock = callFrame->codeBlock();
2771     JSGlobalObject* globalObject = codeBlock->globalObject();
2772     Identifier& ident = stackFrame.args[0].identifier();
2773     unsigned globalResolveInfoIndex = stackFrame.args[1].int32();
2774     ASSERT(globalObject->isGlobalObject());
2775
2776     PropertySlot slot(globalObject);
2777     if (globalObject->getPropertySlot(callFrame, ident, slot)) {
2778         JSValue result = slot.getValue(callFrame, ident);
2779         if (slot.isCacheableValue() && !globalObject->structure()->isUncacheableDictionary() && slot.slotBase() == globalObject) {
2780             GlobalResolveInfo& globalResolveInfo = codeBlock->globalResolveInfo(globalResolveInfoIndex);
2781             if (globalResolveInfo.structure)
2782                 globalResolveInfo.structure->deref();
2783             globalObject->structure()->ref();
2784             globalResolveInfo.structure = globalObject->structure();
2785             globalResolveInfo.offset = slot.cachedOffset();
2786             return JSValue::encode(result);
2787         }
2788
2789         CHECK_FOR_EXCEPTION_AT_END();
2790         return JSValue::encode(result);
2791     }
2792
2793     unsigned vPCIndex = codeBlock->bytecodeOffset(callFrame, STUB_RETURN_ADDRESS);
2794     stackFrame.globalData->exception = createUndefinedVariableError(callFrame, ident, vPCIndex, codeBlock);
2795     VM_THROW_EXCEPTION();
2796 }
2797
2798 DEFINE_STUB_FUNCTION(EncodedJSValue, op_div)
2799 {
2800     STUB_INIT_STACK_FRAME(stackFrame);
2801
2802     JSValue src1 = stackFrame.args[0].jsValue();
2803     JSValue src2 = stackFrame.args[1].jsValue();
2804
2805     double left;
2806     double right;
2807     if (src1.getNumber(left) && src2.getNumber(right))
2808         return JSValue::encode(jsNumber(left / right));
2809
2810     CallFrame* callFrame = stackFrame.callFrame;
2811     JSValue result = jsNumber(src1.toNumber(callFrame) / src2.toNumber(callFrame));
2812     CHECK_FOR_EXCEPTION_AT_END();
2813     return JSValue::encode(result);
2814 }
2815
2816 DEFINE_STUB_FUNCTION(EncodedJSValue, op_pre_dec)
2817 {
2818     STUB_INIT_STACK_FRAME(stackFrame);
2819
2820     JSValue v = stackFrame.args[0].jsValue();
2821
2822     CallFrame* callFrame = stackFrame.callFrame;
2823     JSValue result = jsNumber(v.toNumber(callFrame) - 1);
2824     CHECK_FOR_EXCEPTION_AT_END();
2825     return JSValue::encode(result);
2826 }
2827
2828 DEFINE_STUB_FUNCTION(int, op_jless)
2829 {
2830     STUB_INIT_STACK_FRAME(stackFrame);
2831
2832     JSValue src1 = stackFrame.args[0].jsValue();
2833     JSValue src2 = stackFrame.args[1].jsValue();
2834     CallFrame* callFrame = stackFrame.callFrame;
2835
2836     bool result = jsLess(callFrame, src1, src2);
2837     CHECK_FOR_EXCEPTION_AT_END();
2838     return result;
2839 }
2840
2841 DEFINE_STUB_FUNCTION(int, op_jlesseq)
2842 {
2843     STUB_INIT_STACK_FRAME(stackFrame);
2844
2845     JSValue src1 = stackFrame.args[0].jsValue();
2846     JSValue src2 = stackFrame.args[1].jsValue();
2847     CallFrame* callFrame = stackFrame.callFrame;
2848
2849     bool result = jsLessEq(callFrame, src1, src2);
2850     CHECK_FOR_EXCEPTION_AT_END();
2851     return result;
2852 }
2853
2854 DEFINE_STUB_FUNCTION(EncodedJSValue, op_not)
2855 {
2856     STUB_INIT_STACK_FRAME(stackFrame);
2857
2858     JSValue src = stackFrame.args[0].jsValue();
2859
2860     CallFrame* callFrame = stackFrame.callFrame;
2861
2862     JSValue result = jsBoolean(!src.toBoolean(callFrame));
2863     CHECK_FOR_EXCEPTION_AT_END();
2864     return JSValue::encode(result);
2865 }
2866
2867 DEFINE_STUB_FUNCTION(int, op_jtrue)
2868 {
2869     STUB_INIT_STACK_FRAME(stackFrame);
2870
2871     JSValue src1 = stackFrame.args[0].jsValue();
2872
2873     CallFrame* callFrame = stackFrame.callFrame;
2874
2875     bool result = src1.toBoolean(callFrame);
2876     CHECK_FOR_EXCEPTION_AT_END();
2877     return result;
2878 }
2879
2880 DEFINE_STUB_FUNCTION(EncodedJSValue, op_post_inc)
2881 {
2882     STUB_INIT_STACK_FRAME(stackFrame);
2883
2884     JSValue v = stackFrame.args[0].jsValue();
2885
2886     CallFrame* callFrame = stackFrame.callFrame;
2887
2888     JSValue number = v.toJSNumber(callFrame);
2889     CHECK_FOR_EXCEPTION_AT_END();
2890
2891     callFrame->registers()[stackFrame.args[1].int32()] = jsNumber(number.uncheckedGetNumber() + 1);
2892     return JSValue::encode(number);
2893 }
2894
2895 DEFINE_STUB_FUNCTION(int, op_eq)
2896 {
2897     STUB_INIT_STACK_FRAME(stackFrame);
2898
2899     JSValue src1 = stackFrame.args[0].jsValue();
2900     JSValue src2 = stackFrame.args[1].jsValue();
2901
2902 #if USE(JSVALUE32_64)
2903     start:
2904     if (src2.isUndefined()) {
2905         return src1.isNull() || 
2906                (src1.isCell() && src1.asCell()->structure()->typeInfo().masqueradesAsUndefined())
2907                || src1.isUndefined();
2908     }
2909     
2910     if (src2.isNull()) {
2911         return src1.isUndefined() || 
2912                (src1.isCell() && src1.asCell()->structure()->typeInfo().masqueradesAsUndefined())
2913                || src1.isNull();
2914     }
2915
2916     if (src1.isInt32()) {
2917         if (src2.isDouble())
2918             return src1.asInt32() == src2.asDouble();
2919         double d = src2.toNumber(stackFrame.callFrame);
2920         CHECK_FOR_EXCEPTION();
2921         return src1.asInt32() == d;
2922     }
2923
2924     if (src1.isDouble()) {
2925         if (src2.isInt32())
2926             return src1.asDouble() == src2.asInt32();
2927         double d = src2.toNumber(stackFrame.callFrame);
2928         CHECK_FOR_EXCEPTION();
2929         return src1.asDouble() == d;
2930     }
2931
2932     if (src1.isTrue()) {
2933         if (src2.isFalse())
2934             return false;
2935         double d = src2.toNumber(stackFrame.callFrame);
2936         CHECK_FOR_EXCEPTION();
2937         return d == 1.0;
2938     }
2939
2940     if (src1.isFalse()) {
2941         if (src2.isTrue())
2942             return false;
2943         double d = src2.toNumber(stackFrame.callFrame);
2944         CHECK_FOR_EXCEPTION();
2945         return d == 0.0;
2946     }
2947     
2948     if (src1.isUndefined())
2949         return src2.isCell() && src2.asCell()->structure()->typeInfo().masqueradesAsUndefined();
2950     
2951     if (src1.isNull())
2952         return src2.isCell() && src2.asCell()->structure()->typeInfo().masqueradesAsUndefined();
2953
2954     JSCell* cell1 = src1.asCell();
2955
2956     if (cell1->isString()) {
2957         if (src2.isInt32())
2958             return jsToNumber(static_cast<JSString*>(cell1)->value(stackFrame.callFrame)) == src2.asInt32();
2959             
2960         if (src2.isDouble())
2961             return jsToNumber(static_cast<JSString*>(cell1)->value(stackFrame.callFrame)) == src2.asDouble();
2962
2963         if (src2.isTrue())
2964             return jsToNumber(static_cast<JSString*>(cell1)->value(stackFrame.callFrame)) == 1.0;
2965
2966         if (src2.isFalse())
2967             return jsToNumber(static_cast<JSString*>(cell1)->value(stackFrame.callFrame)) == 0.0;
2968
2969         JSCell* cell2 = src2.asCell();
2970         if (cell2->isString())
2971             return static_cast<JSString*>(cell1)->value(stackFrame.callFrame) == static_cast<JSString*>(cell2)->value(stackFrame.callFrame);
2972
2973         src2 = asObject(cell2)->toPrimitive(stackFrame.callFrame);
2974         CHECK_FOR_EXCEPTION();
2975         goto start;
2976     }
2977
2978     if (src2.isObject())
2979         return asObject(cell1) == asObject(src2);
2980     src1 = asObject(cell1)->toPrimitive(stackFrame.callFrame);
2981     CHECK_FOR_EXCEPTION();
2982     goto start;
2983     
2984 #else // USE(JSVALUE32_64)
2985     CallFrame* callFrame = stackFrame.callFrame;
2986     
2987     bool result = JSValue::equalSlowCaseInline(callFrame, src1, src2);
2988     CHECK_FOR_EXCEPTION_AT_END();
2989     return result;
2990 #endif // USE(JSVALUE32_64)
2991 }
2992
2993 DEFINE_STUB_FUNCTION(int, op_eq_strings)
2994 {
2995 #if USE(JSVALUE32_64)
2996     STUB_INIT_STACK_FRAME(stackFrame);
2997
2998     JSString* string1 = stackFrame.args[0].jsString();
2999     JSString* string2 = stackFrame.args[1].jsString();
3000
3001     ASSERT(string1->isString());
3002     ASSERT(string2->isString());
3003     return string1->value(stackFrame.callFrame) == string2->value(stackFrame.callFrame);
3004 #else
3005     UNUSED_PARAM(args);
3006     ASSERT_NOT_REACHED();
3007     return 0;
3008 #endif
3009 }
3010
3011 DEFINE_STUB_FUNCTION(EncodedJSValue, op_lshift)
3012 {
3013     STUB_INIT_STACK_FRAME(stackFrame);
3014
3015     JSValue val = stackFrame.args[0].jsValue();
3016     JSValue shift = stackFrame.args[1].jsValue();
3017
3018     CallFrame* callFrame = stackFrame.callFrame;
3019     JSValue result = jsNumber((val.toInt32(callFrame)) << (shift.toUInt32(callFrame) & 0x1f));
3020     CHECK_FOR_EXCEPTION_AT_END();
3021     return JSValue::encode(result);
3022 }
3023
3024 DEFINE_STUB_FUNCTION(EncodedJSValue, op_bitand)
3025 {
3026     STUB_INIT_STACK_FRAME(stackFrame);
3027
3028     JSValue src1 = stackFrame.args[0].jsValue();
3029     JSValue src2 = stackFrame.args[1].jsValue();
3030
3031     ASSERT(!src1.isInt32() || !src2.isInt32());
3032     CallFrame* callFrame = stackFrame.callFrame;
3033     JSValue result = jsNumber(src1.toInt32(callFrame) & src2.toInt32(callFrame));
3034     CHECK_FOR_EXCEPTION_AT_END();
3035     return JSValue::encode(result);
3036 }
3037
3038 DEFINE_STUB_FUNCTION(EncodedJSValue, op_rshift)
3039 {
3040     STUB_INIT_STACK_FRAME(stackFrame);
3041
3042     JSValue val = stackFrame.args[0].jsValue();
3043     JSValue shift = stackFrame.args[1].jsValue();
3044
3045     CallFrame* callFrame = stackFrame.callFrame;
3046     JSValue result = jsNumber((val.toInt32(callFrame)) >> (shift.toUInt32(callFrame) & 0x1f));
3047
3048     CHECK_FOR_EXCEPTION_AT_END();
3049     return JSValue::encode(result);
3050 }
3051
3052 DEFINE_STUB_FUNCTION(EncodedJSValue, op_bitnot)
3053 {
3054     STUB_INIT_STACK_FRAME(stackFrame);
3055
3056     JSValue src = stackFrame.args[0].jsValue();
3057
3058     ASSERT(!src.isInt32());
3059     CallFrame* callFrame = stackFrame.callFrame;
3060     JSValue result = jsNumber(~src.toInt32(callFrame));
3061     CHECK_FOR_EXCEPTION_AT_END();
3062     return JSValue::encode(result);
3063 }
3064
3065 DEFINE_STUB_FUNCTION(EncodedJSValue, op_resolve_with_base)
3066 {
3067     STUB_INIT_STACK_FRAME(stackFrame);
3068
3069     CallFrame* callFrame = stackFrame.callFrame;
3070     ScopeChainNode* scopeChain = callFrame->scopeChain();
3071
3072     ScopeChainIterator iter = scopeChain->begin();
3073     ScopeChainIterator end = scopeChain->end();
3074
3075     // FIXME: add scopeDepthIsZero optimization
3076
3077     ASSERT(iter != end);
3078
3079     Identifier& ident = stackFrame.args[0].identifier();
3080     JSObject* base;
3081     do {
3082         base = *iter;
3083         PropertySlot slot(base);
3084         if (base->getPropertySlot(callFrame, ident, slot)) {
3085             JSValue result = slot.getValue(callFrame, ident);
3086             CHECK_FOR_EXCEPTION_AT_END();
3087
3088             callFrame->registers()[stackFrame.args[1].int32()] = JSValue(base);
3089             return JSValue::encode(result);
3090         }
3091         ++iter;
3092     } while (iter != end);
3093
3094     CodeBlock* codeBlock = callFrame->codeBlock();
3095     unsigned vPCIndex = codeBlock->bytecodeOffset(callFrame, STUB_RETURN_ADDRESS);
3096     stackFrame.globalData->exception = createUndefinedVariableError(callFrame, ident, vPCIndex, codeBlock);
3097     VM_THROW_EXCEPTION_AT_END();
3098     return JSValue::encode(JSValue());
3099 }
3100
3101 DEFINE_STUB_FUNCTION(JSObject*, op_new_func_exp)
3102 {
3103     STUB_INIT_STACK_FRAME(stackFrame);
3104     CallFrame* callFrame = stackFrame.callFrame;
3105
3106     FunctionExecutable* function = stackFrame.args[0].function();
3107     JSFunction* func = function->make(callFrame, callFrame->scopeChain());
3108     ASSERT(callFrame->codeBlock()->codeType() != FunctionCode || !callFrame->codeBlock()->needsFullScopeChain() || callFrame->r(callFrame->codeBlock()->activationRegister()).jsValue());
3109
3110     /* 
3111         The Identifier in a FunctionExpression can be referenced from inside
3112         the FunctionExpression's FunctionBody to allow the function to call
3113         itself recursively. However, unlike in a FunctionDeclaration, the
3114         Identifier in a FunctionExpression cannot be referenced from and
3115         does not affect the scope enclosing the FunctionExpression.
3116      */
3117     if (!function->name().isNull()) {
3118         JSStaticScopeObject* functionScopeObject = new (callFrame) JSStaticScopeObject(callFrame, function->name(), func, ReadOnly | DontDelete);
3119         func->scope().push(functionScopeObject);
3120     }
3121
3122     return func;
3123 }
3124
3125 DEFINE_STUB_FUNCTION(EncodedJSValue, op_mod)
3126 {
3127     STUB_INIT_STACK_FRAME(stackFrame);
3128
3129     JSValue dividendValue = stackFrame.args[0].jsValue();
3130     JSValue divisorValue = stackFrame.args[1].jsValue();
3131
3132     CallFrame* callFrame = stackFrame.callFrame;
3133     double d = dividendValue.toNumber(callFrame);
3134     JSValue result = jsNumber(fmod(d, divisorValue.toNumber(callFrame)));
3135     CHECK_FOR_EXCEPTION_AT_END();
3136     return JSValue::encode(result);
3137 }
3138
3139 DEFINE_STUB_FUNCTION(EncodedJSValue, op_less)
3140 {
3141     STUB_INIT_STACK_FRAME(stackFrame);
3142
3143     CallFrame* callFrame = stackFrame.callFrame;
3144     JSValue result = jsBoolean(jsLess(callFrame, stackFrame.args[0].jsValue(), stackFrame.args[1].jsValue()));
3145     CHECK_FOR_EXCEPTION_AT_END();
3146     return JSValue::encode(result);
3147 }
3148
3149 DEFINE_STUB_FUNCTION(EncodedJSValue, op_post_dec)
3150 {
3151     STUB_INIT_STACK_FRAME(stackFrame);
3152
3153     JSValue v = stackFrame.args[0].jsValue();
3154
3155     CallFrame* callFrame = stackFrame.callFrame;
3156
3157     JSValue number = v.toJSNumber(callFrame);
3158     CHECK_FOR_EXCEPTION_AT_END();
3159
3160     callFrame->registers()[stackFrame.args[1].int32()] = jsNumber(number.uncheckedGetNumber() - 1);
3161     return JSValue::encode(number);
3162 }
3163
3164 DEFINE_STUB_FUNCTION(EncodedJSValue, op_urshift)
3165 {
3166     STUB_INIT_STACK_FRAME(stackFrame);
3167
3168     JSValue val = stackFrame.args[0].jsValue();
3169     JSValue shift = stackFrame.args[1].jsValue();
3170
3171     CallFrame* callFrame = stackFrame.callFrame;
3172     JSValue result = jsNumber((val.toUInt32(callFrame)) >> (shift.toUInt32(callFrame) & 0x1f));
3173     CHECK_FOR_EXCEPTION_AT_END();
3174     return JSValue::encode(result);
3175 }
3176
3177 DEFINE_STUB_FUNCTION(EncodedJSValue, op_bitxor)
3178 {
3179     STUB_INIT_STACK_FRAME(stackFrame);
3180
3181     JSValue src1 = stackFrame.args[0].jsValue();
3182     JSValue src2 = stackFrame.args[1].jsValue();
3183
3184     CallFrame* callFrame = stackFrame.callFrame;
3185
3186     JSValue result = jsNumber(src1.toInt32(callFrame) ^ src2.toInt32(callFrame));
3187     CHECK_FOR_EXCEPTION_AT_END();
3188     return JSValue::encode(result);
3189 }
3190
3191 DEFINE_STUB_FUNCTION(JSObject*, op_new_regexp)
3192 {
3193     STUB_INIT_STACK_FRAME(stackFrame);
3194
3195     return new (stackFrame.globalData) RegExpObject(stackFrame.callFrame->lexicalGlobalObject(), stackFrame.callFrame->lexicalGlobalObject()->regExpStructure(), stackFrame.args[0].regExp());
3196 }
3197
3198 DEFINE_STUB_FUNCTION(EncodedJSValue, op_bitor)
3199 {
3200     STUB_INIT_STACK_FRAME(stackFrame);
3201
3202     JSValue src1 = stackFrame.args[0].jsValue();
3203     JSValue src2 = stackFrame.args[1].jsValue();
3204
3205     CallFrame* callFrame = stackFrame.callFrame;
3206
3207     JSValue result = jsNumber(src1.toInt32(callFrame) | src2.toInt32(callFrame));
3208     CHECK_FOR_EXCEPTION_AT_END();
3209     return JSValue::encode(result);
3210 }
3211
3212 DEFINE_STUB_FUNCTION(EncodedJSValue, op_call_eval)
3213 {
3214     STUB_INIT_STACK_FRAME(stackFrame);
3215     ASSERT(stackFrame.callFrame->codeBlock()->codeType() != FunctionCode || !stackFrame.callFrame->codeBlock()->needsFullScopeChain() || stackFrame.callFrame->r(stackFrame.callFrame->codeBlock()->activationRegister()).jsValue());
3216
3217     CallFrame* callFrame = stackFrame.callFrame;
3218     RegisterFile* registerFile = stackFrame.registerFile;
3219
3220     Interpreter* interpreter = stackFrame.globalData->interpreter;
3221     
3222     JSValue funcVal = stackFrame.args[0].jsValue();
3223     int registerOffset = stackFrame.args[1].int32();
3224     int argCount = stackFrame.args[2].int32();
3225
3226     Register* newCallFrame = callFrame->registers() + registerOffset;
3227     Register* argv = newCallFrame - RegisterFile::CallFrameHeaderSize - argCount;
3228     JSValue baseValue = argv[0].jsValue();
3229     JSGlobalObject* globalObject = callFrame->scopeChain()->globalObject;
3230
3231     if (baseValue == globalObject && funcVal == globalObject->evalFunction()) {
3232         JSValue result = interpreter->callEval(callFrame, registerFile, argv, argCount, registerOffset);
3233         CHECK_FOR_EXCEPTION_AT_END();
3234         return JSValue::encode(result);
3235     }
3236
3237     return JSValue::encode(JSValue());
3238 }
3239
3240 DEFINE_STUB_FUNCTION(void*, op_throw)
3241 {
3242     STUB_INIT_STACK_FRAME(stackFrame);
3243     ExceptionHandler handler = jitThrow(stackFrame.globalData, stackFrame.callFrame, stackFrame.args[0].jsValue(), STUB_RETURN_ADDRESS, true);
3244     STUB_SET_RETURN_ADDRESS(handler.catchRoutine);
3245     return handler.callFrame;
3246 }
3247
3248 DEFINE_STUB_FUNCTION(JSPropertyNameIterator*, op_get_pnames)
3249 {
3250     STUB_INIT_STACK_FRAME(stackFrame);
3251
3252     CallFrame* callFrame = stackFrame.callFrame;
3253     JSObject* o = stackFrame.args[0].jsObject();
3254     Structure* structure = o->structure();
3255     JSPropertyNameIterator* jsPropertyNameIterator = structure->enumerationCache();
3256     if (!jsPropertyNameIterator || jsPropertyNameIterator->cachedPrototypeChain() != structure->prototypeChain(callFrame))
3257         jsPropertyNameIterator = JSPropertyNameIterator::create(callFrame, o);
3258     return jsPropertyNameIterator;
3259 }
3260
3261 DEFINE_STUB_FUNCTION(int, has_property)
3262 {
3263     STUB_INIT_STACK_FRAME(stackFrame);
3264
3265     JSObject* base = stackFrame.args[0].jsObject();
3266     JSString* property = stackFrame.args[1].jsString();
3267     int result = base->hasProperty(stackFrame.callFrame, Identifier(stackFrame.callFrame, property->value(stackFrame.callFrame)));
3268     CHECK_FOR_EXCEPTION_AT_END();
3269     return result;
3270 }
3271
3272 DEFINE_STUB_FUNCTION(JSObject*, op_push_scope)
3273 {
3274     STUB_INIT_STACK_FRAME(stackFrame);
3275
3276     JSObject* o = stackFrame.args[0].jsValue().toObject(stackFrame.callFrame);
3277     CHECK_FOR_EXCEPTION();
3278     stackFrame.callFrame->setScopeChain(stackFrame.callFrame->scopeChain()->push(o));
3279     return o;
3280 }
3281
3282 DEFINE_STUB_FUNCTION(void, op_pop_scope)
3283 {
3284     STUB_INIT_STACK_FRAME(stackFrame);
3285
3286     stackFrame.callFrame->setScopeChain(stackFrame.callFrame->scopeChain()->pop());
3287 }
3288
3289 DEFINE_STUB_FUNCTION(EncodedJSValue, op_typeof)
3290 {
3291     STUB_INIT_STACK_FRAME(stackFrame);
3292
3293     return JSValue::encode(jsTypeStringForValue(stackFrame.callFrame, stackFrame.args[0].jsValue()));
3294 }
3295
3296 DEFINE_STUB_FUNCTION(EncodedJSValue, op_is_undefined)
3297 {
3298     STUB_INIT_STACK_FRAME(stackFrame);
3299
3300     JSValue v = stackFrame.args[0].jsValue();
3301     return JSValue::encode(jsBoolean(v.isCell() ? v.asCell()->structure()->typeInfo().masqueradesAsUndefined() : v.isUndefined()));
3302 }
3303
3304 DEFINE_STUB_FUNCTION(EncodedJSValue, op_is_boolean)
3305 {
3306     STUB_INIT_STACK_FRAME(stackFrame);
3307
3308     return JSValue::encode(jsBoolean(stackFrame.args[0].jsValue().isBoolean()));
3309 }
3310
3311 DEFINE_STUB_FUNCTION(EncodedJSValue, op_is_number)
3312 {
3313     STUB_INIT_STACK_FRAME(stackFrame);
3314
3315     return JSValue::encode(jsBoolean(stackFrame.args[0].jsValue().isNumber()));
3316 }
3317
3318 DEFINE_STUB_FUNCTION(EncodedJSValue, op_is_string)
3319 {
3320     STUB_INIT_STACK_FRAME(stackFrame);
3321
3322     return JSValue::encode(jsBoolean(isJSString(stackFrame.globalData, stackFrame.args[0].jsValue())));
3323 }
3324
3325 DEFINE_STUB_FUNCTION(EncodedJSValue, op_is_object)
3326 {
3327     STUB_INIT_STACK_FRAME(stackFrame);
3328
3329     return JSValue::encode(jsBoolean(jsIsObjectType(stackFrame.args[0].jsValue())));
3330 }
3331
3332 DEFINE_STUB_FUNCTION(EncodedJSValue, op_is_function)
3333 {
3334     STUB_INIT_STACK_FRAME(stackFrame);
3335
3336     return JSValue::encode(jsBoolean(jsIsFunctionType(stackFrame.args[0].jsValue())));
3337 }
3338
3339 DEFINE_STUB_FUNCTION(EncodedJSValue, op_stricteq)
3340 {
3341     STUB_INIT_STACK_FRAME(stackFrame);
3342
3343     JSValue src1 = stackFrame.args[0].jsValue();
3344     JSValue src2 = stackFrame.args[1].jsValue();
3345
3346     bool result = JSValue::strictEqual(stackFrame.callFrame, src1, src2);
3347     CHECK_FOR_EXCEPTION_AT_END();
3348     return JSValue::encode(jsBoolean(result));
3349 }
3350
3351 DEFINE_STUB_FUNCTION(EncodedJSValue, op_to_primitive)
3352 {
3353     STUB_INIT_STACK_FRAME(stackFrame);
3354
3355     return JSValue::encode(stackFrame.args[0].jsValue().toPrimitive(stackFrame.callFrame));
3356 }
3357
3358 DEFINE_STUB_FUNCTION(EncodedJSValue, op_strcat)
3359 {
3360     STUB_INIT_STACK_FRAME(stackFrame);
3361
3362     JSValue result = jsString(stackFrame.callFrame, &stackFrame.callFrame->registers()[stackFrame.args[0].int32()], stackFrame.args[1].int32());
3363     CHECK_FOR_EXCEPTION_AT_END();
3364     return JSValue::encode(result);
3365 }
3366
3367 DEFINE_STUB_FUNCTION(EncodedJSValue, op_nstricteq)
3368 {
3369     STUB_INIT_STACK_FRAME(stackFrame);
3370
3371     JSValue src1 = stackFrame.args[0].jsValue();
3372     JSValue src2 = stackFrame.args[1].jsValue();
3373
3374     bool result = !JSValue::strictEqual(stackFrame.callFrame, src1, src2);
3375     CHECK_FOR_EXCEPTION_AT_END();
3376     return JSValue::encode(jsBoolean(result));
3377 }
3378
3379 DEFINE_STUB_FUNCTION(EncodedJSValue, op_to_jsnumber)
3380 {
3381     STUB_INIT_STACK_FRAME(stackFrame);
3382
3383     JSValue src = stackFrame.args[0].jsValue();
3384     CallFrame* callFrame = stackFrame.callFrame;
3385
3386     JSValue result = src.toJSNumber(callFrame);
3387     CHECK_FOR_EXCEPTION_AT_END();
3388     return JSValue::encode(result);
3389 }
3390
3391 DEFINE_STUB_FUNCTION(EncodedJSValue, op_in)
3392 {
3393     STUB_INIT_STACK_FRAME(stackFrame);
3394
3395     CallFrame* callFrame = stackFrame.callFrame;
3396     JSValue baseVal = stackFrame.args[1].jsValue();
3397
3398     if (!baseVal.isObject()) {
3399         CallFrame* callFrame = stackFrame.callFrame;
3400         CodeBlock* codeBlock = callFrame->codeBlock();
3401         unsigned vPCIndex = codeBlock->bytecodeOffset(callFrame, STUB_RETURN_ADDRESS);
3402         stackFrame.globalData->exception = createInvalidParamError(callFrame, "in", baseVal, vPCIndex, codeBlock);
3403         VM_THROW_EXCEPTION();
3404     }
3405
3406     JSValue propName = stackFrame.args[0].jsValue();
3407     JSObject* baseObj = asObject(baseVal);
3408
3409     uint32_t i;
3410     if (propName.getUInt32(i))
3411         return JSValue::encode(jsBoolean(baseObj->hasProperty(callFrame, i)));
3412
3413     Identifier property(callFrame, propName.toString(callFrame));
3414     CHECK_FOR_EXCEPTION();
3415     return JSValue::encode(jsBoolean(baseObj->hasProperty(callFrame, property)));
3416 }
3417
3418 DEFINE_STUB_FUNCTION(JSObject*, op_push_new_scope)
3419 {
3420     STUB_INIT_STACK_FRAME(stackFrame);
3421
3422     JSObject* scope = new (stackFrame.globalData) JSStaticScopeObject(stackFrame.callFrame, stackFrame.args[0].identifier(), stackFrame.args[1].jsValue(), DontDelete);
3423
3424     CallFrame* callFrame = stackFrame.callFrame;
3425     callFrame->setScopeChain(callFrame->scopeChain()->push(scope));
3426     return scope;
3427 }
3428
3429 DEFINE_STUB_FUNCTION(void, op_jmp_scopes)
3430 {
3431     STUB_INIT_STACK_FRAME(stackFrame);
3432
3433     unsigned count = stackFrame.args[0].int32();
3434     CallFrame* callFrame = stackFrame.callFrame;
3435
3436     ScopeChainNode* tmp = callFrame->scopeChain();
3437     while (count--)
3438         tmp = tmp->pop();
3439     callFrame->setScopeChain(tmp);
3440 }
3441
3442 DEFINE_STUB_FUNCTION(void, op_put_by_index)
3443 {
3444     STUB_INIT_STACK_FRAME(stackFrame);
3445
3446     CallFrame* callFrame = stackFrame.callFrame;
3447     unsigned property = stackFrame.args[1].int32();
3448
3449     stackFrame.args[0].jsValue().put(callFrame, property, stackFrame.args[2].jsValue());
3450 }
3451
3452 DEFINE_STUB_FUNCTION(void*, op_switch_imm)
3453 {
3454     STUB_INIT_STACK_FRAME(stackFrame);
3455
3456     JSValue scrutinee = stackFrame.args[0].jsValue();
3457     unsigned tableIndex = stackFrame.args[1].int32();
3458     CallFrame* callFrame = stackFrame.callFrame;
3459     CodeBlock* codeBlock = callFrame->codeBlock();
3460
3461     if (scrutinee.isInt32())
3462         return codeBlock->immediateSwitchJumpTable(tableIndex).ctiForValue(scrutinee.asInt32()).executableAddress();
3463     else {
3464         double value;
3465         int32_t intValue;
3466         if (scrutinee.getNumber(value) && ((intValue = static_cast<int32_t>(value)) == value))
3467             return codeBlock->immediateSwitchJumpTable(tableIndex).ctiForValue(intValue).executableAddress();
3468         else
3469             return codeBlock->immediateSwitchJumpTable(tableIndex).ctiDefault.executableAddress();
3470     }
3471 }
3472
3473 DEFINE_STUB_FUNCTION(void*, op_switch_char)
3474 {
3475     STUB_INIT_STACK_FRAME(stackFrame);
3476
3477     JSValue scrutinee = stackFrame.args[0].jsValue();
3478     unsigned tableIndex = stackFrame.args[1].int32();
3479     CallFrame* callFrame = stackFrame.callFrame;
3480     CodeBlock* codeBlock = callFrame->codeBlock();
3481
3482     void* result = codeBlock->characterSwitchJumpTable(tableIndex).ctiDefault.executableAddress();
3483
3484     if (scrutinee.isString()) {
3485         StringImpl* value = asString(scrutinee)->value(callFrame).impl();
3486         if (value->length() == 1)
3487             result = codeBlock->characterSwitchJumpTable(tableIndex).ctiForValue(value->characters()[0]).executableAddress();
3488     }
3489
3490     CHECK_FOR_EXCEPTION_AT_END();
3491     return result;
3492 }
3493
3494 DEFINE_STUB_FUNCTION(void*, op_switch_string)
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     void* result = codeBlock->stringSwitchJumpTable(tableIndex).ctiDefault.executableAddress();
3504
3505     if (scrutinee.isString()) {
3506         StringImpl* value = asString(scrutinee)->value(callFrame).impl();
3507         result = codeBlock->stringSwitchJumpTable(tableIndex).ctiForValue(value).executableAddress();
3508     }
3509
3510     CHECK_FOR_EXCEPTION_AT_END();
3511     return result;
3512 }
3513
3514 DEFINE_STUB_FUNCTION(EncodedJSValue, op_del_by_val)
3515 {
3516     STUB_INIT_STACK_FRAME(stackFrame);
3517
3518     CallFrame* callFrame = stackFrame.callFrame;
3519
3520     JSValue baseValue = stackFrame.args[0].jsValue();
3521     JSObject* baseObj = baseValue.toObject(callFrame); // may throw
3522
3523     JSValue subscript = stackFrame.args[1].jsValue();
3524     bool result;
3525     uint32_t i;
3526     if (subscript.getUInt32(i))
3527         result = baseObj->deleteProperty(callFrame, i);
3528     else {
3529         CHECK_FOR_EXCEPTION();
3530         Identifier property(callFrame, subscript.toString(callFrame));
3531         CHECK_FOR_EXCEPTION();
3532         result = baseObj->deleteProperty(callFrame, property);
3533     }
3534
3535     if (!result && callFrame->codeBlock()->isStrictMode())
3536         stackFrame.globalData->exception = createTypeError(stackFrame.callFrame, "Unable to delete property.");
3537
3538     CHECK_FOR_EXCEPTION_AT_END();
3539     return JSValue::encode(jsBoolean(result));
3540 }
3541
3542 DEFINE_STUB_FUNCTION(void, op_put_getter)
3543 {
3544     STUB_INIT_STACK_FRAME(stackFrame);
3545
3546     CallFrame* callFrame = stackFrame.callFrame;
3547
3548     ASSERT(stackFrame.args[0].jsValue().isObject());
3549     JSObject* baseObj = asObject(stackFrame.args[0].jsValue());
3550     ASSERT(stackFrame.args[2].jsValue().isObject());
3551     baseObj->defineGetter(callFrame, stackFrame.args[1].identifier(), asObject(stackFrame.args[2].jsValue()));
3552 }
3553
3554 DEFINE_STUB_FUNCTION(void, op_put_setter)
3555 {
3556     STUB_INIT_STACK_FRAME(stackFrame);
3557
3558     CallFrame* callFrame = stackFrame.callFrame;
3559
3560     ASSERT(stackFrame.args[0].jsValue().isObject());
3561     JSObject* baseObj = asObject(stackFrame.args[0].jsValue());
3562     ASSERT(stackFrame.args[2].jsValue().isObject());
3563     baseObj->defineSetter(callFrame, stackFrame.args[1].identifier(), asObject(stackFrame.args[2].jsValue()));
3564 }
3565
3566 DEFINE_STUB_FUNCTION(JSObject*, op_new_error)
3567 {
3568     STUB_INIT_STACK_FRAME(stackFrame);
3569
3570     CallFrame* callFrame = stackFrame.callFrame;
3571     CodeBlock* codeBlock = callFrame->codeBlock();
3572     unsigned isReference = stackFrame.args[0].int32();
3573     UString message = stackFrame.args[1].jsValue().toString(callFrame);
3574     unsigned bytecodeOffset = stackFrame.args[2].int32();
3575
3576     JSObject* error = isReference ? createReferenceError(callFrame, message) : createSyntaxError(callFrame, message);
3577     unsigned lineNumber = codeBlock->lineNumberForBytecodeOffset(callFrame, bytecodeOffset);
3578     return addErrorInfo(stackFrame.globalData, error, lineNumber, codeBlock->ownerExecutable()->source());
3579 }
3580
3581 DEFINE_STUB_FUNCTION(void, op_debug)
3582 {
3583     STUB_INIT_STACK_FRAME(stackFrame);
3584
3585     CallFrame* callFrame = stackFrame.callFrame;
3586
3587     int debugHookID = stackFrame.args[0].int32();
3588     int firstLine = stackFrame.args[1].int32();
3589     int lastLine = stackFrame.args[2].int32();
3590
3591     stackFrame.globalData->interpreter->debug(callFrame, static_cast<DebugHookID>(debugHookID), firstLine, lastLine);
3592 }
3593
3594 DEFINE_STUB_FUNCTION(void*, vm_throw)
3595 {
3596     STUB_INIT_STACK_FRAME(stackFrame);
3597     JSGlobalData* globalData = stackFrame.globalData;
3598     ExceptionHandler handler = jitThrow(globalData, stackFrame.callFrame, globalData->exception, globalData->exceptionLocation, false);
3599     STUB_SET_RETURN_ADDRESS(handler.catchRoutine);
3600     return handler.callFrame;
3601 }
3602
3603 DEFINE_STUB_FUNCTION(EncodedJSValue, to_object)
3604 {
3605     STUB_INIT_STACK_FRAME(stackFrame);
3606
3607     CallFrame* callFrame = stackFrame.callFrame;
3608     return JSValue::encode(stackFrame.args[0].jsValue().toObject(callFrame));
3609 }
3610
3611 MacroAssemblerCodePtr JITThunks::ctiStub(JSGlobalData* globalData, ThunkGenerator generator)
3612 {
3613     std::pair<CTIStubMap::iterator, bool> entry = m_ctiStubMap.add(generator, MacroAssemblerCodePtr());
3614     if (entry.second)
3615         entry.first->second = generator(globalData, m_executablePool.get());
3616     return entry.first->second;
3617 }
3618
3619 PassRefPtr<NativeExecutable> JITThunks::hostFunctionStub(JSGlobalData* globalData, NativeFunction function)
3620 {
3621     std::pair<HostFunctionStubMap::iterator, bool> entry = m_hostFunctionStubMap.add(function, 0);
3622     if (entry.second)
3623         entry.first->second = NativeExecutable::create(JIT::compileCTINativeCall(globalData, m_executablePool, function), function, ctiNativeConstruct(), callHostFunctionAsConstructor);
3624     return entry.first->second;
3625 }
3626
3627 PassRefPtr<NativeExecutable> JITThunks::hostFunctionStub(JSGlobalData* globalData, NativeFunction function, ThunkGenerator generator)
3628 {
3629     std::pair<HostFunctionStubMap::iterator, bool> entry = m_hostFunctionStubMap.add(function, 0);
3630     if (entry.second) {
3631         MacroAssemblerCodePtr code = globalData->canUseJIT() ? generator(globalData, m_executablePool.get()) : MacroAssemblerCodePtr();
3632         entry.first->second = NativeExecutable::create(code, function, ctiNativeConstruct(), callHostFunctionAsConstructor);
3633     }
3634     return entry.first->second;
3635 }
3636
3637 } // namespace JSC
3638
3639 #endif // ENABLE(JIT)