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