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 "Arguments.h"
30 #include "ButterflyInlines.h"
31 #include "CodeBlock.h"
32 #include "CopiedSpaceInlines.h"
33 #include "DFGOSRExit.h"
34 #include "DFGRepatch.h"
35 #include "DFGThunks.h"
36 #include "HostCallReturnValue.h"
37 #include "GetterSetter.h"
38 #include "Interpreter.h"
40 #include "JITExceptions.h"
41 #include "JSActivation.h"
43 #include "JSNameScope.h"
44 #include "NameInstance.h"
45 #include "ObjectConstructor.h"
46 #include "Operations.h"
47 #include "StringConstructor.h"
48 #include <wtf/InlineASM.h>
54 #define LOAD_FUNCTION_TO_T9(function) \
55 ".set noreorder" "\n" \
58 "la $t9, " LOCAL_REFERENCE(function) "\n"
60 #define LOAD_FUNCTION_TO_T9(function) "" "\n"
66 #if COMPILER(GCC) && CPU(X86_64)
68 #define FUNCTION_WRAPPER_WITH_RETURN_ADDRESS(function, register) \
70 ".globl " SYMBOL_STRING(function) "\n" \
71 HIDE_SYMBOL(function) "\n" \
72 SYMBOL_STRING(function) ":" "\n" \
73 "mov (%rsp), %" STRINGIZE(register) "\n" \
74 "jmp " LOCAL_REFERENCE(function##WithReturnAddress) "\n" \
76 #define FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_E(function) FUNCTION_WRAPPER_WITH_RETURN_ADDRESS(function, rsi)
77 #define FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_ECI(function) FUNCTION_WRAPPER_WITH_RETURN_ADDRESS(function, rcx)
78 #define FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJI(function) FUNCTION_WRAPPER_WITH_RETURN_ADDRESS(function, rcx)
79 #define FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJCI(function) FUNCTION_WRAPPER_WITH_RETURN_ADDRESS(function, r8)
81 #elif COMPILER(GCC) && CPU(X86)
83 #define FUNCTION_WRAPPER_WITH_RETURN_ADDRESS(function, offset) \
86 ".globl " SYMBOL_STRING(function) "\n" \
87 HIDE_SYMBOL(function) "\n" \
88 SYMBOL_STRING(function) ":" "\n" \
89 "mov (%esp), %eax\n" \
90 "mov %eax, " STRINGIZE(offset) "(%esp)\n" \
91 "jmp " LOCAL_REFERENCE(function##WithReturnAddress) "\n" \
93 #define FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_E(function) FUNCTION_WRAPPER_WITH_RETURN_ADDRESS(function, 8)
94 #define FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_ECI(function) FUNCTION_WRAPPER_WITH_RETURN_ADDRESS(function, 16)
95 #define FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJI(function) FUNCTION_WRAPPER_WITH_RETURN_ADDRESS(function, 20)
96 #define FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJCI(function) FUNCTION_WRAPPER_WITH_RETURN_ADDRESS(function, 24)
100 #define FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_E(function) \
104 ".globl " SYMBOL_STRING(function) "\n" \
105 HIDE_SYMBOL(function) "\n" \
106 SYMBOL_STRING(function) ":" "\n" \
108 "b " LOCAL_REFERENCE(function) "WithReturnAddress" "\n" \
111 #define FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_ECI(function) \
115 ".globl " SYMBOL_STRING(function) "\n" \
116 HIDE_SYMBOL(function) "\n" \
117 SYMBOL_STRING(function) ":" "\n" \
119 "b " LOCAL_REFERENCE(function) "WithReturnAddress" "\n" \
122 #define FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJI(function) \
126 ".globl " SYMBOL_STRING(function) "\n" \
127 HIDE_SYMBOL(function) "\n" \
128 SYMBOL_STRING(function) ":" "\n" \
130 "b " LOCAL_REFERENCE(function) "WithReturnAddress" "\n" \
133 #define FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJCI(function) \
137 ".globl " SYMBOL_STRING(function) "\n" \
138 HIDE_SYMBOL(function) "\n" \
139 SYMBOL_STRING(function) ":" "\n" \
141 "b " LOCAL_REFERENCE(function) "WithReturnAddress" "\n" \
144 #elif COMPILER(GCC) && CPU(ARM_THUMB2)
146 #define FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_E(function) \
150 ".globl " SYMBOL_STRING(function) "\n" \
151 HIDE_SYMBOL(function) "\n" \
153 ".thumb_func " THUMB_FUNC_PARAM(function) "\n" \
154 SYMBOL_STRING(function) ":" "\n" \
156 "b " LOCAL_REFERENCE(function) "WithReturnAddress" "\n" \
159 #define FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_ECI(function) \
163 ".globl " SYMBOL_STRING(function) "\n" \
164 HIDE_SYMBOL(function) "\n" \
166 ".thumb_func " THUMB_FUNC_PARAM(function) "\n" \
167 SYMBOL_STRING(function) ":" "\n" \
169 "b " LOCAL_REFERENCE(function) "WithReturnAddress" "\n" \
172 // 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]).
173 // As a result, return address will be at a 4-byte further location in the following cases.
174 #if COMPILER_SUPPORTS(EABI) && CPU(ARM)
175 #define INSTRUCTION_STORE_RETURN_ADDRESS_EJI "str lr, [sp, #4]"
176 #define INSTRUCTION_STORE_RETURN_ADDRESS_EJCI "str lr, [sp, #8]"
178 #define INSTRUCTION_STORE_RETURN_ADDRESS_EJI "str lr, [sp, #0]"
179 #define INSTRUCTION_STORE_RETURN_ADDRESS_EJCI "str lr, [sp, #4]"
182 #define FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJI(function) \
186 ".globl " SYMBOL_STRING(function) "\n" \
187 HIDE_SYMBOL(function) "\n" \
189 ".thumb_func " THUMB_FUNC_PARAM(function) "\n" \
190 SYMBOL_STRING(function) ":" "\n" \
191 INSTRUCTION_STORE_RETURN_ADDRESS_EJI "\n" \
192 "b " LOCAL_REFERENCE(function) "WithReturnAddress" "\n" \
195 #define FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJCI(function) \
199 ".globl " SYMBOL_STRING(function) "\n" \
200 HIDE_SYMBOL(function) "\n" \
202 ".thumb_func " THUMB_FUNC_PARAM(function) "\n" \
203 SYMBOL_STRING(function) ":" "\n" \
204 INSTRUCTION_STORE_RETURN_ADDRESS_EJCI "\n" \
205 "b " LOCAL_REFERENCE(function) "WithReturnAddress" "\n" \
208 #elif COMPILER(GCC) && CPU(ARM_TRADITIONAL)
210 #define FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_E(function) \
213 ".globl " SYMBOL_STRING(function) "\n" \
214 HIDE_SYMBOL(function) "\n" \
215 INLINE_ARM_FUNCTION(function) \
216 SYMBOL_STRING(function) ":" "\n" \
218 "b " LOCAL_REFERENCE(function) "WithReturnAddress" "\n" \
221 #define FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_ECI(function) \
224 ".globl " SYMBOL_STRING(function) "\n" \
225 HIDE_SYMBOL(function) "\n" \
226 INLINE_ARM_FUNCTION(function) \
227 SYMBOL_STRING(function) ":" "\n" \
229 "b " LOCAL_REFERENCE(function) "WithReturnAddress" "\n" \
232 // 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]).
233 // As a result, return address will be at a 4-byte further location in the following cases.
234 #if COMPILER_SUPPORTS(EABI) && CPU(ARM)
235 #define INSTRUCTION_STORE_RETURN_ADDRESS_EJI "str lr, [sp, #4]"
236 #define INSTRUCTION_STORE_RETURN_ADDRESS_EJCI "str lr, [sp, #8]"
238 #define INSTRUCTION_STORE_RETURN_ADDRESS_EJI "str lr, [sp, #0]"
239 #define INSTRUCTION_STORE_RETURN_ADDRESS_EJCI "str lr, [sp, #4]"
242 #define FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJI(function) \
245 ".globl " SYMBOL_STRING(function) "\n" \
246 HIDE_SYMBOL(function) "\n" \
247 INLINE_ARM_FUNCTION(function) \
248 SYMBOL_STRING(function) ":" "\n" \
249 INSTRUCTION_STORE_RETURN_ADDRESS_EJI "\n" \
250 "b " LOCAL_REFERENCE(function) "WithReturnAddress" "\n" \
253 #define FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJCI(function) \
256 ".globl " SYMBOL_STRING(function) "\n" \
257 HIDE_SYMBOL(function) "\n" \
258 INLINE_ARM_FUNCTION(function) \
259 SYMBOL_STRING(function) ":" "\n" \
260 INSTRUCTION_STORE_RETURN_ADDRESS_EJCI "\n" \
261 "b " LOCAL_REFERENCE(function) "WithReturnAddress" "\n" \
264 #elif COMPILER(GCC) && CPU(MIPS)
266 #define FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_E(function) \
269 ".globl " SYMBOL_STRING(function) "\n" \
270 HIDE_SYMBOL(function) "\n" \
271 SYMBOL_STRING(function) ":" "\n" \
272 LOAD_FUNCTION_TO_T9(function##WithReturnAddress) \
273 "move $a1, $ra" "\n" \
274 "b " LOCAL_REFERENCE(function) "WithReturnAddress" "\n" \
277 #define FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_ECI(function) \
280 ".globl " SYMBOL_STRING(function) "\n" \
281 HIDE_SYMBOL(function) "\n" \
282 SYMBOL_STRING(function) ":" "\n" \
283 LOAD_FUNCTION_TO_T9(function##WithReturnAddress) \
284 "move $a3, $ra" "\n" \
285 "b " LOCAL_REFERENCE(function) "WithReturnAddress" "\n" \
288 #define FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJI(function) \
291 ".globl " SYMBOL_STRING(function) "\n" \
292 HIDE_SYMBOL(function) "\n" \
293 SYMBOL_STRING(function) ":" "\n" \
294 LOAD_FUNCTION_TO_T9(function##WithReturnAddress) \
295 "sw $ra, 20($sp)" "\n" \
296 "b " LOCAL_REFERENCE(function) "WithReturnAddress" "\n" \
299 #define FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJCI(function) \
302 ".globl " SYMBOL_STRING(function) "\n" \
303 HIDE_SYMBOL(function) "\n" \
304 SYMBOL_STRING(function) ":" "\n" \
305 LOAD_FUNCTION_TO_T9(function##WithReturnAddress) \
306 "sw $ra, 24($sp)" "\n" \
307 "b " LOCAL_REFERENCE(function) "WithReturnAddress" "\n" \
312 #define P_FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_E(function) \
313 void* DFG_OPERATION function##WithReturnAddress(ExecState*, ReturnAddressPtr) REFERENCED_FROM_ASM WTF_INTERNAL; \
314 FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_E(function)
316 #define J_FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_ECI(function) \
317 EncodedJSValue DFG_OPERATION function##WithReturnAddress(ExecState*, JSCell*, Identifier*, ReturnAddressPtr) REFERENCED_FROM_ASM WTF_INTERNAL; \
318 FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_ECI(function)
320 #define J_FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJI(function) \
321 EncodedJSValue DFG_OPERATION function##WithReturnAddress(ExecState*, EncodedJSValue, Identifier*, ReturnAddressPtr) REFERENCED_FROM_ASM WTF_INTERNAL; \
322 FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJI(function)
324 #define V_FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJCI(function) \
325 void DFG_OPERATION function##WithReturnAddress(ExecState*, EncodedJSValue, JSCell*, Identifier*, ReturnAddressPtr) REFERENCED_FROM_ASM WTF_INTERNAL; \
326 FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJCI(function)
328 namespace JSC
{ namespace DFG
{
330 template<bool strict
>
331 static inline void putByVal(ExecState
* exec
, JSValue baseValue
, uint32_t index
, JSValue value
)
334 NativeCallFrameTracer
tracer(&vm
, exec
);
336 if (baseValue
.isObject()) {
337 JSObject
* object
= asObject(baseValue
);
338 if (object
->canSetIndexQuickly(index
)) {
339 object
->setIndexQuickly(vm
, index
, value
);
343 object
->methodTable()->putByIndex(object
, exec
, index
, value
, strict
);
347 baseValue
.putByIndex(exec
, index
, value
, strict
);
350 template<bool strict
>
351 ALWAYS_INLINE
static void DFG_OPERATION
operationPutByValInternal(ExecState
* exec
, EncodedJSValue encodedBase
, EncodedJSValue encodedProperty
, EncodedJSValue encodedValue
)
353 VM
* vm
= &exec
->vm();
354 NativeCallFrameTracer
tracer(vm
, exec
);
356 JSValue baseValue
= JSValue::decode(encodedBase
);
357 JSValue property
= JSValue::decode(encodedProperty
);
358 JSValue value
= JSValue::decode(encodedValue
);
360 if (LIKELY(property
.isUInt32())) {
361 putByVal
<strict
>(exec
, baseValue
, property
.asUInt32(), value
);
365 if (property
.isDouble()) {
366 double propertyAsDouble
= property
.asDouble();
367 uint32_t propertyAsUInt32
= static_cast<uint32_t>(propertyAsDouble
);
368 if (propertyAsDouble
== propertyAsUInt32
) {
369 putByVal
<strict
>(exec
, baseValue
, propertyAsUInt32
, value
);
374 if (isName(property
)) {
375 PutPropertySlot
slot(strict
);
376 baseValue
.put(exec
, jsCast
<NameInstance
*>(property
.asCell())->privateName(), value
, slot
);
380 // Don't put to an object if toString throws an exception.
381 Identifier
ident(exec
, property
.toString(exec
)->value(exec
));
382 if (!vm
->exception
) {
383 PutPropertySlot
slot(strict
);
384 baseValue
.put(exec
, ident
, value
, slot
);
390 EncodedJSValue DFG_OPERATION
operationConvertThis(ExecState
* exec
, EncodedJSValue encodedOp
)
392 VM
* vm
= &exec
->vm();
393 NativeCallFrameTracer
tracer(vm
, exec
);
395 return JSValue::encode(JSValue::decode(encodedOp
).toThisObject(exec
));
398 JSCell
* DFG_OPERATION
operationCreateThis(ExecState
* exec
, JSObject
* constructor
, int32_t inlineCapacity
)
400 VM
* vm
= &exec
->vm();
401 NativeCallFrameTracer
tracer(vm
, exec
);
404 ConstructData constructData
;
405 ASSERT(jsCast
<JSFunction
*>(constructor
)->methodTable()->getConstructData(jsCast
<JSFunction
*>(constructor
), constructData
) == ConstructTypeJS
);
408 return constructEmptyObject(exec
, jsCast
<JSFunction
*>(constructor
)->allocationProfile(exec
, inlineCapacity
)->structure());
411 JSCell
* DFG_OPERATION
operationNewObject(ExecState
* exec
, Structure
* structure
)
413 VM
* vm
= &exec
->vm();
414 NativeCallFrameTracer
tracer(vm
, exec
);
416 return constructEmptyObject(exec
, structure
);
419 EncodedJSValue DFG_OPERATION
operationValueAdd(ExecState
* exec
, EncodedJSValue encodedOp1
, EncodedJSValue encodedOp2
)
421 VM
* vm
= &exec
->vm();
422 NativeCallFrameTracer
tracer(vm
, exec
);
424 JSValue op1
= JSValue::decode(encodedOp1
);
425 JSValue op2
= JSValue::decode(encodedOp2
);
427 return JSValue::encode(jsAdd(exec
, op1
, op2
));
430 EncodedJSValue DFG_OPERATION
operationValueAddNotNumber(ExecState
* exec
, EncodedJSValue encodedOp1
, EncodedJSValue encodedOp2
)
432 VM
* vm
= &exec
->vm();
433 NativeCallFrameTracer
tracer(vm
, exec
);
435 JSValue op1
= JSValue::decode(encodedOp1
);
436 JSValue op2
= JSValue::decode(encodedOp2
);
438 ASSERT(!op1
.isNumber() || !op2
.isNumber());
440 if (op1
.isString() && !op2
.isObject())
441 return JSValue::encode(jsString(exec
, asString(op1
), op2
.toString(exec
)));
443 return JSValue::encode(jsAddSlowCase(exec
, op1
, op2
));
446 static inline EncodedJSValue
getByVal(ExecState
* exec
, JSCell
* base
, uint32_t index
)
449 NativeCallFrameTracer
tracer(&vm
, exec
);
451 if (base
->isObject()) {
452 JSObject
* object
= asObject(base
);
453 if (object
->canGetIndexQuickly(index
))
454 return JSValue::encode(object
->getIndexQuickly(index
));
457 if (isJSString(base
) && asString(base
)->canGetIndex(index
))
458 return JSValue::encode(asString(base
)->getIndex(exec
, index
));
460 return JSValue::encode(JSValue(base
).get(exec
, index
));
463 EncodedJSValue DFG_OPERATION
operationGetByVal(ExecState
* exec
, EncodedJSValue encodedBase
, EncodedJSValue encodedProperty
)
465 VM
* vm
= &exec
->vm();
466 NativeCallFrameTracer
tracer(vm
, exec
);
468 JSValue baseValue
= JSValue::decode(encodedBase
);
469 JSValue property
= JSValue::decode(encodedProperty
);
471 if (LIKELY(baseValue
.isCell())) {
472 JSCell
* base
= baseValue
.asCell();
474 if (property
.isUInt32()) {
475 return getByVal(exec
, base
, property
.asUInt32());
476 } else if (property
.isDouble()) {
477 double propertyAsDouble
= property
.asDouble();
478 uint32_t propertyAsUInt32
= static_cast<uint32_t>(propertyAsDouble
);
479 if (propertyAsUInt32
== propertyAsDouble
)
480 return getByVal(exec
, base
, propertyAsUInt32
);
481 } else if (property
.isString()) {
482 if (JSValue result
= base
->fastGetOwnProperty(exec
, asString(property
)->value(exec
)))
483 return JSValue::encode(result
);
487 if (isName(property
))
488 return JSValue::encode(baseValue
.get(exec
, jsCast
<NameInstance
*>(property
.asCell())->privateName()));
490 Identifier
ident(exec
, property
.toString(exec
)->value(exec
));
491 return JSValue::encode(baseValue
.get(exec
, ident
));
494 EncodedJSValue DFG_OPERATION
operationGetByValCell(ExecState
* exec
, JSCell
* base
, EncodedJSValue encodedProperty
)
496 VM
* vm
= &exec
->vm();
497 NativeCallFrameTracer
tracer(vm
, exec
);
499 JSValue property
= JSValue::decode(encodedProperty
);
501 if (property
.isUInt32())
502 return getByVal(exec
, base
, property
.asUInt32());
503 if (property
.isDouble()) {
504 double propertyAsDouble
= property
.asDouble();
505 uint32_t propertyAsUInt32
= static_cast<uint32_t>(propertyAsDouble
);
506 if (propertyAsUInt32
== propertyAsDouble
)
507 return getByVal(exec
, base
, propertyAsUInt32
);
508 } else if (property
.isString()) {
509 if (JSValue result
= base
->fastGetOwnProperty(exec
, asString(property
)->value(exec
)))
510 return JSValue::encode(result
);
513 if (isName(property
))
514 return JSValue::encode(JSValue(base
).get(exec
, jsCast
<NameInstance
*>(property
.asCell())->privateName()));
516 Identifier
ident(exec
, property
.toString(exec
)->value(exec
));
517 return JSValue::encode(JSValue(base
).get(exec
, ident
));
520 EncodedJSValue DFG_OPERATION
operationGetByValArrayInt(ExecState
* exec
, JSArray
* base
, int32_t index
)
522 VM
* vm
= &exec
->vm();
523 NativeCallFrameTracer
tracer(vm
, exec
);
526 // Go the slowest way possible becase negative indices don't use indexed storage.
527 return JSValue::encode(JSValue(base
).get(exec
, Identifier::from(exec
, index
)));
530 // Use this since we know that the value is out of bounds.
531 return JSValue::encode(JSValue(base
).get(exec
, index
));
534 EncodedJSValue DFG_OPERATION
operationGetById(ExecState
* exec
, EncodedJSValue base
, Identifier
* propertyName
)
536 VM
* vm
= &exec
->vm();
537 NativeCallFrameTracer
tracer(vm
, exec
);
539 JSValue baseValue
= JSValue::decode(base
);
540 PropertySlot
slot(baseValue
);
541 return JSValue::encode(baseValue
.get(exec
, *propertyName
, slot
));
544 J_FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJI(operationGetByIdBuildList
);
545 EncodedJSValue DFG_OPERATION
operationGetByIdBuildListWithReturnAddress(ExecState
* exec
, EncodedJSValue base
, Identifier
* propertyName
, ReturnAddressPtr returnAddress
)
547 VM
* vm
= &exec
->vm();
548 NativeCallFrameTracer
tracer(vm
, exec
);
550 StructureStubInfo
& stubInfo
= exec
->codeBlock()->getStubInfo(returnAddress
);
551 AccessType accessType
= static_cast<AccessType
>(stubInfo
.accessType
);
553 JSValue baseValue
= JSValue::decode(base
);
554 PropertySlot
slot(baseValue
);
555 JSValue result
= baseValue
.get(exec
, *propertyName
, slot
);
557 if (accessType
== static_cast<AccessType
>(stubInfo
.accessType
))
558 dfgBuildGetByIDList(exec
, baseValue
, *propertyName
, slot
, stubInfo
);
560 return JSValue::encode(result
);
563 J_FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJI(operationGetByIdProtoBuildList
);
564 EncodedJSValue DFG_OPERATION
operationGetByIdProtoBuildListWithReturnAddress(ExecState
* exec
, EncodedJSValue base
, Identifier
* propertyName
, ReturnAddressPtr returnAddress
)
566 VM
* vm
= &exec
->vm();
567 NativeCallFrameTracer
tracer(vm
, exec
);
569 StructureStubInfo
& stubInfo
= exec
->codeBlock()->getStubInfo(returnAddress
);
570 AccessType accessType
= static_cast<AccessType
>(stubInfo
.accessType
);
572 JSValue baseValue
= JSValue::decode(base
);
573 PropertySlot
slot(baseValue
);
574 JSValue result
= baseValue
.get(exec
, *propertyName
, slot
);
576 if (accessType
== static_cast<AccessType
>(stubInfo
.accessType
))
577 dfgBuildGetByIDProtoList(exec
, baseValue
, *propertyName
, slot
, stubInfo
);
579 return JSValue::encode(result
);
582 J_FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJI(operationGetByIdOptimize
);
583 EncodedJSValue DFG_OPERATION
operationGetByIdOptimizeWithReturnAddress(ExecState
* exec
, EncodedJSValue base
, Identifier
* propertyName
, ReturnAddressPtr returnAddress
)
585 VM
* vm
= &exec
->vm();
586 NativeCallFrameTracer
tracer(vm
, exec
);
588 StructureStubInfo
& stubInfo
= exec
->codeBlock()->getStubInfo(returnAddress
);
589 AccessType accessType
= static_cast<AccessType
>(stubInfo
.accessType
);
591 JSValue baseValue
= JSValue::decode(base
);
592 PropertySlot
slot(baseValue
);
593 JSValue result
= baseValue
.get(exec
, *propertyName
, slot
);
595 if (accessType
== static_cast<AccessType
>(stubInfo
.accessType
)) {
597 dfgRepatchGetByID(exec
, baseValue
, *propertyName
, slot
, stubInfo
);
599 stubInfo
.seen
= true;
602 return JSValue::encode(result
);
605 EncodedJSValue DFG_OPERATION
operationCallCustomGetter(ExecState
* exec
, JSCell
* base
, PropertySlot::GetValueFunc function
, Identifier
* ident
)
607 VM
* vm
= &exec
->vm();
608 NativeCallFrameTracer
tracer(vm
, exec
);
610 return JSValue::encode(function(exec
, asObject(base
), *ident
));
613 EncodedJSValue DFG_OPERATION
operationCallGetter(ExecState
* exec
, JSCell
* base
, JSCell
* value
)
615 VM
* vm
= &exec
->vm();
616 NativeCallFrameTracer
tracer(vm
, exec
);
618 GetterSetter
* getterSetter
= asGetterSetter(value
);
619 JSObject
* getter
= getterSetter
->getter();
621 return JSValue::encode(jsUndefined());
623 CallType callType
= getter
->methodTable()->getCallData(getter
, callData
);
624 return JSValue::encode(call(exec
, getter
, callType
, callData
, asObject(base
), ArgList()));
627 void DFG_OPERATION
operationPutByValStrict(ExecState
* exec
, EncodedJSValue encodedBase
, EncodedJSValue encodedProperty
, EncodedJSValue encodedValue
)
629 VM
* vm
= &exec
->vm();
630 NativeCallFrameTracer
tracer(vm
, exec
);
632 operationPutByValInternal
<true>(exec
, encodedBase
, encodedProperty
, encodedValue
);
635 void DFG_OPERATION
operationPutByValNonStrict(ExecState
* exec
, EncodedJSValue encodedBase
, EncodedJSValue encodedProperty
, EncodedJSValue encodedValue
)
637 VM
* vm
= &exec
->vm();
638 NativeCallFrameTracer
tracer(vm
, exec
);
640 operationPutByValInternal
<false>(exec
, encodedBase
, encodedProperty
, encodedValue
);
643 void DFG_OPERATION
operationPutByValCellStrict(ExecState
* exec
, JSCell
* cell
, EncodedJSValue encodedProperty
, EncodedJSValue encodedValue
)
645 VM
* vm
= &exec
->vm();
646 NativeCallFrameTracer
tracer(vm
, exec
);
648 operationPutByValInternal
<true>(exec
, JSValue::encode(cell
), encodedProperty
, encodedValue
);
651 void DFG_OPERATION
operationPutByValCellNonStrict(ExecState
* exec
, JSCell
* cell
, EncodedJSValue encodedProperty
, EncodedJSValue encodedValue
)
653 VM
* vm
= &exec
->vm();
654 NativeCallFrameTracer
tracer(vm
, exec
);
656 operationPutByValInternal
<false>(exec
, JSValue::encode(cell
), encodedProperty
, encodedValue
);
659 void DFG_OPERATION
operationPutByValBeyondArrayBoundsStrict(ExecState
* exec
, JSObject
* array
, int32_t index
, EncodedJSValue encodedValue
)
661 VM
* vm
= &exec
->vm();
662 NativeCallFrameTracer
tracer(vm
, exec
);
665 array
->putByIndexInline(exec
, index
, JSValue::decode(encodedValue
), true);
669 PutPropertySlot
slot(true);
670 array
->methodTable()->put(
671 array
, exec
, Identifier::from(exec
, index
), JSValue::decode(encodedValue
), slot
);
674 void DFG_OPERATION
operationPutByValBeyondArrayBoundsNonStrict(ExecState
* exec
, JSObject
* array
, int32_t index
, EncodedJSValue encodedValue
)
676 VM
* vm
= &exec
->vm();
677 NativeCallFrameTracer
tracer(vm
, exec
);
680 array
->putByIndexInline(exec
, index
, JSValue::decode(encodedValue
), false);
684 PutPropertySlot
slot(false);
685 array
->methodTable()->put(
686 array
, exec
, Identifier::from(exec
, index
), JSValue::decode(encodedValue
), slot
);
689 void DFG_OPERATION
operationPutDoubleByValBeyondArrayBoundsStrict(ExecState
* exec
, JSObject
* array
, int32_t index
, double value
)
691 VM
* vm
= &exec
->vm();
692 NativeCallFrameTracer
tracer(vm
, exec
);
694 JSValue jsValue
= JSValue(JSValue::EncodeAsDouble
, value
);
697 array
->putByIndexInline(exec
, index
, jsValue
, true);
701 PutPropertySlot
slot(true);
702 array
->methodTable()->put(
703 array
, exec
, Identifier::from(exec
, index
), jsValue
, slot
);
706 void DFG_OPERATION
operationPutDoubleByValBeyondArrayBoundsNonStrict(ExecState
* exec
, JSObject
* array
, int32_t index
, double value
)
708 VM
* vm
= &exec
->vm();
709 NativeCallFrameTracer
tracer(vm
, exec
);
711 JSValue jsValue
= JSValue(JSValue::EncodeAsDouble
, value
);
714 array
->putByIndexInline(exec
, index
, jsValue
, false);
718 PutPropertySlot
slot(false);
719 array
->methodTable()->put(
720 array
, exec
, Identifier::from(exec
, index
), jsValue
, slot
);
723 EncodedJSValue DFG_OPERATION
operationArrayPush(ExecState
* exec
, EncodedJSValue encodedValue
, JSArray
* array
)
725 VM
* vm
= &exec
->vm();
726 NativeCallFrameTracer
tracer(vm
, exec
);
728 array
->push(exec
, JSValue::decode(encodedValue
));
729 return JSValue::encode(jsNumber(array
->length()));
732 EncodedJSValue DFG_OPERATION
operationArrayPushDouble(ExecState
* exec
, double value
, JSArray
* array
)
734 VM
* vm
= &exec
->vm();
735 NativeCallFrameTracer
tracer(vm
, exec
);
737 array
->push(exec
, JSValue(JSValue::EncodeAsDouble
, value
));
738 return JSValue::encode(jsNumber(array
->length()));
741 EncodedJSValue DFG_OPERATION
operationArrayPop(ExecState
* exec
, JSArray
* array
)
743 VM
* vm
= &exec
->vm();
744 NativeCallFrameTracer
tracer(vm
, exec
);
746 return JSValue::encode(array
->pop(exec
));
749 EncodedJSValue DFG_OPERATION
operationArrayPopAndRecoverLength(ExecState
* exec
, JSArray
* array
)
751 VM
* vm
= &exec
->vm();
752 NativeCallFrameTracer
tracer(vm
, exec
);
754 array
->butterfly()->setPublicLength(array
->butterfly()->publicLength() + 1);
756 return JSValue::encode(array
->pop(exec
));
759 EncodedJSValue DFG_OPERATION
operationRegExpExec(ExecState
* exec
, JSCell
* base
, JSCell
* argument
)
762 NativeCallFrameTracer
tracer(&vm
, exec
);
764 if (!base
->inherits(&RegExpObject::s_info
))
765 return throwVMTypeError(exec
);
767 ASSERT(argument
->isString() || argument
->isObject());
768 JSString
* input
= argument
->isString() ? asString(argument
) : asObject(argument
)->toString(exec
);
769 return JSValue::encode(asRegExpObject(base
)->exec(exec
, input
));
772 size_t DFG_OPERATION
operationRegExpTest(ExecState
* exec
, JSCell
* base
, JSCell
* argument
)
775 NativeCallFrameTracer
tracer(&vm
, exec
);
777 if (!base
->inherits(&RegExpObject::s_info
)) {
778 throwTypeError(exec
);
782 ASSERT(argument
->isString() || argument
->isObject());
783 JSString
* input
= argument
->isString() ? asString(argument
) : asObject(argument
)->toString(exec
);
784 return asRegExpObject(base
)->test(exec
, input
);
787 void DFG_OPERATION
operationPutByIdStrict(ExecState
* exec
, EncodedJSValue encodedValue
, JSCell
* base
, Identifier
* propertyName
)
789 VM
* vm
= &exec
->vm();
790 NativeCallFrameTracer
tracer(vm
, exec
);
792 PutPropertySlot
slot(true);
793 base
->methodTable()->put(base
, exec
, *propertyName
, JSValue::decode(encodedValue
), slot
);
796 void DFG_OPERATION
operationPutByIdNonStrict(ExecState
* exec
, EncodedJSValue encodedValue
, JSCell
* base
, Identifier
* propertyName
)
798 VM
* vm
= &exec
->vm();
799 NativeCallFrameTracer
tracer(vm
, exec
);
801 PutPropertySlot
slot(false);
802 base
->methodTable()->put(base
, exec
, *propertyName
, JSValue::decode(encodedValue
), slot
);
805 void DFG_OPERATION
operationPutByIdDirectStrict(ExecState
* exec
, EncodedJSValue encodedValue
, JSCell
* base
, Identifier
* propertyName
)
807 VM
* vm
= &exec
->vm();
808 NativeCallFrameTracer
tracer(vm
, exec
);
810 PutPropertySlot
slot(true);
811 ASSERT(base
->isObject());
812 asObject(base
)->putDirect(exec
->vm(), *propertyName
, JSValue::decode(encodedValue
), slot
);
815 void DFG_OPERATION
operationPutByIdDirectNonStrict(ExecState
* exec
, EncodedJSValue encodedValue
, JSCell
* base
, Identifier
* propertyName
)
817 VM
* vm
= &exec
->vm();
818 NativeCallFrameTracer
tracer(vm
, exec
);
820 PutPropertySlot
slot(false);
821 ASSERT(base
->isObject());
822 asObject(base
)->putDirect(exec
->vm(), *propertyName
, JSValue::decode(encodedValue
), slot
);
825 V_FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJCI(operationPutByIdStrictOptimize
);
826 void DFG_OPERATION
operationPutByIdStrictOptimizeWithReturnAddress(ExecState
* exec
, EncodedJSValue encodedValue
, JSCell
* base
, Identifier
* propertyName
, ReturnAddressPtr returnAddress
)
828 VM
* vm
= &exec
->vm();
829 NativeCallFrameTracer
tracer(vm
, exec
);
831 StructureStubInfo
& stubInfo
= exec
->codeBlock()->getStubInfo(returnAddress
);
832 AccessType accessType
= static_cast<AccessType
>(stubInfo
.accessType
);
834 JSValue value
= JSValue::decode(encodedValue
);
835 JSValue
baseValue(base
);
836 PutPropertySlot
slot(true);
838 baseValue
.put(exec
, *propertyName
, value
, slot
);
840 if (accessType
!= static_cast<AccessType
>(stubInfo
.accessType
))
844 dfgRepatchPutByID(exec
, baseValue
, *propertyName
, slot
, stubInfo
, NotDirect
);
846 stubInfo
.seen
= true;
849 V_FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJCI(operationPutByIdNonStrictOptimize
);
850 void DFG_OPERATION
operationPutByIdNonStrictOptimizeWithReturnAddress(ExecState
* exec
, EncodedJSValue encodedValue
, JSCell
* base
, Identifier
* propertyName
, ReturnAddressPtr returnAddress
)
852 VM
* vm
= &exec
->vm();
853 NativeCallFrameTracer
tracer(vm
, exec
);
855 StructureStubInfo
& stubInfo
= exec
->codeBlock()->getStubInfo(returnAddress
);
856 AccessType accessType
= static_cast<AccessType
>(stubInfo
.accessType
);
858 JSValue value
= JSValue::decode(encodedValue
);
859 JSValue
baseValue(base
);
860 PutPropertySlot
slot(false);
862 baseValue
.put(exec
, *propertyName
, value
, slot
);
864 if (accessType
!= static_cast<AccessType
>(stubInfo
.accessType
))
868 dfgRepatchPutByID(exec
, baseValue
, *propertyName
, slot
, stubInfo
, NotDirect
);
870 stubInfo
.seen
= true;
873 V_FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJCI(operationPutByIdDirectStrictOptimize
);
874 void DFG_OPERATION
operationPutByIdDirectStrictOptimizeWithReturnAddress(ExecState
* exec
, EncodedJSValue encodedValue
, JSCell
* base
, Identifier
* propertyName
, ReturnAddressPtr returnAddress
)
876 VM
* vm
= &exec
->vm();
877 NativeCallFrameTracer
tracer(vm
, exec
);
879 StructureStubInfo
& stubInfo
= exec
->codeBlock()->getStubInfo(returnAddress
);
880 AccessType accessType
= static_cast<AccessType
>(stubInfo
.accessType
);
882 JSValue value
= JSValue::decode(encodedValue
);
883 PutPropertySlot
slot(true);
885 ASSERT(base
->isObject());
886 asObject(base
)->putDirect(exec
->vm(), *propertyName
, value
, slot
);
888 if (accessType
!= static_cast<AccessType
>(stubInfo
.accessType
))
892 dfgRepatchPutByID(exec
, base
, *propertyName
, slot
, stubInfo
, Direct
);
894 stubInfo
.seen
= true;
897 V_FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJCI(operationPutByIdDirectNonStrictOptimize
);
898 void DFG_OPERATION
operationPutByIdDirectNonStrictOptimizeWithReturnAddress(ExecState
* exec
, EncodedJSValue encodedValue
, JSCell
* base
, Identifier
* propertyName
, ReturnAddressPtr returnAddress
)
900 VM
* vm
= &exec
->vm();
901 NativeCallFrameTracer
tracer(vm
, exec
);
903 StructureStubInfo
& stubInfo
= exec
->codeBlock()->getStubInfo(returnAddress
);
904 AccessType accessType
= static_cast<AccessType
>(stubInfo
.accessType
);
906 JSValue value
= JSValue::decode(encodedValue
);
907 PutPropertySlot
slot(false);
909 ASSERT(base
->isObject());
910 asObject(base
)->putDirect(exec
->vm(), *propertyName
, value
, slot
);
912 if (accessType
!= static_cast<AccessType
>(stubInfo
.accessType
))
916 dfgRepatchPutByID(exec
, base
, *propertyName
, slot
, stubInfo
, Direct
);
918 stubInfo
.seen
= true;
921 V_FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJCI(operationPutByIdStrictBuildList
);
922 void DFG_OPERATION
operationPutByIdStrictBuildListWithReturnAddress(ExecState
* exec
, EncodedJSValue encodedValue
, JSCell
* base
, Identifier
* propertyName
, ReturnAddressPtr returnAddress
)
924 VM
* vm
= &exec
->vm();
925 NativeCallFrameTracer
tracer(vm
, exec
);
927 StructureStubInfo
& stubInfo
= exec
->codeBlock()->getStubInfo(returnAddress
);
928 AccessType accessType
= static_cast<AccessType
>(stubInfo
.accessType
);
930 JSValue value
= JSValue::decode(encodedValue
);
931 JSValue
baseValue(base
);
932 PutPropertySlot
slot(true);
934 baseValue
.put(exec
, *propertyName
, value
, slot
);
936 if (accessType
!= static_cast<AccessType
>(stubInfo
.accessType
))
939 dfgBuildPutByIdList(exec
, baseValue
, *propertyName
, slot
, stubInfo
, NotDirect
);
942 V_FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJCI(operationPutByIdNonStrictBuildList
);
943 void DFG_OPERATION
operationPutByIdNonStrictBuildListWithReturnAddress(ExecState
* exec
, EncodedJSValue encodedValue
, JSCell
* base
, Identifier
* propertyName
, ReturnAddressPtr returnAddress
)
945 VM
* vm
= &exec
->vm();
946 NativeCallFrameTracer
tracer(vm
, exec
);
948 StructureStubInfo
& stubInfo
= exec
->codeBlock()->getStubInfo(returnAddress
);
949 AccessType accessType
= static_cast<AccessType
>(stubInfo
.accessType
);
951 JSValue value
= JSValue::decode(encodedValue
);
952 JSValue
baseValue(base
);
953 PutPropertySlot
slot(false);
955 baseValue
.put(exec
, *propertyName
, value
, slot
);
957 if (accessType
!= static_cast<AccessType
>(stubInfo
.accessType
))
960 dfgBuildPutByIdList(exec
, baseValue
, *propertyName
, slot
, stubInfo
, NotDirect
);
963 V_FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJCI(operationPutByIdDirectStrictBuildList
);
964 void DFG_OPERATION
operationPutByIdDirectStrictBuildListWithReturnAddress(ExecState
* exec
, EncodedJSValue encodedValue
, JSCell
* base
, Identifier
* propertyName
, ReturnAddressPtr returnAddress
)
966 VM
* vm
= &exec
->vm();
967 NativeCallFrameTracer
tracer(vm
, exec
);
969 StructureStubInfo
& stubInfo
= exec
->codeBlock()->getStubInfo(returnAddress
);
970 AccessType accessType
= static_cast<AccessType
>(stubInfo
.accessType
);
972 JSValue value
= JSValue::decode(encodedValue
);
973 PutPropertySlot
slot(true);
975 ASSERT(base
->isObject());
976 asObject(base
)->putDirect(exec
->vm(), *propertyName
, value
, slot
);
978 if (accessType
!= static_cast<AccessType
>(stubInfo
.accessType
))
981 dfgBuildPutByIdList(exec
, base
, *propertyName
, slot
, stubInfo
, Direct
);
984 V_FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJCI(operationPutByIdDirectNonStrictBuildList
);
985 void DFG_OPERATION
operationPutByIdDirectNonStrictBuildListWithReturnAddress(ExecState
* exec
, EncodedJSValue encodedValue
, JSCell
* base
, Identifier
* propertyName
, ReturnAddressPtr returnAddress
)
987 VM
* vm
= &exec
->vm();
988 NativeCallFrameTracer
tracer(vm
, exec
);
990 StructureStubInfo
& stubInfo
= exec
->codeBlock()->getStubInfo(returnAddress
);
991 AccessType accessType
= static_cast<AccessType
>(stubInfo
.accessType
);
993 JSValue value
= JSValue::decode(encodedValue
);
994 PutPropertySlot
slot(false);
996 ASSERT(base
->isObject());
997 asObject(base
)->putDirect(exec
->vm(), *propertyName
, value
, slot
);
999 if (accessType
!= static_cast<AccessType
>(stubInfo
.accessType
))
1002 dfgBuildPutByIdList(exec
, base
, *propertyName
, slot
, stubInfo
, Direct
);
1005 size_t DFG_OPERATION
operationCompareLess(ExecState
* exec
, EncodedJSValue encodedOp1
, EncodedJSValue encodedOp2
)
1007 VM
* vm
= &exec
->vm();
1008 NativeCallFrameTracer
tracer(vm
, exec
);
1010 return jsLess
<true>(exec
, JSValue::decode(encodedOp1
), JSValue::decode(encodedOp2
));
1013 size_t DFG_OPERATION
operationCompareLessEq(ExecState
* exec
, EncodedJSValue encodedOp1
, EncodedJSValue encodedOp2
)
1015 VM
* vm
= &exec
->vm();
1016 NativeCallFrameTracer
tracer(vm
, exec
);
1018 return jsLessEq
<true>(exec
, JSValue::decode(encodedOp1
), JSValue::decode(encodedOp2
));
1021 size_t DFG_OPERATION
operationCompareGreater(ExecState
* exec
, EncodedJSValue encodedOp1
, EncodedJSValue encodedOp2
)
1023 VM
* vm
= &exec
->vm();
1024 NativeCallFrameTracer
tracer(vm
, exec
);
1026 return jsLess
<false>(exec
, JSValue::decode(encodedOp2
), JSValue::decode(encodedOp1
));
1029 size_t DFG_OPERATION
operationCompareGreaterEq(ExecState
* exec
, EncodedJSValue encodedOp1
, EncodedJSValue encodedOp2
)
1031 VM
* vm
= &exec
->vm();
1032 NativeCallFrameTracer
tracer(vm
, exec
);
1034 return jsLessEq
<false>(exec
, JSValue::decode(encodedOp2
), JSValue::decode(encodedOp1
));
1037 size_t DFG_OPERATION
operationCompareEq(ExecState
* exec
, EncodedJSValue encodedOp1
, EncodedJSValue encodedOp2
)
1039 VM
* vm
= &exec
->vm();
1040 NativeCallFrameTracer
tracer(vm
, exec
);
1042 return JSValue::equalSlowCaseInline(exec
, JSValue::decode(encodedOp1
), JSValue::decode(encodedOp2
));
1046 EncodedJSValue DFG_OPERATION
operationCompareStringEq(ExecState
* exec
, JSCell
* left
, JSCell
* right
)
1048 size_t DFG_OPERATION
operationCompareStringEq(ExecState
* exec
, JSCell
* left
, JSCell
* right
)
1051 VM
* vm
= &exec
->vm();
1052 NativeCallFrameTracer
tracer(vm
, exec
);
1054 bool result
= asString(left
)->value(exec
) == asString(right
)->value(exec
);
1056 return JSValue::encode(jsBoolean(result
));
1062 size_t DFG_OPERATION
operationCompareStrictEqCell(ExecState
* exec
, EncodedJSValue encodedOp1
, EncodedJSValue encodedOp2
)
1064 VM
* vm
= &exec
->vm();
1065 NativeCallFrameTracer
tracer(vm
, exec
);
1067 JSValue op1
= JSValue::decode(encodedOp1
);
1068 JSValue op2
= JSValue::decode(encodedOp2
);
1070 ASSERT(op1
.isCell());
1071 ASSERT(op2
.isCell());
1073 return JSValue::strictEqualSlowCaseInline(exec
, op1
, op2
);
1076 size_t DFG_OPERATION
operationCompareStrictEq(ExecState
* exec
, EncodedJSValue encodedOp1
, EncodedJSValue encodedOp2
)
1078 VM
* vm
= &exec
->vm();
1079 NativeCallFrameTracer
tracer(vm
, exec
);
1081 JSValue src1
= JSValue::decode(encodedOp1
);
1082 JSValue src2
= JSValue::decode(encodedOp2
);
1084 return JSValue::strictEqual(exec
, src1
, src2
);
1087 static void* handleHostCall(ExecState
* execCallee
, JSValue callee
, CodeSpecializationKind kind
)
1089 ExecState
* exec
= execCallee
->callerFrame();
1090 VM
* vm
= &exec
->vm();
1092 execCallee
->setScope(exec
->scope());
1093 execCallee
->setCodeBlock(0);
1095 if (kind
== CodeForCall
) {
1097 CallType callType
= getCallData(callee
, callData
);
1099 ASSERT(callType
!= CallTypeJS
);
1101 if (callType
== CallTypeHost
) {
1102 NativeCallFrameTracer
tracer(vm
, execCallee
);
1103 execCallee
->setCallee(asObject(callee
));
1104 vm
->hostCallReturnValue
= JSValue::decode(callData
.native
.function(execCallee
));
1106 return vm
->getCTIStub(throwExceptionFromCallSlowPathGenerator
).code().executableAddress();
1108 return reinterpret_cast<void*>(getHostCallReturnValue
);
1111 ASSERT(callType
== CallTypeNone
);
1112 exec
->vm().exception
= createNotAFunctionError(exec
, callee
);
1113 return vm
->getCTIStub(throwExceptionFromCallSlowPathGenerator
).code().executableAddress();
1116 ASSERT(kind
== CodeForConstruct
);
1118 ConstructData constructData
;
1119 ConstructType constructType
= getConstructData(callee
, constructData
);
1121 ASSERT(constructType
!= ConstructTypeJS
);
1123 if (constructType
== ConstructTypeHost
) {
1124 NativeCallFrameTracer
tracer(vm
, execCallee
);
1125 execCallee
->setCallee(asObject(callee
));
1126 vm
->hostCallReturnValue
= JSValue::decode(constructData
.native
.function(execCallee
));
1128 return vm
->getCTIStub(throwExceptionFromCallSlowPathGenerator
).code().executableAddress();
1130 return reinterpret_cast<void*>(getHostCallReturnValue
);
1133 ASSERT(constructType
== ConstructTypeNone
);
1134 exec
->vm().exception
= createNotAConstructorError(exec
, callee
);
1135 return vm
->getCTIStub(throwExceptionFromCallSlowPathGenerator
).code().executableAddress();
1138 inline char* linkFor(ExecState
* execCallee
, CodeSpecializationKind kind
)
1140 ExecState
* exec
= execCallee
->callerFrame();
1141 VM
* vm
= &exec
->vm();
1142 NativeCallFrameTracer
tracer(vm
, exec
);
1144 JSValue calleeAsValue
= execCallee
->calleeAsValue();
1145 JSCell
* calleeAsFunctionCell
= getJSFunction(calleeAsValue
);
1146 if (!calleeAsFunctionCell
)
1147 return reinterpret_cast<char*>(handleHostCall(execCallee
, calleeAsValue
, kind
));
1149 JSFunction
* callee
= jsCast
<JSFunction
*>(calleeAsFunctionCell
);
1150 execCallee
->setScope(callee
->scopeUnchecked());
1151 ExecutableBase
* executable
= callee
->executable();
1153 MacroAssemblerCodePtr codePtr
;
1154 CodeBlock
* codeBlock
= 0;
1155 if (executable
->isHostFunction())
1156 codePtr
= executable
->generatedJITCodeFor(kind
).addressForCall();
1158 FunctionExecutable
* functionExecutable
= static_cast<FunctionExecutable
*>(executable
);
1159 JSObject
* error
= functionExecutable
->compileFor(execCallee
, callee
->scope(), kind
);
1161 vm
->exception
= createStackOverflowError(exec
);
1162 return reinterpret_cast<char*>(vm
->getCTIStub(throwExceptionFromCallSlowPathGenerator
).code().executableAddress());
1164 codeBlock
= &functionExecutable
->generatedBytecodeFor(kind
);
1165 if (execCallee
->argumentCountIncludingThis() < static_cast<size_t>(codeBlock
->numParameters()))
1166 codePtr
= functionExecutable
->generatedJITCodeWithArityCheckFor(kind
);
1168 codePtr
= functionExecutable
->generatedJITCodeFor(kind
).addressForCall();
1170 CallLinkInfo
& callLinkInfo
= exec
->codeBlock()->getCallLinkInfo(execCallee
->returnPC());
1171 if (!callLinkInfo
.seenOnce())
1172 callLinkInfo
.setSeen();
1174 dfgLinkFor(execCallee
, callLinkInfo
, codeBlock
, callee
, codePtr
, kind
);
1175 return reinterpret_cast<char*>(codePtr
.executableAddress());
1178 char* DFG_OPERATION
operationLinkCall(ExecState
* execCallee
)
1180 return linkFor(execCallee
, CodeForCall
);
1183 char* DFG_OPERATION
operationLinkConstruct(ExecState
* execCallee
)
1185 return linkFor(execCallee
, CodeForConstruct
);
1188 inline char* virtualForWithFunction(ExecState
* execCallee
, CodeSpecializationKind kind
, JSCell
*& calleeAsFunctionCell
)
1190 ExecState
* exec
= execCallee
->callerFrame();
1191 VM
* vm
= &exec
->vm();
1192 NativeCallFrameTracer
tracer(vm
, exec
);
1194 JSValue calleeAsValue
= execCallee
->calleeAsValue();
1195 calleeAsFunctionCell
= getJSFunction(calleeAsValue
);
1196 if (UNLIKELY(!calleeAsFunctionCell
))
1197 return reinterpret_cast<char*>(handleHostCall(execCallee
, calleeAsValue
, kind
));
1199 JSFunction
* function
= jsCast
<JSFunction
*>(calleeAsFunctionCell
);
1200 execCallee
->setScope(function
->scopeUnchecked());
1201 ExecutableBase
* executable
= function
->executable();
1202 if (UNLIKELY(!executable
->hasJITCodeFor(kind
))) {
1203 FunctionExecutable
* functionExecutable
= static_cast<FunctionExecutable
*>(executable
);
1204 JSObject
* error
= functionExecutable
->compileFor(execCallee
, function
->scope(), kind
);
1206 exec
->vm().exception
= error
;
1207 return reinterpret_cast<char*>(vm
->getCTIStub(throwExceptionFromCallSlowPathGenerator
).code().executableAddress());
1210 return reinterpret_cast<char*>(executable
->generatedJITCodeWithArityCheckFor(kind
).executableAddress());
1213 inline char* virtualFor(ExecState
* execCallee
, CodeSpecializationKind kind
)
1215 JSCell
* calleeAsFunctionCellIgnored
;
1216 return virtualForWithFunction(execCallee
, kind
, calleeAsFunctionCellIgnored
);
1219 static bool attemptToOptimizeClosureCall(ExecState
* execCallee
, JSCell
* calleeAsFunctionCell
, CallLinkInfo
& callLinkInfo
)
1221 if (!calleeAsFunctionCell
)
1224 JSFunction
* callee
= jsCast
<JSFunction
*>(calleeAsFunctionCell
);
1225 JSFunction
* oldCallee
= callLinkInfo
.callee
.get();
1228 || oldCallee
->structure() != callee
->structure()
1229 || oldCallee
->executable() != callee
->executable())
1232 ASSERT(callee
->executable()->hasJITCodeForCall());
1233 MacroAssemblerCodePtr codePtr
= callee
->executable()->generatedJITCodeForCall().addressForCall();
1235 CodeBlock
* codeBlock
;
1236 if (callee
->executable()->isHostFunction())
1239 codeBlock
= &jsCast
<FunctionExecutable
*>(callee
->executable())->generatedBytecodeForCall();
1240 if (execCallee
->argumentCountIncludingThis() < static_cast<size_t>(codeBlock
->numParameters()))
1245 execCallee
, callLinkInfo
, codeBlock
,
1246 callee
->structure(), callee
->executable(), codePtr
);
1251 char* DFG_OPERATION
operationLinkClosureCall(ExecState
* execCallee
)
1253 JSCell
* calleeAsFunctionCell
;
1254 char* result
= virtualForWithFunction(execCallee
, CodeForCall
, calleeAsFunctionCell
);
1255 CallLinkInfo
& callLinkInfo
= execCallee
->callerFrame()->codeBlock()->getCallLinkInfo(execCallee
->returnPC());
1257 if (!attemptToOptimizeClosureCall(execCallee
, calleeAsFunctionCell
, callLinkInfo
))
1258 dfgLinkSlowFor(execCallee
, callLinkInfo
, CodeForCall
);
1263 char* DFG_OPERATION
operationVirtualCall(ExecState
* execCallee
)
1265 return virtualFor(execCallee
, CodeForCall
);
1268 char* DFG_OPERATION
operationVirtualConstruct(ExecState
* execCallee
)
1270 return virtualFor(execCallee
, CodeForConstruct
);
1273 void DFG_OPERATION
operationNotifyGlobalVarWrite(WatchpointSet
* watchpointSet
)
1275 watchpointSet
->notifyWrite();
1278 EncodedJSValue DFG_OPERATION
operationResolve(ExecState
* exec
, Identifier
* propertyName
, ResolveOperations
* operations
)
1280 VM
* vm
= &exec
->vm();
1281 NativeCallFrameTracer
tracer(vm
, exec
);
1282 return JSValue::encode(JSScope::resolve(exec
, *propertyName
, operations
));
1285 EncodedJSValue DFG_OPERATION
operationResolveBase(ExecState
* exec
, Identifier
* propertyName
, ResolveOperations
* operations
, PutToBaseOperation
* putToBaseOperations
)
1287 VM
* vm
= &exec
->vm();
1288 NativeCallFrameTracer
tracer(vm
, exec
);
1290 return JSValue::encode(JSScope::resolveBase(exec
, *propertyName
, false, operations
, putToBaseOperations
));
1293 EncodedJSValue DFG_OPERATION
operationResolveBaseStrictPut(ExecState
* exec
, Identifier
* propertyName
, ResolveOperations
* operations
, PutToBaseOperation
* putToBaseOperations
)
1295 VM
* vm
= &exec
->vm();
1296 NativeCallFrameTracer
tracer(vm
, exec
);
1298 return JSValue::encode(JSScope::resolveBase(exec
, *propertyName
, true, operations
, putToBaseOperations
));
1301 EncodedJSValue DFG_OPERATION
operationResolveGlobal(ExecState
* exec
, ResolveOperation
* resolveOperation
, JSGlobalObject
* globalObject
, Identifier
* propertyName
)
1303 VM
* vm
= &exec
->vm();
1304 NativeCallFrameTracer
tracer(vm
, exec
);
1305 ASSERT(globalObject
);
1306 UNUSED_PARAM(resolveOperation
);
1307 UNUSED_PARAM(globalObject
);
1308 ASSERT(resolveOperation
->m_operation
== ResolveOperation::GetAndReturnGlobalProperty
);
1309 return JSValue::encode(JSScope::resolveGlobal(exec
, *propertyName
, globalObject
, resolveOperation
));
1312 EncodedJSValue DFG_OPERATION
operationToPrimitive(ExecState
* exec
, EncodedJSValue value
)
1314 VM
* vm
= &exec
->vm();
1315 NativeCallFrameTracer
tracer(vm
, exec
);
1317 return JSValue::encode(JSValue::decode(value
).toPrimitive(exec
));
1320 char* DFG_OPERATION
operationNewArray(ExecState
* exec
, Structure
* arrayStructure
, void* buffer
, size_t size
)
1322 VM
* vm
= &exec
->vm();
1323 NativeCallFrameTracer
tracer(vm
, exec
);
1325 return bitwise_cast
<char*>(constructArray(exec
, arrayStructure
, static_cast<JSValue
*>(buffer
), size
));
1328 char* DFG_OPERATION
operationNewEmptyArray(ExecState
* exec
, Structure
* arrayStructure
)
1330 VM
* vm
= &exec
->vm();
1331 NativeCallFrameTracer
tracer(vm
, exec
);
1333 return bitwise_cast
<char*>(JSArray::create(*vm
, arrayStructure
));
1336 char* DFG_OPERATION
operationNewArrayWithSize(ExecState
* exec
, Structure
* arrayStructure
, int32_t size
)
1338 VM
* vm
= &exec
->vm();
1339 NativeCallFrameTracer
tracer(vm
, exec
);
1341 if (UNLIKELY(size
< 0))
1342 return bitwise_cast
<char*>(throwError(exec
, createRangeError(exec
, ASCIILiteral("Array size is not a small enough positive integer."))));
1344 return bitwise_cast
<char*>(JSArray::create(*vm
, arrayStructure
, size
));
1347 char* DFG_OPERATION
operationNewArrayBuffer(ExecState
* exec
, Structure
* arrayStructure
, size_t start
, size_t size
)
1349 VM
& vm
= exec
->vm();
1350 NativeCallFrameTracer
tracer(&vm
, exec
);
1351 return bitwise_cast
<char*>(constructArray(exec
, arrayStructure
, exec
->codeBlock()->constantBuffer(start
), size
));
1354 EncodedJSValue DFG_OPERATION
operationNewRegexp(ExecState
* exec
, void* regexpPtr
)
1356 VM
& vm
= exec
->vm();
1357 NativeCallFrameTracer
tracer(&vm
, exec
);
1358 RegExp
* regexp
= static_cast<RegExp
*>(regexpPtr
);
1359 if (!regexp
->isValid()) {
1360 throwError(exec
, createSyntaxError(exec
, "Invalid flags supplied to RegExp constructor."));
1361 return JSValue::encode(jsUndefined());
1364 return JSValue::encode(RegExpObject::create(exec
->vm(), exec
->lexicalGlobalObject(), exec
->lexicalGlobalObject()->regExpStructure(), regexp
));
1367 JSCell
* DFG_OPERATION
operationCreateActivation(ExecState
* exec
)
1369 VM
& vm
= exec
->vm();
1370 NativeCallFrameTracer
tracer(&vm
, exec
);
1371 JSActivation
* activation
= JSActivation::create(vm
, exec
, exec
->codeBlock());
1372 exec
->setScope(activation
);
1376 JSCell
* DFG_OPERATION
operationCreateArguments(ExecState
* exec
)
1378 VM
& vm
= exec
->vm();
1379 NativeCallFrameTracer
tracer(&vm
, exec
);
1380 // NB: This needs to be exceedingly careful with top call frame tracking, since it
1381 // may be called from OSR exit, while the state of the call stack is bizarre.
1382 Arguments
* result
= Arguments::create(vm
, exec
);
1383 ASSERT(!vm
.exception
);
1387 JSCell
* DFG_OPERATION
operationCreateInlinedArguments(
1388 ExecState
* exec
, InlineCallFrame
* inlineCallFrame
)
1390 VM
& vm
= exec
->vm();
1391 NativeCallFrameTracer
tracer(&vm
, exec
);
1392 // NB: This needs to be exceedingly careful with top call frame tracking, since it
1393 // may be called from OSR exit, while the state of the call stack is bizarre.
1394 Arguments
* result
= Arguments::create(vm
, exec
, inlineCallFrame
);
1395 ASSERT(!vm
.exception
);
1399 void DFG_OPERATION
operationTearOffArguments(ExecState
* exec
, JSCell
* argumentsCell
, JSCell
* activationCell
)
1401 ASSERT(exec
->codeBlock()->usesArguments());
1402 if (activationCell
) {
1403 jsCast
<Arguments
*>(argumentsCell
)->didTearOffActivation(exec
, jsCast
<JSActivation
*>(activationCell
));
1406 jsCast
<Arguments
*>(argumentsCell
)->tearOff(exec
);
1409 void DFG_OPERATION
operationTearOffInlinedArguments(
1410 ExecState
* exec
, JSCell
* argumentsCell
, JSCell
* activationCell
, InlineCallFrame
* inlineCallFrame
)
1412 ASSERT_UNUSED(activationCell
, !activationCell
); // Currently, we don't inline functions with activations.
1413 jsCast
<Arguments
*>(argumentsCell
)->tearOff(exec
, inlineCallFrame
);
1416 EncodedJSValue DFG_OPERATION
operationGetArgumentsLength(ExecState
* exec
, int32_t argumentsRegister
)
1418 VM
& vm
= exec
->vm();
1419 NativeCallFrameTracer
tracer(&vm
, exec
);
1420 // Here we can assume that the argumernts were created. Because otherwise the JIT code would
1421 // have not made this call.
1422 Identifier
ident(&vm
, "length");
1423 JSValue baseValue
= exec
->uncheckedR(argumentsRegister
).jsValue();
1424 PropertySlot
slot(baseValue
);
1425 return JSValue::encode(baseValue
.get(exec
, ident
, slot
));
1428 EncodedJSValue DFG_OPERATION
operationGetArgumentByVal(ExecState
* exec
, int32_t argumentsRegister
, int32_t index
)
1430 VM
& vm
= exec
->vm();
1431 NativeCallFrameTracer
tracer(&vm
, exec
);
1433 JSValue argumentsValue
= exec
->uncheckedR(argumentsRegister
).jsValue();
1435 // If there are no arguments, and we're accessing out of bounds, then we have to create the
1436 // arguments in case someone has installed a getter on a numeric property.
1437 if (!argumentsValue
)
1438 exec
->uncheckedR(argumentsRegister
) = argumentsValue
= Arguments::create(exec
->vm(), exec
);
1440 return JSValue::encode(argumentsValue
.get(exec
, index
));
1443 EncodedJSValue DFG_OPERATION
operationGetInlinedArgumentByVal(
1444 ExecState
* exec
, int32_t argumentsRegister
, InlineCallFrame
* inlineCallFrame
, int32_t index
)
1446 VM
& vm
= exec
->vm();
1447 NativeCallFrameTracer
tracer(&vm
, exec
);
1449 JSValue argumentsValue
= exec
->uncheckedR(argumentsRegister
).jsValue();
1451 // If there are no arguments, and we're accessing out of bounds, then we have to create the
1452 // arguments in case someone has installed a getter on a numeric property.
1453 if (!argumentsValue
) {
1454 exec
->uncheckedR(argumentsRegister
) = argumentsValue
=
1455 Arguments::create(exec
->vm(), exec
, inlineCallFrame
);
1458 return JSValue::encode(argumentsValue
.get(exec
, index
));
1461 JSCell
* DFG_OPERATION
operationNewFunctionNoCheck(ExecState
* exec
, JSCell
* functionExecutable
)
1463 ASSERT(functionExecutable
->inherits(&FunctionExecutable::s_info
));
1464 VM
& vm
= exec
->vm();
1465 NativeCallFrameTracer
tracer(&vm
, exec
);
1466 return JSFunction::create(exec
, static_cast<FunctionExecutable
*>(functionExecutable
), exec
->scope());
1469 EncodedJSValue DFG_OPERATION
operationNewFunction(ExecState
* exec
, JSCell
* functionExecutable
)
1471 ASSERT(functionExecutable
->inherits(&FunctionExecutable::s_info
));
1472 VM
& vm
= exec
->vm();
1473 NativeCallFrameTracer
tracer(&vm
, exec
);
1474 return JSValue::encode(JSFunction::create(exec
, static_cast<FunctionExecutable
*>(functionExecutable
), exec
->scope()));
1477 JSCell
* DFG_OPERATION
operationNewFunctionExpression(ExecState
* exec
, JSCell
* functionExecutableAsCell
)
1479 ASSERT(functionExecutableAsCell
->inherits(&FunctionExecutable::s_info
));
1481 VM
& vm
= exec
->vm();
1482 NativeCallFrameTracer
tracer(&vm
, exec
);
1484 FunctionExecutable
* functionExecutable
=
1485 static_cast<FunctionExecutable
*>(functionExecutableAsCell
);
1486 return JSFunction::create(exec
, functionExecutable
, exec
->scope());
1489 size_t DFG_OPERATION
operationIsObject(ExecState
* exec
, EncodedJSValue value
)
1491 return jsIsObjectType(exec
, JSValue::decode(value
));
1494 size_t DFG_OPERATION
operationIsFunction(EncodedJSValue value
)
1496 return jsIsFunctionType(JSValue::decode(value
));
1499 JSCell
* DFG_OPERATION
operationTypeOf(ExecState
* exec
, JSCell
* value
)
1501 return jsTypeStringForValue(exec
, JSValue(value
)).asCell();
1504 void DFG_OPERATION
operationReallocateStorageAndFinishPut(ExecState
* exec
, JSObject
* base
, Structure
* structure
, PropertyOffset offset
, EncodedJSValue value
)
1506 VM
& vm
= exec
->vm();
1507 NativeCallFrameTracer
tracer(&vm
, exec
);
1509 ASSERT(structure
->outOfLineCapacity() > base
->structure()->outOfLineCapacity());
1510 ASSERT(!vm
.heap
.storageAllocator().fastPathShouldSucceed(structure
->outOfLineCapacity() * sizeof(JSValue
)));
1511 base
->setStructureAndReallocateStorageIfNecessary(vm
, structure
);
1512 base
->putDirect(vm
, offset
, JSValue::decode(value
));
1515 char* DFG_OPERATION
operationAllocatePropertyStorageWithInitialCapacity(ExecState
* exec
)
1517 VM
& vm
= exec
->vm();
1518 NativeCallFrameTracer
tracer(&vm
, exec
);
1520 return reinterpret_cast<char*>(
1521 Butterfly::createUninitialized(vm
, 0, initialOutOfLineCapacity
, false, 0));
1524 char* DFG_OPERATION
operationAllocatePropertyStorage(ExecState
* exec
, size_t newSize
)
1526 VM
& vm
= exec
->vm();
1527 NativeCallFrameTracer
tracer(&vm
, exec
);
1529 return reinterpret_cast<char*>(
1530 Butterfly::createUninitialized(vm
, 0, newSize
, false, 0));
1533 char* DFG_OPERATION
operationReallocateButterflyToHavePropertyStorageWithInitialCapacity(ExecState
* exec
, JSObject
* object
)
1535 VM
& vm
= exec
->vm();
1536 NativeCallFrameTracer
tracer(&vm
, exec
);
1538 ASSERT(!object
->structure()->outOfLineCapacity());
1539 Butterfly
* result
= object
->growOutOfLineStorage(vm
, 0, initialOutOfLineCapacity
);
1540 object
->setButterflyWithoutChangingStructure(result
);
1541 return reinterpret_cast<char*>(result
);
1544 char* DFG_OPERATION
operationReallocateButterflyToGrowPropertyStorage(ExecState
* exec
, JSObject
* object
, size_t newSize
)
1546 VM
& vm
= exec
->vm();
1547 NativeCallFrameTracer
tracer(&vm
, exec
);
1549 Butterfly
* result
= object
->growOutOfLineStorage(vm
, object
->structure()->outOfLineCapacity(), newSize
);
1550 object
->setButterflyWithoutChangingStructure(result
);
1551 return reinterpret_cast<char*>(result
);
1554 char* DFG_OPERATION
operationEnsureInt32(ExecState
* exec
, JSCell
* cell
)
1556 VM
& vm
= exec
->vm();
1557 NativeCallFrameTracer
tracer(&vm
, exec
);
1559 if (!cell
->isObject())
1562 return reinterpret_cast<char*>(asObject(cell
)->ensureInt32(vm
).data());
1565 char* DFG_OPERATION
operationEnsureDouble(ExecState
* exec
, JSCell
* cell
)
1567 VM
& vm
= exec
->vm();
1568 NativeCallFrameTracer
tracer(&vm
, exec
);
1570 if (!cell
->isObject())
1573 return reinterpret_cast<char*>(asObject(cell
)->ensureDouble(vm
).data());
1576 char* DFG_OPERATION
operationEnsureContiguous(ExecState
* exec
, JSCell
* cell
)
1578 VM
& vm
= exec
->vm();
1579 NativeCallFrameTracer
tracer(&vm
, exec
);
1581 if (!cell
->isObject())
1584 return reinterpret_cast<char*>(asObject(cell
)->ensureContiguous(vm
).data());
1587 char* DFG_OPERATION
operationRageEnsureContiguous(ExecState
* exec
, JSCell
* cell
)
1589 VM
& vm
= exec
->vm();
1590 NativeCallFrameTracer
tracer(&vm
, exec
);
1592 if (!cell
->isObject())
1595 return reinterpret_cast<char*>(asObject(cell
)->rageEnsureContiguous(vm
).data());
1598 char* DFG_OPERATION
operationEnsureArrayStorage(ExecState
* exec
, JSCell
* cell
)
1600 VM
& vm
= exec
->vm();
1601 NativeCallFrameTracer
tracer(&vm
, exec
);
1603 if (!cell
->isObject())
1606 return reinterpret_cast<char*>(asObject(cell
)->ensureArrayStorage(vm
));
1609 StringImpl
* DFG_OPERATION
operationResolveRope(ExecState
* exec
, JSString
* string
)
1611 VM
& vm
= exec
->vm();
1612 NativeCallFrameTracer
tracer(&vm
, exec
);
1614 return string
->value(exec
).impl();
1617 JSCell
* DFG_OPERATION
operationNewStringObject(ExecState
* exec
, JSString
* string
, Structure
* structure
)
1619 VM
& vm
= exec
->vm();
1620 NativeCallFrameTracer
tracer(&vm
, exec
);
1622 return StringObject::create(exec
, structure
, string
);
1625 JSCell
* DFG_OPERATION
operationToStringOnCell(ExecState
* exec
, JSCell
* cell
)
1627 VM
& vm
= exec
->vm();
1628 NativeCallFrameTracer
tracer(&vm
, exec
);
1630 return JSValue(cell
).toString(exec
);
1633 JSCell
* DFG_OPERATION
operationToString(ExecState
* exec
, EncodedJSValue value
)
1635 VM
& vm
= exec
->vm();
1636 NativeCallFrameTracer
tracer(&vm
, exec
);
1638 return JSValue::decode(value
).toString(exec
);
1641 JSCell
* DFG_OPERATION
operationMakeRope2(ExecState
* exec
, JSString
* left
, JSString
* right
)
1643 VM
& vm
= exec
->vm();
1644 NativeCallFrameTracer
tracer(&vm
, exec
);
1646 return JSRopeString::create(vm
, left
, right
);
1649 JSCell
* DFG_OPERATION
operationMakeRope3(ExecState
* exec
, JSString
* a
, JSString
* b
, JSString
* c
)
1651 VM
& vm
= exec
->vm();
1652 NativeCallFrameTracer
tracer(&vm
, exec
);
1654 return JSRopeString::create(vm
, a
, b
, c
);
1657 double DFG_OPERATION
operationFModOnInts(int32_t a
, int32_t b
)
1662 JSCell
* DFG_OPERATION
operationStringFromCharCode(ExecState
* exec
, int32_t op1
)
1664 VM
* vm
= &exec
->vm();
1665 NativeCallFrameTracer
tracer(vm
, exec
);
1666 return JSC::stringFromCharCode(exec
, op1
);
1669 DFGHandlerEncoded DFG_OPERATION
lookupExceptionHandler(ExecState
* exec
, uint32_t callIndex
)
1671 VM
* vm
= &exec
->vm();
1672 NativeCallFrameTracer
tracer(vm
, exec
);
1674 JSValue exceptionValue
= exec
->exception();
1675 ASSERT(exceptionValue
);
1677 unsigned vPCIndex
= exec
->codeBlock()->bytecodeOffsetForCallAtIndex(callIndex
);
1678 ExceptionHandler handler
= genericThrow(vm
, exec
, exceptionValue
, vPCIndex
);
1679 ASSERT(handler
.catchRoutine
);
1680 return dfgHandlerEncoded(handler
.callFrame
, handler
.catchRoutine
);
1683 DFGHandlerEncoded DFG_OPERATION
lookupExceptionHandlerInStub(ExecState
* exec
, StructureStubInfo
* stubInfo
)
1685 VM
* vm
= &exec
->vm();
1686 NativeCallFrameTracer
tracer(vm
, exec
);
1688 JSValue exceptionValue
= exec
->exception();
1689 ASSERT(exceptionValue
);
1691 CodeOrigin codeOrigin
= stubInfo
->codeOrigin
;
1692 while (codeOrigin
.inlineCallFrame
)
1693 codeOrigin
= codeOrigin
.inlineCallFrame
->caller
;
1695 ExceptionHandler handler
= genericThrow(vm
, exec
, exceptionValue
, codeOrigin
.bytecodeIndex
);
1696 ASSERT(handler
.catchRoutine
);
1697 return dfgHandlerEncoded(handler
.callFrame
, handler
.catchRoutine
);
1700 size_t DFG_OPERATION
dfgConvertJSValueToInt32(ExecState
* exec
, EncodedJSValue value
)
1702 VM
* vm
= &exec
->vm();
1703 NativeCallFrameTracer
tracer(vm
, exec
);
1705 // toInt32/toUInt32 return the same value; we want the value zero extended to fill the register.
1706 return JSValue::decode(value
).toUInt32(exec
);
1709 size_t DFG_OPERATION
dfgConvertJSValueToBoolean(ExecState
* exec
, EncodedJSValue encodedOp
)
1711 VM
* vm
= &exec
->vm();
1712 NativeCallFrameTracer
tracer(vm
, exec
);
1714 return JSValue::decode(encodedOp
).toBoolean(exec
);
1717 void DFG_OPERATION
debugOperationPrintSpeculationFailure(ExecState
* exec
, void* debugInfoRaw
, void* scratch
)
1719 VM
* vm
= &exec
->vm();
1720 NativeCallFrameTracer
tracer(vm
, exec
);
1722 SpeculationFailureDebugInfo
* debugInfo
= static_cast<SpeculationFailureDebugInfo
*>(debugInfoRaw
);
1723 CodeBlock
* codeBlock
= debugInfo
->codeBlock
;
1724 CodeBlock
* alternative
= codeBlock
->alternative();
1726 "Speculation failure in ", *codeBlock
, " with ");
1729 "executeCounter = ", alternative
->jitExecuteCounter(),
1730 ", reoptimizationRetryCounter = ", alternative
->reoptimizationRetryCounter(),
1731 ", optimizationDelayCounter = ", alternative
->optimizationDelayCounter());
1733 dataLog("no alternative code block (i.e. we've been jettisoned)");
1734 dataLog(", osrExitCounter = ", codeBlock
->osrExitCounter(), "\n");
1735 dataLog(" GPRs at time of exit:");
1736 char* scratchPointer
= static_cast<char*>(scratch
);
1737 for (unsigned i
= 0; i
< GPRInfo::numberOfRegisters
; ++i
) {
1738 GPRReg gpr
= GPRInfo::toRegister(i
);
1739 dataLog(" ", GPRInfo::debugName(gpr
), ":", RawPointer(*reinterpret_cast_ptr
<void**>(scratchPointer
)));
1740 scratchPointer
+= sizeof(EncodedJSValue
);
1743 dataLog(" FPRs at time of exit:");
1744 for (unsigned i
= 0; i
< FPRInfo::numberOfRegisters
; ++i
) {
1745 FPRReg fpr
= FPRInfo::toRegister(i
);
1746 dataLog(" ", FPRInfo::debugName(fpr
), ":");
1747 uint64_t bits
= *reinterpret_cast_ptr
<uint64_t*>(scratchPointer
);
1748 double value
= *reinterpret_cast_ptr
<double*>(scratchPointer
);
1749 dataLogF("%llx:%lf", static_cast<long long>(bits
), value
);
1750 scratchPointer
+= sizeof(EncodedJSValue
);
1755 extern "C" void DFG_OPERATION
triggerReoptimizationNow(CodeBlock
* codeBlock
)
1757 #if ENABLE(JIT_VERBOSE_OSR)
1758 dataLog(*codeBlock
, ": Entered reoptimize\n");
1760 // We must be called with the baseline code block.
1761 ASSERT(JITCode::isBaselineCode(codeBlock
->getJITType()));
1763 // If I am my own replacement, then reoptimization has already been triggered.
1764 // This can happen in recursive functions.
1765 if (codeBlock
->replacement() == codeBlock
)
1768 // Otherwise, the replacement must be optimized code. Use this as an opportunity
1769 // to check our logic.
1770 ASSERT(codeBlock
->hasOptimizedReplacement());
1771 ASSERT(codeBlock
->replacement()->getJITType() == JITCode::DFGJIT
);
1773 codeBlock
->reoptimize();
1777 } } // namespace JSC::DFG
1779 #endif // ENABLE(DFG_JIT)
1783 #if COMPILER(GCC) && CPU(X86_64)
1785 ".globl " SYMBOL_STRING(getHostCallReturnValue
) "\n"
1786 HIDE_SYMBOL(getHostCallReturnValue
) "\n"
1787 SYMBOL_STRING(getHostCallReturnValue
) ":" "\n"
1788 "mov -40(%r13), %r13\n"
1790 "jmp " LOCAL_REFERENCE(getHostCallReturnValueWithExecState
) "\n"
1792 #elif COMPILER(GCC) && CPU(X86)
1795 ".globl " SYMBOL_STRING(getHostCallReturnValue
) "\n"
1796 HIDE_SYMBOL(getHostCallReturnValue
) "\n"
1797 SYMBOL_STRING(getHostCallReturnValue
) ":" "\n"
1798 "mov -40(%edi), %edi\n"
1799 "mov %edi, 4(%esp)\n"
1800 "jmp " LOCAL_REFERENCE(getHostCallReturnValueWithExecState
) "\n"
1802 #elif COMPILER(GCC) && CPU(ARM_THUMB2)
1806 ".globl " SYMBOL_STRING(getHostCallReturnValue
) "\n"
1807 HIDE_SYMBOL(getHostCallReturnValue
) "\n"
1809 ".thumb_func " THUMB_FUNC_PARAM(getHostCallReturnValue
) "\n"
1810 SYMBOL_STRING(getHostCallReturnValue
) ":" "\n"
1811 "ldr r5, [r5, #-40]" "\n"
1813 "b " LOCAL_REFERENCE(getHostCallReturnValueWithExecState
) "\n"
1815 #elif COMPILER(GCC) && CPU(ARM_TRADITIONAL)
1818 ".globl " SYMBOL_STRING(getHostCallReturnValue
) "\n"
1819 HIDE_SYMBOL(getHostCallReturnValue
) "\n"
1820 INLINE_ARM_FUNCTION(getHostCallReturnValue
)
1821 SYMBOL_STRING(getHostCallReturnValue
) ":" "\n"
1822 "ldr r5, [r5, #-40]" "\n"
1824 "b " LOCAL_REFERENCE(getHostCallReturnValueWithExecState
) "\n"
1830 ".globl " SYMBOL_STRING(getHostCallReturnValue
) "\n"
1831 HIDE_SYMBOL(getHostCallReturnValue
) "\n"
1832 SYMBOL_STRING(getHostCallReturnValue
) ":" "\n"
1833 "ldur x25, [x25, #-40]" "\n"
1835 "b " LOCAL_REFERENCE(getHostCallReturnValueWithExecState
) "\n"
1837 #elif COMPILER(GCC) && CPU(MIPS)
1840 ".globl " SYMBOL_STRING(getHostCallReturnValue
) "\n"
1841 HIDE_SYMBOL(getHostCallReturnValue
) "\n"
1842 SYMBOL_STRING(getHostCallReturnValue
) ":" "\n"
1843 LOAD_FUNCTION_TO_T9(getHostCallReturnValueWithExecState
)
1844 "lw $s0, -40($s0)" "\n"
1845 "move $a0, $s0" "\n"
1846 "b " LOCAL_REFERENCE(getHostCallReturnValueWithExecState
) "\n"
1848 #elif COMPILER(GCC) && CPU(SH4)
1851 ".globl " SYMBOL_STRING(getHostCallReturnValue
) "\n"
1852 HIDE_SYMBOL(getHostCallReturnValue
) "\n"
1853 SYMBOL_STRING(getHostCallReturnValue
) ":" "\n"
1854 "add #-40, r14" "\n"
1855 "mov.l @r14, r14" "\n"
1857 "bra " LOCAL_REFERENCE(getHostCallReturnValueWithExecState
) "\n"
1862 extern "C" EncodedJSValue HOST_CALL_RETURN_VALUE_OPTION
getHostCallReturnValueWithExecState(ExecState
* exec
)
1865 return JSValue::encode(JSValue());
1866 return JSValue::encode(exec
->vm().hostCallReturnValue
);
1871 #endif // ENABLE(JIT)