diff options
| author | Frederik Gladhorn <frederik.gladhorn@theqtcompany.com> | 2014-10-20 19:19:56 +0200 |
|---|---|---|
| committer | Frederik Gladhorn <frederik.gladhorn@theqtcompany.com> | 2014-10-20 20:29:12 +0200 |
| commit | 7a7433bfa61e80b91d1e9e7cf4b44ee8fdc431a0 (patch) | |
| tree | 2ca7eb63ddb38472305f41e8e5b81c89cd20b9f0 /Source/JavaScriptCore | |
| parent | ee21e513f3ed68af68e529b43c8fda94dfcc49ff (diff) | |
| parent | 7778f881ff7dc92fca44dd414b02e7345f8db930 (diff) | |
| download | qtwebkit-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.h | 5 | ||||
| -rw-r--r-- | Source/JavaScriptCore/assembler/MacroAssemblerARMv7.h | 6 | ||||
| -rw-r--r-- | Source/JavaScriptCore/assembler/MacroAssemblerMIPS.h | 6 | ||||
| -rw-r--r-- | Source/JavaScriptCore/assembler/MacroAssemblerSH4.h | 23 | ||||
| -rw-r--r-- | Source/JavaScriptCore/dfg/DFGOperations.cpp | 13 | ||||
| -rw-r--r-- | Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp | 18 | ||||
| -rw-r--r-- | Source/JavaScriptCore/llint/LLIntData.cpp | 4 | ||||
| -rw-r--r-- | Source/JavaScriptCore/llint/LLIntOfflineAsmConfig.h | 6 | ||||
| -rw-r--r-- | Source/JavaScriptCore/llint/LowLevelInterpreter.asm | 29 | ||||
| -rw-r--r-- | Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm | 2 | ||||
| -rw-r--r-- | Source/JavaScriptCore/parser/ParserArena.h | 8 | ||||
| -rw-r--r-- | Source/JavaScriptCore/runtime/JSString.cpp | 1 | ||||
| -rw-r--r-- | Source/JavaScriptCore/runtime/JSString.h | 14 | ||||
| -rw-r--r-- | Source/JavaScriptCore/runtime/Operations.h | 33 | ||||
| -rw-r--r-- | Source/JavaScriptCore/runtime/StringPrototype.cpp | 4 |
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(); |
