67
#if PLATFORM(DARWIN) || PLATFORM(WIN_OS)
67
#if OS(DARWIN) || OS(WINDOWS)
68
68
#define SYMBOL_STRING(name) "_" #name
70
70
#define SYMBOL_STRING(name) #name
74
74
#define THUMB_FUNC_PARAM(name) SYMBOL_STRING(name)
76
76
#define THUMB_FUNC_PARAM(name)
79
#if PLATFORM(LINUX) && PLATFORM(X86_64)
79
#if OS(LINUX) && CPU(X86_64)
80
80
#define SYMBOL_STRING_RELOCATION(name) #name "@plt"
82
82
#define SYMBOL_STRING_RELOCATION(name) SYMBOL_STRING(name)
87
87
#define HIDE_SYMBOL(name) ".private_extern _" #name
89
89
// IBM's own file format
90
90
#define HIDE_SYMBOL(name) ".lglobl " #name
91
#elif PLATFORM(LINUX) || PLATFORM(FREEBSD) || PLATFORM(OPENBSD) || PLATFORM(SOLARIS) || (PLATFORM(HPUX) && PLATFORM(IA64)) || PLATFORM(SYMBIAN) || PLATFORM(NETBSD)
95
|| (OS(HPUX) && CPU(IA64)) \
93
99
#define HIDE_SYMBOL(name) ".hidden " #name
98
104
#if USE(JSVALUE32_64)
100
#if COMPILER(GCC) && PLATFORM(X86)
106
#if COMPILER(GCC) && CPU(X86)
102
108
// These ASSERTs remind you that, if you change the layout of JITStackFrame, you
103
109
// need to change the assembly trampolines below to match.
393
#endif // COMPILER(GCC) && PLATFORM(X86)
399
#endif // COMPILER(GCC) && CPU(X86)
395
401
#else // USE(JSVALUE32_64)
397
#if COMPILER(GCC) && PLATFORM(X86)
403
#if COMPILER(GCC) && CPU(X86)
399
405
// These ASSERTs remind you that, if you change the layout of JITStackFrame, you
400
406
// need to change the assembly trampolines below to match.
711
717
JIT::compileCTIMachineTrampolines(globalData, &m_executablePool, &m_ctiStringLengthTrampoline, &m_ctiVirtualCallLink, &m_ctiVirtualCall, &m_ctiNativeCallThunk);
713
#if PLATFORM(ARM_THUMB2)
714
720
// Unfortunate the arm compiler does not like the use of offsetof on JITStackFrame (since it contains non POD types),
715
721
// and the OBJECT_OFFSETOF macro does not appear constantish enough for it to be happy with its use in COMPILE_ASSERT
848
854
stubInfo->initGetByIdProto(structure, slotBaseObject->structure());
856
ASSERT(!structure->isDictionary());
857
ASSERT(!slotBaseObject->structure()->isDictionary());
850
858
JIT::compileGetByIdProto(callFrame->scopeChain()->globalData, callFrame, codeBlock, stubInfo, structure, slotBaseObject->structure(), slot.cachedOffset(), returnAddress);
1032
1040
JSValue v1 = stackFrame.args[0].jsValue();
1033
1041
JSValue v2 = stackFrame.args[1].jsValue();
1038
bool rightIsNumber = v2.getNumber(right);
1039
if (rightIsNumber && v1.getNumber(left))
1042
CallFrame* callFrame = stackFrame.callFrame;
1044
if (v1.isString()) {
1045
JSValue result = v2.isString()
1046
? jsString(callFrame, asString(v1), asString(v2))
1047
: jsString(callFrame, asString(v1), v2.toPrimitiveString(callFrame));
1048
CHECK_FOR_EXCEPTION_AT_END();
1049
return JSValue::encode(result);
1052
double left = 0.0, right;
1053
if (v1.getNumber(left) && v2.getNumber(right))
1040
1054
return JSValue::encode(jsNumber(stackFrame.globalData, left + right));
1042
CallFrame* callFrame = stackFrame.callFrame;
1044
bool leftIsString = v1.isString();
1045
if (leftIsString && v2.isString()) {
1046
RefPtr<UString::Rep> value = concatenate(asString(v1)->value().rep(), asString(v2)->value().rep());
1047
if (UNLIKELY(!value)) {
1048
throwOutOfMemoryError(callFrame);
1049
VM_THROW_EXCEPTION();
1052
return JSValue::encode(jsString(stackFrame.globalData, value.release()));
1055
if (rightIsNumber & leftIsString) {
1056
RefPtr<UString::Rep> value = v2.isInt32() ?
1057
concatenate(asString(v1)->value().rep(), v2.asInt32()) :
1058
concatenate(asString(v1)->value().rep(), right);
1060
if (UNLIKELY(!value)) {
1061
throwOutOfMemoryError(callFrame);
1062
VM_THROW_EXCEPTION();
1064
return JSValue::encode(jsString(stackFrame.globalData, value.release()));
1067
1056
// All other cases are pretty uncommon
1068
1057
JSValue result = jsAddSlowCase(callFrame, v1, v2);
1111
1100
throwStackOverflowError(oldCallFrame, stackFrame.globalData, ReturnAddressPtr(oldCallFrame->returnPC()), STUB_RETURN_ADDRESS);
1114
DEFINE_STUB_FUNCTION(int, op_loop_if_less)
1116
STUB_INIT_STACK_FRAME(stackFrame);
1118
JSValue src1 = stackFrame.args[0].jsValue();
1119
JSValue src2 = stackFrame.args[1].jsValue();
1120
CallFrame* callFrame = stackFrame.callFrame;
1122
bool result = jsLess(callFrame, src1, src2);
1123
CHECK_FOR_EXCEPTION_AT_END();
1127
1103
DEFINE_STUB_FUNCTION(int, op_loop_if_lesseq)
1129
1105
STUB_INIT_STACK_FRAME(stackFrame);
1398
1374
CHECK_FOR_EXCEPTION();
1400
if (!baseValue.isCell() || !slot.isCacheable() || asCell(baseValue)->structure()->isUncacheableDictionary()) {
1376
if (!baseValue.isCell() || !slot.isCacheable() || asCell(baseValue)->structure()->isDictionary()) {
1401
1377
ctiPatchCallByReturnAddress(callFrame->codeBlock(), STUB_RETURN_ADDRESS, FunctionPtr(cti_op_get_by_id_proto_fail));
1402
1378
return JSValue::encode(result);
1412
1388
if (slot.slotBase() == baseValue)
1413
1389
ctiPatchCallByReturnAddress(codeBlock, STUB_RETURN_ADDRESS, FunctionPtr(cti_op_get_by_id_proto_fail));
1414
1390
else if (slot.slotBase() == asCell(baseValue)->structure()->prototypeForLookup(callFrame)) {
1391
ASSERT(!asCell(baseValue)->structure()->isDictionary());
1415
1392
// Since we're accessing a prototype in a loop, it's a good bet that it
1416
1393
// should not be treated as a dictionary.
1417
1394
if (slotBaseObject->structure()->isDictionary())
1425
1402
if (listIndex == (POLYMORPHIC_LIST_CACHE_SIZE - 1))
1426
1403
ctiPatchCallByReturnAddress(codeBlock, STUB_RETURN_ADDRESS, FunctionPtr(cti_op_get_by_id_proto_list_full));
1427
1404
} else if (size_t count = normalizePrototypeChain(callFrame, baseValue, slot.slotBase())) {
1405
ASSERT(!asCell(baseValue)->structure()->isDictionary());
1429
1407
PolymorphicAccessStructureList* prototypeStructureList = getPolymorphicAccessStructureListSlot(stubInfo, listIndex);
1893
1871
} else if (isJSString(globalData, baseValue) && asString(baseValue)->canGetIndex(i)) {
1894
1872
// All fast byte array accesses are safe from exceptions so return immediately to avoid exception checks.
1895
1873
ctiPatchCallByReturnAddress(callFrame->codeBlock(), STUB_RETURN_ADDRESS, FunctionPtr(cti_op_get_by_val_string));
1896
result = asString(baseValue)->getIndex(stackFrame.globalData, i);
1874
result = asString(baseValue)->getIndex(callFrame, i);
1897
1875
} else if (isJSByteArray(globalData, baseValue) && asByteArray(baseValue)->canAccessIndex(i)) {
1898
1876
// All fast byte array accesses are safe from exceptions so return immediately to avoid exception checks.
1899
1877
ctiPatchCallByReturnAddress(callFrame->codeBlock(), STUB_RETURN_ADDRESS, FunctionPtr(cti_op_get_by_val_byte_array));
1924
1902
if (LIKELY(subscript.isUInt32())) {
1925
1903
uint32_t i = subscript.asUInt32();
1926
1904
if (isJSString(globalData, baseValue) && asString(baseValue)->canGetIndex(i))
1927
result = asString(baseValue)->getIndex(stackFrame.globalData, i);
1905
result = asString(baseValue)->getIndex(callFrame, i);
1929
1907
result = baseValue.get(callFrame, i);
1930
1908
if (!isJSString(globalData, baseValue))
2089
2067
return JSValue::encode(result);
2092
DEFINE_STUB_FUNCTION(int, op_loop_if_true)
2094
STUB_INIT_STACK_FRAME(stackFrame);
2096
JSValue src1 = stackFrame.args[0].jsValue();
2098
CallFrame* callFrame = stackFrame.callFrame;
2100
bool result = src1.toBoolean(callFrame);
2101
CHECK_FOR_EXCEPTION_AT_END();
2105
2070
DEFINE_STUB_FUNCTION(int, op_load_varargs)
2107
2072
STUB_INIT_STACK_FRAME(stackFrame);
2441
2406
if (cell1->isString()) {
2442
2407
if (src2.isInt32())
2443
return static_cast<JSString*>(cell1)->value().toDouble() == src2.asInt32();
2408
return static_cast<JSString*>(cell1)->value(stackFrame.callFrame).toDouble() == src2.asInt32();
2445
2410
if (src2.isDouble())
2446
return static_cast<JSString*>(cell1)->value().toDouble() == src2.asDouble();
2411
return static_cast<JSString*>(cell1)->value(stackFrame.callFrame).toDouble() == src2.asDouble();
2448
2413
if (src2.isTrue())
2449
return static_cast<JSString*>(cell1)->value().toDouble() == 1.0;
2414
return static_cast<JSString*>(cell1)->value(stackFrame.callFrame).toDouble() == 1.0;
2451
2416
if (src2.isFalse())
2452
return static_cast<JSString*>(cell1)->value().toDouble() == 0.0;
2417
return static_cast<JSString*>(cell1)->value(stackFrame.callFrame).toDouble() == 0.0;
2454
2419
JSCell* cell2 = asCell(src2);
2455
2420
if (cell2->isString())
2456
return static_cast<JSString*>(cell1)->value() == static_cast<JSString*>(cell2)->value();
2421
return static_cast<JSString*>(cell1)->value(stackFrame.callFrame) == static_cast<JSString*>(cell2)->value(stackFrame.callFrame);
2458
2423
src2 = asObject(cell2)->toPrimitive(stackFrame.callFrame);
2459
2424
CHECK_FOR_EXCEPTION();
2477
2442
ASSERT(string1->isString());
2478
2443
ASSERT(string2->isString());
2479
return string1->value() == string2->value();
2444
return string1->value(stackFrame.callFrame) == string2->value(stackFrame.callFrame);
2482
2447
#else // USE(JSVALUE32_64)
2775
2740
JSObject* base = stackFrame.args[0].jsObject();
2776
2741
JSString* property = stackFrame.args[1].jsString();
2777
return base->hasProperty(stackFrame.callFrame, Identifier(stackFrame.callFrame, property->value()));
2742
return base->hasProperty(stackFrame.callFrame, Identifier(stackFrame.callFrame, property->value(stackFrame.callFrame)));
2780
2745
DEFINE_STUB_FUNCTION(JSObject*, op_push_scope)
2851
2816
JSValue src1 = stackFrame.args[0].jsValue();
2852
2817
JSValue src2 = stackFrame.args[1].jsValue();
2854
return JSValue::encode(jsBoolean(JSValue::strictEqual(src1, src2)));
2819
return JSValue::encode(jsBoolean(JSValue::strictEqual(stackFrame.callFrame, src1, src2)));
2857
2822
DEFINE_STUB_FUNCTION(EncodedJSValue, op_to_primitive)
2866
2831
STUB_INIT_STACK_FRAME(stackFrame);
2868
return JSValue::encode(concatenateStrings(stackFrame.callFrame, &stackFrame.callFrame->registers()[stackFrame.args[0].int32()], stackFrame.args[1].int32()));
2833
JSValue result = jsString(stackFrame.callFrame, &stackFrame.callFrame->registers()[stackFrame.args[0].int32()], stackFrame.args[1].int32());
2834
CHECK_FOR_EXCEPTION_AT_END();
2835
return JSValue::encode(result);
2871
2838
DEFINE_STUB_FUNCTION(EncodedJSValue, op_nstricteq)
2875
2842
JSValue src1 = stackFrame.args[0].jsValue();
2876
2843
JSValue src2 = stackFrame.args[1].jsValue();
2878
return JSValue::encode(jsBoolean(!JSValue::strictEqual(src1, src2)));
2845
return JSValue::encode(jsBoolean(!JSValue::strictEqual(stackFrame.callFrame, src1, src2)));
2881
2848
DEFINE_STUB_FUNCTION(EncodedJSValue, op_to_jsnumber)
2984
2951
void* result = codeBlock->characterSwitchJumpTable(tableIndex).ctiDefault.executableAddress();
2986
2953
if (scrutinee.isString()) {
2987
UString::Rep* value = asString(scrutinee)->value().rep();
2954
UString::Rep* value = asString(scrutinee)->value(callFrame).rep();
2988
2955
if (value->size() == 1)
2989
2956
result = codeBlock->characterSwitchJumpTable(tableIndex).ctiForValue(value->data()[0]).executableAddress();
3004
2971
void* result = codeBlock->stringSwitchJumpTable(tableIndex).ctiDefault.executableAddress();
3006
2973
if (scrutinee.isString()) {
3007
UString::Rep* value = asString(scrutinee)->value().rep();
2974
UString::Rep* value = asString(scrutinee)->value(callFrame).rep();
3008
2975
result = codeBlock->stringSwitchJumpTable(tableIndex).ctiForValue(value).executableAddress();