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