summaryrefslogtreecommitdiff
path: root/Source/JavaScriptCore
diff options
context:
space:
mode:
authorFrederik Gladhorn <frederik.gladhorn@theqtcompany.com>2014-10-20 19:19:56 +0200
committerFrederik Gladhorn <frederik.gladhorn@theqtcompany.com>2014-10-20 20:29:12 +0200
commit7a7433bfa61e80b91d1e9e7cf4b44ee8fdc431a0 (patch)
tree2ca7eb63ddb38472305f41e8e5b81c89cd20b9f0 /Source/JavaScriptCore
parentee21e513f3ed68af68e529b43c8fda94dfcc49ff (diff)
parent7778f881ff7dc92fca44dd414b02e7345f8db930 (diff)
downloadqtwebkit-7a7433bfa61e80b91d1e9e7cf4b44ee8fdc431a0.tar.gz
Merge remote-tracking branch 'origin/5.4' into dev
Conflicts: Tools/qmake/mkspecs/features/configure.prf Change-Id: I3a704585aaa8bbf4ba4e249248195b9271890981
Diffstat (limited to 'Source/JavaScriptCore')
-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/llint/LLIntData.cpp4
-rw-r--r--Source/JavaScriptCore/llint/LLIntOfflineAsmConfig.h6
-rw-r--r--Source/JavaScriptCore/llint/LowLevelInterpreter.asm29
-rw-r--r--Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm2
-rw-r--r--Source/JavaScriptCore/parser/ParserArena.h8
-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
15 files changed, 137 insertions, 35 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/llint/LLIntData.cpp b/Source/JavaScriptCore/llint/LLIntData.cpp
index f91da9c0a..f1e367510 100644
--- a/Source/JavaScriptCore/llint/LLIntData.cpp
+++ b/Source/JavaScriptCore/llint/LLIntData.cpp
@@ -116,7 +116,11 @@ void Data::performAssertions(VM& vm)
#if !ASSERT_DISABLED
Vector<int> testVector;
testVector.resize(42);
+#if USE(JSVALUE64) && OS(WINDOWS)
+ ASSERT(bitwise_cast<uint32_t*>(&testVector)[4] == 42);
+#else
ASSERT(bitwise_cast<uint32_t*>(&testVector)[sizeof(void*)/sizeof(uint32_t) + 1] == 42);
+#endif
ASSERT(bitwise_cast<int**>(&testVector)[0] == testVector.begin());
#endif
diff --git a/Source/JavaScriptCore/llint/LLIntOfflineAsmConfig.h b/Source/JavaScriptCore/llint/LLIntOfflineAsmConfig.h
index bad62ddf8..9010757b4 100644
--- a/Source/JavaScriptCore/llint/LLIntOfflineAsmConfig.h
+++ b/Source/JavaScriptCore/llint/LLIntOfflineAsmConfig.h
@@ -104,6 +104,12 @@
#define OFFLINE_ASM_JSVALUE64 0
#endif
+#if USE(JSVALUE64) && OS(WINDOWS)
+#define OFFLINE_ASM_WIN64 1
+#else
+#define OFFLINE_ASM_WIN64 0
+#endif
+
#if !ASSERT_DISABLED
#define OFFLINE_ASM_ASSERT_ENABLED 1
#else
diff --git a/Source/JavaScriptCore/llint/LowLevelInterpreter.asm b/Source/JavaScriptCore/llint/LowLevelInterpreter.asm
index 2b5a23c24..22ba11164 100644
--- a/Source/JavaScriptCore/llint/LowLevelInterpreter.asm
+++ b/Source/JavaScriptCore/llint/LowLevelInterpreter.asm
@@ -87,6 +87,12 @@ else
const PayloadOffset = 0
end
+if JSVALUE64
+ const JSCellPayloadOffset = 0
+else
+ const JSCellPayloadOffset = PayloadOffset
+end
+
# Constant for reasoning about butterflies.
const IsArray = 1
const IndexingShapeMask = 30
@@ -155,13 +161,14 @@ end
# This must match wtf/Vector.h
const VectorBufferOffset = 0
-if JSVALUE64
+if WIN64
+ const VectorSizeOffset = 16
+elsif JSVALUE64
const VectorSizeOffset = 12
else
const VectorSizeOffset = 8
end
-
# Some common utilities.
macro crash()
if C_LOOP
@@ -267,13 +274,13 @@ macro assertNotConstant(index)
end
macro functionForCallCodeBlockGetter(targetRegister)
- loadp Callee[cfr], targetRegister
+ loadp Callee + JSCellPayloadOffset[cfr], targetRegister
loadp JSFunction::m_executable[targetRegister], targetRegister
loadp FunctionExecutable::m_codeBlockForCall[targetRegister], targetRegister
end
macro functionForConstructCodeBlockGetter(targetRegister)
- loadp Callee[cfr], targetRegister
+ loadp Callee + JSCellPayloadOffset[cfr], targetRegister
loadp JSFunction::m_executable[targetRegister], targetRegister
loadp FunctionExecutable::m_codeBlockForConstruct[targetRegister], targetRegister
end
@@ -671,7 +678,7 @@ _llint_op_resolve_global_var:
macro resolveScopedVarBody(resolveOperations)
# First ResolveOperation is to skip scope chain nodes
getScope(macro(dest)
- loadp ScopeChain + PayloadOffset[cfr], dest
+ loadp ScopeChain + JSCellPayloadOffset[cfr], dest
end,
ResolveOperation::m_scopesToSkip[resolveOperations], t1, t2)
loadp JSVariableObject::m_registers[t1], t1 # t1 now contains the activation registers
@@ -696,7 +703,7 @@ _llint_op_resolve_scoped_var_on_top_scope:
loadisFromInstruction(1, t3)
# We know we want the top scope chain entry
- loadp ScopeChain + PayloadOffset[cfr], t1
+ loadp ScopeChain + JSCellPayloadOffset[cfr], t1
loadp JSVariableObject::m_registers[t1], t1 # t1 now contains the activation registers
# Second ResolveOperation tells us what offset to use
@@ -718,7 +725,7 @@ _llint_op_resolve_scoped_var_with_top_scope_check:
loadp JSScope::m_next[t1], dest
jmp .done
.scopeChainNotCreated:
- loadp ScopeChain + PayloadOffset[cfr], dest
+ loadp ScopeChain + JSCellPayloadOffset[cfr], dest
.done:
end,
# Second ResolveOperation tells us how many more nodes to skip
@@ -773,7 +780,7 @@ _llint_op_resolve_base_to_scope:
getResolveOperation(4, t0)
# First ResolveOperation is to skip scope chain nodes
getScope(macro(dest)
- loadp ScopeChain + PayloadOffset[cfr], dest
+ loadp ScopeChain + JSCellPayloadOffset[cfr], dest
end,
ResolveOperation::m_scopesToSkip[t0], t1, t2)
loadisFromInstruction(1, t3)
@@ -798,7 +805,7 @@ _llint_op_resolve_base_to_scope_with_top_scope_check:
loadp JSScope::m_next[t1], dest
jmp .done
.scopeChainNotCreated:
- loadp ScopeChain + PayloadOffset[cfr], dest
+ loadp ScopeChain + JSCellPayloadOffset[cfr], dest
.done:
end,
# Second ResolveOperation tells us how many more nodes to skip
@@ -823,7 +830,7 @@ macro interpretResolveWithBase(opcodeLength, slowPath)
getResolveOperation(4, t0)
btpz t0, .slowPath
- loadp ScopeChain[cfr], t3
+ loadp ScopeChain + JSCellPayloadOffset[cfr], t3
# Get the base
loadis ResolveOperation::m_operation[t0], t2
@@ -845,7 +852,7 @@ macro interpretResolveWithBase(opcodeLength, slowPath)
loadp JSScope::m_next[t1], dest
jmp .done
.scopeChainNotCreated:
- loadp ScopeChain + PayloadOffset[cfr], dest
+ loadp ScopeChain + JSCellPayloadOffset[cfr], dest
.done:
end,
sizeof ResolveOperation + ResolveOperation::m_scopesToSkip[t0], t1, t2)
diff --git a/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm b/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm
index 89e40c7d6..87aa09eab 100644
--- a/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm
+++ b/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm
@@ -1692,7 +1692,7 @@ _llint_op_next_pname:
loadi 20[PC], t2
loadi PayloadOffset[cfr, t2, 8], t2
loadp JSPropertyNameIterator::m_jsStrings[t2], t3
- loadi [t3, t0, 8], t3
+ loadi PayloadOffset[t3, t0, 8], t3
addi 1, t0
storei t0, PayloadOffset[cfr, t1, 8]
loadi 4[PC], t1
diff --git a/Source/JavaScriptCore/parser/ParserArena.h b/Source/JavaScriptCore/parser/ParserArena.h
index 45d4b158e..8d790c44c 100644
--- a/Source/JavaScriptCore/parser/ParserArena.h
+++ b/Source/JavaScriptCore/parser/ParserArena.h
@@ -71,6 +71,10 @@ namespace JSC {
template <typename T>
ALWAYS_INLINE const Identifier& IdentifierArena::makeIdentifier(VM* vm, const T* characters, size_t length)
{
+ if (length == 0) {
+ m_identifiers.append(Identifier(Identifier::EmptyIdentifier));
+ return m_identifiers.last();
+ }
if (characters[0] >= MaximumCachableCharacter) {
m_identifiers.append(Identifier(vm, characters, length));
return m_identifiers.last();
@@ -92,6 +96,10 @@ namespace JSC {
ALWAYS_INLINE const Identifier& IdentifierArena::makeIdentifierLCharFromUChar(VM* vm, const UChar* characters, size_t length)
{
+ if (length == 0) {
+ m_identifiers.append(Identifier(Identifier::EmptyIdentifier));
+ return m_identifiers.last();
+ }
if (characters[0] >= MaximumCachableCharacter) {
m_identifiers.append(Identifier::createLCharFromUChar(vm, characters, length));
return m_identifiers.last();
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();