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