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