summaryrefslogtreecommitdiffstats
path: root/JavaScriptCore/jit
diff options
context:
space:
mode:
Diffstat (limited to 'JavaScriptCore/jit')
-rw-r--r--JavaScriptCore/jit/ExecutableAllocator.h13
-rw-r--r--JavaScriptCore/jit/JIT.cpp20
-rw-r--r--JavaScriptCore/jit/JIT.h10
-rw-r--r--JavaScriptCore/jit/JITArithmetic.cpp600
-rw-r--r--JavaScriptCore/jit/JITCall.cpp4
-rw-r--r--JavaScriptCore/jit/JITCall32_64.cpp11
-rw-r--r--JavaScriptCore/jit/JITInlineMethods.h6
-rw-r--r--JavaScriptCore/jit/JITOpcodes.cpp119
-rw-r--r--JavaScriptCore/jit/JITOpcodes32_64.cpp77
-rw-r--r--JavaScriptCore/jit/JITPropertyAccess.cpp14
-rw-r--r--JavaScriptCore/jit/JITStubs.cpp104
-rw-r--r--JavaScriptCore/jit/JITStubs.h5
-rw-r--r--JavaScriptCore/jit/JSInterfaceJIT.h32
-rw-r--r--JavaScriptCore/jit/SpecializedThunkJIT.h13
-rw-r--r--JavaScriptCore/jit/ThunkGenerators.cpp10
15 files changed, 299 insertions, 739 deletions
diff --git a/JavaScriptCore/jit/ExecutableAllocator.h b/JavaScriptCore/jit/ExecutableAllocator.h
index f145404..f362605 100644
--- a/JavaScriptCore/jit/ExecutableAllocator.h
+++ b/JavaScriptCore/jit/ExecutableAllocator.h
@@ -53,6 +53,12 @@
extern "C" __declspec(dllimport) void CacheRangeFlush(LPVOID pAddr, DWORD dwLength, DWORD dwFlags);
#endif
+#if PLATFORM(BREWMP)
+#include <AEEIMemCache1.h>
+#include <AEEMemCache1.bid>
+#include <wtf/brew/RefPtrBrew.h>
+#endif
+
#define JIT_ALLOCATOR_PAGE_SIZE (ExecutableAllocator::pageSize)
#define JIT_ALLOCATOR_LARGE_ALLOC_SIZE (ExecutableAllocator::pageSize * 4)
@@ -294,6 +300,13 @@ public:
{
CacheRangeFlush(code, size, CACHE_SYNC_ALL);
}
+#elif PLATFORM(BREWMP)
+ static void cacheFlush(void* code, size_t size)
+ {
+ PlatformRefPtr<IMemCache1> memCache = createRefPtrInstance<IMemCache1>(AEECLSID_MemCache1);
+ IMemCache1_ClearCache(memCache.get(), reinterpret_cast<uint32>(code), size, MEMSPACE_CACHE_FLUSH, MEMSPACE_DATACACHE);
+ IMemCache1_ClearCache(memCache.get(), reinterpret_cast<uint32>(code), size, MEMSPACE_CACHE_INVALIDATE, MEMSPACE_INSTCACHE);
+ }
#else
#error "The cacheFlush support is missing on this platform."
#endif
diff --git a/JavaScriptCore/jit/JIT.cpp b/JavaScriptCore/jit/JIT.cpp
index a508d0c..0eabdf5 100644
--- a/JavaScriptCore/jit/JIT.cpp
+++ b/JavaScriptCore/jit/JIT.cpp
@@ -186,7 +186,7 @@ void JIT::privateCompileMainPass()
sampleInstruction(currentInstruction);
#endif
-#if !USE(JSVALUE32_64)
+#if USE(JSVALUE64)
if (m_labels[m_bytecodeOffset].isUsed())
killLastResultRegister();
#endif
@@ -195,9 +195,6 @@ void JIT::privateCompileMainPass()
switch (m_interpreter->getOpcodeID(currentInstruction->u.opcode)) {
DEFINE_BINARY_OP(op_del_by_val)
-#if USE(JSVALUE32)
- DEFINE_BINARY_OP(op_div)
-#endif
DEFINE_BINARY_OP(op_in)
DEFINE_BINARY_OP(op_less)
DEFINE_BINARY_OP(op_lesseq)
@@ -207,7 +204,7 @@ void JIT::privateCompileMainPass()
DEFINE_UNARY_OP(op_is_object)
DEFINE_UNARY_OP(op_is_string)
DEFINE_UNARY_OP(op_is_undefined)
-#if !USE(JSVALUE32_64)
+#if USE(JSVALUE64)
DEFINE_UNARY_OP(op_negate)
#endif
DEFINE_UNARY_OP(op_typeof)
@@ -225,16 +222,15 @@ void JIT::privateCompileMainPass()
DEFINE_OP(op_get_callee)
DEFINE_OP(op_create_this)
DEFINE_OP(op_convert_this)
+ DEFINE_OP(op_convert_this_strict)
DEFINE_OP(op_init_lazy_reg)
DEFINE_OP(op_create_arguments)
DEFINE_OP(op_debug)
DEFINE_OP(op_del_by_id)
-#if !USE(JSVALUE32)
DEFINE_OP(op_div)
-#endif
DEFINE_OP(op_end)
DEFINE_OP(op_enter)
- DEFINE_OP(op_enter_with_activation)
+ DEFINE_OP(op_create_activation)
DEFINE_OP(op_eq)
DEFINE_OP(op_eq_null)
DEFINE_OP(op_get_by_id)
@@ -301,6 +297,7 @@ void JIT::privateCompileMainPass()
DEFINE_OP(op_put_setter)
DEFINE_OP(op_resolve)
DEFINE_OP(op_resolve_base)
+ DEFINE_OP(op_ensure_property_exists)
DEFINE_OP(op_resolve_global)
DEFINE_OP(op_resolve_global_dynamic)
DEFINE_OP(op_resolve_skip)
@@ -375,7 +372,7 @@ void JIT::privateCompileSlowCases()
m_callLinkInfoIndex = 0;
for (Vector<SlowCaseEntry>::iterator iter = m_slowCases.begin(); iter != m_slowCases.end();) {
-#if !USE(JSVALUE32_64)
+#if USE(JSVALUE64)
killLastResultRegister();
#endif
@@ -396,9 +393,8 @@ void JIT::privateCompileSlowCases()
DEFINE_SLOWCASE_OP(op_call_varargs)
DEFINE_SLOWCASE_OP(op_construct)
DEFINE_SLOWCASE_OP(op_convert_this)
-#if !USE(JSVALUE32)
+ DEFINE_SLOWCASE_OP(op_convert_this_strict)
DEFINE_SLOWCASE_OP(op_div)
-#endif
DEFINE_SLOWCASE_OP(op_eq)
DEFINE_SLOWCASE_OP(op_get_by_id)
DEFINE_SLOWCASE_OP(op_get_arguments_length)
@@ -596,7 +592,7 @@ JITCode JIT::privateCompile(CodePtr* functionEntryArityCheck)
return patchBuffer.finalizeCode();
}
-#if !USE(JSVALUE32_64)
+#if USE(JSVALUE64)
void JIT::emitGetVariableObjectRegister(RegisterID variableObject, int index, RegisterID dst)
{
loadPtr(Address(variableObject, OBJECT_OFFSETOF(JSVariableObject, d)), dst);
diff --git a/JavaScriptCore/jit/JIT.h b/JavaScriptCore/jit/JIT.h
index 6b2e70e..3ef0538 100644
--- a/JavaScriptCore/jit/JIT.h
+++ b/JavaScriptCore/jit/JIT.h
@@ -516,8 +516,7 @@ namespace JSC {
Jump emitJumpIfNotJSCell(RegisterID);
void emitJumpSlowCaseIfNotJSCell(RegisterID);
void emitJumpSlowCaseIfNotJSCell(RegisterID, int VReg);
-#if USE(JSVALUE64)
-#else
+#if USE(JSVALUE32_64)
JIT::Jump emitJumpIfImmediateNumber(RegisterID reg)
{
return emitJumpIfImmediateInteger(reg);
@@ -535,7 +534,7 @@ namespace JSC {
void emitJumpSlowCaseIfNotImmediateNumber(RegisterID);
void emitJumpSlowCaseIfNotImmediateIntegers(RegisterID, RegisterID, RegisterID);
-#if !USE(JSVALUE64)
+#if USE(JSVALUE32_64)
void emitFastArithDeTagImmediate(RegisterID);
Jump emitFastArithDeTagImmediateJumpIfZero(RegisterID);
#endif
@@ -738,13 +737,14 @@ namespace JSC {
void emit_op_get_callee(Instruction*);
void emit_op_create_this(Instruction*);
void emit_op_convert_this(Instruction*);
+ void emit_op_convert_this_strict(Instruction*);
void emit_op_create_arguments(Instruction*);
void emit_op_debug(Instruction*);
void emit_op_del_by_id(Instruction*);
void emit_op_div(Instruction*);
void emit_op_end(Instruction*);
void emit_op_enter(Instruction*);
- void emit_op_enter_with_activation(Instruction*);
+ void emit_op_create_activation(Instruction*);
void emit_op_eq(Instruction*);
void emit_op_eq_null(Instruction*);
void emit_op_get_by_id(Instruction*);
@@ -810,6 +810,7 @@ namespace JSC {
void emit_op_put_setter(Instruction*);
void emit_op_resolve(Instruction*);
void emit_op_resolve_base(Instruction*);
+ void emit_op_ensure_property_exists(Instruction*);
void emit_op_resolve_global(Instruction*, bool dynamic = false);
void emit_op_resolve_global_dynamic(Instruction*);
void emit_op_resolve_skip(Instruction*);
@@ -845,6 +846,7 @@ namespace JSC {
void emitSlow_op_call_varargs(Instruction*, Vector<SlowCaseEntry>::iterator&);
void emitSlow_op_construct(Instruction*, Vector<SlowCaseEntry>::iterator&);
void emitSlow_op_convert_this(Instruction*, Vector<SlowCaseEntry>::iterator&);
+ void emitSlow_op_convert_this_strict(Instruction*, Vector<SlowCaseEntry>::iterator&);
void emitSlow_op_div(Instruction*, Vector<SlowCaseEntry>::iterator&);
void emitSlow_op_eq(Instruction*, Vector<SlowCaseEntry>::iterator&);
void emitSlow_op_get_by_id(Instruction*, Vector<SlowCaseEntry>::iterator&);
diff --git a/JavaScriptCore/jit/JITArithmetic.cpp b/JavaScriptCore/jit/JITArithmetic.cpp
index d75f8b5..d4fa12f 100644
--- a/JavaScriptCore/jit/JITArithmetic.cpp
+++ b/JavaScriptCore/jit/JITArithmetic.cpp
@@ -26,7 +26,7 @@
#include "config.h"
#if ENABLE(JIT)
-#if !USE(JSVALUE32_64)
+#if USE(JSVALUE64)
#include "JIT.h"
#include "CodeBlock.h"
@@ -60,10 +60,6 @@ void JIT::emit_op_lshift(Instruction* currentInstruction)
emitFastArithImmToInt(regT0);
emitFastArithImmToInt(regT2);
lshift32(regT2, regT0);
-#if USE(JSVALUE32)
- addSlowCase(branchAdd32(Overflow, regT0, regT0));
- signExtend32ToPtr(regT0, regT0);
-#endif
emitFastArithReTagImmediate(regT0, regT0);
emitPutVirtualRegister(result);
}
@@ -74,20 +70,10 @@ void JIT::emitSlow_op_lshift(Instruction* currentInstruction, Vector<SlowCaseEnt
unsigned op1 = currentInstruction[2].u.operand;
unsigned op2 = currentInstruction[3].u.operand;
-#if USE(JSVALUE64)
UNUSED_PARAM(op1);
UNUSED_PARAM(op2);
linkSlowCase(iter);
linkSlowCase(iter);
-#else
- // If we are limited to 32-bit immediates there is a third slow case, which required the operands to have been reloaded.
- Jump notImm1 = getSlowCase(iter);
- Jump notImm2 = getSlowCase(iter);
- linkSlowCase(iter);
- emitGetVirtualRegisters(op1, regT0, op2, regT2);
- notImm1.link(this);
- notImm2.link(this);
-#endif
JITStubCall stubCall(this, cti_op_lshift);
stubCall.addArgument(regT0);
stubCall.addArgument(regT2);
@@ -110,20 +96,11 @@ void JIT::emit_op_rshift(Instruction* currentInstruction)
emitGetVirtualRegisters(op1, regT0, op2, regT2);
if (supportsFloatingPointTruncate()) {
Jump lhsIsInt = emitJumpIfImmediateInteger(regT0);
-#if USE(JSVALUE64)
// supportsFloatingPoint() && USE(JSVALUE64) => 3 SlowCases
addSlowCase(emitJumpIfNotImmediateNumber(regT0));
addPtr(tagTypeNumberRegister, regT0);
movePtrToDouble(regT0, fpRegT0);
addSlowCase(branchTruncateDoubleToInt32(fpRegT0, regT0));
-#else
- // supportsFloatingPoint() && !USE(JSVALUE64) => 5 SlowCases (of which 1 IfNotJSCell)
- emitJumpSlowCaseIfNotJSCell(regT0, op1);
- addSlowCase(checkStructure(regT0, m_globalData->numberStructure.get()));
- loadDouble(Address(regT0, OBJECT_OFFSETOF(JSNumberCell, m_value)), fpRegT0);
- addSlowCase(branchTruncateDoubleToInt32(fpRegT0, regT0));
- addSlowCase(branchAdd32(Overflow, regT0, regT0));
-#endif
lhsIsInt.link(this);
emitJumpSlowCaseIfNotImmediateInteger(regT2);
} else {
@@ -133,15 +110,8 @@ void JIT::emit_op_rshift(Instruction* currentInstruction)
}
emitFastArithImmToInt(regT2);
rshift32(regT2, regT0);
-#if USE(JSVALUE32)
- signExtend32ToPtr(regT0, regT0);
-#endif
}
-#if USE(JSVALUE64)
emitFastArithIntToImmNoCheck(regT0, regT0);
-#else
- orPtr(Imm32(JSImmediate::TagTypeNumber), regT0);
-#endif
emitPutVirtualRegister(result);
}
@@ -159,17 +129,9 @@ void JIT::emitSlow_op_rshift(Instruction* currentInstruction, Vector<SlowCaseEnt
stubCall.addArgument(op2, regT2);
} else {
if (supportsFloatingPointTruncate()) {
-#if USE(JSVALUE64)
- linkSlowCase(iter);
- linkSlowCase(iter);
- linkSlowCase(iter);
-#else
- linkSlowCaseIfNotJSCell(iter, op1);
- linkSlowCase(iter);
linkSlowCase(iter);
linkSlowCase(iter);
linkSlowCase(iter);
-#endif
// We're reloading op1 to regT0 as we can no longer guarantee that
// we have not munged the operand. It may have already been shifted
// correctly, but it still will not have been tagged.
@@ -206,10 +168,6 @@ void JIT::emit_op_urshift(Instruction* currentInstruction)
// as an immediate int.
if (shift < 0 || !(shift & 31))
addSlowCase(branch32(LessThan, regT0, Imm32(0)));
-#if USE(JSVALUE32)
- addSlowCase(branchAdd32(Overflow, regT0, regT0));
- signExtend32ToPtr(regT0, regT0);
-#endif
emitFastArithReTagImmediate(regT0, regT0);
emitPutVirtualRegister(dst, regT0);
return;
@@ -222,10 +180,6 @@ void JIT::emit_op_urshift(Instruction* currentInstruction)
emitFastArithImmToInt(regT1);
urshift32(regT1, regT0);
addSlowCase(branch32(LessThan, regT0, Imm32(0)));
-#if USE(JSVALUE32)
- addSlowCase(branchAdd32(Overflow, regT0, regT0));
- signExtend32ToPtr(regT0, regT0);
-#endif
emitFastArithReTagImmediate(regT0, regT0);
emitPutVirtualRegister(dst, regT0);
}
@@ -239,7 +193,6 @@ void JIT::emitSlow_op_urshift(Instruction* currentInstruction, Vector<SlowCaseEn
int shift = getConstantOperand(op2).asInt32();
// op1 = regT0
linkSlowCase(iter); // int32 check
-#if USE(JSVALUE64)
if (supportsFloatingPointTruncate()) {
JumpList failures;
failures.append(emitJumpIfNotImmediateNumber(regT0)); // op1 is not a double
@@ -255,18 +208,13 @@ void JIT::emitSlow_op_urshift(Instruction* currentInstruction, Vector<SlowCaseEn
emitJumpSlowToHot(jump(), OPCODE_LENGTH(op_rshift));
failures.link(this);
}
-#endif // JSVALUE64
if (shift < 0 || !(shift & 31))
linkSlowCase(iter); // failed to box in hot path
-#if USE(JSVALUE32)
- linkSlowCase(iter); // Couldn't box result
-#endif
} else {
// op1 = regT0
// op2 = regT1
if (!isOperandConstantImmediateInt(op1)) {
linkSlowCase(iter); // int32 check -- op1 is not an int
-#if USE(JSVALUE64)
if (supportsFloatingPointTruncate()) {
JumpList failures;
failures.append(emitJumpIfNotImmediateNumber(regT0)); // op1 is not a double
@@ -282,14 +230,10 @@ void JIT::emitSlow_op_urshift(Instruction* currentInstruction, Vector<SlowCaseEn
emitJumpSlowToHot(jump(), OPCODE_LENGTH(op_rshift));
failures.link(this);
}
-#endif
}
linkSlowCase(iter); // int32 check - op2 is not an int
linkSlowCase(iter); // Can't represent unsigned result as an immediate
-#if USE(JSVALUE32)
- linkSlowCase(iter); // Couldn't box result
-#endif
}
JITStubCall stubCall(this, cti_op_urshift);
@@ -330,20 +274,12 @@ void JIT::emit_op_jnless(Instruction* currentInstruction)
if (isOperandConstantImmediateInt(op2)) {
emitGetVirtualRegister(op1, regT0);
emitJumpSlowCaseIfNotImmediateInteger(regT0);
-#if USE(JSVALUE64)
int32_t op2imm = getConstantOperandImmediateInt(op2);
-#else
- int32_t op2imm = static_cast<int32_t>(JSImmediate::rawValue(getConstantOperand(op2)));
-#endif
addJump(branch32(GreaterThanOrEqual, regT0, Imm32(op2imm)), target);
} else if (isOperandConstantImmediateInt(op1)) {
emitGetVirtualRegister(op2, regT1);
emitJumpSlowCaseIfNotImmediateInteger(regT1);
-#if USE(JSVALUE64)
int32_t op1imm = getConstantOperandImmediateInt(op1);
-#else
- int32_t op1imm = static_cast<int32_t>(JSImmediate::rawValue(getConstantOperand(op1)));
-#endif
addJump(branch32(LessThanOrEqual, regT1, Imm32(op1imm)), target);
} else {
emitGetVirtualRegisters(op1, regT0, op2, regT1);
@@ -381,18 +317,9 @@ void JIT::emitSlow_op_jnless(Instruction* currentInstruction, Vector<SlowCaseEnt
linkSlowCase(iter);
if (supportsFloatingPoint()) {
-#if USE(JSVALUE64)
Jump fail1 = emitJumpIfNotImmediateNumber(regT0);
addPtr(tagTypeNumberRegister, regT0);
movePtrToDouble(regT0, fpRegT0);
-#else
- Jump fail1;
- if (!m_codeBlock->isKnownNotImmediate(op1))
- fail1 = emitJumpIfNotJSCell(regT0);
-
- Jump fail2 = checkStructure(regT0, m_globalData->numberStructure.get());
- loadDouble(Address(regT0, OBJECT_OFFSETOF(JSNumberCell, m_value)), fpRegT0);
-#endif
int32_t op2imm = getConstantOperand(op2).asInt32();;
@@ -403,13 +330,7 @@ void JIT::emitSlow_op_jnless(Instruction* currentInstruction, Vector<SlowCaseEnt
emitJumpSlowToHot(jump(), OPCODE_LENGTH(op_jnless));
-#if USE(JSVALUE64)
fail1.link(this);
-#else
- if (!m_codeBlock->isKnownNotImmediate(op1))
- fail1.link(this);
- fail2.link(this);
-#endif
}
JITStubCall stubCall(this, cti_op_jless);
@@ -422,18 +343,9 @@ void JIT::emitSlow_op_jnless(Instruction* currentInstruction, Vector<SlowCaseEnt
linkSlowCase(iter);
if (supportsFloatingPoint()) {
-#if USE(JSVALUE64)
Jump fail1 = emitJumpIfNotImmediateNumber(regT1);
addPtr(tagTypeNumberRegister, regT1);
movePtrToDouble(regT1, fpRegT1);
-#else
- Jump fail1;
- if (!m_codeBlock->isKnownNotImmediate(op2))
- fail1 = emitJumpIfNotJSCell(regT1);
-
- Jump fail2 = checkStructure(regT1, m_globalData->numberStructure.get());
- loadDouble(Address(regT1, OBJECT_OFFSETOF(JSNumberCell, m_value)), fpRegT1);
-#endif
int32_t op1imm = getConstantOperand(op1).asInt32();;
@@ -444,13 +356,7 @@ void JIT::emitSlow_op_jnless(Instruction* currentInstruction, Vector<SlowCaseEnt
emitJumpSlowToHot(jump(), OPCODE_LENGTH(op_jnless));
-#if USE(JSVALUE64)
fail1.link(this);
-#else
- if (!m_codeBlock->isKnownNotImmediate(op2))
- fail1.link(this);
- fail2.link(this);
-#endif
}
JITStubCall stubCall(this, cti_op_jless);
@@ -463,7 +369,6 @@ void JIT::emitSlow_op_jnless(Instruction* currentInstruction, Vector<SlowCaseEnt
linkSlowCase(iter);
if (supportsFloatingPoint()) {
-#if USE(JSVALUE64)
Jump fail1 = emitJumpIfNotImmediateNumber(regT0);
Jump fail2 = emitJumpIfNotImmediateNumber(regT1);
Jump fail3 = emitJumpIfImmediateInteger(regT1);
@@ -471,37 +376,14 @@ void JIT::emitSlow_op_jnless(Instruction* currentInstruction, Vector<SlowCaseEnt
addPtr(tagTypeNumberRegister, regT1);
movePtrToDouble(regT0, fpRegT0);
movePtrToDouble(regT1, fpRegT1);
-#else
- Jump fail1;
- if (!m_codeBlock->isKnownNotImmediate(op1))
- fail1 = emitJumpIfNotJSCell(regT0);
-
- Jump fail2;
- if (!m_codeBlock->isKnownNotImmediate(op2))
- fail2 = emitJumpIfNotJSCell(regT1);
-
- Jump fail3 = checkStructure(regT0, m_globalData->numberStructure.get());
- Jump fail4 = checkStructure(regT1, m_globalData->numberStructure.get());
- loadDouble(Address(regT0, OBJECT_OFFSETOF(JSNumberCell, m_value)), fpRegT0);
- loadDouble(Address(regT1, OBJECT_OFFSETOF(JSNumberCell, m_value)), fpRegT1);
-#endif
emitJumpSlowToHot(branchDouble(DoubleLessThanOrEqualOrUnordered, fpRegT1, fpRegT0), target);
emitJumpSlowToHot(jump(), OPCODE_LENGTH(op_jnless));
-#if USE(JSVALUE64)
fail1.link(this);
fail2.link(this);
fail3.link(this);
-#else
- if (!m_codeBlock->isKnownNotImmediate(op1))
- fail1.link(this);
- if (!m_codeBlock->isKnownNotImmediate(op2))
- fail2.link(this);
- fail3.link(this);
- fail4.link(this);
-#endif
}
linkSlowCase(iter);
@@ -545,20 +427,12 @@ void JIT::emit_op_jless(Instruction* currentInstruction)
if (isOperandConstantImmediateInt(op2)) {
emitGetVirtualRegister(op1, regT0);
emitJumpSlowCaseIfNotImmediateInteger(regT0);
-#if USE(JSVALUE64)
int32_t op2imm = getConstantOperandImmediateInt(op2);
-#else
- int32_t op2imm = static_cast<int32_t>(JSImmediate::rawValue(getConstantOperand(op2)));
-#endif
addJump(branch32(LessThan, regT0, Imm32(op2imm)), target);
} else if (isOperandConstantImmediateInt(op1)) {
emitGetVirtualRegister(op2, regT1);
emitJumpSlowCaseIfNotImmediateInteger(regT1);
-#if USE(JSVALUE64)
int32_t op1imm = getConstantOperandImmediateInt(op1);
-#else
- int32_t op1imm = static_cast<int32_t>(JSImmediate::rawValue(getConstantOperand(op1)));
-#endif
addJump(branch32(GreaterThan, regT1, Imm32(op1imm)), target);
} else {
emitGetVirtualRegisters(op1, regT0, op2, regT1);
@@ -596,18 +470,9 @@ void JIT::emitSlow_op_jless(Instruction* currentInstruction, Vector<SlowCaseEntr
linkSlowCase(iter);
if (supportsFloatingPoint()) {
-#if USE(JSVALUE64)
Jump fail1 = emitJumpIfNotImmediateNumber(regT0);
addPtr(tagTypeNumberRegister, regT0);
movePtrToDouble(regT0, fpRegT0);
-#else
- Jump fail1;
- if (!m_codeBlock->isKnownNotImmediate(op1))
- fail1 = emitJumpIfNotJSCell(regT0);
-
- Jump fail2 = checkStructure(regT0, m_globalData->numberStructure.get());
- loadDouble(Address(regT0, OBJECT_OFFSETOF(JSNumberCell, m_value)), fpRegT0);
-#endif
int32_t op2imm = getConstantOperand(op2).asInt32();
@@ -618,13 +483,7 @@ void JIT::emitSlow_op_jless(Instruction* currentInstruction, Vector<SlowCaseEntr
emitJumpSlowToHot(jump(), OPCODE_LENGTH(op_jnless));
-#if USE(JSVALUE64)
fail1.link(this);
-#else
- if (!m_codeBlock->isKnownNotImmediate(op1))
- fail1.link(this);
- fail2.link(this);
-#endif
}
JITStubCall stubCall(this, cti_op_jless);
@@ -637,18 +496,9 @@ void JIT::emitSlow_op_jless(Instruction* currentInstruction, Vector<SlowCaseEntr
linkSlowCase(iter);
if (supportsFloatingPoint()) {
-#if USE(JSVALUE64)
Jump fail1 = emitJumpIfNotImmediateNumber(regT1);
addPtr(tagTypeNumberRegister, regT1);
movePtrToDouble(regT1, fpRegT1);
-#else
- Jump fail1;
- if (!m_codeBlock->isKnownNotImmediate(op2))
- fail1 = emitJumpIfNotJSCell(regT1);
-
- Jump fail2 = checkStructure(regT1, m_globalData->numberStructure.get());
- loadDouble(Address(regT1, OBJECT_OFFSETOF(JSNumberCell, m_value)), fpRegT1);
-#endif
int32_t op1imm = getConstantOperand(op1).asInt32();
@@ -659,13 +509,7 @@ void JIT::emitSlow_op_jless(Instruction* currentInstruction, Vector<SlowCaseEntr
emitJumpSlowToHot(jump(), OPCODE_LENGTH(op_jnless));
-#if USE(JSVALUE64)
fail1.link(this);
-#else
- if (!m_codeBlock->isKnownNotImmediate(op2))
- fail1.link(this);
- fail2.link(this);
-#endif
}
JITStubCall stubCall(this, cti_op_jless);
@@ -678,7 +522,6 @@ void JIT::emitSlow_op_jless(Instruction* currentInstruction, Vector<SlowCaseEntr
linkSlowCase(iter);
if (supportsFloatingPoint()) {
-#if USE(JSVALUE64)
Jump fail1 = emitJumpIfNotImmediateNumber(regT0);
Jump fail2 = emitJumpIfNotImmediateNumber(regT1);
Jump fail3 = emitJumpIfImmediateInteger(regT1);
@@ -686,37 +529,14 @@ void JIT::emitSlow_op_jless(Instruction* currentInstruction, Vector<SlowCaseEntr
addPtr(tagTypeNumberRegister, regT1);
movePtrToDouble(regT0, fpRegT0);
movePtrToDouble(regT1, fpRegT1);
-#else
- Jump fail1;
- if (!m_codeBlock->isKnownNotImmediate(op1))
- fail1 = emitJumpIfNotJSCell(regT0);
-
- Jump fail2;
- if (!m_codeBlock->isKnownNotImmediate(op2))
- fail2 = emitJumpIfNotJSCell(regT1);
-
- Jump fail3 = checkStructure(regT0, m_globalData->numberStructure.get());
- Jump fail4 = checkStructure(regT1, m_globalData->numberStructure.get());
- loadDouble(Address(regT0, OBJECT_OFFSETOF(JSNumberCell, m_value)), fpRegT0);
- loadDouble(Address(regT1, OBJECT_OFFSETOF(JSNumberCell, m_value)), fpRegT1);
-#endif
emitJumpSlowToHot(branchDouble(DoubleLessThan, fpRegT0, fpRegT1), target);
emitJumpSlowToHot(jump(), OPCODE_LENGTH(op_jnless));
-#if USE(JSVALUE64)
fail1.link(this);
fail2.link(this);
fail3.link(this);
-#else
- if (!m_codeBlock->isKnownNotImmediate(op1))
- fail1.link(this);
- if (!m_codeBlock->isKnownNotImmediate(op2))
- fail2.link(this);
- fail3.link(this);
- fail4.link(this);
-#endif
}
linkSlowCase(iter);
@@ -760,20 +580,12 @@ void JIT::emit_op_jlesseq(Instruction* currentInstruction, bool invert)
if (isOperandConstantImmediateInt(op2)) {
emitGetVirtualRegister(op1, regT0);
emitJumpSlowCaseIfNotImmediateInteger(regT0);
-#if USE(JSVALUE64)
int32_t op2imm = getConstantOperandImmediateInt(op2);
-#else
- int32_t op2imm = static_cast<int32_t>(JSImmediate::rawValue(getConstantOperand(op2)));
-#endif
addJump(branch32(invert ? GreaterThan : LessThanOrEqual, regT0, Imm32(op2imm)), target);
} else if (isOperandConstantImmediateInt(op1)) {
emitGetVirtualRegister(op2, regT1);
emitJumpSlowCaseIfNotImmediateInteger(regT1);
-#if USE(JSVALUE64)
int32_t op1imm = getConstantOperandImmediateInt(op1);
-#else
- int32_t op1imm = static_cast<int32_t>(JSImmediate::rawValue(getConstantOperand(op1)));
-#endif
addJump(branch32(invert ? LessThan : GreaterThanOrEqual, regT1, Imm32(op1imm)), target);
} else {
emitGetVirtualRegisters(op1, regT0, op2, regT1);
@@ -812,18 +624,9 @@ void JIT::emitSlow_op_jlesseq(Instruction* currentInstruction, Vector<SlowCaseEn
linkSlowCase(iter);
if (supportsFloatingPoint()) {
-#if USE(JSVALUE64)
Jump fail1 = emitJumpIfNotImmediateNumber(regT0);
addPtr(tagTypeNumberRegister, regT0);
movePtrToDouble(regT0, fpRegT0);
-#else
- Jump fail1;
- if (!m_codeBlock->isKnownNotImmediate(op1))
- fail1 = emitJumpIfNotJSCell(regT0);
-
- Jump fail2 = checkStructure(regT0, m_globalData->numberStructure.get());
- loadDouble(Address(regT0, OBJECT_OFFSETOF(JSNumberCell, m_value)), fpRegT0);
-#endif
int32_t op2imm = getConstantOperand(op2).asInt32();;
@@ -834,13 +637,7 @@ void JIT::emitSlow_op_jlesseq(Instruction* currentInstruction, Vector<SlowCaseEn
emitJumpSlowToHot(jump(), OPCODE_LENGTH(op_jnlesseq));
-#if USE(JSVALUE64)
fail1.link(this);
-#else
- if (!m_codeBlock->isKnownNotImmediate(op1))
- fail1.link(this);
- fail2.link(this);
-#endif
}
JITStubCall stubCall(this, cti_op_jlesseq);
@@ -853,18 +650,9 @@ void JIT::emitSlow_op_jlesseq(Instruction* currentInstruction, Vector<SlowCaseEn
linkSlowCase(iter);
if (supportsFloatingPoint()) {
-#if USE(JSVALUE64)
Jump fail1 = emitJumpIfNotImmediateNumber(regT1);
addPtr(tagTypeNumberRegister, regT1);
movePtrToDouble(regT1, fpRegT1);
-#else
- Jump fail1;
- if (!m_codeBlock->isKnownNotImmediate(op2))
- fail1 = emitJumpIfNotJSCell(regT1);
-
- Jump fail2 = checkStructure(regT1, m_globalData->numberStructure.get());
- loadDouble(Address(regT1, OBJECT_OFFSETOF(JSNumberCell, m_value)), fpRegT1);
-#endif
int32_t op1imm = getConstantOperand(op1).asInt32();;
@@ -875,13 +663,7 @@ void JIT::emitSlow_op_jlesseq(Instruction* currentInstruction, Vector<SlowCaseEn
emitJumpSlowToHot(jump(), OPCODE_LENGTH(op_jnlesseq));
-#if USE(JSVALUE64)
fail1.link(this);
-#else
- if (!m_codeBlock->isKnownNotImmediate(op2))
- fail1.link(this);
- fail2.link(this);
-#endif
}
JITStubCall stubCall(this, cti_op_jlesseq);
@@ -894,7 +676,6 @@ void JIT::emitSlow_op_jlesseq(Instruction* currentInstruction, Vector<SlowCaseEn
linkSlowCase(iter);
if (supportsFloatingPoint()) {
-#if USE(JSVALUE64)
Jump fail1 = emitJumpIfNotImmediateNumber(regT0);
Jump fail2 = emitJumpIfNotImmediateNumber(regT1);
Jump fail3 = emitJumpIfImmediateInteger(regT1);
@@ -902,37 +683,14 @@ void JIT::emitSlow_op_jlesseq(Instruction* currentInstruction, Vector<SlowCaseEn
addPtr(tagTypeNumberRegister, regT1);
movePtrToDouble(regT0, fpRegT0);
movePtrToDouble(regT1, fpRegT1);
-#else
- Jump fail1;
- if (!m_codeBlock->isKnownNotImmediate(op1))
- fail1 = emitJumpIfNotJSCell(regT0);
-
- Jump fail2;
- if (!m_codeBlock->isKnownNotImmediate(op2))
- fail2 = emitJumpIfNotJSCell(regT1);
-
- Jump fail3 = checkStructure(regT0, m_globalData->numberStructure.get());
- Jump fail4 = checkStructure(regT1, m_globalData->numberStructure.get());
- loadDouble(Address(regT0, OBJECT_OFFSETOF(JSNumberCell, m_value)), fpRegT0);
- loadDouble(Address(regT1, OBJECT_OFFSETOF(JSNumberCell, m_value)), fpRegT1);
-#endif
emitJumpSlowToHot(branchDouble(invert ? DoubleLessThanOrUnordered : DoubleGreaterThanOrEqual, fpRegT1, fpRegT0), target);
emitJumpSlowToHot(jump(), OPCODE_LENGTH(op_jnlesseq));
-#if USE(JSVALUE64)
fail1.link(this);
fail2.link(this);
fail3.link(this);
-#else
- if (!m_codeBlock->isKnownNotImmediate(op1))
- fail1.link(this);
- if (!m_codeBlock->isKnownNotImmediate(op2))
- fail2.link(this);
- fail3.link(this);
- fail4.link(this);
-#endif
}
linkSlowCase(iter);
@@ -963,25 +721,17 @@ void JIT::emit_op_bitand(Instruction* currentInstruction)
if (isOperandConstantImmediateInt(op1)) {
emitGetVirtualRegister(op2, regT0);
emitJumpSlowCaseIfNotImmediateInteger(regT0);
-#if USE(JSVALUE64)
int32_t imm = getConstantOperandImmediateInt(op1);
andPtr(Imm32(imm), regT0);
if (imm >= 0)
emitFastArithIntToImmNoCheck(regT0, regT0);
-#else
- andPtr(Imm32(static_cast<int32_t>(JSImmediate::rawValue(getConstantOperand(op1)))), regT0);
-#endif
} else if (isOperandConstantImmediateInt(op2)) {
emitGetVirtualRegister(op1, regT0);
emitJumpSlowCaseIfNotImmediateInteger(regT0);
-#if USE(JSVALUE64)
int32_t imm = getConstantOperandImmediateInt(op2);
andPtr(Imm32(imm), regT0);
if (imm >= 0)
emitFastArithIntToImmNoCheck(regT0, regT0);
-#else
- andPtr(Imm32(static_cast<int32_t>(JSImmediate::rawValue(getConstantOperand(op2)))), regT0);
-#endif
} else {
emitGetVirtualRegisters(op1, regT0, op2, regT1);
andPtr(regT1, regT0);
@@ -1023,13 +773,8 @@ void JIT::emit_op_post_inc(Instruction* currentInstruction)
emitGetVirtualRegister(srcDst, regT0);
move(regT0, regT1);
emitJumpSlowCaseIfNotImmediateInteger(regT0);
-#if USE(JSVALUE64)
addSlowCase(branchAdd32(Overflow, Imm32(1), regT1));
emitFastArithIntToImmNoCheck(regT1, regT1);
-#else
- addSlowCase(branchAdd32(Overflow, Imm32(1 << JSImmediate::IntegerPayloadShift), regT1));
- signExtend32ToPtr(regT1, regT1);
-#endif
emitPutVirtualRegister(srcDst, regT1);
emitPutVirtualRegister(result);
}
@@ -1055,13 +800,8 @@ void JIT::emit_op_post_dec(Instruction* currentInstruction)
emitGetVirtualRegister(srcDst, regT0);
move(regT0, regT1);
emitJumpSlowCaseIfNotImmediateInteger(regT0);
-#if USE(JSVALUE64)
addSlowCase(branchSub32(Zero, Imm32(1), regT1));
emitFastArithIntToImmNoCheck(regT1, regT1);
-#else
- addSlowCase(branchSub32(Zero, Imm32(1 << JSImmediate::IntegerPayloadShift), regT1));
- signExtend32ToPtr(regT1, regT1);
-#endif
emitPutVirtualRegister(srcDst, regT1);
emitPutVirtualRegister(result);
}
@@ -1085,13 +825,8 @@ void JIT::emit_op_pre_inc(Instruction* currentInstruction)
emitGetVirtualRegister(srcDst, regT0);
emitJumpSlowCaseIfNotImmediateInteger(regT0);
-#if USE(JSVALUE64)
addSlowCase(branchAdd32(Overflow, Imm32(1), regT0));
emitFastArithIntToImmNoCheck(regT0, regT0);
-#else
- addSlowCase(branchAdd32(Overflow, Imm32(1 << JSImmediate::IntegerPayloadShift), regT0));
- signExtend32ToPtr(regT0, regT0);
-#endif
emitPutVirtualRegister(srcDst);
}
@@ -1114,13 +849,8 @@ void JIT::emit_op_pre_dec(Instruction* currentInstruction)
emitGetVirtualRegister(srcDst, regT0);
emitJumpSlowCaseIfNotImmediateInteger(regT0);
-#if USE(JSVALUE64)
addSlowCase(branchSub32(Zero, Imm32(1), regT0));
emitFastArithIntToImmNoCheck(regT0, regT0);
-#else
- addSlowCase(branchSub32(Zero, Imm32(1 << JSImmediate::IntegerPayloadShift), regT0));
- signExtend32ToPtr(regT0, regT0);
-#endif
emitPutVirtualRegister(srcDst);
}
@@ -1158,22 +888,9 @@ void JIT::emit_op_mod(Instruction* currentInstruction)
emitJumpSlowCaseIfNotImmediateInteger(regT0);
emitJumpSlowCaseIfNotImmediateInteger(regT2);
-#if USE(JSVALUE64)
addSlowCase(branchPtr(Equal, regT2, ImmPtr(JSValue::encode(jsNumber(m_globalData, 0)))));
m_assembler.cdq();
m_assembler.idivl_r(regT2);
-#else
- emitFastArithDeTagImmediate(regT0);
- addSlowCase(emitFastArithDeTagImmediateJumpIfZero(regT2));
-#if CPU(X86) || CPU(X86_64)
- m_assembler.cdq();
- m_assembler.idivl_r(regT2);
- signExtend32ToPtr(regT1, regT1);
-#elif CPU(MIPS)
- m_assembler.div(regT0, regT2);
- m_assembler.mfhi(regT1);
-#endif
-#endif
emitFastArithReTagImmediate(regT1, regT0);
emitPutVirtualRegister(result);
}
@@ -1182,19 +899,9 @@ void JIT::emitSlow_op_mod(Instruction* currentInstruction, Vector<SlowCaseEntry>
{
unsigned result = currentInstruction[1].u.operand;
-#if USE(JSVALUE64)
linkSlowCase(iter);
linkSlowCase(iter);
linkSlowCase(iter);
-#else
- Jump notImm1 = getSlowCase(iter);
- Jump notImm2 = getSlowCase(iter);
- linkSlowCase(iter);
- emitFastArithReTagImmediate(regT0, regT0);
- emitFastArithReTagImmediate(regT2, regT2);
- notImm1.link(this);
- notImm2.link(this);
-#endif
JITStubCall stubCall(this, cti_op_mod);
stubCall.addArgument(regT0);
stubCall.addArgument(regT2);
@@ -1249,8 +956,6 @@ void JIT::emitSlow_op_mod(Instruction* currentInstruction, Vector<SlowCaseEntry>
/* ------------------------------ END: OP_MOD ------------------------------ */
-#if USE(JSVALUE64)
-
/* ------------------------------ BEGIN: USE(JSVALUE64) (OP_ADD, OP_SUB, OP_MUL) ------------------------------ */
void JIT::compileBinaryArithOp(OpcodeID opcodeID, unsigned, unsigned op1, unsigned op2, OperandTypes)
@@ -1543,310 +1248,9 @@ void JIT::emitSlow_op_sub(Instruction* currentInstruction, Vector<SlowCaseEntry>
compileBinaryArithOpSlowCase(op_sub, iter, result, op1, op2, types, false, false);
}
-#else // USE(JSVALUE64)
-
-/* ------------------------------ BEGIN: !USE(JSVALUE64) (OP_ADD, OP_SUB, OP_MUL) ------------------------------ */
-
-void JIT::compileBinaryArithOp(OpcodeID opcodeID, unsigned dst, unsigned src1, unsigned src2, OperandTypes types)
-{
- Structure* numberStructure = m_globalData->numberStructure.get();
- Jump wasJSNumberCell1;
- Jump wasJSNumberCell2;
-
- emitGetVirtualRegisters(src1, regT0, src2, regT1);
-
- if (types.second().isReusable() && supportsFloatingPoint()) {
- ASSERT(types.second().mightBeNumber());
-
- // Check op2 is a number
- Jump op2imm = emitJumpIfImmediateInteger(regT1);
- if (!types.second().definitelyIsNumber()) {
- emitJumpSlowCaseIfNotJSCell(regT1, src2);
- addSlowCase(checkStructure(regT1, numberStructure));
- }
-
- // (1) In this case src2 is a reusable number cell.
- // Slow case if src1 is not a number type.
- Jump op1imm = emitJumpIfImmediateInteger(regT0);
- if (!types.first().definitelyIsNumber()) {
- emitJumpSlowCaseIfNotJSCell(regT0, src1);
- addSlowCase(checkStructure(regT0, numberStructure));
- }
-
- // (1a) if we get here, src1 is also a number cell
- loadDouble(Address(regT0, OBJECT_OFFSETOF(JSNumberCell, m_value)), fpRegT0);
- Jump loadedDouble = jump();
- // (1b) if we get here, src1 is an immediate
- op1imm.link(this);
- emitFastArithImmToInt(regT0);
- convertInt32ToDouble(regT0, fpRegT0);
- // (1c)
- loadedDouble.link(this);
- if (opcodeID == op_add)
- addDouble(Address(regT1, OBJECT_OFFSETOF(JSNumberCell, m_value)), fpRegT0);
- else if (opcodeID == op_sub)
- subDouble(Address(regT1, OBJECT_OFFSETOF(JSNumberCell, m_value)), fpRegT0);
- else {
- ASSERT(opcodeID == op_mul);
- mulDouble(Address(regT1, OBJECT_OFFSETOF(JSNumberCell, m_value)), fpRegT0);
- }
-
- // Store the result to the JSNumberCell and jump.
- storeDouble(fpRegT0, Address(regT1, OBJECT_OFFSETOF(JSNumberCell, m_value)));
- move(regT1, regT0);
- emitPutVirtualRegister(dst);
- wasJSNumberCell2 = jump();
-
- // (2) This handles cases where src2 is an immediate number.
- // Two slow cases - either src1 isn't an immediate, or the subtract overflows.
- op2imm.link(this);
- emitJumpSlowCaseIfNotImmediateInteger(regT0);
- } else if (types.first().isReusable() && supportsFloatingPoint()) {
- ASSERT(types.first().mightBeNumber());
-
- // Check op1 is a number
- Jump op1imm = emitJumpIfImmediateInteger(regT0);
- if (!types.first().definitelyIsNumber()) {
- emitJumpSlowCaseIfNotJSCell(regT0, src1);
- addSlowCase(checkStructure(regT0, numberStructure));
- }
-
- // (1) In this case src1 is a reusable number cell.
- // Slow case if src2 is not a number type.
- Jump op2imm = emitJumpIfImmediateInteger(regT1);
- if (!types.second().definitelyIsNumber()) {
- emitJumpSlowCaseIfNotJSCell(regT1, src2);
- addSlowCase(checkStructure(regT1, numberStructure));
- }
-
- // (1a) if we get here, src2 is also a number cell
- loadDouble(Address(regT1, OBJECT_OFFSETOF(JSNumberCell, m_value)), fpRegT1);
- Jump loadedDouble = jump();
- // (1b) if we get here, src2 is an immediate
- op2imm.link(this);
- emitFastArithImmToInt(regT1);
- convertInt32ToDouble(regT1, fpRegT1);
- // (1c)
- loadedDouble.link(this);
- loadDouble(Address(regT0, OBJECT_OFFSETOF(JSNumberCell, m_value)), fpRegT0);
- if (opcodeID == op_add)
- addDouble(fpRegT1, fpRegT0);
- else if (opcodeID == op_sub)
- subDouble(fpRegT1, fpRegT0);
- else {
- ASSERT(opcodeID == op_mul);
- mulDouble(fpRegT1, fpRegT0);
- }
- storeDouble(fpRegT0, Address(regT0, OBJECT_OFFSETOF(JSNumberCell, m_value)));
- emitPutVirtualRegister(dst);
-
- // Store the result to the JSNumberCell and jump.
- storeDouble(fpRegT0, Address(regT0, OBJECT_OFFSETOF(JSNumberCell, m_value)));
- emitPutVirtualRegister(dst);
- wasJSNumberCell1 = jump();
-
- // (2) This handles cases where src1 is an immediate number.
- // Two slow cases - either src2 isn't an immediate, or the subtract overflows.
- op1imm.link(this);
- emitJumpSlowCaseIfNotImmediateInteger(regT1);
- } else
- emitJumpSlowCaseIfNotImmediateIntegers(regT0, regT1, regT2);
-
- if (opcodeID == op_add) {
- emitFastArithDeTagImmediate(regT0);
- addSlowCase(branchAdd32(Overflow, regT1, regT0));
- } else if (opcodeID == op_sub) {
- addSlowCase(branchSub32(Overflow, regT1, regT0));
- signExtend32ToPtr(regT0, regT0);
- emitFastArithReTagImmediate(regT0, regT0);
- } else {
- ASSERT(opcodeID == op_mul);
- // convert eax & edx from JSImmediates to ints, and check if either are zero
- emitFastArithImmToInt(regT1);
- Jump op1Zero = emitFastArithDeTagImmediateJumpIfZero(regT0);
- Jump op2NonZero = branchTest32(NonZero, regT1);
- op1Zero.link(this);
- // if either input is zero, add the two together, and check if the result is < 0.
- // If it is, we have a problem (N < 0), (N * 0) == -0, not representatble as a JSImmediate.
- move(regT0, regT2);
- addSlowCase(branchAdd32(Signed, regT1, regT2));
- // Skip the above check if neither input is zero
- op2NonZero.link(this);
- addSlowCase(branchMul32(Overflow, regT1, regT0));
- signExtend32ToPtr(regT0, regT0);
- emitFastArithReTagImmediate(regT0, regT0);
- }
- emitPutVirtualRegister(dst);
-
- if (types.second().isReusable() && supportsFloatingPoint())
- wasJSNumberCell2.link(this);
- else if (types.first().isReusable() && supportsFloatingPoint())
- wasJSNumberCell1.link(this);
-}
-
-void JIT::compileBinaryArithOpSlowCase(OpcodeID opcodeID, Vector<SlowCaseEntry>::iterator& iter, unsigned dst, unsigned src1, unsigned src2, OperandTypes types)
-{
- linkSlowCase(iter);
- if (types.second().isReusable() && supportsFloatingPoint()) {
- if (!types.first().definitelyIsNumber()) {
- linkSlowCaseIfNotJSCell(iter, src1);
- linkSlowCase(iter);
- }
- if (!types.second().definitelyIsNumber()) {
- linkSlowCaseIfNotJSCell(iter, src2);
- linkSlowCase(iter);
- }
- } else if (types.first().isReusable() && supportsFloatingPoint()) {
- if (!types.first().definitelyIsNumber()) {
- linkSlowCaseIfNotJSCell(iter, src1);
- linkSlowCase(iter);
- }
- if (!types.second().definitelyIsNumber()) {
- linkSlowCaseIfNotJSCell(iter, src2);
- linkSlowCase(iter);
- }
- }
- linkSlowCase(iter);
-
- // additional entry point to handle -0 cases.
- if (opcodeID == op_mul)
- linkSlowCase(iter);
-
- JITStubCall stubCall(this, opcodeID == op_add ? cti_op_add : opcodeID == op_sub ? cti_op_sub : cti_op_mul);
- stubCall.addArgument(src1, regT2);
- stubCall.addArgument(src2, regT2);
- stubCall.call(dst);
-}
-
-void JIT::emit_op_add(Instruction* currentInstruction)
-{
- unsigned result = currentInstruction[1].u.operand;
- unsigned op1 = currentInstruction[2].u.operand;
- unsigned op2 = currentInstruction[3].u.operand;
- OperandTypes types = OperandTypes::fromInt(currentInstruction[4].u.operand);
-
- if (!types.first().mightBeNumber() || !types.second().mightBeNumber()) {
- JITStubCall stubCall(this, cti_op_add);
- stubCall.addArgument(op1, regT2);
- stubCall.addArgument(op2, regT2);
- stubCall.call(result);
- return;
- }
-
- if (isOperandConstantImmediateInt(op1)) {
- emitGetVirtualRegister(op2, regT0);
- emitJumpSlowCaseIfNotImmediateInteger(regT0);
- addSlowCase(branchAdd32(Overflow, Imm32(getConstantOperandImmediateInt(op1) << JSImmediate::IntegerPayloadShift), regT0));
- signExtend32ToPtr(regT0, regT0);
- emitPutVirtualRegister(result);
- } else if (isOperandConstantImmediateInt(op2)) {
- emitGetVirtualRegister(op1, regT0);
- emitJumpSlowCaseIfNotImmediateInteger(regT0);
- addSlowCase(branchAdd32(Overflow, Imm32(getConstantOperandImmediateInt(op2) << JSImmediate::IntegerPayloadShift), regT0));
- signExtend32ToPtr(regT0, regT0);
- emitPutVirtualRegister(result);
- } else {
- compileBinaryArithOp(op_add, result, op1, op2, OperandTypes::fromInt(currentInstruction[4].u.operand));
- }
-}
-
-void JIT::emitSlow_op_add(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
-{
- unsigned result = currentInstruction[1].u.operand;
- unsigned op1 = currentInstruction[2].u.operand;
- unsigned op2 = currentInstruction[3].u.operand;
-
- OperandTypes types = OperandTypes::fromInt(currentInstruction[4].u.operand);
- if (!types.first().mightBeNumber() || !types.second().mightBeNumber())
- return;
-
- if (isOperandConstantImmediateInt(op1)) {
- Jump notImm = getSlowCase(iter);
- linkSlowCase(iter);
- sub32(Imm32(getConstantOperandImmediateInt(op1) << JSImmediate::IntegerPayloadShift), regT0);
- notImm.link(this);
- JITStubCall stubCall(this, cti_op_add);
- stubCall.addArgument(op1, regT2);
- stubCall.addArgument(regT0);
- stubCall.call(result);
- } else if (isOperandConstantImmediateInt(op2)) {
- Jump notImm = getSlowCase(iter);
- linkSlowCase(iter);
- sub32(Imm32(getConstantOperandImmediateInt(op2) << JSImmediate::IntegerPayloadShift), regT0);
- notImm.link(this);
- JITStubCall stubCall(this, cti_op_add);
- stubCall.addArgument(regT0);
- stubCall.addArgument(op2, regT2);
- stubCall.call(result);
- } else {
- OperandTypes types = OperandTypes::fromInt(currentInstruction[4].u.operand);
- ASSERT(types.first().mightBeNumber() && types.second().mightBeNumber());
- compileBinaryArithOpSlowCase(op_add, iter, result, op1, op2, types);
- }
-}
-
-void JIT::emit_op_mul(Instruction* currentInstruction)
-{
- unsigned result = currentInstruction[1].u.operand;
- unsigned op1 = currentInstruction[2].u.operand;
- unsigned op2 = currentInstruction[3].u.operand;
-
- // For now, only plant a fast int case if the constant operand is greater than zero.
- int32_t value;
- if (isOperandConstantImmediateInt(op1) && ((value = getConstantOperandImmediateInt(op1)) > 0)) {
- emitGetVirtualRegister(op2, regT0);
- emitJumpSlowCaseIfNotImmediateInteger(regT0);
- emitFastArithDeTagImmediate(regT0);
- addSlowCase(branchMul32(Overflow, Imm32(value), regT0, regT0));
- signExtend32ToPtr(regT0, regT0);
- emitFastArithReTagImmediate(regT0, regT0);
- emitPutVirtualRegister(result);
- } else if (isOperandConstantImmediateInt(op2) && ((value = getConstantOperandImmediateInt(op2)) > 0)) {
- emitGetVirtualRegister(op1, regT0);
- emitJumpSlowCaseIfNotImmediateInteger(regT0);
- emitFastArithDeTagImmediate(regT0);
- addSlowCase(branchMul32(Overflow, Imm32(value), regT0, regT0));
- signExtend32ToPtr(regT0, regT0);
- emitFastArithReTagImmediate(regT0, regT0);
- emitPutVirtualRegister(result);
- } else
- compileBinaryArithOp(op_mul, result, op1, op2, OperandTypes::fromInt(currentInstruction[4].u.operand));
-}
-
-void JIT::emitSlow_op_mul(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
-{
- unsigned result = currentInstruction[1].u.operand;
- unsigned op1 = currentInstruction[2].u.operand;
- unsigned op2 = currentInstruction[3].u.operand;
-
- if ((isOperandConstantImmediateInt(op1) && (getConstantOperandImmediateInt(op1) > 0))
- || (isOperandConstantImmediateInt(op2) && (getConstantOperandImmediateInt(op2) > 0))) {
- linkSlowCase(iter);
- linkSlowCase(iter);
- // There is an extra slow case for (op1 * -N) or (-N * op2), to check for 0 since this should produce a result of -0.
- JITStubCall stubCall(this, cti_op_mul);
- stubCall.addArgument(op1, regT2);
- stubCall.addArgument(op2, regT2);
- stubCall.call(result);
- } else
- compileBinaryArithOpSlowCase(op_mul, iter, result, op1, op2, OperandTypes::fromInt(currentInstruction[4].u.operand));
-}
-
-void JIT::emit_op_sub(Instruction* currentInstruction)
-{
- compileBinaryArithOp(op_sub, currentInstruction[1].u.operand, currentInstruction[2].u.operand, currentInstruction[3].u.operand, OperandTypes::fromInt(currentInstruction[4].u.operand));
-}
-
-void JIT::emitSlow_op_sub(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
-{
- compileBinaryArithOpSlowCase(op_sub, iter, currentInstruction[1].u.operand, currentInstruction[2].u.operand, currentInstruction[3].u.operand, OperandTypes::fromInt(currentInstruction[4].u.operand));
-}
-
-#endif // USE(JSVALUE64)
-
/* ------------------------------ END: OP_ADD, OP_SUB, OP_MUL ------------------------------ */
} // namespace JSC
-#endif // !USE(JSVALUE32_64)
+#endif // USE(JSVALUE64)
#endif // ENABLE(JIT)
diff --git a/JavaScriptCore/jit/JITCall.cpp b/JavaScriptCore/jit/JITCall.cpp
index 368eab9..fdd0d47 100644
--- a/JavaScriptCore/jit/JITCall.cpp
+++ b/JavaScriptCore/jit/JITCall.cpp
@@ -26,7 +26,7 @@
#include "config.h"
#if ENABLE(JIT)
-#if !USE(JSVALUE32_64)
+#if USE(JSVALUE64)
#include "JIT.h"
#include "CodeBlock.h"
@@ -257,5 +257,5 @@ void JIT::compileOpCallSlowCase(Instruction* instruction, Vector<SlowCaseEntry>:
} // namespace JSC
-#endif // !USE(JSVALUE32_64)
+#endif // USE(JSVALUE64)
#endif // ENABLE(JIT)
diff --git a/JavaScriptCore/jit/JITCall32_64.cpp b/JavaScriptCore/jit/JITCall32_64.cpp
index e4005ae..daf5d2d 100644
--- a/JavaScriptCore/jit/JITCall32_64.cpp
+++ b/JavaScriptCore/jit/JITCall32_64.cpp
@@ -108,9 +108,11 @@ void JIT::emit_op_ret(Instruction* currentInstruction)
unsigned dst = currentInstruction[1].u.operand;
// We could JIT generate the deref, only calling out to C when the refcount hits zero.
- if (m_codeBlock->needsFullScopeChain())
+ if (m_codeBlock->needsFullScopeChain()) {
+ Jump activationNotCreated = branch32(Equal, tagFor(m_codeBlock->activationRegister()), Imm32(JSValue::EmptyValueTag));
JITStubCall(this, cti_op_ret_scopeChain).call();
-
+ activationNotCreated.link(this);
+ }
emitLoad(dst, regT1, regT0);
emitGetFromCallFrameHeaderPtr(RegisterFile::ReturnPC, regT2);
emitGetFromCallFrameHeaderPtr(RegisterFile::CallerFrame, callFrameRegister);
@@ -125,8 +127,11 @@ void JIT::emit_op_ret_object_or_this(Instruction* currentInstruction)
unsigned thisReg = currentInstruction[2].u.operand;
// We could JIT generate the deref, only calling out to C when the refcount hits zero.
- if (m_codeBlock->needsFullScopeChain())
+ if (m_codeBlock->needsFullScopeChain()) {
+ Jump activationNotCreated = branch32(Equal, tagFor(m_codeBlock->activationRegister()), Imm32(JSValue::EmptyValueTag));
JITStubCall(this, cti_op_ret_scopeChain).call();
+ activationNotCreated.link(this);
+ }
emitLoad(result, regT1, regT0);
Jump notJSCell = branch32(NotEqual, regT1, Imm32(JSValue::CellTag));
diff --git a/JavaScriptCore/jit/JITInlineMethods.h b/JavaScriptCore/jit/JITInlineMethods.h
index e2e77db..0fe9929 100644
--- a/JavaScriptCore/jit/JITInlineMethods.h
+++ b/JavaScriptCore/jit/JITInlineMethods.h
@@ -63,7 +63,7 @@ ALWAYS_INLINE void JIT::emitPutImmediateToCallFrameHeader(void* value, RegisterF
ALWAYS_INLINE void JIT::emitGetFromCallFrameHeaderPtr(RegisterFile::CallFrameHeaderEntry entry, RegisterID to, RegisterID from)
{
loadPtr(Address(from, entry * sizeof(Register)), to);
-#if !USE(JSVALUE32_64)
+#if USE(JSVALUE64)
killLastResultRegister();
#endif
}
@@ -81,7 +81,7 @@ ALWAYS_INLINE void JIT::emitLoadCharacterString(RegisterID src, RegisterID dst,
ALWAYS_INLINE void JIT::emitGetFromCallFrameHeader32(RegisterFile::CallFrameHeaderEntry entry, RegisterID to, RegisterID from)
{
load32(Address(from, entry * sizeof(Register)), to);
-#if !USE(JSVALUE32_64)
+#if USE(JSVALUE64)
killLastResultRegister();
#endif
}
@@ -750,7 +750,7 @@ ALWAYS_INLINE void JIT::emitJumpSlowCaseIfNotImmediateNumber(RegisterID reg)
addSlowCase(emitJumpIfNotImmediateNumber(reg));
}
-#if !USE(JSVALUE64)
+#if USE(JSVALUE32_64)
ALWAYS_INLINE void JIT::emitFastArithDeTagImmediate(RegisterID reg)
{
subPtr(Imm32(JSImmediate::TagTypeNumber), reg);
diff --git a/JavaScriptCore/jit/JITOpcodes.cpp b/JavaScriptCore/jit/JITOpcodes.cpp
index c81932a..a468c18 100644
--- a/JavaScriptCore/jit/JITOpcodes.cpp
+++ b/JavaScriptCore/jit/JITOpcodes.cpp
@@ -39,7 +39,7 @@
namespace JSC {
-#if !USE(JSVALUE32_64)
+#if USE(JSVALUE64)
#define RECORD_JUMP_TARGET(targetOffset) \
do { m_labels[m_bytecodeOffset + (targetOffset)].used(); } while (false)
@@ -337,6 +337,7 @@ void JIT::emit_op_end(Instruction* currentInstruction)
{
if (m_codeBlock->needsFullScopeChain())
JITStubCall(this, cti_op_end).call();
+
ASSERT(returnValueRegister != callFrameRegister);
emitGetVirtualRegister(currentInstruction[1].u.operand, returnValueRegister);
restoreReturnAddressBeforeReturn(Address(callFrameRegister, RegisterFile::ReturnPC * static_cast<int>(sizeof(Register))));
@@ -360,11 +361,7 @@ void JIT::emit_op_loop_if_lesseq(Instruction* currentInstruction)
if (isOperandConstantImmediateInt(op2)) {
emitGetVirtualRegister(op1, regT0);
emitJumpSlowCaseIfNotImmediateInteger(regT0);
-#if USE(JSVALUE64)
int32_t op2imm = getConstantOperandImmediateInt(op2);
-#else
- int32_t op2imm = static_cast<int32_t>(JSImmediate::rawValue(getConstantOperand(op2)));
-#endif
addJump(branch32(LessThanOrEqual, regT0, Imm32(op2imm)), target);
} else {
emitGetVirtualRegisters(op1, regT0, op2, regT1);
@@ -467,6 +464,15 @@ void JIT::emit_op_get_scoped_var(Instruction* currentInstruction)
int skip = currentInstruction[3].u.operand;
emitGetFromCallFrameHeaderPtr(RegisterFile::ScopeChain, regT0);
+ bool checkTopLevel = m_codeBlock->codeType() == FunctionCode && m_codeBlock->needsFullScopeChain();
+ ASSERT(skip || !checkTopLevel);
+ if (checkTopLevel && skip--) {
+ Jump activationNotCreated;
+ if (checkTopLevel)
+ activationNotCreated = branchTestPtr(Zero, addressFor(m_codeBlock->activationRegister()));
+ loadPtr(Address(regT0, OBJECT_OFFSETOF(ScopeChainNode, next)), regT0);
+ activationNotCreated.link(this);
+ }
while (skip--)
loadPtr(Address(regT0, OBJECT_OFFSETOF(ScopeChainNode, next)), regT0);
@@ -481,6 +487,15 @@ void JIT::emit_op_put_scoped_var(Instruction* currentInstruction)
emitGetFromCallFrameHeaderPtr(RegisterFile::ScopeChain, regT1);
emitGetVirtualRegister(currentInstruction[3].u.operand, regT0);
+ bool checkTopLevel = m_codeBlock->codeType() == FunctionCode && m_codeBlock->needsFullScopeChain();
+ ASSERT(skip || !checkTopLevel);
+ if (checkTopLevel && skip--) {
+ Jump activationNotCreated;
+ if (checkTopLevel)
+ activationNotCreated = branchTestPtr(Zero, addressFor(m_codeBlock->activationRegister()));
+ loadPtr(Address(regT1, OBJECT_OFFSETOF(ScopeChainNode, next)), regT1);
+ activationNotCreated.link(this);
+ }
while (skip--)
loadPtr(Address(regT1, OBJECT_OFFSETOF(ScopeChainNode, next)), regT1);
@@ -490,10 +505,16 @@ void JIT::emit_op_put_scoped_var(Instruction* currentInstruction)
void JIT::emit_op_tear_off_activation(Instruction* currentInstruction)
{
+ unsigned activation = currentInstruction[1].u.operand;
+ unsigned arguments = currentInstruction[2].u.operand;
+ Jump activationCreated = branchTestPtr(NonZero, addressFor(activation));
+ Jump argumentsNotCreated = branchTestPtr(Zero, addressFor(arguments));
+ activationCreated.link(this);
JITStubCall stubCall(this, cti_op_tear_off_activation);
- stubCall.addArgument(currentInstruction[1].u.operand, regT2);
- stubCall.addArgument(unmodifiedArgumentsRegister(currentInstruction[2].u.operand), regT2);
+ stubCall.addArgument(activation, regT2);
+ stubCall.addArgument(unmodifiedArgumentsRegister(arguments), regT2);
stubCall.call();
+ argumentsNotCreated.link(this);
}
void JIT::emit_op_tear_off_arguments(Instruction* currentInstruction)
@@ -510,9 +531,11 @@ void JIT::emit_op_tear_off_arguments(Instruction* currentInstruction)
void JIT::emit_op_ret(Instruction* currentInstruction)
{
// We could JIT generate the deref, only calling out to C when the refcount hits zero.
- if (m_codeBlock->needsFullScopeChain())
+ if (m_codeBlock->needsFullScopeChain()) {
+ Jump activationNotCreated = branchTestPtr(Zero, addressFor(m_codeBlock->activationRegister()));
JITStubCall(this, cti_op_ret_scopeChain).call();
-
+ activationNotCreated.link(this);
+ }
ASSERT(callFrameRegister != regT1);
ASSERT(regT1 != returnValueRegister);
ASSERT(returnValueRegister != callFrameRegister);
@@ -534,8 +557,11 @@ void JIT::emit_op_ret(Instruction* currentInstruction)
void JIT::emit_op_ret_object_or_this(Instruction* currentInstruction)
{
// We could JIT generate the deref, only calling out to C when the refcount hits zero.
- if (m_codeBlock->needsFullScopeChain())
+ if (m_codeBlock->needsFullScopeChain()) {
+ Jump activationNotCreated = branchTestPtr(Zero, addressFor(m_codeBlock->activationRegister()));
JITStubCall(this, cti_op_ret_scopeChain).call();
+ activationNotCreated.link(this);
+ }
ASSERT(callFrameRegister != regT1);
ASSERT(regT1 != returnValueRegister);
@@ -614,7 +640,15 @@ void JIT::emit_op_strcat(Instruction* currentInstruction)
void JIT::emit_op_resolve_base(Instruction* currentInstruction)
{
- JITStubCall stubCall(this, cti_op_resolve_base);
+ JITStubCall stubCall(this, currentInstruction[3].u.operand ? cti_op_resolve_base_strict_put : cti_op_resolve_base);
+ stubCall.addArgument(ImmPtr(&m_codeBlock->identifier(currentInstruction[2].u.operand)));
+ stubCall.call(currentInstruction[1].u.operand);
+}
+
+void JIT::emit_op_ensure_property_exists(Instruction* currentInstruction)
+{
+ JITStubCall stubCall(this, cti_op_ensure_property_exists);
+ stubCall.addArgument(Imm32(currentInstruction[1].u.operand));
stubCall.addArgument(ImmPtr(&m_codeBlock->identifier(currentInstruction[2].u.operand)));
stubCall.call(currentInstruction[1].u.operand);
}
@@ -772,12 +806,8 @@ void JIT::emit_op_bitnot(Instruction* currentInstruction)
{
emitGetVirtualRegister(currentInstruction[2].u.operand, regT0);
emitJumpSlowCaseIfNotImmediateInteger(regT0);
-#if USE(JSVALUE64)
not32(regT0);
emitFastArithIntToImmNoCheck(regT0, regT0);
-#else
- xorPtr(Imm32(~JSImmediate::TagTypeNumber), regT0);
-#endif
emitPutVirtualRegister(currentInstruction[1].u.operand);
}
@@ -865,7 +895,7 @@ void JIT::emit_op_get_pnames(Instruction* currentInstruction)
emitGetVirtualRegister(base, regT0);
if (!m_codeBlock->isKnownNotImmediate(base))
isNotObject.append(emitJumpIfNotJSCell(regT0));
- if (base != m_codeBlock->thisRegister()) {
+ if (base != m_codeBlock->thisRegister() || m_codeBlock->isStrictMode()) {
loadPtr(Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure)), regT2);
isNotObject.append(branch8(NotEqual, Address(regT2, OBJECT_OFFSETOF(Structure, m_typeInfo.m_type)), Imm32(ObjectType)));
}
@@ -913,11 +943,7 @@ void JIT::emit_op_next_pname(Instruction* currentInstruction)
loadPtr(addressFor(it), regT1);
loadPtr(Address(regT1, OBJECT_OFFSETOF(JSPropertyNameIterator, m_jsStrings)), regT2);
-#if USE(JSVALUE64)
loadPtr(BaseIndex(regT2, regT0, TimesEight), regT2);
-#else
- loadPtr(BaseIndex(regT2, regT0, TimesFour), regT2);
-#endif
emitPutVirtualRegister(dst, regT2);
@@ -1185,16 +1211,14 @@ void JIT::emit_op_enter(Instruction*)
}
-void JIT::emit_op_enter_with_activation(Instruction* currentInstruction)
+void JIT::emit_op_create_activation(Instruction* currentInstruction)
{
- // Even though CTI doesn't use them, we initialize our constant
- // registers to zap stale pointers, to avoid unnecessarily prolonging
- // object lifetime and increasing GC pressure.
- size_t count = m_codeBlock->m_numVars;
- for (size_t j = 0; j < count; ++j)
- emitInitRegister(j);
-
+ unsigned dst = currentInstruction[1].u.operand;
+
+ Jump activationCreated = branchTestPtr(NonZero, Address(callFrameRegister, sizeof(Register) * dst));
JITStubCall(this, cti_op_push_activation).call(currentInstruction[1].u.operand);
+ emitPutVirtualRegister(dst);
+ activationCreated.link(this);
}
void JIT::emit_op_create_arguments(Instruction* currentInstruction)
@@ -1227,6 +1251,23 @@ void JIT::emit_op_convert_this(Instruction* currentInstruction)
addSlowCase(branchTest8(NonZero, Address(regT1, OBJECT_OFFSETOF(Structure, m_typeInfo.m_flags)), Imm32(NeedsThisConversion)));
}
+void JIT::emit_op_convert_this_strict(Instruction* currentInstruction)
+{
+ emitGetVirtualRegister(currentInstruction[1].u.operand, regT0);
+ Jump notNull = branchTestPtr(NonZero, regT0);
+ move(ImmPtr(JSValue::encode(jsNull())), regT0);
+ emitPutVirtualRegister(currentInstruction[1].u.operand, regT0);
+ Jump setThis = jump();
+ notNull.link(this);
+ Jump isImmediate = emitJumpIfNotJSCell(regT0);
+ loadPtr(Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure)), regT1);
+ Jump notAnObject = branch8(NotEqual, Address(regT3, OBJECT_OFFSETOF(Structure, m_typeInfo.m_type)), Imm32(ObjectType));
+ addSlowCase(branchTest8(NonZero, Address(regT1, OBJECT_OFFSETOF(Structure, m_typeInfo.m_flags)), Imm32(NeedsThisConversion)));
+ isImmediate.link(this);
+ notAnObject.link(this);
+ setThis.link(this);
+}
+
void JIT::emit_op_get_callee(Instruction* currentInstruction)
{
unsigned result = currentInstruction[1].u.operand;
@@ -1276,6 +1317,14 @@ void JIT::emitSlow_op_convert_this(Instruction* currentInstruction, Vector<SlowC
stubCall.call(currentInstruction[1].u.operand);
}
+void JIT::emitSlow_op_convert_this_strict(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
+{
+ linkSlowCase(iter);
+ JITStubCall stubCall(this, cti_op_convert_this_strict);
+ stubCall.addArgument(regT0);
+ stubCall.call(currentInstruction[1].u.operand);
+}
+
void JIT::emitSlow_op_to_primitive(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
{
linkSlowCase(iter);
@@ -1552,13 +1601,25 @@ void JIT::emitSlow_op_get_argument_by_val(Instruction* currentInstruction, Vecto
stubCall.call(dst);
}
-#endif // !USE(JSVALUE32_64)
+#endif // USE(JSVALUE64)
void JIT::emit_op_resolve_global_dynamic(Instruction* currentInstruction)
{
int skip = currentInstruction[5].u.operand;
emitGetFromCallFrameHeaderPtr(RegisterFile::ScopeChain, regT0);
+
+ bool checkTopLevel = m_codeBlock->codeType() == FunctionCode && m_codeBlock->needsFullScopeChain();
+ ASSERT(skip || !checkTopLevel);
+ if (checkTopLevel && skip--) {
+ Jump activationNotCreated;
+ if (checkTopLevel)
+ activationNotCreated = branchTestPtr(Zero, addressFor(m_codeBlock->activationRegister()));
+ loadPtr(Address(regT0, OBJECT_OFFSETOF(ScopeChainNode, object)), regT1);
+ addSlowCase(checkStructure(regT1, m_globalData->activationStructure.get()));
+ loadPtr(Address(regT0, OBJECT_OFFSETOF(ScopeChainNode, next)), regT0);
+ activationNotCreated.link(this);
+ }
while (skip--) {
loadPtr(Address(regT0, OBJECT_OFFSETOF(ScopeChainNode, object)), regT1);
addSlowCase(checkStructure(regT1, m_globalData->activationStructure.get()));
diff --git a/JavaScriptCore/jit/JITOpcodes32_64.cpp b/JavaScriptCore/jit/JITOpcodes32_64.cpp
index ad3b558..c3b7ac2 100644
--- a/JavaScriptCore/jit/JITOpcodes32_64.cpp
+++ b/JavaScriptCore/jit/JITOpcodes32_64.cpp
@@ -610,6 +610,15 @@ void JIT::emit_op_get_scoped_var(Instruction* currentInstruction)
int skip = currentInstruction[3].u.operand;
emitGetFromCallFrameHeaderPtr(RegisterFile::ScopeChain, regT2);
+ bool checkTopLevel = m_codeBlock->codeType() == FunctionCode && m_codeBlock->needsFullScopeChain();
+ ASSERT(skip || !checkTopLevel);
+ if (checkTopLevel && skip--) {
+ Jump activationNotCreated;
+ if (checkTopLevel)
+ activationNotCreated = branch32(Equal, tagFor(m_codeBlock->activationRegister()), Imm32(JSValue::EmptyValueTag));
+ loadPtr(Address(regT2, OBJECT_OFFSETOF(ScopeChainNode, next)), regT2);
+ activationNotCreated.link(this);
+ }
while (skip--)
loadPtr(Address(regT2, OBJECT_OFFSETOF(ScopeChainNode, next)), regT2);
@@ -631,6 +640,15 @@ void JIT::emit_op_put_scoped_var(Instruction* currentInstruction)
emitLoad(value, regT1, regT0);
emitGetFromCallFrameHeaderPtr(RegisterFile::ScopeChain, regT2);
+ bool checkTopLevel = m_codeBlock->codeType() == FunctionCode && m_codeBlock->needsFullScopeChain();
+ ASSERT(skip || !checkTopLevel);
+ if (checkTopLevel && skip--) {
+ Jump activationNotCreated;
+ if (checkTopLevel)
+ activationNotCreated = branch32(Equal, tagFor(m_codeBlock->activationRegister()), Imm32(JSValue::EmptyValueTag));
+ loadPtr(Address(regT2, OBJECT_OFFSETOF(ScopeChainNode, next)), regT2);
+ activationNotCreated.link(this);
+ }
while (skip--)
loadPtr(Address(regT2, OBJECT_OFFSETOF(ScopeChainNode, next)), regT2);
@@ -644,10 +662,16 @@ void JIT::emit_op_put_scoped_var(Instruction* currentInstruction)
void JIT::emit_op_tear_off_activation(Instruction* currentInstruction)
{
+ unsigned activation = currentInstruction[1].u.operand;
+ unsigned arguments = currentInstruction[2].u.operand;
+ Jump activationCreated = branch32(NotEqual, tagFor(activation), Imm32(JSValue::EmptyValueTag));
+ Jump argumentsNotCreated = branch32(Equal, tagFor(arguments), Imm32(JSValue::EmptyValueTag));
+ activationCreated.link(this);
JITStubCall stubCall(this, cti_op_tear_off_activation);
stubCall.addArgument(currentInstruction[1].u.operand);
stubCall.addArgument(unmodifiedArgumentsRegister(currentInstruction[2].u.operand));
stubCall.call();
+ argumentsNotCreated.link(this);
}
void JIT::emit_op_tear_off_arguments(Instruction* currentInstruction)
@@ -713,7 +737,15 @@ void JIT::emit_op_strcat(Instruction* currentInstruction)
void JIT::emit_op_resolve_base(Instruction* currentInstruction)
{
- JITStubCall stubCall(this, cti_op_resolve_base);
+ JITStubCall stubCall(this, currentInstruction[3].u.operand ? cti_op_resolve_base_strict_put : cti_op_resolve_base);
+ stubCall.addArgument(ImmPtr(&m_codeBlock->identifier(currentInstruction[2].u.operand)));
+ stubCall.call(currentInstruction[1].u.operand);
+}
+
+void JIT::emit_op_ensure_property_exists(Instruction* currentInstruction)
+{
+ JITStubCall stubCall(this, cti_op_ensure_property_exists);
+ stubCall.addArgument(Imm32(currentInstruction[1].u.operand));
stubCall.addArgument(ImmPtr(&m_codeBlock->identifier(currentInstruction[2].u.operand)));
stubCall.call(currentInstruction[1].u.operand);
}
@@ -1215,7 +1247,7 @@ void JIT::emit_op_get_pnames(Instruction* currentInstruction)
emitLoad(base, regT1, regT0);
if (!m_codeBlock->isKnownNotImmediate(base))
isNotObject.append(branch32(NotEqual, regT1, Imm32(JSValue::CellTag)));
- if (base != m_codeBlock->thisRegister()) {
+ if (base != m_codeBlock->thisRegister() || m_codeBlock->isStrictMode()) {
loadPtr(Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure)), regT2);
isNotObject.append(branch8(NotEqual, Address(regT2, OBJECT_OFFSETOF(Structure, m_typeInfo.m_type)), Imm32(ObjectType)));
}
@@ -1467,11 +1499,13 @@ void JIT::emit_op_enter(Instruction*)
emitStore(i, jsUndefined());
}
-void JIT::emit_op_enter_with_activation(Instruction* currentInstruction)
+void JIT::emit_op_create_activation(Instruction* currentInstruction)
{
- emit_op_enter(currentInstruction);
-
- JITStubCall(this, cti_op_push_activation).call(currentInstruction[1].u.operand);
+ unsigned activation = currentInstruction[1].u.operand;
+
+ Jump activationCreated = branch32(NotEqual, tagFor(activation), Imm32(JSValue::EmptyValueTag));
+ JITStubCall(this, cti_op_push_activation).call(activation);
+ activationCreated.link(this);
}
void JIT::emit_op_create_arguments(Instruction* currentInstruction)
@@ -1528,6 +1562,26 @@ void JIT::emit_op_convert_this(Instruction* currentInstruction)
map(m_bytecodeOffset + OPCODE_LENGTH(op_convert_this), thisRegister, regT1, regT0);
}
+void JIT::emit_op_convert_this_strict(Instruction* currentInstruction)
+{
+ unsigned thisRegister = currentInstruction[1].u.operand;
+
+ emitLoad(thisRegister, regT1, regT0);
+
+ Jump notNull = branch32(NotEqual, regT1, Imm32(JSValue::EmptyValueTag));
+ emitStore(thisRegister, jsNull());
+ Jump setThis = jump();
+ notNull.link(this);
+ Jump isImmediate = branch32(NotEqual, regT1, Imm32(JSValue::CellTag));
+ loadPtr(Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure)), regT2);
+ Jump notAnObject = branch8(NotEqual, Address(regT3, OBJECT_OFFSETOF(Structure, m_typeInfo.m_type)), Imm32(ObjectType));
+ addSlowCase(branchTest8(NonZero, Address(regT2, OBJECT_OFFSETOF(Structure, m_typeInfo.m_flags)), Imm32(NeedsThisConversion)));
+ isImmediate.link(this);
+ notAnObject.link(this);
+ setThis.link(this);
+ map(m_bytecodeOffset + OPCODE_LENGTH(op_convert_this_strict), thisRegister, regT1, regT0);
+}
+
void JIT::emitSlow_op_convert_this(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
{
unsigned thisRegister = currentInstruction[1].u.operand;
@@ -1540,6 +1594,17 @@ void JIT::emitSlow_op_convert_this(Instruction* currentInstruction, Vector<SlowC
stubCall.call(thisRegister);
}
+void JIT::emitSlow_op_convert_this_strict(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
+{
+ unsigned thisRegister = currentInstruction[1].u.operand;
+
+ linkSlowCase(iter);
+
+ JITStubCall stubCall(this, cti_op_convert_this_strict);
+ stubCall.addArgument(regT1, regT0);
+ stubCall.call(thisRegister);
+}
+
void JIT::emit_op_profile_will_call(Instruction* currentInstruction)
{
peek(regT2, OBJECT_OFFSETOF(JITStackFrame, enabledProfilerReference) / sizeof(void*));
diff --git a/JavaScriptCore/jit/JITPropertyAccess.cpp b/JavaScriptCore/jit/JITPropertyAccess.cpp
index 7c129a5..2edc860 100644
--- a/JavaScriptCore/jit/JITPropertyAccess.cpp
+++ b/JavaScriptCore/jit/JITPropertyAccess.cpp
@@ -26,7 +26,7 @@
#include "config.h"
#if ENABLE(JIT)
-#if !USE(JSVALUE32_64)
+#if USE(JSVALUE64)
#include "JIT.h"
#include "CodeBlock.h"
@@ -89,7 +89,7 @@ void JIT::emit_op_get_by_val(Instruction* currentInstruction)
emitGetVirtualRegisters(base, regT0, property, regT1);
emitJumpSlowCaseIfNotImmediateInteger(regT1);
-#if USE(JSVALUE64)
+
// This is technically incorrect - we're zero-extending an int32. On the hot path this doesn't matter.
// We check the value as if it was a uint32 against the m_vectorLength - which will always fail if
// number was signed since m_vectorLength is always less than intmax (since the total allocation
@@ -97,9 +97,7 @@ void JIT::emit_op_get_by_val(Instruction* currentInstruction)
// to 64-bits is necessary since it's used in the address calculation. We zero extend rather than sign
// extending since it makes it easier to re-tag the value in the slow case.
zeroExtend32ToPtr(regT1, regT1);
-#else
- emitFastArithImmToInt(regT1);
-#endif
+
emitJumpSlowCaseIfNotJSCell(regT0, base);
addSlowCase(branchPtr(NotEqual, Address(regT0), ImmPtr(m_globalData->jsArrayVPtr)));
@@ -204,12 +202,8 @@ void JIT::emit_op_put_by_val(Instruction* currentInstruction)
emitGetVirtualRegisters(base, regT0, property, regT1);
emitJumpSlowCaseIfNotImmediateInteger(regT1);
-#if USE(JSVALUE64)
// See comment in op_get_by_val.
zeroExtend32ToPtr(regT1, regT1);
-#else
- emitFastArithImmToInt(regT1);
-#endif
emitJumpSlowCaseIfNotJSCell(regT0, base);
addSlowCase(branchPtr(NotEqual, Address(regT0), ImmPtr(m_globalData->jsArrayVPtr)));
addSlowCase(branch32(AboveOrEqual, regT1, Address(regT0, OBJECT_OFFSETOF(JSArray, m_vectorLength))));
@@ -1103,5 +1097,5 @@ void JIT::privateCompileGetByIdChain(StructureStubInfo* stubInfo, Structure* str
} // namespace JSC
-#endif // !USE(JSVALUE32_64)
+#endif // USE(JSVALUE64)
#endif // ENABLE(JIT)
diff --git a/JavaScriptCore/jit/JITStubs.cpp b/JavaScriptCore/jit/JITStubs.cpp
index f1ec079..8340211 100644
--- a/JavaScriptCore/jit/JITStubs.cpp
+++ b/JavaScriptCore/jit/JITStubs.cpp
@@ -1065,7 +1065,9 @@ static NEVER_INLINE void throwStackOverflowError(CallFrame* callFrame, JSGlobalD
return 0; \
} while (0)
#define VM_THROW_EXCEPTION_AT_END() \
- returnToThrowTrampoline(stackFrame.globalData, STUB_RETURN_ADDRESS, STUB_RETURN_ADDRESS)
+ do {\
+ returnToThrowTrampoline(stackFrame.globalData, STUB_RETURN_ADDRESS, STUB_RETURN_ADDRESS);\
+ } while (0)
#define CHECK_FOR_EXCEPTION() \
do { \
@@ -1301,6 +1303,18 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_convert_this)
return JSValue::encode(result);
}
+DEFINE_STUB_FUNCTION(EncodedJSValue, op_convert_this_strict)
+{
+ STUB_INIT_STACK_FRAME(stackFrame);
+
+ JSValue v1 = stackFrame.args[0].jsValue();
+ CallFrame* callFrame = stackFrame.callFrame;
+
+ JSValue result = v1.toStrictThisObject(callFrame);
+ CHECK_FOR_EXCEPTION_AT_END();
+ return JSValue::encode(result);
+}
+
DEFINE_STUB_FUNCTION(void, op_end)
{
STUB_INIT_STACK_FRAME(stackFrame);
@@ -1404,7 +1418,7 @@ DEFINE_STUB_FUNCTION(void, op_put_by_id_generic)
{
STUB_INIT_STACK_FRAME(stackFrame);
- PutPropertySlot slot;
+ PutPropertySlot slot(stackFrame.callFrame->codeBlock()->isStrictMode());
stackFrame.args[0].jsValue().put(stackFrame.callFrame, stackFrame.args[1].identifier(), stackFrame.args[2].jsValue(), slot);
CHECK_FOR_EXCEPTION_AT_END();
}
@@ -1413,7 +1427,7 @@ DEFINE_STUB_FUNCTION(void, op_put_by_id_direct_generic)
{
STUB_INIT_STACK_FRAME(stackFrame);
- PutPropertySlot slot;
+ PutPropertySlot slot(stackFrame.callFrame->codeBlock()->isStrictMode());
stackFrame.args[0].jsValue().putDirect(stackFrame.callFrame, stackFrame.args[1].identifier(), stackFrame.args[2].jsValue(), slot);
CHECK_FOR_EXCEPTION_AT_END();
}
@@ -1441,7 +1455,7 @@ DEFINE_STUB_FUNCTION(void, op_put_by_id)
CallFrame* callFrame = stackFrame.callFrame;
Identifier& ident = stackFrame.args[1].identifier();
- PutPropertySlot slot;
+ PutPropertySlot slot(callFrame->codeBlock()->isStrictMode());
stackFrame.args[0].jsValue().put(callFrame, ident, stackFrame.args[2].jsValue(), slot);
CodeBlock* codeBlock = stackFrame.callFrame->codeBlock();
@@ -1460,7 +1474,7 @@ DEFINE_STUB_FUNCTION(void, op_put_by_id_direct)
CallFrame* callFrame = stackFrame.callFrame;
Identifier& ident = stackFrame.args[1].identifier();
- PutPropertySlot slot;
+ PutPropertySlot slot(callFrame->codeBlock()->isStrictMode());
stackFrame.args[0].jsValue().putDirect(callFrame, ident, stackFrame.args[2].jsValue(), slot);
CodeBlock* codeBlock = stackFrame.callFrame->codeBlock();
@@ -1479,8 +1493,8 @@ DEFINE_STUB_FUNCTION(void, op_put_by_id_fail)
CallFrame* callFrame = stackFrame.callFrame;
Identifier& ident = stackFrame.args[1].identifier();
-
- PutPropertySlot slot;
+
+ PutPropertySlot slot(callFrame->codeBlock()->isStrictMode());
stackFrame.args[0].jsValue().put(callFrame, ident, stackFrame.args[2].jsValue(), slot);
CHECK_FOR_EXCEPTION_AT_END();
@@ -1493,7 +1507,7 @@ DEFINE_STUB_FUNCTION(void, op_put_by_id_direct_fail)
CallFrame* callFrame = stackFrame.callFrame;
Identifier& ident = stackFrame.args[1].identifier();
- PutPropertySlot slot;
+ PutPropertySlot slot(callFrame->codeBlock()->isStrictMode());
stackFrame.args[0].jsValue().putDirect(callFrame, ident, stackFrame.args[2].jsValue(), slot);
CHECK_FOR_EXCEPTION_AT_END();
@@ -1880,7 +1894,11 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_del_by_id)
JSObject* baseObj = stackFrame.args[0].jsValue().toObject(callFrame);
- JSValue result = jsBoolean(baseObj->deleteProperty(callFrame, stackFrame.args[1].identifier()));
+ bool couldDelete = baseObj->deleteProperty(callFrame, stackFrame.args[1].identifier());
+ JSValue result = jsBoolean(couldDelete);
+ if (!couldDelete && callFrame->codeBlock()->isStrictMode())
+ stackFrame.globalData->exception = createTypeError(stackFrame.callFrame, "Unable to delete property.");
+
CHECK_FOR_EXCEPTION_AT_END();
return JSValue::encode(result);
}
@@ -1906,7 +1924,8 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_mul)
DEFINE_STUB_FUNCTION(JSObject*, op_new_func)
{
STUB_INIT_STACK_FRAME(stackFrame);
-
+
+ ASSERT(stackFrame.callFrame->codeBlock()->codeType() != FunctionCode || !stackFrame.callFrame->codeBlock()->needsFullScopeChain() || stackFrame.callFrame->r(stackFrame.callFrame->codeBlock()->activationRegister()).jsValue());
return stackFrame.args[0].function()->make(stackFrame.callFrame, stackFrame.callFrame->scopeChain());
}
@@ -2213,10 +2232,18 @@ DEFINE_STUB_FUNCTION(void, op_tear_off_activation)
STUB_INIT_STACK_FRAME(stackFrame);
ASSERT(stackFrame.callFrame->codeBlock()->needsFullScopeChain());
+ JSValue activationValue = stackFrame.args[0].jsValue();
+ if (!activationValue) {
+ if (JSValue v = stackFrame.args[1].jsValue())
+ asArguments(v)->copyRegisters();
+ return;
+ }
JSActivation* activation = asActivation(stackFrame.args[0].jsValue());
activation->copyRegisters();
- if (JSValue v = stackFrame.args[1].jsValue())
- asArguments(v)->setActivation(activation);
+ if (JSValue v = stackFrame.args[1].jsValue()) {
+ if (!stackFrame.callFrame->codeBlock()->isStrictMode())
+ asArguments(v)->setActivation(activation);
+ }
}
DEFINE_STUB_FUNCTION(void, op_tear_off_arguments)
@@ -2496,7 +2523,7 @@ DEFINE_STUB_FUNCTION(void, op_put_by_val)
} else {
Identifier property(callFrame, subscript.toString(callFrame));
if (!stackFrame.globalData->exception) { // Don't put to an object if toString threw an exception.
- PutPropertySlot slot;
+ PutPropertySlot slot(callFrame->codeBlock()->isStrictMode());
baseValue.put(callFrame, property, value, slot);
}
}
@@ -2539,7 +2566,7 @@ DEFINE_STUB_FUNCTION(void, op_put_by_val_byte_array)
} else {
Identifier property(callFrame, subscript.toString(callFrame));
if (!stackFrame.globalData->exception) { // Don't put to an object if toString threw an exception.
- PutPropertySlot slot;
+ PutPropertySlot slot(callFrame->codeBlock()->isStrictMode());
baseValue.put(callFrame, property, value, slot);
}
}
@@ -2670,9 +2697,35 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_resolve_base)
{
STUB_INIT_STACK_FRAME(stackFrame);
- return JSValue::encode(JSC::resolveBase(stackFrame.callFrame, stackFrame.args[0].identifier(), stackFrame.callFrame->scopeChain()));
+ return JSValue::encode(JSC::resolveBase(stackFrame.callFrame, stackFrame.args[0].identifier(), stackFrame.callFrame->scopeChain(), false));
}
+DEFINE_STUB_FUNCTION(EncodedJSValue, op_resolve_base_strict_put)
+{
+ STUB_INIT_STACK_FRAME(stackFrame);
+ JSValue base = JSC::resolveBase(stackFrame.callFrame, stackFrame.args[0].identifier(), stackFrame.callFrame->scopeChain(), true);
+ if (!base) {
+ stackFrame.globalData->exception = createErrorForInvalidGlobalAssignment(stackFrame.callFrame, stackFrame.args[0].identifier().ustring());
+ VM_THROW_EXCEPTION();
+ }
+ return JSValue::encode(base);
+}
+
+DEFINE_STUB_FUNCTION(EncodedJSValue, op_ensure_property_exists)
+{
+ STUB_INIT_STACK_FRAME(stackFrame);
+ JSValue base = stackFrame.callFrame->r(stackFrame.args[0].int32()).jsValue();
+ JSObject* object = asObject(base);
+ PropertySlot slot(object);
+ ASSERT(stackFrame.callFrame->codeBlock()->isStrictMode());
+ if (!object->getPropertySlot(stackFrame.callFrame, stackFrame.args[1].identifier(), slot)) {
+ stackFrame.globalData->exception = createErrorForInvalidGlobalAssignment(stackFrame.callFrame, stackFrame.args[1].identifier().ustring());
+ VM_THROW_EXCEPTION();
+ }
+
+ return JSValue::encode(base);
+}
+
DEFINE_STUB_FUNCTION(EncodedJSValue, op_resolve_skip)
{
STUB_INIT_STACK_FRAME(stackFrame);
@@ -2685,6 +2738,13 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_resolve_skip)
ScopeChainIterator iter = scopeChain->begin();
ScopeChainIterator end = scopeChain->end();
ASSERT(iter != end);
+ CodeBlock* codeBlock = callFrame->codeBlock();
+ bool checkTopLevel = codeBlock->codeType() == FunctionCode && codeBlock->needsFullScopeChain();
+ ASSERT(skip || !checkTopLevel);
+ if (checkTopLevel && skip--) {
+ if (callFrame->r(codeBlock->activationRegister()).jsValue())
+ ++iter;
+ }
while (skip--) {
++iter;
ASSERT(iter != end);
@@ -2700,7 +2760,6 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_resolve_skip)
}
} while (++iter != end);
- CodeBlock* codeBlock = callFrame->codeBlock();
unsigned vPCIndex = codeBlock->bytecodeOffset(callFrame, STUB_RETURN_ADDRESS);
stackFrame.globalData->exception = createUndefinedVariableError(callFrame, ident, vPCIndex, codeBlock);
VM_THROW_EXCEPTION();
@@ -3049,6 +3108,7 @@ DEFINE_STUB_FUNCTION(JSObject*, op_new_func_exp)
FunctionExecutable* function = stackFrame.args[0].function();
JSFunction* func = function->make(callFrame, callFrame->scopeChain());
+ ASSERT(callFrame->codeBlock()->codeType() != FunctionCode || !callFrame->codeBlock()->needsFullScopeChain() || callFrame->r(callFrame->codeBlock()->activationRegister()).jsValue());
/*
The Identifier in a FunctionExpression can be referenced from inside
@@ -3155,6 +3215,7 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_bitor)
DEFINE_STUB_FUNCTION(EncodedJSValue, op_call_eval)
{
STUB_INIT_STACK_FRAME(stackFrame);
+ ASSERT(stackFrame.callFrame->codeBlock()->codeType() != FunctionCode || !stackFrame.callFrame->codeBlock()->needsFullScopeChain() || stackFrame.callFrame->r(stackFrame.callFrame->codeBlock()->activationRegister()).jsValue());
CallFrame* callFrame = stackFrame.callFrame;
RegisterFile* registerFile = stackFrame.registerFile;
@@ -3486,19 +3547,22 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_del_by_val)
JSObject* baseObj = baseValue.toObject(callFrame); // may throw
JSValue subscript = stackFrame.args[1].jsValue();
- JSValue result;
+ bool result;
uint32_t i;
if (subscript.getUInt32(i))
- result = jsBoolean(baseObj->deleteProperty(callFrame, i));
+ result = baseObj->deleteProperty(callFrame, i);
else {
CHECK_FOR_EXCEPTION();
Identifier property(callFrame, subscript.toString(callFrame));
CHECK_FOR_EXCEPTION();
- result = jsBoolean(baseObj->deleteProperty(callFrame, property));
+ result = baseObj->deleteProperty(callFrame, property);
}
+ if (!result && callFrame->codeBlock()->isStrictMode())
+ stackFrame.globalData->exception = createTypeError(stackFrame.callFrame, "Unable to delete property.");
+
CHECK_FOR_EXCEPTION_AT_END();
- return JSValue::encode(result);
+ return JSValue::encode(jsBoolean(result));
}
DEFINE_STUB_FUNCTION(void, op_put_getter)
diff --git a/JavaScriptCore/jit/JITStubs.h b/JavaScriptCore/jit/JITStubs.h
index 2b22e6d..b91a074 100644
--- a/JavaScriptCore/jit/JITStubs.h
+++ b/JavaScriptCore/jit/JITStubs.h
@@ -147,7 +147,7 @@ namespace JSC {
struct JITStackFrame {
JITStubArg reserved; // Unused
JITStubArg args[6];
-#if !USE(JSVALUE32_64)
+#if USE(JSVALUE64)
void* padding; // Maintain 16-byte stack alignment.
#endif
@@ -296,6 +296,7 @@ extern "C" {
EncodedJSValue JIT_STUB cti_op_construct_NotJSConstruct(STUB_ARGS_DECLARATION);
EncodedJSValue JIT_STUB cti_op_create_this(STUB_ARGS_DECLARATION);
EncodedJSValue JIT_STUB cti_op_convert_this(STUB_ARGS_DECLARATION);
+ EncodedJSValue JIT_STUB cti_op_convert_this_strict(STUB_ARGS_DECLARATION);
EncodedJSValue JIT_STUB cti_op_create_arguments(STUB_ARGS_DECLARATION);
EncodedJSValue JIT_STUB cti_op_create_arguments_no_params(STUB_ARGS_DECLARATION);
EncodedJSValue JIT_STUB cti_op_del_by_id(STUB_ARGS_DECLARATION);
@@ -337,6 +338,8 @@ extern "C" {
EncodedJSValue JIT_STUB cti_op_pre_inc(STUB_ARGS_DECLARATION);
EncodedJSValue JIT_STUB cti_op_resolve(STUB_ARGS_DECLARATION);
EncodedJSValue JIT_STUB cti_op_resolve_base(STUB_ARGS_DECLARATION);
+ EncodedJSValue JIT_STUB cti_op_resolve_base_strict_put(STUB_ARGS_DECLARATION);
+ EncodedJSValue JIT_STUB cti_op_ensure_property_exists(STUB_ARGS_DECLARATION);
EncodedJSValue JIT_STUB cti_op_resolve_global(STUB_ARGS_DECLARATION);
EncodedJSValue JIT_STUB cti_op_resolve_global_dynamic(STUB_ARGS_DECLARATION);
EncodedJSValue JIT_STUB cti_op_resolve_skip(STUB_ARGS_DECLARATION);
diff --git a/JavaScriptCore/jit/JSInterfaceJIT.h b/JavaScriptCore/jit/JSInterfaceJIT.h
index 031bfa8..6453bab 100644
--- a/JavaScriptCore/jit/JSInterfaceJIT.h
+++ b/JavaScriptCore/jit/JSInterfaceJIT.h
@@ -166,7 +166,7 @@ namespace JSC {
inline Address tagFor(unsigned index, RegisterID base = callFrameRegister);
#endif
-#if USE(JSVALUE32) || USE(JSVALUE64)
+#if USE(JSVALUE64)
Jump emitJumpIfImmediateNumber(RegisterID reg);
Jump emitJumpIfNotImmediateNumber(RegisterID reg);
void emitFastArithImmToInt(RegisterID reg);
@@ -273,35 +273,7 @@ namespace JSC {
#endif
-#if USE(JSVALUE32)
- inline JSInterfaceJIT::Jump JSInterfaceJIT::emitLoadJSCell(unsigned virtualRegisterIndex, RegisterID dst)
- {
- loadPtr(addressFor(virtualRegisterIndex), dst);
- return branchTest32(NonZero, dst, Imm32(JSImmediate::TagMask));
- }
-
- inline JSInterfaceJIT::Jump JSInterfaceJIT::emitLoadInt32(unsigned virtualRegisterIndex, RegisterID dst)
- {
- loadPtr(addressFor(virtualRegisterIndex), dst);
- Jump result = branchTest32(Zero, dst, Imm32(JSImmediate::TagTypeNumber));
- rshift32(Imm32(JSImmediate::IntegerPayloadShift), dst);
- return result;
- }
-
- inline JSInterfaceJIT::Jump JSInterfaceJIT::emitLoadDouble(unsigned, FPRegisterID, RegisterID)
- {
- ASSERT_NOT_REACHED();
- return jump();
- }
-
- ALWAYS_INLINE void JSInterfaceJIT::emitFastArithImmToInt(RegisterID reg)
- {
- rshift32(Imm32(JSImmediate::IntegerPayloadShift), reg);
- }
-
-#endif
-
-#if !USE(JSVALUE32_64)
+#if USE(JSVALUE64)
inline JSInterfaceJIT::Address JSInterfaceJIT::payloadFor(unsigned virtualRegisterIndex, RegisterID base)
{
ASSERT(static_cast<int>(virtualRegisterIndex) < FirstConstantRegisterIndex);
diff --git a/JavaScriptCore/jit/SpecializedThunkJIT.h b/JavaScriptCore/jit/SpecializedThunkJIT.h
index 57515fb..5c593d9 100644
--- a/JavaScriptCore/jit/SpecializedThunkJIT.h
+++ b/JavaScriptCore/jit/SpecializedThunkJIT.h
@@ -96,14 +96,10 @@ namespace JSC {
#if USE(JSVALUE64)
moveDoubleToPtr(src, regT0);
subPtr(tagTypeNumberRegister, regT0);
-#elif USE(JSVALUE32_64)
+#else
storeDouble(src, Address(stackPointerRegister, -(int)sizeof(double)));
loadPtr(Address(stackPointerRegister, OBJECT_OFFSETOF(JSValue, u.asBits.tag) - sizeof(double)), regT1);
loadPtr(Address(stackPointerRegister, OBJECT_OFFSETOF(JSValue, u.asBits.payload) - sizeof(double)), regT0);
-#else
- UNUSED_PARAM(src);
- ASSERT_NOT_REACHED();
- m_failures.append(jump());
#endif
loadPtr(Address(callFrameRegister, RegisterFile::CallerFrame * (int)sizeof(Register)), callFrameRegister);
ret();
@@ -144,13 +140,8 @@ namespace JSC {
{
#if USE(JSVALUE64)
orPtr(tagTypeNumberRegister, regT0);
-#elif USE(JSVALUE32_64)
- move(Imm32(JSValue::Int32Tag), regT1);
#else
- signExtend32ToPtr(regT0, regT0);
- // If we can't tag the result, give up and jump to the slow case
- m_failures.append(branchAddPtr(Overflow, regT0, regT0));
- addPtr(Imm32(JSImmediate::TagTypeNumber), regT0);
+ move(Imm32(JSValue::Int32Tag), regT1);
#endif
}
diff --git a/JavaScriptCore/jit/ThunkGenerators.cpp b/JavaScriptCore/jit/ThunkGenerators.cpp
index 4c7a354..9b40f12 100644
--- a/JavaScriptCore/jit/ThunkGenerators.cpp
+++ b/JavaScriptCore/jit/ThunkGenerators.cpp
@@ -92,7 +92,6 @@ MacroAssemblerCodePtr fromCharCodeThunkGenerator(JSGlobalData* globalData, Execu
MacroAssemblerCodePtr sqrtThunkGenerator(JSGlobalData* globalData, ExecutablePool* pool)
{
-#if USE(JSVALUE64) || USE(JSVALUE32_64)
SpecializedThunkJIT jit(1, globalData, pool);
if (!jit.supportsFloatingPointSqrt())
return globalData->jitStubs->ctiNativeCall();
@@ -101,10 +100,6 @@ MacroAssemblerCodePtr sqrtThunkGenerator(JSGlobalData* globalData, ExecutablePoo
jit.sqrtDouble(SpecializedThunkJIT::fpRegT0, SpecializedThunkJIT::fpRegT0);
jit.returnDouble(SpecializedThunkJIT::fpRegT0);
return jit.finalize(globalData->jitStubs->ctiNativeCall());
-#else
- UNUSED_PARAM(pool);
- return globalData->jitStubs->ctiNativeCall();
-#endif
}
static const double oneConstant = 1.0;
@@ -112,7 +107,6 @@ static const double negativeHalfConstant = -0.5;
MacroAssemblerCodePtr powThunkGenerator(JSGlobalData* globalData, ExecutablePool* pool)
{
-#if USE(JSVALUE64) || USE(JSVALUE32_64)
SpecializedThunkJIT jit(2, globalData, pool);
if (!jit.supportsFloatingPoint())
return globalData->jitStubs->ctiNativeCall();
@@ -161,10 +155,6 @@ MacroAssemblerCodePtr powThunkGenerator(JSGlobalData* globalData, ExecutablePool
jit.appendFailure(nonIntExponent);
return jit.finalize(globalData->jitStubs->ctiNativeCall());
-#else
- UNUSED_PARAM(pool);
- return globalData->jitStubs->ctiNativeCall();
-#endif
}
}