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