2 * Copyright (C) 2011 Apple Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
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.
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.
27 #include "DFGOperations.h"
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 "JITExceptions.h"
37 #include "JSActivation.h"
38 #include "JSGlobalData.h"
39 #include "JSStaticScopeObject.h"
40 #include "Operations.h"
46 #define FUNCTION_WRAPPER_WITH_RETURN_ADDRESS(function, register) \
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" \
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)
61 #define FUNCTION_WRAPPER_WITH_RETURN_ADDRESS(function, offset) \
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" \
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)
76 #elif COMPILER(GCC) && CPU(ARM_THUMB2)
78 #define FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_E(function) \
82 ".globl " SYMBOL_STRING(function) "\n" \
83 HIDE_SYMBOL(function) "\n" \
85 ".thumb_func " THUMB_FUNC_PARAM(function) "\n" \
86 SYMBOL_STRING(function) ":" "\n" \
88 "b " SYMBOL_STRING_RELOCATION(function) "WithReturnAddress" "\n" \
91 #define FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_ECI(function) \
95 ".globl " SYMBOL_STRING(function) "\n" \
96 HIDE_SYMBOL(function) "\n" \
98 ".thumb_func " THUMB_FUNC_PARAM(function) "\n" \
99 SYMBOL_STRING(function) ":" "\n" \
101 "b " SYMBOL_STRING_RELOCATION(function) "WithReturnAddress" "\n" \
104 #define FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJI(function) \
108 ".globl " SYMBOL_STRING(function) "\n" \
109 HIDE_SYMBOL(function) "\n" \
111 ".thumb_func " THUMB_FUNC_PARAM(function) "\n" \
112 SYMBOL_STRING(function) ":" "\n" \
113 "str lr, [sp, #0]" "\n" \
114 "b " SYMBOL_STRING_RELOCATION(function) "WithReturnAddress" "\n" \
117 #define FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJCI(function) \
121 ".globl " SYMBOL_STRING(function) "\n" \
122 HIDE_SYMBOL(function) "\n" \
124 ".thumb_func " THUMB_FUNC_PARAM(function) "\n" \
125 SYMBOL_STRING(function) ":" "\n" \
126 "str lr, [sp, #4]" "\n" \
127 "b " SYMBOL_STRING_RELOCATION(function) "WithReturnAddress" "\n" \
132 #define P_FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_E(function) \
133 void* DFG_OPERATION function##WithReturnAddress(ExecState*, ReturnAddressPtr); \
134 FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_E(function)
136 #define J_FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_ECI(function) \
137 EncodedJSValue DFG_OPERATION function##WithReturnAddress(ExecState*, JSCell*, Identifier*, ReturnAddressPtr); \
138 FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_ECI(function)
140 #define J_FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJI(function) \
141 EncodedJSValue DFG_OPERATION function##WithReturnAddress(ExecState*, EncodedJSValue, Identifier*, ReturnAddressPtr); \
142 FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJI(function)
144 #define V_FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJCI(function) \
145 void DFG_OPERATION function##WithReturnAddress(ExecState*, EncodedJSValue, JSCell*, Identifier*, ReturnAddressPtr); \
146 FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJCI(function)
148 namespace JSC
{ namespace DFG
{
150 template<bool strict
>
151 static inline void putByVal(ExecState
* exec
, JSValue baseValue
, uint32_t index
, JSValue value
)
153 JSGlobalData
& globalData
= exec
->globalData();
154 NativeCallFrameTracer
tracer(&globalData
, exec
);
156 if (isJSArray(baseValue
)) {
157 JSArray
* array
= asArray(baseValue
);
158 if (array
->canSetIndex(index
)) {
159 array
->setIndex(globalData
, index
, value
);
163 JSArray::putByIndex(array
, exec
, index
, value
, strict
);
167 baseValue
.putByIndex(exec
, index
, value
, strict
);
170 template<bool strict
>
171 ALWAYS_INLINE
static void DFG_OPERATION
operationPutByValInternal(ExecState
* exec
, EncodedJSValue encodedBase
, EncodedJSValue encodedProperty
, EncodedJSValue encodedValue
)
173 JSGlobalData
* globalData
= &exec
->globalData();
174 NativeCallFrameTracer
tracer(globalData
, exec
);
176 JSValue baseValue
= JSValue::decode(encodedBase
);
177 JSValue property
= JSValue::decode(encodedProperty
);
178 JSValue value
= JSValue::decode(encodedValue
);
180 if (LIKELY(property
.isUInt32())) {
181 putByVal
<strict
>(exec
, baseValue
, property
.asUInt32(), value
);
185 if (property
.isDouble()) {
186 double propertyAsDouble
= property
.asDouble();
187 uint32_t propertyAsUInt32
= static_cast<uint32_t>(propertyAsDouble
);
188 if (propertyAsDouble
== propertyAsUInt32
) {
189 putByVal
<strict
>(exec
, baseValue
, propertyAsUInt32
, value
);
195 // Don't put to an object if toString throws an exception.
196 Identifier
ident(exec
, property
.toString(exec
)->value(exec
));
197 if (!globalData
->exception
) {
198 PutPropertySlot
slot(strict
);
199 baseValue
.put(exec
, ident
, value
, slot
);
205 EncodedJSValue DFG_OPERATION
operationConvertThis(ExecState
* exec
, EncodedJSValue encodedOp
)
207 JSGlobalData
* globalData
= &exec
->globalData();
208 NativeCallFrameTracer
tracer(globalData
, exec
);
210 return JSValue::encode(JSValue::decode(encodedOp
).toThisObject(exec
));
213 inline JSCell
* createThis(ExecState
* exec
, JSCell
* prototype
, JSFunction
* constructor
)
216 ConstructData constructData
;
217 ASSERT(constructor
->methodTable()->getConstructData(constructor
, constructData
) == ConstructTypeJS
);
220 JSGlobalData
& globalData
= exec
->globalData();
221 NativeCallFrameTracer
tracer(&globalData
, exec
);
223 Structure
* structure
;
224 if (prototype
->isObject())
225 structure
= asObject(prototype
)->inheritorID(globalData
);
227 structure
= constructor
->scope()->globalObject
->emptyObjectStructure();
229 return constructEmptyObject(exec
, structure
);
232 JSCell
* DFG_OPERATION
operationCreateThis(ExecState
* exec
, JSCell
* prototype
)
234 JSGlobalData
* globalData
= &exec
->globalData();
235 NativeCallFrameTracer
tracer(globalData
, exec
);
237 return createThis(exec
, prototype
, jsCast
<JSFunction
*>(exec
->callee()));
240 JSCell
* DFG_OPERATION
operationCreateThisInlined(ExecState
* exec
, JSCell
* prototype
, JSCell
* constructor
)
242 JSGlobalData
* globalData
= &exec
->globalData();
243 NativeCallFrameTracer
tracer(globalData
, exec
);
245 return createThis(exec
, prototype
, jsCast
<JSFunction
*>(constructor
));
248 JSCell
* DFG_OPERATION
operationNewObject(ExecState
* exec
)
250 JSGlobalData
* globalData
= &exec
->globalData();
251 NativeCallFrameTracer
tracer(globalData
, exec
);
253 return constructEmptyObject(exec
);
256 EncodedJSValue DFG_OPERATION
operationValueAdd(ExecState
* exec
, EncodedJSValue encodedOp1
, EncodedJSValue encodedOp2
)
258 JSGlobalData
* globalData
= &exec
->globalData();
259 NativeCallFrameTracer
tracer(globalData
, exec
);
261 JSValue op1
= JSValue::decode(encodedOp1
);
262 JSValue op2
= JSValue::decode(encodedOp2
);
264 return JSValue::encode(jsAdd(exec
, op1
, op2
));
267 EncodedJSValue DFG_OPERATION
operationValueAddNotNumber(ExecState
* exec
, EncodedJSValue encodedOp1
, EncodedJSValue encodedOp2
)
269 JSGlobalData
* globalData
= &exec
->globalData();
270 NativeCallFrameTracer
tracer(globalData
, exec
);
272 JSValue op1
= JSValue::decode(encodedOp1
);
273 JSValue op2
= JSValue::decode(encodedOp2
);
275 ASSERT(!op1
.isNumber() || !op2
.isNumber());
277 if (op1
.isString() && !op2
.isObject())
278 return JSValue::encode(jsString(exec
, asString(op1
), op2
.toString(exec
)));
280 return JSValue::encode(jsAddSlowCase(exec
, op1
, op2
));
283 static inline EncodedJSValue
getByVal(ExecState
* exec
, JSCell
* base
, uint32_t index
)
285 JSGlobalData
& globalData
= exec
->globalData();
286 NativeCallFrameTracer
tracer(&globalData
, exec
);
288 // FIXME: the JIT used to handle these in compiled code!
289 if (isJSArray(base
) && asArray(base
)->canGetIndex(index
))
290 return JSValue::encode(asArray(base
)->getIndex(index
));
292 // FIXME: the JITstub used to relink this to an optimized form!
293 if (isJSString(base
) && asString(base
)->canGetIndex(index
))
294 return JSValue::encode(asString(base
)->getIndex(exec
, index
));
296 return JSValue::encode(JSValue(base
).get(exec
, index
));
299 EncodedJSValue DFG_OPERATION
operationGetByVal(ExecState
* exec
, EncodedJSValue encodedBase
, EncodedJSValue encodedProperty
)
301 JSGlobalData
* globalData
= &exec
->globalData();
302 NativeCallFrameTracer
tracer(globalData
, exec
);
304 JSValue baseValue
= JSValue::decode(encodedBase
);
305 JSValue property
= JSValue::decode(encodedProperty
);
307 if (LIKELY(baseValue
.isCell())) {
308 JSCell
* base
= baseValue
.asCell();
310 if (property
.isUInt32()) {
311 return getByVal(exec
, base
, property
.asUInt32());
312 } else if (property
.isDouble()) {
313 double propertyAsDouble
= property
.asDouble();
314 uint32_t propertyAsUInt32
= static_cast<uint32_t>(propertyAsDouble
);
315 if (propertyAsUInt32
== propertyAsDouble
)
316 return getByVal(exec
, base
, propertyAsUInt32
);
317 } else if (property
.isString()) {
318 if (JSValue result
= base
->fastGetOwnProperty(exec
, asString(property
)->value(exec
)))
319 return JSValue::encode(result
);
323 Identifier
ident(exec
, property
.toString(exec
)->value(exec
));
324 return JSValue::encode(baseValue
.get(exec
, ident
));
327 EncodedJSValue DFG_OPERATION
operationGetByValCell(ExecState
* exec
, JSCell
* base
, EncodedJSValue encodedProperty
)
329 JSGlobalData
* globalData
= &exec
->globalData();
330 NativeCallFrameTracer
tracer(globalData
, exec
);
332 JSValue property
= JSValue::decode(encodedProperty
);
334 if (property
.isUInt32())
335 return getByVal(exec
, base
, property
.asUInt32());
336 if (property
.isDouble()) {
337 double propertyAsDouble
= property
.asDouble();
338 uint32_t propertyAsUInt32
= static_cast<uint32_t>(propertyAsDouble
);
339 if (propertyAsUInt32
== propertyAsDouble
)
340 return getByVal(exec
, base
, propertyAsUInt32
);
341 } else if (property
.isString()) {
342 if (JSValue result
= base
->fastGetOwnProperty(exec
, asString(property
)->value(exec
)))
343 return JSValue::encode(result
);
346 Identifier
ident(exec
, property
.toString(exec
)->value(exec
));
347 return JSValue::encode(JSValue(base
).get(exec
, ident
));
350 EncodedJSValue DFG_OPERATION
operationGetById(ExecState
* exec
, EncodedJSValue base
, Identifier
* propertyName
)
352 JSGlobalData
* globalData
= &exec
->globalData();
353 NativeCallFrameTracer
tracer(globalData
, exec
);
355 JSValue baseValue
= JSValue::decode(base
);
356 PropertySlot
slot(baseValue
);
357 return JSValue::encode(baseValue
.get(exec
, *propertyName
, slot
));
360 J_FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJI(operationGetByIdBuildList
);
361 EncodedJSValue DFG_OPERATION
operationGetByIdBuildListWithReturnAddress(ExecState
* exec
, EncodedJSValue base
, Identifier
* propertyName
, ReturnAddressPtr returnAddress
)
363 JSGlobalData
* globalData
= &exec
->globalData();
364 NativeCallFrameTracer
tracer(globalData
, exec
);
366 JSValue baseValue
= JSValue::decode(base
);
367 PropertySlot
slot(baseValue
);
368 JSValue result
= baseValue
.get(exec
, *propertyName
, slot
);
370 StructureStubInfo
& stubInfo
= exec
->codeBlock()->getStubInfo(returnAddress
);
371 dfgBuildGetByIDList(exec
, baseValue
, *propertyName
, slot
, stubInfo
);
373 return JSValue::encode(result
);
376 J_FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJI(operationGetByIdProtoBuildList
);
377 EncodedJSValue DFG_OPERATION
operationGetByIdProtoBuildListWithReturnAddress(ExecState
* exec
, EncodedJSValue base
, Identifier
* propertyName
, ReturnAddressPtr returnAddress
)
379 JSGlobalData
* globalData
= &exec
->globalData();
380 NativeCallFrameTracer
tracer(globalData
, exec
);
382 JSValue baseValue
= JSValue::decode(base
);
383 PropertySlot
slot(baseValue
);
384 JSValue result
= baseValue
.get(exec
, *propertyName
, slot
);
386 StructureStubInfo
& stubInfo
= exec
->codeBlock()->getStubInfo(returnAddress
);
387 dfgBuildGetByIDProtoList(exec
, baseValue
, *propertyName
, slot
, stubInfo
);
389 return JSValue::encode(result
);
392 J_FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJI(operationGetByIdOptimize
);
393 EncodedJSValue DFG_OPERATION
operationGetByIdOptimizeWithReturnAddress(ExecState
* exec
, EncodedJSValue base
, Identifier
* propertyName
, ReturnAddressPtr returnAddress
)
395 JSGlobalData
* globalData
= &exec
->globalData();
396 NativeCallFrameTracer
tracer(globalData
, exec
);
398 JSValue baseValue
= JSValue::decode(base
);
399 PropertySlot
slot(baseValue
);
400 JSValue result
= baseValue
.get(exec
, *propertyName
, slot
);
402 StructureStubInfo
& stubInfo
= exec
->codeBlock()->getStubInfo(returnAddress
);
404 dfgRepatchGetByID(exec
, baseValue
, *propertyName
, slot
, stubInfo
);
406 stubInfo
.seen
= true;
408 return JSValue::encode(result
);
411 EncodedJSValue DFG_OPERATION
operationCallCustomGetter(ExecState
* exec
, JSCell
* base
, PropertySlot::GetValueFunc function
, Identifier
* ident
)
413 JSGlobalData
* globalData
= &exec
->globalData();
414 NativeCallFrameTracer
tracer(globalData
, exec
);
416 return JSValue::encode(function(exec
, asObject(base
), *ident
));
419 EncodedJSValue DFG_OPERATION
operationCallGetter(ExecState
* exec
, JSCell
* base
, JSCell
* value
)
421 JSGlobalData
* globalData
= &exec
->globalData();
422 NativeCallFrameTracer
tracer(globalData
, exec
);
424 GetterSetter
* getterSetter
= asGetterSetter(value
);
425 JSObject
* getter
= getterSetter
->getter();
427 return JSValue::encode(jsUndefined());
429 CallType callType
= getter
->methodTable()->getCallData(getter
, callData
);
430 return JSValue::encode(call(exec
, getter
, callType
, callData
, asObject(base
), ArgList()));
433 void DFG_OPERATION
operationPutByValStrict(ExecState
* exec
, EncodedJSValue encodedBase
, EncodedJSValue encodedProperty
, EncodedJSValue encodedValue
)
435 JSGlobalData
* globalData
= &exec
->globalData();
436 NativeCallFrameTracer
tracer(globalData
, exec
);
438 operationPutByValInternal
<true>(exec
, encodedBase
, encodedProperty
, encodedValue
);
441 void DFG_OPERATION
operationPutByValNonStrict(ExecState
* exec
, EncodedJSValue encodedBase
, EncodedJSValue encodedProperty
, EncodedJSValue encodedValue
)
443 JSGlobalData
* globalData
= &exec
->globalData();
444 NativeCallFrameTracer
tracer(globalData
, exec
);
446 operationPutByValInternal
<false>(exec
, encodedBase
, encodedProperty
, encodedValue
);
449 void DFG_OPERATION
operationPutByValCellStrict(ExecState
* exec
, JSCell
* cell
, EncodedJSValue encodedProperty
, EncodedJSValue encodedValue
)
451 JSGlobalData
* globalData
= &exec
->globalData();
452 NativeCallFrameTracer
tracer(globalData
, exec
);
454 operationPutByValInternal
<true>(exec
, JSValue::encode(cell
), encodedProperty
, encodedValue
);
457 void DFG_OPERATION
operationPutByValCellNonStrict(ExecState
* exec
, JSCell
* cell
, EncodedJSValue encodedProperty
, EncodedJSValue encodedValue
)
459 JSGlobalData
* globalData
= &exec
->globalData();
460 NativeCallFrameTracer
tracer(globalData
, exec
);
462 operationPutByValInternal
<false>(exec
, JSValue::encode(cell
), encodedProperty
, encodedValue
);
465 void DFG_OPERATION
operationPutByValBeyondArrayBoundsStrict(ExecState
* exec
, JSArray
* array
, int32_t index
, EncodedJSValue encodedValue
)
467 JSGlobalData
* globalData
= &exec
->globalData();
468 NativeCallFrameTracer
tracer(globalData
, exec
);
471 // We should only get here if index is outside the existing vector.
472 ASSERT(!array
->canSetIndex(index
));
473 JSArray::putByIndex(array
, exec
, index
, JSValue::decode(encodedValue
), true);
477 PutPropertySlot
slot(true);
478 array
->methodTable()->put(
479 array
, exec
, Identifier::from(exec
, index
), JSValue::decode(encodedValue
), slot
);
482 void DFG_OPERATION
operationPutByValBeyondArrayBoundsNonStrict(ExecState
* exec
, JSArray
* array
, int32_t index
, EncodedJSValue encodedValue
)
484 JSGlobalData
* globalData
= &exec
->globalData();
485 NativeCallFrameTracer
tracer(globalData
, exec
);
488 // We should only get here if index is outside the existing vector.
489 ASSERT(!array
->canSetIndex(index
));
490 JSArray::putByIndex(array
, exec
, index
, JSValue::decode(encodedValue
), false);
494 PutPropertySlot
slot(false);
495 array
->methodTable()->put(
496 array
, exec
, Identifier::from(exec
, index
), JSValue::decode(encodedValue
), slot
);
499 EncodedJSValue DFG_OPERATION
operationArrayPush(ExecState
* exec
, EncodedJSValue encodedValue
, JSArray
* array
)
501 JSGlobalData
* globalData
= &exec
->globalData();
502 NativeCallFrameTracer
tracer(globalData
, exec
);
504 array
->push(exec
, JSValue::decode(encodedValue
));
505 return JSValue::encode(jsNumber(array
->length()));
508 EncodedJSValue DFG_OPERATION
operationRegExpExec(ExecState
* exec
, JSCell
* base
, JSCell
* argument
)
510 JSGlobalData
& globalData
= exec
->globalData();
511 NativeCallFrameTracer
tracer(&globalData
, exec
);
513 if (!base
->inherits(&RegExpObject::s_info
))
514 return throwVMTypeError(exec
);
516 ASSERT(argument
->isString() || argument
->isObject());
517 JSString
* input
= argument
->isString() ? asString(argument
) : asObject(argument
)->toString(exec
);
518 return JSValue::encode(asRegExpObject(base
)->exec(exec
, input
));
521 size_t DFG_OPERATION
operationRegExpTest(ExecState
* exec
, JSCell
* base
, JSCell
* argument
)
523 JSGlobalData
& globalData
= exec
->globalData();
524 NativeCallFrameTracer
tracer(&globalData
, exec
);
526 if (!base
->inherits(&RegExpObject::s_info
)) {
527 throwTypeError(exec
);
531 ASSERT(argument
->isString() || argument
->isObject());
532 JSString
* input
= argument
->isString() ? asString(argument
) : asObject(argument
)->toString(exec
);
533 return asRegExpObject(base
)->test(exec
, input
);
536 EncodedJSValue DFG_OPERATION
operationArrayPop(ExecState
* exec
, JSArray
* array
)
538 JSGlobalData
* globalData
= &exec
->globalData();
539 NativeCallFrameTracer
tracer(globalData
, exec
);
541 return JSValue::encode(array
->pop(exec
));
544 void DFG_OPERATION
operationPutByIdStrict(ExecState
* exec
, EncodedJSValue encodedValue
, JSCell
* base
, Identifier
* propertyName
)
546 JSGlobalData
* globalData
= &exec
->globalData();
547 NativeCallFrameTracer
tracer(globalData
, exec
);
549 PutPropertySlot
slot(true);
550 base
->methodTable()->put(base
, exec
, *propertyName
, JSValue::decode(encodedValue
), slot
);
553 void DFG_OPERATION
operationPutByIdNonStrict(ExecState
* exec
, EncodedJSValue encodedValue
, JSCell
* base
, Identifier
* propertyName
)
555 JSGlobalData
* globalData
= &exec
->globalData();
556 NativeCallFrameTracer
tracer(globalData
, exec
);
558 PutPropertySlot
slot(false);
559 base
->methodTable()->put(base
, exec
, *propertyName
, JSValue::decode(encodedValue
), slot
);
562 void DFG_OPERATION
operationPutByIdDirectStrict(ExecState
* exec
, EncodedJSValue encodedValue
, JSCell
* base
, Identifier
* propertyName
)
564 JSGlobalData
* globalData
= &exec
->globalData();
565 NativeCallFrameTracer
tracer(globalData
, exec
);
567 PutPropertySlot
slot(true);
568 ASSERT(base
->isObject());
569 asObject(base
)->putDirect(exec
->globalData(), *propertyName
, JSValue::decode(encodedValue
), slot
);
572 void DFG_OPERATION
operationPutByIdDirectNonStrict(ExecState
* exec
, EncodedJSValue encodedValue
, JSCell
* base
, Identifier
* propertyName
)
574 JSGlobalData
* globalData
= &exec
->globalData();
575 NativeCallFrameTracer
tracer(globalData
, exec
);
577 PutPropertySlot
slot(false);
578 ASSERT(base
->isObject());
579 asObject(base
)->putDirect(exec
->globalData(), *propertyName
, JSValue::decode(encodedValue
), slot
);
582 V_FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJCI(operationPutByIdStrictOptimize
);
583 void DFG_OPERATION
operationPutByIdStrictOptimizeWithReturnAddress(ExecState
* exec
, EncodedJSValue encodedValue
, JSCell
* base
, Identifier
* propertyName
, ReturnAddressPtr returnAddress
)
585 JSGlobalData
* globalData
= &exec
->globalData();
586 NativeCallFrameTracer
tracer(globalData
, exec
);
588 JSValue value
= JSValue::decode(encodedValue
);
589 JSValue
baseValue(base
);
590 PutPropertySlot
slot(true);
592 baseValue
.put(exec
, *propertyName
, value
, slot
);
594 StructureStubInfo
& stubInfo
= exec
->codeBlock()->getStubInfo(returnAddress
);
596 dfgRepatchPutByID(exec
, baseValue
, *propertyName
, slot
, stubInfo
, NotDirect
);
598 stubInfo
.seen
= true;
601 V_FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJCI(operationPutByIdNonStrictOptimize
);
602 void DFG_OPERATION
operationPutByIdNonStrictOptimizeWithReturnAddress(ExecState
* exec
, EncodedJSValue encodedValue
, JSCell
* base
, Identifier
* propertyName
, ReturnAddressPtr returnAddress
)
604 JSGlobalData
* globalData
= &exec
->globalData();
605 NativeCallFrameTracer
tracer(globalData
, exec
);
607 JSValue value
= JSValue::decode(encodedValue
);
608 JSValue
baseValue(base
);
609 PutPropertySlot
slot(false);
611 baseValue
.put(exec
, *propertyName
, value
, slot
);
613 StructureStubInfo
& stubInfo
= exec
->codeBlock()->getStubInfo(returnAddress
);
615 dfgRepatchPutByID(exec
, baseValue
, *propertyName
, slot
, stubInfo
, NotDirect
);
617 stubInfo
.seen
= true;
620 V_FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJCI(operationPutByIdDirectStrictOptimize
);
621 void DFG_OPERATION
operationPutByIdDirectStrictOptimizeWithReturnAddress(ExecState
* exec
, EncodedJSValue encodedValue
, JSCell
* base
, Identifier
* propertyName
, ReturnAddressPtr returnAddress
)
623 JSGlobalData
* globalData
= &exec
->globalData();
624 NativeCallFrameTracer
tracer(globalData
, exec
);
626 JSValue value
= JSValue::decode(encodedValue
);
627 PutPropertySlot
slot(true);
629 ASSERT(base
->isObject());
630 asObject(base
)->putDirect(exec
->globalData(), *propertyName
, value
, slot
);
632 StructureStubInfo
& stubInfo
= exec
->codeBlock()->getStubInfo(returnAddress
);
634 dfgRepatchPutByID(exec
, base
, *propertyName
, slot
, stubInfo
, Direct
);
636 stubInfo
.seen
= true;
639 V_FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJCI(operationPutByIdDirectNonStrictOptimize
);
640 void DFG_OPERATION
operationPutByIdDirectNonStrictOptimizeWithReturnAddress(ExecState
* exec
, EncodedJSValue encodedValue
, JSCell
* base
, Identifier
* propertyName
, ReturnAddressPtr returnAddress
)
642 JSGlobalData
* globalData
= &exec
->globalData();
643 NativeCallFrameTracer
tracer(globalData
, exec
);
645 JSValue value
= JSValue::decode(encodedValue
);
646 PutPropertySlot
slot(false);
648 ASSERT(base
->isObject());
649 asObject(base
)->putDirect(exec
->globalData(), *propertyName
, value
, slot
);
651 StructureStubInfo
& stubInfo
= exec
->codeBlock()->getStubInfo(returnAddress
);
653 dfgRepatchPutByID(exec
, base
, *propertyName
, slot
, stubInfo
, Direct
);
655 stubInfo
.seen
= true;
658 V_FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJCI(operationPutByIdStrictBuildList
);
659 void DFG_OPERATION
operationPutByIdStrictBuildListWithReturnAddress(ExecState
* exec
, EncodedJSValue encodedValue
, JSCell
* base
, Identifier
* propertyName
, ReturnAddressPtr returnAddress
)
661 JSGlobalData
* globalData
= &exec
->globalData();
662 NativeCallFrameTracer
tracer(globalData
, exec
);
664 JSValue value
= JSValue::decode(encodedValue
);
665 JSValue
baseValue(base
);
666 PutPropertySlot
slot(true);
668 baseValue
.put(exec
, *propertyName
, value
, slot
);
670 StructureStubInfo
& stubInfo
= exec
->codeBlock()->getStubInfo(returnAddress
);
671 dfgBuildPutByIdList(exec
, baseValue
, *propertyName
, slot
, stubInfo
, NotDirect
);
674 V_FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJCI(operationPutByIdNonStrictBuildList
);
675 void DFG_OPERATION
operationPutByIdNonStrictBuildListWithReturnAddress(ExecState
* exec
, EncodedJSValue encodedValue
, JSCell
* base
, Identifier
* propertyName
, ReturnAddressPtr returnAddress
)
677 JSGlobalData
* globalData
= &exec
->globalData();
678 NativeCallFrameTracer
tracer(globalData
, exec
);
680 JSValue value
= JSValue::decode(encodedValue
);
681 JSValue
baseValue(base
);
682 PutPropertySlot
slot(false);
684 baseValue
.put(exec
, *propertyName
, value
, slot
);
686 StructureStubInfo
& stubInfo
= exec
->codeBlock()->getStubInfo(returnAddress
);
687 dfgBuildPutByIdList(exec
, baseValue
, *propertyName
, slot
, stubInfo
, NotDirect
);
690 V_FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJCI(operationPutByIdDirectStrictBuildList
);
691 void DFG_OPERATION
operationPutByIdDirectStrictBuildListWithReturnAddress(ExecState
* exec
, EncodedJSValue encodedValue
, JSCell
* base
, Identifier
* propertyName
, ReturnAddressPtr returnAddress
)
693 JSGlobalData
* globalData
= &exec
->globalData();
694 NativeCallFrameTracer
tracer(globalData
, exec
);
696 JSValue value
= JSValue::decode(encodedValue
);
697 PutPropertySlot
slot(true);
699 ASSERT(base
->isObject());
700 asObject(base
)->putDirect(exec
->globalData(), *propertyName
, value
, slot
);
702 StructureStubInfo
& stubInfo
= exec
->codeBlock()->getStubInfo(returnAddress
);
703 dfgBuildPutByIdList(exec
, base
, *propertyName
, slot
, stubInfo
, Direct
);
706 V_FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJCI(operationPutByIdDirectNonStrictBuildList
);
707 void DFG_OPERATION
operationPutByIdDirectNonStrictBuildListWithReturnAddress(ExecState
* exec
, EncodedJSValue encodedValue
, JSCell
* base
, Identifier
* propertyName
, ReturnAddressPtr returnAddress
)
709 JSGlobalData
* globalData
= &exec
->globalData();
710 NativeCallFrameTracer
tracer(globalData
, exec
);
712 JSValue value
= JSValue::decode(encodedValue
);
713 PutPropertySlot
slot(false);
715 ASSERT(base
->isObject());
716 asObject(base
)->putDirect(exec
->globalData(), *propertyName
, value
, slot
);
718 StructureStubInfo
& stubInfo
= exec
->codeBlock()->getStubInfo(returnAddress
);
719 dfgBuildPutByIdList(exec
, base
, *propertyName
, slot
, stubInfo
, Direct
);
722 size_t DFG_OPERATION
operationCompareLess(ExecState
* exec
, EncodedJSValue encodedOp1
, EncodedJSValue encodedOp2
)
724 JSGlobalData
* globalData
= &exec
->globalData();
725 NativeCallFrameTracer
tracer(globalData
, exec
);
727 return jsLess
<true>(exec
, JSValue::decode(encodedOp1
), JSValue::decode(encodedOp2
));
730 size_t DFG_OPERATION
operationCompareLessEq(ExecState
* exec
, EncodedJSValue encodedOp1
, EncodedJSValue encodedOp2
)
732 JSGlobalData
* globalData
= &exec
->globalData();
733 NativeCallFrameTracer
tracer(globalData
, exec
);
735 return jsLessEq
<true>(exec
, JSValue::decode(encodedOp1
), JSValue::decode(encodedOp2
));
738 size_t DFG_OPERATION
operationCompareGreater(ExecState
* exec
, EncodedJSValue encodedOp1
, EncodedJSValue encodedOp2
)
740 JSGlobalData
* globalData
= &exec
->globalData();
741 NativeCallFrameTracer
tracer(globalData
, exec
);
743 return jsLess
<false>(exec
, JSValue::decode(encodedOp2
), JSValue::decode(encodedOp1
));
746 size_t DFG_OPERATION
operationCompareGreaterEq(ExecState
* exec
, EncodedJSValue encodedOp1
, EncodedJSValue encodedOp2
)
748 JSGlobalData
* globalData
= &exec
->globalData();
749 NativeCallFrameTracer
tracer(globalData
, exec
);
751 return jsLessEq
<false>(exec
, JSValue::decode(encodedOp2
), JSValue::decode(encodedOp1
));
754 size_t DFG_OPERATION
operationCompareEq(ExecState
* exec
, EncodedJSValue encodedOp1
, EncodedJSValue encodedOp2
)
756 JSGlobalData
* globalData
= &exec
->globalData();
757 NativeCallFrameTracer
tracer(globalData
, exec
);
759 return JSValue::equalSlowCaseInline(exec
, JSValue::decode(encodedOp1
), JSValue::decode(encodedOp2
));
762 size_t DFG_OPERATION
operationCompareStrictEqCell(ExecState
* exec
, EncodedJSValue encodedOp1
, EncodedJSValue encodedOp2
)
764 JSGlobalData
* globalData
= &exec
->globalData();
765 NativeCallFrameTracer
tracer(globalData
, exec
);
767 JSValue op1
= JSValue::decode(encodedOp1
);
768 JSValue op2
= JSValue::decode(encodedOp2
);
770 ASSERT(op1
.isCell());
771 ASSERT(op2
.isCell());
773 return JSValue::strictEqualSlowCaseInline(exec
, op1
, op2
);
776 size_t DFG_OPERATION
operationCompareStrictEq(ExecState
* exec
, EncodedJSValue encodedOp1
, EncodedJSValue encodedOp2
)
778 JSGlobalData
* globalData
= &exec
->globalData();
779 NativeCallFrameTracer
tracer(globalData
, exec
);
781 JSValue src1
= JSValue::decode(encodedOp1
);
782 JSValue src2
= JSValue::decode(encodedOp2
);
784 return JSValue::strictEqual(exec
, src1
, src2
);
787 static void* handleHostCall(ExecState
* execCallee
, JSValue callee
, CodeSpecializationKind kind
)
789 ExecState
* exec
= execCallee
->callerFrame();
790 JSGlobalData
* globalData
= &exec
->globalData();
792 execCallee
->setScopeChain(exec
->scopeChain());
793 execCallee
->setCodeBlock(0);
794 execCallee
->clearReturnPC();
796 if (kind
== CodeForCall
) {
798 CallType callType
= getCallData(callee
, callData
);
800 ASSERT(callType
!= CallTypeJS
);
802 if (callType
== CallTypeHost
) {
803 NativeCallFrameTracer
tracer(globalData
, execCallee
);
804 execCallee
->setCallee(asObject(callee
));
805 globalData
->hostCallReturnValue
= JSValue::decode(callData
.native
.function(execCallee
));
806 if (globalData
->exception
)
809 return reinterpret_cast<void*>(getHostCallReturnValue
);
812 ASSERT(callType
== CallTypeNone
);
813 exec
->globalData().exception
= createNotAFunctionError(exec
, callee
);
817 ASSERT(kind
== CodeForConstruct
);
819 ConstructData constructData
;
820 ConstructType constructType
= getConstructData(callee
, constructData
);
822 ASSERT(constructType
!= ConstructTypeJS
);
824 if (constructType
== ConstructTypeHost
) {
825 NativeCallFrameTracer
tracer(globalData
, execCallee
);
826 execCallee
->setCallee(asObject(callee
));
827 globalData
->hostCallReturnValue
= JSValue::decode(constructData
.native
.function(execCallee
));
828 if (globalData
->exception
)
831 return reinterpret_cast<void*>(getHostCallReturnValue
);
834 ASSERT(constructType
== ConstructTypeNone
);
835 exec
->globalData().exception
= createNotAConstructorError(exec
, callee
);
839 inline void* linkFor(ExecState
* execCallee
, ReturnAddressPtr returnAddress
, CodeSpecializationKind kind
)
841 ExecState
* exec
= execCallee
->callerFrame();
842 JSGlobalData
* globalData
= &exec
->globalData();
843 NativeCallFrameTracer
tracer(globalData
, exec
);
845 JSValue calleeAsValue
= execCallee
->calleeAsValue();
846 JSCell
* calleeAsFunctionCell
= getJSFunction(calleeAsValue
);
847 if (!calleeAsFunctionCell
)
848 return handleHostCall(execCallee
, calleeAsValue
, kind
);
850 JSFunction
* callee
= jsCast
<JSFunction
*>(calleeAsFunctionCell
);
851 execCallee
->setScopeChain(callee
->scopeUnchecked());
852 ExecutableBase
* executable
= callee
->executable();
854 MacroAssemblerCodePtr codePtr
;
855 CodeBlock
* codeBlock
= 0;
856 if (executable
->isHostFunction())
857 codePtr
= executable
->generatedJITCodeFor(kind
).addressForCall();
859 FunctionExecutable
* functionExecutable
= static_cast<FunctionExecutable
*>(executable
);
860 JSObject
* error
= functionExecutable
->compileFor(execCallee
, callee
->scope(), kind
);
862 globalData
->exception
= createStackOverflowError(exec
);
865 codeBlock
= &functionExecutable
->generatedBytecodeFor(kind
);
866 if (execCallee
->argumentCountIncludingThis() < static_cast<size_t>(codeBlock
->numParameters()))
867 codePtr
= functionExecutable
->generatedJITCodeWithArityCheckFor(kind
);
869 codePtr
= functionExecutable
->generatedJITCodeFor(kind
).addressForCall();
871 CallLinkInfo
& callLinkInfo
= exec
->codeBlock()->getCallLinkInfo(returnAddress
);
872 if (!callLinkInfo
.seenOnce())
873 callLinkInfo
.setSeen();
875 dfgLinkFor(execCallee
, callLinkInfo
, codeBlock
, callee
, codePtr
, kind
);
876 return codePtr
.executableAddress();
879 P_FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_E(operationLinkCall
);
880 void* DFG_OPERATION
operationLinkCallWithReturnAddress(ExecState
* execCallee
, ReturnAddressPtr returnAddress
)
882 return linkFor(execCallee
, returnAddress
, CodeForCall
);
885 P_FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_E(operationLinkConstruct
);
886 void* DFG_OPERATION
operationLinkConstructWithReturnAddress(ExecState
* execCallee
, ReturnAddressPtr returnAddress
)
888 return linkFor(execCallee
, returnAddress
, CodeForConstruct
);
891 inline void* virtualFor(ExecState
* execCallee
, CodeSpecializationKind kind
)
893 ExecState
* exec
= execCallee
->callerFrame();
894 JSGlobalData
* globalData
= &exec
->globalData();
895 NativeCallFrameTracer
tracer(globalData
, exec
);
897 JSValue calleeAsValue
= execCallee
->calleeAsValue();
898 JSCell
* calleeAsFunctionCell
= getJSFunction(calleeAsValue
);
899 if (UNLIKELY(!calleeAsFunctionCell
))
900 return handleHostCall(execCallee
, calleeAsValue
, kind
);
902 JSFunction
* function
= jsCast
<JSFunction
*>(calleeAsFunctionCell
);
903 execCallee
->setScopeChain(function
->scopeUnchecked());
904 ExecutableBase
* executable
= function
->executable();
905 if (UNLIKELY(!executable
->hasJITCodeFor(kind
))) {
906 FunctionExecutable
* functionExecutable
= static_cast<FunctionExecutable
*>(executable
);
907 JSObject
* error
= functionExecutable
->compileFor(execCallee
, function
->scope(), kind
);
909 exec
->globalData().exception
= error
;
913 return executable
->generatedJITCodeWithArityCheckFor(kind
).executableAddress();
916 void* DFG_OPERATION
operationVirtualCall(ExecState
* execCallee
)
918 return virtualFor(execCallee
, CodeForCall
);
921 void* DFG_OPERATION
operationVirtualConstruct(ExecState
* execCallee
)
923 return virtualFor(execCallee
, CodeForConstruct
);
926 EncodedJSValue DFG_OPERATION
operationResolve(ExecState
* exec
, Identifier
* propertyName
)
928 JSGlobalData
* globalData
= &exec
->globalData();
929 NativeCallFrameTracer
tracer(globalData
, exec
);
931 ScopeChainNode
* scopeChain
= exec
->scopeChain();
932 ScopeChainIterator iter
= scopeChain
->begin();
933 ScopeChainIterator end
= scopeChain
->end();
937 JSObject
* record
= iter
->get();
938 PropertySlot
slot(record
);
939 if (record
->getPropertySlot(exec
, *propertyName
, slot
))
940 return JSValue::encode(slot
.getValue(exec
, *propertyName
));
941 } while (++iter
!= end
);
943 return throwVMError(exec
, createUndefinedVariableError(exec
, *propertyName
));
946 EncodedJSValue DFG_OPERATION
operationResolveBase(ExecState
* exec
, Identifier
* propertyName
)
948 JSGlobalData
* globalData
= &exec
->globalData();
949 NativeCallFrameTracer
tracer(globalData
, exec
);
951 return JSValue::encode(resolveBase(exec
, *propertyName
, exec
->scopeChain(), false));
954 EncodedJSValue DFG_OPERATION
operationResolveBaseStrictPut(ExecState
* exec
, Identifier
* propertyName
)
956 JSGlobalData
* globalData
= &exec
->globalData();
957 NativeCallFrameTracer
tracer(globalData
, exec
);
959 JSValue base
= resolveBase(exec
, *propertyName
, exec
->scopeChain(), true);
961 throwError(exec
, createErrorForInvalidGlobalAssignment(exec
, propertyName
->ustring()));
962 return JSValue::encode(base
);
965 EncodedJSValue DFG_OPERATION
operationResolveGlobal(ExecState
* exec
, GlobalResolveInfo
* resolveInfo
, Identifier
* propertyName
)
967 JSGlobalData
* globalData
= &exec
->globalData();
968 NativeCallFrameTracer
tracer(globalData
, exec
);
970 JSGlobalObject
* globalObject
= exec
->lexicalGlobalObject();
972 PropertySlot
slot(globalObject
);
973 if (globalObject
->getPropertySlot(exec
, *propertyName
, slot
)) {
974 JSValue result
= slot
.getValue(exec
, *propertyName
);
976 if (slot
.isCacheableValue() && !globalObject
->structure()->isUncacheableDictionary() && slot
.slotBase() == globalObject
) {
977 resolveInfo
->structure
.set(exec
->globalData(), exec
->codeBlock()->ownerExecutable(), globalObject
->structure());
978 resolveInfo
->offset
= slot
.cachedOffset();
981 return JSValue::encode(result
);
984 return throwVMError(exec
, createUndefinedVariableError(exec
, *propertyName
));
987 EncodedJSValue DFG_OPERATION
operationToPrimitive(ExecState
* exec
, EncodedJSValue value
)
989 JSGlobalData
* globalData
= &exec
->globalData();
990 NativeCallFrameTracer
tracer(globalData
, exec
);
992 return JSValue::encode(JSValue::decode(value
).toPrimitive(exec
));
995 EncodedJSValue DFG_OPERATION
operationStrCat(ExecState
* exec
, void* buffer
, size_t size
)
997 JSGlobalData
* globalData
= &exec
->globalData();
998 NativeCallFrameTracer
tracer(globalData
, exec
);
1000 return JSValue::encode(jsString(exec
, static_cast<Register
*>(buffer
), size
));
1003 EncodedJSValue DFG_OPERATION
operationNewArray(ExecState
* exec
, void* buffer
, size_t size
)
1005 JSGlobalData
* globalData
= &exec
->globalData();
1006 NativeCallFrameTracer
tracer(globalData
, exec
);
1008 return JSValue::encode(constructArray(exec
, static_cast<JSValue
*>(buffer
), size
));
1011 EncodedJSValue DFG_OPERATION
operationNewArrayBuffer(ExecState
* exec
, size_t start
, size_t size
)
1013 JSGlobalData
& globalData
= exec
->globalData();
1014 NativeCallFrameTracer
tracer(&globalData
, exec
);
1015 return JSValue::encode(constructArray(exec
, exec
->codeBlock()->constantBuffer(start
), size
));
1018 EncodedJSValue DFG_OPERATION
operationNewRegexp(ExecState
* exec
, void* regexpPtr
)
1020 JSGlobalData
& globalData
= exec
->globalData();
1021 NativeCallFrameTracer
tracer(&globalData
, exec
);
1022 RegExp
* regexp
= static_cast<RegExp
*>(regexpPtr
);
1023 if (!regexp
->isValid()) {
1024 throwError(exec
, createSyntaxError(exec
, "Invalid flags supplied to RegExp constructor."));
1025 return JSValue::encode(jsUndefined());
1028 return JSValue::encode(RegExpObject::create(exec
->globalData(), exec
->lexicalGlobalObject(), exec
->lexicalGlobalObject()->regExpStructure(), regexp
));
1031 JSCell
* DFG_OPERATION
operationCreateActivation(ExecState
* exec
)
1033 JSGlobalData
& globalData
= exec
->globalData();
1034 NativeCallFrameTracer
tracer(&globalData
, exec
);
1035 JSActivation
* activation
= JSActivation::create(
1036 globalData
, exec
, static_cast<FunctionExecutable
*>(exec
->codeBlock()->ownerExecutable()));
1037 exec
->setScopeChain(exec
->scopeChain()->push(activation
));
1041 void DFG_OPERATION
operationTearOffActivation(ExecState
* exec
, JSCell
* activation
)
1044 ASSERT(activation
->inherits(&JSActivation::s_info
));
1045 JSGlobalData
& globalData
= exec
->globalData();
1046 NativeCallFrameTracer
tracer(&globalData
, exec
);
1047 jsCast
<JSActivation
*>(activation
)->tearOff(exec
->globalData());
1050 JSCell
* DFG_OPERATION
operationNewFunction(ExecState
* exec
, JSCell
* functionExecutable
)
1052 ASSERT(functionExecutable
->inherits(&FunctionExecutable::s_info
));
1053 JSGlobalData
& globalData
= exec
->globalData();
1054 NativeCallFrameTracer
tracer(&globalData
, exec
);
1055 return static_cast<FunctionExecutable
*>(functionExecutable
)->make(exec
, exec
->scopeChain());
1058 JSCell
* DFG_OPERATION
operationNewFunctionExpression(ExecState
* exec
, JSCell
* functionExecutableAsCell
)
1060 ASSERT(functionExecutableAsCell
->inherits(&FunctionExecutable::s_info
));
1061 FunctionExecutable
* functionExecutable
=
1062 static_cast<FunctionExecutable
*>(functionExecutableAsCell
);
1063 JSFunction
*function
= functionExecutable
->make(exec
, exec
->scopeChain());
1064 if (!functionExecutable
->name().isNull()) {
1065 JSStaticScopeObject
* functionScopeObject
=
1066 JSStaticScopeObject::create(
1067 exec
, functionExecutable
->name(), function
, ReadOnly
| DontDelete
);
1068 function
->setScope(exec
->globalData(), function
->scope()->push(functionScopeObject
));
1073 size_t DFG_OPERATION
operationIsObject(EncodedJSValue value
)
1075 return jsIsObjectType(JSValue::decode(value
));
1078 size_t DFG_OPERATION
operationIsFunction(EncodedJSValue value
)
1080 return jsIsFunctionType(JSValue::decode(value
));
1083 double DFG_OPERATION
operationFModOnInts(int32_t a
, int32_t b
)
1088 DFGHandlerEncoded DFG_OPERATION
lookupExceptionHandler(ExecState
* exec
, uint32_t callIndex
)
1090 JSGlobalData
* globalData
= &exec
->globalData();
1091 NativeCallFrameTracer
tracer(globalData
, exec
);
1093 JSValue exceptionValue
= exec
->exception();
1094 ASSERT(exceptionValue
);
1096 unsigned vPCIndex
= exec
->codeBlock()->bytecodeOffsetForCallAtIndex(callIndex
);
1097 ExceptionHandler handler
= genericThrow(globalData
, exec
, exceptionValue
, vPCIndex
);
1098 ASSERT(handler
.catchRoutine
);
1099 return dfgHandlerEncoded(handler
.callFrame
, handler
.catchRoutine
);
1102 DFGHandlerEncoded DFG_OPERATION
lookupExceptionHandlerInStub(ExecState
* exec
, StructureStubInfo
* stubInfo
)
1104 JSGlobalData
* globalData
= &exec
->globalData();
1105 NativeCallFrameTracer
tracer(globalData
, exec
);
1107 JSValue exceptionValue
= exec
->exception();
1108 ASSERT(exceptionValue
);
1110 CodeOrigin codeOrigin
= stubInfo
->codeOrigin
;
1111 while (codeOrigin
.inlineCallFrame
)
1112 codeOrigin
= codeOrigin
.inlineCallFrame
->caller
;
1114 ExceptionHandler handler
= genericThrow(globalData
, exec
, exceptionValue
, codeOrigin
.bytecodeIndex
);
1115 ASSERT(handler
.catchRoutine
);
1116 return dfgHandlerEncoded(handler
.callFrame
, handler
.catchRoutine
);
1119 double DFG_OPERATION
dfgConvertJSValueToNumber(ExecState
* exec
, EncodedJSValue value
)
1121 JSGlobalData
* globalData
= &exec
->globalData();
1122 NativeCallFrameTracer
tracer(globalData
, exec
);
1124 return JSValue::decode(value
).toNumber(exec
);
1127 size_t DFG_OPERATION
dfgConvertJSValueToInt32(ExecState
* exec
, EncodedJSValue value
)
1129 JSGlobalData
* globalData
= &exec
->globalData();
1130 NativeCallFrameTracer
tracer(globalData
, exec
);
1132 // toInt32/toUInt32 return the same value; we want the value zero extended to fill the register.
1133 return JSValue::decode(value
).toUInt32(exec
);
1136 size_t DFG_OPERATION
dfgConvertJSValueToBoolean(ExecState
* exec
, EncodedJSValue encodedOp
)
1138 JSGlobalData
* globalData
= &exec
->globalData();
1139 NativeCallFrameTracer
tracer(globalData
, exec
);
1141 return JSValue::decode(encodedOp
).toBoolean(exec
);
1144 #if DFG_ENABLE(VERBOSE_SPECULATION_FAILURE)
1145 void DFG_OPERATION
debugOperationPrintSpeculationFailure(ExecState
* exec
, void* debugInfoRaw
)
1147 JSGlobalData
* globalData
= &exec
->globalData();
1148 NativeCallFrameTracer
tracer(globalData
, exec
);
1150 SpeculationFailureDebugInfo
* debugInfo
= static_cast<SpeculationFailureDebugInfo
*>(debugInfoRaw
);
1151 CodeBlock
* codeBlock
= debugInfo
->codeBlock
;
1152 CodeBlock
* alternative
= codeBlock
->alternative();
1153 dataLog("Speculation failure in %p at @%u with executeCounter = %d, "
1154 "reoptimizationRetryCounter = %u, optimizationDelayCounter = %u, "
1155 "success/fail %u/(%u+%u)\n",
1157 debugInfo
->nodeIndex
,
1158 alternative
? alternative
->jitExecuteCounter() : 0,
1159 alternative
? alternative
->reoptimizationRetryCounter() : 0,
1160 alternative
? alternative
->optimizationDelayCounter() : 0,
1161 codeBlock
->speculativeSuccessCounter(),
1162 codeBlock
->speculativeFailCounter(),
1163 codeBlock
->forcedOSRExitCounter());
1168 } } // namespace JSC::DFG
1178 ".globl " SYMBOL_STRING(getHostCallReturnValue
) "\n"
1179 HIDE_SYMBOL(getHostCallReturnValue
) "\n"
1180 SYMBOL_STRING(getHostCallReturnValue
) ":" "\n"
1181 "mov -40(%r13), %r13\n"
1183 "jmp " SYMBOL_STRING_RELOCATION(getHostCallReturnValueWithExecState
) "\n"
1188 ".globl " SYMBOL_STRING(getHostCallReturnValue
) "\n"
1189 HIDE_SYMBOL(getHostCallReturnValue
) "\n"
1190 SYMBOL_STRING(getHostCallReturnValue
) ":" "\n"
1191 "mov -40(%edi), %edi\n"
1192 "mov %edi, 4(%esp)\n"
1193 "jmp " SYMBOL_STRING_RELOCATION(getHostCallReturnValueWithExecState
) "\n"
1195 #elif CPU(ARM_THUMB2)
1199 ".globl " SYMBOL_STRING(getHostCallReturnValue
) "\n"
1200 HIDE_SYMBOL(getHostCallReturnValue
) "\n"
1202 ".thumb_func " THUMB_FUNC_PARAM(getHostCallReturnValue
) "\n"
1203 SYMBOL_STRING(getHostCallReturnValue
) ":" "\n"
1204 "ldr r5, [r5, #-40]" "\n"
1206 "b " SYMBOL_STRING_RELOCATION(getHostCallReturnValueWithExecState
) "\n"
1210 extern "C" EncodedJSValue HOST_CALL_RETURN_VALUE_OPTION
getHostCallReturnValueWithExecState(ExecState
* exec
)
1213 return JSValue::encode(JSValue());
1214 return JSValue::encode(exec
->globalData().hostCallReturnValue
);
1219 #endif // COMPILER(GCC)