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