[BlackBerry][ARM] Fix cast-align warnings in JavaScriptCore
[WebKit-https.git] / Source / JavaScriptCore / dfg / DFGOperations.cpp
1 /*
2  * Copyright (C) 2011 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
24  */
25
26 #include "config.h"
27 #include "DFGOperations.h"
28
29 #include "Arguments.h"
30 #include "ButterflyInlines.h"
31 #include "CodeBlock.h"
32 #include "CopiedSpaceInlines.h"
33 #include "DFGOSRExit.h"
34 #include "DFGRepatch.h"
35 #include "DFGThunks.h"
36 #include "HostCallReturnValue.h"
37 #include "GetterSetter.h"
38 #include "Interpreter.h"
39 #include "JIT.h"
40 #include "JITExceptions.h"
41 #include "JSActivation.h"
42 #include "JSGlobalData.h"
43 #include "JSNameScope.h"
44 #include "NameInstance.h"
45 #include "ObjectConstructor.h"
46 #include "Operations.h"
47 #include <wtf/InlineASM.h>
48
49 #if ENABLE(JIT)
50
51 #if CPU(MIPS)
52 #if WTF_MIPS_PIC
53 #define LOAD_FUNCTION_TO_T9(function) \
54         ".set noreorder" "\n" \
55         ".cpload $25" "\n" \
56         ".set reorder" "\n" \
57         "la $t9, " LOCAL_REFERENCE(function) "\n"
58 #else
59 #define LOAD_FUNCTION_TO_T9(function) "" "\n"
60 #endif
61 #endif
62
63 #if ENABLE(DFG_JIT)
64
65 #if COMPILER(GCC) && CPU(X86_64)
66
67 #define FUNCTION_WRAPPER_WITH_RETURN_ADDRESS(function, register) \
68     asm( \
69     ".globl " SYMBOL_STRING(function) "\n" \
70     HIDE_SYMBOL(function) "\n" \
71     SYMBOL_STRING(function) ":" "\n" \
72         "mov (%rsp), %" STRINGIZE(register) "\n" \
73         "jmp " LOCAL_REFERENCE(function##WithReturnAddress) "\n" \
74     );
75 #define FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_E(function)    FUNCTION_WRAPPER_WITH_RETURN_ADDRESS(function, rsi)
76 #define FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_ECI(function)  FUNCTION_WRAPPER_WITH_RETURN_ADDRESS(function, rcx)
77 #define FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJI(function)  FUNCTION_WRAPPER_WITH_RETURN_ADDRESS(function, rcx)
78 #define FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJCI(function) FUNCTION_WRAPPER_WITH_RETURN_ADDRESS(function, r8)
79
80 #elif COMPILER(GCC) && CPU(X86)
81
82 #define FUNCTION_WRAPPER_WITH_RETURN_ADDRESS(function, offset) \
83     asm( \
84     ".text" "\n" \
85     ".globl " SYMBOL_STRING(function) "\n" \
86     HIDE_SYMBOL(function) "\n" \
87     SYMBOL_STRING(function) ":" "\n" \
88         "mov (%esp), %eax\n" \
89         "mov %eax, " STRINGIZE(offset) "(%esp)\n" \
90         "jmp " LOCAL_REFERENCE(function##WithReturnAddress) "\n" \
91     );
92 #define FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_E(function)    FUNCTION_WRAPPER_WITH_RETURN_ADDRESS(function, 8)
93 #define FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_ECI(function)  FUNCTION_WRAPPER_WITH_RETURN_ADDRESS(function, 16)
94 #define FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJI(function)  FUNCTION_WRAPPER_WITH_RETURN_ADDRESS(function, 20)
95 #define FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJCI(function) FUNCTION_WRAPPER_WITH_RETURN_ADDRESS(function, 24)
96
97 #elif COMPILER(GCC) && CPU(ARM_THUMB2)
98
99 #define FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_E(function) \
100     asm ( \
101     ".text" "\n" \
102     ".align 2" "\n" \
103     ".globl " SYMBOL_STRING(function) "\n" \
104     HIDE_SYMBOL(function) "\n" \
105     ".thumb" "\n" \
106     ".thumb_func " THUMB_FUNC_PARAM(function) "\n" \
107     SYMBOL_STRING(function) ":" "\n" \
108         "mov a2, lr" "\n" \
109         "b " LOCAL_REFERENCE(function) "WithReturnAddress" "\n" \
110     );
111
112 #define FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_ECI(function) \
113     asm ( \
114     ".text" "\n" \
115     ".align 2" "\n" \
116     ".globl " SYMBOL_STRING(function) "\n" \
117     HIDE_SYMBOL(function) "\n" \
118     ".thumb" "\n" \
119     ".thumb_func " THUMB_FUNC_PARAM(function) "\n" \
120     SYMBOL_STRING(function) ":" "\n" \
121         "mov a4, lr" "\n" \
122         "b " LOCAL_REFERENCE(function) "WithReturnAddress" "\n" \
123     );
124
125 // EncodedJSValue in JSVALUE32_64 is a 64-bit integer. When being compiled in ARM EABI, it must be aligned even-numbered register (r0, r2 or [sp]).
126 // As a result, return address will be at a 4-byte further location in the following cases.
127 #if COMPILER_SUPPORTS(EABI) && CPU(ARM)
128 #define INSTRUCTION_STORE_RETURN_ADDRESS_EJI "str lr, [sp, #4]"
129 #define INSTRUCTION_STORE_RETURN_ADDRESS_EJCI "str lr, [sp, #8]"
130 #else
131 #define INSTRUCTION_STORE_RETURN_ADDRESS_EJI "str lr, [sp, #0]"
132 #define INSTRUCTION_STORE_RETURN_ADDRESS_EJCI "str lr, [sp, #4]"
133 #endif
134
135 #define FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJI(function) \
136     asm ( \
137     ".text" "\n" \
138     ".align 2" "\n" \
139     ".globl " SYMBOL_STRING(function) "\n" \
140     HIDE_SYMBOL(function) "\n" \
141     ".thumb" "\n" \
142     ".thumb_func " THUMB_FUNC_PARAM(function) "\n" \
143     SYMBOL_STRING(function) ":" "\n" \
144         INSTRUCTION_STORE_RETURN_ADDRESS_EJI "\n" \
145         "b " LOCAL_REFERENCE(function) "WithReturnAddress" "\n" \
146     );
147
148 #define FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJCI(function) \
149     asm ( \
150     ".text" "\n" \
151     ".align 2" "\n" \
152     ".globl " SYMBOL_STRING(function) "\n" \
153     HIDE_SYMBOL(function) "\n" \
154     ".thumb" "\n" \
155     ".thumb_func " THUMB_FUNC_PARAM(function) "\n" \
156     SYMBOL_STRING(function) ":" "\n" \
157         INSTRUCTION_STORE_RETURN_ADDRESS_EJCI "\n" \
158         "b " LOCAL_REFERENCE(function) "WithReturnAddress" "\n" \
159     );
160
161 #elif COMPILER(GCC) && CPU(ARM_TRADITIONAL)
162
163 #define FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_E(function) \
164     asm ( \
165     ".text" "\n" \
166     ".globl " SYMBOL_STRING(function) "\n" \
167     HIDE_SYMBOL(function) "\n" \
168     INLINE_ARM_FUNCTION(function) \
169     SYMBOL_STRING(function) ":" "\n" \
170         "mov a2, lr" "\n" \
171         "b " LOCAL_REFERENCE(function) "WithReturnAddress" "\n" \
172     );
173
174 #define FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_ECI(function) \
175     asm ( \
176     ".text" "\n" \
177     ".globl " SYMBOL_STRING(function) "\n" \
178     HIDE_SYMBOL(function) "\n" \
179     INLINE_ARM_FUNCTION(function) \
180     SYMBOL_STRING(function) ":" "\n" \
181         "mov a4, lr" "\n" \
182         "b " LOCAL_REFERENCE(function) "WithReturnAddress" "\n" \
183     );
184
185 // EncodedJSValue in JSVALUE32_64 is a 64-bit integer. When being compiled in ARM EABI, it must be aligned even-numbered register (r0, r2 or [sp]).
186 // As a result, return address will be at a 4-byte further location in the following cases.
187 #if COMPILER_SUPPORTS(EABI) && CPU(ARM)
188 #define INSTRUCTION_STORE_RETURN_ADDRESS_EJI "str lr, [sp, #4]"
189 #define INSTRUCTION_STORE_RETURN_ADDRESS_EJCI "str lr, [sp, #8]"
190 #else
191 #define INSTRUCTION_STORE_RETURN_ADDRESS_EJI "str lr, [sp, #0]"
192 #define INSTRUCTION_STORE_RETURN_ADDRESS_EJCI "str lr, [sp, #4]"
193 #endif
194
195 #define FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJI(function) \
196     asm ( \
197     ".text" "\n" \
198     ".globl " SYMBOL_STRING(function) "\n" \
199     HIDE_SYMBOL(function) "\n" \
200     INLINE_ARM_FUNCTION(function) \
201     SYMBOL_STRING(function) ":" "\n" \
202         INSTRUCTION_STORE_RETURN_ADDRESS_EJI "\n" \
203         "b " LOCAL_REFERENCE(function) "WithReturnAddress" "\n" \
204     );
205
206 #define FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJCI(function) \
207     asm ( \
208     ".text" "\n" \
209     ".globl " SYMBOL_STRING(function) "\n" \
210     HIDE_SYMBOL(function) "\n" \
211     INLINE_ARM_FUNCTION(function) \
212     SYMBOL_STRING(function) ":" "\n" \
213         INSTRUCTION_STORE_RETURN_ADDRESS_EJCI "\n" \
214         "b " LOCAL_REFERENCE(function) "WithReturnAddress" "\n" \
215     );
216
217 #elif COMPILER(GCC) && CPU(MIPS)
218
219 #define FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_E(function) \
220     asm( \
221     ".text" "\n" \
222     ".globl " SYMBOL_STRING(function) "\n" \
223     HIDE_SYMBOL(function) "\n" \
224     SYMBOL_STRING(function) ":" "\n" \
225     LOAD_FUNCTION_TO_T9(function##WithReturnAddress) \
226         "move $a1, $ra" "\n" \
227         "b " LOCAL_REFERENCE(function) "WithReturnAddress" "\n" \
228     );
229
230 #define FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_ECI(function) \
231     asm( \
232     ".text" "\n" \
233     ".globl " SYMBOL_STRING(function) "\n" \
234     HIDE_SYMBOL(function) "\n" \
235     SYMBOL_STRING(function) ":" "\n" \
236     LOAD_FUNCTION_TO_T9(function##WithReturnAddress) \
237         "move $a3, $ra" "\n" \
238         "b " LOCAL_REFERENCE(function) "WithReturnAddress" "\n" \
239     );
240
241 #define FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJI(function) \
242     asm( \
243     ".text" "\n" \
244     ".globl " SYMBOL_STRING(function) "\n" \
245     HIDE_SYMBOL(function) "\n" \
246     SYMBOL_STRING(function) ":" "\n" \
247     LOAD_FUNCTION_TO_T9(function##WithReturnAddress) \
248         "sw $ra, 20($sp)" "\n" \
249         "b " LOCAL_REFERENCE(function) "WithReturnAddress" "\n" \
250     );
251
252 #define FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJCI(function) \
253     asm( \
254     ".text" "\n" \
255     ".globl " SYMBOL_STRING(function) "\n" \
256     HIDE_SYMBOL(function) "\n" \
257     SYMBOL_STRING(function) ":" "\n" \
258     LOAD_FUNCTION_TO_T9(function##WithReturnAddress) \
259         "sw $ra, 24($sp)" "\n" \
260         "b " LOCAL_REFERENCE(function) "WithReturnAddress" "\n" \
261     );
262
263 #endif
264
265 #define P_FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_E(function) \
266 void* DFG_OPERATION function##WithReturnAddress(ExecState*, ReturnAddressPtr) REFERENCED_FROM_ASM WTF_INTERNAL; \
267 FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_E(function)
268
269 #define J_FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_ECI(function) \
270 EncodedJSValue DFG_OPERATION function##WithReturnAddress(ExecState*, JSCell*, Identifier*, ReturnAddressPtr) REFERENCED_FROM_ASM WTF_INTERNAL; \
271 FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_ECI(function)
272
273 #define J_FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJI(function) \
274 EncodedJSValue DFG_OPERATION function##WithReturnAddress(ExecState*, EncodedJSValue, Identifier*, ReturnAddressPtr) REFERENCED_FROM_ASM WTF_INTERNAL; \
275 FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJI(function)
276
277 #define V_FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJCI(function) \
278 void DFG_OPERATION function##WithReturnAddress(ExecState*, EncodedJSValue, JSCell*, Identifier*, ReturnAddressPtr) REFERENCED_FROM_ASM WTF_INTERNAL; \
279 FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJCI(function)
280
281 namespace JSC { namespace DFG {
282
283 template<bool strict>
284 static inline void putByVal(ExecState* exec, JSValue baseValue, uint32_t index, JSValue value)
285 {
286     JSGlobalData& globalData = exec->globalData();
287     NativeCallFrameTracer tracer(&globalData, exec);
288     
289     if (baseValue.isObject()) {
290         JSObject* object = asObject(baseValue);
291         if (object->canSetIndexQuickly(index)) {
292             object->setIndexQuickly(globalData, index, value);
293             return;
294         }
295
296         object->methodTable()->putByIndex(object, exec, index, value, strict);
297         return;
298     }
299
300     baseValue.putByIndex(exec, index, value, strict);
301 }
302
303 template<bool strict>
304 ALWAYS_INLINE static void DFG_OPERATION operationPutByValInternal(ExecState* exec, EncodedJSValue encodedBase, EncodedJSValue encodedProperty, EncodedJSValue encodedValue)
305 {
306     JSGlobalData* globalData = &exec->globalData();
307     NativeCallFrameTracer tracer(globalData, exec);
308
309     JSValue baseValue = JSValue::decode(encodedBase);
310     JSValue property = JSValue::decode(encodedProperty);
311     JSValue value = JSValue::decode(encodedValue);
312
313     if (LIKELY(property.isUInt32())) {
314         putByVal<strict>(exec, baseValue, property.asUInt32(), value);
315         return;
316     }
317
318     if (property.isDouble()) {
319         double propertyAsDouble = property.asDouble();
320         uint32_t propertyAsUInt32 = static_cast<uint32_t>(propertyAsDouble);
321         if (propertyAsDouble == propertyAsUInt32) {
322             putByVal<strict>(exec, baseValue, propertyAsUInt32, value);
323             return;
324         }
325     }
326
327     if (isName(property)) {
328         PutPropertySlot slot(strict);
329         baseValue.put(exec, jsCast<NameInstance*>(property.asCell())->privateName(), value, slot);
330         return;
331     }
332
333     // Don't put to an object if toString throws an exception.
334     Identifier ident(exec, property.toString(exec)->value(exec));
335     if (!globalData->exception) {
336         PutPropertySlot slot(strict);
337         baseValue.put(exec, ident, value, slot);
338     }
339 }
340
341 extern "C" {
342
343 EncodedJSValue DFG_OPERATION operationConvertThis(ExecState* exec, EncodedJSValue encodedOp)
344 {
345     JSGlobalData* globalData = &exec->globalData();
346     NativeCallFrameTracer tracer(globalData, exec);
347
348     return JSValue::encode(JSValue::decode(encodedOp).toThisObject(exec));
349 }
350
351 JSCell* DFG_OPERATION operationCreateThis(ExecState* exec, JSObject* constructor, int32_t inlineCapacity)
352 {
353     JSGlobalData* globalData = &exec->globalData();
354     NativeCallFrameTracer tracer(globalData, exec);
355
356 #if !ASSERT_DISABLED
357     ConstructData constructData;
358     ASSERT(jsCast<JSFunction*>(constructor)->methodTable()->getConstructData(jsCast<JSFunction*>(constructor), constructData) == ConstructTypeJS);
359 #endif
360     
361     return constructEmptyObject(exec, jsCast<JSFunction*>(constructor)->allocationProfile(exec, inlineCapacity)->structure());
362 }
363
364 JSCell* DFG_OPERATION operationNewObject(ExecState* exec, Structure* structure)
365 {
366     JSGlobalData* globalData = &exec->globalData();
367     NativeCallFrameTracer tracer(globalData, exec);
368     
369     return constructEmptyObject(exec, structure);
370 }
371
372 EncodedJSValue DFG_OPERATION operationValueAdd(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
373 {
374     JSGlobalData* globalData = &exec->globalData();
375     NativeCallFrameTracer tracer(globalData, exec);
376     
377     JSValue op1 = JSValue::decode(encodedOp1);
378     JSValue op2 = JSValue::decode(encodedOp2);
379     
380     return JSValue::encode(jsAdd(exec, op1, op2));
381 }
382
383 EncodedJSValue DFG_OPERATION operationValueAddNotNumber(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
384 {
385     JSGlobalData* globalData = &exec->globalData();
386     NativeCallFrameTracer tracer(globalData, exec);
387     
388     JSValue op1 = JSValue::decode(encodedOp1);
389     JSValue op2 = JSValue::decode(encodedOp2);
390     
391     ASSERT(!op1.isNumber() || !op2.isNumber());
392     
393     if (op1.isString() && !op2.isObject())
394         return JSValue::encode(jsString(exec, asString(op1), op2.toString(exec)));
395
396     return JSValue::encode(jsAddSlowCase(exec, op1, op2));
397 }
398
399 static inline EncodedJSValue getByVal(ExecState* exec, JSCell* base, uint32_t index)
400 {
401     JSGlobalData& globalData = exec->globalData();
402     NativeCallFrameTracer tracer(&globalData, exec);
403     
404     if (base->isObject()) {
405         JSObject* object = asObject(base);
406         if (object->canGetIndexQuickly(index))
407             return JSValue::encode(object->getIndexQuickly(index));
408     }
409
410     if (isJSString(base) && asString(base)->canGetIndex(index))
411         return JSValue::encode(asString(base)->getIndex(exec, index));
412
413     return JSValue::encode(JSValue(base).get(exec, index));
414 }
415
416 EncodedJSValue DFG_OPERATION operationGetByVal(ExecState* exec, EncodedJSValue encodedBase, EncodedJSValue encodedProperty)
417 {
418     JSGlobalData* globalData = &exec->globalData();
419     NativeCallFrameTracer tracer(globalData, exec);
420     
421     JSValue baseValue = JSValue::decode(encodedBase);
422     JSValue property = JSValue::decode(encodedProperty);
423
424     if (LIKELY(baseValue.isCell())) {
425         JSCell* base = baseValue.asCell();
426
427         if (property.isUInt32()) {
428             return getByVal(exec, base, property.asUInt32());
429         } else if (property.isDouble()) {
430             double propertyAsDouble = property.asDouble();
431             uint32_t propertyAsUInt32 = static_cast<uint32_t>(propertyAsDouble);
432             if (propertyAsUInt32 == propertyAsDouble)
433                 return getByVal(exec, base, propertyAsUInt32);
434         } else if (property.isString()) {
435             if (JSValue result = base->fastGetOwnProperty(exec, asString(property)->value(exec)))
436                 return JSValue::encode(result);
437         }
438     }
439
440     if (isName(property))
441         return JSValue::encode(baseValue.get(exec, jsCast<NameInstance*>(property.asCell())->privateName()));
442
443     Identifier ident(exec, property.toString(exec)->value(exec));
444     return JSValue::encode(baseValue.get(exec, ident));
445 }
446
447 EncodedJSValue DFG_OPERATION operationGetByValCell(ExecState* exec, JSCell* base, EncodedJSValue encodedProperty)
448 {
449     JSGlobalData* globalData = &exec->globalData();
450     NativeCallFrameTracer tracer(globalData, exec);
451     
452     JSValue property = JSValue::decode(encodedProperty);
453
454     if (property.isUInt32())
455         return getByVal(exec, base, property.asUInt32());
456     if (property.isDouble()) {
457         double propertyAsDouble = property.asDouble();
458         uint32_t propertyAsUInt32 = static_cast<uint32_t>(propertyAsDouble);
459         if (propertyAsUInt32 == propertyAsDouble)
460             return getByVal(exec, base, propertyAsUInt32);
461     } else if (property.isString()) {
462         if (JSValue result = base->fastGetOwnProperty(exec, asString(property)->value(exec)))
463             return JSValue::encode(result);
464     }
465
466     if (isName(property))
467         return JSValue::encode(JSValue(base).get(exec, jsCast<NameInstance*>(property.asCell())->privateName()));
468
469     Identifier ident(exec, property.toString(exec)->value(exec));
470     return JSValue::encode(JSValue(base).get(exec, ident));
471 }
472
473 EncodedJSValue DFG_OPERATION operationGetByValArrayInt(ExecState* exec, JSArray* base, int32_t index)
474 {
475     JSGlobalData* globalData = &exec->globalData();
476     NativeCallFrameTracer tracer(globalData, exec);
477     
478     if (index < 0) {
479         // Go the slowest way possible becase negative indices don't use indexed storage.
480         return JSValue::encode(JSValue(base).get(exec, Identifier::from(exec, index)));
481     }
482
483     // Use this since we know that the value is out of bounds.
484     return JSValue::encode(JSValue(base).get(exec, index));
485 }
486
487 EncodedJSValue DFG_OPERATION operationGetById(ExecState* exec, EncodedJSValue base, Identifier* propertyName)
488 {
489     JSGlobalData* globalData = &exec->globalData();
490     NativeCallFrameTracer tracer(globalData, exec);
491     
492     JSValue baseValue = JSValue::decode(base);
493     PropertySlot slot(baseValue);
494     return JSValue::encode(baseValue.get(exec, *propertyName, slot));
495 }
496
497 J_FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJI(operationGetByIdBuildList);
498 EncodedJSValue DFG_OPERATION operationGetByIdBuildListWithReturnAddress(ExecState* exec, EncodedJSValue base, Identifier* propertyName, ReturnAddressPtr returnAddress)
499 {
500     JSGlobalData* globalData = &exec->globalData();
501     NativeCallFrameTracer tracer(globalData, exec);
502     
503     StructureStubInfo& stubInfo = exec->codeBlock()->getStubInfo(returnAddress);
504     AccessType accessType = static_cast<AccessType>(stubInfo.accessType);
505
506     JSValue baseValue = JSValue::decode(base);
507     PropertySlot slot(baseValue);
508     JSValue result = baseValue.get(exec, *propertyName, slot);
509
510     if (accessType == static_cast<AccessType>(stubInfo.accessType))
511         dfgBuildGetByIDList(exec, baseValue, *propertyName, slot, stubInfo);
512
513     return JSValue::encode(result);
514 }
515
516 J_FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJI(operationGetByIdProtoBuildList);
517 EncodedJSValue DFG_OPERATION operationGetByIdProtoBuildListWithReturnAddress(ExecState* exec, EncodedJSValue base, Identifier* propertyName, ReturnAddressPtr returnAddress)
518 {
519     JSGlobalData* globalData = &exec->globalData();
520     NativeCallFrameTracer tracer(globalData, exec);
521     
522     StructureStubInfo& stubInfo = exec->codeBlock()->getStubInfo(returnAddress);
523     AccessType accessType = static_cast<AccessType>(stubInfo.accessType);
524
525     JSValue baseValue = JSValue::decode(base);
526     PropertySlot slot(baseValue);
527     JSValue result = baseValue.get(exec, *propertyName, slot);
528     
529     if (accessType == static_cast<AccessType>(stubInfo.accessType))
530         dfgBuildGetByIDProtoList(exec, baseValue, *propertyName, slot, stubInfo);
531
532     return JSValue::encode(result);
533 }
534
535 J_FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJI(operationGetByIdOptimize);
536 EncodedJSValue DFG_OPERATION operationGetByIdOptimizeWithReturnAddress(ExecState* exec, EncodedJSValue base, Identifier* propertyName, ReturnAddressPtr returnAddress)
537 {
538     JSGlobalData* globalData = &exec->globalData();
539     NativeCallFrameTracer tracer(globalData, exec);
540     
541     StructureStubInfo& stubInfo = exec->codeBlock()->getStubInfo(returnAddress);
542     AccessType accessType = static_cast<AccessType>(stubInfo.accessType);
543
544     JSValue baseValue = JSValue::decode(base);
545     PropertySlot slot(baseValue);
546     JSValue result = baseValue.get(exec, *propertyName, slot);
547     
548     if (accessType == static_cast<AccessType>(stubInfo.accessType)) {
549         if (stubInfo.seen)
550             dfgRepatchGetByID(exec, baseValue, *propertyName, slot, stubInfo);
551         else
552             stubInfo.seen = true;
553     }
554
555     return JSValue::encode(result);
556 }
557
558 EncodedJSValue DFG_OPERATION operationCallCustomGetter(ExecState* exec, JSCell* base, PropertySlot::GetValueFunc function, Identifier* ident)
559 {
560     JSGlobalData* globalData = &exec->globalData();
561     NativeCallFrameTracer tracer(globalData, exec);
562     
563     return JSValue::encode(function(exec, asObject(base), *ident));
564 }
565
566 EncodedJSValue DFG_OPERATION operationCallGetter(ExecState* exec, JSCell* base, JSCell* value)
567 {
568     JSGlobalData* globalData = &exec->globalData();
569     NativeCallFrameTracer tracer(globalData, exec);
570     
571     GetterSetter* getterSetter = asGetterSetter(value);
572     JSObject* getter = getterSetter->getter();
573     if (!getter)
574         return JSValue::encode(jsUndefined());
575     CallData callData;
576     CallType callType = getter->methodTable()->getCallData(getter, callData);
577     return JSValue::encode(call(exec, getter, callType, callData, asObject(base), ArgList()));
578 }
579
580 void DFG_OPERATION operationPutByValStrict(ExecState* exec, EncodedJSValue encodedBase, EncodedJSValue encodedProperty, EncodedJSValue encodedValue)
581 {
582     JSGlobalData* globalData = &exec->globalData();
583     NativeCallFrameTracer tracer(globalData, exec);
584     
585     operationPutByValInternal<true>(exec, encodedBase, encodedProperty, encodedValue);
586 }
587
588 void DFG_OPERATION operationPutByValNonStrict(ExecState* exec, EncodedJSValue encodedBase, EncodedJSValue encodedProperty, EncodedJSValue encodedValue)
589 {
590     JSGlobalData* globalData = &exec->globalData();
591     NativeCallFrameTracer tracer(globalData, exec);
592     
593     operationPutByValInternal<false>(exec, encodedBase, encodedProperty, encodedValue);
594 }
595
596 void DFG_OPERATION operationPutByValCellStrict(ExecState* exec, JSCell* cell, EncodedJSValue encodedProperty, EncodedJSValue encodedValue)
597 {
598     JSGlobalData* globalData = &exec->globalData();
599     NativeCallFrameTracer tracer(globalData, exec);
600     
601     operationPutByValInternal<true>(exec, JSValue::encode(cell), encodedProperty, encodedValue);
602 }
603
604 void DFG_OPERATION operationPutByValCellNonStrict(ExecState* exec, JSCell* cell, EncodedJSValue encodedProperty, EncodedJSValue encodedValue)
605 {
606     JSGlobalData* globalData = &exec->globalData();
607     NativeCallFrameTracer tracer(globalData, exec);
608     
609     operationPutByValInternal<false>(exec, JSValue::encode(cell), encodedProperty, encodedValue);
610 }
611
612 void DFG_OPERATION operationPutByValBeyondArrayBoundsStrict(ExecState* exec, JSObject* array, int32_t index, EncodedJSValue encodedValue)
613 {
614     JSGlobalData* globalData = &exec->globalData();
615     NativeCallFrameTracer tracer(globalData, exec);
616     
617     if (index >= 0) {
618         array->putByIndexInline(exec, index, JSValue::decode(encodedValue), true);
619         return;
620     }
621     
622     PutPropertySlot slot(true);
623     array->methodTable()->put(
624         array, exec, Identifier::from(exec, index), JSValue::decode(encodedValue), slot);
625 }
626
627 void DFG_OPERATION operationPutByValBeyondArrayBoundsNonStrict(ExecState* exec, JSObject* array, int32_t index, EncodedJSValue encodedValue)
628 {
629     JSGlobalData* globalData = &exec->globalData();
630     NativeCallFrameTracer tracer(globalData, exec);
631     
632     if (index >= 0) {
633         array->putByIndexInline(exec, index, JSValue::decode(encodedValue), false);
634         return;
635     }
636     
637     PutPropertySlot slot(false);
638     array->methodTable()->put(
639         array, exec, Identifier::from(exec, index), JSValue::decode(encodedValue), slot);
640 }
641
642 void DFG_OPERATION operationPutDoubleByValBeyondArrayBoundsStrict(ExecState* exec, JSObject* array, int32_t index, double value)
643 {
644     JSGlobalData* globalData = &exec->globalData();
645     NativeCallFrameTracer tracer(globalData, exec);
646     
647     JSValue jsValue = JSValue(JSValue::EncodeAsDouble, value);
648     
649     if (index >= 0) {
650         array->putByIndexInline(exec, index, jsValue, true);
651         return;
652     }
653     
654     PutPropertySlot slot(true);
655     array->methodTable()->put(
656         array, exec, Identifier::from(exec, index), jsValue, slot);
657 }
658
659 void DFG_OPERATION operationPutDoubleByValBeyondArrayBoundsNonStrict(ExecState* exec, JSObject* array, int32_t index, double value)
660 {
661     JSGlobalData* globalData = &exec->globalData();
662     NativeCallFrameTracer tracer(globalData, exec);
663     
664     JSValue jsValue = JSValue(JSValue::EncodeAsDouble, value);
665     
666     if (index >= 0) {
667         array->putByIndexInline(exec, index, jsValue, false);
668         return;
669     }
670     
671     PutPropertySlot slot(false);
672     array->methodTable()->put(
673         array, exec, Identifier::from(exec, index), jsValue, slot);
674 }
675
676 EncodedJSValue DFG_OPERATION operationArrayPush(ExecState* exec, EncodedJSValue encodedValue, JSArray* array)
677 {
678     JSGlobalData* globalData = &exec->globalData();
679     NativeCallFrameTracer tracer(globalData, exec);
680     
681     array->push(exec, JSValue::decode(encodedValue));
682     return JSValue::encode(jsNumber(array->length()));
683 }
684
685 EncodedJSValue DFG_OPERATION operationArrayPushDouble(ExecState* exec, double value, JSArray* array)
686 {
687     JSGlobalData* globalData = &exec->globalData();
688     NativeCallFrameTracer tracer(globalData, exec);
689     
690     array->push(exec, JSValue(JSValue::EncodeAsDouble, value));
691     return JSValue::encode(jsNumber(array->length()));
692 }
693
694 EncodedJSValue DFG_OPERATION operationArrayPop(ExecState* exec, JSArray* array)
695 {
696     JSGlobalData* globalData = &exec->globalData();
697     NativeCallFrameTracer tracer(globalData, exec);
698     
699     return JSValue::encode(array->pop(exec));
700 }
701         
702 EncodedJSValue DFG_OPERATION operationArrayPopAndRecoverLength(ExecState* exec, JSArray* array)
703 {
704     JSGlobalData* globalData = &exec->globalData();
705     NativeCallFrameTracer tracer(globalData, exec);
706     
707     array->butterfly()->setPublicLength(array->butterfly()->publicLength() + 1);
708     
709     return JSValue::encode(array->pop(exec));
710 }
711         
712 EncodedJSValue DFG_OPERATION operationRegExpExec(ExecState* exec, JSCell* base, JSCell* argument)
713 {
714     JSGlobalData& globalData = exec->globalData();
715     NativeCallFrameTracer tracer(&globalData, exec);
716     
717     if (!base->inherits(&RegExpObject::s_info))
718         return throwVMTypeError(exec);
719
720     ASSERT(argument->isString() || argument->isObject());
721     JSString* input = argument->isString() ? asString(argument) : asObject(argument)->toString(exec);
722     return JSValue::encode(asRegExpObject(base)->exec(exec, input));
723 }
724         
725 size_t DFG_OPERATION operationRegExpTest(ExecState* exec, JSCell* base, JSCell* argument)
726 {
727     JSGlobalData& globalData = exec->globalData();
728     NativeCallFrameTracer tracer(&globalData, exec);
729
730     if (!base->inherits(&RegExpObject::s_info)) {
731         throwTypeError(exec);
732         return false;
733     }
734
735     ASSERT(argument->isString() || argument->isObject());
736     JSString* input = argument->isString() ? asString(argument) : asObject(argument)->toString(exec);
737     return asRegExpObject(base)->test(exec, input);
738 }
739         
740 void DFG_OPERATION operationPutByIdStrict(ExecState* exec, EncodedJSValue encodedValue, JSCell* base, Identifier* propertyName)
741 {
742     JSGlobalData* globalData = &exec->globalData();
743     NativeCallFrameTracer tracer(globalData, exec);
744     
745     PutPropertySlot slot(true);
746     base->methodTable()->put(base, exec, *propertyName, JSValue::decode(encodedValue), slot);
747 }
748
749 void DFG_OPERATION operationPutByIdNonStrict(ExecState* exec, EncodedJSValue encodedValue, JSCell* base, Identifier* propertyName)
750 {
751     JSGlobalData* globalData = &exec->globalData();
752     NativeCallFrameTracer tracer(globalData, exec);
753     
754     PutPropertySlot slot(false);
755     base->methodTable()->put(base, exec, *propertyName, JSValue::decode(encodedValue), slot);
756 }
757
758 void DFG_OPERATION operationPutByIdDirectStrict(ExecState* exec, EncodedJSValue encodedValue, JSCell* base, Identifier* propertyName)
759 {
760     JSGlobalData* globalData = &exec->globalData();
761     NativeCallFrameTracer tracer(globalData, exec);
762     
763     PutPropertySlot slot(true);
764     ASSERT(base->isObject());
765     asObject(base)->putDirect(exec->globalData(), *propertyName, JSValue::decode(encodedValue), slot);
766 }
767
768 void DFG_OPERATION operationPutByIdDirectNonStrict(ExecState* exec, EncodedJSValue encodedValue, JSCell* base, Identifier* propertyName)
769 {
770     JSGlobalData* globalData = &exec->globalData();
771     NativeCallFrameTracer tracer(globalData, exec);
772     
773     PutPropertySlot slot(false);
774     ASSERT(base->isObject());
775     asObject(base)->putDirect(exec->globalData(), *propertyName, JSValue::decode(encodedValue), slot);
776 }
777
778 V_FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJCI(operationPutByIdStrictOptimize);
779 void DFG_OPERATION operationPutByIdStrictOptimizeWithReturnAddress(ExecState* exec, EncodedJSValue encodedValue, JSCell* base, Identifier* propertyName, ReturnAddressPtr returnAddress)
780 {
781     JSGlobalData* globalData = &exec->globalData();
782     NativeCallFrameTracer tracer(globalData, exec);
783     
784     StructureStubInfo& stubInfo = exec->codeBlock()->getStubInfo(returnAddress);
785     AccessType accessType = static_cast<AccessType>(stubInfo.accessType);
786
787     JSValue value = JSValue::decode(encodedValue);
788     JSValue baseValue(base);
789     PutPropertySlot slot(true);
790     
791     baseValue.put(exec, *propertyName, value, slot);
792     
793     if (accessType != static_cast<AccessType>(stubInfo.accessType))
794         return;
795     
796     if (stubInfo.seen)
797         dfgRepatchPutByID(exec, baseValue, *propertyName, slot, stubInfo, NotDirect);
798     else
799         stubInfo.seen = true;
800 }
801
802 V_FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJCI(operationPutByIdNonStrictOptimize);
803 void DFG_OPERATION operationPutByIdNonStrictOptimizeWithReturnAddress(ExecState* exec, EncodedJSValue encodedValue, JSCell* base, Identifier* propertyName, ReturnAddressPtr returnAddress)
804 {
805     JSGlobalData* globalData = &exec->globalData();
806     NativeCallFrameTracer tracer(globalData, exec);
807     
808     StructureStubInfo& stubInfo = exec->codeBlock()->getStubInfo(returnAddress);
809     AccessType accessType = static_cast<AccessType>(stubInfo.accessType);
810
811     JSValue value = JSValue::decode(encodedValue);
812     JSValue baseValue(base);
813     PutPropertySlot slot(false);
814     
815     baseValue.put(exec, *propertyName, value, slot);
816     
817     if (accessType != static_cast<AccessType>(stubInfo.accessType))
818         return;
819     
820     if (stubInfo.seen)
821         dfgRepatchPutByID(exec, baseValue, *propertyName, slot, stubInfo, NotDirect);
822     else
823         stubInfo.seen = true;
824 }
825
826 V_FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJCI(operationPutByIdDirectStrictOptimize);
827 void DFG_OPERATION operationPutByIdDirectStrictOptimizeWithReturnAddress(ExecState* exec, EncodedJSValue encodedValue, JSCell* base, Identifier* propertyName, ReturnAddressPtr returnAddress)
828 {
829     JSGlobalData* globalData = &exec->globalData();
830     NativeCallFrameTracer tracer(globalData, exec);
831     
832     StructureStubInfo& stubInfo = exec->codeBlock()->getStubInfo(returnAddress);
833     AccessType accessType = static_cast<AccessType>(stubInfo.accessType);
834
835     JSValue value = JSValue::decode(encodedValue);
836     PutPropertySlot slot(true);
837     
838     ASSERT(base->isObject());
839     asObject(base)->putDirect(exec->globalData(), *propertyName, value, slot);
840     
841     if (accessType != static_cast<AccessType>(stubInfo.accessType))
842         return;
843     
844     if (stubInfo.seen)
845         dfgRepatchPutByID(exec, base, *propertyName, slot, stubInfo, Direct);
846     else
847         stubInfo.seen = true;
848 }
849
850 V_FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJCI(operationPutByIdDirectNonStrictOptimize);
851 void DFG_OPERATION operationPutByIdDirectNonStrictOptimizeWithReturnAddress(ExecState* exec, EncodedJSValue encodedValue, JSCell* base, Identifier* propertyName, ReturnAddressPtr returnAddress)
852 {
853     JSGlobalData* globalData = &exec->globalData();
854     NativeCallFrameTracer tracer(globalData, exec);
855     
856     StructureStubInfo& stubInfo = exec->codeBlock()->getStubInfo(returnAddress);
857     AccessType accessType = static_cast<AccessType>(stubInfo.accessType);
858
859     JSValue value = JSValue::decode(encodedValue);
860     PutPropertySlot slot(false);
861     
862     ASSERT(base->isObject());
863     asObject(base)->putDirect(exec->globalData(), *propertyName, value, slot);
864     
865     if (accessType != static_cast<AccessType>(stubInfo.accessType))
866         return;
867     
868     if (stubInfo.seen)
869         dfgRepatchPutByID(exec, base, *propertyName, slot, stubInfo, Direct);
870     else
871         stubInfo.seen = true;
872 }
873
874 V_FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJCI(operationPutByIdStrictBuildList);
875 void DFG_OPERATION operationPutByIdStrictBuildListWithReturnAddress(ExecState* exec, EncodedJSValue encodedValue, JSCell* base, Identifier* propertyName, ReturnAddressPtr returnAddress)
876 {
877     JSGlobalData* globalData = &exec->globalData();
878     NativeCallFrameTracer tracer(globalData, exec);
879     
880     StructureStubInfo& stubInfo = exec->codeBlock()->getStubInfo(returnAddress);
881     AccessType accessType = static_cast<AccessType>(stubInfo.accessType);
882
883     JSValue value = JSValue::decode(encodedValue);
884     JSValue baseValue(base);
885     PutPropertySlot slot(true);
886     
887     baseValue.put(exec, *propertyName, value, slot);
888     
889     if (accessType != static_cast<AccessType>(stubInfo.accessType))
890         return;
891     
892     dfgBuildPutByIdList(exec, baseValue, *propertyName, slot, stubInfo, NotDirect);
893 }
894
895 V_FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJCI(operationPutByIdNonStrictBuildList);
896 void DFG_OPERATION operationPutByIdNonStrictBuildListWithReturnAddress(ExecState* exec, EncodedJSValue encodedValue, JSCell* base, Identifier* propertyName, ReturnAddressPtr returnAddress)
897 {
898     JSGlobalData* globalData = &exec->globalData();
899     NativeCallFrameTracer tracer(globalData, exec);
900     
901     StructureStubInfo& stubInfo = exec->codeBlock()->getStubInfo(returnAddress);
902     AccessType accessType = static_cast<AccessType>(stubInfo.accessType);
903
904     JSValue value = JSValue::decode(encodedValue);
905     JSValue baseValue(base);
906     PutPropertySlot slot(false);
907     
908     baseValue.put(exec, *propertyName, value, slot);
909     
910     if (accessType != static_cast<AccessType>(stubInfo.accessType))
911         return;
912     
913     dfgBuildPutByIdList(exec, baseValue, *propertyName, slot, stubInfo, NotDirect);
914 }
915
916 V_FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJCI(operationPutByIdDirectStrictBuildList);
917 void DFG_OPERATION operationPutByIdDirectStrictBuildListWithReturnAddress(ExecState* exec, EncodedJSValue encodedValue, JSCell* base, Identifier* propertyName, ReturnAddressPtr returnAddress)
918 {
919     JSGlobalData* globalData = &exec->globalData();
920     NativeCallFrameTracer tracer(globalData, exec);
921     
922     StructureStubInfo& stubInfo = exec->codeBlock()->getStubInfo(returnAddress);
923     AccessType accessType = static_cast<AccessType>(stubInfo.accessType);
924     
925     JSValue value = JSValue::decode(encodedValue);
926     PutPropertySlot slot(true);
927     
928     ASSERT(base->isObject());
929     asObject(base)->putDirect(exec->globalData(), *propertyName, value, slot);
930     
931     if (accessType != static_cast<AccessType>(stubInfo.accessType))
932         return;
933     
934     dfgBuildPutByIdList(exec, base, *propertyName, slot, stubInfo, Direct);
935 }
936
937 V_FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJCI(operationPutByIdDirectNonStrictBuildList);
938 void DFG_OPERATION operationPutByIdDirectNonStrictBuildListWithReturnAddress(ExecState* exec, EncodedJSValue encodedValue, JSCell* base, Identifier* propertyName, ReturnAddressPtr returnAddress)
939 {
940     JSGlobalData* globalData = &exec->globalData();
941     NativeCallFrameTracer tracer(globalData, exec);
942     
943     StructureStubInfo& stubInfo = exec->codeBlock()->getStubInfo(returnAddress);
944     AccessType accessType = static_cast<AccessType>(stubInfo.accessType);
945
946     JSValue value = JSValue::decode(encodedValue);
947     PutPropertySlot slot(false);
948     
949     ASSERT(base->isObject());
950     asObject(base)->putDirect(exec->globalData(), *propertyName, value, slot);
951     
952     if (accessType != static_cast<AccessType>(stubInfo.accessType))
953         return;
954     
955     dfgBuildPutByIdList(exec, base, *propertyName, slot, stubInfo, Direct);
956 }
957
958 size_t DFG_OPERATION operationCompareLess(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
959 {
960     JSGlobalData* globalData = &exec->globalData();
961     NativeCallFrameTracer tracer(globalData, exec);
962     
963     return jsLess<true>(exec, JSValue::decode(encodedOp1), JSValue::decode(encodedOp2));
964 }
965
966 size_t DFG_OPERATION operationCompareLessEq(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
967 {
968     JSGlobalData* globalData = &exec->globalData();
969     NativeCallFrameTracer tracer(globalData, exec);
970     
971     return jsLessEq<true>(exec, JSValue::decode(encodedOp1), JSValue::decode(encodedOp2));
972 }
973
974 size_t DFG_OPERATION operationCompareGreater(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
975 {
976     JSGlobalData* globalData = &exec->globalData();
977     NativeCallFrameTracer tracer(globalData, exec);
978     
979     return jsLess<false>(exec, JSValue::decode(encodedOp2), JSValue::decode(encodedOp1));
980 }
981
982 size_t DFG_OPERATION operationCompareGreaterEq(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
983 {
984     JSGlobalData* globalData = &exec->globalData();
985     NativeCallFrameTracer tracer(globalData, exec);
986     
987     return jsLessEq<false>(exec, JSValue::decode(encodedOp2), JSValue::decode(encodedOp1));
988 }
989
990 size_t DFG_OPERATION operationCompareEq(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
991 {
992     JSGlobalData* globalData = &exec->globalData();
993     NativeCallFrameTracer tracer(globalData, exec);
994     
995     return JSValue::equalSlowCaseInline(exec, JSValue::decode(encodedOp1), JSValue::decode(encodedOp2));
996 }
997
998 size_t DFG_OPERATION operationCompareStrictEqCell(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
999 {
1000     JSGlobalData* globalData = &exec->globalData();
1001     NativeCallFrameTracer tracer(globalData, exec);
1002     
1003     JSValue op1 = JSValue::decode(encodedOp1);
1004     JSValue op2 = JSValue::decode(encodedOp2);
1005     
1006     ASSERT(op1.isCell());
1007     ASSERT(op2.isCell());
1008     
1009     return JSValue::strictEqualSlowCaseInline(exec, op1, op2);
1010 }
1011
1012 size_t DFG_OPERATION operationCompareStrictEq(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
1013 {
1014     JSGlobalData* globalData = &exec->globalData();
1015     NativeCallFrameTracer tracer(globalData, exec);
1016
1017     JSValue src1 = JSValue::decode(encodedOp1);
1018     JSValue src2 = JSValue::decode(encodedOp2);
1019     
1020     return JSValue::strictEqual(exec, src1, src2);
1021 }
1022
1023 static void* handleHostCall(ExecState* execCallee, JSValue callee, CodeSpecializationKind kind)
1024 {
1025     ExecState* exec = execCallee->callerFrame();
1026     JSGlobalData* globalData = &exec->globalData();
1027
1028     execCallee->setScope(exec->scope());
1029     execCallee->setCodeBlock(0);
1030
1031     if (kind == CodeForCall) {
1032         CallData callData;
1033         CallType callType = getCallData(callee, callData);
1034     
1035         ASSERT(callType != CallTypeJS);
1036     
1037         if (callType == CallTypeHost) {
1038             NativeCallFrameTracer tracer(globalData, execCallee);
1039             execCallee->setCallee(asObject(callee));
1040             globalData->hostCallReturnValue = JSValue::decode(callData.native.function(execCallee));
1041             if (globalData->exception)
1042                 return globalData->getCTIStub(throwExceptionFromCallSlowPathGenerator).code().executableAddress();
1043
1044             return reinterpret_cast<void*>(getHostCallReturnValue);
1045         }
1046     
1047         ASSERT(callType == CallTypeNone);
1048         exec->globalData().exception = createNotAFunctionError(exec, callee);
1049         return globalData->getCTIStub(throwExceptionFromCallSlowPathGenerator).code().executableAddress();
1050     }
1051
1052     ASSERT(kind == CodeForConstruct);
1053     
1054     ConstructData constructData;
1055     ConstructType constructType = getConstructData(callee, constructData);
1056     
1057     ASSERT(constructType != ConstructTypeJS);
1058     
1059     if (constructType == ConstructTypeHost) {
1060         NativeCallFrameTracer tracer(globalData, execCallee);
1061         execCallee->setCallee(asObject(callee));
1062         globalData->hostCallReturnValue = JSValue::decode(constructData.native.function(execCallee));
1063         if (globalData->exception)
1064             return globalData->getCTIStub(throwExceptionFromCallSlowPathGenerator).code().executableAddress();
1065
1066         return reinterpret_cast<void*>(getHostCallReturnValue);
1067     }
1068     
1069     ASSERT(constructType == ConstructTypeNone);
1070     exec->globalData().exception = createNotAConstructorError(exec, callee);
1071     return globalData->getCTIStub(throwExceptionFromCallSlowPathGenerator).code().executableAddress();
1072 }
1073
1074 inline char* linkFor(ExecState* execCallee, CodeSpecializationKind kind)
1075 {
1076     ExecState* exec = execCallee->callerFrame();
1077     JSGlobalData* globalData = &exec->globalData();
1078     NativeCallFrameTracer tracer(globalData, exec);
1079     
1080     JSValue calleeAsValue = execCallee->calleeAsValue();
1081     JSCell* calleeAsFunctionCell = getJSFunction(calleeAsValue);
1082     if (!calleeAsFunctionCell)
1083         return reinterpret_cast<char*>(handleHostCall(execCallee, calleeAsValue, kind));
1084
1085     JSFunction* callee = jsCast<JSFunction*>(calleeAsFunctionCell);
1086     execCallee->setScope(callee->scopeUnchecked());
1087     ExecutableBase* executable = callee->executable();
1088
1089     MacroAssemblerCodePtr codePtr;
1090     CodeBlock* codeBlock = 0;
1091     if (executable->isHostFunction())
1092         codePtr = executable->generatedJITCodeFor(kind).addressForCall();
1093     else {
1094         FunctionExecutable* functionExecutable = static_cast<FunctionExecutable*>(executable);
1095         JSObject* error = functionExecutable->compileFor(execCallee, callee->scope(), kind);
1096         if (error) {
1097             globalData->exception = createStackOverflowError(exec);
1098             return reinterpret_cast<char*>(globalData->getCTIStub(throwExceptionFromCallSlowPathGenerator).code().executableAddress());
1099         }
1100         codeBlock = &functionExecutable->generatedBytecodeFor(kind);
1101         if (execCallee->argumentCountIncludingThis() < static_cast<size_t>(codeBlock->numParameters()))
1102             codePtr = functionExecutable->generatedJITCodeWithArityCheckFor(kind);
1103         else
1104             codePtr = functionExecutable->generatedJITCodeFor(kind).addressForCall();
1105     }
1106     CallLinkInfo& callLinkInfo = exec->codeBlock()->getCallLinkInfo(execCallee->returnPC());
1107     if (!callLinkInfo.seenOnce())
1108         callLinkInfo.setSeen();
1109     else
1110         dfgLinkFor(execCallee, callLinkInfo, codeBlock, callee, codePtr, kind);
1111     return reinterpret_cast<char*>(codePtr.executableAddress());
1112 }
1113
1114 char* DFG_OPERATION operationLinkCall(ExecState* execCallee)
1115 {
1116     return linkFor(execCallee, CodeForCall);
1117 }
1118
1119 char* DFG_OPERATION operationLinkConstruct(ExecState* execCallee)
1120 {
1121     return linkFor(execCallee, CodeForConstruct);
1122 }
1123
1124 inline char* virtualForWithFunction(ExecState* execCallee, CodeSpecializationKind kind, JSCell*& calleeAsFunctionCell)
1125 {
1126     ExecState* exec = execCallee->callerFrame();
1127     JSGlobalData* globalData = &exec->globalData();
1128     NativeCallFrameTracer tracer(globalData, exec);
1129
1130     JSValue calleeAsValue = execCallee->calleeAsValue();
1131     calleeAsFunctionCell = getJSFunction(calleeAsValue);
1132     if (UNLIKELY(!calleeAsFunctionCell))
1133         return reinterpret_cast<char*>(handleHostCall(execCallee, calleeAsValue, kind));
1134     
1135     JSFunction* function = jsCast<JSFunction*>(calleeAsFunctionCell);
1136     execCallee->setScope(function->scopeUnchecked());
1137     ExecutableBase* executable = function->executable();
1138     if (UNLIKELY(!executable->hasJITCodeFor(kind))) {
1139         FunctionExecutable* functionExecutable = static_cast<FunctionExecutable*>(executable);
1140         JSObject* error = functionExecutable->compileFor(execCallee, function->scope(), kind);
1141         if (error) {
1142             exec->globalData().exception = error;
1143             return reinterpret_cast<char*>(globalData->getCTIStub(throwExceptionFromCallSlowPathGenerator).code().executableAddress());
1144         }
1145     }
1146     return reinterpret_cast<char*>(executable->generatedJITCodeWithArityCheckFor(kind).executableAddress());
1147 }
1148
1149 inline char* virtualFor(ExecState* execCallee, CodeSpecializationKind kind)
1150 {
1151     JSCell* calleeAsFunctionCellIgnored;
1152     return virtualForWithFunction(execCallee, kind, calleeAsFunctionCellIgnored);
1153 }
1154
1155 static bool attemptToOptimizeClosureCall(ExecState* execCallee, JSCell* calleeAsFunctionCell, CallLinkInfo& callLinkInfo)
1156 {
1157     if (!calleeAsFunctionCell)
1158         return false;
1159     
1160     JSFunction* callee = jsCast<JSFunction*>(calleeAsFunctionCell);
1161     JSFunction* oldCallee = callLinkInfo.callee.get();
1162     
1163     if (!oldCallee
1164         || oldCallee->structure() != callee->structure()
1165         || oldCallee->executable() != callee->executable())
1166         return false;
1167     
1168     ASSERT(callee->executable()->hasJITCodeForCall());
1169     MacroAssemblerCodePtr codePtr = callee->executable()->generatedJITCodeForCall().addressForCall();
1170     
1171     CodeBlock* codeBlock;
1172     if (callee->executable()->isHostFunction())
1173         codeBlock = 0;
1174     else {
1175         codeBlock = &jsCast<FunctionExecutable*>(callee->executable())->generatedBytecodeForCall();
1176         if (execCallee->argumentCountIncludingThis() < static_cast<size_t>(codeBlock->numParameters()))
1177             return false;
1178     }
1179     
1180     dfgLinkClosureCall(
1181         execCallee, callLinkInfo, codeBlock,
1182         callee->structure(), callee->executable(), codePtr);
1183     
1184     return true;
1185 }
1186
1187 char* DFG_OPERATION operationLinkClosureCall(ExecState* execCallee)
1188 {
1189     JSCell* calleeAsFunctionCell;
1190     char* result = virtualForWithFunction(execCallee, CodeForCall, calleeAsFunctionCell);
1191     CallLinkInfo& callLinkInfo = execCallee->callerFrame()->codeBlock()->getCallLinkInfo(execCallee->returnPC());
1192
1193     if (!attemptToOptimizeClosureCall(execCallee, calleeAsFunctionCell, callLinkInfo))
1194         dfgLinkSlowFor(execCallee, callLinkInfo, CodeForCall);
1195     
1196     return result;
1197 }
1198
1199 char* DFG_OPERATION operationVirtualCall(ExecState* execCallee)
1200 {    
1201     return virtualFor(execCallee, CodeForCall);
1202 }
1203
1204 char* DFG_OPERATION operationVirtualConstruct(ExecState* execCallee)
1205 {
1206     return virtualFor(execCallee, CodeForConstruct);
1207 }
1208
1209 void DFG_OPERATION operationNotifyGlobalVarWrite(WatchpointSet* watchpointSet)
1210 {
1211     watchpointSet->notifyWrite();
1212 }
1213
1214 EncodedJSValue DFG_OPERATION operationResolve(ExecState* exec, Identifier* propertyName, ResolveOperations* operations)
1215 {
1216     JSGlobalData* globalData = &exec->globalData();
1217     NativeCallFrameTracer tracer(globalData, exec);
1218     return JSValue::encode(JSScope::resolve(exec, *propertyName, operations));
1219 }
1220
1221 EncodedJSValue DFG_OPERATION operationResolveBase(ExecState* exec, Identifier* propertyName, ResolveOperations* operations, PutToBaseOperation* putToBaseOperations)
1222 {
1223     JSGlobalData* globalData = &exec->globalData();
1224     NativeCallFrameTracer tracer(globalData, exec);
1225     
1226     return JSValue::encode(JSScope::resolveBase(exec, *propertyName, false, operations, putToBaseOperations));
1227 }
1228
1229 EncodedJSValue DFG_OPERATION operationResolveBaseStrictPut(ExecState* exec, Identifier* propertyName, ResolveOperations* operations, PutToBaseOperation* putToBaseOperations)
1230 {
1231     JSGlobalData* globalData = &exec->globalData();
1232     NativeCallFrameTracer tracer(globalData, exec);
1233     
1234     return JSValue::encode(JSScope::resolveBase(exec, *propertyName, true, operations, putToBaseOperations));
1235 }
1236
1237 EncodedJSValue DFG_OPERATION operationResolveGlobal(ExecState* exec, ResolveOperation* resolveOperation, JSGlobalObject* globalObject, Identifier* propertyName)
1238 {
1239     JSGlobalData* globalData = &exec->globalData();
1240     NativeCallFrameTracer tracer(globalData, exec);
1241     ASSERT(globalObject);
1242     UNUSED_PARAM(resolveOperation);
1243     UNUSED_PARAM(globalObject);
1244     ASSERT(resolveOperation->m_operation == ResolveOperation::GetAndReturnGlobalProperty);
1245     return JSValue::encode(JSScope::resolveGlobal(exec, *propertyName, globalObject, resolveOperation));
1246 }
1247
1248 EncodedJSValue DFG_OPERATION operationToPrimitive(ExecState* exec, EncodedJSValue value)
1249 {
1250     JSGlobalData* globalData = &exec->globalData();
1251     NativeCallFrameTracer tracer(globalData, exec);
1252     
1253     return JSValue::encode(JSValue::decode(value).toPrimitive(exec));
1254 }
1255
1256 EncodedJSValue DFG_OPERATION operationStrCat(ExecState* exec, void* buffer, size_t size)
1257 {
1258     JSGlobalData* globalData = &exec->globalData();
1259     NativeCallFrameTracer tracer(globalData, exec);
1260
1261     return JSValue::encode(jsString(exec, static_cast<Register*>(buffer), size));
1262 }
1263
1264 char* DFG_OPERATION operationNewArray(ExecState* exec, Structure* arrayStructure, void* buffer, size_t size)
1265 {
1266     JSGlobalData* globalData = &exec->globalData();
1267     NativeCallFrameTracer tracer(globalData, exec);
1268     
1269     return bitwise_cast<char*>(constructArray(exec, arrayStructure, static_cast<JSValue*>(buffer), size));
1270 }
1271
1272 char* DFG_OPERATION operationNewEmptyArray(ExecState* exec, Structure* arrayStructure)
1273 {
1274     JSGlobalData* globalData = &exec->globalData();
1275     NativeCallFrameTracer tracer(globalData, exec);
1276     
1277     return bitwise_cast<char*>(JSArray::create(*globalData, arrayStructure));
1278 }
1279
1280 char* DFG_OPERATION operationNewArrayWithSize(ExecState* exec, Structure* arrayStructure, int32_t size)
1281 {
1282     JSGlobalData* globalData = &exec->globalData();
1283     NativeCallFrameTracer tracer(globalData, exec);
1284     
1285     return bitwise_cast<char*>(JSArray::create(*globalData, arrayStructure, size));
1286 }
1287
1288 char* DFG_OPERATION operationNewArrayBuffer(ExecState* exec, Structure* arrayStructure, size_t start, size_t size)
1289 {
1290     JSGlobalData& globalData = exec->globalData();
1291     NativeCallFrameTracer tracer(&globalData, exec);
1292     return bitwise_cast<char*>(constructArray(exec, arrayStructure, exec->codeBlock()->constantBuffer(start), size));
1293 }
1294
1295 EncodedJSValue DFG_OPERATION operationNewRegexp(ExecState* exec, void* regexpPtr)
1296 {
1297     JSGlobalData& globalData = exec->globalData();
1298     NativeCallFrameTracer tracer(&globalData, exec);
1299     RegExp* regexp = static_cast<RegExp*>(regexpPtr);
1300     if (!regexp->isValid()) {
1301         throwError(exec, createSyntaxError(exec, "Invalid flags supplied to RegExp constructor."));
1302         return JSValue::encode(jsUndefined());
1303     }
1304     
1305     return JSValue::encode(RegExpObject::create(exec->globalData(), exec->lexicalGlobalObject(), exec->lexicalGlobalObject()->regExpStructure(), regexp));
1306 }
1307
1308 JSCell* DFG_OPERATION operationCreateActivation(ExecState* exec)
1309 {
1310     JSGlobalData& globalData = exec->globalData();
1311     NativeCallFrameTracer tracer(&globalData, exec);
1312     JSActivation* activation = JSActivation::create(globalData, exec, exec->codeBlock());
1313     exec->setScope(activation);
1314     return activation;
1315 }
1316
1317 JSCell* DFG_OPERATION operationCreateArguments(ExecState* exec)
1318 {
1319     JSGlobalData& globalData = exec->globalData();
1320     NativeCallFrameTracer tracer(&globalData, exec);
1321     // NB: This needs to be exceedingly careful with top call frame tracking, since it
1322     // may be called from OSR exit, while the state of the call stack is bizarre.
1323     Arguments* result = Arguments::create(globalData, exec);
1324     ASSERT(!globalData.exception);
1325     return result;
1326 }
1327
1328 JSCell* DFG_OPERATION operationCreateInlinedArguments(
1329     ExecState* exec, InlineCallFrame* inlineCallFrame)
1330 {
1331     JSGlobalData& globalData = exec->globalData();
1332     NativeCallFrameTracer tracer(&globalData, exec);
1333     // NB: This needs to be exceedingly careful with top call frame tracking, since it
1334     // may be called from OSR exit, while the state of the call stack is bizarre.
1335     Arguments* result = Arguments::create(globalData, exec, inlineCallFrame);
1336     ASSERT(!globalData.exception);
1337     return result;
1338 }
1339
1340 void DFG_OPERATION operationTearOffArguments(ExecState* exec, JSCell* argumentsCell, JSCell* activationCell)
1341 {
1342     ASSERT(exec->codeBlock()->usesArguments());
1343     if (activationCell) {
1344         jsCast<Arguments*>(argumentsCell)->didTearOffActivation(exec, jsCast<JSActivation*>(activationCell));
1345         return;
1346     }
1347     jsCast<Arguments*>(argumentsCell)->tearOff(exec);
1348 }
1349
1350 void DFG_OPERATION operationTearOffInlinedArguments(
1351     ExecState* exec, JSCell* argumentsCell, JSCell* activationCell, InlineCallFrame* inlineCallFrame)
1352 {
1353     ASSERT_UNUSED(activationCell, !activationCell); // Currently, we don't inline functions with activations.
1354     jsCast<Arguments*>(argumentsCell)->tearOff(exec, inlineCallFrame);
1355 }
1356
1357 EncodedJSValue DFG_OPERATION operationGetArgumentsLength(ExecState* exec, int32_t argumentsRegister)
1358 {
1359     JSGlobalData& globalData = exec->globalData();
1360     NativeCallFrameTracer tracer(&globalData, exec);
1361     // Here we can assume that the argumernts were created. Because otherwise the JIT code would
1362     // have not made this call.
1363     Identifier ident(&globalData, "length");
1364     JSValue baseValue = exec->uncheckedR(argumentsRegister).jsValue();
1365     PropertySlot slot(baseValue);
1366     return JSValue::encode(baseValue.get(exec, ident, slot));
1367 }
1368
1369 EncodedJSValue DFG_OPERATION operationGetArgumentByVal(ExecState* exec, int32_t argumentsRegister, int32_t index)
1370 {
1371     JSGlobalData& globalData = exec->globalData();
1372     NativeCallFrameTracer tracer(&globalData, exec);
1373
1374     JSValue argumentsValue = exec->uncheckedR(argumentsRegister).jsValue();
1375     
1376     // If there are no arguments, and we're accessing out of bounds, then we have to create the
1377     // arguments in case someone has installed a getter on a numeric property.
1378     if (!argumentsValue)
1379         exec->uncheckedR(argumentsRegister) = argumentsValue = Arguments::create(exec->globalData(), exec);
1380     
1381     return JSValue::encode(argumentsValue.get(exec, index));
1382 }
1383
1384 EncodedJSValue DFG_OPERATION operationGetInlinedArgumentByVal(
1385     ExecState* exec, int32_t argumentsRegister, InlineCallFrame* inlineCallFrame, int32_t index)
1386 {
1387     JSGlobalData& globalData = exec->globalData();
1388     NativeCallFrameTracer tracer(&globalData, exec);
1389
1390     JSValue argumentsValue = exec->uncheckedR(argumentsRegister).jsValue();
1391     
1392     // If there are no arguments, and we're accessing out of bounds, then we have to create the
1393     // arguments in case someone has installed a getter on a numeric property.
1394     if (!argumentsValue) {
1395         exec->uncheckedR(argumentsRegister) = argumentsValue =
1396             Arguments::create(exec->globalData(), exec, inlineCallFrame);
1397     }
1398     
1399     return JSValue::encode(argumentsValue.get(exec, index));
1400 }
1401
1402 JSCell* DFG_OPERATION operationNewFunction(ExecState* exec, JSCell* functionExecutable)
1403 {
1404     ASSERT(functionExecutable->inherits(&FunctionExecutable::s_info));
1405     JSGlobalData& globalData = exec->globalData();
1406     NativeCallFrameTracer tracer(&globalData, exec);
1407     return JSFunction::create(exec, static_cast<FunctionExecutable*>(functionExecutable), exec->scope());
1408 }
1409
1410 JSCell* DFG_OPERATION operationNewFunctionExpression(ExecState* exec, JSCell* functionExecutableAsCell)
1411 {
1412     ASSERT(functionExecutableAsCell->inherits(&FunctionExecutable::s_info));
1413
1414     JSGlobalData& globalData = exec->globalData();
1415     NativeCallFrameTracer tracer(&globalData, exec);
1416
1417     FunctionExecutable* functionExecutable =
1418         static_cast<FunctionExecutable*>(functionExecutableAsCell);
1419     return JSFunction::create(exec, functionExecutable, exec->scope());
1420 }
1421
1422 size_t DFG_OPERATION operationIsObject(ExecState* exec, EncodedJSValue value)
1423 {
1424     return jsIsObjectType(exec, JSValue::decode(value));
1425 }
1426
1427 size_t DFG_OPERATION operationIsFunction(EncodedJSValue value)
1428 {
1429     return jsIsFunctionType(JSValue::decode(value));
1430 }
1431
1432 JSCell* DFG_OPERATION operationTypeOf(ExecState* exec, JSCell* value)
1433 {
1434     return jsTypeStringForValue(exec, JSValue(value)).asCell();
1435 }
1436
1437 void DFG_OPERATION operationReallocateStorageAndFinishPut(ExecState* exec, JSObject* base, Structure* structure, PropertyOffset offset, EncodedJSValue value)
1438 {
1439     JSGlobalData& globalData = exec->globalData();
1440     NativeCallFrameTracer tracer(&globalData, exec);
1441
1442     ASSERT(structure->outOfLineCapacity() > base->structure()->outOfLineCapacity());
1443     ASSERT(!globalData.heap.storageAllocator().fastPathShouldSucceed(structure->outOfLineCapacity() * sizeof(JSValue)));
1444     base->setStructureAndReallocateStorageIfNecessary(globalData, structure);
1445     base->putDirect(globalData, offset, JSValue::decode(value));
1446 }
1447
1448 char* DFG_OPERATION operationAllocatePropertyStorageWithInitialCapacity(ExecState* exec)
1449 {
1450     JSGlobalData& globalData = exec->globalData();
1451     NativeCallFrameTracer tracer(&globalData, exec);
1452
1453     return reinterpret_cast<char*>(
1454         Butterfly::createUninitialized(globalData, 0, initialOutOfLineCapacity, false, 0));
1455 }
1456
1457 char* DFG_OPERATION operationAllocatePropertyStorage(ExecState* exec, size_t newSize)
1458 {
1459     JSGlobalData& globalData = exec->globalData();
1460     NativeCallFrameTracer tracer(&globalData, exec);
1461
1462     return reinterpret_cast<char*>(
1463         Butterfly::createUninitialized(globalData, 0, newSize, false, 0));
1464 }
1465
1466 char* DFG_OPERATION operationReallocateButterflyToHavePropertyStorageWithInitialCapacity(ExecState* exec, JSObject* object)
1467 {
1468     JSGlobalData& globalData = exec->globalData();
1469     NativeCallFrameTracer tracer(&globalData, exec);
1470
1471     ASSERT(!object->structure()->outOfLineCapacity());
1472     Butterfly* result = object->growOutOfLineStorage(globalData, 0, initialOutOfLineCapacity);
1473     object->setButterflyWithoutChangingStructure(result);
1474     return reinterpret_cast<char*>(result);
1475 }
1476
1477 char* DFG_OPERATION operationReallocateButterflyToGrowPropertyStorage(ExecState* exec, JSObject* object, size_t newSize)
1478 {
1479     JSGlobalData& globalData = exec->globalData();
1480     NativeCallFrameTracer tracer(&globalData, exec);
1481
1482     Butterfly* result = object->growOutOfLineStorage(globalData, object->structure()->outOfLineCapacity(), newSize);
1483     object->setButterflyWithoutChangingStructure(result);
1484     return reinterpret_cast<char*>(result);
1485 }
1486
1487 char* DFG_OPERATION operationEnsureInt32(ExecState* exec, JSCell* cell)
1488 {
1489     JSGlobalData& globalData = exec->globalData();
1490     NativeCallFrameTracer tracer(&globalData, exec);
1491     
1492     if (!cell->isObject())
1493         return 0;
1494     
1495     return reinterpret_cast<char*>(asObject(cell)->ensureInt32(globalData).data());
1496 }
1497
1498 char* DFG_OPERATION operationEnsureDouble(ExecState* exec, JSCell* cell)
1499 {
1500     JSGlobalData& globalData = exec->globalData();
1501     NativeCallFrameTracer tracer(&globalData, exec);
1502     
1503     if (!cell->isObject())
1504         return 0;
1505     
1506     return reinterpret_cast<char*>(asObject(cell)->ensureDouble(globalData).data());
1507 }
1508
1509 char* DFG_OPERATION operationEnsureContiguous(ExecState* exec, JSCell* cell)
1510 {
1511     JSGlobalData& globalData = exec->globalData();
1512     NativeCallFrameTracer tracer(&globalData, exec);
1513     
1514     if (!cell->isObject())
1515         return 0;
1516     
1517     return reinterpret_cast<char*>(asObject(cell)->ensureContiguous(globalData).data());
1518 }
1519
1520 char* DFG_OPERATION operationRageEnsureContiguous(ExecState* exec, JSCell* cell)
1521 {
1522     JSGlobalData& globalData = exec->globalData();
1523     NativeCallFrameTracer tracer(&globalData, exec);
1524     
1525     if (!cell->isObject())
1526         return 0;
1527     
1528     return reinterpret_cast<char*>(asObject(cell)->rageEnsureContiguous(globalData).data());
1529 }
1530
1531 char* DFG_OPERATION operationEnsureArrayStorage(ExecState* exec, JSCell* cell)
1532 {
1533     JSGlobalData& globalData = exec->globalData();
1534     NativeCallFrameTracer tracer(&globalData, exec);
1535     
1536     if (!cell->isObject())
1537         return 0;
1538
1539     return reinterpret_cast<char*>(asObject(cell)->ensureArrayStorage(globalData));
1540 }
1541
1542 StringImpl* DFG_OPERATION operationResolveRope(ExecState* exec, JSString* string)
1543 {
1544     JSGlobalData& globalData = exec->globalData();
1545     NativeCallFrameTracer tracer(&globalData, exec);
1546
1547     return string->value(exec).impl();
1548 }
1549
1550 double DFG_OPERATION operationFModOnInts(int32_t a, int32_t b)
1551 {
1552     return fmod(a, b);
1553 }
1554
1555 DFGHandlerEncoded DFG_OPERATION lookupExceptionHandler(ExecState* exec, uint32_t callIndex)
1556 {
1557     JSGlobalData* globalData = &exec->globalData();
1558     NativeCallFrameTracer tracer(globalData, exec);
1559
1560     JSValue exceptionValue = exec->exception();
1561     ASSERT(exceptionValue);
1562     
1563     unsigned vPCIndex = exec->codeBlock()->bytecodeOffsetForCallAtIndex(callIndex);
1564     ExceptionHandler handler = genericThrow(globalData, exec, exceptionValue, vPCIndex);
1565     ASSERT(handler.catchRoutine);
1566     return dfgHandlerEncoded(handler.callFrame, handler.catchRoutine);
1567 }
1568
1569 DFGHandlerEncoded DFG_OPERATION lookupExceptionHandlerInStub(ExecState* exec, StructureStubInfo* stubInfo)
1570 {
1571     JSGlobalData* globalData = &exec->globalData();
1572     NativeCallFrameTracer tracer(globalData, exec);
1573
1574     JSValue exceptionValue = exec->exception();
1575     ASSERT(exceptionValue);
1576     
1577     CodeOrigin codeOrigin = stubInfo->codeOrigin;
1578     while (codeOrigin.inlineCallFrame)
1579         codeOrigin = codeOrigin.inlineCallFrame->caller;
1580     
1581     ExceptionHandler handler = genericThrow(globalData, exec, exceptionValue, codeOrigin.bytecodeIndex);
1582     ASSERT(handler.catchRoutine);
1583     return dfgHandlerEncoded(handler.callFrame, handler.catchRoutine);
1584 }
1585
1586 size_t DFG_OPERATION dfgConvertJSValueToInt32(ExecState* exec, EncodedJSValue value)
1587 {
1588     JSGlobalData* globalData = &exec->globalData();
1589     NativeCallFrameTracer tracer(globalData, exec);
1590     
1591     // toInt32/toUInt32 return the same value; we want the value zero extended to fill the register.
1592     return JSValue::decode(value).toUInt32(exec);
1593 }
1594
1595 size_t DFG_OPERATION dfgConvertJSValueToBoolean(ExecState* exec, EncodedJSValue encodedOp)
1596 {
1597     JSGlobalData* globalData = &exec->globalData();
1598     NativeCallFrameTracer tracer(globalData, exec);
1599     
1600     return JSValue::decode(encodedOp).toBoolean(exec);
1601 }
1602
1603 void DFG_OPERATION debugOperationPrintSpeculationFailure(ExecState* exec, void* debugInfoRaw, void* scratch)
1604 {
1605     JSGlobalData* globalData = &exec->globalData();
1606     NativeCallFrameTracer tracer(globalData, exec);
1607     
1608     SpeculationFailureDebugInfo* debugInfo = static_cast<SpeculationFailureDebugInfo*>(debugInfoRaw);
1609     CodeBlock* codeBlock = debugInfo->codeBlock;
1610     CodeBlock* alternative = codeBlock->alternative();
1611     dataLog(
1612         "Speculation failure in ", *codeBlock, " with ");
1613     if (alternative) {
1614         dataLog(
1615             "executeCounter = ", alternative->jitExecuteCounter(),
1616             ", reoptimizationRetryCounter = ", alternative->reoptimizationRetryCounter(),
1617             ", optimizationDelayCounter = ", alternative->optimizationDelayCounter());
1618     } else
1619         dataLog("no alternative code block (i.e. we've been jettisoned)");
1620     dataLog(", osrExitCounter = ", codeBlock->osrExitCounter(), "\n");
1621     dataLog("    GPRs at time of exit:");
1622     char* scratchPointer = static_cast<char*>(scratch);
1623     for (unsigned i = 0; i < GPRInfo::numberOfRegisters; ++i) {
1624         GPRReg gpr = GPRInfo::toRegister(i);
1625         dataLog(" ", GPRInfo::debugName(gpr), ":", RawPointer(*reinterpret_cast_ptr<void**>(scratchPointer)));
1626         scratchPointer += sizeof(EncodedJSValue);
1627     }
1628     dataLog("\n");
1629     dataLog("    FPRs at time of exit:");
1630     for (unsigned i = 0; i < FPRInfo::numberOfRegisters; ++i) {
1631         FPRReg fpr = FPRInfo::toRegister(i);
1632         dataLog(" ", FPRInfo::debugName(fpr), ":");
1633         uint64_t bits = *reinterpret_cast_ptr<uint64_t*>(scratchPointer);
1634         double value = *reinterpret_cast_ptr<double*>(scratchPointer);
1635         dataLogF("%llx:%lf", static_cast<long long>(bits), value);
1636         scratchPointer += sizeof(EncodedJSValue);
1637     }
1638     dataLog("\n");
1639 }
1640
1641 extern "C" void DFG_OPERATION triggerReoptimizationNow(CodeBlock* codeBlock)
1642 {
1643 #if ENABLE(JIT_VERBOSE_OSR)
1644     dataLog(*codeBlock, ": Entered reoptimize\n");
1645 #endif
1646     // We must be called with the baseline code block.
1647     ASSERT(JITCode::isBaselineCode(codeBlock->getJITType()));
1648
1649     // If I am my own replacement, then reoptimization has already been triggered.
1650     // This can happen in recursive functions.
1651     if (codeBlock->replacement() == codeBlock)
1652         return;
1653
1654     // Otherwise, the replacement must be optimized code. Use this as an opportunity
1655     // to check our logic.
1656     ASSERT(codeBlock->hasOptimizedReplacement());
1657     ASSERT(codeBlock->replacement()->getJITType() == JITCode::DFGJIT);
1658
1659     codeBlock->reoptimize();
1660 }
1661
1662 } // extern "C"
1663 } } // namespace JSC::DFG
1664
1665 #endif // ENABLE(DFG_JIT)
1666
1667 namespace JSC {
1668
1669 #if COMPILER(GCC) && CPU(X86_64)
1670 asm (
1671 ".globl " SYMBOL_STRING(getHostCallReturnValue) "\n"
1672 HIDE_SYMBOL(getHostCallReturnValue) "\n"
1673 SYMBOL_STRING(getHostCallReturnValue) ":" "\n"
1674     "mov -40(%r13), %r13\n"
1675     "mov %r13, %rdi\n"
1676     "jmp " LOCAL_REFERENCE(getHostCallReturnValueWithExecState) "\n"
1677 );
1678 #elif COMPILER(GCC) && CPU(X86)
1679 asm (
1680 ".text" "\n" \
1681 ".globl " SYMBOL_STRING(getHostCallReturnValue) "\n"
1682 HIDE_SYMBOL(getHostCallReturnValue) "\n"
1683 SYMBOL_STRING(getHostCallReturnValue) ":" "\n"
1684     "mov -40(%edi), %edi\n"
1685     "mov %edi, 4(%esp)\n"
1686     "jmp " LOCAL_REFERENCE(getHostCallReturnValueWithExecState) "\n"
1687 );
1688 #elif COMPILER(GCC) && CPU(ARM_THUMB2)
1689 asm (
1690 ".text" "\n"
1691 ".align 2" "\n"
1692 ".globl " SYMBOL_STRING(getHostCallReturnValue) "\n"
1693 HIDE_SYMBOL(getHostCallReturnValue) "\n"
1694 ".thumb" "\n"
1695 ".thumb_func " THUMB_FUNC_PARAM(getHostCallReturnValue) "\n"
1696 SYMBOL_STRING(getHostCallReturnValue) ":" "\n"
1697     "ldr r5, [r5, #-40]" "\n"
1698     "mov r0, r5" "\n"
1699     "b " LOCAL_REFERENCE(getHostCallReturnValueWithExecState) "\n"
1700 );
1701 #elif COMPILER(GCC) && CPU(ARM_TRADITIONAL)
1702 asm (
1703 ".text" "\n"
1704 ".globl " SYMBOL_STRING(getHostCallReturnValue) "\n"
1705 HIDE_SYMBOL(getHostCallReturnValue) "\n"
1706 INLINE_ARM_FUNCTION(getHostCallReturnValue)
1707 SYMBOL_STRING(getHostCallReturnValue) ":" "\n"
1708     "ldr r5, [r5, #-40]" "\n"
1709     "mov r0, r5" "\n"
1710     "b " LOCAL_REFERENCE(getHostCallReturnValueWithExecState) "\n"
1711 );
1712 #elif COMPILER(GCC) && CPU(MIPS)
1713 asm(
1714 ".text" "\n"
1715 ".globl " SYMBOL_STRING(getHostCallReturnValue) "\n"
1716 HIDE_SYMBOL(getHostCallReturnValue) "\n"
1717 SYMBOL_STRING(getHostCallReturnValue) ":" "\n"
1718     LOAD_FUNCTION_TO_T9(getHostCallReturnValueWithExecState)
1719     "lw $s0, -40($s0)" "\n"
1720     "move $a0, $s0" "\n"
1721     "b " LOCAL_REFERENCE(getHostCallReturnValueWithExecState) "\n"
1722 );
1723 #endif
1724
1725 extern "C" EncodedJSValue HOST_CALL_RETURN_VALUE_OPTION getHostCallReturnValueWithExecState(ExecState* exec)
1726 {
1727     if (!exec)
1728         return JSValue::encode(JSValue());
1729     return JSValue::encode(exec->globalData().hostCallReturnValue);
1730 }
1731
1732 } // namespace JSC
1733
1734 #endif // ENABLE(JIT)