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)
98 #elif COMPILER(GCC) && CPU(ARM_THUMB2)
100 #define FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_E(function) \
104 ".globl " SYMBOL_STRING(function) "\n" \
105 HIDE_SYMBOL(function) "\n" \
107 ".thumb_func " THUMB_FUNC_PARAM(function) "\n" \
108 SYMBOL_STRING(function) ":" "\n" \
110 "b " LOCAL_REFERENCE(function) "WithReturnAddress" "\n" \
113 #define FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_ECI(function) \
117 ".globl " SYMBOL_STRING(function) "\n" \
118 HIDE_SYMBOL(function) "\n" \
120 ".thumb_func " THUMB_FUNC_PARAM(function) "\n" \
121 SYMBOL_STRING(function) ":" "\n" \
123 "b " LOCAL_REFERENCE(function) "WithReturnAddress" "\n" \
126 // 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]).
127 // As a result, return address will be at a 4-byte further location in the following cases.
128 #if COMPILER_SUPPORTS(EABI) && CPU(ARM)
129 #define INSTRUCTION_STORE_RETURN_ADDRESS_EJI "str lr, [sp, #4]"
130 #define INSTRUCTION_STORE_RETURN_ADDRESS_EJCI "str lr, [sp, #8]"
132 #define INSTRUCTION_STORE_RETURN_ADDRESS_EJI "str lr, [sp, #0]"
133 #define INSTRUCTION_STORE_RETURN_ADDRESS_EJCI "str lr, [sp, #4]"
136 #define FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJI(function) \
140 ".globl " SYMBOL_STRING(function) "\n" \
141 HIDE_SYMBOL(function) "\n" \
143 ".thumb_func " THUMB_FUNC_PARAM(function) "\n" \
144 SYMBOL_STRING(function) ":" "\n" \
145 INSTRUCTION_STORE_RETURN_ADDRESS_EJI "\n" \
146 "b " LOCAL_REFERENCE(function) "WithReturnAddress" "\n" \
149 #define FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJCI(function) \
153 ".globl " SYMBOL_STRING(function) "\n" \
154 HIDE_SYMBOL(function) "\n" \
156 ".thumb_func " THUMB_FUNC_PARAM(function) "\n" \
157 SYMBOL_STRING(function) ":" "\n" \
158 INSTRUCTION_STORE_RETURN_ADDRESS_EJCI "\n" \
159 "b " LOCAL_REFERENCE(function) "WithReturnAddress" "\n" \
162 #elif COMPILER(GCC) && CPU(ARM_TRADITIONAL)
164 #define FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_E(function) \
167 ".globl " SYMBOL_STRING(function) "\n" \
168 HIDE_SYMBOL(function) "\n" \
169 INLINE_ARM_FUNCTION(function) \
170 SYMBOL_STRING(function) ":" "\n" \
172 "b " LOCAL_REFERENCE(function) "WithReturnAddress" "\n" \
175 #define FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_ECI(function) \
178 ".globl " SYMBOL_STRING(function) "\n" \
179 HIDE_SYMBOL(function) "\n" \
180 INLINE_ARM_FUNCTION(function) \
181 SYMBOL_STRING(function) ":" "\n" \
183 "b " LOCAL_REFERENCE(function) "WithReturnAddress" "\n" \
186 // 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]).
187 // As a result, return address will be at a 4-byte further location in the following cases.
188 #if COMPILER_SUPPORTS(EABI) && CPU(ARM)
189 #define INSTRUCTION_STORE_RETURN_ADDRESS_EJI "str lr, [sp, #4]"
190 #define INSTRUCTION_STORE_RETURN_ADDRESS_EJCI "str lr, [sp, #8]"
192 #define INSTRUCTION_STORE_RETURN_ADDRESS_EJI "str lr, [sp, #0]"
193 #define INSTRUCTION_STORE_RETURN_ADDRESS_EJCI "str lr, [sp, #4]"
196 #define FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJI(function) \
199 ".globl " SYMBOL_STRING(function) "\n" \
200 HIDE_SYMBOL(function) "\n" \
201 INLINE_ARM_FUNCTION(function) \
202 SYMBOL_STRING(function) ":" "\n" \
203 INSTRUCTION_STORE_RETURN_ADDRESS_EJI "\n" \
204 "b " LOCAL_REFERENCE(function) "WithReturnAddress" "\n" \
207 #define FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJCI(function) \
210 ".globl " SYMBOL_STRING(function) "\n" \
211 HIDE_SYMBOL(function) "\n" \
212 INLINE_ARM_FUNCTION(function) \
213 SYMBOL_STRING(function) ":" "\n" \
214 INSTRUCTION_STORE_RETURN_ADDRESS_EJCI "\n" \
215 "b " LOCAL_REFERENCE(function) "WithReturnAddress" "\n" \
218 #elif COMPILER(GCC) && CPU(MIPS)
220 #define FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_E(function) \
223 ".globl " SYMBOL_STRING(function) "\n" \
224 HIDE_SYMBOL(function) "\n" \
225 SYMBOL_STRING(function) ":" "\n" \
226 LOAD_FUNCTION_TO_T9(function##WithReturnAddress) \
227 "move $a1, $ra" "\n" \
228 "b " LOCAL_REFERENCE(function) "WithReturnAddress" "\n" \
231 #define FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_ECI(function) \
234 ".globl " SYMBOL_STRING(function) "\n" \
235 HIDE_SYMBOL(function) "\n" \
236 SYMBOL_STRING(function) ":" "\n" \
237 LOAD_FUNCTION_TO_T9(function##WithReturnAddress) \
238 "move $a3, $ra" "\n" \
239 "b " LOCAL_REFERENCE(function) "WithReturnAddress" "\n" \
242 #define FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJI(function) \
245 ".globl " SYMBOL_STRING(function) "\n" \
246 HIDE_SYMBOL(function) "\n" \
247 SYMBOL_STRING(function) ":" "\n" \
248 LOAD_FUNCTION_TO_T9(function##WithReturnAddress) \
249 "sw $ra, 20($sp)" "\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 SYMBOL_STRING(function) ":" "\n" \
259 LOAD_FUNCTION_TO_T9(function##WithReturnAddress) \
260 "sw $ra, 24($sp)" "\n" \
261 "b " LOCAL_REFERENCE(function) "WithReturnAddress" "\n" \
266 #define P_FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_E(function) \
267 void* DFG_OPERATION function##WithReturnAddress(ExecState*, ReturnAddressPtr) REFERENCED_FROM_ASM WTF_INTERNAL; \
268 FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_E(function)
270 #define J_FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_ECI(function) \
271 EncodedJSValue DFG_OPERATION function##WithReturnAddress(ExecState*, JSCell*, Identifier*, ReturnAddressPtr) REFERENCED_FROM_ASM WTF_INTERNAL; \
272 FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_ECI(function)
274 #define J_FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJI(function) \
275 EncodedJSValue DFG_OPERATION function##WithReturnAddress(ExecState*, EncodedJSValue, Identifier*, ReturnAddressPtr) REFERENCED_FROM_ASM WTF_INTERNAL; \
276 FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJI(function)
278 #define V_FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJCI(function) \
279 void DFG_OPERATION function##WithReturnAddress(ExecState*, EncodedJSValue, JSCell*, Identifier*, ReturnAddressPtr) REFERENCED_FROM_ASM WTF_INTERNAL; \
280 FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJCI(function)
282 namespace JSC { namespace DFG {
284 template<bool strict>
285 static inline void putByVal(ExecState* exec, JSValue baseValue, uint32_t index, JSValue value)
288 NativeCallFrameTracer tracer(&vm, exec);
290 if (baseValue.isObject()) {
291 JSObject* object = asObject(baseValue);
292 if (object->canSetIndexQuickly(index)) {
293 object->setIndexQuickly(vm, index, value);
297 object->methodTable()->putByIndex(object, exec, index, value, strict);
301 baseValue.putByIndex(exec, index, value, strict);
304 template<bool strict>
305 ALWAYS_INLINE static void DFG_OPERATION operationPutByValInternal(ExecState* exec, EncodedJSValue encodedBase, EncodedJSValue encodedProperty, EncodedJSValue encodedValue)
307 VM* vm = &exec->vm();
308 NativeCallFrameTracer tracer(vm, exec);
310 JSValue baseValue = JSValue::decode(encodedBase);
311 JSValue property = JSValue::decode(encodedProperty);
312 JSValue value = JSValue::decode(encodedValue);
314 if (LIKELY(property.isUInt32())) {
315 putByVal<strict>(exec, baseValue, property.asUInt32(), value);
319 if (property.isDouble()) {
320 double propertyAsDouble = property.asDouble();
321 uint32_t propertyAsUInt32 = static_cast<uint32_t>(propertyAsDouble);
322 if (propertyAsDouble == propertyAsUInt32) {
323 putByVal<strict>(exec, baseValue, propertyAsUInt32, value);
328 if (isName(property)) {
329 PutPropertySlot slot(strict);
330 baseValue.put(exec, jsCast<NameInstance*>(property.asCell())->privateName(), value, slot);
334 // Don't put to an object if toString throws an exception.
335 Identifier ident(exec, property.toString(exec)->value(exec));
336 if (!vm->exception) {
337 PutPropertySlot slot(strict);
338 baseValue.put(exec, ident, value, slot);
344 EncodedJSValue DFG_OPERATION operationConvertThis(ExecState* exec, EncodedJSValue encodedOp)
346 VM* vm = &exec->vm();
347 NativeCallFrameTracer tracer(vm, exec);
349 return JSValue::encode(JSValue::decode(encodedOp).toThisObject(exec));
352 JSCell* DFG_OPERATION operationCreateThis(ExecState* exec, JSObject* constructor, int32_t inlineCapacity)
354 VM* vm = &exec->vm();
355 NativeCallFrameTracer tracer(vm, exec);
358 ConstructData constructData;
359 ASSERT(jsCast<JSFunction*>(constructor)->methodTable()->getConstructData(jsCast<JSFunction*>(constructor), constructData) == ConstructTypeJS);
362 return constructEmptyObject(exec, jsCast<JSFunction*>(constructor)->allocationProfile(exec, inlineCapacity)->structure());
365 JSCell* DFG_OPERATION operationNewObject(ExecState* exec, Structure* structure)
367 VM* vm = &exec->vm();
368 NativeCallFrameTracer tracer(vm, exec);
370 return constructEmptyObject(exec, structure);
373 EncodedJSValue DFG_OPERATION operationValueAdd(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
375 VM* vm = &exec->vm();
376 NativeCallFrameTracer tracer(vm, exec);
378 JSValue op1 = JSValue::decode(encodedOp1);
379 JSValue op2 = JSValue::decode(encodedOp2);
381 return JSValue::encode(jsAdd(exec, op1, op2));
384 EncodedJSValue DFG_OPERATION operationValueAddNotNumber(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
386 VM* vm = &exec->vm();
387 NativeCallFrameTracer tracer(vm, exec);
389 JSValue op1 = JSValue::decode(encodedOp1);
390 JSValue op2 = JSValue::decode(encodedOp2);
392 ASSERT(!op1.isNumber() || !op2.isNumber());
394 if (op1.isString() && !op2.isObject())
395 return JSValue::encode(jsString(exec, asString(op1), op2.toString(exec)));
397 return JSValue::encode(jsAddSlowCase(exec, op1, op2));
400 static inline EncodedJSValue getByVal(ExecState* exec, JSCell* base, uint32_t index)
403 NativeCallFrameTracer tracer(&vm, exec);
405 if (base->isObject()) {
406 JSObject* object = asObject(base);
407 if (object->canGetIndexQuickly(index))
408 return JSValue::encode(object->getIndexQuickly(index));
411 if (isJSString(base) && asString(base)->canGetIndex(index))
412 return JSValue::encode(asString(base)->getIndex(exec, index));
414 return JSValue::encode(JSValue(base).get(exec, index));
417 EncodedJSValue DFG_OPERATION operationGetByVal(ExecState* exec, EncodedJSValue encodedBase, EncodedJSValue encodedProperty)
419 VM* vm = &exec->vm();
420 NativeCallFrameTracer tracer(vm, exec);
422 JSValue baseValue = JSValue::decode(encodedBase);
423 JSValue property = JSValue::decode(encodedProperty);
425 if (LIKELY(baseValue.isCell())) {
426 JSCell* base = baseValue.asCell();
428 if (property.isUInt32()) {
429 return getByVal(exec, base, property.asUInt32());
430 } else if (property.isDouble()) {
431 double propertyAsDouble = property.asDouble();
432 uint32_t propertyAsUInt32 = static_cast<uint32_t>(propertyAsDouble);
433 if (propertyAsUInt32 == propertyAsDouble)
434 return getByVal(exec, base, propertyAsUInt32);
435 } else if (property.isString()) {
436 if (JSValue result = base->fastGetOwnProperty(exec, asString(property)->value(exec)))
437 return JSValue::encode(result);
441 if (isName(property))
442 return JSValue::encode(baseValue.get(exec, jsCast<NameInstance*>(property.asCell())->privateName()));
444 Identifier ident(exec, property.toString(exec)->value(exec));
445 return JSValue::encode(baseValue.get(exec, ident));
448 EncodedJSValue DFG_OPERATION operationGetByValCell(ExecState* exec, JSCell* base, EncodedJSValue encodedProperty)
450 VM* vm = &exec->vm();
451 NativeCallFrameTracer tracer(vm, exec);
453 JSValue property = JSValue::decode(encodedProperty);
455 if (property.isUInt32())
456 return getByVal(exec, base, property.asUInt32());
457 if (property.isDouble()) {
458 double propertyAsDouble = property.asDouble();
459 uint32_t propertyAsUInt32 = static_cast<uint32_t>(propertyAsDouble);
460 if (propertyAsUInt32 == propertyAsDouble)
461 return getByVal(exec, base, propertyAsUInt32);
462 } else if (property.isString()) {
463 if (JSValue result = base->fastGetOwnProperty(exec, asString(property)->value(exec)))
464 return JSValue::encode(result);
467 if (isName(property))
468 return JSValue::encode(JSValue(base).get(exec, jsCast<NameInstance*>(property.asCell())->privateName()));
470 Identifier ident(exec, property.toString(exec)->value(exec));
471 return JSValue::encode(JSValue(base).get(exec, ident));
474 EncodedJSValue DFG_OPERATION operationGetByValArrayInt(ExecState* exec, JSArray* base, int32_t index)
476 VM* vm = &exec->vm();
477 NativeCallFrameTracer tracer(vm, exec);
480 // Go the slowest way possible becase negative indices don't use indexed storage.
481 return JSValue::encode(JSValue(base).get(exec, Identifier::from(exec, index)));
484 // Use this since we know that the value is out of bounds.
485 return JSValue::encode(JSValue(base).get(exec, index));
488 EncodedJSValue DFG_OPERATION operationGetById(ExecState* exec, EncodedJSValue base, Identifier* propertyName)
490 VM* vm = &exec->vm();
491 NativeCallFrameTracer tracer(vm, exec);
493 JSValue baseValue = JSValue::decode(base);
494 PropertySlot slot(baseValue);
495 return JSValue::encode(baseValue.get(exec, *propertyName, slot));
498 J_FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJI(operationGetByIdBuildList);
499 EncodedJSValue DFG_OPERATION operationGetByIdBuildListWithReturnAddress(ExecState* exec, EncodedJSValue base, Identifier* propertyName, ReturnAddressPtr returnAddress)
501 VM* vm = &exec->vm();
502 NativeCallFrameTracer tracer(vm, exec);
504 StructureStubInfo& stubInfo = exec->codeBlock()->getStubInfo(returnAddress);
505 AccessType accessType = static_cast<AccessType>(stubInfo.accessType);
507 JSValue baseValue = JSValue::decode(base);
508 PropertySlot slot(baseValue);
509 JSValue result = baseValue.get(exec, *propertyName, slot);
511 if (accessType == static_cast<AccessType>(stubInfo.accessType))
512 dfgBuildGetByIDList(exec, baseValue, *propertyName, slot, stubInfo);
514 return JSValue::encode(result);
517 J_FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJI(operationGetByIdProtoBuildList);
518 EncodedJSValue DFG_OPERATION operationGetByIdProtoBuildListWithReturnAddress(ExecState* exec, EncodedJSValue base, Identifier* propertyName, ReturnAddressPtr returnAddress)
520 VM* vm = &exec->vm();
521 NativeCallFrameTracer tracer(vm, exec);
523 StructureStubInfo& stubInfo = exec->codeBlock()->getStubInfo(returnAddress);
524 AccessType accessType = static_cast<AccessType>(stubInfo.accessType);
526 JSValue baseValue = JSValue::decode(base);
527 PropertySlot slot(baseValue);
528 JSValue result = baseValue.get(exec, *propertyName, slot);
530 if (accessType == static_cast<AccessType>(stubInfo.accessType))
531 dfgBuildGetByIDProtoList(exec, baseValue, *propertyName, slot, stubInfo);
533 return JSValue::encode(result);
536 J_FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJI(operationGetByIdOptimize);
537 EncodedJSValue DFG_OPERATION operationGetByIdOptimizeWithReturnAddress(ExecState* exec, EncodedJSValue base, Identifier* propertyName, ReturnAddressPtr returnAddress)
539 VM* vm = &exec->vm();
540 NativeCallFrameTracer tracer(vm, exec);
542 StructureStubInfo& stubInfo = exec->codeBlock()->getStubInfo(returnAddress);
543 AccessType accessType = static_cast<AccessType>(stubInfo.accessType);
545 JSValue baseValue = JSValue::decode(base);
546 PropertySlot slot(baseValue);
547 JSValue result = baseValue.get(exec, *propertyName, slot);
549 if (accessType == static_cast<AccessType>(stubInfo.accessType)) {
551 dfgRepatchGetByID(exec, baseValue, *propertyName, slot, stubInfo);
553 stubInfo.seen = true;
556 return JSValue::encode(result);
559 EncodedJSValue DFG_OPERATION operationCallCustomGetter(ExecState* exec, JSCell* base, PropertySlot::GetValueFunc function, Identifier* ident)
561 VM* vm = &exec->vm();
562 NativeCallFrameTracer tracer(vm, exec);
564 return JSValue::encode(function(exec, asObject(base), *ident));
567 EncodedJSValue DFG_OPERATION operationCallGetter(ExecState* exec, JSCell* base, JSCell* value)
569 VM* vm = &exec->vm();
570 NativeCallFrameTracer tracer(vm, exec);
572 GetterSetter* getterSetter = asGetterSetter(value);
573 JSObject* getter = getterSetter->getter();
575 return JSValue::encode(jsUndefined());
577 CallType callType = getter->methodTable()->getCallData(getter, callData);
578 return JSValue::encode(call(exec, getter, callType, callData, asObject(base), ArgList()));
581 void DFG_OPERATION operationPutByValStrict(ExecState* exec, EncodedJSValue encodedBase, EncodedJSValue encodedProperty, EncodedJSValue encodedValue)
583 VM* vm = &exec->vm();
584 NativeCallFrameTracer tracer(vm, exec);
586 operationPutByValInternal<true>(exec, encodedBase, encodedProperty, encodedValue);
589 void DFG_OPERATION operationPutByValNonStrict(ExecState* exec, EncodedJSValue encodedBase, EncodedJSValue encodedProperty, EncodedJSValue encodedValue)
591 VM* vm = &exec->vm();
592 NativeCallFrameTracer tracer(vm, exec);
594 operationPutByValInternal<false>(exec, encodedBase, encodedProperty, encodedValue);
597 void DFG_OPERATION operationPutByValCellStrict(ExecState* exec, JSCell* cell, EncodedJSValue encodedProperty, EncodedJSValue encodedValue)
599 VM* vm = &exec->vm();
600 NativeCallFrameTracer tracer(vm, exec);
602 operationPutByValInternal<true>(exec, JSValue::encode(cell), encodedProperty, encodedValue);
605 void DFG_OPERATION operationPutByValCellNonStrict(ExecState* exec, JSCell* cell, EncodedJSValue encodedProperty, EncodedJSValue encodedValue)
607 VM* vm = &exec->vm();
608 NativeCallFrameTracer tracer(vm, exec);
610 operationPutByValInternal<false>(exec, JSValue::encode(cell), encodedProperty, encodedValue);
613 void DFG_OPERATION operationPutByValBeyondArrayBoundsStrict(ExecState* exec, JSObject* array, int32_t index, EncodedJSValue encodedValue)
615 VM* vm = &exec->vm();
616 NativeCallFrameTracer tracer(vm, exec);
619 array->putByIndexInline(exec, index, JSValue::decode(encodedValue), true);
623 PutPropertySlot slot(true);
624 array->methodTable()->put(
625 array, exec, Identifier::from(exec, index), JSValue::decode(encodedValue), slot);
628 void DFG_OPERATION operationPutByValBeyondArrayBoundsNonStrict(ExecState* exec, JSObject* array, int32_t index, EncodedJSValue encodedValue)
630 VM* vm = &exec->vm();
631 NativeCallFrameTracer tracer(vm, exec);
634 array->putByIndexInline(exec, index, JSValue::decode(encodedValue), false);
638 PutPropertySlot slot(false);
639 array->methodTable()->put(
640 array, exec, Identifier::from(exec, index), JSValue::decode(encodedValue), slot);
643 void DFG_OPERATION operationPutDoubleByValBeyondArrayBoundsStrict(ExecState* exec, JSObject* array, int32_t index, double value)
645 VM* vm = &exec->vm();
646 NativeCallFrameTracer tracer(vm, exec);
648 JSValue jsValue = JSValue(JSValue::EncodeAsDouble, value);
651 array->putByIndexInline(exec, index, jsValue, true);
655 PutPropertySlot slot(true);
656 array->methodTable()->put(
657 array, exec, Identifier::from(exec, index), jsValue, slot);
660 void DFG_OPERATION operationPutDoubleByValBeyondArrayBoundsNonStrict(ExecState* exec, JSObject* array, int32_t index, double value)
662 VM* vm = &exec->vm();
663 NativeCallFrameTracer tracer(vm, exec);
665 JSValue jsValue = JSValue(JSValue::EncodeAsDouble, value);
668 array->putByIndexInline(exec, index, jsValue, false);
672 PutPropertySlot slot(false);
673 array->methodTable()->put(
674 array, exec, Identifier::from(exec, index), jsValue, slot);
677 EncodedJSValue DFG_OPERATION operationArrayPush(ExecState* exec, EncodedJSValue encodedValue, JSArray* array)
679 VM* vm = &exec->vm();
680 NativeCallFrameTracer tracer(vm, exec);
682 array->push(exec, JSValue::decode(encodedValue));
683 return JSValue::encode(jsNumber(array->length()));
686 EncodedJSValue DFG_OPERATION operationArrayPushDouble(ExecState* exec, double value, JSArray* array)
688 VM* vm = &exec->vm();
689 NativeCallFrameTracer tracer(vm, exec);
691 array->push(exec, JSValue(JSValue::EncodeAsDouble, value));
692 return JSValue::encode(jsNumber(array->length()));
695 EncodedJSValue DFG_OPERATION operationArrayPop(ExecState* exec, JSArray* array)
697 VM* vm = &exec->vm();
698 NativeCallFrameTracer tracer(vm, exec);
700 return JSValue::encode(array->pop(exec));
703 EncodedJSValue DFG_OPERATION operationArrayPopAndRecoverLength(ExecState* exec, JSArray* array)
705 VM* vm = &exec->vm();
706 NativeCallFrameTracer tracer(vm, exec);
708 array->butterfly()->setPublicLength(array->butterfly()->publicLength() + 1);
710 return JSValue::encode(array->pop(exec));
713 EncodedJSValue DFG_OPERATION operationRegExpExec(ExecState* exec, JSCell* base, JSCell* argument)
716 NativeCallFrameTracer tracer(&vm, exec);
718 if (!base->inherits(&RegExpObject::s_info))
719 return throwVMTypeError(exec);
721 ASSERT(argument->isString() || argument->isObject());
722 JSString* input = argument->isString() ? asString(argument) : asObject(argument)->toString(exec);
723 return JSValue::encode(asRegExpObject(base)->exec(exec, input));
726 size_t DFG_OPERATION operationRegExpTest(ExecState* exec, JSCell* base, JSCell* argument)
729 NativeCallFrameTracer tracer(&vm, exec);
731 if (!base->inherits(&RegExpObject::s_info)) {
732 throwTypeError(exec);
736 ASSERT(argument->isString() || argument->isObject());
737 JSString* input = argument->isString() ? asString(argument) : asObject(argument)->toString(exec);
738 return asRegExpObject(base)->test(exec, input);
741 void DFG_OPERATION operationPutByIdStrict(ExecState* exec, EncodedJSValue encodedValue, JSCell* base, Identifier* propertyName)
743 VM* vm = &exec->vm();
744 NativeCallFrameTracer tracer(vm, exec);
746 PutPropertySlot slot(true);
747 base->methodTable()->put(base, exec, *propertyName, JSValue::decode(encodedValue), slot);
750 void DFG_OPERATION operationPutByIdNonStrict(ExecState* exec, EncodedJSValue encodedValue, JSCell* base, Identifier* propertyName)
752 VM* vm = &exec->vm();
753 NativeCallFrameTracer tracer(vm, exec);
755 PutPropertySlot slot(false);
756 base->methodTable()->put(base, exec, *propertyName, JSValue::decode(encodedValue), slot);
759 void DFG_OPERATION operationPutByIdDirectStrict(ExecState* exec, EncodedJSValue encodedValue, JSCell* base, Identifier* propertyName)
761 VM* vm = &exec->vm();
762 NativeCallFrameTracer tracer(vm, exec);
764 PutPropertySlot slot(true);
765 ASSERT(base->isObject());
766 asObject(base)->putDirect(exec->vm(), *propertyName, JSValue::decode(encodedValue), slot);
769 void DFG_OPERATION operationPutByIdDirectNonStrict(ExecState* exec, EncodedJSValue encodedValue, JSCell* base, Identifier* propertyName)
771 VM* vm = &exec->vm();
772 NativeCallFrameTracer tracer(vm, exec);
774 PutPropertySlot slot(false);
775 ASSERT(base->isObject());
776 asObject(base)->putDirect(exec->vm(), *propertyName, JSValue::decode(encodedValue), slot);
779 V_FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJCI(operationPutByIdStrictOptimize);
780 void DFG_OPERATION operationPutByIdStrictOptimizeWithReturnAddress(ExecState* exec, EncodedJSValue encodedValue, JSCell* base, Identifier* propertyName, ReturnAddressPtr returnAddress)
782 VM* vm = &exec->vm();
783 NativeCallFrameTracer tracer(vm, exec);
785 StructureStubInfo& stubInfo = exec->codeBlock()->getStubInfo(returnAddress);
786 AccessType accessType = static_cast<AccessType>(stubInfo.accessType);
788 JSValue value = JSValue::decode(encodedValue);
789 JSValue baseValue(base);
790 PutPropertySlot slot(true);
792 baseValue.put(exec, *propertyName, value, slot);
794 if (accessType != static_cast<AccessType>(stubInfo.accessType))
798 dfgRepatchPutByID(exec, baseValue, *propertyName, slot, stubInfo, NotDirect);
800 stubInfo.seen = true;
803 V_FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJCI(operationPutByIdNonStrictOptimize);
804 void DFG_OPERATION operationPutByIdNonStrictOptimizeWithReturnAddress(ExecState* exec, EncodedJSValue encodedValue, JSCell* base, Identifier* propertyName, ReturnAddressPtr returnAddress)
806 VM* vm = &exec->vm();
807 NativeCallFrameTracer tracer(vm, exec);
809 StructureStubInfo& stubInfo = exec->codeBlock()->getStubInfo(returnAddress);
810 AccessType accessType = static_cast<AccessType>(stubInfo.accessType);
812 JSValue value = JSValue::decode(encodedValue);
813 JSValue baseValue(base);
814 PutPropertySlot slot(false);
816 baseValue.put(exec, *propertyName, value, slot);
818 if (accessType != static_cast<AccessType>(stubInfo.accessType))
822 dfgRepatchPutByID(exec, baseValue, *propertyName, slot, stubInfo, NotDirect);
824 stubInfo.seen = true;
827 V_FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJCI(operationPutByIdDirectStrictOptimize);
828 void DFG_OPERATION operationPutByIdDirectStrictOptimizeWithReturnAddress(ExecState* exec, EncodedJSValue encodedValue, JSCell* base, Identifier* propertyName, ReturnAddressPtr returnAddress)
830 VM* vm = &exec->vm();
831 NativeCallFrameTracer tracer(vm, exec);
833 StructureStubInfo& stubInfo = exec->codeBlock()->getStubInfo(returnAddress);
834 AccessType accessType = static_cast<AccessType>(stubInfo.accessType);
836 JSValue value = JSValue::decode(encodedValue);
837 PutPropertySlot slot(true);
839 ASSERT(base->isObject());
840 asObject(base)->putDirect(exec->vm(), *propertyName, value, slot);
842 if (accessType != static_cast<AccessType>(stubInfo.accessType))
846 dfgRepatchPutByID(exec, base, *propertyName, slot, stubInfo, Direct);
848 stubInfo.seen = true;
851 V_FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJCI(operationPutByIdDirectNonStrictOptimize);
852 void DFG_OPERATION operationPutByIdDirectNonStrictOptimizeWithReturnAddress(ExecState* exec, EncodedJSValue encodedValue, JSCell* base, Identifier* propertyName, ReturnAddressPtr returnAddress)
854 VM* vm = &exec->vm();
855 NativeCallFrameTracer tracer(vm, exec);
857 StructureStubInfo& stubInfo = exec->codeBlock()->getStubInfo(returnAddress);
858 AccessType accessType = static_cast<AccessType>(stubInfo.accessType);
860 JSValue value = JSValue::decode(encodedValue);
861 PutPropertySlot slot(false);
863 ASSERT(base->isObject());
864 asObject(base)->putDirect(exec->vm(), *propertyName, value, slot);
866 if (accessType != static_cast<AccessType>(stubInfo.accessType))
870 dfgRepatchPutByID(exec, base, *propertyName, slot, stubInfo, Direct);
872 stubInfo.seen = true;
875 V_FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJCI(operationPutByIdStrictBuildList);
876 void DFG_OPERATION operationPutByIdStrictBuildListWithReturnAddress(ExecState* exec, EncodedJSValue encodedValue, JSCell* base, Identifier* propertyName, ReturnAddressPtr returnAddress)
878 VM* vm = &exec->vm();
879 NativeCallFrameTracer tracer(vm, exec);
881 StructureStubInfo& stubInfo = exec->codeBlock()->getStubInfo(returnAddress);
882 AccessType accessType = static_cast<AccessType>(stubInfo.accessType);
884 JSValue value = JSValue::decode(encodedValue);
885 JSValue baseValue(base);
886 PutPropertySlot slot(true);
888 baseValue.put(exec, *propertyName, value, slot);
890 if (accessType != static_cast<AccessType>(stubInfo.accessType))
893 dfgBuildPutByIdList(exec, baseValue, *propertyName, slot, stubInfo, NotDirect);
896 V_FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJCI(operationPutByIdNonStrictBuildList);
897 void DFG_OPERATION operationPutByIdNonStrictBuildListWithReturnAddress(ExecState* exec, EncodedJSValue encodedValue, JSCell* base, Identifier* propertyName, ReturnAddressPtr returnAddress)
899 VM* vm = &exec->vm();
900 NativeCallFrameTracer tracer(vm, exec);
902 StructureStubInfo& stubInfo = exec->codeBlock()->getStubInfo(returnAddress);
903 AccessType accessType = static_cast<AccessType>(stubInfo.accessType);
905 JSValue value = JSValue::decode(encodedValue);
906 JSValue baseValue(base);
907 PutPropertySlot slot(false);
909 baseValue.put(exec, *propertyName, value, slot);
911 if (accessType != static_cast<AccessType>(stubInfo.accessType))
914 dfgBuildPutByIdList(exec, baseValue, *propertyName, slot, stubInfo, NotDirect);
917 V_FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJCI(operationPutByIdDirectStrictBuildList);
918 void DFG_OPERATION operationPutByIdDirectStrictBuildListWithReturnAddress(ExecState* exec, EncodedJSValue encodedValue, JSCell* base, Identifier* propertyName, ReturnAddressPtr returnAddress)
920 VM* vm = &exec->vm();
921 NativeCallFrameTracer tracer(vm, exec);
923 StructureStubInfo& stubInfo = exec->codeBlock()->getStubInfo(returnAddress);
924 AccessType accessType = static_cast<AccessType>(stubInfo.accessType);
926 JSValue value = JSValue::decode(encodedValue);
927 PutPropertySlot slot(true);
929 ASSERT(base->isObject());
930 asObject(base)->putDirect(exec->vm(), *propertyName, value, slot);
932 if (accessType != static_cast<AccessType>(stubInfo.accessType))
935 dfgBuildPutByIdList(exec, base, *propertyName, slot, stubInfo, Direct);
938 V_FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJCI(operationPutByIdDirectNonStrictBuildList);
939 void DFG_OPERATION operationPutByIdDirectNonStrictBuildListWithReturnAddress(ExecState* exec, EncodedJSValue encodedValue, JSCell* base, Identifier* propertyName, ReturnAddressPtr returnAddress)
941 VM* vm = &exec->vm();
942 NativeCallFrameTracer tracer(vm, exec);
944 StructureStubInfo& stubInfo = exec->codeBlock()->getStubInfo(returnAddress);
945 AccessType accessType = static_cast<AccessType>(stubInfo.accessType);
947 JSValue value = JSValue::decode(encodedValue);
948 PutPropertySlot slot(false);
950 ASSERT(base->isObject());
951 asObject(base)->putDirect(exec->vm(), *propertyName, value, slot);
953 if (accessType != static_cast<AccessType>(stubInfo.accessType))
956 dfgBuildPutByIdList(exec, base, *propertyName, slot, stubInfo, Direct);
959 size_t DFG_OPERATION operationCompareLess(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
961 VM* vm = &exec->vm();
962 NativeCallFrameTracer tracer(vm, exec);
964 return jsLess<true>(exec, JSValue::decode(encodedOp1), JSValue::decode(encodedOp2));
967 size_t DFG_OPERATION operationCompareLessEq(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
969 VM* vm = &exec->vm();
970 NativeCallFrameTracer tracer(vm, exec);
972 return jsLessEq<true>(exec, JSValue::decode(encodedOp1), JSValue::decode(encodedOp2));
975 size_t DFG_OPERATION operationCompareGreater(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
977 VM* vm = &exec->vm();
978 NativeCallFrameTracer tracer(vm, exec);
980 return jsLess<false>(exec, JSValue::decode(encodedOp2), JSValue::decode(encodedOp1));
983 size_t DFG_OPERATION operationCompareGreaterEq(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
985 VM* vm = &exec->vm();
986 NativeCallFrameTracer tracer(vm, exec);
988 return jsLessEq<false>(exec, JSValue::decode(encodedOp2), JSValue::decode(encodedOp1));
991 size_t DFG_OPERATION operationCompareEq(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
993 VM* vm = &exec->vm();
994 NativeCallFrameTracer tracer(vm, exec);
996 return JSValue::equalSlowCaseInline(exec, JSValue::decode(encodedOp1), JSValue::decode(encodedOp2));
1000 EncodedJSValue DFG_OPERATION operationCompareStringEq(ExecState* exec, JSCell* left, JSCell* right)
1002 size_t DFG_OPERATION operationCompareStringEq(ExecState* exec, JSCell* left, JSCell* right)
1005 VM* vm = &exec->vm();
1006 NativeCallFrameTracer tracer(vm, exec);
1008 bool result = asString(left)->value(exec) == asString(right)->value(exec);
1010 return JSValue::encode(jsBoolean(result));
1016 size_t DFG_OPERATION operationCompareStrictEqCell(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
1018 VM* vm = &exec->vm();
1019 NativeCallFrameTracer tracer(vm, exec);
1021 JSValue op1 = JSValue::decode(encodedOp1);
1022 JSValue op2 = JSValue::decode(encodedOp2);
1024 ASSERT(op1.isCell());
1025 ASSERT(op2.isCell());
1027 return JSValue::strictEqualSlowCaseInline(exec, op1, op2);
1030 size_t DFG_OPERATION operationCompareStrictEq(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
1032 VM* vm = &exec->vm();
1033 NativeCallFrameTracer tracer(vm, exec);
1035 JSValue src1 = JSValue::decode(encodedOp1);
1036 JSValue src2 = JSValue::decode(encodedOp2);
1038 return JSValue::strictEqual(exec, src1, src2);
1041 static void* handleHostCall(ExecState* execCallee, JSValue callee, CodeSpecializationKind kind)
1043 ExecState* exec = execCallee->callerFrame();
1044 VM* vm = &exec->vm();
1046 execCallee->setScope(exec->scope());
1047 execCallee->setCodeBlock(0);
1049 if (kind == CodeForCall) {
1051 CallType callType = getCallData(callee, callData);
1053 ASSERT(callType != CallTypeJS);
1055 if (callType == CallTypeHost) {
1056 NativeCallFrameTracer tracer(vm, execCallee);
1057 execCallee->setCallee(asObject(callee));
1058 vm->hostCallReturnValue = JSValue::decode(callData.native.function(execCallee));
1060 return vm->getCTIStub(throwExceptionFromCallSlowPathGenerator).code().executableAddress();
1062 return reinterpret_cast<void*>(getHostCallReturnValue);
1065 ASSERT(callType == CallTypeNone);
1066 exec->vm().exception = createNotAFunctionError(exec, callee);
1067 return vm->getCTIStub(throwExceptionFromCallSlowPathGenerator).code().executableAddress();
1070 ASSERT(kind == CodeForConstruct);
1072 ConstructData constructData;
1073 ConstructType constructType = getConstructData(callee, constructData);
1075 ASSERT(constructType != ConstructTypeJS);
1077 if (constructType == ConstructTypeHost) {
1078 NativeCallFrameTracer tracer(vm, execCallee);
1079 execCallee->setCallee(asObject(callee));
1080 vm->hostCallReturnValue = JSValue::decode(constructData.native.function(execCallee));
1082 return vm->getCTIStub(throwExceptionFromCallSlowPathGenerator).code().executableAddress();
1084 return reinterpret_cast<void*>(getHostCallReturnValue);
1087 ASSERT(constructType == ConstructTypeNone);
1088 exec->vm().exception = createNotAConstructorError(exec, callee);
1089 return vm->getCTIStub(throwExceptionFromCallSlowPathGenerator).code().executableAddress();
1092 inline char* linkFor(ExecState* execCallee, CodeSpecializationKind kind)
1094 ExecState* exec = execCallee->callerFrame();
1095 VM* vm = &exec->vm();
1096 NativeCallFrameTracer tracer(vm, exec);
1098 JSValue calleeAsValue = execCallee->calleeAsValue();
1099 JSCell* calleeAsFunctionCell = getJSFunction(calleeAsValue);
1100 if (!calleeAsFunctionCell)
1101 return reinterpret_cast<char*>(handleHostCall(execCallee, calleeAsValue, kind));
1103 JSFunction* callee = jsCast<JSFunction*>(calleeAsFunctionCell);
1104 execCallee->setScope(callee->scopeUnchecked());
1105 ExecutableBase* executable = callee->executable();
1107 MacroAssemblerCodePtr codePtr;
1108 CodeBlock* codeBlock = 0;
1109 if (executable->isHostFunction())
1110 codePtr = executable->generatedJITCodeFor(kind).addressForCall();
1112 FunctionExecutable* functionExecutable = static_cast<FunctionExecutable*>(executable);
1113 JSObject* error = functionExecutable->compileFor(execCallee, callee->scope(), kind);
1115 vm->exception = createStackOverflowError(exec);
1116 return reinterpret_cast<char*>(vm->getCTIStub(throwExceptionFromCallSlowPathGenerator).code().executableAddress());
1118 codeBlock = &functionExecutable->generatedBytecodeFor(kind);
1119 if (execCallee->argumentCountIncludingThis() < static_cast<size_t>(codeBlock->numParameters()))
1120 codePtr = functionExecutable->generatedJITCodeWithArityCheckFor(kind);
1122 codePtr = functionExecutable->generatedJITCodeFor(kind).addressForCall();
1124 CallLinkInfo& callLinkInfo = exec->codeBlock()->getCallLinkInfo(execCallee->returnPC());
1125 if (!callLinkInfo.seenOnce())
1126 callLinkInfo.setSeen();
1128 dfgLinkFor(execCallee, callLinkInfo, codeBlock, callee, codePtr, kind);
1129 return reinterpret_cast<char*>(codePtr.executableAddress());
1132 char* DFG_OPERATION operationLinkCall(ExecState* execCallee)
1134 return linkFor(execCallee, CodeForCall);
1137 char* DFG_OPERATION operationLinkConstruct(ExecState* execCallee)
1139 return linkFor(execCallee, CodeForConstruct);
1142 inline char* virtualForWithFunction(ExecState* execCallee, CodeSpecializationKind kind, JSCell*& calleeAsFunctionCell)
1144 ExecState* exec = execCallee->callerFrame();
1145 VM* vm = &exec->vm();
1146 NativeCallFrameTracer tracer(vm, exec);
1148 JSValue calleeAsValue = execCallee->calleeAsValue();
1149 calleeAsFunctionCell = getJSFunction(calleeAsValue);
1150 if (UNLIKELY(!calleeAsFunctionCell))
1151 return reinterpret_cast<char*>(handleHostCall(execCallee, calleeAsValue, kind));
1153 JSFunction* function = jsCast<JSFunction*>(calleeAsFunctionCell);
1154 execCallee->setScope(function->scopeUnchecked());
1155 ExecutableBase* executable = function->executable();
1156 if (UNLIKELY(!executable->hasJITCodeFor(kind))) {
1157 FunctionExecutable* functionExecutable = static_cast<FunctionExecutable*>(executable);
1158 JSObject* error = functionExecutable->compileFor(execCallee, function->scope(), kind);
1160 exec->vm().exception = error;
1161 return reinterpret_cast<char*>(vm->getCTIStub(throwExceptionFromCallSlowPathGenerator).code().executableAddress());
1164 return reinterpret_cast<char*>(executable->generatedJITCodeWithArityCheckFor(kind).executableAddress());
1167 inline char* virtualFor(ExecState* execCallee, CodeSpecializationKind kind)
1169 JSCell* calleeAsFunctionCellIgnored;
1170 return virtualForWithFunction(execCallee, kind, calleeAsFunctionCellIgnored);
1173 static bool attemptToOptimizeClosureCall(ExecState* execCallee, JSCell* calleeAsFunctionCell, CallLinkInfo& callLinkInfo)
1175 if (!calleeAsFunctionCell)
1178 JSFunction* callee = jsCast<JSFunction*>(calleeAsFunctionCell);
1179 JSFunction* oldCallee = callLinkInfo.callee.get();
1182 || oldCallee->structure() != callee->structure()
1183 || oldCallee->executable() != callee->executable())
1186 ASSERT(callee->executable()->hasJITCodeForCall());
1187 MacroAssemblerCodePtr codePtr = callee->executable()->generatedJITCodeForCall().addressForCall();
1189 CodeBlock* codeBlock;
1190 if (callee->executable()->isHostFunction())
1193 codeBlock = &jsCast<FunctionExecutable*>(callee->executable())->generatedBytecodeForCall();
1194 if (execCallee->argumentCountIncludingThis() < static_cast<size_t>(codeBlock->numParameters()))
1199 execCallee, callLinkInfo, codeBlock,
1200 callee->structure(), callee->executable(), codePtr);
1205 char* DFG_OPERATION operationLinkClosureCall(ExecState* execCallee)
1207 JSCell* calleeAsFunctionCell;
1208 char* result = virtualForWithFunction(execCallee, CodeForCall, calleeAsFunctionCell);
1209 CallLinkInfo& callLinkInfo = execCallee->callerFrame()->codeBlock()->getCallLinkInfo(execCallee->returnPC());
1211 if (!attemptToOptimizeClosureCall(execCallee, calleeAsFunctionCell, callLinkInfo))
1212 dfgLinkSlowFor(execCallee, callLinkInfo, CodeForCall);
1217 char* DFG_OPERATION operationVirtualCall(ExecState* execCallee)
1219 return virtualFor(execCallee, CodeForCall);
1222 char* DFG_OPERATION operationVirtualConstruct(ExecState* execCallee)
1224 return virtualFor(execCallee, CodeForConstruct);
1227 void DFG_OPERATION operationNotifyGlobalVarWrite(WatchpointSet* watchpointSet)
1229 watchpointSet->notifyWrite();
1232 EncodedJSValue DFG_OPERATION operationResolve(ExecState* exec, Identifier* propertyName, ResolveOperations* operations)
1234 VM* vm = &exec->vm();
1235 NativeCallFrameTracer tracer(vm, exec);
1236 return JSValue::encode(JSScope::resolve(exec, *propertyName, operations));
1239 EncodedJSValue DFG_OPERATION operationResolveBase(ExecState* exec, Identifier* propertyName, ResolveOperations* operations, PutToBaseOperation* putToBaseOperations)
1241 VM* vm = &exec->vm();
1242 NativeCallFrameTracer tracer(vm, exec);
1244 return JSValue::encode(JSScope::resolveBase(exec, *propertyName, false, operations, putToBaseOperations));
1247 EncodedJSValue DFG_OPERATION operationResolveBaseStrictPut(ExecState* exec, Identifier* propertyName, ResolveOperations* operations, PutToBaseOperation* putToBaseOperations)
1249 VM* vm = &exec->vm();
1250 NativeCallFrameTracer tracer(vm, exec);
1252 return JSValue::encode(JSScope::resolveBase(exec, *propertyName, true, operations, putToBaseOperations));
1255 EncodedJSValue DFG_OPERATION operationResolveGlobal(ExecState* exec, ResolveOperation* resolveOperation, JSGlobalObject* globalObject, Identifier* propertyName)
1257 VM* vm = &exec->vm();
1258 NativeCallFrameTracer tracer(vm, exec);
1259 ASSERT(globalObject);
1260 UNUSED_PARAM(resolveOperation);
1261 UNUSED_PARAM(globalObject);
1262 ASSERT(resolveOperation->m_operation == ResolveOperation::GetAndReturnGlobalProperty);
1263 return JSValue::encode(JSScope::resolveGlobal(exec, *propertyName, globalObject, resolveOperation));
1266 EncodedJSValue DFG_OPERATION operationToPrimitive(ExecState* exec, EncodedJSValue value)
1268 VM* vm = &exec->vm();
1269 NativeCallFrameTracer tracer(vm, exec);
1271 return JSValue::encode(JSValue::decode(value).toPrimitive(exec));
1274 char* DFG_OPERATION operationNewArray(ExecState* exec, Structure* arrayStructure, void* buffer, size_t size)
1276 VM* vm = &exec->vm();
1277 NativeCallFrameTracer tracer(vm, exec);
1279 return bitwise_cast<char*>(constructArray(exec, arrayStructure, static_cast<JSValue*>(buffer), size));
1282 char* DFG_OPERATION operationNewEmptyArray(ExecState* exec, Structure* arrayStructure)
1284 VM* vm = &exec->vm();
1285 NativeCallFrameTracer tracer(vm, exec);
1287 return bitwise_cast<char*>(JSArray::create(*vm, arrayStructure));
1290 char* DFG_OPERATION operationNewArrayWithSize(ExecState* exec, Structure* arrayStructure, int32_t size)
1292 VM* vm = &exec->vm();
1293 NativeCallFrameTracer tracer(vm, exec);
1295 if (UNLIKELY(size < 0))
1296 return bitwise_cast<char*>(throwError(exec, createRangeError(exec, ASCIILiteral("Array size is not a small enough positive integer."))));
1298 return bitwise_cast<char*>(JSArray::create(*vm, arrayStructure, size));
1301 char* DFG_OPERATION operationNewArrayBuffer(ExecState* exec, Structure* arrayStructure, size_t start, size_t size)
1303 VM& vm = exec->vm();
1304 NativeCallFrameTracer tracer(&vm, exec);
1305 return bitwise_cast<char*>(constructArray(exec, arrayStructure, exec->codeBlock()->constantBuffer(start), size));
1308 EncodedJSValue DFG_OPERATION operationNewRegexp(ExecState* exec, void* regexpPtr)
1310 VM& vm = exec->vm();
1311 NativeCallFrameTracer tracer(&vm, exec);
1312 RegExp* regexp = static_cast<RegExp*>(regexpPtr);
1313 if (!regexp->isValid()) {
1314 throwError(exec, createSyntaxError(exec, "Invalid flags supplied to RegExp constructor."));
1315 return JSValue::encode(jsUndefined());
1318 return JSValue::encode(RegExpObject::create(exec->vm(), exec->lexicalGlobalObject(), exec->lexicalGlobalObject()->regExpStructure(), regexp));
1321 JSCell* DFG_OPERATION operationCreateActivation(ExecState* exec)
1323 VM& vm = exec->vm();
1324 NativeCallFrameTracer tracer(&vm, exec);
1325 JSActivation* activation = JSActivation::create(vm, exec, exec->codeBlock());
1326 exec->setScope(activation);
1330 JSCell* DFG_OPERATION operationCreateArguments(ExecState* exec)
1332 VM& vm = exec->vm();
1333 NativeCallFrameTracer tracer(&vm, exec);
1334 // NB: This needs to be exceedingly careful with top call frame tracking, since it
1335 // may be called from OSR exit, while the state of the call stack is bizarre.
1336 Arguments* result = Arguments::create(vm, exec);
1337 ASSERT(!vm.exception);
1341 JSCell* DFG_OPERATION operationCreateInlinedArguments(
1342 ExecState* exec, InlineCallFrame* inlineCallFrame)
1344 VM& vm = exec->vm();
1345 NativeCallFrameTracer tracer(&vm, exec);
1346 // NB: This needs to be exceedingly careful with top call frame tracking, since it
1347 // may be called from OSR exit, while the state of the call stack is bizarre.
1348 Arguments* result = Arguments::create(vm, exec, inlineCallFrame);
1349 ASSERT(!vm.exception);
1353 void DFG_OPERATION operationTearOffArguments(ExecState* exec, JSCell* argumentsCell, JSCell* activationCell)
1355 ASSERT(exec->codeBlock()->usesArguments());
1356 if (activationCell) {
1357 jsCast<Arguments*>(argumentsCell)->didTearOffActivation(exec, jsCast<JSActivation*>(activationCell));
1360 jsCast<Arguments*>(argumentsCell)->tearOff(exec);
1363 void DFG_OPERATION operationTearOffInlinedArguments(
1364 ExecState* exec, JSCell* argumentsCell, JSCell* activationCell, InlineCallFrame* inlineCallFrame)
1366 ASSERT_UNUSED(activationCell, !activationCell); // Currently, we don't inline functions with activations.
1367 jsCast<Arguments*>(argumentsCell)->tearOff(exec, inlineCallFrame);
1370 EncodedJSValue DFG_OPERATION operationGetArgumentsLength(ExecState* exec, int32_t argumentsRegister)
1372 VM& vm = exec->vm();
1373 NativeCallFrameTracer tracer(&vm, exec);
1374 // Here we can assume that the argumernts were created. Because otherwise the JIT code would
1375 // have not made this call.
1376 Identifier ident(&vm, "length");
1377 JSValue baseValue = exec->uncheckedR(argumentsRegister).jsValue();
1378 PropertySlot slot(baseValue);
1379 return JSValue::encode(baseValue.get(exec, ident, slot));
1382 EncodedJSValue DFG_OPERATION operationGetArgumentByVal(ExecState* exec, int32_t argumentsRegister, int32_t index)
1384 VM& vm = exec->vm();
1385 NativeCallFrameTracer tracer(&vm, exec);
1387 JSValue argumentsValue = exec->uncheckedR(argumentsRegister).jsValue();
1389 // If there are no arguments, and we're accessing out of bounds, then we have to create the
1390 // arguments in case someone has installed a getter on a numeric property.
1391 if (!argumentsValue)
1392 exec->uncheckedR(argumentsRegister) = argumentsValue = Arguments::create(exec->vm(), exec);
1394 return JSValue::encode(argumentsValue.get(exec, index));
1397 EncodedJSValue DFG_OPERATION operationGetInlinedArgumentByVal(
1398 ExecState* exec, int32_t argumentsRegister, InlineCallFrame* inlineCallFrame, int32_t index)
1400 VM& vm = exec->vm();
1401 NativeCallFrameTracer tracer(&vm, exec);
1403 JSValue argumentsValue = exec->uncheckedR(argumentsRegister).jsValue();
1405 // If there are no arguments, and we're accessing out of bounds, then we have to create the
1406 // arguments in case someone has installed a getter on a numeric property.
1407 if (!argumentsValue) {
1408 exec->uncheckedR(argumentsRegister) = argumentsValue =
1409 Arguments::create(exec->vm(), exec, inlineCallFrame);
1412 return JSValue::encode(argumentsValue.get(exec, index));
1415 JSCell* DFG_OPERATION operationNewFunction(ExecState* exec, JSCell* functionExecutable)
1417 ASSERT(functionExecutable->inherits(&FunctionExecutable::s_info));
1418 VM& vm = exec->vm();
1419 NativeCallFrameTracer tracer(&vm, exec);
1420 return JSFunction::create(exec, static_cast<FunctionExecutable*>(functionExecutable), exec->scope());
1423 JSCell* DFG_OPERATION operationNewFunctionExpression(ExecState* exec, JSCell* functionExecutableAsCell)
1425 ASSERT(functionExecutableAsCell->inherits(&FunctionExecutable::s_info));
1427 VM& vm = exec->vm();
1428 NativeCallFrameTracer tracer(&vm, exec);
1430 FunctionExecutable* functionExecutable =
1431 static_cast<FunctionExecutable*>(functionExecutableAsCell);
1432 return JSFunction::create(exec, functionExecutable, exec->scope());
1435 size_t DFG_OPERATION operationIsObject(ExecState* exec, EncodedJSValue value)
1437 return jsIsObjectType(exec, JSValue::decode(value));
1440 size_t DFG_OPERATION operationIsFunction(EncodedJSValue value)
1442 return jsIsFunctionType(JSValue::decode(value));
1445 JSCell* DFG_OPERATION operationTypeOf(ExecState* exec, JSCell* value)
1447 return jsTypeStringForValue(exec, JSValue(value)).asCell();
1450 void DFG_OPERATION operationReallocateStorageAndFinishPut(ExecState* exec, JSObject* base, Structure* structure, PropertyOffset offset, EncodedJSValue value)
1452 VM& vm = exec->vm();
1453 NativeCallFrameTracer tracer(&vm, exec);
1455 ASSERT(structure->outOfLineCapacity() > base->structure()->outOfLineCapacity());
1456 ASSERT(!vm.heap.storageAllocator().fastPathShouldSucceed(structure->outOfLineCapacity() * sizeof(JSValue)));
1457 base->setStructureAndReallocateStorageIfNecessary(vm, structure);
1458 base->putDirect(vm, offset, JSValue::decode(value));
1461 char* DFG_OPERATION operationAllocatePropertyStorageWithInitialCapacity(ExecState* exec)
1463 VM& vm = exec->vm();
1464 NativeCallFrameTracer tracer(&vm, exec);
1466 return reinterpret_cast<char*>(
1467 Butterfly::createUninitialized(vm, 0, initialOutOfLineCapacity, false, 0));
1470 char* DFG_OPERATION operationAllocatePropertyStorage(ExecState* exec, size_t newSize)
1472 VM& vm = exec->vm();
1473 NativeCallFrameTracer tracer(&vm, exec);
1475 return reinterpret_cast<char*>(
1476 Butterfly::createUninitialized(vm, 0, newSize, false, 0));
1479 char* DFG_OPERATION operationReallocateButterflyToHavePropertyStorageWithInitialCapacity(ExecState* exec, JSObject* object)
1481 VM& vm = exec->vm();
1482 NativeCallFrameTracer tracer(&vm, exec);
1484 ASSERT(!object->structure()->outOfLineCapacity());
1485 Butterfly* result = object->growOutOfLineStorage(vm, 0, initialOutOfLineCapacity);
1486 object->setButterflyWithoutChangingStructure(result);
1487 return reinterpret_cast<char*>(result);
1490 char* DFG_OPERATION operationReallocateButterflyToGrowPropertyStorage(ExecState* exec, JSObject* object, size_t newSize)
1492 VM& vm = exec->vm();
1493 NativeCallFrameTracer tracer(&vm, exec);
1495 Butterfly* result = object->growOutOfLineStorage(vm, object->structure()->outOfLineCapacity(), newSize);
1496 object->setButterflyWithoutChangingStructure(result);
1497 return reinterpret_cast<char*>(result);
1500 char* DFG_OPERATION operationEnsureInt32(ExecState* exec, JSCell* cell)
1502 VM& vm = exec->vm();
1503 NativeCallFrameTracer tracer(&vm, exec);
1505 if (!cell->isObject())
1508 return reinterpret_cast<char*>(asObject(cell)->ensureInt32(vm).data());
1511 char* DFG_OPERATION operationEnsureDouble(ExecState* exec, JSCell* cell)
1513 VM& vm = exec->vm();
1514 NativeCallFrameTracer tracer(&vm, exec);
1516 if (!cell->isObject())
1519 return reinterpret_cast<char*>(asObject(cell)->ensureDouble(vm).data());
1522 char* DFG_OPERATION operationEnsureContiguous(ExecState* exec, JSCell* cell)
1524 VM& vm = exec->vm();
1525 NativeCallFrameTracer tracer(&vm, exec);
1527 if (!cell->isObject())
1530 return reinterpret_cast<char*>(asObject(cell)->ensureContiguous(vm).data());
1533 char* DFG_OPERATION operationRageEnsureContiguous(ExecState* exec, JSCell* cell)
1535 VM& vm = exec->vm();
1536 NativeCallFrameTracer tracer(&vm, exec);
1538 if (!cell->isObject())
1541 return reinterpret_cast<char*>(asObject(cell)->rageEnsureContiguous(vm).data());
1544 char* DFG_OPERATION operationEnsureArrayStorage(ExecState* exec, JSCell* cell)
1546 VM& vm = exec->vm();
1547 NativeCallFrameTracer tracer(&vm, exec);
1549 if (!cell->isObject())
1552 return reinterpret_cast<char*>(asObject(cell)->ensureArrayStorage(vm));
1555 StringImpl* DFG_OPERATION operationResolveRope(ExecState* exec, JSString* string)
1557 VM& vm = exec->vm();
1558 NativeCallFrameTracer tracer(&vm, exec);
1560 return string->value(exec).impl();
1563 JSCell* DFG_OPERATION operationNewStringObject(ExecState* exec, JSString* string, Structure* structure)
1565 VM& vm = exec->vm();
1566 NativeCallFrameTracer tracer(&vm, exec);
1568 return StringObject::create(exec, structure, string);
1571 JSCell* DFG_OPERATION operationToStringOnCell(ExecState* exec, JSCell* cell)
1573 VM& vm = exec->vm();
1574 NativeCallFrameTracer tracer(&vm, exec);
1576 return JSValue(cell).toString(exec);
1579 JSCell* DFG_OPERATION operationToString(ExecState* exec, EncodedJSValue value)
1581 VM& vm = exec->vm();
1582 NativeCallFrameTracer tracer(&vm, exec);
1584 return JSValue::decode(value).toString(exec);
1587 JSCell* DFG_OPERATION operationMakeRope2(ExecState* exec, JSString* left, JSString* right)
1589 VM& vm = exec->vm();
1590 NativeCallFrameTracer tracer(&vm, exec);
1592 return JSRopeString::create(vm, left, right);
1595 JSCell* DFG_OPERATION operationMakeRope3(ExecState* exec, JSString* a, JSString* b, JSString* c)
1597 VM& vm = exec->vm();
1598 NativeCallFrameTracer tracer(&vm, exec);
1600 return JSRopeString::create(vm, a, b, c);
1603 double DFG_OPERATION operationFModOnInts(int32_t a, int32_t b)
1608 JSCell* DFG_OPERATION operationStringFromCharCode(ExecState* exec, int32_t op1)
1610 VM* vm = &exec->vm();
1611 NativeCallFrameTracer tracer(vm, exec);
1612 return JSC::stringFromCharCode(exec, op1);
1615 DFGHandlerEncoded DFG_OPERATION lookupExceptionHandler(ExecState* exec, uint32_t callIndex)
1617 VM* vm = &exec->vm();
1618 NativeCallFrameTracer tracer(vm, exec);
1620 JSValue exceptionValue = exec->exception();
1621 ASSERT(exceptionValue);
1623 unsigned vPCIndex = exec->codeBlock()->bytecodeOffsetForCallAtIndex(callIndex);
1624 ExceptionHandler handler = genericThrow(vm, exec, exceptionValue, vPCIndex);
1625 ASSERT(handler.catchRoutine);
1626 return dfgHandlerEncoded(handler.callFrame, handler.catchRoutine);
1629 DFGHandlerEncoded DFG_OPERATION lookupExceptionHandlerInStub(ExecState* exec, StructureStubInfo* stubInfo)
1631 VM* vm = &exec->vm();
1632 NativeCallFrameTracer tracer(vm, exec);
1634 JSValue exceptionValue = exec->exception();
1635 ASSERT(exceptionValue);
1637 CodeOrigin codeOrigin = stubInfo->codeOrigin;
1638 while (codeOrigin.inlineCallFrame)
1639 codeOrigin = codeOrigin.inlineCallFrame->caller;
1641 ExceptionHandler handler = genericThrow(vm, exec, exceptionValue, codeOrigin.bytecodeIndex);
1642 ASSERT(handler.catchRoutine);
1643 return dfgHandlerEncoded(handler.callFrame, handler.catchRoutine);
1646 size_t DFG_OPERATION dfgConvertJSValueToInt32(ExecState* exec, EncodedJSValue value)
1648 VM* vm = &exec->vm();
1649 NativeCallFrameTracer tracer(vm, exec);
1651 // toInt32/toUInt32 return the same value; we want the value zero extended to fill the register.
1652 return JSValue::decode(value).toUInt32(exec);
1655 size_t DFG_OPERATION dfgConvertJSValueToBoolean(ExecState* exec, EncodedJSValue encodedOp)
1657 VM* vm = &exec->vm();
1658 NativeCallFrameTracer tracer(vm, exec);
1660 return JSValue::decode(encodedOp).toBoolean(exec);
1663 void DFG_OPERATION debugOperationPrintSpeculationFailure(ExecState* exec, void* debugInfoRaw, void* scratch)
1665 VM* vm = &exec->vm();
1666 NativeCallFrameTracer tracer(vm, exec);
1668 SpeculationFailureDebugInfo* debugInfo = static_cast<SpeculationFailureDebugInfo*>(debugInfoRaw);
1669 CodeBlock* codeBlock = debugInfo->codeBlock;
1670 CodeBlock* alternative = codeBlock->alternative();
1672 "Speculation failure in ", *codeBlock, " with ");
1675 "executeCounter = ", alternative->jitExecuteCounter(),
1676 ", reoptimizationRetryCounter = ", alternative->reoptimizationRetryCounter(),
1677 ", optimizationDelayCounter = ", alternative->optimizationDelayCounter());
1679 dataLog("no alternative code block (i.e. we've been jettisoned)");
1680 dataLog(", osrExitCounter = ", codeBlock->osrExitCounter(), "\n");
1681 dataLog(" GPRs at time of exit:");
1682 char* scratchPointer = static_cast<char*>(scratch);
1683 for (unsigned i = 0; i < GPRInfo::numberOfRegisters; ++i) {
1684 GPRReg gpr = GPRInfo::toRegister(i);
1685 dataLog(" ", GPRInfo::debugName(gpr), ":", RawPointer(*reinterpret_cast_ptr<void**>(scratchPointer)));
1686 scratchPointer += sizeof(EncodedJSValue);
1689 dataLog(" FPRs at time of exit:");
1690 for (unsigned i = 0; i < FPRInfo::numberOfRegisters; ++i) {
1691 FPRReg fpr = FPRInfo::toRegister(i);
1692 dataLog(" ", FPRInfo::debugName(fpr), ":");
1693 uint64_t bits = *reinterpret_cast_ptr<uint64_t*>(scratchPointer);
1694 double value = *reinterpret_cast_ptr<double*>(scratchPointer);
1695 dataLogF("%llx:%lf", static_cast<long long>(bits), value);
1696 scratchPointer += sizeof(EncodedJSValue);
1701 extern "C" void DFG_OPERATION triggerReoptimizationNow(CodeBlock* codeBlock)
1703 #if ENABLE(JIT_VERBOSE_OSR)
1704 dataLog(*codeBlock, ": Entered reoptimize\n");
1706 // We must be called with the baseline code block.
1707 ASSERT(JITCode::isBaselineCode(codeBlock->getJITType()));
1709 // If I am my own replacement, then reoptimization has already been triggered.
1710 // This can happen in recursive functions.
1711 if (codeBlock->replacement() == codeBlock)
1714 // Otherwise, the replacement must be optimized code. Use this as an opportunity
1715 // to check our logic.
1716 ASSERT(codeBlock->hasOptimizedReplacement());
1717 ASSERT(codeBlock->replacement()->getJITType() == JITCode::DFGJIT);
1719 codeBlock->reoptimize();
1723 } } // namespace JSC::DFG
1725 #endif // ENABLE(DFG_JIT)
1729 #if COMPILER(GCC) && CPU(X86_64)
1731 ".globl " SYMBOL_STRING(getHostCallReturnValue) "\n"
1732 HIDE_SYMBOL(getHostCallReturnValue) "\n"
1733 SYMBOL_STRING(getHostCallReturnValue) ":" "\n"
1734 "mov -40(%r13), %r13\n"
1736 "jmp " LOCAL_REFERENCE(getHostCallReturnValueWithExecState) "\n"
1738 #elif COMPILER(GCC) && CPU(X86)
1741 ".globl " SYMBOL_STRING(getHostCallReturnValue) "\n"
1742 HIDE_SYMBOL(getHostCallReturnValue) "\n"
1743 SYMBOL_STRING(getHostCallReturnValue) ":" "\n"
1744 "mov -40(%edi), %edi\n"
1745 "mov %edi, 4(%esp)\n"
1746 "jmp " LOCAL_REFERENCE(getHostCallReturnValueWithExecState) "\n"
1748 #elif COMPILER(GCC) && CPU(ARM_THUMB2)
1752 ".globl " SYMBOL_STRING(getHostCallReturnValue) "\n"
1753 HIDE_SYMBOL(getHostCallReturnValue) "\n"
1755 ".thumb_func " THUMB_FUNC_PARAM(getHostCallReturnValue) "\n"
1756 SYMBOL_STRING(getHostCallReturnValue) ":" "\n"
1757 "ldr r5, [r5, #-40]" "\n"
1759 "b " LOCAL_REFERENCE(getHostCallReturnValueWithExecState) "\n"
1761 #elif COMPILER(GCC) && CPU(ARM_TRADITIONAL)
1764 ".globl " SYMBOL_STRING(getHostCallReturnValue) "\n"
1765 HIDE_SYMBOL(getHostCallReturnValue) "\n"
1766 INLINE_ARM_FUNCTION(getHostCallReturnValue)
1767 SYMBOL_STRING(getHostCallReturnValue) ":" "\n"
1768 "ldr r5, [r5, #-40]" "\n"
1770 "b " LOCAL_REFERENCE(getHostCallReturnValueWithExecState) "\n"
1772 #elif COMPILER(GCC) && CPU(MIPS)
1775 ".globl " SYMBOL_STRING(getHostCallReturnValue) "\n"
1776 HIDE_SYMBOL(getHostCallReturnValue) "\n"
1777 SYMBOL_STRING(getHostCallReturnValue) ":" "\n"
1778 LOAD_FUNCTION_TO_T9(getHostCallReturnValueWithExecState)
1779 "lw $s0, -40($s0)" "\n"
1780 "move $a0, $s0" "\n"
1781 "b " LOCAL_REFERENCE(getHostCallReturnValueWithExecState) "\n"
1783 #elif COMPILER(GCC) && CPU(SH4)
1786 ".globl " SYMBOL_STRING(getHostCallReturnValue) "\n"
1787 HIDE_SYMBOL(getHostCallReturnValue) "\n"
1788 SYMBOL_STRING(getHostCallReturnValue) ":" "\n"
1789 "add #-40, r14" "\n"
1790 "mov.l @r14, r14" "\n"
1792 "bra " LOCAL_REFERENCE(getHostCallReturnValueWithExecState) "\n"
1797 extern "C" EncodedJSValue HOST_CALL_RETURN_VALUE_OPTION getHostCallReturnValueWithExecState(ExecState* exec)
1800 return JSValue::encode(JSValue());
1801 return JSValue::encode(exec->vm().hostCallReturnValue);
1806 #endif // ENABLE(JIT)