summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@digia.com>2014-10-14 17:18:28 +0200
committerThe Qt Project <gerrit-noreply@qt-project.org>2014-10-14 20:26:43 +0200
commit520572a67c4e747583792b256702c488b74bff3d (patch)
tree2144cf369c2f49754c6e9242e5ea901616735de5
parentc3b2b9d23396e4853d152bef5479d8f05d651e27 (diff)
parent5a45e3b78724563f05d62569d8ed31adc4ffd342 (diff)
downloadqtwebkit-520572a67c4e747583792b256702c488b74bff3d.tar.gz
Merge "Merge remote-tracking branch 'origin/5.3' into 5.4" into refs/staging/5.4
-rw-r--r--Source/JavaScriptCore/assembler/MacroAssemblerARM.h5
-rw-r--r--Source/JavaScriptCore/assembler/MacroAssemblerARMv7.h6
-rw-r--r--Source/JavaScriptCore/assembler/MacroAssemblerMIPS.h6
-rw-r--r--Source/JavaScriptCore/assembler/MacroAssemblerSH4.h23
-rw-r--r--Source/JavaScriptCore/dfg/DFGOperations.cpp13
-rw-r--r--Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp18
-rw-r--r--Source/JavaScriptCore/runtime/JSString.cpp1
-rw-r--r--Source/JavaScriptCore/runtime/JSString.h14
-rw-r--r--Source/JavaScriptCore/runtime/Operations.h33
-rw-r--r--Source/JavaScriptCore/runtime/StringPrototype.cpp4
10 files changed, 100 insertions, 23 deletions
diff --git a/Source/JavaScriptCore/assembler/MacroAssemblerARM.h b/Source/JavaScriptCore/assembler/MacroAssemblerARM.h
index 494fe640d..9058514dc 100644
--- a/Source/JavaScriptCore/assembler/MacroAssemblerARM.h
+++ b/Source/JavaScriptCore/assembler/MacroAssemblerARM.h
@@ -725,6 +725,11 @@ public:
return Jump(m_assembler.jmp(ARMCondition(cond)));
}
+ Jump branchAdd32(ResultCondition cond, Address src, RegisterID dest)
+ {
+ load32(src, ARMRegisters::S0);
+ return branchAdd32(cond, dest, ARMRegisters::S0, dest);
+ }
void mull32(RegisterID op1, RegisterID op2, RegisterID dest)
{
if (op2 == dest) {
diff --git a/Source/JavaScriptCore/assembler/MacroAssemblerARMv7.h b/Source/JavaScriptCore/assembler/MacroAssemblerARMv7.h
index b1bc41729..ac3cc8646 100644
--- a/Source/JavaScriptCore/assembler/MacroAssemblerARMv7.h
+++ b/Source/JavaScriptCore/assembler/MacroAssemblerARMv7.h
@@ -1473,6 +1473,12 @@ public:
return branchAdd32(cond, dest, src, dest);
}
+ Jump branchAdd32(ResultCondition cond, Address src, RegisterID dest)
+ {
+ load32(src, dataTempRegister);
+ return branchAdd32(cond, dest, dataTempRegister, dest);
+ }
+
Jump branchAdd32(ResultCondition cond, TrustedImm32 imm, RegisterID dest)
{
return branchAdd32(cond, dest, imm, dest);
diff --git a/Source/JavaScriptCore/assembler/MacroAssemblerMIPS.h b/Source/JavaScriptCore/assembler/MacroAssemblerMIPS.h
index 927b08b07..fe78431bd 100644
--- a/Source/JavaScriptCore/assembler/MacroAssemblerMIPS.h
+++ b/Source/JavaScriptCore/assembler/MacroAssemblerMIPS.h
@@ -1676,6 +1676,12 @@ public:
return branchAdd32(cond, immTempRegister, dest);
}
+ Jump branchAdd32(ResultCondition cond, Address address, RegisterID dest)
+ {
+ load32(address, immTempRegister);
+ return branchAdd32(cond, immTempRegister, dest);
+ }
+
Jump branchAdd32(ResultCondition cond, RegisterID src, TrustedImm32 imm, RegisterID dest)
{
move(imm, immTempRegister);
diff --git a/Source/JavaScriptCore/assembler/MacroAssemblerSH4.h b/Source/JavaScriptCore/assembler/MacroAssemblerSH4.h
index 16e604b00..a65614b92 100644
--- a/Source/JavaScriptCore/assembler/MacroAssemblerSH4.h
+++ b/Source/JavaScriptCore/assembler/MacroAssemblerSH4.h
@@ -2080,6 +2080,29 @@ public:
return result ? branchTrue() : branchFalse();
}
+ Jump branchAdd32(ResultCondition cond, Address src, RegisterID dest)
+ {
+ ASSERT((cond == Overflow) || (cond == Signed) || (cond == PositiveOrZero) || (cond == Zero) || (cond == NonZero));
+
+ if (cond == Overflow) {
+ RegisterID srcVal = claimScratch();
+ load32(src, srcVal);
+ m_assembler.addvlRegReg(srcVal, dest);
+ releaseScratch(srcVal);
+ return branchTrue();
+ }
+
+ add32(src, dest);
+
+ if ((cond == Signed) || (cond == PositiveOrZero)) {
+ m_assembler.cmppz(dest);
+ return (cond == Signed) ? branchFalse() : branchTrue();
+ }
+
+ compare32(0, dest, Equal);
+ return (cond == NonZero) ? branchFalse() : branchTrue();
+ }
+
Jump branchMul32(ResultCondition cond, RegisterID src, RegisterID dest)
{
ASSERT((cond == Overflow) || (cond == Signed) || (cond == Zero) || (cond == NonZero));
diff --git a/Source/JavaScriptCore/dfg/DFGOperations.cpp b/Source/JavaScriptCore/dfg/DFGOperations.cpp
index 29a0b2b61..1305c0a5d 100644
--- a/Source/JavaScriptCore/dfg/DFGOperations.cpp
+++ b/Source/JavaScriptCore/dfg/DFGOperations.cpp
@@ -1644,6 +1644,11 @@ JSCell* DFG_OPERATION operationMakeRope2(ExecState* exec, JSString* left, JSStri
VM& vm = exec->vm();
NativeCallFrameTracer tracer(&vm, exec);
+ if (static_cast<int32_t>(left->length() + right->length()) < 0) {
+ throwOutOfMemoryError(exec);
+ return 0;
+ }
+
return JSRopeString::create(vm, left, right);
}
@@ -1652,6 +1657,14 @@ JSCell* DFG_OPERATION operationMakeRope3(ExecState* exec, JSString* a, JSString*
VM& vm = exec->vm();
NativeCallFrameTracer tracer(&vm, exec);
+ Checked<int32_t, RecordOverflow> length = a->length();
+ length += b->length();
+ length += c->length();
+ if (length.hasOverflowed()) {
+ throwOutOfMemoryError(exec);
+ return 0;
+ }
+
return JSRopeString::create(vm, a, b, c);
}
diff --git a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp
index 71fd99a04..07312e036 100644
--- a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp
+++ b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp
@@ -3222,12 +3222,28 @@ void SpeculativeJIT::compileMakeRope(Node* node)
m_jit.storePtr(TrustedImmPtr(0), JITCompiler::Address(resultGPR, JSRopeString::offsetOfFibers() + sizeof(WriteBarrier<JSString>) * i));
m_jit.load32(JITCompiler::Address(opGPRs[0], JSString::offsetOfFlags()), scratchGPR);
m_jit.load32(JITCompiler::Address(opGPRs[0], JSString::offsetOfLength()), allocatorGPR);
+ if (!ASSERT_DISABLED) {
+ JITCompiler::Jump ok = m_jit.branch32(
+ JITCompiler::GreaterThanOrEqual, allocatorGPR, TrustedImm32(0));
+ m_jit.breakpoint();
+ ok.link(&m_jit);
+ }
for (unsigned i = 1; i < numOpGPRs; ++i) {
m_jit.and32(JITCompiler::Address(opGPRs[i], JSString::offsetOfFlags()), scratchGPR);
- m_jit.add32(JITCompiler::Address(opGPRs[i], JSString::offsetOfLength()), allocatorGPR);
+ speculationCheck(
+ Uncountable, JSValueSource(), 0,
+ m_jit.branchAdd32(
+ JITCompiler::Overflow,
+ JITCompiler::Address(opGPRs[i], JSString::offsetOfLength()), allocatorGPR));
}
m_jit.and32(JITCompiler::TrustedImm32(JSString::Is8Bit), scratchGPR);
m_jit.store32(scratchGPR, JITCompiler::Address(resultGPR, JSString::offsetOfFlags()));
+ if (!ASSERT_DISABLED) {
+ JITCompiler::Jump ok = m_jit.branch32(
+ JITCompiler::GreaterThanOrEqual, allocatorGPR, TrustedImm32(0));
+ m_jit.breakpoint();
+ ok.link(&m_jit);
+ }
m_jit.store32(allocatorGPR, JITCompiler::Address(resultGPR, JSString::offsetOfLength()));
switch (numOpGPRs) {
diff --git a/Source/JavaScriptCore/runtime/JSString.cpp b/Source/JavaScriptCore/runtime/JSString.cpp
index 86704d715..6f0b09d13 100644
--- a/Source/JavaScriptCore/runtime/JSString.cpp
+++ b/Source/JavaScriptCore/runtime/JSString.cpp
@@ -40,6 +40,7 @@ void JSRopeString::RopeBuilder::expand()
{
ASSERT(m_index == JSRopeString::s_maxInternalRopeLength);
JSString* jsString = m_jsString;
+ RELEASE_ASSERT(jsString);
m_jsString = jsStringBuilder(&m_vm);
m_index = 0;
append(jsString);
diff --git a/Source/JavaScriptCore/runtime/JSString.h b/Source/JavaScriptCore/runtime/JSString.h
index 855de974d..fc383b2f4 100644
--- a/Source/JavaScriptCore/runtime/JSString.h
+++ b/Source/JavaScriptCore/runtime/JSString.h
@@ -1,7 +1,7 @@
/*
* Copyright (C) 1999-2001 Harri Porten (porten@kde.org)
* Copyright (C) 2001 Peter Kelly (pmk@post.com)
- * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2014 Apple Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -121,7 +121,8 @@ public:
static JSString* create(VM& vm, PassRefPtr<StringImpl> value)
{
ASSERT(value);
- size_t length = value->length();
+ int32_t length = value->length();
+ RELEASE_ASSERT(length >= 0);
size_t cost = value->cost();
JSString* newString = new (NotNull, allocateCell<JSString>(vm.heap)) JSString(vm, value);
newString->finishCreation(vm, length, cost);
@@ -226,15 +227,21 @@ class JSRopeString : public JSString {
{
}
- void append(JSString* jsString)
+ bool append(JSString* jsString)
{
if (m_index == JSRopeString::s_maxInternalRopeLength)
expand();
+ if (static_cast<int32_t>(m_jsString->length() + jsString->length()) < 0) {
+ m_jsString = 0;
+ return false;
+ }
m_jsString->append(m_vm, m_index++, jsString);
+ return true;
}
JSRopeString* release()
{
+ RELEASE_ASSERT(m_jsString);
JSRopeString* tmp = m_jsString;
m_jsString = 0;
return tmp;
@@ -284,6 +291,7 @@ private:
{
m_fibers[index].set(vm, this, jsString);
m_length += jsString->m_length;
+ RELEASE_ASSERT(static_cast<int32_t>(m_length) >= 0);
setIs8Bit(is8Bit() && jsString->is8Bit());
}
diff --git a/Source/JavaScriptCore/runtime/Operations.h b/Source/JavaScriptCore/runtime/Operations.h
index afac13000..e628662e0 100644
--- a/Source/JavaScriptCore/runtime/Operations.h
+++ b/Source/JavaScriptCore/runtime/Operations.h
@@ -42,13 +42,13 @@ ALWAYS_INLINE JSValue jsString(ExecState* exec, JSString* s1, JSString* s2)
{
VM& vm = exec->vm();
- unsigned length1 = s1->length();
+ int32_t length1 = s1->length();
if (!length1)
return s2;
- unsigned length2 = s2->length();
+ int32_t length2 = s2->length();
if (!length2)
return s1;
- if ((length1 + length2) < length1)
+ if ((length1 + length2) < 0)
return throwOutOfMemoryError(exec);
return JSRopeString::create(vm, s1, s2);
@@ -58,9 +58,13 @@ ALWAYS_INLINE JSValue jsString(ExecState* exec, const String& u1, const String&
{
VM* vm = &exec->vm();
- unsigned length1 = u1.length();
- unsigned length2 = u2.length();
- unsigned length3 = u3.length();
+ int32_t length1 = u1.length();
+ int32_t length2 = u2.length();
+ int32_t length3 = u3.length();
+
+ if (length1 < 0 || length2 < 0 || length3 < 0)
+ return throwOutOfMemoryError(exec);
+
if (!length1)
return jsString(exec, jsString(vm, u2), jsString(vm, u3));
if (!length2)
@@ -68,9 +72,9 @@ ALWAYS_INLINE JSValue jsString(ExecState* exec, const String& u1, const String&
if (!length3)
return jsString(exec, jsString(vm, u1), jsString(vm, u2));
- if ((length1 + length2) < length1)
+ if ((length1 + length2) < 0)
return throwOutOfMemoryError(exec);
- if ((length1 + length2 + length3) < length3)
+ if ((length1 + length2 + length3) < 0)
return throwOutOfMemoryError(exec);
return JSRopeString::create(exec->vm(), jsString(vm, u1), jsString(vm, u2), jsString(vm, u3));
@@ -81,15 +85,11 @@ ALWAYS_INLINE JSValue jsString(ExecState* exec, Register* strings, unsigned coun
VM* vm = &exec->vm();
JSRopeString::RopeBuilder ropeBuilder(*vm);
- unsigned oldLength = 0;
-
for (unsigned i = 0; i < count; ++i) {
JSValue v = strings[i].jsValue();
- ropeBuilder.append(v.toString(exec));
- if (ropeBuilder.length() < oldLength) // True for overflow
+ if (!ropeBuilder.append(v.toString(exec)))
return throwOutOfMemoryError(exec);
- oldLength = ropeBuilder.length();
}
return ropeBuilder.release();
@@ -101,15 +101,10 @@ ALWAYS_INLINE JSValue jsStringFromArguments(ExecState* exec, JSValue thisValue)
JSRopeString::RopeBuilder ropeBuilder(*vm);
ropeBuilder.append(thisValue.toString(exec));
- unsigned oldLength = 0;
-
for (unsigned i = 0; i < exec->argumentCount(); ++i) {
JSValue v = exec->argument(i);
- ropeBuilder.append(v.toString(exec));
-
- if (ropeBuilder.length() < oldLength) // True for overflow
+ if (!ropeBuilder.append(v.toString(exec)))
return throwOutOfMemoryError(exec);
- oldLength = ropeBuilder.length();
}
return ropeBuilder.release();
diff --git a/Source/JavaScriptCore/runtime/StringPrototype.cpp b/Source/JavaScriptCore/runtime/StringPrototype.cpp
index c422fd17b..2e9baba73 100644
--- a/Source/JavaScriptCore/runtime/StringPrototype.cpp
+++ b/Source/JavaScriptCore/runtime/StringPrototype.cpp
@@ -761,6 +761,7 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncIndexOf(ExecState* exec)
else {
unsigned pos;
int len = s.length();
+ RELEASE_ASSERT(len >= 0);
if (a1.isUInt32())
pos = std::min<uint32_t>(a1.asUInt32(), len);
else {
@@ -904,6 +905,7 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncSlice(ExecState* exec)
return throwVMTypeError(exec);
String s = thisValue.toString(exec)->value(exec);
int len = s.length();
+ RELEASE_ASSERT(len >= 0);
JSValue a0 = exec->argument(0);
JSValue a1 = exec->argument(1);
@@ -1216,6 +1218,7 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncSubstring(ExecState* exec)
JSValue a0 = exec->argument(0);
JSValue a1 = exec->argument(1);
int len = jsString->length();
+ RELEASE_ASSERT(len >= 0);
double start = a0.toNumber(exec);
double end;
@@ -1253,6 +1256,7 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncToLowerCase(ExecState* exec)
int sSize = s.length();
if (!sSize)
return JSValue::encode(sVal);
+ RELEASE_ASSERT(sSize >= 0);
StringImpl* ourImpl = s.impl();
RefPtr<StringImpl> lower = ourImpl->lower();