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