1dc3f1f75ea2181b0180beeaf66c20b43fe824aa
[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 "CodeBlock.h"
30 #include "DFGOSRExit.h"
31 #include "DFGRepatch.h"
32 #include "HostCallReturnValue.h"
33 #include "GetterSetter.h"
34 #include <wtf/InlineASM.h>
35 #include "Interpreter.h"
36 #include "JSActivation.h"
37 #include "JSGlobalData.h"
38 #include "JSStaticScopeObject.h"
39 #include "Operations.h"
40
41 #if ENABLE(DFG_JIT)
42
43 #if CPU(X86_64)
44
45 #define FUNCTION_WRAPPER_WITH_RETURN_ADDRESS(function, register) \
46     asm( \
47     ".globl " SYMBOL_STRING(function) "\n" \
48     HIDE_SYMBOL(function) "\n" \
49     SYMBOL_STRING(function) ":" "\n" \
50         "mov (%rsp), %" STRINGIZE(register) "\n" \
51         "jmp " SYMBOL_STRING_RELOCATION(function##WithReturnAddress) "\n" \
52     );
53 #define FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_E(function)    FUNCTION_WRAPPER_WITH_RETURN_ADDRESS(function, rsi)
54 #define FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_ECI(function)  FUNCTION_WRAPPER_WITH_RETURN_ADDRESS(function, rcx)
55 #define FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJI(function)  FUNCTION_WRAPPER_WITH_RETURN_ADDRESS(function, rcx)
56 #define FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJCI(function) FUNCTION_WRAPPER_WITH_RETURN_ADDRESS(function, r8)
57
58 #elif CPU(X86)
59
60 #define FUNCTION_WRAPPER_WITH_RETURN_ADDRESS(function, offset) \
61     asm( \
62     ".text" "\n" \
63     ".globl " SYMBOL_STRING(function) "\n" \
64     HIDE_SYMBOL(function) "\n" \
65     SYMBOL_STRING(function) ":" "\n" \
66         "mov (%esp), %eax\n" \
67         "mov %eax, " STRINGIZE(offset) "(%esp)\n" \
68         "jmp " SYMBOL_STRING_RELOCATION(function##WithReturnAddress) "\n" \
69     );
70 #define FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_E(function)    FUNCTION_WRAPPER_WITH_RETURN_ADDRESS(function, 8)
71 #define FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_ECI(function)  FUNCTION_WRAPPER_WITH_RETURN_ADDRESS(function, 16)
72 #define FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJI(function)  FUNCTION_WRAPPER_WITH_RETURN_ADDRESS(function, 20)
73 #define FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJCI(function) FUNCTION_WRAPPER_WITH_RETURN_ADDRESS(function, 24)
74
75 #elif COMPILER(GCC) && CPU(ARM_THUMB2)
76
77 #define FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_E(function) \
78     asm ( \
79     ".text" "\n" \
80     ".align 2" "\n" \
81     ".globl " SYMBOL_STRING(function) "\n" \
82     HIDE_SYMBOL(function) "\n" \
83     ".thumb" "\n" \
84     ".thumb_func " THUMB_FUNC_PARAM(function) "\n" \
85     SYMBOL_STRING(function) ":" "\n" \
86         "mov a2, lr" "\n" \
87         "b " SYMBOL_STRING_RELOCATION(function) "WithReturnAddress" "\n" \
88     );
89
90 #define FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_ECI(function) \
91     asm ( \
92     ".text" "\n" \
93     ".align 2" "\n" \
94     ".globl " SYMBOL_STRING(function) "\n" \
95     HIDE_SYMBOL(function) "\n" \
96     ".thumb" "\n" \
97     ".thumb_func " THUMB_FUNC_PARAM(function) "\n" \
98     SYMBOL_STRING(function) ":" "\n" \
99         "mov a4, lr" "\n" \
100         "b " SYMBOL_STRING_RELOCATION(function) "WithReturnAddress" "\n" \
101     );
102
103 // 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]).
104 // As a result, return address will be at a 4-byte further location in the following cases.
105 #if COMPILER_SUPPORTS(EABI) && CPU(ARM)
106 #define INSTRUCTION_STORE_RETURN_ADDRESS_EJI "str lr, [sp, #4]"
107 #define INSTRUCTION_STORE_RETURN_ADDRESS_EJCI "str lr, [sp, #8]"
108 #else
109 #define INSTRUCTION_STORE_RETURN_ADDRESS_EJI "str lr, [sp, #0]"
110 #define INSTRUCTION_STORE_RETURN_ADDRESS_EJCI "str lr, [sp, #4]"
111 #endif
112
113 #define FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJI(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         INSTRUCTION_STORE_RETURN_ADDRESS_EJI "\n" \
123         "b " SYMBOL_STRING_RELOCATION(function) "WithReturnAddress" "\n" \
124     );
125
126 #define FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJCI(function) \
127     asm ( \
128     ".text" "\n" \
129     ".align 2" "\n" \
130     ".globl " SYMBOL_STRING(function) "\n" \
131     HIDE_SYMBOL(function) "\n" \
132     ".thumb" "\n" \
133     ".thumb_func " THUMB_FUNC_PARAM(function) "\n" \
134     SYMBOL_STRING(function) ":" "\n" \
135         INSTRUCTION_STORE_RETURN_ADDRESS_EJCI "\n" \
136         "b " SYMBOL_STRING_RELOCATION(function) "WithReturnAddress" "\n" \
137     );
138
139 #endif
140
141 #define P_FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_E(function) \
142 void* DFG_OPERATION function##WithReturnAddress(ExecState*, ReturnAddressPtr); \
143 FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_E(function)
144
145 #define J_FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_ECI(function) \
146 EncodedJSValue DFG_OPERATION function##WithReturnAddress(ExecState*, JSCell*, Identifier*, ReturnAddressPtr); \
147 FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_ECI(function)
148
149 #define J_FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJI(function) \
150 EncodedJSValue DFG_OPERATION function##WithReturnAddress(ExecState*, EncodedJSValue, Identifier*, ReturnAddressPtr); \
151 FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJI(function)
152
153 #define V_FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJCI(function) \
154 void DFG_OPERATION function##WithReturnAddress(ExecState*, EncodedJSValue, JSCell*, Identifier*, ReturnAddressPtr); \
155 FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJCI(function)
156
157 namespace JSC { namespace DFG {
158
159 template<bool strict>
160 static inline void putByVal(ExecState* exec, JSValue baseValue, uint32_t index, JSValue value)
161 {
162     JSGlobalData& globalData = exec->globalData();
163     NativeCallFrameTracer tracer(&globalData, exec);
164     
165     if (isJSArray(baseValue)) {
166         JSArray* array = asArray(baseValue);
167         if (array->canSetIndex(index)) {
168             array->setIndex(globalData, index, value);
169             return;
170         }
171
172         JSArray::putByIndex(array, exec, index, value, strict);
173         return;
174     }
175
176     baseValue.putByIndex(exec, index, value, strict);
177 }
178
179 template<bool strict>
180 ALWAYS_INLINE static void DFG_OPERATION operationPutByValInternal(ExecState* exec, EncodedJSValue encodedBase, EncodedJSValue encodedProperty, EncodedJSValue encodedValue)
181 {
182     JSGlobalData* globalData = &exec->globalData();
183     NativeCallFrameTracer tracer(globalData, exec);
184
185     JSValue baseValue = JSValue::decode(encodedBase);
186     JSValue property = JSValue::decode(encodedProperty);
187     JSValue value = JSValue::decode(encodedValue);
188
189     if (LIKELY(property.isUInt32())) {
190         putByVal<strict>(exec, baseValue, property.asUInt32(), value);
191         return;
192     }
193
194     if (property.isDouble()) {
195         double propertyAsDouble = property.asDouble();
196         uint32_t propertyAsUInt32 = static_cast<uint32_t>(propertyAsDouble);
197         if (propertyAsDouble == propertyAsUInt32) {
198             putByVal<strict>(exec, baseValue, propertyAsUInt32, value);
199             return;
200         }
201     }
202
203
204     // Don't put to an object if toString throws an exception.
205     Identifier ident(exec, property.toString(exec)->value(exec));
206     if (!globalData->exception) {
207         PutPropertySlot slot(strict);
208         baseValue.put(exec, ident, value, slot);
209     }
210 }
211
212 extern "C" {
213
214 EncodedJSValue DFG_OPERATION operationConvertThis(ExecState* exec, EncodedJSValue encodedOp)
215 {
216     JSGlobalData* globalData = &exec->globalData();
217     NativeCallFrameTracer tracer(globalData, exec);
218
219     return JSValue::encode(JSValue::decode(encodedOp).toThisObject(exec));
220 }
221
222 JSCell* DFG_OPERATION operationCreateThis(ExecState* exec, JSCell* constructor)
223 {
224     JSGlobalData* globalData = &exec->globalData();
225     NativeCallFrameTracer tracer(globalData, exec);
226
227 #if !ASSERT_DISABLED
228     ConstructData constructData;
229     ASSERT(jsCast<JSFunction*>(constructor)->methodTable()->getConstructData(jsCast<JSFunction*>(constructor), constructData) == ConstructTypeJS);
230 #endif
231     
232     return constructEmptyObject(exec, jsCast<JSFunction*>(constructor)->cachedInheritorID(exec));
233 }
234
235 JSCell* DFG_OPERATION operationNewObject(ExecState* exec)
236 {
237     JSGlobalData* globalData = &exec->globalData();
238     NativeCallFrameTracer tracer(globalData, exec);
239     
240     return constructEmptyObject(exec);
241 }
242
243 EncodedJSValue DFG_OPERATION operationValueAdd(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
244 {
245     JSGlobalData* globalData = &exec->globalData();
246     NativeCallFrameTracer tracer(globalData, exec);
247     
248     JSValue op1 = JSValue::decode(encodedOp1);
249     JSValue op2 = JSValue::decode(encodedOp2);
250     
251     return JSValue::encode(jsAdd(exec, op1, op2));
252 }
253
254 EncodedJSValue DFG_OPERATION operationValueAddNotNumber(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
255 {
256     JSGlobalData* globalData = &exec->globalData();
257     NativeCallFrameTracer tracer(globalData, exec);
258     
259     JSValue op1 = JSValue::decode(encodedOp1);
260     JSValue op2 = JSValue::decode(encodedOp2);
261     
262     ASSERT(!op1.isNumber() || !op2.isNumber());
263     
264     if (op1.isString() && !op2.isObject())
265         return JSValue::encode(jsString(exec, asString(op1), op2.toString(exec)));
266
267     return JSValue::encode(jsAddSlowCase(exec, op1, op2));
268 }
269
270 static inline EncodedJSValue getByVal(ExecState* exec, JSCell* base, uint32_t index)
271 {
272     JSGlobalData& globalData = exec->globalData();
273     NativeCallFrameTracer tracer(&globalData, exec);
274     
275     // FIXME: the JIT used to handle these in compiled code!
276     if (isJSArray(base) && asArray(base)->canGetIndex(index))
277         return JSValue::encode(asArray(base)->getIndex(index));
278
279     // FIXME: the JITstub used to relink this to an optimized form!
280     if (isJSString(base) && asString(base)->canGetIndex(index))
281         return JSValue::encode(asString(base)->getIndex(exec, index));
282
283     return JSValue::encode(JSValue(base).get(exec, index));
284 }
285
286 EncodedJSValue DFG_OPERATION operationGetByVal(ExecState* exec, EncodedJSValue encodedBase, EncodedJSValue encodedProperty)
287 {
288     JSGlobalData* globalData = &exec->globalData();
289     NativeCallFrameTracer tracer(globalData, exec);
290     
291     JSValue baseValue = JSValue::decode(encodedBase);
292     JSValue property = JSValue::decode(encodedProperty);
293
294     if (LIKELY(baseValue.isCell())) {
295         JSCell* base = baseValue.asCell();
296
297         if (property.isUInt32()) {
298             return getByVal(exec, base, property.asUInt32());
299         } else if (property.isDouble()) {
300             double propertyAsDouble = property.asDouble();
301             uint32_t propertyAsUInt32 = static_cast<uint32_t>(propertyAsDouble);
302             if (propertyAsUInt32 == propertyAsDouble)
303                 return getByVal(exec, base, propertyAsUInt32);
304         } else if (property.isString()) {
305             if (JSValue result = base->fastGetOwnProperty(exec, asString(property)->value(exec)))
306                 return JSValue::encode(result);
307         }
308     }
309
310     Identifier ident(exec, property.toString(exec)->value(exec));
311     return JSValue::encode(baseValue.get(exec, ident));
312 }
313
314 EncodedJSValue DFG_OPERATION operationGetByValCell(ExecState* exec, JSCell* base, EncodedJSValue encodedProperty)
315 {
316     JSGlobalData* globalData = &exec->globalData();
317     NativeCallFrameTracer tracer(globalData, exec);
318     
319     JSValue property = JSValue::decode(encodedProperty);
320
321     if (property.isUInt32())
322         return getByVal(exec, base, property.asUInt32());
323     if (property.isDouble()) {
324         double propertyAsDouble = property.asDouble();
325         uint32_t propertyAsUInt32 = static_cast<uint32_t>(propertyAsDouble);
326         if (propertyAsUInt32 == propertyAsDouble)
327             return getByVal(exec, base, propertyAsUInt32);
328     } else if (property.isString()) {
329         if (JSValue result = base->fastGetOwnProperty(exec, asString(property)->value(exec)))
330             return JSValue::encode(result);
331     }
332
333     Identifier ident(exec, property.toString(exec)->value(exec));
334     return JSValue::encode(JSValue(base).get(exec, ident));
335 }
336
337 EncodedJSValue DFG_OPERATION operationGetById(ExecState* exec, EncodedJSValue base, Identifier* propertyName)
338 {
339     JSGlobalData* globalData = &exec->globalData();
340     NativeCallFrameTracer tracer(globalData, exec);
341     
342     JSValue baseValue = JSValue::decode(base);
343     PropertySlot slot(baseValue);
344     return JSValue::encode(baseValue.get(exec, *propertyName, slot));
345 }
346
347 J_FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJI(operationGetByIdBuildList);
348 EncodedJSValue DFG_OPERATION operationGetByIdBuildListWithReturnAddress(ExecState* exec, EncodedJSValue base, Identifier* propertyName, ReturnAddressPtr returnAddress)
349 {
350     JSGlobalData* globalData = &exec->globalData();
351     NativeCallFrameTracer tracer(globalData, exec);
352     
353     JSValue baseValue = JSValue::decode(base);
354     PropertySlot slot(baseValue);
355     JSValue result = baseValue.get(exec, *propertyName, slot);
356
357     StructureStubInfo& stubInfo = exec->codeBlock()->getStubInfo(returnAddress);
358     dfgBuildGetByIDList(exec, baseValue, *propertyName, slot, stubInfo);
359
360     return JSValue::encode(result);
361 }
362
363 J_FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJI(operationGetByIdProtoBuildList);
364 EncodedJSValue DFG_OPERATION operationGetByIdProtoBuildListWithReturnAddress(ExecState* exec, EncodedJSValue base, Identifier* propertyName, ReturnAddressPtr returnAddress)
365 {
366     JSGlobalData* globalData = &exec->globalData();
367     NativeCallFrameTracer tracer(globalData, exec);
368     
369     JSValue baseValue = JSValue::decode(base);
370     PropertySlot slot(baseValue);
371     JSValue result = baseValue.get(exec, *propertyName, slot);
372
373     StructureStubInfo& stubInfo = exec->codeBlock()->getStubInfo(returnAddress);
374     dfgBuildGetByIDProtoList(exec, baseValue, *propertyName, slot, stubInfo);
375
376     return JSValue::encode(result);
377 }
378
379 J_FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJI(operationGetByIdOptimize);
380 EncodedJSValue DFG_OPERATION operationGetByIdOptimizeWithReturnAddress(ExecState* exec, EncodedJSValue base, Identifier* propertyName, ReturnAddressPtr returnAddress)
381 {
382     JSGlobalData* globalData = &exec->globalData();
383     NativeCallFrameTracer tracer(globalData, exec);
384     
385     JSValue baseValue = JSValue::decode(base);
386     PropertySlot slot(baseValue);
387     JSValue result = baseValue.get(exec, *propertyName, slot);
388     
389     StructureStubInfo& stubInfo = exec->codeBlock()->getStubInfo(returnAddress);
390     if (stubInfo.seen)
391         dfgRepatchGetByID(exec, baseValue, *propertyName, slot, stubInfo);
392     else
393         stubInfo.seen = true;
394
395     return JSValue::encode(result);
396 }
397
398 EncodedJSValue DFG_OPERATION operationCallCustomGetter(ExecState* exec, JSCell* base, PropertySlot::GetValueFunc function, Identifier* ident)
399 {
400     JSGlobalData* globalData = &exec->globalData();
401     NativeCallFrameTracer tracer(globalData, exec);
402     
403     return JSValue::encode(function(exec, asObject(base), *ident));
404 }
405
406 EncodedJSValue DFG_OPERATION operationCallGetter(ExecState* exec, JSCell* base, JSCell* value)
407 {
408     JSGlobalData* globalData = &exec->globalData();
409     NativeCallFrameTracer tracer(globalData, exec);
410     
411     GetterSetter* getterSetter = asGetterSetter(value);
412     JSObject* getter = getterSetter->getter();
413     if (!getter)
414         return JSValue::encode(jsUndefined());
415     CallData callData;
416     CallType callType = getter->methodTable()->getCallData(getter, callData);
417     return JSValue::encode(call(exec, getter, callType, callData, asObject(base), ArgList()));
418 }
419
420 void DFG_OPERATION operationPutByValStrict(ExecState* exec, EncodedJSValue encodedBase, EncodedJSValue encodedProperty, EncodedJSValue encodedValue)
421 {
422     JSGlobalData* globalData = &exec->globalData();
423     NativeCallFrameTracer tracer(globalData, exec);
424     
425     operationPutByValInternal<true>(exec, encodedBase, encodedProperty, encodedValue);
426 }
427
428 void DFG_OPERATION operationPutByValNonStrict(ExecState* exec, EncodedJSValue encodedBase, EncodedJSValue encodedProperty, EncodedJSValue encodedValue)
429 {
430     JSGlobalData* globalData = &exec->globalData();
431     NativeCallFrameTracer tracer(globalData, exec);
432     
433     operationPutByValInternal<false>(exec, encodedBase, encodedProperty, encodedValue);
434 }
435
436 void DFG_OPERATION operationPutByValCellStrict(ExecState* exec, JSCell* cell, EncodedJSValue encodedProperty, EncodedJSValue encodedValue)
437 {
438     JSGlobalData* globalData = &exec->globalData();
439     NativeCallFrameTracer tracer(globalData, exec);
440     
441     operationPutByValInternal<true>(exec, JSValue::encode(cell), encodedProperty, encodedValue);
442 }
443
444 void DFG_OPERATION operationPutByValCellNonStrict(ExecState* exec, JSCell* cell, EncodedJSValue encodedProperty, EncodedJSValue encodedValue)
445 {
446     JSGlobalData* globalData = &exec->globalData();
447     NativeCallFrameTracer tracer(globalData, exec);
448     
449     operationPutByValInternal<false>(exec, JSValue::encode(cell), encodedProperty, encodedValue);
450 }
451
452 void DFG_OPERATION operationPutByValBeyondArrayBoundsStrict(ExecState* exec, JSArray* array, int32_t index, EncodedJSValue encodedValue)
453 {
454     JSGlobalData* globalData = &exec->globalData();
455     NativeCallFrameTracer tracer(globalData, exec);
456     
457     if (index >= 0) {
458         // We should only get here if index is outside the existing vector.
459         ASSERT(!array->canSetIndex(index));
460         JSArray::putByIndex(array, exec, index, JSValue::decode(encodedValue), true);
461         return;
462     }
463     
464     PutPropertySlot slot(true);
465     array->methodTable()->put(
466         array, exec, Identifier::from(exec, index), JSValue::decode(encodedValue), slot);
467 }
468
469 void DFG_OPERATION operationPutByValBeyondArrayBoundsNonStrict(ExecState* exec, JSArray* array, int32_t index, EncodedJSValue encodedValue)
470 {
471     JSGlobalData* globalData = &exec->globalData();
472     NativeCallFrameTracer tracer(globalData, exec);
473     
474     if (index >= 0) {
475         // We should only get here if index is outside the existing vector.
476         ASSERT(!array->canSetIndex(index));
477         JSArray::putByIndex(array, exec, index, JSValue::decode(encodedValue), false);
478         return;
479     }
480     
481     PutPropertySlot slot(false);
482     array->methodTable()->put(
483         array, exec, Identifier::from(exec, index), JSValue::decode(encodedValue), slot);
484 }
485
486 EncodedJSValue DFG_OPERATION operationArrayPush(ExecState* exec, EncodedJSValue encodedValue, JSArray* array)
487 {
488     JSGlobalData* globalData = &exec->globalData();
489     NativeCallFrameTracer tracer(globalData, exec);
490     
491     array->push(exec, JSValue::decode(encodedValue));
492     return JSValue::encode(jsNumber(array->length()));
493 }
494
495 EncodedJSValue DFG_OPERATION operationRegExpExec(ExecState* exec, JSCell* base, JSCell* argument)
496 {
497     JSGlobalData& globalData = exec->globalData();
498     NativeCallFrameTracer tracer(&globalData, exec);
499     
500     if (!base->inherits(&RegExpObject::s_info))
501         return throwVMTypeError(exec);
502
503     ASSERT(argument->isString() || argument->isObject());
504     JSString* input = argument->isString() ? asString(argument) : asObject(argument)->toString(exec);
505     return JSValue::encode(asRegExpObject(base)->exec(exec, input));
506 }
507         
508 size_t DFG_OPERATION operationRegExpTest(ExecState* exec, JSCell* base, JSCell* argument)
509 {
510     JSGlobalData& globalData = exec->globalData();
511     NativeCallFrameTracer tracer(&globalData, exec);
512
513     if (!base->inherits(&RegExpObject::s_info)) {
514         throwTypeError(exec);
515         return false;
516     }
517
518     ASSERT(argument->isString() || argument->isObject());
519     JSString* input = argument->isString() ? asString(argument) : asObject(argument)->toString(exec);
520     return asRegExpObject(base)->test(exec, input);
521 }
522         
523 EncodedJSValue DFG_OPERATION operationArrayPop(ExecState* exec, JSArray* array)
524 {
525     JSGlobalData* globalData = &exec->globalData();
526     NativeCallFrameTracer tracer(globalData, exec);
527     
528     return JSValue::encode(array->pop(exec));
529 }
530         
531 void DFG_OPERATION operationPutByIdStrict(ExecState* exec, EncodedJSValue encodedValue, JSCell* base, Identifier* propertyName)
532 {
533     JSGlobalData* globalData = &exec->globalData();
534     NativeCallFrameTracer tracer(globalData, exec);
535     
536     PutPropertySlot slot(true);
537     base->methodTable()->put(base, exec, *propertyName, JSValue::decode(encodedValue), slot);
538 }
539
540 void DFG_OPERATION operationPutByIdNonStrict(ExecState* exec, EncodedJSValue encodedValue, JSCell* base, Identifier* propertyName)
541 {
542     JSGlobalData* globalData = &exec->globalData();
543     NativeCallFrameTracer tracer(globalData, exec);
544     
545     PutPropertySlot slot(false);
546     base->methodTable()->put(base, exec, *propertyName, JSValue::decode(encodedValue), slot);
547 }
548
549 void DFG_OPERATION operationPutByIdDirectStrict(ExecState* exec, EncodedJSValue encodedValue, JSCell* base, Identifier* propertyName)
550 {
551     JSGlobalData* globalData = &exec->globalData();
552     NativeCallFrameTracer tracer(globalData, exec);
553     
554     PutPropertySlot slot(true);
555     ASSERT(base->isObject());
556     asObject(base)->putDirect(exec->globalData(), *propertyName, JSValue::decode(encodedValue), slot);
557 }
558
559 void DFG_OPERATION operationPutByIdDirectNonStrict(ExecState* exec, EncodedJSValue encodedValue, JSCell* base, Identifier* propertyName)
560 {
561     JSGlobalData* globalData = &exec->globalData();
562     NativeCallFrameTracer tracer(globalData, exec);
563     
564     PutPropertySlot slot(false);
565     ASSERT(base->isObject());
566     asObject(base)->putDirect(exec->globalData(), *propertyName, JSValue::decode(encodedValue), slot);
567 }
568
569 V_FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJCI(operationPutByIdStrictOptimize);
570 void DFG_OPERATION operationPutByIdStrictOptimizeWithReturnAddress(ExecState* exec, EncodedJSValue encodedValue, JSCell* base, Identifier* propertyName, ReturnAddressPtr returnAddress)
571 {
572     JSGlobalData* globalData = &exec->globalData();
573     NativeCallFrameTracer tracer(globalData, exec);
574     
575     JSValue value = JSValue::decode(encodedValue);
576     JSValue baseValue(base);
577     PutPropertySlot slot(true);
578     
579     baseValue.put(exec, *propertyName, value, slot);
580     
581     StructureStubInfo& stubInfo = exec->codeBlock()->getStubInfo(returnAddress);
582     if (stubInfo.seen)
583         dfgRepatchPutByID(exec, baseValue, *propertyName, slot, stubInfo, NotDirect);
584     else
585         stubInfo.seen = true;
586 }
587
588 V_FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJCI(operationPutByIdNonStrictOptimize);
589 void DFG_OPERATION operationPutByIdNonStrictOptimizeWithReturnAddress(ExecState* exec, EncodedJSValue encodedValue, JSCell* base, Identifier* propertyName, ReturnAddressPtr returnAddress)
590 {
591     JSGlobalData* globalData = &exec->globalData();
592     NativeCallFrameTracer tracer(globalData, exec);
593     
594     JSValue value = JSValue::decode(encodedValue);
595     JSValue baseValue(base);
596     PutPropertySlot slot(false);
597     
598     baseValue.put(exec, *propertyName, value, slot);
599     
600     StructureStubInfo& stubInfo = exec->codeBlock()->getStubInfo(returnAddress);
601     if (stubInfo.seen)
602         dfgRepatchPutByID(exec, baseValue, *propertyName, slot, stubInfo, NotDirect);
603     else
604         stubInfo.seen = true;
605 }
606
607 V_FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJCI(operationPutByIdDirectStrictOptimize);
608 void DFG_OPERATION operationPutByIdDirectStrictOptimizeWithReturnAddress(ExecState* exec, EncodedJSValue encodedValue, JSCell* base, Identifier* propertyName, ReturnAddressPtr returnAddress)
609 {
610     JSGlobalData* globalData = &exec->globalData();
611     NativeCallFrameTracer tracer(globalData, exec);
612     
613     JSValue value = JSValue::decode(encodedValue);
614     PutPropertySlot slot(true);
615     
616     ASSERT(base->isObject());
617     asObject(base)->putDirect(exec->globalData(), *propertyName, value, slot);
618     
619     StructureStubInfo& stubInfo = exec->codeBlock()->getStubInfo(returnAddress);
620     if (stubInfo.seen)
621         dfgRepatchPutByID(exec, base, *propertyName, slot, stubInfo, Direct);
622     else
623         stubInfo.seen = true;
624 }
625
626 V_FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJCI(operationPutByIdDirectNonStrictOptimize);
627 void DFG_OPERATION operationPutByIdDirectNonStrictOptimizeWithReturnAddress(ExecState* exec, EncodedJSValue encodedValue, JSCell* base, Identifier* propertyName, ReturnAddressPtr returnAddress)
628 {
629     JSGlobalData* globalData = &exec->globalData();
630     NativeCallFrameTracer tracer(globalData, exec);
631     
632     JSValue value = JSValue::decode(encodedValue);
633     PutPropertySlot slot(false);
634     
635     ASSERT(base->isObject());
636     asObject(base)->putDirect(exec->globalData(), *propertyName, value, slot);
637     
638     StructureStubInfo& stubInfo = exec->codeBlock()->getStubInfo(returnAddress);
639     if (stubInfo.seen)
640         dfgRepatchPutByID(exec, base, *propertyName, slot, stubInfo, Direct);
641     else
642         stubInfo.seen = true;
643 }
644
645 V_FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJCI(operationPutByIdStrictBuildList);
646 void DFG_OPERATION operationPutByIdStrictBuildListWithReturnAddress(ExecState* exec, EncodedJSValue encodedValue, JSCell* base, Identifier* propertyName, ReturnAddressPtr returnAddress)
647 {
648     JSGlobalData* globalData = &exec->globalData();
649     NativeCallFrameTracer tracer(globalData, exec);
650     
651     JSValue value = JSValue::decode(encodedValue);
652     JSValue baseValue(base);
653     PutPropertySlot slot(true);
654     
655     baseValue.put(exec, *propertyName, value, slot);
656     
657     StructureStubInfo& stubInfo = exec->codeBlock()->getStubInfo(returnAddress);
658     dfgBuildPutByIdList(exec, baseValue, *propertyName, slot, stubInfo, NotDirect);
659 }
660
661 V_FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJCI(operationPutByIdNonStrictBuildList);
662 void DFG_OPERATION operationPutByIdNonStrictBuildListWithReturnAddress(ExecState* exec, EncodedJSValue encodedValue, JSCell* base, Identifier* propertyName, ReturnAddressPtr returnAddress)
663 {
664     JSGlobalData* globalData = &exec->globalData();
665     NativeCallFrameTracer tracer(globalData, exec);
666     
667     JSValue value = JSValue::decode(encodedValue);
668     JSValue baseValue(base);
669     PutPropertySlot slot(false);
670     
671     baseValue.put(exec, *propertyName, value, slot);
672     
673     StructureStubInfo& stubInfo = exec->codeBlock()->getStubInfo(returnAddress);
674     dfgBuildPutByIdList(exec, baseValue, *propertyName, slot, stubInfo, NotDirect);
675 }
676
677 V_FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJCI(operationPutByIdDirectStrictBuildList);
678 void DFG_OPERATION operationPutByIdDirectStrictBuildListWithReturnAddress(ExecState* exec, EncodedJSValue encodedValue, JSCell* base, Identifier* propertyName, ReturnAddressPtr returnAddress)
679 {
680     JSGlobalData* globalData = &exec->globalData();
681     NativeCallFrameTracer tracer(globalData, exec);
682     
683     JSValue value = JSValue::decode(encodedValue);
684     PutPropertySlot slot(true);
685     
686     ASSERT(base->isObject());
687     asObject(base)->putDirect(exec->globalData(), *propertyName, value, slot);
688     
689     StructureStubInfo& stubInfo = exec->codeBlock()->getStubInfo(returnAddress);
690     dfgBuildPutByIdList(exec, base, *propertyName, slot, stubInfo, Direct);
691 }
692
693 V_FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJCI(operationPutByIdDirectNonStrictBuildList);
694 void DFG_OPERATION operationPutByIdDirectNonStrictBuildListWithReturnAddress(ExecState* exec, EncodedJSValue encodedValue, JSCell* base, Identifier* propertyName, ReturnAddressPtr returnAddress)
695 {
696     JSGlobalData* globalData = &exec->globalData();
697     NativeCallFrameTracer tracer(globalData, exec);
698     
699     JSValue value = JSValue::decode(encodedValue);
700     PutPropertySlot slot(false);
701     
702     ASSERT(base->isObject());
703     asObject(base)->putDirect(exec->globalData(), *propertyName, value, slot);
704     
705     StructureStubInfo& stubInfo = exec->codeBlock()->getStubInfo(returnAddress);
706     dfgBuildPutByIdList(exec, base, *propertyName, slot, stubInfo, Direct);
707 }
708
709 size_t DFG_OPERATION operationCompareLess(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
710 {
711     JSGlobalData* globalData = &exec->globalData();
712     NativeCallFrameTracer tracer(globalData, exec);
713     
714     return jsLess<true>(exec, JSValue::decode(encodedOp1), JSValue::decode(encodedOp2));
715 }
716
717 size_t DFG_OPERATION operationCompareLessEq(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
718 {
719     JSGlobalData* globalData = &exec->globalData();
720     NativeCallFrameTracer tracer(globalData, exec);
721     
722     return jsLessEq<true>(exec, JSValue::decode(encodedOp1), JSValue::decode(encodedOp2));
723 }
724
725 size_t DFG_OPERATION operationCompareGreater(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
726 {
727     JSGlobalData* globalData = &exec->globalData();
728     NativeCallFrameTracer tracer(globalData, exec);
729     
730     return jsLess<false>(exec, JSValue::decode(encodedOp2), JSValue::decode(encodedOp1));
731 }
732
733 size_t DFG_OPERATION operationCompareGreaterEq(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
734 {
735     JSGlobalData* globalData = &exec->globalData();
736     NativeCallFrameTracer tracer(globalData, exec);
737     
738     return jsLessEq<false>(exec, JSValue::decode(encodedOp2), JSValue::decode(encodedOp1));
739 }
740
741 size_t DFG_OPERATION operationCompareEq(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
742 {
743     JSGlobalData* globalData = &exec->globalData();
744     NativeCallFrameTracer tracer(globalData, exec);
745     
746     return JSValue::equalSlowCaseInline(exec, JSValue::decode(encodedOp1), JSValue::decode(encodedOp2));
747 }
748
749 size_t DFG_OPERATION operationCompareStrictEqCell(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
750 {
751     JSGlobalData* globalData = &exec->globalData();
752     NativeCallFrameTracer tracer(globalData, exec);
753     
754     JSValue op1 = JSValue::decode(encodedOp1);
755     JSValue op2 = JSValue::decode(encodedOp2);
756     
757     ASSERT(op1.isCell());
758     ASSERT(op2.isCell());
759     
760     return JSValue::strictEqualSlowCaseInline(exec, op1, op2);
761 }
762
763 size_t DFG_OPERATION operationCompareStrictEq(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
764 {
765     JSGlobalData* globalData = &exec->globalData();
766     NativeCallFrameTracer tracer(globalData, exec);
767
768     JSValue src1 = JSValue::decode(encodedOp1);
769     JSValue src2 = JSValue::decode(encodedOp2);
770     
771     return JSValue::strictEqual(exec, src1, src2);
772 }
773
774 static void* handleHostCall(ExecState* execCallee, JSValue callee, CodeSpecializationKind kind)
775 {
776     ExecState* exec = execCallee->callerFrame();
777     JSGlobalData* globalData = &exec->globalData();
778
779     execCallee->setScopeChain(exec->scopeChain());
780     execCallee->setCodeBlock(0);
781     execCallee->clearReturnPC();
782
783     if (kind == CodeForCall) {
784         CallData callData;
785         CallType callType = getCallData(callee, callData);
786     
787         ASSERT(callType != CallTypeJS);
788     
789         if (callType == CallTypeHost) {
790             NativeCallFrameTracer tracer(globalData, execCallee);
791             execCallee->setCallee(asObject(callee));
792             globalData->hostCallReturnValue = JSValue::decode(callData.native.function(execCallee));
793             if (globalData->exception)
794                 return 0;
795
796             return reinterpret_cast<void*>(getHostCallReturnValue);
797         }
798     
799         ASSERT(callType == CallTypeNone);
800         exec->globalData().exception = createNotAFunctionError(exec, callee);
801         return 0;
802     }
803
804     ASSERT(kind == CodeForConstruct);
805     
806     ConstructData constructData;
807     ConstructType constructType = getConstructData(callee, constructData);
808     
809     ASSERT(constructType != ConstructTypeJS);
810     
811     if (constructType == ConstructTypeHost) {
812         NativeCallFrameTracer tracer(globalData, execCallee);
813         execCallee->setCallee(asObject(callee));
814         globalData->hostCallReturnValue = JSValue::decode(constructData.native.function(execCallee));
815         if (globalData->exception)
816             return 0;
817
818         return reinterpret_cast<void*>(getHostCallReturnValue);
819     }
820     
821     ASSERT(constructType == ConstructTypeNone);
822     exec->globalData().exception = createNotAConstructorError(exec, callee);
823     return 0;
824 }
825
826 inline void* linkFor(ExecState* execCallee, ReturnAddressPtr returnAddress, CodeSpecializationKind kind)
827 {
828     ExecState* exec = execCallee->callerFrame();
829     JSGlobalData* globalData = &exec->globalData();
830     NativeCallFrameTracer tracer(globalData, exec);
831     
832     JSValue calleeAsValue = execCallee->calleeAsValue();
833     JSCell* calleeAsFunctionCell = getJSFunction(calleeAsValue);
834     if (!calleeAsFunctionCell)
835         return handleHostCall(execCallee, calleeAsValue, kind);
836
837     JSFunction* callee = jsCast<JSFunction*>(calleeAsFunctionCell);
838     execCallee->setScopeChain(callee->scopeUnchecked());
839     ExecutableBase* executable = callee->executable();
840
841     MacroAssemblerCodePtr codePtr;
842     CodeBlock* codeBlock = 0;
843     if (executable->isHostFunction())
844         codePtr = executable->generatedJITCodeFor(kind).addressForCall();
845     else {
846         FunctionExecutable* functionExecutable = static_cast<FunctionExecutable*>(executable);
847         JSObject* error = functionExecutable->compileFor(execCallee, callee->scope(), kind);
848         if (error) {
849             globalData->exception = createStackOverflowError(exec);
850             return 0;
851         }
852         codeBlock = &functionExecutable->generatedBytecodeFor(kind);
853         if (execCallee->argumentCountIncludingThis() < static_cast<size_t>(codeBlock->numParameters()))
854             codePtr = functionExecutable->generatedJITCodeWithArityCheckFor(kind);
855         else
856             codePtr = functionExecutable->generatedJITCodeFor(kind).addressForCall();
857     }
858     CallLinkInfo& callLinkInfo = exec->codeBlock()->getCallLinkInfo(returnAddress);
859     if (!callLinkInfo.seenOnce())
860         callLinkInfo.setSeen();
861     else
862         dfgLinkFor(execCallee, callLinkInfo, codeBlock, callee, codePtr, kind);
863     return codePtr.executableAddress();
864 }
865
866 P_FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_E(operationLinkCall);
867 void* DFG_OPERATION operationLinkCallWithReturnAddress(ExecState* execCallee, ReturnAddressPtr returnAddress)
868 {
869     return linkFor(execCallee, returnAddress, CodeForCall);
870 }
871
872 P_FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_E(operationLinkConstruct);
873 void* DFG_OPERATION operationLinkConstructWithReturnAddress(ExecState* execCallee, ReturnAddressPtr returnAddress)
874 {
875     return linkFor(execCallee, returnAddress, CodeForConstruct);
876 }
877
878 inline void* virtualFor(ExecState* execCallee, CodeSpecializationKind kind)
879 {
880     ExecState* exec = execCallee->callerFrame();
881     JSGlobalData* globalData = &exec->globalData();
882     NativeCallFrameTracer tracer(globalData, exec);
883
884     JSValue calleeAsValue = execCallee->calleeAsValue();
885     JSCell* calleeAsFunctionCell = getJSFunction(calleeAsValue);
886     if (UNLIKELY(!calleeAsFunctionCell))
887         return handleHostCall(execCallee, calleeAsValue, kind);
888     
889     JSFunction* function = jsCast<JSFunction*>(calleeAsFunctionCell);
890     execCallee->setScopeChain(function->scopeUnchecked());
891     ExecutableBase* executable = function->executable();
892     if (UNLIKELY(!executable->hasJITCodeFor(kind))) {
893         FunctionExecutable* functionExecutable = static_cast<FunctionExecutable*>(executable);
894         JSObject* error = functionExecutable->compileFor(execCallee, function->scope(), kind);
895         if (error) {
896             exec->globalData().exception = error;
897             return 0;
898         }
899     }
900     return executable->generatedJITCodeWithArityCheckFor(kind).executableAddress();
901 }
902
903 void* DFG_OPERATION operationVirtualCall(ExecState* execCallee)
904 {    
905     return virtualFor(execCallee, CodeForCall);
906 }
907
908 void* DFG_OPERATION operationVirtualConstruct(ExecState* execCallee)
909 {
910     return virtualFor(execCallee, CodeForConstruct);
911 }
912
913 EncodedJSValue DFG_OPERATION operationResolve(ExecState* exec, Identifier* propertyName)
914 {
915     JSGlobalData* globalData = &exec->globalData();
916     NativeCallFrameTracer tracer(globalData, exec);
917     
918     ScopeChainNode* scopeChain = exec->scopeChain();
919     ScopeChainIterator iter = scopeChain->begin();
920     ScopeChainIterator end = scopeChain->end();
921     ASSERT(iter != end);
922
923     do {
924         JSObject* record = iter->get();
925         PropertySlot slot(record);
926         if (record->getPropertySlot(exec, *propertyName, slot))
927             return JSValue::encode(slot.getValue(exec, *propertyName));
928     } while (++iter != end);
929
930     return throwVMError(exec, createUndefinedVariableError(exec, *propertyName));
931 }
932
933 EncodedJSValue DFG_OPERATION operationResolveBase(ExecState* exec, Identifier* propertyName)
934 {
935     JSGlobalData* globalData = &exec->globalData();
936     NativeCallFrameTracer tracer(globalData, exec);
937     
938     return JSValue::encode(resolveBase(exec, *propertyName, exec->scopeChain(), false));
939 }
940
941 EncodedJSValue DFG_OPERATION operationResolveBaseStrictPut(ExecState* exec, Identifier* propertyName)
942 {
943     JSGlobalData* globalData = &exec->globalData();
944     NativeCallFrameTracer tracer(globalData, exec);
945     
946     JSValue base = resolveBase(exec, *propertyName, exec->scopeChain(), true);
947     if (!base)
948         throwError(exec, createErrorForInvalidGlobalAssignment(exec, propertyName->ustring()));
949     return JSValue::encode(base);
950 }
951
952 EncodedJSValue DFG_OPERATION operationResolveGlobal(ExecState* exec, GlobalResolveInfo* resolveInfo, Identifier* propertyName)
953 {
954     JSGlobalData* globalData = &exec->globalData();
955     NativeCallFrameTracer tracer(globalData, exec);
956     
957     JSGlobalObject* globalObject = exec->lexicalGlobalObject();
958
959     PropertySlot slot(globalObject);
960     if (globalObject->getPropertySlot(exec, *propertyName, slot)) {
961         JSValue result = slot.getValue(exec, *propertyName);
962
963         if (slot.isCacheableValue() && !globalObject->structure()->isUncacheableDictionary() && slot.slotBase() == globalObject) {
964             resolveInfo->structure.set(exec->globalData(), exec->codeBlock()->ownerExecutable(), globalObject->structure());
965             resolveInfo->offset = slot.cachedOffset();
966         }
967
968         return JSValue::encode(result);
969     }
970
971     return throwVMError(exec, createUndefinedVariableError(exec, *propertyName));
972 }
973
974 EncodedJSValue DFG_OPERATION operationToPrimitive(ExecState* exec, EncodedJSValue value)
975 {
976     JSGlobalData* globalData = &exec->globalData();
977     NativeCallFrameTracer tracer(globalData, exec);
978     
979     return JSValue::encode(JSValue::decode(value).toPrimitive(exec));
980 }
981
982 EncodedJSValue DFG_OPERATION operationStrCat(ExecState* exec, void* scratch, size_t size)
983 {
984     JSGlobalData* globalData = &exec->globalData();
985     NativeCallFrameTracer tracer(globalData, exec);
986
987     return JSValue::encode(jsString(exec, static_cast<Register*>(static_cast<ScratchBuffer*>(scratch)->dataBuffer()), size));
988 }
989
990 EncodedJSValue DFG_OPERATION operationNewArray(ExecState* exec, void* scratch, size_t size)
991 {
992     JSGlobalData* globalData = &exec->globalData();
993     NativeCallFrameTracer tracer(globalData, exec);
994
995     return JSValue::encode(constructArray(exec, static_cast<JSValue*>(static_cast<ScratchBuffer*>(scratch)->dataBuffer()), size));
996 }
997
998 EncodedJSValue DFG_OPERATION operationNewArrayBuffer(ExecState* exec, size_t start, size_t size)
999 {
1000     JSGlobalData& globalData = exec->globalData();
1001     NativeCallFrameTracer tracer(&globalData, exec);
1002     return JSValue::encode(constructArray(exec, exec->codeBlock()->constantBuffer(start), size));
1003 }
1004
1005 EncodedJSValue DFG_OPERATION operationNewRegexp(ExecState* exec, void* regexpPtr)
1006 {
1007     JSGlobalData& globalData = exec->globalData();
1008     NativeCallFrameTracer tracer(&globalData, exec);
1009     RegExp* regexp = static_cast<RegExp*>(regexpPtr);
1010     if (!regexp->isValid()) {
1011         throwError(exec, createSyntaxError(exec, "Invalid flags supplied to RegExp constructor."));
1012         return JSValue::encode(jsUndefined());
1013     }
1014     
1015     return JSValue::encode(RegExpObject::create(exec->globalData(), exec->lexicalGlobalObject(), exec->lexicalGlobalObject()->regExpStructure(), regexp));
1016 }
1017
1018 JSCell* DFG_OPERATION operationCreateActivation(ExecState* exec)
1019 {
1020     JSGlobalData& globalData = exec->globalData();
1021     NativeCallFrameTracer tracer(&globalData, exec);
1022     JSActivation* activation = JSActivation::create(
1023         globalData, exec, static_cast<FunctionExecutable*>(exec->codeBlock()->ownerExecutable()));
1024     exec->setScopeChain(exec->scopeChain()->push(activation));
1025     return activation;
1026 }
1027
1028 void DFG_OPERATION operationTearOffActivation(ExecState* exec, JSCell* activation)
1029 {
1030     ASSERT(activation);
1031     ASSERT(activation->inherits(&JSActivation::s_info));
1032     JSGlobalData& globalData = exec->globalData();
1033     NativeCallFrameTracer tracer(&globalData, exec);
1034     jsCast<JSActivation*>(activation)->tearOff(exec->globalData());
1035 }
1036
1037 JSCell* DFG_OPERATION operationNewFunction(ExecState* exec, JSCell* functionExecutable)
1038 {
1039     ASSERT(functionExecutable->inherits(&FunctionExecutable::s_info));
1040     JSGlobalData& globalData = exec->globalData();
1041     NativeCallFrameTracer tracer(&globalData, exec);
1042     return static_cast<FunctionExecutable*>(functionExecutable)->make(exec, exec->scopeChain());
1043 }
1044
1045 JSCell* DFG_OPERATION operationNewFunctionExpression(ExecState* exec, JSCell* functionExecutableAsCell)
1046 {
1047     ASSERT(functionExecutableAsCell->inherits(&FunctionExecutable::s_info));
1048     FunctionExecutable* functionExecutable =
1049         static_cast<FunctionExecutable*>(functionExecutableAsCell);
1050     JSFunction *function = functionExecutable->make(exec, exec->scopeChain());
1051     if (!functionExecutable->name().isNull()) {
1052         JSStaticScopeObject* functionScopeObject =
1053             JSStaticScopeObject::create(
1054                 exec, functionExecutable->name(), function, ReadOnly | DontDelete);
1055         function->setScope(exec->globalData(), function->scope()->push(functionScopeObject));
1056     }
1057     return function;
1058 }
1059
1060 size_t DFG_OPERATION operationIsObject(EncodedJSValue value)
1061 {
1062     return jsIsObjectType(JSValue::decode(value));
1063 }
1064
1065 size_t DFG_OPERATION operationIsFunction(EncodedJSValue value)
1066 {
1067     return jsIsFunctionType(JSValue::decode(value));
1068 }
1069
1070 double DFG_OPERATION operationFModOnInts(int32_t a, int32_t b)
1071 {
1072     return fmod(a, b);
1073 }
1074
1075 DFGHandlerEncoded DFG_OPERATION lookupExceptionHandler(ExecState* exec, uint32_t callIndex)
1076 {
1077     JSGlobalData* globalData = &exec->globalData();
1078     NativeCallFrameTracer tracer(globalData, exec);
1079     
1080     JSValue exceptionValue = exec->exception();
1081     ASSERT(exceptionValue);
1082
1083     unsigned vPCIndex = exec->codeBlock()->bytecodeOffsetForCallAtIndex(callIndex);
1084     HandlerInfo* handler = exec->globalData().interpreter->throwException(exec, exceptionValue, vPCIndex);
1085
1086     void* catchRoutine = handler ? handler->nativeCode.executableAddress() : (void*)ctiOpThrowNotCaught;
1087     ASSERT(catchRoutine);
1088     return dfgHandlerEncoded(exec, catchRoutine);
1089 }
1090
1091 DFGHandlerEncoded DFG_OPERATION lookupExceptionHandlerInStub(ExecState* exec, StructureStubInfo* stubInfo)
1092 {
1093     JSGlobalData* globalData = &exec->globalData();
1094     NativeCallFrameTracer tracer(globalData, exec);
1095     
1096     JSValue exceptionValue = exec->exception();
1097     ASSERT(exceptionValue);
1098     
1099     CodeOrigin codeOrigin = stubInfo->codeOrigin;
1100     while (codeOrigin.inlineCallFrame)
1101         codeOrigin = codeOrigin.inlineCallFrame->caller;
1102
1103     HandlerInfo* handler = exec->globalData().interpreter->throwException(exec, exceptionValue, codeOrigin.bytecodeIndex);
1104
1105     void* catchRoutine = handler ? handler->nativeCode.executableAddress() : (void*)ctiOpThrowNotCaught;
1106     ASSERT(catchRoutine);
1107     return dfgHandlerEncoded(exec, catchRoutine);
1108 }
1109
1110 double DFG_OPERATION dfgConvertJSValueToNumber(ExecState* exec, EncodedJSValue value)
1111 {
1112     JSGlobalData* globalData = &exec->globalData();
1113     NativeCallFrameTracer tracer(globalData, exec);
1114     
1115     return JSValue::decode(value).toNumber(exec);
1116 }
1117
1118 size_t DFG_OPERATION dfgConvertJSValueToInt32(ExecState* exec, EncodedJSValue value)
1119 {
1120     JSGlobalData* globalData = &exec->globalData();
1121     NativeCallFrameTracer tracer(globalData, exec);
1122     
1123     // toInt32/toUInt32 return the same value; we want the value zero extended to fill the register.
1124     return JSValue::decode(value).toUInt32(exec);
1125 }
1126
1127 size_t DFG_OPERATION dfgConvertJSValueToBoolean(ExecState* exec, EncodedJSValue encodedOp)
1128 {
1129     JSGlobalData* globalData = &exec->globalData();
1130     NativeCallFrameTracer tracer(globalData, exec);
1131     
1132     return JSValue::decode(encodedOp).toBoolean();
1133 }
1134
1135 #if DFG_ENABLE(VERBOSE_SPECULATION_FAILURE)
1136 void DFG_OPERATION debugOperationPrintSpeculationFailure(ExecState* exec, void* debugInfoRaw)
1137 {
1138     JSGlobalData* globalData = &exec->globalData();
1139     NativeCallFrameTracer tracer(globalData, exec);
1140     
1141     SpeculationFailureDebugInfo* debugInfo = static_cast<SpeculationFailureDebugInfo*>(debugInfoRaw);
1142     CodeBlock* codeBlock = debugInfo->codeBlock;
1143     CodeBlock* alternative = codeBlock->alternative();
1144     dataLog("Speculation failure in %p at @%u with executeCounter = %d, "
1145             "reoptimizationRetryCounter = %u, optimizationDelayCounter = %u, "
1146             "success/fail %u/(%u+%u)\n",
1147             codeBlock,
1148             debugInfo->nodeIndex,
1149             alternative ? alternative->jitExecuteCounter() : 0,
1150             alternative ? alternative->reoptimizationRetryCounter() : 0,
1151             alternative ? alternative->optimizationDelayCounter() : 0,
1152             codeBlock->speculativeSuccessCounter(),
1153             codeBlock->speculativeFailCounter(),
1154             codeBlock->forcedOSRExitCounter());
1155 }
1156 #endif
1157
1158 } // extern "C"
1159 } } // namespace JSC::DFG
1160
1161 #endif
1162
1163 #if COMPILER(GCC)
1164
1165 namespace JSC {
1166
1167 #if CPU(X86_64)
1168 asm (
1169 ".globl " SYMBOL_STRING(getHostCallReturnValue) "\n"
1170 HIDE_SYMBOL(getHostCallReturnValue) "\n"
1171 SYMBOL_STRING(getHostCallReturnValue) ":" "\n"
1172     "mov -40(%r13), %r13\n"
1173     "mov %r13, %rdi\n"
1174     "jmp " SYMBOL_STRING_RELOCATION(getHostCallReturnValueWithExecState) "\n"
1175 );
1176 #elif CPU(X86)
1177 asm (
1178 ".text" "\n" \
1179 ".globl " SYMBOL_STRING(getHostCallReturnValue) "\n"
1180 HIDE_SYMBOL(getHostCallReturnValue) "\n"
1181 SYMBOL_STRING(getHostCallReturnValue) ":" "\n"
1182     "mov -40(%edi), %edi\n"
1183     "mov %edi, 4(%esp)\n"
1184     "jmp " SYMBOL_STRING_RELOCATION(getHostCallReturnValueWithExecState) "\n"
1185 );
1186 #elif CPU(ARM_THUMB2)
1187 asm (
1188 ".text" "\n"
1189 ".align 2" "\n"
1190 ".globl " SYMBOL_STRING(getHostCallReturnValue) "\n"
1191 HIDE_SYMBOL(getHostCallReturnValue) "\n"
1192 ".thumb" "\n"
1193 ".thumb_func " THUMB_FUNC_PARAM(getHostCallReturnValue) "\n"
1194 SYMBOL_STRING(getHostCallReturnValue) ":" "\n"
1195     "ldr r5, [r5, #-40]" "\n"
1196     "mov r0, r5" "\n"
1197     "b " SYMBOL_STRING_RELOCATION(getHostCallReturnValueWithExecState) "\n"
1198 );
1199 #endif
1200
1201 extern "C" EncodedJSValue HOST_CALL_RETURN_VALUE_OPTION getHostCallReturnValueWithExecState(ExecState* exec)
1202 {
1203     if (!exec)
1204         return JSValue::encode(JSValue());
1205     return JSValue::encode(exec->globalData().hostCallReturnValue);
1206 }
1207
1208 } // namespace JSC
1209
1210 #endif // COMPILER(GCC)
1211