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