diff options
Diffstat (limited to 'JavaScriptCore')
135 files changed, 3825 insertions, 2275 deletions
diff --git a/JavaScriptCore/API/JSCallbackObject.h b/JavaScriptCore/API/JSCallbackObject.h index cf42818..83442b2 100644 --- a/JavaScriptCore/API/JSCallbackObject.h +++ b/JavaScriptCore/API/JSCallbackObject.h @@ -80,7 +80,7 @@ struct JSCallbackObjectData { struct JSPrivatePropertyMap { JSValue getPrivateProperty(const Identifier& propertyName) const { - PrivatePropertyMap::const_iterator location = m_propertyMap.find(propertyName.ustring().rep()); + PrivatePropertyMap::const_iterator location = m_propertyMap.find(propertyName.impl()); if (location == m_propertyMap.end()) return JSValue(); return location->second; @@ -88,12 +88,12 @@ struct JSCallbackObjectData { void setPrivateProperty(const Identifier& propertyName, JSValue value) { - m_propertyMap.set(propertyName.ustring().rep(), value); + m_propertyMap.set(propertyName.impl(), value); } void deletePrivateProperty(const Identifier& propertyName) { - m_propertyMap.remove(propertyName.ustring().rep()); + m_propertyMap.remove(propertyName.impl()); } void markChildren(MarkStack& markStack) @@ -105,7 +105,7 @@ struct JSCallbackObjectData { } private: - typedef HashMap<RefPtr<UString::Rep>, JSValue, IdentifierRepHash> PrivatePropertyMap; + typedef HashMap<RefPtr<StringImpl>, JSValue, IdentifierRepHash> PrivatePropertyMap; PrivatePropertyMap m_propertyMap; }; OwnPtr<JSPrivatePropertyMap> m_privateProperties; diff --git a/JavaScriptCore/API/JSCallbackObjectFunctions.h b/JavaScriptCore/API/JSCallbackObjectFunctions.h index 9a3e448..de5d842 100644 --- a/JavaScriptCore/API/JSCallbackObjectFunctions.h +++ b/JavaScriptCore/API/JSCallbackObjectFunctions.h @@ -146,14 +146,14 @@ bool JSCallbackObject<Base>::getOwnPropertySlot(ExecState* exec, const Identifie } if (OpaqueJSClassStaticValuesTable* staticValues = jsClass->staticValues(exec)) { - if (staticValues->contains(propertyName.ustring().rep())) { + if (staticValues->contains(propertyName.impl())) { slot.setCustom(this, staticValueGetter); return true; } } if (OpaqueJSClassStaticFunctionsTable* staticFunctions = jsClass->staticFunctions(exec)) { - if (staticFunctions->contains(propertyName.ustring().rep())) { + if (staticFunctions->contains(propertyName.impl())) { slot.setCustom(this, staticFunctionGetter); return true; } @@ -213,7 +213,7 @@ void JSCallbackObject<Base>::put(ExecState* exec, const Identifier& propertyName } if (OpaqueJSClassStaticValuesTable* staticValues = jsClass->staticValues(exec)) { - if (StaticValueEntry* entry = staticValues->get(propertyName.ustring().rep())) { + if (StaticValueEntry* entry = staticValues->get(propertyName.impl())) { if (entry->attributes & kJSPropertyAttributeReadOnly) return; if (JSObjectSetPropertyCallback setProperty = entry->setProperty) { @@ -235,7 +235,7 @@ void JSCallbackObject<Base>::put(ExecState* exec, const Identifier& propertyName } if (OpaqueJSClassStaticFunctionsTable* staticFunctions = jsClass->staticFunctions(exec)) { - if (StaticFunctionEntry* entry = staticFunctions->get(propertyName.ustring().rep())) { + if (StaticFunctionEntry* entry = staticFunctions->get(propertyName.impl())) { if (entry->attributes & kJSPropertyAttributeReadOnly) return; JSCallbackObject<Base>::putDirect(propertyName, value); // put as override property @@ -271,7 +271,7 @@ bool JSCallbackObject<Base>::deleteProperty(ExecState* exec, const Identifier& p } if (OpaqueJSClassStaticValuesTable* staticValues = jsClass->staticValues(exec)) { - if (StaticValueEntry* entry = staticValues->get(propertyName.ustring().rep())) { + if (StaticValueEntry* entry = staticValues->get(propertyName.impl())) { if (entry->attributes & kJSPropertyAttributeDontDelete) return false; return true; @@ -279,7 +279,7 @@ bool JSCallbackObject<Base>::deleteProperty(ExecState* exec, const Identifier& p } if (OpaqueJSClassStaticFunctionsTable* staticFunctions = jsClass->staticFunctions(exec)) { - if (StaticFunctionEntry* entry = staticFunctions->get(propertyName.ustring().rep())) { + if (StaticFunctionEntry* entry = staticFunctions->get(propertyName.impl())) { if (entry->attributes & kJSPropertyAttributeDontDelete) return false; return true; @@ -417,7 +417,7 @@ void JSCallbackObject<Base>::getOwnPropertyNames(ExecState* exec, PropertyNameAr typedef OpaqueJSClassStaticValuesTable::const_iterator iterator; iterator end = staticValues->end(); for (iterator it = staticValues->begin(); it != end; ++it) { - UString::Rep* name = it->first.get(); + StringImpl* name = it->first.get(); StaticValueEntry* entry = it->second; if (entry->getProperty && (!(entry->attributes & kJSPropertyAttributeDontEnum) || (mode == IncludeDontEnumProperties))) propertyNames.add(Identifier(exec, name)); @@ -428,7 +428,7 @@ void JSCallbackObject<Base>::getOwnPropertyNames(ExecState* exec, PropertyNameAr typedef OpaqueJSClassStaticFunctionsTable::const_iterator iterator; iterator end = staticFunctions->end(); for (iterator it = staticFunctions->begin(); it != end; ++it) { - UString::Rep* name = it->first.get(); + StringImpl* name = it->first.get(); StaticFunctionEntry* entry = it->second; if (!(entry->attributes & kJSPropertyAttributeDontEnum) || (mode == IncludeDontEnumProperties)) propertyNames.add(Identifier(exec, name)); @@ -528,7 +528,7 @@ JSValue JSCallbackObject<Base>::staticValueGetter(ExecState* exec, JSValue slotB for (JSClassRef jsClass = thisObj->classRef(); jsClass; jsClass = jsClass->parentClass) if (OpaqueJSClassStaticValuesTable* staticValues = jsClass->staticValues(exec)) - if (StaticValueEntry* entry = staticValues->get(propertyName.ustring().rep())) + if (StaticValueEntry* entry = staticValues->get(propertyName.impl())) if (JSObjectGetPropertyCallback getProperty = entry->getProperty) { if (!propertyNameRef) propertyNameRef = OpaqueJSString::create(propertyName.ustring()); @@ -561,7 +561,7 @@ JSValue JSCallbackObject<Base>::staticFunctionGetter(ExecState* exec, JSValue sl for (JSClassRef jsClass = thisObj->classRef(); jsClass; jsClass = jsClass->parentClass) { if (OpaqueJSClassStaticFunctionsTable* staticFunctions = jsClass->staticFunctions(exec)) { - if (StaticFunctionEntry* entry = staticFunctions->get(propertyName.ustring().rep())) { + if (StaticFunctionEntry* entry = staticFunctions->get(propertyName.impl())) { if (JSObjectCallAsFunctionCallback callAsFunction = entry->callAsFunction) { JSObject* o = new (exec) JSCallbackFunction(exec, asGlobalObject(thisObj->getAnonymousValue(0)), callAsFunction, propertyName); diff --git a/JavaScriptCore/API/JSClassRef.cpp b/JavaScriptCore/API/JSClassRef.cpp index d8393f1..decf493 100644 --- a/JavaScriptCore/API/JSClassRef.cpp +++ b/JavaScriptCore/API/JSClassRef.cpp @@ -45,13 +45,13 @@ const JSClassDefinition kJSClassDefinitionEmpty = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 static inline UString tryCreateStringFromUTF8(const char* string) { if (!string) - return UString::null(); + return UString(); size_t length = strlen(string); Vector<UChar, 1024> buffer(length); UChar* p = buffer.data(); if (conversionOK != convertUTF8ToUTF16(&string, string + length, &p, p + length)) - return UString::null(); + return UString(); return UString(buffer.data(), p - buffer.data()); } @@ -83,7 +83,7 @@ OpaqueJSClass::OpaqueJSClass(const JSClassDefinition* definition, OpaqueJSClass* if (!valueName.isNull()) { // Use a local variable here to sidestep an RVCT compiler bug. StaticValueEntry* entry = new StaticValueEntry(staticValue->getProperty, staticValue->setProperty, staticValue->attributes); - UStringImpl* impl = valueName.rep(); + StringImpl* impl = valueName.impl(); impl->ref(); m_staticValues->add(impl, entry); } @@ -98,7 +98,7 @@ OpaqueJSClass::OpaqueJSClass(const JSClassDefinition* definition, OpaqueJSClass* if (!functionName.isNull()) { // Use a local variable here to sidestep an RVCT compiler bug. StaticFunctionEntry* entry = new StaticFunctionEntry(staticFunction->callAsFunction, staticFunction->attributes); - UStringImpl* impl = functionName.rep(); + StringImpl* impl = functionName.impl(); impl->ref(); m_staticFunctions->add(impl, entry); } @@ -113,7 +113,7 @@ OpaqueJSClass::OpaqueJSClass(const JSClassDefinition* definition, OpaqueJSClass* OpaqueJSClass::~OpaqueJSClass() { // The empty string is shared across threads & is an identifier, in all other cases we should have done a deep copy in className(), below. - ASSERT(!m_className.size() || !m_className.rep()->isIdentifier()); + ASSERT(!m_className.length() || !m_className.impl()->isIdentifier()); if (m_staticValues) { OpaqueJSClassStaticValuesTable::const_iterator end = m_staticValues->end(); @@ -173,7 +173,7 @@ OpaqueJSClassContextData::OpaqueJSClassContextData(OpaqueJSClass* jsClass) ASSERT(!it->first->isIdentifier()); // Use a local variable here to sidestep an RVCT compiler bug. StaticValueEntry* entry = new StaticValueEntry(it->second->getProperty, it->second->setProperty, it->second->attributes); - staticValues->add(UString::Rep::create(it->first->characters(), it->first->length()), entry); + staticValues->add(StringImpl::create(it->first->characters(), it->first->length()), entry); } } else staticValues = 0; @@ -185,7 +185,7 @@ OpaqueJSClassContextData::OpaqueJSClassContextData(OpaqueJSClass* jsClass) ASSERT(!it->first->isIdentifier()); // Use a local variable here to sidestep an RVCT compiler bug. StaticFunctionEntry* entry = new StaticFunctionEntry(it->second->callAsFunction, it->second->attributes); - staticFunctions->add(UString::Rep::create(it->first->characters(), it->first->length()), entry); + staticFunctions->add(StringImpl::create(it->first->characters(), it->first->length()), entry); } } else @@ -216,7 +216,7 @@ OpaqueJSClassContextData& OpaqueJSClass::contextData(ExecState* exec) UString OpaqueJSClass::className() { // Make a deep copy, so that the caller has no chance to put the original into IdentifierTable. - return UString(m_className.data(), m_className.size()); + return UString(m_className.characters(), m_className.length()); } OpaqueJSClassStaticValuesTable* OpaqueJSClass::staticValues(JSC::ExecState* exec) diff --git a/JavaScriptCore/API/JSClassRef.h b/JavaScriptCore/API/JSClassRef.h index 5a3a17e..5062093 100644 --- a/JavaScriptCore/API/JSClassRef.h +++ b/JavaScriptCore/API/JSClassRef.h @@ -55,8 +55,8 @@ struct StaticFunctionEntry : FastAllocBase { JSPropertyAttributes attributes; }; -typedef HashMap<RefPtr<JSC::UString::Rep>, StaticValueEntry*> OpaqueJSClassStaticValuesTable; -typedef HashMap<RefPtr<JSC::UString::Rep>, StaticFunctionEntry*> OpaqueJSClassStaticFunctionsTable; +typedef HashMap<RefPtr<StringImpl>, StaticValueEntry*> OpaqueJSClassStaticValuesTable; +typedef HashMap<RefPtr<StringImpl>, StaticFunctionEntry*> OpaqueJSClassStaticFunctionsTable; struct OpaqueJSClass; diff --git a/JavaScriptCore/API/JSRetainPtr.h b/JavaScriptCore/API/JSRetainPtr.h index 69c6de1..a884f38 100644 --- a/JavaScriptCore/API/JSRetainPtr.h +++ b/JavaScriptCore/API/JSRetainPtr.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2005, 2006, 2007 Apple Inc. All rights reserved. + * Copyright (C) 2005, 2006, 2007, 2010 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -37,23 +37,20 @@ inline void JSRelease(JSStringRef string) { JSStringRelease(string); } enum AdoptTag { Adopt }; -template <typename T> class JSRetainPtr { +template<typename T> class JSRetainPtr { public: - JSRetainPtr() : m_ptr(0) {} + JSRetainPtr() : m_ptr(0) { } JSRetainPtr(T ptr) : m_ptr(ptr) { if (ptr) JSRetain(ptr); } - JSRetainPtr(AdoptTag, T ptr) : m_ptr(ptr) { } - - JSRetainPtr(const JSRetainPtr& o) : m_ptr(o.m_ptr) { if (T ptr = m_ptr) JSRetain(ptr); } - - ~JSRetainPtr() { if (T ptr = m_ptr) JSRelease(ptr); } - - template <typename U> JSRetainPtr(const JSRetainPtr<U>& o) : m_ptr(o.get()) { if (T ptr = m_ptr) JSRetain(ptr); } + JSRetainPtr(const JSRetainPtr&); + template<typename U> JSRetainPtr(const JSRetainPtr<U>&); + ~JSRetainPtr(); T get() const { return m_ptr; } - T releaseRef() { T tmp = m_ptr; m_ptr = 0; return tmp; } - + void clear(); + T leakRef(); + T operator->() const { return m_ptr; } bool operator!() const { return !m_ptr; } @@ -63,19 +60,57 @@ public: operator UnspecifiedBoolType() const { return m_ptr ? &JSRetainPtr::m_ptr : 0; } JSRetainPtr& operator=(const JSRetainPtr&); - template <typename U> JSRetainPtr& operator=(const JSRetainPtr<U>&); + template<typename U> JSRetainPtr& operator=(const JSRetainPtr<U>&); JSRetainPtr& operator=(T); - template <typename U> JSRetainPtr& operator=(U*); + template<typename U> JSRetainPtr& operator=(U*); void adopt(T); void swap(JSRetainPtr&); + // FIXME: Remove releaseRef once we change all callers to call leakRef instead. + T releaseRef() { return leakRef(); } + private: T m_ptr; }; -template <typename T> inline JSRetainPtr<T>& JSRetainPtr<T>::operator=(const JSRetainPtr<T>& o) +template<typename T> inline JSRetainPtr<T>::JSRetainPtr(const JSRetainPtr& o) + : m_ptr(o.m_ptr) +{ + if (m_ptr) + JSRetain(m_ptr); +} + +template<typename T> template<typename U> inline JSRetainPtr<T>::JSRetainPtr(const JSRetainPtr<U>& o) + : m_ptr(o.get()) +{ + if (m_ptr) + JSRetain(m_ptr); +} + +template<typename T> inline JSRetainPtr<T>::~JSRetainPtr() +{ + if (m_ptr) + JSRelease(m_ptr); +} + +template<typename T> inline void JSRetainPtr<T>::clear() +{ + if (T ptr = m_ptr) { + m_ptr = 0; + JSRelease(ptr); + } +} + +template<typename T> inline T JSRetainPtr<T>::leakRef() +{ + T ptr = m_ptr; + m_ptr = 0; + return ptr; +} + +template<typename T> inline JSRetainPtr<T>& JSRetainPtr<T>::operator=(const JSRetainPtr<T>& o) { T optr = o.get(); if (optr) @@ -87,7 +122,7 @@ template <typename T> inline JSRetainPtr<T>& JSRetainPtr<T>::operator=(const JSR return *this; } -template <typename T> template <typename U> inline JSRetainPtr<T>& JSRetainPtr<T>::operator=(const JSRetainPtr<U>& o) +template<typename T> template<typename U> inline JSRetainPtr<T>& JSRetainPtr<T>::operator=(const JSRetainPtr<U>& o) { T optr = o.get(); if (optr) @@ -99,7 +134,7 @@ template <typename T> template <typename U> inline JSRetainPtr<T>& JSRetainPtr<T return *this; } -template <typename T> inline JSRetainPtr<T>& JSRetainPtr<T>::operator=(T optr) +template<typename T> inline JSRetainPtr<T>& JSRetainPtr<T>::operator=(T optr) { if (optr) JSRetain(optr); @@ -110,7 +145,7 @@ template <typename T> inline JSRetainPtr<T>& JSRetainPtr<T>::operator=(T optr) return *this; } -template <typename T> inline void JSRetainPtr<T>::adopt(T optr) +template<typename T> inline void JSRetainPtr<T>::adopt(T optr) { T ptr = m_ptr; m_ptr = optr; @@ -118,7 +153,7 @@ template <typename T> inline void JSRetainPtr<T>::adopt(T optr) JSRelease(ptr); } -template <typename T> template <typename U> inline JSRetainPtr<T>& JSRetainPtr<T>::operator=(U* optr) +template<typename T> template<typename U> inline JSRetainPtr<T>& JSRetainPtr<T>::operator=(U* optr) { if (optr) JSRetain(optr); @@ -129,42 +164,42 @@ template <typename T> template <typename U> inline JSRetainPtr<T>& JSRetainPtr<T return *this; } -template <class T> inline void JSRetainPtr<T>::swap(JSRetainPtr<T>& o) +template<typename T> inline void JSRetainPtr<T>::swap(JSRetainPtr<T>& o) { std::swap(m_ptr, o.m_ptr); } -template <class T> inline void swap(JSRetainPtr<T>& a, JSRetainPtr<T>& b) +template<typename T> inline void swap(JSRetainPtr<T>& a, JSRetainPtr<T>& b) { a.swap(b); } -template <typename T, typename U> inline bool operator==(const JSRetainPtr<T>& a, const JSRetainPtr<U>& b) +template<typename T, typename U> inline bool operator==(const JSRetainPtr<T>& a, const JSRetainPtr<U>& b) { return a.get() == b.get(); } -template <typename T, typename U> inline bool operator==(const JSRetainPtr<T>& a, U* b) +template<typename T, typename U> inline bool operator==(const JSRetainPtr<T>& a, U* b) { return a.get() == b; } -template <typename T, typename U> inline bool operator==(T* a, const JSRetainPtr<U>& b) +template<typename T, typename U> inline bool operator==(T* a, const JSRetainPtr<U>& b) { return a == b.get(); } -template <typename T, typename U> inline bool operator!=(const JSRetainPtr<T>& a, const JSRetainPtr<U>& b) +template<typename T, typename U> inline bool operator!=(const JSRetainPtr<T>& a, const JSRetainPtr<U>& b) { return a.get() != b.get(); } -template <typename T, typename U> inline bool operator!=(const JSRetainPtr<T>& a, U* b) +template<typename T, typename U> inline bool operator!=(const JSRetainPtr<T>& a, U* b) { return a.get() != b; } -template <typename T, typename U> inline bool operator!=(T* a, const JSRetainPtr<U>& b) +template<typename T, typename U> inline bool operator!=(T* a, const JSRetainPtr<U>& b) { return a != b.get(); } diff --git a/JavaScriptCore/API/OpaqueJSString.cpp b/JavaScriptCore/API/OpaqueJSString.cpp index f740abe..9a116e6 100644 --- a/JavaScriptCore/API/OpaqueJSString.cpp +++ b/JavaScriptCore/API/OpaqueJSString.cpp @@ -35,7 +35,7 @@ using namespace JSC; PassRefPtr<OpaqueJSString> OpaqueJSString::create(const UString& ustring) { if (!ustring.isNull()) - return adoptRef(new OpaqueJSString(ustring.data(), ustring.size())); + return adoptRef(new OpaqueJSString(ustring.characters(), ustring.length())); return 0; } @@ -43,7 +43,7 @@ UString OpaqueJSString::ustring() const { if (this && m_characters) return UString(m_characters, m_length); - return UString::null(); + return UString(); } Identifier OpaqueJSString::identifier(JSGlobalData* globalData) const diff --git a/JavaScriptCore/CMakeLists.txt b/JavaScriptCore/CMakeLists.txt index a944363..89c9ef1 100644 --- a/JavaScriptCore/CMakeLists.txt +++ b/JavaScriptCore/CMakeLists.txt @@ -203,13 +203,10 @@ GENERATE_HASH_LUT(${JAVASCRIPTCORE_DIR}/parser/Keywords.table ${DERIVED_SOURCES_ LIST(APPEND JavaScriptCore_HEADERS ${DERIVED_SOURCES_DIR}/Lexer.lut.h) # GENERATOR: "chartables.c": compile and execute the chartables generator (and add it to sources) -IF (MSVC) - SET(JSC_DFTABLES_PREPROCESSOR --preprocessor=cl.exe) -ENDIF () ADD_CUSTOM_COMMAND( OUTPUT ${DERIVED_SOURCES_DIR}/chartables.c MAIN_DEPENDENCY ${JAVASCRIPTCORE_DIR}/pcre/dftables - COMMAND ${PERL_EXECUTABLE} ${JAVASCRIPTCORE_DIR}/pcre/dftables ${JSC_DFTABLES_PREPROCESSOR} ${DERIVED_SOURCES_DIR}/chartables.c + COMMAND ${PERL_EXECUTABLE} ${JAVASCRIPTCORE_DIR}/pcre/dftables --preprocessor "${CODE_GENERATOR_PREPROCESSOR}" ${DERIVED_SOURCES_DIR}/chartables.c VERBATIM) ADD_SOURCE_DEPENDENCIES(${JAVASCRIPTCORE_DIR}/pcre/pcre_tables.cpp ${DERIVED_SOURCES_DIR}/chartables.c) @@ -264,7 +261,10 @@ INCLUDE_DIRECTORIES(${JavaScriptCore_INCLUDE_DIRECTORIES}) ADD_DEFINITIONS(-DBUILDING_JavaScriptCore) ADD_LIBRARY(${JavaScriptCore_LIBRARY_NAME} ${JavaScriptCore_LIBRARY_TYPE} ${JavaScriptCore_HEADERS} ${JavaScriptCore_SOURCES}) TARGET_LINK_LIBRARIES(${JavaScriptCore_LIBRARY_NAME} ${JavaScriptCore_LIBRARIES}) -ADD_TARGET_PROPERTIES(${JavaScriptCore_LIBRARY_NAME} LINK_FLAGS ${JavaScriptCore_LINK_FLAGS}) + +IF (JavaScriptCore_LINK_FLAGS) + ADD_TARGET_PROPERTIES(${JavaScriptCore_LIBRARY_NAME} LINK_FLAGS "${JavaScriptCore_LINK_FLAGS}") +ENDIF () IF (SHARED_CORE) SET_TARGET_PROPERTIES(${JavaScriptCore_LIBRARY_NAME} PROPERTIES VERSION ${PROJECT_VERSION} SOVERSION ${PROJECT_VERSION_MAJOR}) diff --git a/JavaScriptCore/ChangeLog b/JavaScriptCore/ChangeLog index c7c09b0..1c7f689 100644 --- a/JavaScriptCore/ChangeLog +++ b/JavaScriptCore/ChangeLog @@ -1,3 +1,1369 @@ +2010-08-18 Gabor Loki <loki@webkit.org> + + Reviewed by Gavin Barraclough. + + The JITStackFrame is wrong using Thumb-2 JIT with JSVALUE32_64 + https://bugs.webkit.org/show_bug.cgi?id=43897 + + A 64 bits wide member in a structure is aligned to 8 bytes on ARM by + default, but this is not taken into account in the offset defines of + JITStackFrame. + + * jit/JITStubs.cpp: + * jit/JITStubs.h: + +2010-08-18 Gavin Barraclough <barraclough@apple.com> + + Rubber stamped by Sam Weinig. + + Rename UString::substr to substringSharingImpl, add to WTF::String. + Now WTF::String can do everything that JSC::UString can do! + + * JavaScriptCore.exp: + * bytecode/CodeBlock.cpp: + (JSC::escapeQuotes): + * bytecompiler/NodesCodegen.cpp: + (JSC::substitute): + * parser/SourceProvider.h: + (JSC::UStringSourceProvider::getRange): + * runtime/FunctionPrototype.cpp: + (JSC::insertSemicolonIfNeeded): + * runtime/JSGlobalObjectFunctions.cpp: + (JSC::parseInt): + * runtime/JSONObject.cpp: + (JSC::gap): + (JSC::Stringifier::indent): + (JSC::Stringifier::unindent): + * runtime/JSString.cpp: + (JSC::JSString::replaceCharacter): + * runtime/NumberPrototype.cpp: + (JSC::numberProtoFuncToFixed): + (JSC::numberProtoFuncToPrecision): + * runtime/StringPrototype.cpp: + (JSC::stringProtoFuncReplace): + (JSC::trimString): + * runtime/UString.cpp: + (JSC::UString::substringSharingImpl): + * runtime/UString.h: + * wtf/text/WTFString.cpp: + (WTF::String::substringSharingImpl): + * wtf/text/WTFString.h: + +2010-08-18 Gavin Barraclough <barraclough@apple.com> + + Windows build fix. + + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def: + * JavaScriptCore.xcodeproj/project.pbxproj: + +2010-08-18 Gavin Barraclough <barraclough@apple.com> + + Windows build fix. + + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def: + * JavaScriptCore.xcodeproj/project.pbxproj: + +2010-08-17 Gavin Barraclough <barraclough@apple.com> + + Reviewed by Sam Weinig. + + Bug 44146 - Remove toDouble/toUInt32 methods from UString. + + These methods all implement JavaScript language specific behaviour, and as such + are not suited to being on a generic string object. They are also inefficient + and incorrectly used, refactor & cleanup. Uses of these methods really divide + out into two cases. + + ToNumber: + Uses of toDouble from JSString and from parseFloat are implementing ecma's + ToNumber conversion from strings (see ecma-262 9.3.1), so UString::toDouble + should largely just be moved out to a global jsToNumber function. ToNumber is + capable of recognizing either decimal or hexadecimal numbers, but parseFloat + should only recognize decimal values. This is currently handled by testing for + hexadecimal before calling toDouble, which should unnecessary - instead we can + just split out the two parts to the grammar into separate functions. Also, + strtod recognizes a set of literals (nan, inf, and infinity - all with any + capitalization) - which are not defined by any of the specs we are implementing. + To handle this we need to perform additional work in toDouble to convert the + unsupported cases of infinities back to NaNs. Instead we should simply remove + support for this literals from strtod. This should provide a more desirable + behaviour for all clients of strtod. + + Indexed properties: + Uses of the toStrictUInt32 methods are were all converting property names to + indices, and all uses of toUInt32 were incorrect; in all cases we should have + been calling toUInt32. This error results in some incorrect behaviour in the + DOM (accessing property "0 " of a NodeList should fail; it currently does not). + Move this method onto Identifier (our canonical property name), and make it + always perform a strict conversion. Add a layout test to check NodeList does + convert indexed property names correctly. + + * JavaScriptCore.exp: + * runtime/Arguments.cpp: + (JSC::Arguments::getOwnPropertySlot): + (JSC::Arguments::getOwnPropertyDescriptor): + (JSC::Arguments::put): + (JSC::Arguments::deleteProperty): + * runtime/Identifier.cpp: + (JSC::Identifier::toUInt32): + * runtime/Identifier.h: + (JSC::Identifier::toUInt32): + * runtime/JSArray.cpp: + (JSC::JSArray::getOwnPropertySlot): + (JSC::JSArray::getOwnPropertyDescriptor): + (JSC::JSArray::put): + (JSC::JSArray::deleteProperty): + * runtime/JSArray.h: + (JSC::Identifier::toArrayIndex): + * runtime/JSByteArray.cpp: + (JSC::JSByteArray::getOwnPropertySlot): + (JSC::JSByteArray::getOwnPropertyDescriptor): + (JSC::JSByteArray::put): + * runtime/JSGlobalObjectFunctions.cpp: + (JSC::isInfinity): + (JSC::jsHexIntegerLiteral): + (JSC::jsStrDecimalLiteral): + (JSC::jsToNumber): + (JSC::parseFloat): + * runtime/JSGlobalObjectFunctions.h: + * runtime/JSString.cpp: + (JSC::JSString::getPrimitiveNumber): + (JSC::JSString::toNumber): + (JSC::JSString::getStringPropertyDescriptor): + * runtime/JSString.h: + (JSC::JSString::getStringPropertySlot): + * runtime/ObjectPrototype.cpp: + (JSC::ObjectPrototype::put): + * runtime/StringObject.cpp: + (JSC::StringObject::deleteProperty): + * runtime/UString.cpp: + * runtime/UString.h: + * wtf/dtoa.cpp: + (WTF::strtod): + +2010-08-17 Gavin Barraclough <barraclough@apple.com> + + Reviewed by Sam Weinig. + + Bug 44099 - REGRESSION(r65468): Crashes in StringImpl::find + + Bug 44080 introuduced a couple of cases in which array bounds could be overrun. + One of these was fixed in r65493, this patch fixes the other and address the + concerns voiced in comment #6 by restructuring the loops to remove the code + dupliction without introducing an additional if check. + + * wtf/text/StringImpl.cpp: + (WTF::StringImpl::find): + (WTF::StringImpl::findIgnoringCase): + (WTF::StringImpl::reverseFind): + (WTF::StringImpl::reverseFindIgnoringCase): + +2010-08-17 No'am Rosenthal <noam.rosenthal@nokia.com> + + Reviewed by Ariya Hidayat. + + [Qt] Move the accelerated compositing build flag to the right place + https://bugs.webkit.org/show_bug.cgi?id=43882 + + * wtf/Platform.h: + +2010-08-17 Yuta Kitamura <yutak@chromium.org> + + Reviewed by Shinichiro Hamaji. + + Avoid uninitialized memory read in StringImpl::find(). + + REGRESSION(r65468): Crashes in StringImpl::find + https://bugs.webkit.org/show_bug.cgi?id=44099 + + * wtf/text/StringImpl.cpp: + (WTF::StringImpl::find): + +2010-08-16 Gavin Barraclough <barraclough@apple.com> + + Rubber stamped by Sam Weinig + + Add VectorTraits to String & DefaultHash traits to UString to unify behaviour. + + * runtime/UString.h: + (JSC::UStringHash::hash): + (JSC::UStringHash::equal): + (WTF::): + * wtf/text/WTFString.h: + (WTF::): + +2010-08-16 Gavin Barraclough <barraclough@apple.com> + + Rubber stamped by Sam Weinig + + Remove unnecessary includes from UString.h, add new includes as necessary. + + * profiler/CallIdentifier.h: + * profiler/ProfileNode.h: + * runtime/DateConversion.cpp: + * runtime/Identifier.h: + (JSC::IdentifierRepHash::hash): + * runtime/RegExpCache.h: + * runtime/RegExpKey.h: + * runtime/UString.cpp: + (JSC::UString::substr): + * runtime/UString.h: + * wtf/text/WTFString.h: + +2010-08-16 Gavin Barraclough <barraclough@apple.com> + + Reviewed by Sam Weinig + + Bug 44080 - String find/reverseFind methods need tidying up + These methods have a couple of problems with their interface, and implementation. + + These methods take and int index, and return an int - however this is problematic + since on 64-bit string indices may have a full 32-bit range. This spills out into + surrounding code, which unsafely casts string indices from unsigned to int. Code + checking the result of these methods check for a mix of "== -1", "< 0", and + "== notFound". Clean this up by changing these methods to take an unsigned + starting index, and return a size_t. with a failed match indicated by notFound. + reverseFind also has a special meaning for the starting index argument, in that a + negative index is interpreted as an offset back from the end of the string. Remove + this functionality, in the (1!) case where it is used we should just calculate the + offset by subtracting from the string's length. + + The implementation has a few problems too. The code is not in webkit style, in + using assorted abbreviations in variable names, and implementations of similar + find methods with differing argument types were unnecessarily inconsistent. When + find is passed const char* data the string would be handled as latin1 (zero + extended to UTF-16) for all characters but the first; this is sign extended. + Case-insensitive find is broken for unicode strings; the hashing optimization is + not unicode safe, and could result in false negatives. + + Unify UString find methods to match String. + + * JavaScriptCore.exp: + * bytecode/CodeBlock.cpp: + (JSC::escapeQuotes): + * bytecompiler/NodesCodegen.cpp: + (JSC::substitute): + * runtime/JSString.cpp: + (JSC::JSString::replaceCharacter): + * runtime/RegExp.cpp: + (JSC::RegExp::RegExp): + * runtime/RegExpKey.h: + (JSC::RegExpKey::getFlagsValue): + * runtime/StringPrototype.cpp: + (JSC::substituteBackreferencesSlow): + (JSC::substituteBackreferences): + (JSC::stringProtoFuncReplace): + (JSC::stringProtoFuncIndexOf): + (JSC::stringProtoFuncLastIndexOf): + (JSC::stringProtoFuncSplit): + * runtime/UString.cpp: + * runtime/UString.h: + (JSC::UString::find): + (JSC::UString::reverseFind): + * wtf/text/AtomicString.h: + (WTF::AtomicString::find): + * wtf/text/StringImpl.cpp: + (WTF::StringImpl::find): + (WTF::StringImpl::findCaseInsensitive): + (WTF::StringImpl::reverseFind): + (WTF::StringImpl::reverseFindCaseInsensitive): + (WTF::StringImpl::endsWith): + (WTF::StringImpl::replace): + * wtf/text/StringImpl.h: + (WTF::StringImpl::startsWith): + * wtf/text/WTFString.cpp: + (WTF::String::split): + * wtf/text/WTFString.h: + (WTF::String::find): + (WTF::String::reverseFind): + (WTF::String::findCaseInsensitive): + (WTF::String::reverseFindCaseInsensitive): + (WTF::String::contains): + (WTF::find): + (WTF::reverseFind): + +2010-08-16 Kevin Ollivier <kevino@theolliviers.com> + + [wx] Build fix, do not build WebCore as a convenience library as this leads to + errors in the Win build w/export symbols and causes problems with DOM bindings + debugging in gdb. + + * wscript: + +2010-08-16 Leandro Pereira <leandro@profusion.mobi> + + [EFL] Build fix after r65366. + + * CMakeLists.txt: Use if (VAR) instead of if (${VAR}) to check if + they're empty. + * jsc/CMakeLists.txt: Ditto. + * wtf/CMakeLists.txt: Ditto. + +2010-08-15 Kevin Ollivier <kevino@theolliviers.com> + + [wx] Build fix, don't build intermediate source in DerivedSources dir. + + * wscript: + +2010-08-14 Patrick Gansterer <paroga@paroga.com> + + Reviewed by Kenneth Rohde Christiansen. + + [CMake] Add preprocessor detection for generator scripts + https://bugs.webkit.org/show_bug.cgi?id=43984 + + * CMakeLists.txt: + +2010-08-14 Patrick Gansterer <paroga@paroga.com> + + Reviewed by Kenneth Rohde Christiansen. + + [CMake] Set target properties only if available + https://bugs.webkit.org/show_bug.cgi?id=43978 + + * CMakeLists.txt: + * jsc/CMakeLists.txt: + * wtf/CMakeLists.txt: + +2010-08-13 Kevin Ollivier <kevino@theolliviers.com> + + [wx] Build fix, add CString to the list of forwards. + + * wtf/Forward.h: + +2010-08-13 Gavin Barraclough <barraclough@apple.com> + + Windows build fix + + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def: + +2010-08-13 Gavin Barraclough <barraclough@apple.com> + + Windows build fix + + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def: + +2010-08-13 Gavin Barraclough <barraclough@apple.com> + + Windows build fix + + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def: + +2010-08-13 Gavin Barraclough <barraclough@apple.com> + + Rubber stamped by Sam Weinig. + Switch String::/UString::ascii() to return a CString. + + * JavaScriptCore.exp: + * JavaScriptCore.xcodeproj/project.pbxproj: + * bytecode/CodeBlock.cpp: + (JSC::CodeBlock::dump): + * bytecode/SamplingTool.cpp: + (JSC::SamplingTool::dump): + * interpreter/CallFrame.cpp: + (JSC::CallFrame::dumpCaller): + * jsc.cpp: + (runWithScripts): + (runInteractive): + * runtime/Identifier.h: + (JSC::Identifier::ascii): + * runtime/ScopeChain.cpp: + (JSC::ScopeChainNode::print): + * runtime/UString.cpp: + (JSC::UString::ascii): + (JSC::UString::latin1): + * runtime/UString.h: + * wtf/text/StringImpl.cpp: + (WTF::StringImpl::asciiOLD): + * wtf/text/StringImpl.h: + * wtf/text/WTFString.cpp: + (WTF::String::ascii): + (WTF::String::latin1): + * wtf/text/WTFString.h: + +2010-08-13 Gabor Loki <loki@webkit.org> + + Reviewed by Gavin Barraclough. + + Avoid increasing required alignment of target type warning on ARM + https://bugs.webkit.org/show_bug.cgi?id=38045 + + The reinterpret_cast<Type1*>([pointer to Type2]) expressions - where + sizeof(Type1) > sizeof(Type2) - cause the following warning on ARM: + increases required alignment of target type warnings. + Casting the type of [pointer to Type2] object to void* bypasses the + warning. + + * assembler/ARMAssembler.cpp: + (JSC::ARMAssembler::executableCopy): + * assembler/AssemblerBuffer.h: + (JSC::AssemblerBuffer::putShortUnchecked): + (JSC::AssemblerBuffer::putIntUnchecked): + (JSC::AssemblerBuffer::putInt64Unchecked): + * interpreter/RegisterFile.h: + (JSC::RegisterFile::RegisterFile): + (JSC::RegisterFile::grow): + * jit/JITStubs.cpp: + * pcre/pcre_compile.cpp: + (jsRegExpCompile): + * runtime/JSArray.cpp: + (JSC::JSArray::putSlowCase): + (JSC::JSArray::increaseVectorLength): + (JSC::JSArray::increaseVectorPrefixLength): + (JSC::JSArray::shiftCount): + (JSC::JSArray::unshiftCount): + * wtf/FastMalloc.cpp: + (WTF::PageHeapAllocator::New): + (WTF::TCMalloc_Central_FreeList::Populate): + * wtf/MD5.cpp: + (WTF::reverseBytes): + (WTF::MD5::addBytes): + (WTF::MD5::checksum): + * wtf/StdLibExtras.h: + (isPointerTypeAlignmentOkay): + (reinterpret_cast_ptr): + * wtf/Vector.h: + (WTF::VectorBuffer::inlineBuffer): + * wtf/qt/StringQt.cpp: + (WTF::String::String): + +2010-08-13 Gavin Barraclough <barraclough@apple.com> + + Reviewed by Sam Weinig + + Unify UString::UTF8String() & String::utf8() methods, + remove UString::cost() & make atArrayIndex a free function. + + * JavaScriptCore.exp: + * bytecode/CodeBlock.cpp: + (JSC::constantName): + (JSC::idName): + (JSC::CodeBlock::registerName): + (JSC::regexpName): + (JSC::printGlobalResolveInfo): + (JSC::printStructureStubInfo): + (JSC::CodeBlock::printStructure): + (JSC::CodeBlock::printStructures): + * jsc.cpp: + (functionPrint): + (functionDebug): + (runInteractive): + (fillBufferWithContentsOfFile): + * pcre/pcre_exec.cpp: + (Histogram::~Histogram): + * profiler/CallIdentifier.h: + (JSC::CallIdentifier::c_str): + * profiler/Profile.cpp: + (JSC::Profile::debugPrintDataSampleStyle): + * profiler/ProfileGenerator.cpp: + (JSC::ProfileGenerator::willExecute): + (JSC::ProfileGenerator::didExecute): + * profiler/ProfileNode.cpp: + (JSC::ProfileNode::debugPrintData): + (JSC::ProfileNode::debugPrintDataSampleStyle): + * runtime/Arguments.cpp: + (JSC::Arguments::getOwnPropertySlot): + (JSC::Arguments::getOwnPropertyDescriptor): + (JSC::Arguments::put): + (JSC::Arguments::deleteProperty): + * runtime/DateConversion.cpp: + (JSC::parseDate): + * runtime/Identifier.h: + (JSC::Identifier::toStrictUInt32): + * runtime/JSArray.cpp: + (JSC::JSArray::getOwnPropertySlot): + (JSC::JSArray::getOwnPropertyDescriptor): + (JSC::JSArray::put): + (JSC::JSArray::deleteProperty): + * runtime/JSArray.h: + (JSC::toArrayIndex): + * runtime/JSGlobalObjectFunctions.cpp: + (JSC::encode): + (JSC::parseInt): + (JSC::globalFuncJSCPrint): + * runtime/JSString.h: + (JSC::RopeBuilder::JSString): + * runtime/UString.cpp: + (JSC::UString::toDouble): + (JSC::putUTF8Triple): + (JSC::UString::utf8): + * runtime/UString.h: + (JSC::UString::~UString): + (JSC::UString::isNull): + (JSC::UString::isEmpty): + (JSC::UString::impl): + * wtf/text/WTFString.cpp: + (WTF::String::utf8): + * wtf/text/WTFString.h: + (WTF::String::~String): + (WTF::String::swap): + (WTF::String::isNull): + (WTF::String::isEmpty): + (WTF::String::impl): + (WTF::String::length): + (WTF::String::String): + (WTF::String::isHashTableDeletedValue): + +2010-08-12 Zoltan Herczeg <zherczeg@webkit.org> + + Reviewed by Gavin Barraclough. + + Refactoring the fpu code generator for the ARM port + https://bugs.webkit.org/show_bug.cgi?id=43842 + + Support up to 32 double precision registers, and the + recent VFP instruction formats. This patch is mainly + a style change which keeps the current functionality. + + * assembler/ARMAssembler.h: + (JSC::ARMRegisters::): + (JSC::ARMAssembler::): + (JSC::ARMAssembler::emitInst): + (JSC::ARMAssembler::emitDoublePrecisionInst): + (JSC::ARMAssembler::emitSinglePrecisionInst): + (JSC::ARMAssembler::vadd_f64_r): + (JSC::ARMAssembler::vdiv_f64_r): + (JSC::ARMAssembler::vsub_f64_r): + (JSC::ARMAssembler::vmul_f64_r): + (JSC::ARMAssembler::vcmp_f64_r): + (JSC::ARMAssembler::vsqrt_f64_r): + (JSC::ARMAssembler::vmov_vfp_r): + (JSC::ARMAssembler::vmov_arm_r): + (JSC::ARMAssembler::vcvt_f64_s32_r): + (JSC::ARMAssembler::vcvt_s32_f64_r): + (JSC::ARMAssembler::vmrs_apsr): + * assembler/MacroAssemblerARM.h: + (JSC::MacroAssemblerARM::addDouble): + (JSC::MacroAssemblerARM::divDouble): + (JSC::MacroAssemblerARM::subDouble): + (JSC::MacroAssemblerARM::mulDouble): + (JSC::MacroAssemblerARM::sqrtDouble): + (JSC::MacroAssemblerARM::convertInt32ToDouble): + (JSC::MacroAssemblerARM::branchDouble): + (JSC::MacroAssemblerARM::branchConvertDoubleToInt32): + +2010-08-12 Sheriff Bot <webkit.review.bot@gmail.com> + + Unreviewed, rolling out r65295. + http://trac.webkit.org/changeset/65295 + https://bugs.webkit.org/show_bug.cgi?id=43950 + + It broke 4 sputnik tests (Requested by Ossy on #webkit). + + * JavaScriptCore.exp: + * bytecode/CodeBlock.cpp: + (JSC::constantName): + (JSC::idName): + (JSC::CodeBlock::registerName): + (JSC::regexpName): + (JSC::printGlobalResolveInfo): + (JSC::printStructureStubInfo): + (JSC::CodeBlock::printStructure): + (JSC::CodeBlock::printStructures): + * jsc.cpp: + (functionPrint): + (functionDebug): + (runInteractive): + (fillBufferWithContentsOfFile): + * pcre/pcre_exec.cpp: + (Histogram::~Histogram): + * profiler/CallIdentifier.h: + (JSC::CallIdentifier::c_str): + * profiler/Profile.cpp: + (JSC::Profile::debugPrintDataSampleStyle): + * profiler/ProfileGenerator.cpp: + (JSC::ProfileGenerator::willExecute): + (JSC::ProfileGenerator::didExecute): + * profiler/ProfileNode.cpp: + (JSC::ProfileNode::debugPrintData): + (JSC::ProfileNode::debugPrintDataSampleStyle): + * runtime/Arguments.cpp: + (JSC::Arguments::getOwnPropertySlot): + (JSC::Arguments::getOwnPropertyDescriptor): + (JSC::Arguments::put): + (JSC::Arguments::deleteProperty): + * runtime/DateConversion.cpp: + (JSC::parseDate): + * runtime/Identifier.h: + (JSC::Identifier::Identifier): + (JSC::Identifier::toArrayIndex): + * runtime/JSArray.cpp: + (JSC::JSArray::getOwnPropertySlot): + (JSC::JSArray::getOwnPropertyDescriptor): + (JSC::JSArray::put): + (JSC::JSArray::deleteProperty): + * runtime/JSArray.h: + * runtime/JSGlobalObjectFunctions.cpp: + (JSC::encode): + (JSC::parseInt): + (JSC::globalFuncJSCPrint): + * runtime/JSString.h: + (JSC::RopeBuilder::JSString): + * runtime/UString.cpp: + (JSC::UString::toDouble): + (JSC::UString::UTF8String): + * runtime/UString.h: + (JSC::UString::isNull): + (JSC::UString::isEmpty): + (JSC::UString::impl): + (JSC::UString::cost): + (JSC::UString::~UString): + (JSC::UString::toArrayIndex): + * wtf/text/WTFString.cpp: + (WTF::String::utf8): + * wtf/text/WTFString.h: + (WTF::String::String): + (WTF::String::isHashTableDeletedValue): + (WTF::String::length): + (WTF::String::operator[]): + (WTF::String::isNull): + (WTF::String::isEmpty): + (WTF::String::impl): + +2010-08-12 Gavin Barraclough <barraclough@apple.com> + + Windows build fix. + + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def: + +2010-08-12 Gavin Barraclough <barraclough@apple.com> + + Reviewed by Sam Weinig + + Unify UString::UTF8String() & String::utf8() methods, + remove UString::cost() & make atArrayIndex a free function. + + * JavaScriptCore.exp: + * bytecode/CodeBlock.cpp: + (JSC::constantName): + (JSC::idName): + (JSC::CodeBlock::registerName): + (JSC::regexpName): + (JSC::printGlobalResolveInfo): + (JSC::printStructureStubInfo): + (JSC::CodeBlock::printStructure): + (JSC::CodeBlock::printStructures): + * jsc.cpp: + (functionPrint): + (functionDebug): + (runInteractive): + (fillBufferWithContentsOfFile): + * pcre/pcre_exec.cpp: + (Histogram::~Histogram): + * profiler/CallIdentifier.h: + (JSC::CallIdentifier::c_str): + * profiler/Profile.cpp: + (JSC::Profile::debugPrintDataSampleStyle): + * profiler/ProfileGenerator.cpp: + (JSC::ProfileGenerator::willExecute): + (JSC::ProfileGenerator::didExecute): + * profiler/ProfileNode.cpp: + (JSC::ProfileNode::debugPrintData): + (JSC::ProfileNode::debugPrintDataSampleStyle): + * runtime/Arguments.cpp: + (JSC::Arguments::getOwnPropertySlot): + (JSC::Arguments::getOwnPropertyDescriptor): + (JSC::Arguments::put): + (JSC::Arguments::deleteProperty): + * runtime/DateConversion.cpp: + (JSC::parseDate): + * runtime/Identifier.h: + (JSC::Identifier::toStrictUInt32): + * runtime/JSArray.cpp: + (JSC::JSArray::getOwnPropertySlot): + (JSC::JSArray::getOwnPropertyDescriptor): + (JSC::JSArray::put): + (JSC::JSArray::deleteProperty): + * runtime/JSArray.h: + (JSC::toArrayIndex): + * runtime/JSGlobalObjectFunctions.cpp: + (JSC::encode): + (JSC::parseInt): + (JSC::globalFuncJSCPrint): + * runtime/JSString.h: + (JSC::RopeBuilder::JSString): + * runtime/UString.cpp: + (JSC::UString::toDouble): + (JSC::putUTF8Triple): + (JSC::UString::utf8): + * runtime/UString.h: + (JSC::UString::~UString): + (JSC::UString::isNull): + (JSC::UString::isEmpty): + (JSC::UString::impl): + * wtf/text/WTFString.cpp: + (WTF::String::utf8): + * wtf/text/WTFString.h: + (WTF::String::~String): + (WTF::String::swap): + (WTF::String::isNull): + (WTF::String::isEmpty): + (WTF::String::impl): + (WTF::String::length): + (WTF::String::String): + (WTF::String::isHashTableDeletedValue): + +2010-08-12 Gavin Barraclough <barraclough@apple.com> + + Eeerk! - revert accidentally committed changes in UString! + + * JavaScriptCore.exp: + * runtime/UString.cpp: + (JSC::UString::UString): + * runtime/UString.h: + +2010-08-12 Gavin Barraclough <barraclough@apple.com> + + Reviewed by Sam Weinig + + Change UString constructors to match those in WTF::String. + This changes behaviour of UString((char*)0) to create null + strings, akin to UString() rather than UString::empty(). + (This matches String). Remove unused constructors from + UString, and add null-terminated UTF-16 constructor, to + match String. Move String's constructor into the .cpp to + match UString. + + * JavaScriptCore.exp: + * debugger/DebuggerCallFrame.cpp: + (JSC::DebuggerCallFrame::calculatedFunctionName): + * runtime/RegExpKey.h: + (JSC::RegExpKey::RegExpKey): + * runtime/SmallStrings.cpp: + (JSC::SmallStrings::createSingleCharacterString): + * runtime/UString.cpp: + (JSC::UString::UString): + * runtime/UString.h: + (JSC::UString::UString): + (JSC::UString::swap): + (JSC::UString::adopt): + (JSC::UString::operator[]): + * wtf/text/WTFString.h: + (WTF::String::String): + (WTF::String::adopt): + (WTF::String::operator[]): + +2010-08-12 David Levin <levin@chromium.org> + + Reviewed by NOBODY (build fix). + + * runtime/UString.h: Removed unneccessary #include. + +2010-08-12 Gavin Barraclough <barraclough@apple.com> + + Reviewed by Sam Weinig + + Revert changes to ALWAYS_INLINEness of a couple of functions in UString. + This appears to have degraded performance. + + * runtime/UString.cpp: + (JSC::UString::ascii): + * runtime/UString.h: + (JSC::UString::length): + (JSC::UString::isEmpty): + (JSC::UString::~UString): + +2010-08-12 Csaba Osztrogonác <ossy@webkit.org> + + Reviewed by Antonio Gomes. + + [Qt] Fix warnings: unknown conversion type character 'l' in format + https://bugs.webkit.org/show_bug.cgi?id=43359 + + Qt port doesn't call any printf in String::format(...), consequently + using __attribute__((format(printf,m,n))) is incorrect and causes + false positive warnings on Windows if you build with MinGW. + + Qt port calls QString::vsprintf(...) , which is platform + independent, and handles %lli, %llu and %llx on all platforms. + (http://trac.webkit.org/changeset/35712) + + * wtf/text/WTFString.h: + +2010-08-12 Gabor Loki <loki@webkit.org> + + Reviewed by Geoffrey Garen. + + Fix the array subscript is above array bounds warning in ByteArray on ARM. + https://bugs.webkit.org/show_bug.cgi?id=43358 + + The warning is very similar to this one: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=37861 + + * wtf/ByteArray.cpp: + (WTF::ByteArray::create): + +2010-08-12 Gustavo Noronha Silva <gustavo.noronha@collabora.co.uk> + + Reviewed by Martin Robinson. + + [GTK] Use GSettings to save/restore Web Inspector settings + https://bugs.webkit.org/show_bug.cgi?id=43512 + + * wtf/gobject/GRefPtr.cpp: Added support for GVariant, used by our + GSettings support. + (WTF::refGPtr): + (WTF::derefGPtr): + * wtf/gobject/GRefPtr.h: + +2010-08-12 Gabor Loki <loki@webkit.org> + + Reviewed by Simon Hausmann. + + The scratch register should be saved in YARR with ARM JIT + https://bugs.webkit.org/show_bug.cgi?id=43910 + + Reported by Jocelyn Turcotte. + + * yarr/RegexJIT.cpp: + (JSC::Yarr::RegexGenerator::generateEnter): + (JSC::Yarr::RegexGenerator::generateReturn): + +2010-08-11 Gavin Barraclough <barraclough@apple.com> + + Windows build fix. + + * JavaScriptCore.xcodeproj/project.pbxproj: + * wtf/Forward.h: + +2010-08-11 Leo Yang <leo.yang@torchmobile.com.cn> + + Reviewed by Geoffrey Garen. + + Date("") should be an invalid date. For IE, Firefox and Chrome, Date("") is invalid date, + which means isNaN(new Date("")) should return true. + https://bugs.webkit.org/show_bug.cgi?id=43793 + Tests: fast/js/date-constructor.html + + * runtime/JSGlobalData.cpp: + (JSC::JSGlobalData::resetDateCache): + +2010-08-11 Gavin Barraclough <barraclough@apple.com> + + Windows & !JIT build fix. + + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def: + * JavaScriptCore.xcodeproj/project.pbxproj: + * runtime/RegExp.cpp: + (JSC::RegExp::match): + +2010-08-11 Gavin Barraclough <barraclough@apple.com> + + Rubber stamp by sam weinig + + Touch a file to stop the bot rolling a bit change out! + + * runtime/UString.cpp: + (JSC::UString::ascii): + +2010-08-11 Kevin Ollivier <kevino@theolliviers.com> + + [wx] Build fix for wx and WebDOM bindings, add CString classes to the list of forwards. + + * wtf/Forward.h: + +2010-08-11 Gavin Barraclough <barraclough@apple.com> + + Rubber stamps by Darin Adler & Sam Weinig. + + Bug 43867 - Some UString cleanup + + Change JSC::UString data(), size(), and from(), to characters(), length(), and number() to match WTF::String. + Move string concatenation methods to a new header to simplify down UString.h. Remove is8Bit(). + + * API/JSClassRef.cpp: + (OpaqueJSClass::~OpaqueJSClass): + (OpaqueJSClass::className): + * API/OpaqueJSString.cpp: + (OpaqueJSString::create): + * JavaScriptCore.exp: + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def: + * JavaScriptCore.xcodeproj/project.pbxproj: + * bytecode/CodeBlock.cpp: + (JSC::constantName): + (JSC::idName): + (JSC::CodeBlock::registerName): + (JSC::regexpName): + * bytecode/EvalCodeCache.h: + (JSC::EvalCodeCache::get): + * bytecompiler/NodesCodegen.cpp: + (JSC::ResolveNode::emitBytecode): + (JSC::FunctionCallResolveNode::emitBytecode): + (JSC::ReadModifyResolveNode::emitBytecode): + (JSC::processClauseList): + * parser/ASTBuilder.h: + (JSC::ASTBuilder::createRegex): + * parser/ParserArena.h: + (JSC::IdentifierArena::makeNumericIdentifier): + * parser/SourceProvider.h: + (JSC::UStringSourceProvider::data): + (JSC::UStringSourceProvider::length): + * profiler/Profiler.cpp: + * runtime/Arguments.cpp: + (JSC::Arguments::getOwnPropertySlot): + (JSC::Arguments::getOwnPropertyNames): + (JSC::Arguments::put): + (JSC::Arguments::deleteProperty): + * runtime/ArrayPrototype.cpp: + (JSC::arrayProtoFuncToString): + * runtime/DatePrototype.cpp: + (JSC::formatLocaleDate): + * runtime/ExceptionHelpers.cpp: + * runtime/FunctionConstructor.cpp: + * runtime/FunctionPrototype.cpp: + (JSC::insertSemicolonIfNeeded): + * runtime/Identifier.h: + (JSC::Identifier::characters): + (JSC::Identifier::length): + * runtime/JSGlobalObjectFunctions.cpp: + (JSC::decode): + (JSC::parseInt): + (JSC::parseFloat): + (JSC::globalFuncEscape): + (JSC::globalFuncUnescape): + * runtime/JSNumberCell.cpp: + (JSC::JSNumberCell::toString): + * runtime/JSONObject.cpp: + (JSC::gap): + (JSC::Stringifier::appendQuotedString): + (JSC::Stringifier::appendStringifiedValue): + (JSC::Stringifier::indent): + (JSC::Stringifier::unindent): + (JSC::Walker::walk): + * runtime/JSString.cpp: + (JSC::JSString::replaceCharacter): + (JSC::JSString::getIndexSlowCase): + * runtime/JSString.h: + (JSC::RopeBuilder::JSString): + (JSC::RopeBuilder::appendValueInConstructAndIncrementLength): + (JSC::RopeBuilder::fiberCount): + (JSC::jsSingleCharacterSubstring): + (JSC::jsNontrivialString): + (JSC::JSString::getIndex): + (JSC::jsString): + (JSC::jsStringWithFinalizer): + (JSC::jsSubstring): + (JSC::jsOwnedString): + * runtime/JSStringBuilder.h: + (JSC::JSStringBuilder::append): + * runtime/LiteralParser.h: + (JSC::LiteralParser::Lexer::Lexer): + * runtime/NumberPrototype.cpp: + (JSC::numberProtoFuncToString): + (JSC::numberProtoFuncToFixed): + (JSC::numberProtoFuncToExponential): + (JSC::numberProtoFuncToPrecision): + * runtime/NumericStrings.h: + (JSC::NumericStrings::add): + (JSC::NumericStrings::lookupSmallString): + * runtime/Operations.h: + (JSC::jsString): + * runtime/RegExp.cpp: + (JSC::RegExp::match): + * runtime/RegExpCache.cpp: + (JSC::RegExpCache::lookupOrCreate): + (JSC::RegExpCache::create): + * runtime/RegExpConstructor.cpp: + (JSC::RegExpConstructor::getRightContext): + * runtime/RegExpObject.cpp: + (JSC::RegExpObject::match): + * runtime/RegExpPrototype.cpp: + (JSC::regExpProtoFuncToString): + * runtime/StringBuilder.h: + (JSC::StringBuilder::append): + * runtime/StringConcatenate.h: Copied from JavaScriptCore/runtime/UString.h. + (JSC::): + (JSC::sumWithOverflow): + (JSC::tryMakeString): + (JSC::makeString): + * runtime/StringObject.cpp: + (JSC::StringObject::getOwnPropertyNames): + * runtime/StringPrototype.cpp: + (JSC::substituteBackreferencesSlow): + (JSC::localeCompare): + (JSC::jsSpliceSubstringsWithSeparators): + (JSC::stringProtoFuncReplace): + (JSC::stringProtoFuncCharAt): + (JSC::stringProtoFuncCharCodeAt): + (JSC::stringProtoFuncIndexOf): + (JSC::stringProtoFuncLastIndexOf): + (JSC::stringProtoFuncSlice): + (JSC::stringProtoFuncSplit): + (JSC::stringProtoFuncSubstr): + (JSC::stringProtoFuncSubstring): + (JSC::stringProtoFuncToLowerCase): + (JSC::stringProtoFuncToUpperCase): + (JSC::stringProtoFuncFontsize): + (JSC::stringProtoFuncLink): + (JSC::trimString): + * runtime/UString.cpp: + (JSC::UString::number): + (JSC::UString::ascii): + (JSC::UString::operator[]): + (JSC::UString::toDouble): + (JSC::UString::find): + (JSC::UString::rfind): + (JSC::UString::substr): + (JSC::operator==): + (JSC::operator<): + (JSC::operator>): + (JSC::UString::UTF8String): + * runtime/UString.h: + (JSC::UString::UString): + (JSC::UString::adopt): + (JSC::UString::length): + (JSC::UString::characters): + (JSC::UString::isNull): + (JSC::UString::isEmpty): + (JSC::UString::impl): + (JSC::UString::cost): + (JSC::operator==): + (JSC::operator!=): + (JSC::codePointCompare): + (JSC::UString::toArrayIndex): + (JSC::IdentifierRepHash::hash): + (WTF::): + * yarr/RegexJIT.cpp: + (JSC::Yarr::jitCompileRegex): + * yarr/RegexParser.h: + (JSC::Yarr::Parser::Parser): + +2010-08-11 Gabor Loki <loki@webkit.org> + + Qt build fix (ARMv7). + + Fix invalid conversion from int to Condition. + Add ARMv7Assembler.cpp to JavaScriptCore.pro. + + * JavaScriptCore.pro: + * assembler/ARMv7Assembler.h: + (JSC::ARMv7Assembler::): + (JSC::ARMv7Assembler::JmpSrc::JmpSrc): + +2010-08-11 Nathan Lawrence <nlawrence@apple.com> + + Reviewed by Geoffrey Garen. + + At collection time, we frequently want to mark a cell, while checking + whether it was originally checked. Previously, this was a get + operation follwed by a set operation. Fusing the two saves + computation and gives a 0.5% sunspider speedup. + + * runtime/Collector.h: + (JSC::CollectorBitmap::getset): + (JSC::Heap::checkMarkCell): + * runtime/JSArray.h: + (JSC::MarkStack::drain): + * runtime/JSCell.h: + (JSC::MarkStack::append): + +2010-08-11 Steve Falkenburg <sfalken@apple.com> + + Reviewed by Adam Roben. + + Improve vsprops copying for Windows build + https://bugs.webkit.org/show_bug.cgi?id=41982 + + When we detect a new SDK, always copy a new set of vsprops files. + Previously, if someone updated their SDK after updating their sources, + they could end up with out-of-date vsprops files. + + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreGenerated.make: + +2010-08-10 Darin Adler <darin@apple.com> + + Reviewed by Sam Weinig. + + Add leakRef and clear to all RefPtr variants + https://bugs.webkit.org/show_bug.cgi?id=42389 + + * API/JSRetainPtr.h: Changed all uses of "template <...>" to instead do + "template<...>". We should probably put this in the style guide and do it + consitently. Fixed other minor style issues. Defined many of the inlined + functions outside the class definition, to avoid style checker warnings + about multiple statements on a single line and for slightly better clarity + of the class definition itself. Renamed releaseRef to leakRef. Added a + releaseRef that calls leakRef so we don't have to rename all callers oat + once. Added a clear function. + + * wtf/PassRefPtr.h: Changed all uses of releaseRef to leakRef. + + * wtf/RefPtr.h: Changed all uses of "template <...>" to instead do + "template<...>". Tidied up declarations and comments a bit. + Changed all uses of releaseRef to leakRef. + + * wtf/RetainPtr.h: Changed all uses of "template <...>" to instead do + "template<...>". Defined many of the inlined functions outside the class + definition, to avoid style checker warnings about multiple statements on + a single line and for slightly better clarity of the class definition itself. + Renamed releaseRef to leakRef. Added a releaseRef that calls leakRef so we + don't have to rename all callers at once. Added a clear function. + +2010-08-10 Dumitru Daniliuc <dumi@chromium.org> + + Unreviewed, reverting an unintentional change to a file submitted in r65108. + + * bytecode/CodeBlock.h: + (JSC::binaryChop): + +2010-08-10 Gavin Barraclough <barraclough@apple.com> + + Rubber stamped by Sam Weinig + + Bug 43817 - Remove UString::Rep + UString::Rep has for a long time been replaced by UStringImpl (Rep + remaining as a typedef). UStringImpl has since been removed too + (unified with StringImpl). Remove Rep, rename rep() to impl() and + m_rep to m_impl. Also add impl() method to Identifier, and rename + its UString member from _ustring to m_string. + + * API/JSCallbackObject.h: + (JSC::JSCallbackObjectData::JSPrivatePropertyMap::getPrivateProperty): + (JSC::JSCallbackObjectData::JSPrivatePropertyMap::setPrivateProperty): + (JSC::JSCallbackObjectData::JSPrivatePropertyMap::deletePrivateProperty): + * API/JSCallbackObjectFunctions.h: + (JSC::::getOwnPropertySlot): + (JSC::::put): + (JSC::::deleteProperty): + (JSC::::getOwnPropertyNames): + (JSC::::staticValueGetter): + (JSC::::staticFunctionGetter): + * API/JSClassRef.cpp: + (tryCreateStringFromUTF8): + (OpaqueJSClass::OpaqueJSClass): + (OpaqueJSClass::~OpaqueJSClass): + (OpaqueJSClassContextData::OpaqueJSClassContextData): + * API/JSClassRef.h: + * API/OpaqueJSString.cpp: + (OpaqueJSString::ustring): + * bytecode/EvalCodeCache.h: + (JSC::EvalCodeCache::get): + * bytecode/JumpTable.h: + (JSC::StringJumpTable::offsetForValue): + (JSC::StringJumpTable::ctiForValue): + * bytecompiler/BytecodeGenerator.cpp: + (JSC::BytecodeGenerator::addVar): + (JSC::BytecodeGenerator::addGlobalVar): + (JSC::BytecodeGenerator::BytecodeGenerator): + (JSC::BytecodeGenerator::addParameter): + (JSC::BytecodeGenerator::registerFor): + (JSC::BytecodeGenerator::willResolveToArguments): + (JSC::BytecodeGenerator::uncheckedRegisterForArguments): + (JSC::BytecodeGenerator::constRegisterFor): + (JSC::BytecodeGenerator::isLocal): + (JSC::BytecodeGenerator::isLocalConstant): + (JSC::BytecodeGenerator::addConstant): + (JSC::BytecodeGenerator::emitLoad): + (JSC::BytecodeGenerator::findScopedProperty): + (JSC::keyForCharacterSwitch): + (JSC::prepareJumpTableForStringSwitch): + * bytecompiler/BytecodeGenerator.h: + * bytecompiler/NodesCodegen.cpp: + (JSC::processClauseList): + * interpreter/Interpreter.cpp: + (JSC::Interpreter::privateExecute): + * jit/JITStubs.cpp: + (JSC::DEFINE_STUB_FUNCTION): + * parser/JSParser.cpp: + (JSC::JSParser::parseStrictObjectLiteral): + * pcre/pcre_exec.cpp: + (Histogram::add): + * profiler/CallIdentifier.h: + (JSC::CallIdentifier::Hash::hash): + * profiler/Profile.cpp: + * profiler/ProfileNode.cpp: + (JSC::ProfileNode::debugPrintDataSampleStyle): + * profiler/ProfileNode.h: + * runtime/ArrayPrototype.cpp: + (JSC::arrayProtoFuncToString): + * runtime/Identifier.cpp: + (JSC::Identifier::equal): + (JSC::IdentifierCStringTranslator::hash): + (JSC::IdentifierCStringTranslator::equal): + (JSC::IdentifierCStringTranslator::translate): + (JSC::Identifier::add): + (JSC::IdentifierUCharBufferTranslator::hash): + (JSC::IdentifierUCharBufferTranslator::equal): + (JSC::IdentifierUCharBufferTranslator::translate): + (JSC::Identifier::addSlowCase): + * runtime/Identifier.h: + (JSC::Identifier::Identifier): + (JSC::Identifier::ustring): + (JSC::Identifier::impl): + (JSC::Identifier::data): + (JSC::Identifier::size): + (JSC::Identifier::ascii): + (JSC::Identifier::isNull): + (JSC::Identifier::isEmpty): + (JSC::Identifier::toUInt32): + (JSC::Identifier::toStrictUInt32): + (JSC::Identifier::toArrayIndex): + (JSC::Identifier::toDouble): + (JSC::Identifier::equal): + (JSC::Identifier::add): + * runtime/InitializeThreading.cpp: + (JSC::initializeThreadingOnce): + * runtime/InternalFunction.cpp: + (JSC::InternalFunction::displayName): + * runtime/JSFunction.cpp: + (JSC::JSFunction::displayName): + * runtime/JSGlobalObject.h: + (JSC::JSGlobalObject::addStaticGlobals): + * runtime/JSStaticScopeObject.h: + (JSC::JSStaticScopeObject::JSStaticScopeObject): + * runtime/JSString.h: + (JSC::): + (JSC::RopeBuilder::appendStringInConstruct): + (JSC::RopeBuilder::appendValueInConstructAndIncrementLength): + (JSC::jsSingleCharacterSubstring): + (JSC::jsSubstring): + * runtime/JSVariableObject.cpp: + (JSC::JSVariableObject::deleteProperty): + (JSC::JSVariableObject::symbolTableGet): + * runtime/JSVariableObject.h: + (JSC::JSVariableObject::symbolTableGet): + (JSC::JSVariableObject::symbolTablePut): + (JSC::JSVariableObject::symbolTablePutWithAttributes): + * runtime/Lookup.cpp: + (JSC::HashTable::createTable): + (JSC::HashTable::deleteTable): + * runtime/Lookup.h: + (JSC::HashEntry::initialize): + (JSC::HashEntry::setKey): + (JSC::HashEntry::key): + (JSC::HashTable::entry): + * runtime/PropertyMapHashTable.h: + (JSC::PropertyMapEntry::PropertyMapEntry): + * runtime/PropertyNameArray.cpp: + (JSC::PropertyNameArray::add): + * runtime/PropertyNameArray.h: + (JSC::PropertyNameArray::add): + (JSC::PropertyNameArray::addKnownUnique): + * runtime/RegExp.cpp: + (JSC::RegExp::match): + * runtime/RegExpCache.cpp: + (JSC::RegExpCache::create): + * runtime/RegExpKey.h: + (JSC::RegExpKey::RegExpKey): + * runtime/SmallStrings.cpp: + (JSC::SmallStringsStorage::rep): + (JSC::SmallStrings::singleCharacterStringRep): + * runtime/SmallStrings.h: + * runtime/StringPrototype.cpp: + (JSC::jsSpliceSubstringsWithSeparators): + (JSC::stringProtoFuncMatch): + (JSC::stringProtoFuncSearch): + * runtime/Structure.cpp: + (JSC::Structure::~Structure): + (JSC::Structure::despecifyDictionaryFunction): + (JSC::Structure::addPropertyTransitionToExistingStructure): + (JSC::Structure::addPropertyTransition): + (JSC::Structure::copyPropertyTable): + (JSC::Structure::get): + (JSC::Structure::despecifyFunction): + (JSC::Structure::put): + (JSC::Structure::hasTransition): + (JSC::Structure::remove): + (JSC::Structure::checkConsistency): + * runtime/Structure.h: + (JSC::Structure::get): + (JSC::Structure::hasTransition): + * runtime/StructureTransitionTable.h: + * runtime/SymbolTable.h: + * runtime/UString.cpp: + (JSC::UString::UString): + (JSC::UString::toStrictUInt32): + (JSC::UString::substr): + * runtime/UString.h: + (JSC::UString::UString): + (JSC::UString::adopt): + (JSC::UString::data): + (JSC::UString::size): + (JSC::UString::isNull): + (JSC::UString::isEmpty): + (JSC::UString::impl): + (JSC::UString::cost): + (JSC::operator==): + (JSC::codePointCompare): + (JSC::IdentifierRepHash::hash): + (WTF::): + +2010-08-10 Gavin Barraclough <barraclough@apple.com> + + Bug 43816 - Remove UStringImpl + The class was actually removed a long time ago, replaced by StringImpl. + UStringImpl is just a typedef onto StringImpl. Remove this. + + * API/JSClassRef.cpp: + (OpaqueJSClass::OpaqueJSClass): + * JavaScriptCore.xcodeproj/project.pbxproj: + * runtime/JSString.cpp: + (JSC::JSString::resolveRope): + (JSC::JSString::replaceCharacter): + * runtime/JSString.h: + (JSC::RopeBuilder::RopeIterator::operator*): + (JSC::RopeBuilder::JSString): + (JSC::RopeBuilder::appendStringInConstruct): + (JSC::RopeBuilder::appendValueInConstructAndIncrementLength): + (JSC::jsSingleCharacterSubstring): + (JSC::jsSubstring): + * runtime/JSStringBuilder.h: + (JSC::jsMakeNontrivialString): + * runtime/RopeImpl.cpp: + (JSC::RopeImpl::derefFibersNonRecursive): + * runtime/RopeImpl.h: + (JSC::RopeImpl::deref): + * runtime/SmallStrings.cpp: + (JSC::SmallStringsStorage::SmallStringsStorage): + * runtime/StringConstructor.cpp: + (JSC::stringFromCharCodeSlowCase): + * runtime/StringPrototype.cpp: + (JSC::jsSpliceSubstringsWithSeparators): + (JSC::stringProtoFuncFontsize): + (JSC::stringProtoFuncLink): + * runtime/UString.cpp: + (JSC::initializeUString): + * runtime/UString.h: + (JSC::UString::adopt): + (JSC::tryMakeString): + (JSC::makeString): + * runtime/UStringImpl.h: Removed. + +2010-08-10 Patrick Gansterer <paroga@paroga.com> + + Reviewed by Eric Seidel. + + Make FastMalloc more portable. + https://bugs.webkit.org/show_bug.cgi?id=41790 + + * wtf/FastMalloc.cpp: + (WTF::TCMalloc_Central_FreeList::Populate): + (WTF::TCMalloc_ThreadCache::CreateCacheIfNecessary): + +2010-08-10 Patrick Gansterer <paroga@paroga.com> + + Reviewed by David Levin. + + [WINCE] Buildfix for CE 6.0 + https://bugs.webkit.org/show_bug.cgi?id=43027 + + CE 6.0 doesn't define localtime in the system include files. + + * wtf/Platform.h: Include ce_time.h on all OS(WINCE). + +2010-08-10 Gavin Barraclough <barraclough@apple.com> + + Rubber stamped by Sam Weinig. + + Bug 43786 - Move AtomicStringHash from WebCore to WTF + Also remove deprecated string headers from WebCore/platform/text. + + * GNUmakefile.am: + * JavaScriptCore.gypi: + * JavaScriptCore.vcproj/WTF/WTF.vcproj: + * JavaScriptCore.xcodeproj/project.pbxproj: + * wtf/text/AtomicString.h: + * wtf/text/AtomicStringHash.h: Copied from WebCore/platform/text/AtomicStringHash.h. + 2010-08-09 Oliver Hunt <oliver@apple.com> Fix Qt/ARM again, this time including the other changed file. diff --git a/JavaScriptCore/GNUmakefile.am b/JavaScriptCore/GNUmakefile.am index 2ead8e0..fae85e1 100644 --- a/JavaScriptCore/GNUmakefile.am +++ b/JavaScriptCore/GNUmakefile.am @@ -491,6 +491,7 @@ javascriptcore_sources += \ JavaScriptCore/wtf/TCSystemAlloc.h \ JavaScriptCore/wtf/text/AtomicString.cpp \ JavaScriptCore/wtf/text/AtomicString.h \ + JavaScriptCore/wtf/text/AtomicStringHash.h \ JavaScriptCore/wtf/text/AtomicStringImpl.h \ JavaScriptCore/wtf/text/CString.cpp \ JavaScriptCore/wtf/text/CString.h \ diff --git a/JavaScriptCore/JavaScriptCore.exp b/JavaScriptCore/JavaScriptCore.exp index 241ed5c..5cfa1c2 100644 --- a/JavaScriptCore/JavaScriptCore.exp +++ b/JavaScriptCore/JavaScriptCore.exp @@ -107,6 +107,7 @@ __ZN3JSC10Identifier3addEPNS_9ExecStateEPKc __ZN3JSC10Identifier4fromEPNS_9ExecStateEi __ZN3JSC10Identifier4fromEPNS_9ExecStateEj __ZN3JSC10Identifier5equalEPKN3WTF10StringImplEPKc +__ZN3JSC10Identifier8toUInt32ERKNS_7UStringERb __ZN3JSC10JSFunction4infoE __ZN3JSC10JSFunction4nameEPNS_9ExecStateE __ZN3JSC10throwErrorEPNS_9ExecStateENS_7JSValueE @@ -251,11 +252,13 @@ __ZN3JSC7Profile10restoreAllEv __ZN3JSC7Profile5focusEPKNS_11ProfileNodeE __ZN3JSC7Profile7excludeEPKNS_11ProfileNodeE __ZN3JSC7Profile7forEachEMNS_11ProfileNodeEFvvE -__ZN3JSC7UString4fromEd -__ZN3JSC7UString4fromEi -__ZN3JSC7UString4fromEj -__ZN3JSC7UString4fromEl +__ZN3JSC7UString6numberEd +__ZN3JSC7UString6numberEi +__ZN3JSC7UString6numberEj +__ZN3JSC7UString6numberEl __ZN3JSC7UStringC1EPKc +__ZN3JSC7UStringC1EPKcj +__ZN3JSC7UStringC1EPKt __ZN3JSC7UStringC1EPKtj __ZN3JSC8Debugger23recompileAllJSFunctionsEPNS_12JSGlobalDataE __ZN3JSC8Debugger6attachEPNS_14JSGlobalObjectE @@ -317,21 +320,23 @@ __ZN3JSC9constructEPNS_9ExecStateENS_7JSValueENS_13ConstructTypeERKNS_13Construc __ZN3JSCeqERKNS_7UStringEPKc __ZN3JSCgtERKNS_7UStringES2_ __ZN3JSCltERKNS_7UStringES2_ -__ZN3WTF10StringImpl11reverseFindEPS0_ib -__ZN3WTF10StringImpl11reverseFindEti +__ZN3WTF10StringImpl11reverseFindEPS0_j +__ZN3WTF10StringImpl11reverseFindEtj __ZN3WTF10StringImpl12sharedBufferEv +__ZN3WTF10StringImpl16findIgnoringCaseEPKcj +__ZN3WTF10StringImpl16findIgnoringCaseEPS0_j __ZN3WTF10StringImpl18simplifyWhiteSpaceEv __ZN3WTF10StringImpl19characterStartingAtEj __ZN3WTF10StringImpl19createUninitializedEjRPt __ZN3WTF10StringImpl22containsOnlyWhitespaceEv __ZN3WTF10StringImpl23defaultWritingDirectionEv +__ZN3WTF10StringImpl23reverseFindIgnoringCaseEPS0_j __ZN3WTF10StringImpl37createStrippingNullCharactersSlowCaseEPKtj -__ZN3WTF10StringImpl4findEPFbtEi -__ZN3WTF10StringImpl4findEPKcib -__ZN3WTF10StringImpl4findEPS0_ib -__ZN3WTF10StringImpl4findEti +__ZN3WTF10StringImpl4findEPFbtEj +__ZN3WTF10StringImpl4findEPKcj +__ZN3WTF10StringImpl4findEPS0_j +__ZN3WTF10StringImpl4findEtj __ZN3WTF10StringImpl5adoptERNS_12StringBufferE -__ZN3WTF10StringImpl5asciiEv __ZN3WTF10StringImpl5emptyEv __ZN3WTF10StringImpl5lowerEv __ZN3WTF10StringImpl5toIntEPb @@ -442,7 +447,10 @@ __ZN3WTF6String6removeEji __ZN3WTF6String8fromUTF8EPKc __ZN3WTF6String8fromUTF8EPKcm __ZN3WTF6String8truncateEj +__ZN3WTF6StringC1EPKc +__ZN3WTF6StringC1EPKcj __ZN3WTF6StringC1EPKt +__ZN3WTF6StringC1EPKtj __ZN3WTF6strtodEPKcPPc __ZN3WTF7CString11mutableDataEv __ZN3WTF7CString16newUninitializedEmRPc @@ -508,13 +516,9 @@ __ZNK3JSC7JSValue16toObjectSlowCaseEPNS_9ExecStateE __ZNK3JSC7JSValue19synthesizePrototypeEPNS_9ExecStateE __ZNK3JSC7JSValue20toThisObjectSlowCaseEPNS_9ExecStateE __ZNK3JSC7JSValue9toIntegerEPNS_9ExecStateE -__ZNK3JSC7UString10UTF8StringEb -__ZNK3JSC7UString14toStrictUInt32EPb +__ZNK3JSC7UString20substringSharingImplEjj +__ZNK3JSC7UString4utf8Eb __ZNK3JSC7UString5asciiEv -__ZNK3JSC7UString6is8BitEv -__ZNK3JSC7UString6substrEjj -__ZNK3JSC7UString8toUInt32EPb -__ZNK3JSC7UString8toUInt32EPbb __ZNK3JSC8JSObject11hasPropertyEPNS_9ExecStateERKNS_10IdentifierE __ZNK3JSC8JSObject11hasPropertyEPNS_9ExecStateEj __ZNK3JSC8JSObject12defaultValueEPNS_9ExecStateENS_22PreferredPrimitiveTypeE @@ -536,7 +540,7 @@ __ZNK3WTF6String16removeCharactersEPFbtE __ZNK3WTF6String17crossThreadStringEv __ZNK3WTF6String18simplifyWhiteSpaceEv __ZNK3WTF6String19characterStartingAtEj -__ZNK3WTF6String4utf8Ev +__ZNK3WTF6String4utf8Eb __ZNK3WTF6String5asciiEv __ZNK3WTF6String5lowerEv __ZNK3WTF6String5splitERKS0_bRNS_6VectorIS0_Lm0EEE diff --git a/JavaScriptCore/JavaScriptCore.gypi b/JavaScriptCore/JavaScriptCore.gypi index a85d11c..12614d0 100644 --- a/JavaScriptCore/JavaScriptCore.gypi +++ b/JavaScriptCore/JavaScriptCore.gypi @@ -445,6 +445,7 @@ 'wtf/TypeTraits.h', 'wtf/text/AtomicString.cpp', 'wtf/text/AtomicString.h', + 'wtf/text/AtomicStringHash.h', 'wtf/text/AtomicStringImpl.h', 'wtf/text/CString.cpp', 'wtf/text/CString.h', diff --git a/JavaScriptCore/JavaScriptCore.pro b/JavaScriptCore/JavaScriptCore.pro index d6c4420..7f6b27d 100644 --- a/JavaScriptCore/JavaScriptCore.pro +++ b/JavaScriptCore/JavaScriptCore.pro @@ -79,6 +79,7 @@ SOURCES += \ API/JSValueRef.cpp \ API/OpaqueJSString.cpp \ assembler/ARMAssembler.cpp \ + assembler/ARMv7Assembler.cpp \ assembler/MacroAssemblerARM.cpp \ bytecode/CodeBlock.cpp \ bytecode/JumpTable.cpp \ diff --git a/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def b/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def index 90fd3ad..934688f 100644 --- a/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def +++ b/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def @@ -38,7 +38,7 @@ EXPORTS ??8JSC@@YA_NABVUString@0@0@Z ??8WTF@@YA_NABVCString@0@0@Z ?NaN@JSC@@3NB - ?UTF8String@UString@JSC@@QBE?AVCString@WTF@@_N@Z + ?utf8@UString@JSC@@QBE?AVCString@WTF@@_N@Z ?add@Identifier@JSC@@SA?AV?$PassRefPtr@VStringImpl@WTF@@@WTF@@PAVExecState@2@PBD@Z ?add@PropertyNameArray@JSC@@QAEXPAVStringImpl@WTF@@@Z ?addBytes@MD5@WTF@@QAEXPBEI@Z @@ -50,7 +50,7 @@ EXPORTS ?allocate@Heap@JSC@@QAEPAXI@Z ?allocatePropertyStorage@JSObject@JSC@@QAEXII@Z ?allocateStack@MarkStack@JSC@@CAPAXI@Z - ?ascii@UString@JSC@@QBEPADXZ + ?ascii@UString@JSC@@QBE?AVCString@WTF@@XZ ?attach@Debugger@JSC@@QAEXPAVJSGlobalObject@2@@Z ?broadcast@ThreadCondition@WTF@@QAEXXZ ?calculatedFunctionName@DebuggerCallFrame@JSC@@QBE?AVUString@2@XZ @@ -146,9 +146,9 @@ EXPORTS ?free@WeakGCHandlePool@JSC@@QAEXPAVWeakGCHandle@2@@Z ?from@Identifier@JSC@@SA?AV12@PAVExecState@2@H@Z ?from@Identifier@JSC@@SA?AV12@PAVExecState@2@I@Z - ?from@UString@JSC@@SA?AV12@H@Z - ?from@UString@JSC@@SA?AV12@I@Z - ?from@UString@JSC@@SA?AV12@N@Z + ?number@UString@JSC@@SA?AV12@H@Z + ?number@UString@JSC@@SA?AV12@I@Z + ?number@UString@JSC@@SA?AV12@N@Z ?functionGetter@PropertySlot@JSC@@ABE?AVJSValue@2@PAVExecState@2@@Z ?functionName@DebuggerCallFrame@JSC@@QBEPBVUString@2@XZ ?get@Structure@JSC@@QAEIPBVStringImpl@WTF@@AAIAAPAVJSCell@2@@Z @@ -193,7 +193,6 @@ EXPORTS ?initializeMainThread@WTF@@YAXXZ ?initializeThreading@JSC@@YAXXZ ?initializeThreading@WTF@@YAXXZ - ?is8Bit@UString@JSC@@QBE_NXZ ?isAccessorDescriptor@PropertyDescriptor@JSC@@QBE_NXZ ?isBusy@Heap@JSC@@QAE_NXZ ?isDataDescriptor@PropertyDescriptor@JSC@@QBE_NXZ @@ -286,7 +285,7 @@ EXPORTS ?stopProfiling@Profiler@JSC@@QAE?AV?$PassRefPtr@VProfile@JSC@@@WTF@@PAVExecState@2@ABVUString@2@@Z ?stopSampling@JSGlobalData@JSC@@QAEXXZ ?strtod@WTF@@YANPBDPAPAD@Z - ?substr@UString@JSC@@QBE?AV12@II@Z + ?substringSharingImpl@UString@JSC@@QBE?AV12@II@Z ?symbolTableGet@JSVariableObject@JSC@@IAE_NABVIdentifier@2@AAVPropertyDescriptor@2@@Z ?synthesizePrototype@JSValue@JSC@@ABEPAVJSObject@2@PAVExecState@2@@Z ?thisObject@DebuggerCallFrame@JSC@@QBEPAVJSObject@2@XZ @@ -311,7 +310,6 @@ EXPORTS ?toObjectSlowCase@JSValue@JSC@@ABEPAVJSObject@2@PAVExecState@2@@Z ?toPrimitive@JSCell@JSC@@UBE?AVJSValue@2@PAVExecState@2@W4PreferredPrimitiveType@2@@Z ?toPrimitive@JSString@JSC@@EBE?AVJSValue@2@PAVExecState@2@W4PreferredPrimitiveType@2@@Z - ?toStrictUInt32@UString@JSC@@QBEIPA_N@Z ?toString@JSCell@JSC@@UBE?AVUString@2@PAVExecState@2@@Z ?toString@JSObject@JSC@@UBE?AVUString@2@PAVExecState@2@@Z ?toString@JSString@JSC@@EBE?AVUString@2@PAVExecState@2@@Z @@ -319,8 +317,7 @@ EXPORTS ?toThisObject@JSObject@JSC@@UBEPAV12@PAVExecState@2@@Z ?toThisObject@JSString@JSC@@EBEPAVJSObject@2@PAVExecState@2@@Z ?toThisObjectSlowCase@JSValue@JSC@@ABEPAVJSObject@2@PAVExecState@2@@Z - ?toUInt32@UString@JSC@@QBEIPA_N@Z - ?toUInt32@UString@JSC@@QBEIPA_N_N@Z + ?toUInt32@Identifier@JSC@@SAIABVUString@2@AA_N@Z ?toUInt32SlowCase@JSC@@YAINAA_N@Z ?tryFastCalloc@WTF@@YA?AUTryMallocReturnValue@1@II@Z ?tryFastMalloc@WTF@@YA?AUTryMallocReturnValue@1@I@Z diff --git a/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreGenerated.make b/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreGenerated.make index 098ff08..a9493a3 100644 --- a/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreGenerated.make +++ b/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreGenerated.make @@ -1,4 +1,5 @@ all: + -if not exist "$(WEBKITLIBRARIESDIR)\tools\vsprops\.svn" del /s/q "$(WEBKITLIBRARIESDIR)\tools\vsprops\" -xcopy /y/d/e/i "..\..\..\WebKitLibraries\win\tools" "$(WEBKITLIBRARIESDIR)\tools" touch "$(WEBKITOUTPUTDIR)\buildfailed" bash build-generated-files.sh "$(WEBKITOUTPUTDIR)" "$(WEBKITLIBRARIESDIR)" diff --git a/JavaScriptCore/JavaScriptCore.vcproj/WTF/WTF.vcproj b/JavaScriptCore/JavaScriptCore.vcproj/WTF/WTF.vcproj index 9d551d0..aedc122 100644 --- a/JavaScriptCore/JavaScriptCore.vcproj/WTF/WTF.vcproj +++ b/JavaScriptCore/JavaScriptCore.vcproj/WTF/WTF.vcproj @@ -577,6 +577,10 @@ >
</File>
<File
+ RelativePath="..\..\wtf\text\AtomicStringHash.h"
+ >
+ </File>
+ <File
RelativePath="..\..\wtf\text\AtomicStringImpl.h"
>
</File>
diff --git a/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj b/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj index de3afaa..511a7a0 100644 --- a/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj +++ b/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj @@ -216,12 +216,12 @@ 868BFA60117D048200B908B1 /* StaticConstructors.h in Headers */ = {isa = PBXBuildFile; fileRef = 868BFA5F117D048200B908B1 /* StaticConstructors.h */; settings = {ATTRIBUTES = (Private, ); }; }; 8690231512092D5C00630AF9 /* PageReservation.h in Headers */ = {isa = PBXBuildFile; fileRef = 8690231412092D5C00630AF9 /* PageReservation.h */; settings = {ATTRIBUTES = (Private, ); }; }; 8698B86910D44D9400D8D01B /* StringBuilder.h in Headers */ = {isa = PBXBuildFile; fileRef = 8698B86810D44D9400D8D01B /* StringBuilder.h */; settings = {ATTRIBUTES = (Private, ); }; }; - 8698BB3910D86BAF00D8D01B /* UStringImpl.h in Headers */ = {isa = PBXBuildFile; fileRef = 8698BB3710D86BAF00D8D01B /* UStringImpl.h */; settings = {ATTRIBUTES = (Private, ); }; }; 869D04AF1193B54D00803475 /* CachedTranscendentalFunction.h in Headers */ = {isa = PBXBuildFile; fileRef = 869D04AE1193B54D00803475 /* CachedTranscendentalFunction.h */; settings = {ATTRIBUTES = (Private, ); }; }; 869EBCB70E8C6D4A008722CC /* ResultType.h in Headers */ = {isa = PBXBuildFile; fileRef = 869EBCB60E8C6D4A008722CC /* ResultType.h */; settings = {ATTRIBUTES = (Private, ); }; }; 86A90ED00EE7D51F00AB350D /* JITArithmetic.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 86A90ECF0EE7D51F00AB350D /* JITArithmetic.cpp */; }; 86ADD1450FDDEA980006EEC2 /* ARMv7Assembler.h in Headers */ = {isa = PBXBuildFile; fileRef = 86ADD1430FDDEA980006EEC2 /* ARMv7Assembler.h */; }; 86ADD1460FDDEA980006EEC2 /* MacroAssemblerARMv7.h in Headers */ = {isa = PBXBuildFile; fileRef = 86ADD1440FDDEA980006EEC2 /* MacroAssemblerARMv7.h */; }; + 86B6DA0212132B9A000D316F /* StringConcatenate.h in Headers */ = {isa = PBXBuildFile; fileRef = 86B6DA0112132B9A000D316F /* StringConcatenate.h */; }; 86B99AB8117E391E00DF5A90 /* RopeImpl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 86B99AB6117E391E00DF5A90 /* RopeImpl.cpp */; }; 86B99AB9117E391E00DF5A90 /* RopeImpl.h in Headers */ = {isa = PBXBuildFile; fileRef = 86B99AB7117E391E00DF5A90 /* RopeImpl.h */; settings = {ATTRIBUTES = (Private, ); }; }; 86B99AE3117E578100DF5A90 /* StringBuffer.h in Headers */ = {isa = PBXBuildFile; fileRef = 86B99AE1117E578100DF5A90 /* StringBuffer.h */; settings = {ATTRIBUTES = (Private, ); }; }; @@ -255,6 +255,7 @@ 86EAC49A0F93E8D1008EC948 /* RegexJIT.h in Headers */ = {isa = PBXBuildFile; fileRef = 86EAC4920F93E8D1008EC948 /* RegexJIT.h */; }; 86EAC49B0F93E8D1008EC948 /* RegexParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 86EAC4930F93E8D1008EC948 /* RegexParser.h */; }; 86EAC49C0F93E8D1008EC948 /* RegexPattern.h in Headers */ = {isa = PBXBuildFile; fileRef = 86EAC4940F93E8D1008EC948 /* RegexPattern.h */; }; + 86F38859121130CA007A7CE3 /* AtomicStringHash.h in Headers */ = {isa = PBXBuildFile; fileRef = 86F38858121130CA007A7CE3 /* AtomicStringHash.h */; settings = {ATTRIBUTES = (Private, ); }; }; 905B02AE0E28640F006DF882 /* RefCountedLeakCounter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 905B02AD0E28640F006DF882 /* RefCountedLeakCounter.cpp */; }; 90D3469C0E285280009492EE /* RefCountedLeakCounter.h in Headers */ = {isa = PBXBuildFile; fileRef = 90D3469B0E285280009492EE /* RefCountedLeakCounter.h */; settings = {ATTRIBUTES = (Private, ); }; }; 93052C340FB792190048FDC3 /* ParserArena.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 93052C320FB792190048FDC3 /* ParserArena.cpp */; }; @@ -803,12 +804,12 @@ 868BFA5F117D048200B908B1 /* StaticConstructors.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StaticConstructors.h; sourceTree = "<group>"; }; 8690231412092D5C00630AF9 /* PageReservation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PageReservation.h; sourceTree = "<group>"; }; 8698B86810D44D9400D8D01B /* StringBuilder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StringBuilder.h; sourceTree = "<group>"; }; - 8698BB3710D86BAF00D8D01B /* UStringImpl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UStringImpl.h; sourceTree = "<group>"; }; 869D04AE1193B54D00803475 /* CachedTranscendentalFunction.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CachedTranscendentalFunction.h; sourceTree = "<group>"; }; 869EBCB60E8C6D4A008722CC /* ResultType.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ResultType.h; sourceTree = "<group>"; }; 86A90ECF0EE7D51F00AB350D /* JITArithmetic.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JITArithmetic.cpp; sourceTree = "<group>"; }; 86ADD1430FDDEA980006EEC2 /* ARMv7Assembler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ARMv7Assembler.h; sourceTree = "<group>"; }; 86ADD1440FDDEA980006EEC2 /* MacroAssemblerARMv7.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MacroAssemblerARMv7.h; sourceTree = "<group>"; }; + 86B6DA0112132B9A000D316F /* StringConcatenate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StringConcatenate.h; sourceTree = "<group>"; }; 86B99AB6117E391E00DF5A90 /* RopeImpl.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RopeImpl.cpp; sourceTree = "<group>"; }; 86B99AB7117E391E00DF5A90 /* RopeImpl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RopeImpl.h; sourceTree = "<group>"; }; 86B99AE1117E578100DF5A90 /* StringBuffer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = StringBuffer.h; path = text/StringBuffer.h; sourceTree = "<group>"; }; @@ -842,6 +843,7 @@ 86EAC4920F93E8D1008EC948 /* RegexJIT.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RegexJIT.h; path = yarr/RegexJIT.h; sourceTree = "<group>"; }; 86EAC4930F93E8D1008EC948 /* RegexParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RegexParser.h; path = yarr/RegexParser.h; sourceTree = "<group>"; }; 86EAC4940F93E8D1008EC948 /* RegexPattern.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RegexPattern.h; path = yarr/RegexPattern.h; sourceTree = "<group>"; }; + 86F38858121130CA007A7CE3 /* AtomicStringHash.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AtomicStringHash.h; path = text/AtomicStringHash.h; sourceTree = "<group>"; }; 905B02AD0E28640F006DF882 /* RefCountedLeakCounter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RefCountedLeakCounter.cpp; sourceTree = "<group>"; }; 90D3469B0E285280009492EE /* RefCountedLeakCounter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RefCountedLeakCounter.h; sourceTree = "<group>"; }; 9303F567099118FA00AD71B8 /* OwnPtr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OwnPtr.h; sourceTree = "<group>"; }; @@ -1751,6 +1753,7 @@ 93303FE80E6A72B500786E6A /* SmallStrings.cpp */, 93303FEA0E6A72C000786E6A /* SmallStrings.h */, 8698B86810D44D9400D8D01B /* StringBuilder.h */, + 86B6DA0112132B9A000D316F /* StringConcatenate.h */, BC18C3C00E16EE3300B34460 /* StringConstructor.cpp */, BC18C3C10E16EE3300B34460 /* StringConstructor.h */, BC18C3C20E16EE3300B34460 /* StringObject.cpp */, @@ -1771,7 +1774,6 @@ 5D53726E0E1C54880021E549 /* Tracing.h */, F692A8850255597D01FF60F7 /* UString.cpp */, F692A8860255597D01FF60F7 /* UString.h */, - 8698BB3710D86BAF00D8D01B /* UStringImpl.h */, 14BFCE6810CDB1FC00364CCE /* WeakGCMap.h */, 14035DB010DBFB2A00FFFFE7 /* WeakGCPtr.h */, 1420BE7A10AA6DDB00F455D2 /* WeakRandom.h */, @@ -1784,6 +1786,7 @@ children = ( 868BFA00117CEFD100B908B1 /* AtomicString.cpp */, 868BFA01117CEFD100B908B1 /* AtomicString.h */, + 86F38858121130CA007A7CE3 /* AtomicStringHash.h */, 868BFA02117CEFD100B908B1 /* AtomicStringImpl.h */, 86565740115BE3DA00291F40 /* CString.cpp */, 86565741115BE3DA00291F40 /* CString.h */, @@ -2213,7 +2216,6 @@ BC18C4740E16F5CD00B34460 /* UnicodeIcu.h in Headers */, BC18C4750E16F5CD00B34460 /* UnusedParam.h in Headers */, BC18C4760E16F5CD00B34460 /* UString.h in Headers */, - 8698BB3910D86BAF00D8D01B /* UStringImpl.h in Headers */, BC18C4770E16F5CD00B34460 /* UTF8.h in Headers */, E17FF771112131D200076A19 /* ValueCheck.h in Headers */, BC18C4780E16F5CD00B34460 /* Vector.h in Headers */, @@ -2229,6 +2231,8 @@ DDF7ABD411F60ED200108E36 /* GCActivityCallback.h in Headers */, DD2724691208D1FF00F9ABE7 /* AlignedMemoryAllocator.h in Headers */, DDE82AD81209D955005C1756 /* GCHandle.h in Headers */, + 86F38859121130CA007A7CE3 /* AtomicStringHash.h in Headers */, + 86B6DA0212132B9A000D316F /* StringConcatenate.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/JavaScriptCore/assembler/ARMAssembler.cpp b/JavaScriptCore/assembler/ARMAssembler.cpp index 9442b4b..42a6402 100644 --- a/JavaScriptCore/assembler/ARMAssembler.cpp +++ b/JavaScriptCore/assembler/ARMAssembler.cpp @@ -357,11 +357,11 @@ void* ARMAssembler::executableCopy(ExecutablePool* allocator) for (Jumps::Iterator iter = m_jumps.begin(); iter != m_jumps.end(); ++iter) { // The last bit is set if the constant must be placed on constant pool. int pos = (*iter) & (~0x1); - ARMWord* ldrAddr = reinterpret_cast<ARMWord*>(data + pos); + ARMWord* ldrAddr = reinterpret_cast_ptr<ARMWord*>(data + pos); ARMWord* addr = getLdrImmAddress(ldrAddr); if (*addr != InvalidBranchTarget) { if (!(*iter & 1)) { - int diff = reinterpret_cast<ARMWord*>(data + *addr) - (ldrAddr + DefaultPrefetching); + int diff = reinterpret_cast_ptr<ARMWord*>(data + *addr) - (ldrAddr + DefaultPrefetching); if ((diff <= BOFFSET_MAX && diff >= BOFFSET_MIN)) { *ldrAddr = B | getConditionalField(*ldrAddr) | (diff & BRANCH_MASK); diff --git a/JavaScriptCore/assembler/ARMAssembler.h b/JavaScriptCore/assembler/ARMAssembler.h index a19864a..da128e7 100644 --- a/JavaScriptCore/assembler/ARMAssembler.h +++ b/JavaScriptCore/assembler/ARMAssembler.h @@ -40,32 +40,54 @@ namespace JSC { r0 = 0, r1, r2, - r3, - S0 = r3, + r3, S0 = r3, r4, r5, r6, r7, - r8, - S1 = r8, + r8, S1 = r8, r9, r10, r11, r12, - r13, - sp = r13, - r14, - lr = r14, - r15, - pc = r15 + r13, sp = r13, + r14, lr = r14, + r15, pc = r15 } RegisterID; typedef enum { d0, d1, d2, - d3, - SD0 = d3 + d3, SD0 = d3, + d4, + d5, + d6, + d7, + d8, + d9, + d10, + d11, + d12, + d13, + d14, + d15, + d16, + d17, + d18, + d19, + d20, + d21, + d22, + d23, + d24, + d25, + d26, + d27, + d28, + d29, + d30, + d31 } FPRegisterID; } // namespace ARMRegisters @@ -118,12 +140,12 @@ namespace JSC { MVN = (0xf << 21), MUL = 0x00000090, MULL = 0x00c00090, - FADDD = 0x0e300b00, - FDIVD = 0x0e800b00, - FSUBD = 0x0e300b40, - FMULD = 0x0e200b00, - FCMPD = 0x0eb40b40, - FSQRTD = 0x0eb10bc0, + VADD_F64 = 0x0e300b00, + VDIV_F64 = 0x0e800b00, + VSUB_F64 = 0x0e300b40, + VMUL_F64 = 0x0e200b00, + VCMP_F64 = 0x0eb40b40, + VSQRT_F64 = 0x0eb10bc0, DTR = 0x05000000, LDRH = 0x00100090, STRH = 0x00000090, @@ -135,11 +157,11 @@ namespace JSC { #if WTF_ARM_ARCH_AT_LEAST(5) || defined(__ARM_ARCH_4T__) BX = 0x012fff10, #endif - FMSR = 0x0e000a10, - FMRS = 0x0e100a10, - FSITOD = 0x0eb80bc0, - FTOSID = 0x0ebd0b40, - FMSTAT = 0x0ef1fa10, + VMOV_VFP = 0x0e000a10, + VMOV_ARM = 0x0e100a10, + VCVT_F64_S32 = 0x0eb80bc0, + VCVT_S32_F64 = 0x0ebd0b40, + VMRS_APSR = 0x0ef1fa10, #if WTF_ARM_ARCH_AT_LEAST(5) CLZ = 0x016f0f10, BKPT = 0xe120070, @@ -234,10 +256,26 @@ namespace JSC { void emitInst(ARMWord op, int rd, int rn, ARMWord op2) { - ASSERT ( ((op2 & ~OP2_IMM) <= 0xfff) || (((op2 & ~OP2_IMMh) <= 0xfff)) ); + ASSERT(((op2 & ~OP2_IMM) <= 0xfff) || (((op2 & ~OP2_IMMh) <= 0xfff))); m_buffer.putInt(op | RN(rn) | RD(rd) | op2); } + void emitDoublePrecisionInst(ARMWord op, int dd, int dn, int dm) + { + ASSERT((dd >= 0 && dd <= 31) && (dn >= 0 && dn <= 31) && (dm >= 0 && dm <= 31)); + m_buffer.putInt(op | ((dd & 0xf) << 12) | ((dd & 0x10) << (22 - 4)) + | ((dn & 0xf) << 16) | ((dn & 0x10) << (7 - 4)) + | (dm & 0xf) | ((dm & 0x10) << (5 - 4))); + } + + void emitSinglePrecisionInst(ARMWord op, int sd, int sn, int sm) + { + ASSERT((sd >= 0 && sd <= 31) && (sn >= 0 && sn <= 31) && (sm >= 0 && sm <= 31)); + m_buffer.putInt(op | ((sd >> 1) << 12) | ((sd & 0x1) << 22) + | ((sn >> 1) << 16) | ((sn & 0x1) << 7) + | (sm >> 1) | ((sm & 0x1) << 5)); + } + void and_r(int rd, int rn, ARMWord op2, Condition cc = AL) { emitInst(static_cast<ARMWord>(cc) | AND, rd, rn, op2); @@ -402,34 +440,34 @@ namespace JSC { m_buffer.putInt(static_cast<ARMWord>(cc) | MULL | RN(rdhi) | RD(rdlo) | RS(rn) | RM(rm)); } - void faddd_r(int dd, int dn, int dm, Condition cc = AL) + void vadd_f64_r(int dd, int dn, int dm, Condition cc = AL) { - emitInst(static_cast<ARMWord>(cc) | FADDD, dd, dn, dm); + emitDoublePrecisionInst(static_cast<ARMWord>(cc) | VADD_F64, dd, dn, dm); } - void fdivd_r(int dd, int dn, int dm, Condition cc = AL) + void vdiv_f64_r(int dd, int dn, int dm, Condition cc = AL) { - emitInst(static_cast<ARMWord>(cc) | FDIVD, dd, dn, dm); + emitDoublePrecisionInst(static_cast<ARMWord>(cc) | VDIV_F64, dd, dn, dm); } - void fsubd_r(int dd, int dn, int dm, Condition cc = AL) + void vsub_f64_r(int dd, int dn, int dm, Condition cc = AL) { - emitInst(static_cast<ARMWord>(cc) | FSUBD, dd, dn, dm); + emitDoublePrecisionInst(static_cast<ARMWord>(cc) | VSUB_F64, dd, dn, dm); } - void fmuld_r(int dd, int dn, int dm, Condition cc = AL) + void vmul_f64_r(int dd, int dn, int dm, Condition cc = AL) { - emitInst(static_cast<ARMWord>(cc) | FMULD, dd, dn, dm); + emitDoublePrecisionInst(static_cast<ARMWord>(cc) | VMUL_F64, dd, dn, dm); } - void fcmpd_r(int dd, int dm, Condition cc = AL) + void vcmp_f64_r(int dd, int dm, Condition cc = AL) { - emitInst(static_cast<ARMWord>(cc) | FCMPD, dd, 0, dm); + emitDoublePrecisionInst(static_cast<ARMWord>(cc) | VCMP_F64, dd, 0, dm); } - void fsqrtd_r(int dd, int dm, Condition cc = AL) + void vsqrt_f64_r(int dd, int dm, Condition cc = AL) { - emitInst(static_cast<ARMWord>(cc) | FSQRTD, dd, 0, dm); + emitDoublePrecisionInst(static_cast<ARMWord>(cc) | VSQRT_F64, dd, 0, dm); } void ldr_imm(int rd, ARMWord imm, Condition cc = AL) @@ -516,29 +554,33 @@ namespace JSC { dtr_u(true, reg, ARMRegisters::sp, 0, cc); } - void fmsr_r(int dd, int rn, Condition cc = AL) + void vmov_vfp_r(int sn, int rt, Condition cc = AL) { - emitInst(static_cast<ARMWord>(cc) | FMSR, rn, dd, 0); + ASSERT(rt <= 15); + emitSinglePrecisionInst(static_cast<ARMWord>(cc) | VMOV_VFP, rt << 1, sn, 0); } - void fmrs_r(int rd, int dn, Condition cc = AL) + void vmov_arm_r(int rt, int sn, Condition cc = AL) { - emitInst(static_cast<ARMWord>(cc) | FMRS, rd, dn, 0); + ASSERT(rt <= 15); + emitSinglePrecisionInst(static_cast<ARMWord>(cc) | VMOV_ARM, rt << 1, sn, 0); } - void fsitod_r(int dd, int dm, Condition cc = AL) + void vcvt_f64_s32_r(int dd, int sm, Condition cc = AL) { - emitInst(static_cast<ARMWord>(cc) | FSITOD, dd, 0, dm); + ASSERT(!(sm & 0x1)); // sm must be divisible by 2 + emitDoublePrecisionInst(static_cast<ARMWord>(cc) | VCVT_F64_S32, dd, 0, (sm >> 1)); } - void ftosid_r(int fd, int dm, Condition cc = AL) + void vcvt_s32_f64_r(int sd, int dm, Condition cc = AL) { - emitInst(static_cast<ARMWord>(cc) | FTOSID, fd, 0, dm); + ASSERT(!(sd & 0x1)); // sd must be divisible by 2 + emitDoublePrecisionInst(static_cast<ARMWord>(cc) | VCVT_S32_F64, (sd >> 1), 0, dm); } - void fmstat(Condition cc = AL) + void vmrs_apsr(Condition cc = AL) { - m_buffer.putInt(static_cast<ARMWord>(cc) | FMSTAT); + m_buffer.putInt(static_cast<ARMWord>(cc) | VMRS_APSR); } #if WTF_ARM_ARCH_AT_LEAST(5) diff --git a/JavaScriptCore/assembler/ARMv7Assembler.h b/JavaScriptCore/assembler/ARMv7Assembler.h index f1b57b8..d960546 100644 --- a/JavaScriptCore/assembler/ARMv7Assembler.h +++ b/JavaScriptCore/assembler/ARMv7Assembler.h @@ -462,8 +462,8 @@ public: typedef enum { ConditionEQ, ConditionNE, - ConditionHS, - ConditionLO, + ConditionHS, ConditionCS = ConditionHS, + ConditionLO, ConditionCC = ConditionLO, ConditionMI, ConditionPL, ConditionVS, @@ -475,9 +475,7 @@ public: ConditionGT, ConditionLE, ConditionAL, - - ConditionCS = ConditionHS, - ConditionCC = ConditionLO, + ConditionInvalid } Condition; enum JumpType { JumpNoCondition, JumpCondition, JumpFullSize }; @@ -522,7 +520,7 @@ public: private: JmpSrc(int offset, JumpType type) : m_offset(offset) - , m_condition(0xffff) + , m_condition(ConditionInvalid) , m_type(type) { ASSERT(m_type != JumpCondition); diff --git a/JavaScriptCore/assembler/AssemblerBuffer.h b/JavaScriptCore/assembler/AssemblerBuffer.h index 11e0df0..0454a99 100644 --- a/JavaScriptCore/assembler/AssemblerBuffer.h +++ b/JavaScriptCore/assembler/AssemblerBuffer.h @@ -33,6 +33,7 @@ #include <jit/ExecutableAllocator.h> #include <wtf/Assertions.h> #include <wtf/FastMalloc.h> +#include <wtf/StdLibExtras.h> namespace JSC { @@ -81,7 +82,7 @@ namespace JSC { void putShortUnchecked(int value) { ASSERT(!(m_size > m_capacity - 4)); - *reinterpret_cast<short*>(&m_buffer[m_size]) = value; + *reinterpret_cast_ptr<short*>(&m_buffer[m_size]) = value; m_size += 2; } @@ -95,14 +96,14 @@ namespace JSC { void putIntUnchecked(int value) { ASSERT(!(m_size > m_capacity - 4)); - *reinterpret_cast<int*>(&m_buffer[m_size]) = value; + *reinterpret_cast_ptr<int*>(&m_buffer[m_size]) = value; m_size += 4; } void putInt64Unchecked(int64_t value) { ASSERT(!(m_size > m_capacity - 8)); - *reinterpret_cast<int64_t*>(&m_buffer[m_size]) = value; + *reinterpret_cast_ptr<int64_t*>(&m_buffer[m_size]) = value; m_size += 8; } diff --git a/JavaScriptCore/assembler/MacroAssemblerARM.h b/JavaScriptCore/assembler/MacroAssemblerARM.h index bb1a6da..48ddf24 100644 --- a/JavaScriptCore/assembler/MacroAssemblerARM.h +++ b/JavaScriptCore/assembler/MacroAssemblerARM.h @@ -795,7 +795,7 @@ public: void addDouble(FPRegisterID src, FPRegisterID dest) { - m_assembler.faddd_r(dest, dest, src); + m_assembler.vadd_f64_r(dest, dest, src); } void addDouble(Address src, FPRegisterID dest) @@ -806,7 +806,7 @@ public: void divDouble(FPRegisterID src, FPRegisterID dest) { - m_assembler.fdivd_r(dest, dest, src); + m_assembler.vdiv_f64_r(dest, dest, src); } void divDouble(Address src, FPRegisterID dest) @@ -818,7 +818,7 @@ public: void subDouble(FPRegisterID src, FPRegisterID dest) { - m_assembler.fsubd_r(dest, dest, src); + m_assembler.vsub_f64_r(dest, dest, src); } void subDouble(Address src, FPRegisterID dest) @@ -829,7 +829,7 @@ public: void mulDouble(FPRegisterID src, FPRegisterID dest) { - m_assembler.fmuld_r(dest, dest, src); + m_assembler.vmul_f64_r(dest, dest, src); } void mulDouble(Address src, FPRegisterID dest) @@ -840,13 +840,13 @@ public: void sqrtDouble(FPRegisterID src, FPRegisterID dest) { - m_assembler.fsqrtd_r(dest, src); + m_assembler.vsqrt_f64_r(dest, src); } void convertInt32ToDouble(RegisterID src, FPRegisterID dest) { - m_assembler.fmsr_r(dest, src); - m_assembler.fsitod_r(dest, dest); + m_assembler.vmov_vfp_r(dest << 1, src); + m_assembler.vcvt_f64_s32_r(dest, dest << 1); } void convertInt32ToDouble(Address src, FPRegisterID dest) @@ -868,8 +868,8 @@ public: Jump branchDouble(DoubleCondition cond, FPRegisterID left, FPRegisterID right) { - m_assembler.fcmpd_r(left, right); - m_assembler.fmstat(); + m_assembler.vcmp_f64_r(left, right); + m_assembler.vmrs_apsr(); if (cond & DoubleConditionBitSpecial) m_assembler.cmp_r(ARMRegisters::S0, ARMRegisters::S0, ARMAssembler::VS); return Jump(m_assembler.jmp(static_cast<ARMAssembler::Condition>(cond & ~DoubleConditionMask))); @@ -893,11 +893,11 @@ public: // (specifically, in this case, 0). void branchConvertDoubleToInt32(FPRegisterID src, RegisterID dest, JumpList& failureCases, FPRegisterID fpTemp) { - m_assembler.ftosid_r(ARMRegisters::SD0, src); - m_assembler.fmrs_r(dest, ARMRegisters::SD0); + m_assembler.vcvt_s32_f64_r(ARMRegisters::SD0 << 1, src); + m_assembler.vmov_arm_r(dest, ARMRegisters::SD0 << 1); // Convert the integer result back to float & compare to the original value - if not equal or unordered (NaN) then jump. - m_assembler.fsitod_r(ARMRegisters::SD0, ARMRegisters::SD0); + m_assembler.vcvt_f64_s32_r(ARMRegisters::SD0, ARMRegisters::SD0 << 1); failureCases.append(branchDouble(DoubleNotEqualOrUnordered, src, ARMRegisters::SD0)); // If the result is zero, it might have been -0.0, and 0.0 equals to -0.0 diff --git a/JavaScriptCore/bytecode/CodeBlock.cpp b/JavaScriptCore/bytecode/CodeBlock.cpp index 9a8c332..0749cf6 100644 --- a/JavaScriptCore/bytecode/CodeBlock.cpp +++ b/JavaScriptCore/bytecode/CodeBlock.cpp @@ -30,13 +30,14 @@ #include "config.h" #include "CodeBlock.h" -#include "JIT.h" -#include "JSValue.h" +#include "BytecodeGenerator.h" +#include "Debugger.h" #include "Interpreter.h" +#include "JIT.h" #include "JSFunction.h" #include "JSStaticScopeObject.h" -#include "Debugger.h" -#include "BytecodeGenerator.h" +#include "JSValue.h" +#include "StringConcatenate.h" #include <stdio.h> #include <wtf/StringExtras.h> @@ -49,9 +50,9 @@ namespace JSC { static UString escapeQuotes(const UString& str) { UString result = str; - unsigned pos = 0; - while ((pos = result.find('\"', pos)) != UString::NotFound) { - result = makeString(result.substr(0, pos), "\"\\\"\"", result.substr(pos + 1)); + size_t pos = 0; + while ((pos = result.find('\"', pos)) != notFound) { + result = makeString(result.substringSharingImpl(0, pos), "\"\\\"\"", result.substringSharingImpl(pos + 1)); pos += 4; } return result; @@ -70,12 +71,12 @@ static UString valueToSourceString(ExecState* exec, JSValue val) static CString constantName(ExecState* exec, int k, JSValue value) { - return makeString(valueToSourceString(exec, value), "(@k", UString::from(k - FirstConstantRegisterIndex), ")").UTF8String(); + return makeString(valueToSourceString(exec, value), "(@k", UString::number(k - FirstConstantRegisterIndex), ")").utf8(); } static CString idName(int id0, const Identifier& ident) { - return makeString(ident.ustring(), "(@id", UString::from(id0), ")").UTF8String(); + return makeString(ident.ustring(), "(@id", UString::number(id0), ")").utf8(); } CString CodeBlock::registerName(ExecState* exec, int r) const @@ -86,7 +87,7 @@ CString CodeBlock::registerName(ExecState* exec, int r) const if (isConstantRegisterIndex(r)) return constantName(exec, r, getConstant(r)); - return makeString("r", UString::from(r)).UTF8String(); + return makeString("r", UString::number(r)).utf8(); } static UString regexpToSourceString(RegExp* regExp) @@ -105,7 +106,7 @@ static UString regexpToSourceString(RegExp* regExp) static CString regexpName(int re, RegExp* regexp) { - return makeString(regexpToSourceString(regexp), "(@re", UString::from(re), ")").UTF8String(); + return makeString(regexpToSourceString(regexp), "(@re", UString::number(re), ")").utf8(); } static UString pointerToSourceString(void* p) @@ -223,32 +224,32 @@ static unsigned instructionOffsetForNth(ExecState* exec, const Vector<Instructio static void printGlobalResolveInfo(const GlobalResolveInfo& resolveInfo, unsigned instructionOffset) { - printf(" [%4d] %s: %s\n", instructionOffset, "resolve_global", pointerToSourceString(resolveInfo.structure).UTF8String().data()); + printf(" [%4d] %s: %s\n", instructionOffset, "resolve_global", pointerToSourceString(resolveInfo.structure).utf8().data()); } static void printStructureStubInfo(const StructureStubInfo& stubInfo, unsigned instructionOffset) { switch (stubInfo.accessType) { case access_get_by_id_self: - printf(" [%4d] %s: %s\n", instructionOffset, "get_by_id_self", pointerToSourceString(stubInfo.u.getByIdSelf.baseObjectStructure).UTF8String().data()); + printf(" [%4d] %s: %s\n", instructionOffset, "get_by_id_self", pointerToSourceString(stubInfo.u.getByIdSelf.baseObjectStructure).utf8().data()); return; case access_get_by_id_proto: - printf(" [%4d] %s: %s, %s\n", instructionOffset, "get_by_id_proto", pointerToSourceString(stubInfo.u.getByIdProto.baseObjectStructure).UTF8String().data(), pointerToSourceString(stubInfo.u.getByIdProto.prototypeStructure).UTF8String().data()); + printf(" [%4d] %s: %s, %s\n", instructionOffset, "get_by_id_proto", pointerToSourceString(stubInfo.u.getByIdProto.baseObjectStructure).utf8().data(), pointerToSourceString(stubInfo.u.getByIdProto.prototypeStructure).utf8().data()); return; case access_get_by_id_chain: - printf(" [%4d] %s: %s, %s\n", instructionOffset, "get_by_id_chain", pointerToSourceString(stubInfo.u.getByIdChain.baseObjectStructure).UTF8String().data(), pointerToSourceString(stubInfo.u.getByIdChain.chain).UTF8String().data()); + printf(" [%4d] %s: %s, %s\n", instructionOffset, "get_by_id_chain", pointerToSourceString(stubInfo.u.getByIdChain.baseObjectStructure).utf8().data(), pointerToSourceString(stubInfo.u.getByIdChain.chain).utf8().data()); return; case access_get_by_id_self_list: - printf(" [%4d] %s: %s (%d)\n", instructionOffset, "op_get_by_id_self_list", pointerToSourceString(stubInfo.u.getByIdSelfList.structureList).UTF8String().data(), stubInfo.u.getByIdSelfList.listSize); + printf(" [%4d] %s: %s (%d)\n", instructionOffset, "op_get_by_id_self_list", pointerToSourceString(stubInfo.u.getByIdSelfList.structureList).utf8().data(), stubInfo.u.getByIdSelfList.listSize); return; case access_get_by_id_proto_list: - printf(" [%4d] %s: %s (%d)\n", instructionOffset, "op_get_by_id_proto_list", pointerToSourceString(stubInfo.u.getByIdProtoList.structureList).UTF8String().data(), stubInfo.u.getByIdProtoList.listSize); + printf(" [%4d] %s: %s (%d)\n", instructionOffset, "op_get_by_id_proto_list", pointerToSourceString(stubInfo.u.getByIdProtoList.structureList).utf8().data(), stubInfo.u.getByIdProtoList.listSize); return; case access_put_by_id_transition: - printf(" [%4d] %s: %s, %s, %s\n", instructionOffset, "put_by_id_transition", pointerToSourceString(stubInfo.u.putByIdTransition.previousStructure).UTF8String().data(), pointerToSourceString(stubInfo.u.putByIdTransition.structure).UTF8String().data(), pointerToSourceString(stubInfo.u.putByIdTransition.chain).UTF8String().data()); + printf(" [%4d] %s: %s, %s, %s\n", instructionOffset, "put_by_id_transition", pointerToSourceString(stubInfo.u.putByIdTransition.previousStructure).utf8().data(), pointerToSourceString(stubInfo.u.putByIdTransition.structure).utf8().data(), pointerToSourceString(stubInfo.u.putByIdTransition.chain).utf8().data()); return; case access_put_by_id_replace: - printf(" [%4d] %s: %s\n", instructionOffset, "put_by_id_replace", pointerToSourceString(stubInfo.u.putByIdReplace.baseObjectStructure).UTF8String().data()); + printf(" [%4d] %s: %s\n", instructionOffset, "put_by_id_replace", pointerToSourceString(stubInfo.u.putByIdReplace.baseObjectStructure).utf8().data()); return; case access_get_by_id: printf(" [%4d] %s\n", instructionOffset, "get_by_id"); @@ -277,7 +278,7 @@ static void printStructureStubInfo(const StructureStubInfo& stubInfo, unsigned i void CodeBlock::printStructure(const char* name, const Instruction* vPC, int operand) const { unsigned instructionOffset = vPC - m_instructions.begin(); - printf(" [%4d] %s: %s\n", instructionOffset, name, pointerToSourceString(vPC[operand].u.structure).UTF8String().data()); + printf(" [%4d] %s: %s\n", instructionOffset, name, pointerToSourceString(vPC[operand].u.structure).utf8().data()); } void CodeBlock::printStructures(const Instruction* vPC) const @@ -294,15 +295,15 @@ void CodeBlock::printStructures(const Instruction* vPC) const return; } if (vPC[0].u.opcode == interpreter->getOpcode(op_get_by_id_proto)) { - printf(" [%4d] %s: %s, %s\n", instructionOffset, "get_by_id_proto", pointerToSourceString(vPC[4].u.structure).UTF8String().data(), pointerToSourceString(vPC[5].u.structure).UTF8String().data()); + printf(" [%4d] %s: %s, %s\n", instructionOffset, "get_by_id_proto", pointerToSourceString(vPC[4].u.structure).utf8().data(), pointerToSourceString(vPC[5].u.structure).utf8().data()); return; } if (vPC[0].u.opcode == interpreter->getOpcode(op_put_by_id_transition)) { - printf(" [%4d] %s: %s, %s, %s\n", instructionOffset, "put_by_id_transition", pointerToSourceString(vPC[4].u.structure).UTF8String().data(), pointerToSourceString(vPC[5].u.structure).UTF8String().data(), pointerToSourceString(vPC[6].u.structureChain).UTF8String().data()); + printf(" [%4d] %s: %s, %s, %s\n", instructionOffset, "put_by_id_transition", pointerToSourceString(vPC[4].u.structure).utf8().data(), pointerToSourceString(vPC[5].u.structure).utf8().data(), pointerToSourceString(vPC[6].u.structureChain).utf8().data()); return; } if (vPC[0].u.opcode == interpreter->getOpcode(op_get_by_id_chain)) { - printf(" [%4d] %s: %s, %s\n", instructionOffset, "get_by_id_chain", pointerToSourceString(vPC[4].u.structure).UTF8String().data(), pointerToSourceString(vPC[5].u.structureChain).UTF8String().data()); + printf(" [%4d] %s: %s, %s\n", instructionOffset, "get_by_id_chain", pointerToSourceString(vPC[4].u.structure).utf8().data(), pointerToSourceString(vPC[5].u.structureChain).utf8().data()); return; } if (vPC[0].u.opcode == interpreter->getOpcode(op_put_by_id)) { @@ -352,7 +353,7 @@ void CodeBlock::dump(ExecState* exec) const printf("\nIdentifiers:\n"); size_t i = 0; do { - printf(" id%u = %s\n", static_cast<unsigned>(i), m_identifiers[i].ascii()); + printf(" id%u = %s\n", static_cast<unsigned>(i), m_identifiers[i].ustring().utf8().data()); ++i; } while (i != m_identifiers.size()); } @@ -362,7 +363,7 @@ void CodeBlock::dump(ExecState* exec) const unsigned registerIndex = m_numVars; size_t i = 0; do { - printf(" k%u = %s\n", registerIndex, valueToSourceString(exec, m_constantRegisters[i].jsValue()).ascii()); + printf(" k%u = %s\n", registerIndex, valueToSourceString(exec, m_constantRegisters[i].jsValue()).utf8().data()); ++i; ++registerIndex; } while (i < m_constantRegisters.size()); @@ -372,7 +373,7 @@ void CodeBlock::dump(ExecState* exec) const printf("\nm_regexps:\n"); size_t i = 0; do { - printf(" re%u = %s\n", static_cast<unsigned>(i), regexpToSourceString(m_rareData->m_regexps[i].get()).ascii()); + printf(" re%u = %s\n", static_cast<unsigned>(i), regexpToSourceString(m_rareData->m_regexps[i].get()).utf8().data()); ++i; } while (i < m_rareData->m_regexps.size()); } @@ -453,7 +454,7 @@ void CodeBlock::dump(ExecState* exec) const continue; ASSERT(!((i + m_rareData->m_characterSwitchJumpTables[i].min) & ~0xFFFF)); UChar ch = static_cast<UChar>(entry + m_rareData->m_characterSwitchJumpTables[i].min); - printf("\t\t\"%s\" => %04d\n", UString(&ch, 1).ascii(), *iter); + printf("\t\t\"%s\" => %04d\n", UString(&ch, 1).utf8().data(), *iter); } printf(" }\n"); ++i; @@ -467,7 +468,7 @@ void CodeBlock::dump(ExecState* exec) const printf(" %1d = {\n", i); StringJumpTable::StringOffsetTable::const_iterator end = m_rareData->m_stringSwitchJumpTables[i].offsetTable.end(); for (StringJumpTable::StringOffsetTable::const_iterator iter = m_rareData->m_stringSwitchJumpTables[i].offsetTable.begin(); iter != end; ++iter) - printf("\t\t\"%s\" => %04d\n", UString(iter->first).ascii(), iter->second.branchOffset); + printf("\t\t\"%s\" => %04d\n", UString(iter->first).utf8().data(), iter->second.branchOffset); printf(" }\n"); ++i; } while (i < m_rareData->m_stringSwitchJumpTables.size()); @@ -713,7 +714,7 @@ void CodeBlock::dump(ExecState* exec, const Vector<Instruction>::const_iterator& int r0 = (++it)->u.operand; JSValue scope = JSValue((++it)->u.jsCell); int id0 = (++it)->u.operand; - printf("[%4d] resolve_global\t %s, %s, %s\n", location, registerName(exec, r0).data(), valueToSourceString(exec, scope).ascii(), idName(id0, m_identifiers[id0]).data()); + printf("[%4d] resolve_global\t %s, %s, %s\n", location, registerName(exec, r0).data(), valueToSourceString(exec, scope).utf8().data(), idName(id0, m_identifiers[id0]).data()); it += 2; break; } @@ -722,7 +723,7 @@ void CodeBlock::dump(ExecState* exec, const Vector<Instruction>::const_iterator& JSValue scope = JSValue((++it)->u.jsCell); int id0 = (++it)->u.operand; int depth = it[2].u.operand; - printf("[%4d] resolve_global_dynamic\t %s, %s, %s, %d\n", location, registerName(exec, r0).data(), valueToSourceString(exec, scope).ascii(), idName(id0, m_identifiers[id0]).data(), depth); + printf("[%4d] resolve_global_dynamic\t %s, %s, %s, %d\n", location, registerName(exec, r0).data(), valueToSourceString(exec, scope).utf8().data(), idName(id0, m_identifiers[id0]).data(), depth); it += 3; break; } @@ -744,14 +745,14 @@ void CodeBlock::dump(ExecState* exec, const Vector<Instruction>::const_iterator& int r0 = (++it)->u.operand; JSValue scope = JSValue((++it)->u.jsCell); int index = (++it)->u.operand; - printf("[%4d] get_global_var\t %s, %s, %d\n", location, registerName(exec, r0).data(), valueToSourceString(exec, scope).ascii(), index); + printf("[%4d] get_global_var\t %s, %s, %d\n", location, registerName(exec, r0).data(), valueToSourceString(exec, scope).utf8().data(), index); break; } case op_put_global_var: { JSValue scope = JSValue((++it)->u.jsCell); int index = (++it)->u.operand; int r0 = (++it)->u.operand; - printf("[%4d] put_global_var\t %s, %d, %s\n", location, valueToSourceString(exec, scope).ascii(), index, registerName(exec, r0).data()); + printf("[%4d] put_global_var\t %s, %d, %s\n", location, valueToSourceString(exec, scope).utf8().data(), index, registerName(exec, r0).data()); break; } case op_resolve_base: { diff --git a/JavaScriptCore/bytecode/EvalCodeCache.h b/JavaScriptCore/bytecode/EvalCodeCache.h index 27c479d..7c4cb33 100644 --- a/JavaScriptCore/bytecode/EvalCodeCache.h +++ b/JavaScriptCore/bytecode/EvalCodeCache.h @@ -47,8 +47,8 @@ namespace JSC { { RefPtr<EvalExecutable> evalExecutable; - if (evalSource.size() < maxCacheableSourceLength && (*scopeChain->begin())->isVariableObject()) - evalExecutable = m_cacheMap.get(evalSource.rep()); + if (evalSource.length() < maxCacheableSourceLength && (*scopeChain->begin())->isVariableObject()) + evalExecutable = m_cacheMap.get(evalSource.impl()); if (!evalExecutable) { evalExecutable = EvalExecutable::create(exec, makeSource(evalSource)); @@ -56,8 +56,8 @@ namespace JSC { if (exceptionValue) return 0; - if (evalSource.size() < maxCacheableSourceLength && (*scopeChain->begin())->isVariableObject() && m_cacheMap.size() < maxCacheEntries) - m_cacheMap.set(evalSource.rep(), evalExecutable); + if (evalSource.length() < maxCacheableSourceLength && (*scopeChain->begin())->isVariableObject() && m_cacheMap.size() < maxCacheEntries) + m_cacheMap.set(evalSource.impl(), evalExecutable); } return evalExecutable.release(); @@ -69,7 +69,7 @@ namespace JSC { static const unsigned maxCacheableSourceLength = 256; static const int maxCacheEntries = 64; - typedef HashMap<RefPtr<UString::Rep>, RefPtr<EvalExecutable> > EvalCacheMap; + typedef HashMap<RefPtr<StringImpl>, RefPtr<EvalExecutable> > EvalCacheMap; EvalCacheMap m_cacheMap; }; diff --git a/JavaScriptCore/bytecode/JumpTable.h b/JavaScriptCore/bytecode/JumpTable.h index b4f8e44..5bbe047 100644 --- a/JavaScriptCore/bytecode/JumpTable.h +++ b/JavaScriptCore/bytecode/JumpTable.h @@ -45,13 +45,13 @@ namespace JSC { }; struct StringJumpTable { - typedef HashMap<RefPtr<UString::Rep>, OffsetLocation> StringOffsetTable; + typedef HashMap<RefPtr<StringImpl>, OffsetLocation> StringOffsetTable; StringOffsetTable offsetTable; #if ENABLE(JIT) CodeLocationLabel ctiDefault; // FIXME: it should not be necessary to store this. #endif - inline int32_t offsetForValue(UString::Rep* value, int32_t defaultOffset) + inline int32_t offsetForValue(StringImpl* value, int32_t defaultOffset) { StringOffsetTable::const_iterator end = offsetTable.end(); StringOffsetTable::const_iterator loc = offsetTable.find(value); @@ -61,7 +61,7 @@ namespace JSC { } #if ENABLE(JIT) - inline CodeLocationLabel ctiForValue(UString::Rep* value) + inline CodeLocationLabel ctiForValue(StringImpl* value) { StringOffsetTable::const_iterator end = offsetTable.end(); StringOffsetTable::const_iterator loc = offsetTable.find(value); diff --git a/JavaScriptCore/bytecode/SamplingTool.cpp b/JavaScriptCore/bytecode/SamplingTool.cpp index 7191e38..4614776 100644 --- a/JavaScriptCore/bytecode/SamplingTool.cpp +++ b/JavaScriptCore/bytecode/SamplingTool.cpp @@ -337,7 +337,7 @@ void SamplingTool::dump(ExecState* exec) if (blockPercent >= 1) { //Instruction* code = codeBlock->instructions().begin(); - printf("#%d: %s:%d: %d / %lld (%.3f%%)\n", i + 1, record->m_executable->sourceURL().ascii(), codeBlock->lineNumberForBytecodeOffset(exec, 0), record->m_sampleCount, m_sampleCount, blockPercent); + printf("#%d: %s:%d: %d / %lld (%.3f%%)\n", i + 1, record->m_executable->sourceURL().utf8().data(), codeBlock->lineNumberForBytecodeOffset(exec, 0), record->m_sampleCount, m_sampleCount, blockPercent); if (i < 10) { HashMap<unsigned,unsigned> lineCounts; codeBlock->dump(exec); diff --git a/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp b/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp index 34011c1..ab259a6 100644 --- a/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp +++ b/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp @@ -165,7 +165,7 @@ bool BytecodeGenerator::addVar(const Identifier& ident, bool isConstant, Registe { int index = m_calleeRegisters.size(); SymbolTableEntry newEntry(index, isConstant ? ReadOnly : 0); - pair<SymbolTable::iterator, bool> result = symbolTable().add(ident.ustring().rep(), newEntry); + pair<SymbolTable::iterator, bool> result = symbolTable().add(ident.impl(), newEntry); if (!result.second) { r0 = ®isterFor(result.first->second.getIndex()); @@ -180,7 +180,7 @@ bool BytecodeGenerator::addGlobalVar(const Identifier& ident, bool isConstant, R { int index = m_nextGlobalIndex; SymbolTableEntry newEntry(index, isConstant ? ReadOnly : 0); - pair<SymbolTable::iterator, bool> result = symbolTable().add(ident.ustring().rep(), newEntry); + pair<SymbolTable::iterator, bool> result = symbolTable().add(ident.impl(), newEntry); if (!result.second) index = result.first->second.getIndex(); @@ -350,7 +350,7 @@ BytecodeGenerator::BytecodeGenerator(FunctionBodyNode* functionBody, const Debug for (size_t i = 0; i < functionStack.size(); ++i) { FunctionBodyNode* function = functionStack[i]; const Identifier& ident = function->ident(); - m_functions.add(ident.ustring().rep()); + m_functions.add(ident.impl()); emitNewFunction(addVar(ident, false), function); } @@ -437,7 +437,7 @@ BytecodeGenerator::BytecodeGenerator(EvalNode* evalNode, const Debugger* debugge void BytecodeGenerator::addParameter(const Identifier& ident, int parameterIndex) { // Parameters overwrite var declarations, but not function declarations. - UString::Rep* rep = ident.ustring().rep(); + StringImpl* rep = ident.impl(); if (!m_functions.contains(rep)) { symbolTable().set(rep, parameterIndex); RegisterID& parameter = registerFor(parameterIndex); @@ -457,7 +457,7 @@ RegisterID* BytecodeGenerator::registerFor(const Identifier& ident) if (!shouldOptimizeLocals()) return 0; - SymbolTableEntry entry = symbolTable().get(ident.ustring().rep()); + SymbolTableEntry entry = symbolTable().get(ident.impl()); if (entry.isNull()) return 0; @@ -475,7 +475,7 @@ bool BytecodeGenerator::willResolveToArguments(const Identifier& ident) if (!shouldOptimizeLocals()) return false; - SymbolTableEntry entry = symbolTable().get(ident.ustring().rep()); + SymbolTableEntry entry = symbolTable().get(ident.impl()); if (entry.isNull()) return false; @@ -489,7 +489,7 @@ RegisterID* BytecodeGenerator::uncheckedRegisterForArguments() { ASSERT(willResolveToArguments(propertyNames().arguments)); - SymbolTableEntry entry = symbolTable().get(propertyNames().arguments.ustring().rep()); + SymbolTableEntry entry = symbolTable().get(propertyNames().arguments.impl()); ASSERT(!entry.isNull()); return ®isterFor(entry.getIndex()); } @@ -499,7 +499,7 @@ RegisterID* BytecodeGenerator::constRegisterFor(const Identifier& ident) if (m_codeType == EvalCode) return 0; - SymbolTableEntry entry = symbolTable().get(ident.ustring().rep()); + SymbolTableEntry entry = symbolTable().get(ident.impl()); if (entry.isNull()) return 0; @@ -511,12 +511,12 @@ bool BytecodeGenerator::isLocal(const Identifier& ident) if (ident == propertyNames().thisIdentifier) return true; - return shouldOptimizeLocals() && symbolTable().contains(ident.ustring().rep()); + return shouldOptimizeLocals() && symbolTable().contains(ident.impl()); } bool BytecodeGenerator::isLocalConstant(const Identifier& ident) { - return symbolTable().get(ident.ustring().rep()).isReadOnly(); + return symbolTable().get(ident.impl()).isReadOnly(); } RegisterID* BytecodeGenerator::newRegister() @@ -829,7 +829,7 @@ PassRefPtr<Label> BytecodeGenerator::emitJumpIfNotFunctionApply(RegisterID* cond unsigned BytecodeGenerator::addConstant(const Identifier& ident) { - UString::Rep* rep = ident.ustring().rep(); + StringImpl* rep = ident.impl(); pair<IdentifierMap::iterator, bool> result = m_identifierMap.add(rep, m_codeBlock->numberOfIdentifiers()); if (result.second) // new entry m_codeBlock->addIdentifier(Identifier(m_globalData, rep)); @@ -1001,7 +1001,7 @@ RegisterID* BytecodeGenerator::emitLoad(RegisterID* dst, double number) RegisterID* BytecodeGenerator::emitLoad(RegisterID* dst, const Identifier& identifier) { - JSString*& stringInMap = m_stringMap.add(identifier.ustring().rep(), 0).first->second; + JSString*& stringInMap = m_stringMap.add(identifier.impl(), 0).first->second; if (!stringInMap) stringInMap = jsOwnedString(globalData(), identifier.ustring()); return emitLoad(dst, JSValue(stringInMap)); @@ -1039,7 +1039,7 @@ bool BytecodeGenerator::findScopedProperty(const Identifier& property, int& inde if (!currentScope->isVariableObject()) break; JSVariableObject* currentVariableObject = static_cast<JSVariableObject*>(currentScope); - SymbolTableEntry entry = currentVariableObject->symbolTable().get(property.ustring().rep()); + SymbolTableEntry entry = currentVariableObject->symbolTable().get(property.impl()); // Found the property if (!entry.isNull()) { @@ -1974,7 +1974,7 @@ static int32_t keyForCharacterSwitch(ExpressionNode* node, int32_t min, int32_t { UNUSED_PARAM(max); ASSERT(node->isString()); - UString::Rep* clause = static_cast<StringNode*>(node)->value().ustring().rep(); + StringImpl* clause = static_cast<StringNode*>(node)->value().impl(); ASSERT(clause->length() == 1); int32_t key = clause->characters()[0]; @@ -2004,7 +2004,7 @@ static void prepareJumpTableForStringSwitch(StringJumpTable& jumpTable, int32_t ASSERT(!labels[i]->isForward()); ASSERT(nodes[i]->isString()); - UString::Rep* clause = static_cast<StringNode*>(nodes[i])->value().ustring().rep(); + StringImpl* clause = static_cast<StringNode*>(nodes[i])->value().impl(); OffsetLocation location; location.branchOffset = labels[i]->bind(switchAddress, switchAddress + 3); jumpTable.offsetTable.add(clause, location); diff --git a/JavaScriptCore/bytecompiler/BytecodeGenerator.h b/JavaScriptCore/bytecompiler/BytecodeGenerator.h index f855d12..f7bd0bf 100644 --- a/JavaScriptCore/bytecompiler/BytecodeGenerator.h +++ b/JavaScriptCore/bytecompiler/BytecodeGenerator.h @@ -436,9 +436,9 @@ namespace JSC { static const bool needsRef = false; }; - typedef HashMap<RefPtr<UString::Rep>, int, IdentifierRepHash, HashTraits<RefPtr<UString::Rep> >, IdentifierMapIndexHashTraits> IdentifierMap; + typedef HashMap<RefPtr<StringImpl>, int, IdentifierRepHash, HashTraits<RefPtr<StringImpl> >, IdentifierMapIndexHashTraits> IdentifierMap; typedef HashMap<double, JSValue> NumberMap; - typedef HashMap<UString::Rep*, JSString*, IdentifierRepHash> IdentifierStringMap; + typedef HashMap<StringImpl*, JSString*, IdentifierRepHash> IdentifierStringMap; RegisterID* emitCall(OpcodeID, RegisterID* dst, RegisterID* func, CallArguments&, unsigned divot, unsigned startOffset, unsigned endOffset); @@ -524,7 +524,7 @@ namespace JSC { // Some of these objects keep pointers to one another. They are arranged // to ensure a sane destruction order that avoids references to freed memory. - HashSet<RefPtr<UString::Rep>, IdentifierRepHash> m_functions; + HashSet<RefPtr<StringImpl>, IdentifierRepHash> m_functions; RegisterID m_ignoredResultRegister; RegisterID m_thisRegister; RegisterID* m_activationRegister; diff --git a/JavaScriptCore/bytecompiler/NodesCodegen.cpp b/JavaScriptCore/bytecompiler/NodesCodegen.cpp index 277562d..f098ba6 100644 --- a/JavaScriptCore/bytecompiler/NodesCodegen.cpp +++ b/JavaScriptCore/bytecompiler/NodesCodegen.cpp @@ -42,6 +42,7 @@ #include "RegExpCache.h" #include "RegExpObject.h" #include "SamplingTool.h" +#include "StringConcatenate.h" #include <wtf/Assertions.h> #include <wtf/RefCountedLeakCounter.h> #include <wtf/Threading.h> @@ -77,9 +78,9 @@ namespace JSC { static void substitute(UString& string, const UString& substring) { - unsigned position = string.find("%s"); - ASSERT(position != UString::NotFound); - string = makeString(string.substr(0, position), substring, string.substr(position + 2)); + size_t position = string.find("%s"); + ASSERT(position != notFound); + string = makeString(string.substringSharingImpl(0, position), substring, string.substringSharingImpl(position + 2)); } RegisterID* ThrowableExpressionData::emitThrowError(BytecodeGenerator& generator, bool isReferenceError, const char* message) @@ -177,7 +178,7 @@ RegisterID* ResolveNode::emitBytecode(BytecodeGenerator& generator, RegisterID* return generator.moveToDestinationIfNeeded(dst, local); } - generator.emitExpressionInfo(m_startOffset + m_ident.size(), m_ident.size(), 0); + generator.emitExpressionInfo(m_startOffset + m_ident.length(), m_ident.length(), 0); return generator.emitResolve(generator.finalDestination(dst), m_ident); } @@ -381,7 +382,7 @@ RegisterID* FunctionCallResolveNode::emitBytecode(BytecodeGenerator& generator, RefPtr<RegisterID> func = generator.newTemporary(); CallArguments callArguments(generator, m_args); int identifierStart = divot() - startOffset(); - generator.emitExpressionInfo(identifierStart + m_ident.size(), m_ident.size(), 0); + generator.emitExpressionInfo(identifierStart + m_ident.length(), m_ident.length(), 0); generator.emitResolveWithBase(callArguments.thisRegister(), func.get(), m_ident); return generator.emitCall(generator.finalDestinationOrIgnored(dst, func.get()), func.get(), callArguments, divot(), startOffset(), endOffset()); } @@ -1183,7 +1184,7 @@ RegisterID* ReadModifyResolveNode::emitBytecode(BytecodeGenerator& generator, Re } RefPtr<RegisterID> src1 = generator.tempDestination(dst); - generator.emitExpressionInfo(divot() - startOffset() + m_ident.size(), m_ident.size(), 0); + generator.emitExpressionInfo(divot() - startOffset() + m_ident.length(), m_ident.length(), 0); RefPtr<RegisterID> base = generator.emitResolveWithBase(generator.newTemporary(), src1.get(), m_ident); RegisterID* result = emitReadModifyAssignment(generator, generator.finalDestination(dst, src1.get()), src1.get(), m_right, m_operator, OperandTypes(ResultType::unknownType(), m_right->resultDescriptor()), this); return generator.emitPutById(base.get(), m_ident, result); @@ -1747,8 +1748,8 @@ static void processClauseList(ClauseListNode* list, Vector<ExpressionNode*, 8>& break; } const UString& value = static_cast<StringNode*>(clauseExpression)->value().ustring(); - if (singleCharacterSwitch &= value.size() == 1) { - int32_t intVal = value.rep()->characters()[0]; + if (singleCharacterSwitch &= value.length() == 1) { + int32_t intVal = value.impl()->characters()[0]; if (intVal < min_num) min_num = intVal; if (intVal > max_num) diff --git a/JavaScriptCore/debugger/DebuggerCallFrame.cpp b/JavaScriptCore/debugger/DebuggerCallFrame.cpp index da9cb52..32f65dd 100644 --- a/JavaScriptCore/debugger/DebuggerCallFrame.cpp +++ b/JavaScriptCore/debugger/DebuggerCallFrame.cpp @@ -57,7 +57,7 @@ UString DebuggerCallFrame::calculatedFunctionName() const JSObject* function = m_callFrame->callee(); if (!function || !function->inherits(&JSFunction::info)) - return 0; + return UString(); return asFunction(function)->calculatedDisplayName(m_callFrame); } diff --git a/JavaScriptCore/interpreter/CallFrame.cpp b/JavaScriptCore/interpreter/CallFrame.cpp index ff061db..5819875 100644 --- a/JavaScriptCore/interpreter/CallFrame.cpp +++ b/JavaScriptCore/interpreter/CallFrame.cpp @@ -40,7 +40,7 @@ void CallFrame::dumpCaller() JSValue function; interpreter()->retrieveLastCaller(this, signedLineNumber, sourceID, urlString, function); - printf("Callpoint => %s:%d\n", urlString.ascii(), signedLineNumber); + printf("Callpoint => %s:%d\n", urlString.utf8().data(), signedLineNumber); } RegisterFile* CallFrame::registerFile() diff --git a/JavaScriptCore/interpreter/Interpreter.cpp b/JavaScriptCore/interpreter/Interpreter.cpp index e7ae540..b1049ad 100644 --- a/JavaScriptCore/interpreter/Interpreter.cpp +++ b/JavaScriptCore/interpreter/Interpreter.cpp @@ -3574,7 +3574,7 @@ skip_id_custom_self: if (!scrutinee.isString()) vPC += defaultOffset; else { - UString::Rep* value = asString(scrutinee)->value(callFrame).rep(); + StringImpl* value = asString(scrutinee)->value(callFrame).impl(); if (value->length() != 1) vPC += defaultOffset; else @@ -3597,7 +3597,7 @@ skip_id_custom_self: if (!scrutinee.isString()) vPC += defaultOffset; else - vPC += codeBlock->stringSwitchJumpTable(tableIndex).offsetForValue(asString(scrutinee)->value(callFrame).rep(), defaultOffset); + vPC += codeBlock->stringSwitchJumpTable(tableIndex).offsetForValue(asString(scrutinee)->value(callFrame).impl(), defaultOffset); NEXT_INSTRUCTION(); } DEFINE_OPCODE(op_new_func) { diff --git a/JavaScriptCore/interpreter/RegisterFile.h b/JavaScriptCore/interpreter/RegisterFile.h index 6c4e969..f3284ff 100644 --- a/JavaScriptCore/interpreter/RegisterFile.h +++ b/JavaScriptCore/interpreter/RegisterFile.h @@ -166,7 +166,7 @@ namespace JSC { checkAllocatedOkay(base); size_t committedSize = roundUpAllocationSize(maxGlobals * sizeof(Register), commitSize); checkAllocatedOkay(m_reservation.commit(base, committedSize)); - m_commitEnd = reinterpret_cast<Register*>(reinterpret_cast<char*>(base) + committedSize); + m_commitEnd = reinterpret_cast_ptr<Register*>(reinterpret_cast<char*>(base) + committedSize); m_start = static_cast<Register*>(base) + maxGlobals; m_end = m_start; m_maxUsed = m_end; @@ -193,7 +193,7 @@ namespace JSC { if (newEnd > m_commitEnd) { size_t size = roundUpAllocationSize(reinterpret_cast<char*>(newEnd) - reinterpret_cast<char*>(m_commitEnd), commitSize); checkAllocatedOkay(m_reservation.commit(m_commitEnd, size)); - m_commitEnd = reinterpret_cast<Register*>(reinterpret_cast<char*>(m_commitEnd) + size); + m_commitEnd = reinterpret_cast_ptr<Register*>(reinterpret_cast<char*>(m_commitEnd) + size); } if (newEnd > m_maxUsed) diff --git a/JavaScriptCore/jit/JITStubs.cpp b/JavaScriptCore/jit/JITStubs.cpp index c4ff0ca..f1808d5 100644 --- a/JavaScriptCore/jit/JITStubs.cpp +++ b/JavaScriptCore/jit/JITStubs.cpp @@ -45,6 +45,7 @@ #include "JSArray.h" #include "JSByteArray.h" #include "JSFunction.h" +#include "JSGlobalObjectFunctions.h" #include "JSNotAnObject.h" #include "JSPropertyNameIterator.h" #include "JSStaticScopeObject.h" @@ -229,15 +230,15 @@ SYMBOL_STRING(ctiOpThrowNotCaught) ":" "\n" #elif COMPILER(GCC) && CPU(ARM_THUMB2) -#define THUNK_RETURN_ADDRESS_OFFSET 0x3C -#define PRESERVED_RETURN_ADDRESS_OFFSET 0x40 -#define PRESERVED_R4_OFFSET 0x44 -#define PRESERVED_R5_OFFSET 0x48 -#define PRESERVED_R6_OFFSET 0x4C -#define REGISTER_FILE_OFFSET 0x50 -#define CALLFRAME_OFFSET 0x54 -#define EXCEPTION_OFFSET 0x58 -#define ENABLE_PROFILER_REFERENCE_OFFSET 0x60 +#define THUNK_RETURN_ADDRESS_OFFSET 0x40 +#define PRESERVED_RETURN_ADDRESS_OFFSET 0x44 +#define PRESERVED_R4_OFFSET 0x48 +#define PRESERVED_R5_OFFSET 0x4C +#define PRESERVED_R6_OFFSET 0x50 +#define REGISTER_FILE_OFFSET 0x54 +#define CALLFRAME_OFFSET 0x58 +#define EXCEPTION_OFFSET 0x5C +#define ENABLE_PROFILER_REFERENCE_OFFSET 0x64 #elif (COMPILER(GCC) || COMPILER(RVCT)) && CPU(ARM_TRADITIONAL) @@ -967,13 +968,13 @@ struct StackHack { ReturnAddressPtr savedReturnAddress; }; -#define STUB_INIT_STACK_FRAME(stackFrame) JITStackFrame& stackFrame = *reinterpret_cast<JITStackFrame*>(STUB_ARGS); StackHack stackHack(stackFrame) +#define STUB_INIT_STACK_FRAME(stackFrame) JITStackFrame& stackFrame = *reinterpret_cast_ptr<JITStackFrame*>(STUB_ARGS); StackHack stackHack(stackFrame) #define STUB_SET_RETURN_ADDRESS(returnAddress) stackHack.savedReturnAddress = ReturnAddressPtr(returnAddress) #define STUB_RETURN_ADDRESS stackHack.savedReturnAddress #else -#define STUB_INIT_STACK_FRAME(stackFrame) JITStackFrame& stackFrame = *reinterpret_cast<JITStackFrame*>(STUB_ARGS) +#define STUB_INIT_STACK_FRAME(stackFrame) JITStackFrame& stackFrame = *reinterpret_cast_ptr<JITStackFrame*>(STUB_ARGS) #define STUB_SET_RETURN_ADDRESS(returnAddress) *stackFrame.returnAddressSlot() = ReturnAddressPtr(returnAddress) #define STUB_RETURN_ADDRESS *stackFrame.returnAddressSlot() @@ -2814,16 +2815,16 @@ DEFINE_STUB_FUNCTION(int, op_eq) if (cell1->isString()) { if (src2.isInt32()) - return static_cast<JSString*>(cell1)->value(stackFrame.callFrame).toDouble() == src2.asInt32(); + return jsToNumber(static_cast<JSString*>(cell1)->value(stackFrame.callFrame)) == src2.asInt32(); if (src2.isDouble()) - return static_cast<JSString*>(cell1)->value(stackFrame.callFrame).toDouble() == src2.asDouble(); + return jsToNumber(static_cast<JSString*>(cell1)->value(stackFrame.callFrame)) == src2.asDouble(); if (src2.isTrue()) - return static_cast<JSString*>(cell1)->value(stackFrame.callFrame).toDouble() == 1.0; + return jsToNumber(static_cast<JSString*>(cell1)->value(stackFrame.callFrame)) == 1.0; if (src2.isFalse()) - return static_cast<JSString*>(cell1)->value(stackFrame.callFrame).toDouble() == 0.0; + return jsToNumber(static_cast<JSString*>(cell1)->value(stackFrame.callFrame)) == 0.0; JSCell* cell2 = asCell(src2); if (cell2->isString()) @@ -3362,7 +3363,7 @@ DEFINE_STUB_FUNCTION(void*, op_switch_char) void* result = codeBlock->characterSwitchJumpTable(tableIndex).ctiDefault.executableAddress(); if (scrutinee.isString()) { - UString::Rep* value = asString(scrutinee)->value(callFrame).rep(); + StringImpl* value = asString(scrutinee)->value(callFrame).impl(); if (value->length() == 1) result = codeBlock->characterSwitchJumpTable(tableIndex).ctiForValue(value->characters()[0]).executableAddress(); } @@ -3383,7 +3384,7 @@ DEFINE_STUB_FUNCTION(void*, op_switch_string) void* result = codeBlock->stringSwitchJumpTable(tableIndex).ctiDefault.executableAddress(); if (scrutinee.isString()) { - UString::Rep* value = asString(scrutinee)->value(callFrame).rep(); + StringImpl* value = asString(scrutinee)->value(callFrame).impl(); result = codeBlock->stringSwitchJumpTable(tableIndex).ctiForValue(value).executableAddress(); } diff --git a/JavaScriptCore/jit/JITStubs.h b/JavaScriptCore/jit/JITStubs.h index 94e319f..43f3d19 100644 --- a/JavaScriptCore/jit/JITStubs.h +++ b/JavaScriptCore/jit/JITStubs.h @@ -144,7 +144,7 @@ namespace JSC { #endif // COMPILER(MSVC) || (OS(WINDOWS) && COMPILER(GCC)) #elif CPU(ARM_THUMB2) struct JITStackFrame { - void* reserved; // Unused + JITStubArg reserved; // Unused JITStubArg args[6]; #if USE(JSVALUE32_64) void* padding[2]; // Maintain 16-byte stack alignment. diff --git a/JavaScriptCore/jsc.cpp b/JavaScriptCore/jsc.cpp index 03bc411..8b535a9 100644 --- a/JavaScriptCore/jsc.cpp +++ b/JavaScriptCore/jsc.cpp @@ -178,7 +178,7 @@ EncodedJSValue JSC_HOST_CALL functionPrint(ExecState* exec) if (i) putchar(' '); - printf("%s", exec->argument(i).toString(exec).UTF8String().data()); + printf("%s", exec->argument(i).toString(exec).utf8().data()); } putchar('\n'); @@ -188,7 +188,7 @@ EncodedJSValue JSC_HOST_CALL functionPrint(ExecState* exec) EncodedJSValue JSC_HOST_CALL functionDebug(ExecState* exec) { - fprintf(stderr, "--> %s\n", exec->argument(0).toString(exec).UTF8String().data()); + fprintf(stderr, "--> %s\n", exec->argument(0).toString(exec).utf8().data()); return JSValue::encode(jsUndefined()); } @@ -392,9 +392,9 @@ static bool runWithScripts(GlobalObject* globalObject, const Vector<Script>& scr success = success && completion.complType() != Throw; if (dump) { if (completion.complType() == Throw) - printf("Exception: %s\n", completion.value().toString(globalObject->globalExec()).ascii()); + printf("Exception: %s\n", completion.value().toString(globalObject->globalExec()).utf8().data()); else - printf("End: %s\n", completion.value().toString(globalObject->globalExec()).ascii()); + printf("End: %s\n", completion.value().toString(globalObject->globalExec()).utf8().data()); } globalData->stopSampling(); @@ -440,9 +440,9 @@ static void runInteractive(GlobalObject* globalObject) Completion completion = evaluate(globalObject->globalExec(), globalObject->globalScopeChain(), makeSource(line.data(), interpreterName)); #endif if (completion.complType() == Throw) - printf("Exception: %s\n", completion.value().toString(globalObject->globalExec()).ascii()); + printf("Exception: %s\n", completion.value().toString(globalObject->globalExec()).utf8().data()); else - printf("%s\n", completion.value().toString(globalObject->globalExec()).UTF8String().data()); + printf("%s\n", completion.value().toString(globalObject->globalExec()).utf8().data()); globalObject->globalExec()->clearException(); } @@ -532,9 +532,9 @@ int jscmain(int argc, char** argv, JSGlobalData* globalData) static bool fillBufferWithContentsOfFile(const UString& fileName, Vector<char>& buffer) { - FILE* f = fopen(fileName.UTF8String().data(), "r"); + FILE* f = fopen(fileName.utf8().data(), "r"); if (!f) { - fprintf(stderr, "Could not open file: %s\n", fileName.UTF8String().data()); + fprintf(stderr, "Could not open file: %s\n", fileName.utf8().data()); return false; } diff --git a/JavaScriptCore/jsc/CMakeLists.txt b/JavaScriptCore/jsc/CMakeLists.txt index 756ba92..1f529a5 100644 --- a/JavaScriptCore/jsc/CMakeLists.txt +++ b/JavaScriptCore/jsc/CMakeLists.txt @@ -15,5 +15,11 @@ WEBKIT_WRAP_SOURCELIST(${JSC_SOURCES}) INCLUDE_DIRECTORIES(./ ${JavaScriptCore_INCLUDE_DIRECTORIES}) ADD_EXECUTABLE(${JSC_EXECUTABLE_NAME} ${JSC_HEADERS} ${JSC_SOURCES}) TARGET_LINK_LIBRARIES(${JSC_EXECUTABLE_NAME} ${JSC_LIBRARIES}) -ADD_TARGET_PROPERTIES(${JSC_EXECUTABLE_NAME} LINK_FLAGS ${JSC_LINK_FLAGS}) -SET_TARGET_PROPERTIES(${JSC_EXECUTABLE_NAME} PROPERTIES VERSION ${PROJECT_VERSION}) + +IF (JSC_LINK_FLAGS) + ADD_TARGET_PROPERTIES(${JSC_EXECUTABLE_NAME} LINK_FLAGS "${JSC_LINK_FLAGS}") +ENDIF () + +IF (SHARED_CORE) + SET_TARGET_PROPERTIES(${JSC_EXECUTABLE_NAME} PROPERTIES VERSION ${PROJECT_VERSION}) +ENDIF () diff --git a/JavaScriptCore/parser/ASTBuilder.h b/JavaScriptCore/parser/ASTBuilder.h index f627756..dbf3c07 100644 --- a/JavaScriptCore/parser/ASTBuilder.h +++ b/JavaScriptCore/parser/ASTBuilder.h @@ -210,7 +210,7 @@ public: ExpressionNode* createRegex(const Identifier& pattern, const Identifier& flags, int start) { RegExpNode* node = new (m_globalData) RegExpNode(m_globalData, pattern, flags); - int size = pattern.size() + 2; // + 2 for the two /'s + int size = pattern.length() + 2; // + 2 for the two /'s setExceptionLocation(node, start, start + size, start + size); return node; } diff --git a/JavaScriptCore/parser/JSParser.cpp b/JavaScriptCore/parser/JSParser.cpp index 13013c7..3baceba 100644 --- a/JavaScriptCore/parser/JSParser.cpp +++ b/JavaScriptCore/parser/JSParser.cpp @@ -1186,11 +1186,11 @@ template <class TreeBuilder> TreeExpression JSParser::parseStrictObjectLiteral(T TreeProperty property = parseProperty<true>(context); failIfFalse(property); - typedef HashMap<RefPtr<UString::Rep>, unsigned, IdentifierRepHash> ObjectValidationMap; + typedef HashMap<RefPtr<StringImpl>, unsigned, IdentifierRepHash> ObjectValidationMap; ObjectValidationMap objectValidator; // Add the first property if (!m_syntaxAlreadyValidated) - objectValidator.add(context.getName(property).ustring().rep(), context.getType(property)); + objectValidator.add(context.getName(property).impl(), context.getType(property)); TreePropertyList propertyList = context.createPropertyList(property); TreePropertyList tail = propertyList; @@ -1202,7 +1202,7 @@ template <class TreeBuilder> TreeExpression JSParser::parseStrictObjectLiteral(T property = parseProperty<true>(context); failIfFalse(property); if (!m_syntaxAlreadyValidated) { - std::pair<ObjectValidationMap::iterator, bool> propertyEntryIter = objectValidator.add(context.getName(property).ustring().rep(), context.getType(property)); + std::pair<ObjectValidationMap::iterator, bool> propertyEntryIter = objectValidator.add(context.getName(property).impl(), context.getType(property)); if (!propertyEntryIter.second) { if ((context.getType(property) & propertyEntryIter.first->second) != PropertyNode::Constant) { // Can't have multiple getters or setters with the same name, nor can we define diff --git a/JavaScriptCore/parser/ParserArena.h b/JavaScriptCore/parser/ParserArena.h index eef8e93..7c1809e 100644 --- a/JavaScriptCore/parser/ParserArena.h +++ b/JavaScriptCore/parser/ParserArena.h @@ -55,7 +55,7 @@ namespace JSC { inline const Identifier& IdentifierArena::makeNumericIdentifier(JSGlobalData* globalData, double number) { - m_identifiers.append(Identifier(globalData, UString::from(number))); + m_identifiers.append(Identifier(globalData, UString::number(number))); return m_identifiers.last(); } diff --git a/JavaScriptCore/parser/SourceProvider.h b/JavaScriptCore/parser/SourceProvider.h index 5a57542..5ff1d14 100644 --- a/JavaScriptCore/parser/SourceProvider.h +++ b/JavaScriptCore/parser/SourceProvider.h @@ -67,10 +67,10 @@ namespace JSC { UString getRange(int start, int end) const { - return m_source.substr(start, end - start); + return m_source.substringSharingImpl(start, end - start); } - const UChar* data() const { return m_source.data(); } - int length() const { return m_source.size(); } + const UChar* data() const { return m_source.characters(); } + int length() const { return m_source.length(); } private: UStringSourceProvider(const UString& source, const UString& url) diff --git a/JavaScriptCore/pcre/pcre_compile.cpp b/JavaScriptCore/pcre/pcre_compile.cpp index ea6e44c..9d472d8 100644 --- a/JavaScriptCore/pcre/pcre_compile.cpp +++ b/JavaScriptCore/pcre/pcre_compile.cpp @@ -49,6 +49,7 @@ supporting internal functions that are not used by other modules. */ #include <wtf/ASCIICType.h> #include <wtf/FastMalloc.h> #include <wtf/FixedArray.h> +#include <wtf/StdLibExtras.h> using namespace WTF; @@ -2590,7 +2591,7 @@ JSRegExp* jsRegExpCompile(const UChar* pattern, int patternLength, size_t stringOffset = (size + sizeof(UChar) - 1) / sizeof(UChar) * sizeof(UChar); size = stringOffset + patternLength * sizeof(UChar); #endif - JSRegExp* re = reinterpret_cast<JSRegExp*>(new char[size]); + JSRegExp* re = reinterpret_cast_ptr<JSRegExp*>(new char[size]); if (!re) return returnError(ERR13, errorPtr); diff --git a/JavaScriptCore/pcre/pcre_exec.cpp b/JavaScriptCore/pcre/pcre_exec.cpp index 994ec57..f4899f2 100644 --- a/JavaScriptCore/pcre/pcre_exec.cpp +++ b/JavaScriptCore/pcre/pcre_exec.cpp @@ -88,7 +88,7 @@ public: void add(const JSRegExp*, double); private: - typedef HashMap<RefPtr<UString::Rep>, double> Map; + typedef HashMap<RefPtr<StringImpl>, double> Map; Map times; }; @@ -2143,7 +2143,7 @@ Histogram::~Histogram() size_t size = values.size(); printf("Regular Expressions, sorted by time spent evaluating them:\n"); for (size_t i = 0; i < size; ++i) - printf(" %f - %s\n", values[size - i - 1].second, values[size - i - 1].first.UTF8String().c_str()); + printf(" %f - %s\n", values[size - i - 1].second, values[size - i - 1].first.utf8().c_str()); } void Histogram::add(const JSRegExp* re, double elapsedTime) @@ -2157,7 +2157,7 @@ void Histogram::add(const JSRegExp* re, double elapsedTime) if (re->options & MatchAcrossMultipleLinesOption) string += " (multi-line)"; } - pair<Map::iterator, bool> result = times.add(string.rep(), elapsedTime); + pair<Map::iterator, bool> result = times.add(string.impl(), elapsedTime); if (!result.second) result.first->second += elapsedTime; } diff --git a/JavaScriptCore/profiler/CallIdentifier.h b/JavaScriptCore/profiler/CallIdentifier.h index f2d04fc..5487209 100644 --- a/JavaScriptCore/profiler/CallIdentifier.h +++ b/JavaScriptCore/profiler/CallIdentifier.h @@ -29,6 +29,8 @@ #include <runtime/UString.h> #include "FastAllocBase.h" +#include <wtf/text/CString.h> +#include <wtf/text/StringHash.h> namespace JSC { @@ -56,11 +58,11 @@ namespace JSC { static unsigned hash(const CallIdentifier& key) { unsigned hashCodes[3] = { - key.m_name.rep()->hash(), - key.m_url.rep()->hash(), + key.m_name.impl()->hash(), + key.m_url.impl()->hash(), key.m_lineNumber }; - return UString::Rep::computeHash(reinterpret_cast<char*>(hashCodes), sizeof(hashCodes)); + return StringImpl::computeHash(reinterpret_cast<char*>(hashCodes), sizeof(hashCodes)); } static bool equal(const CallIdentifier& a, const CallIdentifier& b) { return a == b; } @@ -71,7 +73,7 @@ namespace JSC { #ifndef NDEBUG operator const char*() const { return c_str(); } - const char* c_str() const { return m_name.UTF8String().data(); } + const char* c_str() const { return m_name.utf8().data(); } #endif }; diff --git a/JavaScriptCore/profiler/Profile.cpp b/JavaScriptCore/profiler/Profile.cpp index 126e6f6..bc239b3 100644 --- a/JavaScriptCore/profiler/Profile.cpp +++ b/JavaScriptCore/profiler/Profile.cpp @@ -106,7 +106,7 @@ void Profile::debugPrintData() const m_head->debugPrintData(0); } -typedef pair<UString::Rep*, unsigned> NameCountPair; +typedef pair<StringImpl*, unsigned> NameCountPair; static inline bool functionNameCountPairComparator(const NameCountPair& a, const NameCountPair& b) { @@ -127,7 +127,7 @@ void Profile::debugPrintDataSampleStyle() const std::sort(sortedFunctions.begin(), sortedFunctions.end(), functionNameCountPairComparator); for (NameCountPairVector::iterator it = sortedFunctions.begin(); it != sortedFunctions.end(); ++it) - printf(" %-12d%s\n", (*it).second, UString((*it).first).UTF8String().data()); + printf(" %-12d%s\n", (*it).second, UString((*it).first).utf8().data()); printf("\nSort by top of stack, same collapsed (when >= 5):\n"); } diff --git a/JavaScriptCore/profiler/ProfileGenerator.cpp b/JavaScriptCore/profiler/ProfileGenerator.cpp index bdfa27b..1d916ea 100644 --- a/JavaScriptCore/profiler/ProfileGenerator.cpp +++ b/JavaScriptCore/profiler/ProfileGenerator.cpp @@ -75,8 +75,8 @@ const UString& ProfileGenerator::title() const void ProfileGenerator::willExecute(const CallIdentifier& callIdentifier) { if (JAVASCRIPTCORE_PROFILE_WILL_EXECUTE_ENABLED()) { - CString name = callIdentifier.m_name.UTF8String(); - CString url = callIdentifier.m_url.UTF8String(); + CString name = callIdentifier.m_name.utf8(); + CString url = callIdentifier.m_url.utf8(); JAVASCRIPTCORE_PROFILE_WILL_EXECUTE(m_profileGroup, const_cast<char*>(name.data()), const_cast<char*>(url.data()), callIdentifier.m_lineNumber); } @@ -90,8 +90,8 @@ void ProfileGenerator::willExecute(const CallIdentifier& callIdentifier) void ProfileGenerator::didExecute(const CallIdentifier& callIdentifier) { if (JAVASCRIPTCORE_PROFILE_DID_EXECUTE_ENABLED()) { - CString name = callIdentifier.m_name.UTF8String(); - CString url = callIdentifier.m_url.UTF8String(); + CString name = callIdentifier.m_name.utf8(); + CString url = callIdentifier.m_url.utf8(); JAVASCRIPTCORE_PROFILE_DID_EXECUTE(m_profileGroup, const_cast<char*>(name.data()), const_cast<char*>(url.data()), callIdentifier.m_lineNumber); } diff --git a/JavaScriptCore/profiler/ProfileNode.cpp b/JavaScriptCore/profiler/ProfileNode.cpp index 1391f99..bfcfcbe 100644 --- a/JavaScriptCore/profiler/ProfileNode.cpp +++ b/JavaScriptCore/profiler/ProfileNode.cpp @@ -294,11 +294,11 @@ void ProfileNode::debugPrintData(int indentLevel) const printf(" "); printf("Function Name %s %d SelfTime %.3fms/%.3f%% TotalTime %.3fms/%.3f%% VSelf %.3fms VTotal %.3fms Visible %s Next Sibling %s\n", - functionName().UTF8String().data(), + functionName().utf8().data(), m_numberOfCalls, m_actualSelfTime, selfPercent(), m_actualTotalTime, totalPercent(), m_visibleSelfTime, m_visibleTotalTime, (m_visible ? "True" : "False"), - m_nextSibling ? m_nextSibling->functionName().UTF8String().data() : ""); + m_nextSibling ? m_nextSibling->functionName().utf8().data() : ""); ++indentLevel; @@ -313,13 +313,13 @@ double ProfileNode::debugPrintDataSampleStyle(int indentLevel, FunctionCallHashC printf(" "); // Print function names - const char* name = functionName().UTF8String().data(); + const char* name = functionName().utf8().data(); double sampleCount = m_actualTotalTime * 1000; if (indentLevel) { for (int i = 0; i < indentLevel; ++i) printf(" "); - countedFunctions.add(functionName().rep()); + countedFunctions.add(functionName().impl()); printf("%.0f %s\n", sampleCount ? sampleCount : 1, name); } else @@ -339,7 +339,7 @@ double ProfileNode::debugPrintDataSampleStyle(int indentLevel, FunctionCallHashC while (indentLevel--) printf(" "); - printf("%.0f %s\n", sampleCount - sumOfChildrensCount, functionName().UTF8String().data()); + printf("%.0f %s\n", sampleCount - sumOfChildrensCount, functionName().utf8().data()); } return m_actualTotalTime; diff --git a/JavaScriptCore/profiler/ProfileNode.h b/JavaScriptCore/profiler/ProfileNode.h index 2b5a936..eafeea6 100644 --- a/JavaScriptCore/profiler/ProfileNode.h +++ b/JavaScriptCore/profiler/ProfileNode.h @@ -30,16 +30,17 @@ #define ProfileNode_h #include "CallIdentifier.h" -#include <wtf/Vector.h> +#include <wtf/HashCountedSet.h> #include <wtf/RefCounted.h> #include <wtf/RefPtr.h> +#include <wtf/Vector.h> namespace JSC { class ProfileNode; typedef Vector<RefPtr<ProfileNode> >::const_iterator StackIterator; - typedef HashCountedSet<UString::Rep*> FunctionCallHashCount; + typedef HashCountedSet<StringImpl*> FunctionCallHashCount; class ProfileNode : public RefCounted<ProfileNode> { public: diff --git a/JavaScriptCore/profiler/Profiler.cpp b/JavaScriptCore/profiler/Profiler.cpp index 94e46a4..021ecff 100644 --- a/JavaScriptCore/profiler/Profiler.cpp +++ b/JavaScriptCore/profiler/Profiler.cpp @@ -39,6 +39,7 @@ #include "Profile.h" #include "ProfileGenerator.h" #include "ProfileNode.h" +#include "StringConcatenate.h" #include <stdio.h> namespace JSC { diff --git a/JavaScriptCore/runtime/Arguments.cpp b/JavaScriptCore/runtime/Arguments.cpp index bb30e3b..450dc7d 100644 --- a/JavaScriptCore/runtime/Arguments.cpp +++ b/JavaScriptCore/runtime/Arguments.cpp @@ -151,13 +151,13 @@ bool Arguments::getOwnPropertySlot(ExecState* exec, unsigned i, PropertySlot& sl return true; } - return JSObject::getOwnPropertySlot(exec, Identifier(exec, UString::from(i)), slot); + return JSObject::getOwnPropertySlot(exec, Identifier(exec, UString::number(i)), slot); } bool Arguments::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot) { bool isArrayIndex; - unsigned i = propertyName.toArrayIndex(&isArrayIndex); + unsigned i = propertyName.toArrayIndex(isArrayIndex); if (isArrayIndex && i < d->numArguments && (!d->deletedArguments || !d->deletedArguments[i])) { if (i < d->numParameters) { slot.setRegisterSlot(&d->registers[d->firstParameterIndex + i]); @@ -182,7 +182,7 @@ bool Arguments::getOwnPropertySlot(ExecState* exec, const Identifier& propertyNa bool Arguments::getOwnPropertyDescriptor(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor) { bool isArrayIndex; - unsigned i = propertyName.toArrayIndex(&isArrayIndex); + unsigned i = propertyName.toArrayIndex(isArrayIndex); if (isArrayIndex && i < d->numArguments && (!d->deletedArguments || !d->deletedArguments[i])) { if (i < d->numParameters) { descriptor.setDescriptor(d->registers[d->firstParameterIndex + i].jsValue(), DontEnum); @@ -209,7 +209,7 @@ void Arguments::getOwnPropertyNames(ExecState* exec, PropertyNameArray& property if (mode == IncludeDontEnumProperties) { for (unsigned i = 0; i < d->numArguments; ++i) { if (!d->deletedArguments || !d->deletedArguments[i]) - propertyNames.add(Identifier(exec, UString::from(i))); + propertyNames.add(Identifier(exec, UString::number(i))); } propertyNames.add(exec->propertyNames().callee); propertyNames.add(exec->propertyNames().length); @@ -227,13 +227,13 @@ void Arguments::put(ExecState* exec, unsigned i, JSValue value, PutPropertySlot& return; } - JSObject::put(exec, Identifier(exec, UString::from(i)), value, slot); + JSObject::put(exec, Identifier(exec, UString::number(i)), value, slot); } void Arguments::put(ExecState* exec, const Identifier& propertyName, JSValue value, PutPropertySlot& slot) { bool isArrayIndex; - unsigned i = propertyName.toArrayIndex(&isArrayIndex); + unsigned i = propertyName.toArrayIndex(isArrayIndex); if (isArrayIndex && i < d->numArguments && (!d->deletedArguments || !d->deletedArguments[i])) { if (i < d->numParameters) d->registers[d->firstParameterIndex + i] = JSValue(value); @@ -270,13 +270,13 @@ bool Arguments::deleteProperty(ExecState* exec, unsigned i) } } - return JSObject::deleteProperty(exec, Identifier(exec, UString::from(i))); + return JSObject::deleteProperty(exec, Identifier(exec, UString::number(i))); } bool Arguments::deleteProperty(ExecState* exec, const Identifier& propertyName) { bool isArrayIndex; - unsigned i = propertyName.toArrayIndex(&isArrayIndex); + unsigned i = propertyName.toArrayIndex(isArrayIndex); if (isArrayIndex && i < d->numArguments) { if (!d->deletedArguments) { d->deletedArguments.set(new bool[d->numArguments]); diff --git a/JavaScriptCore/runtime/ArrayPrototype.cpp b/JavaScriptCore/runtime/ArrayPrototype.cpp index fa6eb99..e49ca28 100644 --- a/JavaScriptCore/runtime/ArrayPrototype.cpp +++ b/JavaScriptCore/runtime/ArrayPrototype.cpp @@ -166,7 +166,7 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncToString(ExecState* exec) unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec); unsigned totalSize = length ? length - 1 : 0; - Vector<RefPtr<UString::Rep>, 256> strBuffer(length); + Vector<RefPtr<StringImpl>, 256> strBuffer(length); for (unsigned k = 0; k < length; k++) { JSValue element; if (isRealArray && thisObj->canGetIndex(k)) @@ -178,8 +178,8 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncToString(ExecState* exec) continue; UString str = element.toString(exec); - strBuffer[k] = str.rep(); - totalSize += str.size(); + strBuffer[k] = str.impl(); + totalSize += str.length(); if (!strBuffer.data()) { throwOutOfMemoryError(exec); @@ -199,7 +199,7 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncToString(ExecState* exec) for (unsigned i = 0; i < length; i++) { if (i) buffer.append(','); - if (RefPtr<UString::Rep> rep = strBuffer[i]) + if (RefPtr<StringImpl> rep = strBuffer[i]) buffer.append(rep->characters(), rep->length()); } ASSERT(buffer.size() == totalSize); diff --git a/JavaScriptCore/runtime/Collector.h b/JavaScriptCore/runtime/Collector.h index 38c178b..05d5c10 100644 --- a/JavaScriptCore/runtime/Collector.h +++ b/JavaScriptCore/runtime/Collector.h @@ -130,6 +130,7 @@ namespace JSC { void registerThread(); // Only needs to be called by clients that can use the same heap from multiple threads. static bool isCellMarked(const JSCell*); + static bool checkMarkCell(const JSCell*); static void markCell(JSCell*); WeakGCHandle* addWeakGCHandle(JSCell*); @@ -226,6 +227,14 @@ namespace JSC { FixedArray<uint32_t, BITMAP_WORDS> bits; bool get(size_t n) const { return !!(bits[n >> 5] & (1 << (n & 0x1F))); } void set(size_t n) { bits[n >> 5] |= (1 << (n & 0x1F)); } + bool getset(size_t n) + { + unsigned i = (1 << (n & 0x1F)); + uint32_t& b = bits[n >> 5]; + bool r = !!(b & i); + b |= i; + return r; + } void clear(size_t n) { bits[n >> 5] &= ~(1 << (n & 0x1F)); } void clearAll() { memset(bits.data(), 0, sizeof(bits)); } ALWAYS_INLINE void advanceToNextPossibleFreeCell(size_t& startCell) @@ -288,6 +297,11 @@ namespace JSC { return cellBlock(cell)->marked.get(cellOffset(cell)); } + inline bool Heap::checkMarkCell(const JSCell* cell) + { + return cellBlock(cell)->marked.getset(cellOffset(cell)); + } + inline void Heap::markCell(JSCell* cell) { cellBlock(cell)->marked.set(cellOffset(cell)); diff --git a/JavaScriptCore/runtime/DateConversion.cpp b/JavaScriptCore/runtime/DateConversion.cpp index 70dbaa0..7eb82e4 100644 --- a/JavaScriptCore/runtime/DateConversion.cpp +++ b/JavaScriptCore/runtime/DateConversion.cpp @@ -47,6 +47,7 @@ #include "UString.h" #include <wtf/DateMath.h> #include <wtf/StringExtras.h> +#include <wtf/text/CString.h> using namespace WTF; @@ -56,7 +57,7 @@ double parseDate(ExecState* exec, const UString &date) { if (date == exec->globalData().cachedDateString) return exec->globalData().cachedDateStringValue; - double value = parseDateFromNullTerminatedCharacters(exec, date.UTF8String().data()); + double value = parseDateFromNullTerminatedCharacters(exec, date.utf8().data()); exec->globalData().cachedDateString = date; exec->globalData().cachedDateStringValue = value; return value; diff --git a/JavaScriptCore/runtime/DatePrototype.cpp b/JavaScriptCore/runtime/DatePrototype.cpp index 9dec33b..249f427 100644 --- a/JavaScriptCore/runtime/DatePrototype.cpp +++ b/JavaScriptCore/runtime/DatePrototype.cpp @@ -170,7 +170,7 @@ static JSCell* formatLocaleDate(ExecState* exec, DateInstance*, double timeInMil CFRelease(locale); if (useCustomFormat) { - CFStringRef customFormatCFString = CFStringCreateWithCharacters(0, customFormatString.data(), customFormatString.size()); + CFStringRef customFormatCFString = CFStringCreateWithCharacters(0, customFormatString.characters(), customFormatString.length()); CFDateFormatterSetFormat(formatter, customFormatCFString); CFRelease(customFormatCFString); } diff --git a/JavaScriptCore/runtime/ExceptionHelpers.cpp b/JavaScriptCore/runtime/ExceptionHelpers.cpp index 3e0b70c..871b2d5 100644 --- a/JavaScriptCore/runtime/ExceptionHelpers.cpp +++ b/JavaScriptCore/runtime/ExceptionHelpers.cpp @@ -36,6 +36,7 @@ #include "JSNotAnObject.h" #include "Interpreter.h" #include "Nodes.h" +#include "StringConcatenate.h" namespace JSC { diff --git a/JavaScriptCore/runtime/FunctionConstructor.cpp b/JavaScriptCore/runtime/FunctionConstructor.cpp index a036eef..f72a273 100644 --- a/JavaScriptCore/runtime/FunctionConstructor.cpp +++ b/JavaScriptCore/runtime/FunctionConstructor.cpp @@ -31,6 +31,7 @@ #include "Nodes.h" #include "Parser.h" #include "StringBuilder.h" +#include "StringConcatenate.h" namespace JSC { diff --git a/JavaScriptCore/runtime/FunctionPrototype.cpp b/JavaScriptCore/runtime/FunctionPrototype.cpp index fb2f627..c740624 100644 --- a/JavaScriptCore/runtime/FunctionPrototype.cpp +++ b/JavaScriptCore/runtime/FunctionPrototype.cpp @@ -71,13 +71,13 @@ CallType FunctionPrototype::getCallData(CallData& callData) static inline void insertSemicolonIfNeeded(UString& functionBody) { ASSERT(functionBody[0] == '{'); - ASSERT(functionBody[functionBody.size() - 1] == '}'); + ASSERT(functionBody[functionBody.length() - 1] == '}'); - for (size_t i = functionBody.size() - 2; i > 0; --i) { + for (size_t i = functionBody.length() - 2; i > 0; --i) { UChar ch = functionBody[i]; if (!Lexer::isWhiteSpace(ch) && !Lexer::isLineTerminator(ch)) { if (ch != ';' && ch != '}') - functionBody = makeString(functionBody.substr(0, i + 1), ";", functionBody.substr(i + 1, functionBody.size() - (i + 1))); + functionBody = makeString(functionBody.substringSharingImpl(0, i + 1), ";", functionBody.substringSharingImpl(i + 1, functionBody.length() - (i + 1))); return; } } diff --git a/JavaScriptCore/runtime/Identifier.cpp b/JavaScriptCore/runtime/Identifier.cpp index 46772d0..d375eff 100644 --- a/JavaScriptCore/runtime/Identifier.cpp +++ b/JavaScriptCore/runtime/Identifier.cpp @@ -65,7 +65,7 @@ void deleteIdentifierTable(IdentifierTable* table) delete table; } -bool Identifier::equal(const UString::Rep* r, const char* s) +bool Identifier::equal(const StringImpl* r, const char* s) { int length = r->length(); const UChar* d = r->characters(); @@ -75,7 +75,7 @@ bool Identifier::equal(const UString::Rep* r, const char* s) return s[length] == 0; } -bool Identifier::equal(const UString::Rep* r, const UChar* s, unsigned length) +bool Identifier::equal(const StringImpl* r, const UChar* s, unsigned length) { if (r->length() != length) return false; @@ -89,19 +89,19 @@ bool Identifier::equal(const UString::Rep* r, const UChar* s, unsigned length) struct IdentifierCStringTranslator { static unsigned hash(const char* c) { - return UString::Rep::computeHash(c); + return StringImpl::computeHash(c); } - static bool equal(UString::Rep* r, const char* s) + static bool equal(StringImpl* r, const char* s) { return Identifier::equal(r, s); } - static void translate(UString::Rep*& location, const char* c, unsigned hash) + static void translate(StringImpl*& location, const char* c, unsigned hash) { size_t length = strlen(c); UChar* d; - UString::Rep* r = UString::Rep::createUninitialized(length, d).releaseRef(); + StringImpl* r = StringImpl::createUninitialized(length, d).releaseRef(); for (size_t i = 0; i != length; i++) d[i] = static_cast<unsigned char>(c[i]); // use unsigned char to zero-extend instead of sign-extend r->setHash(hash); @@ -109,12 +109,12 @@ struct IdentifierCStringTranslator { } }; -PassRefPtr<UString::Rep> Identifier::add(JSGlobalData* globalData, const char* c) +PassRefPtr<StringImpl> Identifier::add(JSGlobalData* globalData, const char* c) { if (!c) - return UString::null().rep(); + return 0; if (!c[0]) - return UString::Rep::empty(); + return StringImpl::empty(); if (!c[1]) return add(globalData, globalData->smallStrings.singleCharacterStringRep(static_cast<unsigned char>(c[0]))); @@ -125,18 +125,18 @@ PassRefPtr<UString::Rep> Identifier::add(JSGlobalData* globalData, const char* c if (iter != literalIdentifierTable.end()) return iter->second; - pair<HashSet<UString::Rep*>::iterator, bool> addResult = identifierTable.add<const char*, IdentifierCStringTranslator>(c); + pair<HashSet<StringImpl*>::iterator, bool> addResult = identifierTable.add<const char*, IdentifierCStringTranslator>(c); // If the string is newly-translated, then we need to adopt it. // The boolean in the pair tells us if that is so. - RefPtr<UString::Rep> addedString = addResult.second ? adoptRef(*addResult.first) : *addResult.first; + RefPtr<StringImpl> addedString = addResult.second ? adoptRef(*addResult.first) : *addResult.first; literalIdentifierTable.add(c, addedString.get()); return addedString.release(); } -PassRefPtr<UString::Rep> Identifier::add(ExecState* exec, const char* c) +PassRefPtr<StringImpl> Identifier::add(ExecState* exec, const char* c) { return add(&exec->globalData(), c); } @@ -149,18 +149,18 @@ struct UCharBuffer { struct IdentifierUCharBufferTranslator { static unsigned hash(const UCharBuffer& buf) { - return UString::Rep::computeHash(buf.s, buf.length); + return StringImpl::computeHash(buf.s, buf.length); } - static bool equal(UString::Rep* str, const UCharBuffer& buf) + static bool equal(StringImpl* str, const UCharBuffer& buf) { return Identifier::equal(str, buf.s, buf.length); } - static void translate(UString::Rep*& location, const UCharBuffer& buf, unsigned hash) + static void translate(StringImpl*& location, const UCharBuffer& buf, unsigned hash) { UChar* d; - UString::Rep* r = UString::Rep::createUninitialized(buf.length, d).releaseRef(); + StringImpl* r = StringImpl::createUninitialized(buf.length, d).releaseRef(); for (unsigned i = 0; i != buf.length; i++) d[i] = buf.s[i]; r->setHash(hash); @@ -168,7 +168,50 @@ struct IdentifierUCharBufferTranslator { } }; -PassRefPtr<UString::Rep> Identifier::add(JSGlobalData* globalData, const UChar* s, int length) +uint32_t Identifier::toUInt32(const UString& string, bool& ok) +{ + ok = false; + + unsigned length = string.length(); + const UChar* characters = string.characters(); + + // An empty string is not a number. + if (!length) + return 0; + + // Get the first character, turning it into a digit. + uint32_t value = characters[0] - '0'; + if (value > 9) + return 0; + + // Check for leading zeros. If the first characher is 0, then the + // length of the string must be one - e.g. "042" is not equal to "42". + if (!value && length > 1) + return 0; + + while (--length) { + // Multiply value by 10, checking for overflow out of 32 bits. + if (value > 0xFFFFFFFFU / 10) + return 0; + value *= 10; + + // Get the next character, turning it into a digit. + uint32_t newValue = *(++characters) - '0'; + if (newValue > 9) + return 0; + + // Add in the old value, checking for overflow out of 32 bits. + newValue += value; + if (newValue < value) + return 0; + value = newValue; + } + + ok = true; + return value; +} + +PassRefPtr<StringImpl> Identifier::add(JSGlobalData* globalData, const UChar* s, int length) { if (length == 1) { UChar c = s[0]; @@ -176,21 +219,21 @@ PassRefPtr<UString::Rep> Identifier::add(JSGlobalData* globalData, const UChar* return add(globalData, globalData->smallStrings.singleCharacterStringRep(c)); } if (!length) - return UString::Rep::empty(); + return StringImpl::empty(); UCharBuffer buf = {s, length}; - pair<HashSet<UString::Rep*>::iterator, bool> addResult = globalData->identifierTable->add<UCharBuffer, IdentifierUCharBufferTranslator>(buf); + pair<HashSet<StringImpl*>::iterator, bool> addResult = globalData->identifierTable->add<UCharBuffer, IdentifierUCharBufferTranslator>(buf); // If the string is newly-translated, then we need to adopt it. // The boolean in the pair tells us if that is so. return addResult.second ? adoptRef(*addResult.first) : *addResult.first; } -PassRefPtr<UString::Rep> Identifier::add(ExecState* exec, const UChar* s, int length) +PassRefPtr<StringImpl> Identifier::add(ExecState* exec, const UChar* s, int length) { return add(&exec->globalData(), s, length); } -PassRefPtr<UString::Rep> Identifier::addSlowCase(JSGlobalData* globalData, UString::Rep* r) +PassRefPtr<StringImpl> Identifier::addSlowCase(JSGlobalData* globalData, StringImpl* r) { ASSERT(!r->isIdentifier()); // The empty & null strings are static singletons, and static strings are handled @@ -208,7 +251,7 @@ PassRefPtr<UString::Rep> Identifier::addSlowCase(JSGlobalData* globalData, UStri return *globalData->identifierTable->add(r).first; } -PassRefPtr<UString::Rep> Identifier::addSlowCase(ExecState* exec, UString::Rep* r) +PassRefPtr<StringImpl> Identifier::addSlowCase(ExecState* exec, StringImpl* r) { return addSlowCase(&exec->globalData(), r); } diff --git a/JavaScriptCore/runtime/Identifier.h b/JavaScriptCore/runtime/Identifier.h index 2db0716..3a8aed7 100644 --- a/JavaScriptCore/runtime/Identifier.h +++ b/JavaScriptCore/runtime/Identifier.h @@ -24,6 +24,7 @@ #include "JSGlobalData.h" #include "ThreadSpecific.h" #include "UString.h" +#include <wtf/text/CString.h> namespace JSC { @@ -34,25 +35,23 @@ namespace JSC { public: Identifier() { } - Identifier(ExecState* exec, const char* s) : _ustring(add(exec, s)) { } // Only to be used with string literals. - Identifier(ExecState* exec, const UChar* s, int length) : _ustring(add(exec, s, length)) { } - Identifier(ExecState* exec, UString::Rep* rep) : _ustring(add(exec, rep)) { } - Identifier(ExecState* exec, const UString& s) : _ustring(add(exec, s.rep())) { } + Identifier(ExecState* exec, const char* s) : m_string(add(exec, s)) { } // Only to be used with string literals. + Identifier(ExecState* exec, const UChar* s, int length) : m_string(add(exec, s, length)) { } + Identifier(ExecState* exec, StringImpl* rep) : m_string(add(exec, rep)) { } + Identifier(ExecState* exec, const UString& s) : m_string(add(exec, s.impl())) { } - Identifier(JSGlobalData* globalData, const char* s) : _ustring(add(globalData, s)) { } // Only to be used with string literals. - Identifier(JSGlobalData* globalData, const UChar* s, int length) : _ustring(add(globalData, s, length)) { } - Identifier(JSGlobalData* globalData, UString::Rep* rep) : _ustring(add(globalData, rep)) { } - Identifier(JSGlobalData* globalData, const UString& s) : _ustring(add(globalData, s.rep())) { } + Identifier(JSGlobalData* globalData, const char* s) : m_string(add(globalData, s)) { } // Only to be used with string literals. + Identifier(JSGlobalData* globalData, const UChar* s, int length) : m_string(add(globalData, s, length)) { } + Identifier(JSGlobalData* globalData, StringImpl* rep) : m_string(add(globalData, rep)) { } + Identifier(JSGlobalData* globalData, const UString& s) : m_string(add(globalData, s.impl())) { } - // Special constructor for cases where we overwrite an object in place. - Identifier(PlacementNewAdoptType) : _ustring(PlacementNewAdopt) { } + const UString& ustring() const { return m_string; } + StringImpl* impl() const { return m_string.impl(); } - const UString& ustring() const { return _ustring; } + const UChar* characters() const { return m_string.characters(); } + int length() const { return m_string.length(); } - const UChar* data() const { return _ustring.data(); } - int size() const { return _ustring.size(); } - - const char* ascii() const { return _ustring.ascii(); } + CString ascii() const { return m_string.ascii(); } static Identifier from(ExecState* exec, unsigned y); static Identifier from(ExecState* exec, int y); @@ -60,15 +59,13 @@ namespace JSC { static Identifier from(JSGlobalData*, unsigned y); static Identifier from(JSGlobalData*, int y); static Identifier from(JSGlobalData*, double y); - - bool isNull() const { return _ustring.isNull(); } - bool isEmpty() const { return _ustring.isEmpty(); } - - uint32_t toUInt32(bool* ok) const { return _ustring.toUInt32(ok); } - uint32_t toUInt32(bool* ok, bool tolerateEmptyString) const { return _ustring.toUInt32(ok, tolerateEmptyString); }; - uint32_t toStrictUInt32(bool* ok) const { return _ustring.toStrictUInt32(ok); } - unsigned toArrayIndex(bool* ok) const { return _ustring.toArrayIndex(ok); } - double toDouble() const { return _ustring.toDouble(); } + + static uint32_t toUInt32(const UString&, bool& ok); + uint32_t toUInt32(bool& ok) const { return toUInt32(m_string, ok); } + unsigned toArrayIndex(bool& ok) const; + + bool isNull() const { return m_string.isNull(); } + bool isEmpty() const { return m_string.isEmpty(); } friend bool operator==(const Identifier&, const Identifier&); friend bool operator!=(const Identifier&, const Identifier&); @@ -76,23 +73,23 @@ namespace JSC { friend bool operator==(const Identifier&, const char*); friend bool operator!=(const Identifier&, const char*); - static bool equal(const UString::Rep*, const char*); - static bool equal(const UString::Rep*, const UChar*, unsigned length); - static bool equal(const UString::Rep* a, const UString::Rep* b) { return ::equal(a, b); } + static bool equal(const StringImpl*, const char*); + static bool equal(const StringImpl*, const UChar*, unsigned length); + static bool equal(const StringImpl* a, const StringImpl* b) { return ::equal(a, b); } - static PassRefPtr<UString::Rep> add(ExecState*, const char*); // Only to be used with string literals. - static PassRefPtr<UString::Rep> add(JSGlobalData*, const char*); // Only to be used with string literals. + static PassRefPtr<StringImpl> add(ExecState*, const char*); // Only to be used with string literals. + static PassRefPtr<StringImpl> add(JSGlobalData*, const char*); // Only to be used with string literals. private: - UString _ustring; + UString m_string; - static bool equal(const Identifier& a, const Identifier& b) { return a._ustring.rep() == b._ustring.rep(); } - static bool equal(const Identifier& a, const char* b) { return equal(a._ustring.rep(), b); } + static bool equal(const Identifier& a, const Identifier& b) { return a.m_string.impl() == b.m_string.impl(); } + static bool equal(const Identifier& a, const char* b) { return equal(a.m_string.impl(), b); } - static PassRefPtr<UString::Rep> add(ExecState*, const UChar*, int length); - static PassRefPtr<UString::Rep> add(JSGlobalData*, const UChar*, int length); + static PassRefPtr<StringImpl> add(ExecState*, const UChar*, int length); + static PassRefPtr<StringImpl> add(JSGlobalData*, const UChar*, int length); - static PassRefPtr<UString::Rep> add(ExecState* exec, UString::Rep* r) + static PassRefPtr<StringImpl> add(ExecState* exec, StringImpl* r) { #ifndef NDEBUG checkCurrentIdentifierTable(exec); @@ -101,7 +98,7 @@ namespace JSC { return r; return addSlowCase(exec, r); } - static PassRefPtr<UString::Rep> add(JSGlobalData* globalData, UString::Rep* r) + static PassRefPtr<StringImpl> add(JSGlobalData* globalData, StringImpl* r) { #ifndef NDEBUG checkCurrentIdentifierTable(globalData); @@ -111,8 +108,8 @@ namespace JSC { return addSlowCase(globalData, r); } - static PassRefPtr<UString::Rep> addSlowCase(ExecState*, UString::Rep* r); - static PassRefPtr<UString::Rep> addSlowCase(JSGlobalData*, UString::Rep* r); + static PassRefPtr<StringImpl> addSlowCase(ExecState*, StringImpl* r); + static PassRefPtr<StringImpl> addSlowCase(JSGlobalData*, StringImpl* r); static void checkCurrentIdentifierTable(ExecState*); static void checkCurrentIdentifierTable(JSGlobalData*); @@ -141,6 +138,11 @@ namespace JSC { IdentifierTable* createIdentifierTable(); void deleteIdentifierTable(IdentifierTable*); + struct IdentifierRepHash : PtrHash<RefPtr<StringImpl> > { + static unsigned hash(const RefPtr<StringImpl>& key) { return key->existingHash(); } + static unsigned hash(StringImpl* key) { return key->existingHash(); } + }; + } // namespace JSC #endif // Identifier_h diff --git a/JavaScriptCore/runtime/InitializeThreading.cpp b/JavaScriptCore/runtime/InitializeThreading.cpp index 51d43ee..33e8e68 100644 --- a/JavaScriptCore/runtime/InitializeThreading.cpp +++ b/JavaScriptCore/runtime/InitializeThreading.cpp @@ -48,9 +48,12 @@ static pthread_once_t initializeThreadingKeyOnce = PTHREAD_ONCE_INIT; static void initializeThreadingOnce() { + // StringImpl::empty() does not construct its static string in a threadsafe fashion, + // so ensure it has been initialized from here. + StringImpl::empty(); + WTF::initializeThreading(); wtfThreadData(); - initializeUString(); JSGlobalData::storeVPtrs(); #if ENABLE(JSC_MULTIPLE_THREADS) s_dtoaP5Mutex = new Mutex; diff --git a/JavaScriptCore/runtime/InternalFunction.cpp b/JavaScriptCore/runtime/InternalFunction.cpp index f774993..0a8d9de 100644 --- a/JavaScriptCore/runtime/InternalFunction.cpp +++ b/JavaScriptCore/runtime/InternalFunction.cpp @@ -61,7 +61,7 @@ const UString InternalFunction::displayName(ExecState* exec) if (displayName && isJSString(&exec->globalData(), displayName)) return asString(displayName)->tryGetValue(); - return UString::null(); + return UString(); } const UString InternalFunction::calculatedDisplayName(ExecState* exec) diff --git a/JavaScriptCore/runtime/JSArray.cpp b/JavaScriptCore/runtime/JSArray.cpp index 0db0a63..9c3570b 100644 --- a/JavaScriptCore/runtime/JSArray.cpp +++ b/JavaScriptCore/runtime/JSArray.cpp @@ -273,7 +273,7 @@ bool JSArray::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName } bool isArrayIndex; - unsigned i = propertyName.toArrayIndex(&isArrayIndex); + unsigned i = propertyName.toArrayIndex(isArrayIndex); if (isArrayIndex) return JSArray::getOwnPropertySlot(exec, i, slot); @@ -290,7 +290,7 @@ bool JSArray::getOwnPropertyDescriptor(ExecState* exec, const Identifier& proper ArrayStorage* storage = m_storage; bool isArrayIndex; - unsigned i = propertyName.toArrayIndex(&isArrayIndex); + unsigned i = propertyName.toArrayIndex(isArrayIndex); if (isArrayIndex) { if (i >= storage->m_length) return false; @@ -317,7 +317,7 @@ bool JSArray::getOwnPropertyDescriptor(ExecState* exec, const Identifier& proper void JSArray::put(ExecState* exec, const Identifier& propertyName, JSValue value, PutPropertySlot& slot) { bool isArrayIndex; - unsigned i = propertyName.toArrayIndex(&isArrayIndex); + unsigned i = propertyName.toArrayIndex(isArrayIndex); if (isArrayIndex) { put(exec, i, value); return; @@ -441,7 +441,7 @@ NEVER_INLINE void JSArray::putSlowCase(ExecState* exec, unsigned i, JSValue valu return; } - m_storage = reinterpret_cast<ArrayStorage*>(static_cast<char*>(baseStorage) + m_indexBias * sizeof(JSValue)); + m_storage = reinterpret_cast_ptr<ArrayStorage*>(static_cast<char*>(baseStorage) + m_indexBias * sizeof(JSValue)); m_storage->m_allocBase = baseStorage; storage = m_storage; @@ -475,7 +475,7 @@ NEVER_INLINE void JSArray::putSlowCase(ExecState* exec, unsigned i, JSValue valu bool JSArray::deleteProperty(ExecState* exec, const Identifier& propertyName) { bool isArrayIndex; - unsigned i = propertyName.toArrayIndex(&isArrayIndex); + unsigned i = propertyName.toArrayIndex(isArrayIndex); if (isArrayIndex) return deleteProperty(exec, i); @@ -591,7 +591,7 @@ bool JSArray::increaseVectorLength(unsigned newLength) if (!tryFastRealloc(baseStorage, storageSize(newVectorLength + m_indexBias)).getValue(baseStorage)) return false; - storage = m_storage = reinterpret_cast<ArrayStorage*>(static_cast<char*>(baseStorage) + m_indexBias * sizeof(JSValue)); + storage = m_storage = reinterpret_cast_ptr<ArrayStorage*>(static_cast<char*>(baseStorage) + m_indexBias * sizeof(JSValue)); m_storage->m_allocBase = baseStorage; JSValue* vector = storage->m_vector; @@ -623,7 +623,7 @@ bool JSArray::increaseVectorPrefixLength(unsigned newLength) m_indexBias += newVectorLength - newLength; - m_storage = reinterpret_cast<ArrayStorage*>(static_cast<char*>(newBaseStorage) + m_indexBias * sizeof(JSValue)); + m_storage = reinterpret_cast_ptr<ArrayStorage*>(static_cast<char*>(newBaseStorage) + m_indexBias * sizeof(JSValue)); memcpy(m_storage, storage, storageSize(0)); memcpy(&m_storage->m_vector[newLength - m_vectorLength], &storage->m_vector[0], vectorLength * sizeof(JSValue)); @@ -802,7 +802,7 @@ void JSArray::shiftCount(ExecState* exec, int count) if (m_vectorLength) { char* newBaseStorage = reinterpret_cast<char*>(storage) + count * sizeof(JSValue); memmove(newBaseStorage, storage, storageSize(0)); - m_storage = reinterpret_cast<ArrayStorage*>(newBaseStorage); + m_storage = reinterpret_cast_ptr<ArrayStorage*>(newBaseStorage); m_indexBias += count; } @@ -839,7 +839,7 @@ void JSArray::unshiftCount(ExecState* exec, int count) m_indexBias -= count; char* newBaseStorage = reinterpret_cast<char*>(storage) - count * sizeof(JSValue); memmove(newBaseStorage, storage, storageSize(0)); - m_storage = reinterpret_cast<ArrayStorage*>(newBaseStorage); + m_storage = reinterpret_cast_ptr<ArrayStorage*>(newBaseStorage); m_vectorLength += count; } else if (!increaseVectorPrefixLength(m_vectorLength + count)) { throwOutOfMemoryError(exec); diff --git a/JavaScriptCore/runtime/JSArray.h b/JavaScriptCore/runtime/JSArray.h index f718d7e..9e155d8 100644 --- a/JavaScriptCore/runtime/JSArray.h +++ b/JavaScriptCore/runtime/JSArray.h @@ -236,7 +236,7 @@ namespace JSC { current.m_values++; JSCell* cell; - if (!value || !value.isCell() || Heap::isCellMarked(cell = value.asCell())) { + if (!value || !value.isCell() || Heap::checkMarkCell(cell = value.asCell())) { if (current.m_values == end) { m_markSets.removeLast(); continue; @@ -244,7 +244,6 @@ namespace JSC { goto findNextUnmarkedNullValue; } - Heap::markCell(cell); if (cell->structure()->typeInfo().type() < CompoundType) { if (current.m_values == end) { m_markSets.removeLast(); @@ -262,7 +261,17 @@ namespace JSC { markChildren(m_values.removeLast()); } } - + + // Rule from ECMA 15.2 about what an array index is. + // Must exactly match string form of an unsigned integer, and be less than 2^32 - 1. + inline unsigned Identifier::toArrayIndex(bool& ok) const + { + unsigned i = toUInt32(ok); + if (ok && i >= 0xFFFFFFFFU) + ok = false; + return i; + } + } // namespace JSC #endif // JSArray_h diff --git a/JavaScriptCore/runtime/JSByteArray.cpp b/JavaScriptCore/runtime/JSByteArray.cpp index 803a08c..88519cf 100644 --- a/JavaScriptCore/runtime/JSByteArray.cpp +++ b/JavaScriptCore/runtime/JSByteArray.cpp @@ -60,7 +60,7 @@ PassRefPtr<Structure> JSByteArray::createStructure(JSValue prototype) bool JSByteArray::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot) { bool ok; - unsigned index = propertyName.toUInt32(&ok, false); + unsigned index = propertyName.toUInt32(ok); if (ok && canAccessIndex(index)) { slot.setValue(getIndex(exec, index)); return true; @@ -71,7 +71,7 @@ bool JSByteArray::getOwnPropertySlot(ExecState* exec, const Identifier& property bool JSByteArray::getOwnPropertyDescriptor(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor) { bool ok; - unsigned index = propertyName.toUInt32(&ok, false); + unsigned index = propertyName.toUInt32(ok); if (ok && canAccessIndex(index)) { descriptor.setDescriptor(getIndex(exec, index), DontDelete); return true; @@ -91,7 +91,7 @@ bool JSByteArray::getOwnPropertySlot(ExecState* exec, unsigned propertyName, Pro void JSByteArray::put(ExecState* exec, const Identifier& propertyName, JSValue value, PutPropertySlot& slot) { bool ok; - unsigned index = propertyName.toUInt32(&ok, false); + unsigned index = propertyName.toUInt32(ok); if (ok) { setIndex(exec, index, value); return; diff --git a/JavaScriptCore/runtime/JSCell.h b/JavaScriptCore/runtime/JSCell.h index 72f81df..2ffce8d 100644 --- a/JavaScriptCore/runtime/JSCell.h +++ b/JavaScriptCore/runtime/JSCell.h @@ -333,9 +333,8 @@ namespace JSC { { ASSERT(!m_isCheckingForDefaultMarkViolation); ASSERT(cell); - if (Heap::isCellMarked(cell)) + if (Heap::checkMarkCell(cell)) return; - Heap::markCell(cell); if (cell->structure()->typeInfo().type() >= CompoundType) m_values.append(cell); } diff --git a/JavaScriptCore/runtime/JSFunction.cpp b/JavaScriptCore/runtime/JSFunction.cpp index 49cc8fa..7eb9ba5 100644 --- a/JavaScriptCore/runtime/JSFunction.cpp +++ b/JavaScriptCore/runtime/JSFunction.cpp @@ -134,7 +134,7 @@ const UString JSFunction::displayName(ExecState* exec) if (displayName && isJSString(&exec->globalData(), displayName)) return asString(displayName)->tryGetValue(); - return UString::null(); + return UString(); } const UString JSFunction::calculatedDisplayName(ExecState* exec) diff --git a/JavaScriptCore/runtime/JSGlobalData.cpp b/JavaScriptCore/runtime/JSGlobalData.cpp index abb2db2..ca8605b 100644 --- a/JavaScriptCore/runtime/JSGlobalData.cpp +++ b/JavaScriptCore/runtime/JSGlobalData.cpp @@ -283,6 +283,7 @@ void JSGlobalData::resetDateCache() cachedUTCOffset = NaN; dstOffsetCache.reset(); cachedDateString = UString(); + cachedDateStringValue = NaN; dateInstanceCache.reset(); } diff --git a/JavaScriptCore/runtime/JSGlobalObject.h b/JavaScriptCore/runtime/JSGlobalObject.h index 115af87..e57b737 100644 --- a/JavaScriptCore/runtime/JSGlobalObject.h +++ b/JavaScriptCore/runtime/JSGlobalObject.h @@ -353,7 +353,7 @@ namespace JSC { GlobalPropertyInfo& global = globals[i]; ASSERT(global.attributes & DontDelete); SymbolTableEntry newEntry(index, global.attributes); - symbolTable().add(global.identifier.ustring().rep(), newEntry); + symbolTable().add(global.identifier.impl(), newEntry); registerAt(index) = global.value; } } diff --git a/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp b/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp index d88d6a9..1e20f7f 100644 --- a/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp +++ b/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp @@ -53,7 +53,7 @@ namespace JSC { static JSValue encode(ExecState* exec, const char* doNotEscape) { UString str = exec->argument(0).toString(exec); - CString cstr = str.UTF8String(true); + CString cstr = str.utf8(true); if (!cstr.data()) return throwError(exec, createURIError(exec, "String contained an illegal UTF-16 sequence.")); @@ -77,8 +77,8 @@ static JSValue decode(ExecState* exec, const char* doNotUnescape, bool strict) JSStringBuilder builder; UString str = exec->argument(0).toString(exec); int k = 0; - int len = str.size(); - const UChar* d = str.data(); + int len = str.length(); + const UChar* d = str.characters(); UChar u = 0; while (k < len) { const UChar* p = d + k; @@ -220,8 +220,8 @@ double parseIntOverflow(const UChar* s, int length, int radix) static double parseInt(const UString& s, int radix) { - int length = s.size(); - const UChar* data = s.data(); + int length = s.length(); + const UChar* data = s.characters(); int p = 0; while (p < length && isStrWhiteSpace(data[p])) @@ -265,9 +265,9 @@ static double parseInt(const UString& s, int radix) if (number >= mantissaOverflowLowerBound) { if (radix == 10) - number = WTF::strtod(s.substr(firstDigitPosition, p - firstDigitPosition).UTF8String().data(), 0); + number = WTF::strtod(s.substringSharingImpl(firstDigitPosition, p - firstDigitPosition).utf8().data(), 0); else if (radix == 2 || radix == 4 || radix == 8 || radix == 16 || radix == 32) - number = parseIntOverflow(s.substr(firstDigitPosition, p - firstDigitPosition).UTF8String().data(), p - firstDigitPosition, radix); + number = parseIntOverflow(s.substringSharingImpl(firstDigitPosition, p - firstDigitPosition).utf8().data(), p - firstDigitPosition, radix); } if (!sawDigit) @@ -276,23 +276,161 @@ static double parseInt(const UString& s, int radix) return sign * number; } +static const int SizeOfInfinity = 8; + +static bool isInfinity(const UChar* data, const UChar* end) +{ + return (end - data) >= SizeOfInfinity + && data[0] == 'I' + && data[1] == 'n' + && data[2] == 'f' + && data[3] == 'i' + && data[4] == 'n' + && data[5] == 'i' + && data[6] == 't' + && data[7] == 'y'; +} + +// See ecma-262 9.3.1 +static double jsHexIntegerLiteral(const UChar*& data, const UChar* end) +{ + // Hex number. + data += 2; + const UChar* firstDigitPosition = data; + double number = 0; + while (true) { + number = number * 16 + toASCIIHexValue(*data); + ++data; + if (data == end) + break; + if (!isASCIIHexDigit(*data)) + break; + } + if (number >= mantissaOverflowLowerBound) + number = parseIntOverflow(firstDigitPosition, data - firstDigitPosition, 16); + + return number; +} + +// See ecma-262 9.3.1 +static double jsStrDecimalLiteral(const UChar*& data, const UChar* end) +{ + ASSERT(data < end); + + // Copy the sting into a null-terminated byte buffer, and call strtod. + Vector<char, 32> byteBuffer; + for (const UChar* characters = data; characters < end; ++characters) { + UChar character = *characters; + byteBuffer.append(isASCII(character) ? character : 0); + } + byteBuffer.append(0); + char* endOfNumber; + double number = WTF::strtod(byteBuffer.data(), &endOfNumber); + + // Check if strtod found a number; if so return it. + ptrdiff_t consumed = endOfNumber - byteBuffer.data(); + if (consumed) { + data += consumed; + return number; + } + + // Check for [+-]?Infinity + switch (*data) { + case 'I': + if (isInfinity(data, end)) { + data += SizeOfInfinity; + return Inf; + } + break; + + case '+': + if (isInfinity(data + 1, end)) { + data += SizeOfInfinity + 1; + return Inf; + } + break; + + case '-': + if (isInfinity(data + 1, end)) { + data += SizeOfInfinity + 1; + return -Inf; + } + break; + } + + // Not a number. + return NaN; +} + +// See ecma-262 9.3.1 +double jsToNumber(const UString& s) +{ + unsigned size = s.length(); + + if (size == 1) { + UChar c = s.characters()[0]; + if (isASCIIDigit(c)) + return c - '0'; + if (isStrWhiteSpace(c)) + return 0; + return NaN; + } + + const UChar* data = s.characters(); + const UChar* end = data + size; + + // Skip leading white space. + for (; data < end; ++data) { + if (!isStrWhiteSpace(*data)) + break; + } + + // Empty string. + if (data == end) + return 0.0; + + double number; + if (data[0] == '0' && data + 2 < end && (data[1] | 0x20) == 'x' && isASCIIHexDigit(data[2])) + number = jsHexIntegerLiteral(data, end); + else + number = jsStrDecimalLiteral(data, end); + + // Allow trailing white space. + for (; data < end; ++data) { + if (!isStrWhiteSpace(*data)) + break; + } + if (data != end) + return NaN; + + return number; +} + static double parseFloat(const UString& s) { - // Check for 0x prefix here, because toDouble allows it, but we must treat it as 0. - // Need to skip any whitespace and then one + or - sign. - int length = s.size(); - const UChar* data = s.data(); - int p = 0; - while (p < length && isStrWhiteSpace(data[p])) - ++p; + unsigned size = s.length(); - if (p < length && (data[p] == '+' || data[p] == '-')) - ++p; + if (size == 1) { + UChar c = s.characters()[0]; + if (isASCIIDigit(c)) + return c - '0'; + return NaN; + } + + const UChar* data = s.characters(); + const UChar* end = data + size; + + // Skip leading white space. + for (; data < end; ++data) { + if (!isStrWhiteSpace(*data)) + break; + } - if (length - p >= 2 && data[p] == '0' && (data[p + 1] == 'x' || data[p + 1] == 'X')) - return 0; + // Empty string. + if (data == end) + return NaN; - return s.toDouble(true /*tolerant*/, false /* NaN for empty string */); + return jsStrDecimalLiteral(data, end); } EncodedJSValue JSC_HOST_CALL globalFuncEval(ExecState* exec) @@ -404,8 +542,8 @@ EncodedJSValue JSC_HOST_CALL globalFuncEscape(ExecState* exec) JSStringBuilder builder; UString str = exec->argument(0).toString(exec); - const UChar* c = str.data(); - for (unsigned k = 0; k < str.size(); k++, c++) { + const UChar* c = str.characters(); + for (unsigned k = 0; k < str.length(); k++, c++) { int u = c[0]; if (u > 255) { char tmp[7]; @@ -428,9 +566,9 @@ EncodedJSValue JSC_HOST_CALL globalFuncUnescape(ExecState* exec) StringBuilder builder; UString str = exec->argument(0).toString(exec); int k = 0; - int len = str.size(); + int len = str.length(); while (k < len) { - const UChar* c = str.data() + k; + const UChar* c = str.characters() + k; UChar u; if (c[0] == '%' && k <= len - 6 && c[1] == 'u') { if (isASCIIHexDigit(c[2]) && isASCIIHexDigit(c[3]) && isASCIIHexDigit(c[4]) && isASCIIHexDigit(c[5])) { @@ -453,7 +591,7 @@ EncodedJSValue JSC_HOST_CALL globalFuncUnescape(ExecState* exec) #ifndef NDEBUG EncodedJSValue JSC_HOST_CALL globalFuncJSCPrint(ExecState* exec) { - CString string = exec->argument(0).toString(exec).UTF8String(); + CString string = exec->argument(0).toString(exec).utf8(); puts(string.data()); return JSValue::encode(jsUndefined()); } diff --git a/JavaScriptCore/runtime/JSGlobalObjectFunctions.h b/JavaScriptCore/runtime/JSGlobalObjectFunctions.h index e634fae..6dc7343 100644 --- a/JavaScriptCore/runtime/JSGlobalObjectFunctions.h +++ b/JavaScriptCore/runtime/JSGlobalObjectFunctions.h @@ -55,6 +55,7 @@ namespace JSC { double parseIntOverflow(const char*, int length, int radix); double parseIntOverflow(const UChar*, int length, int radix); bool isStrWhiteSpace(UChar); + double jsToNumber(const UString& s); } // namespace JSC diff --git a/JavaScriptCore/runtime/JSNumberCell.cpp b/JavaScriptCore/runtime/JSNumberCell.cpp index a61c751..77388e0 100644 --- a/JavaScriptCore/runtime/JSNumberCell.cpp +++ b/JavaScriptCore/runtime/JSNumberCell.cpp @@ -54,7 +54,7 @@ double JSNumberCell::toNumber(ExecState*) const UString JSNumberCell::toString(ExecState*) const { - return UString::from(m_value); + return UString::number(m_value); } JSObject* JSNumberCell::toObject(ExecState* exec) const diff --git a/JavaScriptCore/runtime/JSONObject.cpp b/JavaScriptCore/runtime/JSONObject.cpp index ccfd43a..ba50721 100644 --- a/JavaScriptCore/runtime/JSONObject.cpp +++ b/JavaScriptCore/runtime/JSONObject.cpp @@ -35,6 +35,7 @@ #include "Lookup.h" #include "PropertyNameArray.h" #include "StringBuilder.h" +#include "StringConcatenate.h" #include <wtf/MathExtras.h> namespace JSC { @@ -163,8 +164,8 @@ static inline UString gap(ExecState* exec, JSValue space) // If the space value is a string, use it as the gap string, otherwise use no gap string. UString spaces = space.getString(exec); - if (spaces.size() > maxGapLength) { - spaces = spaces.substr(0, maxGapLength); + if (spaces.length() > maxGapLength) { + spaces = spaces.substringSharingImpl(0, maxGapLength); } return spaces; } @@ -280,14 +281,14 @@ JSValue Stringifier::stringify(JSValue value) void Stringifier::appendQuotedString(StringBuilder& builder, const UString& value) { - int length = value.size(); + int length = value.length(); // String length plus 2 for quote marks plus 8 so we can accomodate a few escaped characters. builder.reserveCapacity(builder.size() + length + 2 + 8); builder.append('"'); - const UChar* data = value.data(); + const UChar* data = value.characters(); for (int i = 0; i < length; ++i) { int start = i; while (i < length && (data[i] > 0x1F && data[i] != '"' && data[i] != '\\')) @@ -405,7 +406,7 @@ Stringifier::StringifyResult Stringifier::appendStringifiedValue(StringBuilder& if (!isfinite(numericValue)) builder.append("null"); else - builder.append(UString::from(numericValue)); + builder.append(UString::number(numericValue)); return StringifySucceeded; } @@ -463,17 +464,17 @@ inline bool Stringifier::willIndent() const inline void Stringifier::indent() { // Use a single shared string, m_repeatedGap, so we don't keep allocating new ones as we indent and unindent. - unsigned newSize = m_indent.size() + m_gap.size(); - if (newSize > m_repeatedGap.size()) + unsigned newSize = m_indent.length() + m_gap.length(); + if (newSize > m_repeatedGap.length()) m_repeatedGap = makeString(m_repeatedGap, m_gap); - ASSERT(newSize <= m_repeatedGap.size()); - m_indent = m_repeatedGap.substr(0, newSize); + ASSERT(newSize <= m_repeatedGap.length()); + m_indent = m_repeatedGap.substringSharingImpl(0, newSize); } inline void Stringifier::unindent() { - ASSERT(m_indent.size() >= m_gap.size()); - m_indent = m_repeatedGap.substr(0, m_indent.size() - m_gap.size()); + ASSERT(m_indent.length() >= m_gap.length()); + m_indent = m_repeatedGap.substringSharingImpl(0, m_indent.length() - m_gap.length()); } inline void Stringifier::startNewLine(StringBuilder& builder) const @@ -722,7 +723,7 @@ NEVER_INLINE JSValue Walker::walk(JSValue unfiltered) } case ArrayEndVisitMember: { JSArray* array = arrayStack.last(); - JSValue filteredValue = callReviver(array, jsString(m_exec, UString::from(indexStack.last())), outValue); + JSValue filteredValue = callReviver(array, jsString(m_exec, UString::number(indexStack.last())), outValue); if (filteredValue.isUndefined()) array->deleteProperty(m_exec, indexStack.last()); else { diff --git a/JavaScriptCore/runtime/JSStaticScopeObject.h b/JavaScriptCore/runtime/JSStaticScopeObject.h index dcece9d..c0519c1 100644 --- a/JavaScriptCore/runtime/JSStaticScopeObject.h +++ b/JavaScriptCore/runtime/JSStaticScopeObject.h @@ -47,7 +47,7 @@ namespace JSC{ : JSVariableObject(exec->globalData().staticScopeStructure, new JSStaticScopeObjectData()) { d()->registerStore = value; - symbolTable().add(ident.ustring().rep(), SymbolTableEntry(-1, attributes)); + symbolTable().add(ident.impl(), SymbolTableEntry(-1, attributes)); } virtual ~JSStaticScopeObject(); virtual void markChildren(MarkStack&); diff --git a/JavaScriptCore/runtime/JSString.cpp b/JavaScriptCore/runtime/JSString.cpp index 13c5a51..bc0120f 100644 --- a/JavaScriptCore/runtime/JSString.cpp +++ b/JavaScriptCore/runtime/JSString.cpp @@ -24,6 +24,7 @@ #include "JSString.h" #include "JSGlobalObject.h" +#include "JSGlobalObjectFunctions.h" #include "JSObject.h" #include "Operations.h" #include "StringObject.h" @@ -37,7 +38,7 @@ namespace JSC { // representing the rope is likely imbalanced with more nodes down the left side // (since appending to the string is likely more common) - and as such resolving // in this fashion should minimize work queue size. (If we built the queue forwards -// we would likely have to place all of the constituent UStringImpls into the +// we would likely have to place all of the constituent StringImpls into the // Vector before performing any concatenation, but by working backwards we likely // only fill the queue with the number of substrings at any given level in a // rope-of-ropes.) @@ -47,7 +48,7 @@ void JSString::resolveRope(ExecState* exec) const // Allocate the buffer to hold the final string, position initially points to the end. UChar* buffer; - if (PassRefPtr<UStringImpl> newImpl = UStringImpl::tryCreateUninitialized(m_length, buffer)) + if (PassRefPtr<StringImpl> newImpl = StringImpl::tryCreateUninitialized(m_length, buffer)) m_value = newImpl; else { for (unsigned i = 0; i < m_fiberCount; ++i) { @@ -79,10 +80,10 @@ void JSString::resolveRope(ExecState* exec) const workQueue.append(rope->fibers()[i]); currentFiber = rope->fibers()[fiberCountMinusOne]; } else { - UStringImpl* string = static_cast<UStringImpl*>(currentFiber); + StringImpl* string = static_cast<StringImpl*>(currentFiber); unsigned length = string->length(); position -= length; - UStringImpl::copyChars(position, string->characters(), length); + StringImpl::copyChars(position, string->characters(), length); // Was this the last item in the work queue? if (workQueue.isEmpty()) { @@ -108,26 +109,26 @@ void JSString::resolveRope(ExecState* exec) const JSValue JSString::replaceCharacter(ExecState* exec, UChar character, const UString& replacement) { if (!isRope()) { - unsigned matchPosition = m_value.find(character); - if (matchPosition == UString::NotFound) + size_t matchPosition = m_value.find(character); + if (matchPosition == notFound) return JSValue(this); - return jsString(exec, m_value.substr(0, matchPosition), replacement, m_value.substr(matchPosition + 1)); + return jsString(exec, m_value.substringSharingImpl(0, matchPosition), replacement, m_value.substringSharingImpl(matchPosition + 1)); } RopeIterator end; // Count total fibers and find matching string. size_t fiberCount = 0; - UStringImpl* matchString = 0; - int matchPosition = -1; + StringImpl* matchString = 0; + size_t matchPosition = notFound; for (RopeIterator it(m_other.m_fibers.data(), m_fiberCount); it != end; ++it) { ++fiberCount; if (matchString) continue; - UStringImpl* string = *it; + StringImpl* string = *it; matchPosition = string->find(character); - if (matchPosition == -1) + if (matchPosition == notFound) continue; matchString = string; } @@ -135,21 +136,21 @@ JSValue JSString::replaceCharacter(ExecState* exec, UChar character, const UStri if (!matchString) return this; - RopeBuilder builder(replacement.size() ? fiberCount + 2 : fiberCount + 1); + RopeBuilder builder(replacement.length() ? fiberCount + 2 : fiberCount + 1); if (UNLIKELY(builder.isOutOfMemory())) return throwOutOfMemoryError(exec); for (RopeIterator it(m_other.m_fibers.data(), m_fiberCount); it != end; ++it) { - UStringImpl* string = *it; + StringImpl* string = *it; if (string != matchString) { builder.append(UString(string)); continue; } - builder.append(UString(string).substr(0, matchPosition)); - if (replacement.size()) + builder.append(UString(string).substringSharingImpl(0, matchPosition)); + if (replacement.length()) builder.append(replacement); - builder.append(UString(string).substr(matchPosition + 1)); + builder.append(UString(string).substringSharingImpl(matchPosition + 1)); matchString = 0; } @@ -165,7 +166,7 @@ JSString* JSString::getIndexSlowCase(ExecState* exec, unsigned i) if (exec->exception()) return jsString(exec, ""); ASSERT(!isRope()); - ASSERT(i < m_value.size()); + ASSERT(i < m_value.length()); return jsSingleCharacterSubstring(exec, m_value, i); } @@ -177,7 +178,7 @@ JSValue JSString::toPrimitive(ExecState*, PreferredPrimitiveType) const bool JSString::getPrimitiveNumber(ExecState* exec, double& number, JSValue& result) { result = this; - number = value(exec).toDouble(); + number = jsToNumber(value(exec)); return false; } @@ -188,7 +189,7 @@ bool JSString::toBoolean(ExecState*) const double JSString::toNumber(ExecState* exec) const { - return value(exec).toDouble(); + return jsToNumber(value(exec)); } UString JSString::toString(ExecState* exec) const @@ -240,7 +241,7 @@ bool JSString::getStringPropertyDescriptor(ExecState* exec, const Identifier& pr } bool isStrictUInt32; - unsigned i = propertyName.toStrictUInt32(&isStrictUInt32); + unsigned i = propertyName.toUInt32(isStrictUInt32); if (isStrictUInt32 && i < m_length) { descriptor.setDescriptor(getIndex(exec, i), DontDelete | ReadOnly); return true; diff --git a/JavaScriptCore/runtime/JSString.h b/JavaScriptCore/runtime/JSString.h index 53c144b..12ced10 100644 --- a/JavaScriptCore/runtime/JSString.h +++ b/JavaScriptCore/runtime/JSString.h @@ -87,7 +87,7 @@ namespace JSC { void append(const UString& string) { ASSERT(m_rope); - m_rope->initializeFiber(m_index, string.rep()); + m_rope->initializeFiber(m_index, string.impl()); } void append(JSString* jsString) { @@ -132,12 +132,12 @@ namespace JSC { return *this; } - UStringImpl* operator*() + StringImpl* operator*() { WorkItem& item = m_workQueue.last(); RopeImpl::Fiber fiber = item.fibers[item.i]; ASSERT(!RopeImpl::isRope(fiber)); - return static_cast<UStringImpl*>(fiber); + return static_cast<StringImpl*>(fiber); } bool operator!=(const RopeIterator& other) const @@ -186,24 +186,24 @@ namespace JSC { ALWAYS_INLINE JSString(JSGlobalData* globalData, const UString& value) : JSCell(globalData->stringStructure.get()) - , m_length(value.size()) + , m_length(value.length()) , m_value(value) , m_fiberCount(0) { ASSERT(!m_value.isNull()); - Heap::heap(this)->reportExtraMemoryCost(value.cost()); + Heap::heap(this)->reportExtraMemoryCost(value.impl()->cost()); } enum HasOtherOwnerType { HasOtherOwner }; JSString(JSGlobalData* globalData, const UString& value, HasOtherOwnerType) : JSCell(globalData->stringStructure.get()) - , m_length(value.size()) + , m_length(value.length()) , m_value(value) , m_fiberCount(0) { ASSERT(!m_value.isNull()); } - JSString(JSGlobalData* globalData, PassRefPtr<UStringImpl> value, HasOtherOwnerType) + JSString(JSGlobalData* globalData, PassRefPtr<StringImpl> value, HasOtherOwnerType) : JSCell(globalData->stringStructure.get()) , m_length(value->length()) , m_value(value) @@ -235,7 +235,7 @@ namespace JSC { // This should only be called with fiberCount <= 3. JSString(JSGlobalData* globalData, unsigned fiberCount, JSString* s1, const UString& u2) : JSCell(globalData->stringStructure.get()) - , m_length(s1->length() + u2.size()) + , m_length(s1->length() + u2.length()) , m_fiberCount(fiberCount) { ASSERT(fiberCount <= s_maxInternalRopeLength); @@ -248,7 +248,7 @@ namespace JSC { // This should only be called with fiberCount <= 3. JSString(JSGlobalData* globalData, unsigned fiberCount, const UString& u1, JSString* s2) : JSCell(globalData->stringStructure.get()) - , m_length(u1.size() + s2->length()) + , m_length(u1.length() + s2->length()) , m_fiberCount(fiberCount) { ASSERT(fiberCount <= s_maxInternalRopeLength); @@ -276,7 +276,7 @@ namespace JSC { // This constructor constructs a new string by concatenating u1 & u2. JSString(JSGlobalData* globalData, const UString& u1, const UString& u2) : JSCell(globalData->stringStructure.get()) - , m_length(u1.size() + u2.size()) + , m_length(u1.length() + u2.length()) , m_fiberCount(2) { unsigned index = 0; @@ -288,7 +288,7 @@ namespace JSC { // This constructor constructs a new string by concatenating u1, u2 & u3. JSString(JSGlobalData* globalData, const UString& u1, const UString& u2, const UString& u3) : JSCell(globalData->stringStructure.get()) - , m_length(u1.size() + u2.size() + u3.size()) + , m_length(u1.length() + u2.length() + u3.length()) , m_fiberCount(s_maxInternalRopeLength) { unsigned index = 0; @@ -300,7 +300,7 @@ namespace JSC { JSString(JSGlobalData* globalData, const UString& value, JSStringFinalizerCallback finalizer, void* context) : JSCell(globalData->stringStructure.get()) - , m_length(value.size()) + , m_length(value.length()) , m_value(value) , m_fiberCount(0) { @@ -308,7 +308,7 @@ namespace JSC { // nasty hack because we can't union non-POD types m_other.m_finalizerCallback = finalizer; m_other.m_finalizerContext = context; - Heap::heap(this)->reportExtraMemoryCost(value.cost()); + Heap::heap(this)->reportExtraMemoryCost(value.impl()->cost()); } ~JSString() @@ -359,7 +359,7 @@ namespace JSC { void appendStringInConstruct(unsigned& index, const UString& string) { - UStringImpl* impl = string.rep(); + StringImpl* impl = string.impl(); impl->ref(); m_other.m_fibers[index++] = impl; } @@ -381,15 +381,15 @@ namespace JSC { if (v.isString()) { ASSERT(asCell(v)->isString()); JSString* s = static_cast<JSString*>(asCell(v)); - ASSERT(s->size() == 1); + ASSERT(s->fiberCount() == 1); appendStringInConstruct(index, s); m_length += s->length(); } else { UString u(v.toString(exec)); - UStringImpl* impl = u.rep(); + StringImpl* impl = u.impl(); impl->ref(); m_other.m_fibers[index++] = impl; - m_length += u.size(); + m_length += u.length(); } } @@ -427,7 +427,7 @@ namespace JSC { bool isRope() const { return m_fiberCount; } UString& string() { ASSERT(!isRope()); return m_value; } - unsigned size() { return m_fiberCount ? m_fiberCount : 1; } + unsigned fiberCount() { return m_fiberCount ? m_fiberCount : 1; } friend JSValue jsString(ExecState* exec, JSString* s1, JSString* s2); friend JSValue jsString(ExecState* exec, const UString& u1, JSString* s2); @@ -470,11 +470,11 @@ namespace JSC { inline JSString* jsSingleCharacterSubstring(ExecState* exec, const UString& s, unsigned offset) { JSGlobalData* globalData = &exec->globalData(); - ASSERT(offset < static_cast<unsigned>(s.size())); - UChar c = s.data()[offset]; + ASSERT(offset < static_cast<unsigned>(s.length())); + UChar c = s.characters()[offset]; if (c <= 0xFF) return globalData->smallStrings.singleCharacterString(globalData, c); - return fixupVPtr(globalData, new (globalData) JSString(globalData, UString(UStringImpl::create(s.rep(), offset, 1)))); + return fixupVPtr(globalData, new (globalData) JSString(globalData, UString(StringImpl::create(s.impl(), offset, 1)))); } inline JSString* jsNontrivialString(JSGlobalData* globalData, const char* s) @@ -487,7 +487,7 @@ namespace JSC { inline JSString* jsNontrivialString(JSGlobalData* globalData, const UString& s) { - ASSERT(s.size() > 1); + ASSERT(s.length() > 1); return fixupVPtr(globalData, new (globalData) JSString(globalData, s)); } @@ -496,17 +496,17 @@ namespace JSC { ASSERT(canGetIndex(i)); if (isRope()) return getIndexSlowCase(exec, i); - ASSERT(i < m_value.size()); + ASSERT(i < m_value.length()); return jsSingleCharacterSubstring(exec, m_value, i); } inline JSString* jsString(JSGlobalData* globalData, const UString& s) { - int size = s.size(); + int size = s.length(); if (!size) return globalData->smallStrings.emptyString(globalData); if (size == 1) { - UChar c = s.data()[0]; + UChar c = s.characters()[0]; if (c <= 0xFF) return globalData->smallStrings.singleCharacterString(globalData, c); } @@ -515,33 +515,33 @@ namespace JSC { inline JSString* jsStringWithFinalizer(ExecState* exec, const UString& s, JSStringFinalizerCallback callback, void* context) { - ASSERT(s.size() && (s.size() > 1 || s.data()[0] > 0xFF)); + ASSERT(s.length() && (s.length() > 1 || s.characters()[0] > 0xFF)); JSGlobalData* globalData = &exec->globalData(); return fixupVPtr(globalData, new (globalData) JSString(globalData, s, callback, context)); } inline JSString* jsSubstring(JSGlobalData* globalData, const UString& s, unsigned offset, unsigned length) { - ASSERT(offset <= static_cast<unsigned>(s.size())); - ASSERT(length <= static_cast<unsigned>(s.size())); - ASSERT(offset + length <= static_cast<unsigned>(s.size())); + ASSERT(offset <= static_cast<unsigned>(s.length())); + ASSERT(length <= static_cast<unsigned>(s.length())); + ASSERT(offset + length <= static_cast<unsigned>(s.length())); if (!length) return globalData->smallStrings.emptyString(globalData); if (length == 1) { - UChar c = s.data()[offset]; + UChar c = s.characters()[offset]; if (c <= 0xFF) return globalData->smallStrings.singleCharacterString(globalData, c); } - return fixupVPtr(globalData, new (globalData) JSString(globalData, UString(UStringImpl::create(s.rep(), offset, length)), JSString::HasOtherOwner)); + return fixupVPtr(globalData, new (globalData) JSString(globalData, UString(StringImpl::create(s.impl(), offset, length)), JSString::HasOtherOwner)); } inline JSString* jsOwnedString(JSGlobalData* globalData, const UString& s) { - int size = s.size(); + int size = s.length(); if (!size) return globalData->smallStrings.emptyString(globalData); if (size == 1) { - UChar c = s.data()[0]; + UChar c = s.characters()[0]; if (c <= 0xFF) return globalData->smallStrings.singleCharacterString(globalData, c); } @@ -564,7 +564,7 @@ namespace JSC { } bool isStrictUInt32; - unsigned i = propertyName.toStrictUInt32(&isStrictUInt32); + unsigned i = propertyName.toUInt32(isStrictUInt32); if (isStrictUInt32 && i < m_length) { slot.setValue(getIndex(exec, i)); return true; diff --git a/JavaScriptCore/runtime/JSStringBuilder.h b/JavaScriptCore/runtime/JSStringBuilder.h index 8f208a1..25fe685 100644 --- a/JavaScriptCore/runtime/JSStringBuilder.h +++ b/JavaScriptCore/runtime/JSStringBuilder.h @@ -28,6 +28,7 @@ #include "ExceptionHelpers.h" #include "JSString.h" +#include "StringConcatenate.h" #include "Vector.h" namespace JSC { @@ -65,7 +66,7 @@ public: void append(const UString& str) { - m_okay &= buffer.tryAppend(str.data(), str.size()); + m_okay &= buffer.tryAppend(str.characters(), str.length()); } JSValue build(ExecState* exec) @@ -86,7 +87,7 @@ protected: template<typename StringType1, typename StringType2> inline JSValue jsMakeNontrivialString(ExecState* exec, StringType1 string1, StringType2 string2) { - PassRefPtr<UStringImpl> result = tryMakeString(string1, string2); + PassRefPtr<StringImpl> result = tryMakeString(string1, string2); if (!result) return throwOutOfMemoryError(exec); return jsNontrivialString(exec, result); @@ -95,7 +96,7 @@ inline JSValue jsMakeNontrivialString(ExecState* exec, StringType1 string1, Stri template<typename StringType1, typename StringType2, typename StringType3> inline JSValue jsMakeNontrivialString(ExecState* exec, StringType1 string1, StringType2 string2, StringType3 string3) { - PassRefPtr<UStringImpl> result = tryMakeString(string1, string2, string3); + PassRefPtr<StringImpl> result = tryMakeString(string1, string2, string3); if (!result) return throwOutOfMemoryError(exec); return jsNontrivialString(exec, result); @@ -104,7 +105,7 @@ inline JSValue jsMakeNontrivialString(ExecState* exec, StringType1 string1, Stri template<typename StringType1, typename StringType2, typename StringType3, typename StringType4> inline JSValue jsMakeNontrivialString(ExecState* exec, StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4) { - PassRefPtr<UStringImpl> result = tryMakeString(string1, string2, string3, string4); + PassRefPtr<StringImpl> result = tryMakeString(string1, string2, string3, string4); if (!result) return throwOutOfMemoryError(exec); return jsNontrivialString(exec, result); @@ -113,7 +114,7 @@ inline JSValue jsMakeNontrivialString(ExecState* exec, StringType1 string1, Stri template<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5> inline JSValue jsMakeNontrivialString(ExecState* exec, StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5) { - PassRefPtr<UStringImpl> result = tryMakeString(string1, string2, string3, string4, string5); + PassRefPtr<StringImpl> result = tryMakeString(string1, string2, string3, string4, string5); if (!result) return throwOutOfMemoryError(exec); return jsNontrivialString(exec, result); @@ -122,7 +123,7 @@ inline JSValue jsMakeNontrivialString(ExecState* exec, StringType1 string1, Stri template<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5, typename StringType6> inline JSValue jsMakeNontrivialString(ExecState* exec, StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5, StringType6 string6) { - PassRefPtr<UStringImpl> result = tryMakeString(string1, string2, string3, string4, string5, string6); + PassRefPtr<StringImpl> result = tryMakeString(string1, string2, string3, string4, string5, string6); if (!result) return throwOutOfMemoryError(exec); return jsNontrivialString(exec, result); diff --git a/JavaScriptCore/runtime/JSVariableObject.cpp b/JavaScriptCore/runtime/JSVariableObject.cpp index 7365001..81d05ba 100644 --- a/JavaScriptCore/runtime/JSVariableObject.cpp +++ b/JavaScriptCore/runtime/JSVariableObject.cpp @@ -36,7 +36,7 @@ namespace JSC { bool JSVariableObject::deleteProperty(ExecState* exec, const Identifier& propertyName) { - if (symbolTable().contains(propertyName.ustring().rep())) + if (symbolTable().contains(propertyName.impl())) return false; return JSObject::deleteProperty(exec, propertyName); @@ -60,7 +60,7 @@ bool JSVariableObject::isVariableObject() const bool JSVariableObject::symbolTableGet(const Identifier& propertyName, PropertyDescriptor& descriptor) { - SymbolTableEntry entry = symbolTable().inlineGet(propertyName.ustring().rep()); + SymbolTableEntry entry = symbolTable().inlineGet(propertyName.impl()); if (!entry.isNull()) { descriptor.setDescriptor(registerAt(entry.getIndex()).jsValue(), entry.getAttributes() | DontDelete); return true; diff --git a/JavaScriptCore/runtime/JSVariableObject.h b/JavaScriptCore/runtime/JSVariableObject.h index f2efcdf..3f2e218 100644 --- a/JavaScriptCore/runtime/JSVariableObject.h +++ b/JavaScriptCore/runtime/JSVariableObject.h @@ -103,7 +103,7 @@ namespace JSC { inline bool JSVariableObject::symbolTableGet(const Identifier& propertyName, PropertySlot& slot) { - SymbolTableEntry entry = symbolTable().inlineGet(propertyName.ustring().rep()); + SymbolTableEntry entry = symbolTable().inlineGet(propertyName.impl()); if (!entry.isNull()) { slot.setRegisterSlot(®isterAt(entry.getIndex())); return true; @@ -113,7 +113,7 @@ namespace JSC { inline bool JSVariableObject::symbolTableGet(const Identifier& propertyName, PropertySlot& slot, bool& slotIsWriteable) { - SymbolTableEntry entry = symbolTable().inlineGet(propertyName.ustring().rep()); + SymbolTableEntry entry = symbolTable().inlineGet(propertyName.impl()); if (!entry.isNull()) { slot.setRegisterSlot(®isterAt(entry.getIndex())); slotIsWriteable = !entry.isReadOnly(); @@ -126,7 +126,7 @@ namespace JSC { { ASSERT(!Heap::heap(value) || Heap::heap(value) == Heap::heap(this)); - SymbolTableEntry entry = symbolTable().inlineGet(propertyName.ustring().rep()); + SymbolTableEntry entry = symbolTable().inlineGet(propertyName.impl()); if (entry.isNull()) return false; if (entry.isReadOnly()) @@ -139,7 +139,7 @@ namespace JSC { { ASSERT(!Heap::heap(value) || Heap::heap(value) == Heap::heap(this)); - SymbolTable::iterator iter = symbolTable().find(propertyName.ustring().rep()); + SymbolTable::iterator iter = symbolTable().find(propertyName.impl()); if (iter == symbolTable().end()) return false; SymbolTableEntry& entry = iter->second; diff --git a/JavaScriptCore/runtime/LiteralParser.h b/JavaScriptCore/runtime/LiteralParser.h index 0f8072b..6df5d06 100644 --- a/JavaScriptCore/runtime/LiteralParser.h +++ b/JavaScriptCore/runtime/LiteralParser.h @@ -72,8 +72,8 @@ namespace JSC { Lexer(const UString& s, ParserMode mode) : m_string(s) , m_mode(mode) - , m_ptr(s.data()) - , m_end(s.data() + s.size()) + , m_ptr(s.characters()) + , m_end(s.characters() + s.length()) { } diff --git a/JavaScriptCore/runtime/Lookup.cpp b/JavaScriptCore/runtime/Lookup.cpp index 50d096c..07416af 100644 --- a/JavaScriptCore/runtime/Lookup.cpp +++ b/JavaScriptCore/runtime/Lookup.cpp @@ -34,7 +34,7 @@ void HashTable::createTable(JSGlobalData* globalData) const for (int i = 0; i < compactSize; ++i) entries[i].setKey(0); for (int i = 0; values[i].key; ++i) { - UString::Rep* identifier = Identifier::add(globalData, values[i].key).releaseRef(); + StringImpl* identifier = Identifier::add(globalData, values[i].key).releaseRef(); int hashIndex = identifier->existingHash() & compactHashSizeMask; HashEntry* entry = &entries[hashIndex]; @@ -61,7 +61,7 @@ void HashTable::deleteTable() const if (table) { int max = compactSize; for (int i = 0; i != max; ++i) { - if (UString::Rep* key = table[i].key()) + if (StringImpl* key = table[i].key()) key->deref(); } delete [] table; diff --git a/JavaScriptCore/runtime/Lookup.h b/JavaScriptCore/runtime/Lookup.h index 5a96fd3..9bc81d4 100644 --- a/JavaScriptCore/runtime/Lookup.h +++ b/JavaScriptCore/runtime/Lookup.h @@ -55,7 +55,7 @@ namespace JSC { class HashEntry : public FastAllocBase { public: - void initialize(UString::Rep* key, unsigned char attributes, intptr_t v1, intptr_t v2 + void initialize(StringImpl* key, unsigned char attributes, intptr_t v1, intptr_t v2 #if ENABLE(JIT) , ThunkGenerator generator = 0 #endif @@ -71,8 +71,8 @@ namespace JSC { m_next = 0; } - void setKey(UString::Rep* key) { m_key = key; } - UString::Rep* key() const { return m_key; } + void setKey(StringImpl* key) { m_key = key; } + StringImpl* key() const { return m_key; } unsigned char attributes() const { return m_attributes; } @@ -91,7 +91,7 @@ namespace JSC { HashEntry* next() const { return m_next; } private: - UString::Rep* m_key; + StringImpl* m_key; unsigned char m_attributes; // JSObject attributes union { @@ -159,13 +159,13 @@ namespace JSC { { ASSERT(table); - const HashEntry* entry = &table[identifier.ustring().rep()->existingHash() & compactHashSizeMask]; + const HashEntry* entry = &table[identifier.impl()->existingHash() & compactHashSizeMask]; if (!entry->key()) return 0; do { - if (entry->key() == identifier.ustring().rep()) + if (entry->key() == identifier.impl()) return entry; entry = entry->next(); } while (entry); diff --git a/JavaScriptCore/runtime/NumberPrototype.cpp b/JavaScriptCore/runtime/NumberPrototype.cpp index e338d7c..80b7ce0 100644 --- a/JavaScriptCore/runtime/NumberPrototype.cpp +++ b/JavaScriptCore/runtime/NumberPrototype.cpp @@ -179,7 +179,7 @@ EncodedJSValue JSC_HOST_CALL numberProtoFuncToString(ExecState* exec) const char* lastCharInString = s + sizeof(s) - 1; double x = v.uncheckedGetNumber(); if (isnan(x) || isinf(x)) - return JSValue::encode(jsString(exec, UString::from(x))); + return JSValue::encode(jsString(exec, UString::number(x))); bool isNegative = x < 0.0; if (isNegative) @@ -271,7 +271,7 @@ EncodedJSValue JSC_HOST_CALL numberProtoFuncToFixed(ExecState* exec) } if (x >= pow(10.0, 21.0)) - return JSValue::encode(jsString(exec, makeString(s, UString::from(x)))); + return JSValue::encode(jsString(exec, makeString(s, UString::number(x)))); const double tenToTheF = pow(10.0, f); double n = floor(x * tenToTheF); @@ -280,7 +280,7 @@ EncodedJSValue JSC_HOST_CALL numberProtoFuncToFixed(ExecState* exec) UString m = integerPartNoExp(n); - int k = m.size(); + int k = m.length(); if (k <= f) { StringBuilder z; for (int i = 0; i < f + 1 - k; i++) @@ -288,13 +288,13 @@ EncodedJSValue JSC_HOST_CALL numberProtoFuncToFixed(ExecState* exec) z.append(m); m = z.build(); k = f + 1; - ASSERT(k == static_cast<int>(m.size())); + ASSERT(k == static_cast<int>(m.length())); } int kMinusf = k - f; - if (kMinusf < static_cast<int>(m.size())) - return JSValue::encode(jsString(exec, makeString(s, m.substr(0, kMinusf), ".", m.substr(kMinusf)))); - return JSValue::encode(jsString(exec, makeString(s, m.substr(0, kMinusf)))); + if (kMinusf < static_cast<int>(m.length())) + return JSValue::encode(jsString(exec, makeString(s, m.substringSharingImpl(0, kMinusf), ".", m.substringSharingImpl(kMinusf)))); + return JSValue::encode(jsString(exec, makeString(s, m.substringSharingImpl(0, kMinusf)))); } static void fractionalPartToString(char* buf, int& i, const char* result, int resultLength, int fractionalDigits) @@ -345,7 +345,7 @@ EncodedJSValue JSC_HOST_CALL numberProtoFuncToExponential(ExecState* exec) double x = v.uncheckedGetNumber(); if (isnan(x) || isinf(x)) - return JSValue::encode(jsString(exec, UString::from(x))); + return JSValue::encode(jsString(exec, UString::number(x))); JSValue fractionalDigitsValue = exec->argument(0); double df = fractionalDigitsValue.toInteger(exec); @@ -455,11 +455,11 @@ EncodedJSValue JSC_HOST_CALL numberProtoFuncToPrecision(ExecState* exec) m = integerPartNoExp(n); if (e < -6 || e >= precision) { - if (m.size() > 1) - m = makeString(m.substr(0, 1), ".", m.substr(1)); + if (m.length() > 1) + m = makeString(m.substringSharingImpl(0, 1), ".", m.substringSharingImpl(1)); if (e >= 0) - return JSValue::encode(jsMakeNontrivialString(exec, s, m, "e+", UString::from(e))); - return JSValue::encode(jsMakeNontrivialString(exec, s, m, "e-", UString::from(-e))); + return JSValue::encode(jsMakeNontrivialString(exec, s, m, "e+", UString::number(e))); + return JSValue::encode(jsMakeNontrivialString(exec, s, m, "e-", UString::number(-e))); } } else { m = charSequence('0', precision); @@ -469,8 +469,8 @@ EncodedJSValue JSC_HOST_CALL numberProtoFuncToPrecision(ExecState* exec) if (e == precision - 1) return JSValue::encode(jsString(exec, makeString(s, m))); if (e >= 0) { - if (e + 1 < static_cast<int>(m.size())) - return JSValue::encode(jsString(exec, makeString(s, m.substr(0, e + 1), ".", m.substr(e + 1)))); + if (e + 1 < static_cast<int>(m.length())) + return JSValue::encode(jsString(exec, makeString(s, m.substringSharingImpl(0, e + 1), ".", m.substringSharingImpl(e + 1)))); return JSValue::encode(jsString(exec, makeString(s, m))); } return JSValue::encode(jsMakeNontrivialString(exec, s, "0.", charSequence('0', -(e + 1)), m)); diff --git a/JavaScriptCore/runtime/NumericStrings.h b/JavaScriptCore/runtime/NumericStrings.h index 47fbbb2..d65f142 100644 --- a/JavaScriptCore/runtime/NumericStrings.h +++ b/JavaScriptCore/runtime/NumericStrings.h @@ -40,7 +40,7 @@ namespace JSC { if (d == entry.key && !entry.value.isNull()) return entry.value; entry.key = d; - entry.value = UString::from(d); + entry.value = UString::number(d); return entry.value; } @@ -52,7 +52,7 @@ namespace JSC { if (i == entry.key && !entry.value.isNull()) return entry.value; entry.key = i; - entry.value = UString::from(i); + entry.value = UString::number(i); return entry.value; } @@ -64,7 +64,7 @@ namespace JSC { if (i == entry.key && !entry.value.isNull()) return entry.value; entry.key = i; - entry.value = UString::from(i); + entry.value = UString::number(i); return entry.value; } private: @@ -83,7 +83,7 @@ namespace JSC { { ASSERT(i < cacheSize); if (smallIntCache[i].isNull()) - smallIntCache[i] = UString::from(i); + smallIntCache[i] = UString::number(i); return smallIntCache[i]; } diff --git a/JavaScriptCore/runtime/ObjectPrototype.cpp b/JavaScriptCore/runtime/ObjectPrototype.cpp index 6197f75..57a8a31 100644 --- a/JavaScriptCore/runtime/ObjectPrototype.cpp +++ b/JavaScriptCore/runtime/ObjectPrototype.cpp @@ -65,7 +65,7 @@ void ObjectPrototype::put(ExecState* exec, const Identifier& propertyName, JSVal if (m_hasNoPropertiesWithUInt32Names) { bool isUInt32; - propertyName.toStrictUInt32(&isUInt32); + propertyName.toUInt32(isUInt32); m_hasNoPropertiesWithUInt32Names = !isUInt32; } } diff --git a/JavaScriptCore/runtime/Operations.h b/JavaScriptCore/runtime/Operations.h index bd6c205..eed1f16 100644 --- a/JavaScriptCore/runtime/Operations.h +++ b/JavaScriptCore/runtime/Operations.h @@ -46,7 +46,7 @@ namespace JSC { if ((length1 + length2) < length1) return throwOutOfMemoryError(exec); - unsigned fiberCount = s1->size() + s2->size(); + unsigned fiberCount = s1->fiberCount() + s2->fiberCount(); JSGlobalData* globalData = &exec->globalData(); if (fiberCount <= JSString::s_maxInternalRopeLength) @@ -62,7 +62,7 @@ namespace JSC { ALWAYS_INLINE JSValue jsString(ExecState* exec, const UString& u1, JSString* s2) { - unsigned length1 = u1.size(); + unsigned length1 = u1.length(); if (!length1) return s2; unsigned length2 = s2->length(); @@ -71,7 +71,7 @@ namespace JSC { if ((length1 + length2) < length1) return throwOutOfMemoryError(exec); - unsigned fiberCount = 1 + s2->size(); + unsigned fiberCount = 1 + s2->fiberCount(); JSGlobalData* globalData = &exec->globalData(); if (fiberCount <= JSString::s_maxInternalRopeLength) @@ -90,13 +90,13 @@ namespace JSC { unsigned length1 = s1->length(); if (!length1) return jsString(exec, u2); - unsigned length2 = u2.size(); + unsigned length2 = u2.length(); if (!length2) return s1; if ((length1 + length2) < length1) return throwOutOfMemoryError(exec); - unsigned fiberCount = s1->size() + 1; + unsigned fiberCount = s1->fiberCount() + 1; JSGlobalData* globalData = &exec->globalData(); if (fiberCount <= JSString::s_maxInternalRopeLength) @@ -112,10 +112,10 @@ namespace JSC { ALWAYS_INLINE JSValue jsString(ExecState* exec, const UString& u1, const UString& u2) { - unsigned length1 = u1.size(); + unsigned length1 = u1.length(); if (!length1) return jsString(exec, u2); - unsigned length2 = u2.size(); + unsigned length2 = u2.length(); if (!length2) return jsString(exec, u1); if ((length1 + length2) < length1) @@ -127,9 +127,9 @@ namespace JSC { ALWAYS_INLINE JSValue jsString(ExecState* exec, const UString& u1, const UString& u2, const UString& u3) { - unsigned length1 = u1.size(); - unsigned length2 = u2.size(); - unsigned length3 = u3.size(); + unsigned length1 = u1.length(); + unsigned length2 = u2.length(); + unsigned length3 = u3.length(); if (!length1) return jsString(exec, u2, u3); if (!length2) @@ -154,7 +154,7 @@ namespace JSC { for (unsigned i = 0; i < count; ++i) { JSValue v = strings[i].jsValue(); if (LIKELY(v.isString())) - fiberCount += asString(v)->size(); + fiberCount += asString(v)->fiberCount(); else ++fiberCount; } @@ -193,13 +193,13 @@ namespace JSC { { unsigned fiberCount = 0; if (LIKELY(thisValue.isString())) - fiberCount += asString(thisValue)->size(); + fiberCount += asString(thisValue)->fiberCount(); else ++fiberCount; for (unsigned i = 0; i < exec->argumentCount(); ++i) { JSValue v = exec->argument(i); if (LIKELY(v.isString())) - fiberCount += asString(v)->size(); + fiberCount += asString(v)->fiberCount(); else ++fiberCount; } diff --git a/JavaScriptCore/runtime/PropertyMapHashTable.h b/JavaScriptCore/runtime/PropertyMapHashTable.h index 44dc2b8..bd452b6 100644 --- a/JavaScriptCore/runtime/PropertyMapHashTable.h +++ b/JavaScriptCore/runtime/PropertyMapHashTable.h @@ -27,13 +27,13 @@ namespace JSC { struct PropertyMapEntry { - UString::Rep* key; + StringImpl* key; unsigned offset; unsigned attributes; JSCell* specificValue; unsigned index; - PropertyMapEntry(UString::Rep* key, unsigned attributes, JSCell* specificValue) + PropertyMapEntry(StringImpl* key, unsigned attributes, JSCell* specificValue) : key(key) , offset(0) , attributes(attributes) @@ -42,7 +42,7 @@ namespace JSC { { } - PropertyMapEntry(UString::Rep* key, unsigned offset, unsigned attributes, JSCell* specificValue, unsigned index) + PropertyMapEntry(StringImpl* key, unsigned offset, unsigned attributes, JSCell* specificValue, unsigned index) : key(key) , offset(offset) , attributes(attributes) diff --git a/JavaScriptCore/runtime/PropertyNameArray.cpp b/JavaScriptCore/runtime/PropertyNameArray.cpp index 6b24669..afb41be 100644 --- a/JavaScriptCore/runtime/PropertyNameArray.cpp +++ b/JavaScriptCore/runtime/PropertyNameArray.cpp @@ -28,20 +28,20 @@ namespace JSC { static const size_t setThreshold = 20; -void PropertyNameArray::add(UString::Rep* identifier) +void PropertyNameArray::add(StringImpl* identifier) { - ASSERT(identifier == UString::null().rep() || identifier == UString::Rep::empty() || identifier->isIdentifier()); + ASSERT(!identifier || identifier == StringImpl::empty() || identifier->isIdentifier()); size_t size = m_data->propertyNameVector().size(); if (size < setThreshold) { for (size_t i = 0; i < size; ++i) { - if (identifier == m_data->propertyNameVector()[i].ustring().rep()) + if (identifier == m_data->propertyNameVector()[i].impl()) return; } } else { if (m_set.isEmpty()) { for (size_t i = 0; i < size; ++i) - m_set.add(m_data->propertyNameVector()[i].ustring().rep()); + m_set.add(m_data->propertyNameVector()[i].impl()); } if (!m_set.add(identifier).second) return; diff --git a/JavaScriptCore/runtime/PropertyNameArray.h b/JavaScriptCore/runtime/PropertyNameArray.h index 3dbcc9d..0da930f 100644 --- a/JavaScriptCore/runtime/PropertyNameArray.h +++ b/JavaScriptCore/runtime/PropertyNameArray.h @@ -68,9 +68,9 @@ namespace JSC { JSGlobalData* globalData() { return m_globalData; } - void add(const Identifier& identifier) { add(identifier.ustring().rep()); } - void add(UString::Rep*); - void addKnownUnique(UString::Rep* identifier) { m_data->propertyNameVector().append(Identifier(m_globalData, identifier)); } + void add(const Identifier& identifier) { add(identifier.impl()); } + void add(StringImpl*); + void addKnownUnique(StringImpl* identifier) { m_data->propertyNameVector().append(Identifier(m_globalData, identifier)); } Identifier& operator[](unsigned i) { return m_data->propertyNameVector()[i]; } const Identifier& operator[](unsigned i) const { return m_data->propertyNameVector()[i]; } @@ -86,7 +86,7 @@ namespace JSC { const_iterator end() const { return m_data->propertyNameVector().end(); } private: - typedef HashSet<UString::Rep*, PtrHash<UString::Rep*> > IdentifierSet; + typedef HashSet<StringImpl*, PtrHash<StringImpl*> > IdentifierSet; RefPtr<PropertyNameArrayData> m_data; IdentifierSet m_set; diff --git a/JavaScriptCore/runtime/RegExp.cpp b/JavaScriptCore/runtime/RegExp.cpp index 59e3f35..2b844c1 100644 --- a/JavaScriptCore/runtime/RegExp.cpp +++ b/JavaScriptCore/runtime/RegExp.cpp @@ -56,11 +56,11 @@ inline RegExp::RegExp(JSGlobalData* globalData, const UString& pattern, const US // NOTE: The global flag is handled on a case-by-case basis by functions like // String::match and RegExpObject::match. if (!flags.isNull()) { - if (flags.find('g') != UString::NotFound) + if (flags.find('g') != notFound) m_flagBits |= Global; - if (flags.find('i') != UString::NotFound) + if (flags.find('i') != notFound) m_flagBits |= IgnoreCase; - if (flags.find('m') != UString::NotFound) + if (flags.find('m') != notFound) m_flagBits |= Multiline; } compile(globalData); @@ -96,7 +96,7 @@ int RegExp::match(const UString& s, int startOffset, Vector<int, 32>* ovector) if (ovector) ovector->resize(0); - if (static_cast<unsigned>(startOffset) > s.size() || s.isNull()) { + if (static_cast<unsigned>(startOffset) > s.length() || s.isNull()) { m_lastMatchString = UString(); m_lastMatchStart = -1; m_lastOVector.shrink(0); @@ -105,7 +105,7 @@ int RegExp::match(const UString& s, int startOffset, Vector<int, 32>* ovector) // Perform check to see if this match call is the same as the last match invocation // and if it is return the prior result. - if ((startOffset == m_lastMatchStart) && (s.rep() == m_lastMatchString.rep())) { + if ((startOffset == m_lastMatchStart) && (s.impl() == m_lastMatchString.impl())) { if (ovector) *ovector = m_lastOVector; @@ -136,9 +136,9 @@ int RegExp::match(const UString& s, int startOffset, Vector<int, 32>* ovector) offsetVector[j] = -1; #if ENABLE(YARR_JIT) - int result = Yarr::executeRegex(m_regExpJITCode, s.data(), startOffset, s.size(), offsetVector, offsetVectorSize); + int result = Yarr::executeRegex(m_regExpJITCode, s.characters(), startOffset, s.length(), offsetVector, offsetVectorSize); #else - int result = Yarr::interpretRegex(m_regExpBytecode.get(), s.data(), startOffset, s.size(), offsetVector); + int result = Yarr::interpretRegex(m_regExpBytecode.get(), s.characters(), startOffset, s.length(), offsetVector); #endif if (result < 0) { @@ -176,7 +176,7 @@ void RegExp::compile(JSGlobalData*) m_regExp = 0; JSRegExpIgnoreCaseOption ignoreCaseOption = ignoreCase() ? JSRegExpIgnoreCase : JSRegExpDoNotIgnoreCase; JSRegExpMultilineOption multilineOption = multiline() ? JSRegExpMultiline : JSRegExpSingleLine; - m_regExp = jsRegExpCompile(reinterpret_cast<const UChar*>(m_pattern.data()), m_pattern.size(), ignoreCaseOption, multilineOption, &m_numSubpatterns, &m_constructionError); + m_regExp = jsRegExpCompile(reinterpret_cast<const UChar*>(m_pattern.characters()), m_pattern.length(), ignoreCaseOption, multilineOption, &m_numSubpatterns, &m_constructionError); } int RegExp::match(const UString& s, int startOffset, Vector<int, 32>* ovector) @@ -186,7 +186,7 @@ int RegExp::match(const UString& s, int startOffset, Vector<int, 32>* ovector) if (ovector) ovector->clear(); - if (static_cast<unsigned>(startOffset) > s.size() || s.isNull()) + if (static_cast<unsigned>(startOffset) > s.length() || s.isNull()) return -1; if (m_regExp) { @@ -204,7 +204,7 @@ int RegExp::match(const UString& s, int startOffset, Vector<int, 32>* ovector) offsetVector = ovector->data(); } - int numMatches = jsRegExpExecute(m_regExp, reinterpret_cast<const UChar*>(s.data()), s.size(), startOffset, offsetVector, offsetVectorSize); + int numMatches = jsRegExpExecute(m_regExp, reinterpret_cast<const UChar*>(s.characters()), s.length(), startOffset, offsetVector, offsetVectorSize); if (numMatches < 0) { #ifndef NDEBUG diff --git a/JavaScriptCore/runtime/RegExpCache.cpp b/JavaScriptCore/runtime/RegExpCache.cpp index b9d250d..d101758 100644 --- a/JavaScriptCore/runtime/RegExpCache.cpp +++ b/JavaScriptCore/runtime/RegExpCache.cpp @@ -33,7 +33,7 @@ namespace JSC { PassRefPtr<RegExp> RegExpCache::lookupOrCreate(const UString& patternString, const UString& flags) { - if (patternString.size() < maxCacheablePatternLength) { + if (patternString.length() < maxCacheablePatternLength) { pair<RegExpCacheMap::iterator, bool> result = m_cacheMap.add(RegExpKey(flags, patternString), 0); if (!result.second) return result.first->second; @@ -47,7 +47,7 @@ PassRefPtr<RegExp> RegExpCache::create(const UString& patternString, const UStri { RefPtr<RegExp> regExp = RegExp::create(m_globalData, patternString, flags); - if (patternString.size() >= maxCacheablePatternLength) + if (patternString.length() >= maxCacheablePatternLength) return regExp; RegExpKey key = RegExpKey(flags, patternString); @@ -63,7 +63,7 @@ PassRefPtr<RegExp> RegExpCache::create(const UString& patternString, const UStri m_cacheMap.remove(RegExpKey(patternKeyArray[m_nextKeyToEvict].flagsValue, patternKeyArray[m_nextKeyToEvict].pattern)); patternKeyArray[m_nextKeyToEvict].flagsValue = key.flagsValue; - patternKeyArray[m_nextKeyToEvict].pattern = patternString.rep(); + patternKeyArray[m_nextKeyToEvict].pattern = patternString.impl(); return regExp; } diff --git a/JavaScriptCore/runtime/RegExpCache.h b/JavaScriptCore/runtime/RegExpCache.h index fb30a9e..e897b43 100644 --- a/JavaScriptCore/runtime/RegExpCache.h +++ b/JavaScriptCore/runtime/RegExpCache.h @@ -28,6 +28,8 @@ #include "RegExp.h" #include "RegExpKey.h" #include "UString.h" +#include <wtf/FixedArray.h> +#include <wtf/HashMap.h> #ifndef RegExpCache_h #define RegExpCache_h diff --git a/JavaScriptCore/runtime/RegExpConstructor.cpp b/JavaScriptCore/runtime/RegExpConstructor.cpp index aff83e7..214e528 100644 --- a/JavaScriptCore/runtime/RegExpConstructor.cpp +++ b/JavaScriptCore/runtime/RegExpConstructor.cpp @@ -35,6 +35,7 @@ #include "RegExpPrototype.h" #include "RegExp.h" #include "RegExpCache.h" +#include "StringConcatenate.h" #include <wtf/PassOwnPtr.h> namespace JSC { @@ -185,7 +186,7 @@ JSValue RegExpConstructor::getLeftContext(ExecState* exec) const JSValue RegExpConstructor::getRightContext(ExecState* exec) const { if (!d->lastOvector().isEmpty()) - return jsSubstring(exec, d->lastInput, d->lastOvector()[1], d->lastInput.size() - d->lastOvector()[1]); + return jsSubstring(exec, d->lastInput, d->lastOvector()[1], d->lastInput.length() - d->lastOvector()[1]); return jsEmptyString(exec); } diff --git a/JavaScriptCore/runtime/RegExpKey.h b/JavaScriptCore/runtime/RegExpKey.h index 2bbdb07..cd1368d 100644 --- a/JavaScriptCore/runtime/RegExpKey.h +++ b/JavaScriptCore/runtime/RegExpKey.h @@ -26,6 +26,7 @@ */ #include "UString.h" +#include <wtf/text/StringHash.h> #ifndef RegExpKey_h #define RegExpKey_h @@ -34,7 +35,7 @@ namespace JSC { struct RegExpKey { int flagsValue; - RefPtr<UString::Rep> pattern; + RefPtr<StringImpl> pattern; RegExpKey() : flagsValue(0) @@ -48,18 +49,24 @@ struct RegExpKey { RegExpKey(int flags, const UString& pattern) : flagsValue(flags) - , pattern(pattern.rep()) + , pattern(pattern.impl()) { } - RegExpKey(int flags, const PassRefPtr<UString::Rep> pattern) + RegExpKey(int flags, const PassRefPtr<StringImpl> pattern) + : flagsValue(flags) + , pattern(pattern) + { + } + + RegExpKey(int flags, const RefPtr<StringImpl>& pattern) : flagsValue(flags) , pattern(pattern) { } RegExpKey(const UString& flags, const UString& pattern) - : pattern(pattern.rep()) + : pattern(pattern.impl()) { flagsValue = getFlagsValue(flags); } @@ -67,11 +74,11 @@ struct RegExpKey { int getFlagsValue(const UString flags) { flagsValue = 0; - if (flags.find('g') != UString::NotFound) + if (flags.find('g') != notFound) flagsValue += 4; - if (flags.find('i') != UString::NotFound) + if (flags.find('i') != notFound) flagsValue += 2; - if (flags.find('m') != UString::NotFound) + if (flags.find('m') != notFound) flagsValue += 1; return flagsValue; } diff --git a/JavaScriptCore/runtime/RegExpObject.cpp b/JavaScriptCore/runtime/RegExpObject.cpp index 0f2c1e1..4462879 100644 --- a/JavaScriptCore/runtime/RegExpObject.cpp +++ b/JavaScriptCore/runtime/RegExpObject.cpp @@ -29,6 +29,7 @@ #include "Lookup.h" #include "RegExpConstructor.h" #include "RegExpPrototype.h" +#include "StringConcatenate.h" #include <wtf/PassOwnPtr.h> namespace JSC { @@ -156,7 +157,7 @@ bool RegExpObject::match(ExecState* exec) return position >= 0; } - if (d->lastIndex < 0 || d->lastIndex > input.size()) { + if (d->lastIndex < 0 || d->lastIndex > input.length()) { d->lastIndex = 0; return false; } diff --git a/JavaScriptCore/runtime/RegExpPrototype.cpp b/JavaScriptCore/runtime/RegExpPrototype.cpp index ac215ec..d66f5d7 100644 --- a/JavaScriptCore/runtime/RegExpPrototype.cpp +++ b/JavaScriptCore/runtime/RegExpPrototype.cpp @@ -120,7 +120,7 @@ EncodedJSValue JSC_HOST_CALL regExpProtoFuncToString(ExecState* exec) postfix[index] = 'm'; UString source = asRegExpObject(thisValue)->get(exec, exec->propertyNames().source).toString(exec); // If source is empty, use "/(?:)/" to avoid colliding with comment syntax - return JSValue::encode(jsMakeNontrivialString(exec, "/", source.size() ? source : UString("(?:)"), postfix)); + return JSValue::encode(jsMakeNontrivialString(exec, "/", source.length() ? source : UString("(?:)"), postfix)); } } // namespace JSC diff --git a/JavaScriptCore/runtime/RopeImpl.cpp b/JavaScriptCore/runtime/RopeImpl.cpp index 25b9848..09c24a9 100644 --- a/JavaScriptCore/runtime/RopeImpl.cpp +++ b/JavaScriptCore/runtime/RopeImpl.cpp @@ -40,7 +40,7 @@ void RopeImpl::derefFibersNonRecursive(Vector<RopeImpl*, 32>& workQueue) else nextRope->deref(); } else - static_cast<UStringImpl*>(fiber)->deref(); + static_cast<StringImpl*>(fiber)->deref(); } } diff --git a/JavaScriptCore/runtime/RopeImpl.h b/JavaScriptCore/runtime/RopeImpl.h index ac2b502..dfacbf5 100644 --- a/JavaScriptCore/runtime/RopeImpl.h +++ b/JavaScriptCore/runtime/RopeImpl.h @@ -26,14 +26,14 @@ #ifndef RopeImpl_h #define RopeImpl_h -#include "UStringImpl.h" +#include <wtf/text/StringImpl.h> namespace JSC { class RopeImpl : public StringImplBase { public: // A RopeImpl is composed from a set of smaller strings called Fibers. - // Each Fiber in a rope is either UStringImpl or another RopeImpl. + // Each Fiber in a rope is either StringImpl or another RopeImpl. typedef StringImplBase* Fiber; // Creates a RopeImpl comprising of 'fiberCount' Fibers. @@ -56,7 +56,7 @@ public: if (isRope(fiber)) static_cast<RopeImpl*>(fiber)->deref(); else - static_cast<UStringImpl*>(fiber)->deref(); + static_cast<StringImpl*>(fiber)->deref(); } void initializeFiber(unsigned &index, Fiber fiber) diff --git a/JavaScriptCore/runtime/ScopeChain.cpp b/JavaScriptCore/runtime/ScopeChain.cpp index 981794b..54c5082 100644 --- a/JavaScriptCore/runtime/ScopeChain.cpp +++ b/JavaScriptCore/runtime/ScopeChain.cpp @@ -43,7 +43,7 @@ void ScopeChainNode::print() const fprintf(stderr, "----- [scope %p] -----\n", o); for (PropertyNameArray::const_iterator propIter = propertyNames.begin(); propIter != propEnd; propIter++) { Identifier name = *propIter; - fprintf(stderr, "%s, ", name.ascii()); + fprintf(stderr, "%s, ", name.ustring().utf8().data()); } fprintf(stderr, "\n"); } diff --git a/JavaScriptCore/runtime/SmallStrings.cpp b/JavaScriptCore/runtime/SmallStrings.cpp index 822303c..f358727 100644 --- a/JavaScriptCore/runtime/SmallStrings.cpp +++ b/JavaScriptCore/runtime/SmallStrings.cpp @@ -44,19 +44,19 @@ class SmallStringsStorage : public Noncopyable { public: SmallStringsStorage(); - UString::Rep* rep(unsigned char character) { return m_reps[character].get(); } + StringImpl* rep(unsigned char character) { return m_reps[character].get(); } private: - RefPtr<UString::Rep> m_reps[numCharactersToStore]; + RefPtr<StringImpl> m_reps[numCharactersToStore]; }; SmallStringsStorage::SmallStringsStorage() { UChar* characterBuffer = 0; - RefPtr<UStringImpl> baseString = UStringImpl::createUninitialized(numCharactersToStore, characterBuffer); + RefPtr<StringImpl> baseString = StringImpl::createUninitialized(numCharactersToStore, characterBuffer); for (unsigned i = 0; i < numCharactersToStore; ++i) { characterBuffer[i] = i; - m_reps[i] = UStringImpl::create(baseString, i, 1); + m_reps[i] = StringImpl::create(baseString, i, 1); } } @@ -129,10 +129,10 @@ void SmallStrings::createSingleCharacterString(JSGlobalData* globalData, unsigne if (!m_storage) m_storage = adoptPtr(new SmallStringsStorage); ASSERT(!m_singleCharacterStrings[character]); - m_singleCharacterStrings[character] = new (globalData) JSString(globalData, m_storage->rep(character), JSString::HasOtherOwner); + m_singleCharacterStrings[character] = new (globalData) JSString(globalData, PassRefPtr<StringImpl>(m_storage->rep(character)), JSString::HasOtherOwner); } -UString::Rep* SmallStrings::singleCharacterStringRep(unsigned char character) +StringImpl* SmallStrings::singleCharacterStringRep(unsigned char character) { if (!m_storage) m_storage = adoptPtr(new SmallStringsStorage); diff --git a/JavaScriptCore/runtime/SmallStrings.h b/JavaScriptCore/runtime/SmallStrings.h index b550a04..d1ebfb1 100644 --- a/JavaScriptCore/runtime/SmallStrings.h +++ b/JavaScriptCore/runtime/SmallStrings.h @@ -55,7 +55,7 @@ namespace JSC { return m_singleCharacterStrings[character]; } - UString::Rep* singleCharacterStringRep(unsigned char character); + StringImpl* singleCharacterStringRep(unsigned char character); void markChildren(MarkStack&); void clear(); diff --git a/JavaScriptCore/runtime/StringBuilder.h b/JavaScriptCore/runtime/StringBuilder.h index 59b01e0..a26b94c 100644 --- a/JavaScriptCore/runtime/StringBuilder.h +++ b/JavaScriptCore/runtime/StringBuilder.h @@ -56,7 +56,7 @@ public: void append(const UString& str) { - buffer.append(str.data(), str.size()); + buffer.append(str.characters(), str.length()); } bool isEmpty() { return buffer.isEmpty(); } diff --git a/JavaScriptCore/runtime/StringConcatenate.h b/JavaScriptCore/runtime/StringConcatenate.h new file mode 100644 index 0000000..18a52ef --- /dev/null +++ b/JavaScriptCore/runtime/StringConcatenate.h @@ -0,0 +1,428 @@ +/* + * Copyright (C) 2010 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef StringConcatenate_h +#define StringConcatenate_h + +#include "UString.h" + +namespace JSC { + +template<typename StringType> +class StringTypeAdapter { +}; + +template<> +class StringTypeAdapter<char*> { +public: + StringTypeAdapter<char*>(char* buffer) + : m_buffer((unsigned char*)buffer) + , m_length(strlen(buffer)) + { + } + + unsigned length() { return m_length; } + + void writeTo(UChar* destination) + { + for (unsigned i = 0; i < m_length; ++i) + destination[i] = m_buffer[i]; + } + +private: + const unsigned char* m_buffer; + unsigned m_length; +}; + +template<> +class StringTypeAdapter<const char*> { +public: + StringTypeAdapter<const char*>(const char* buffer) + : m_buffer((unsigned char*)buffer) + , m_length(strlen(buffer)) + { + } + + unsigned length() { return m_length; } + + void writeTo(UChar* destination) + { + for (unsigned i = 0; i < m_length; ++i) + destination[i] = m_buffer[i]; + } + +private: + const unsigned char* m_buffer; + unsigned m_length; +}; + +template<> +class StringTypeAdapter<UString> { +public: + StringTypeAdapter<UString>(UString& string) + : m_data(string.characters()) + , m_length(string.length()) + { + } + + unsigned length() { return m_length; } + + void writeTo(UChar* destination) + { + for (unsigned i = 0; i < m_length; ++i) + destination[i] = m_data[i]; + } + +private: + const UChar* m_data; + unsigned m_length; +}; + +inline void sumWithOverflow(unsigned& total, unsigned addend, bool& overflow) +{ + unsigned oldTotal = total; + total = oldTotal + addend; + if (total < oldTotal) + overflow = true; +} + +template<typename StringType1, typename StringType2> +PassRefPtr<StringImpl> tryMakeString(StringType1 string1, StringType2 string2) +{ + StringTypeAdapter<StringType1> adapter1(string1); + StringTypeAdapter<StringType2> adapter2(string2); + + UChar* buffer; + bool overflow = false; + unsigned length = adapter1.length(); + sumWithOverflow(length, adapter2.length(), overflow); + if (overflow) + return 0; + PassRefPtr<StringImpl> resultImpl = StringImpl::tryCreateUninitialized(length, buffer); + if (!resultImpl) + return 0; + + UChar* result = buffer; + adapter1.writeTo(result); + result += adapter1.length(); + adapter2.writeTo(result); + + return resultImpl; +} + +template<typename StringType1, typename StringType2, typename StringType3> +PassRefPtr<StringImpl> tryMakeString(StringType1 string1, StringType2 string2, StringType3 string3) +{ + StringTypeAdapter<StringType1> adapter1(string1); + StringTypeAdapter<StringType2> adapter2(string2); + StringTypeAdapter<StringType3> adapter3(string3); + + UChar* buffer = 0; + bool overflow = false; + unsigned length = adapter1.length(); + sumWithOverflow(length, adapter2.length(), overflow); + sumWithOverflow(length, adapter3.length(), overflow); + if (overflow) + return 0; + PassRefPtr<StringImpl> resultImpl = StringImpl::tryCreateUninitialized(length, buffer); + if (!resultImpl) + return 0; + + UChar* result = buffer; + adapter1.writeTo(result); + result += adapter1.length(); + adapter2.writeTo(result); + result += adapter2.length(); + adapter3.writeTo(result); + + return resultImpl; +} + +template<typename StringType1, typename StringType2, typename StringType3, typename StringType4> +PassRefPtr<StringImpl> tryMakeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4) +{ + StringTypeAdapter<StringType1> adapter1(string1); + StringTypeAdapter<StringType2> adapter2(string2); + StringTypeAdapter<StringType3> adapter3(string3); + StringTypeAdapter<StringType4> adapter4(string4); + + UChar* buffer; + bool overflow = false; + unsigned length = adapter1.length(); + sumWithOverflow(length, adapter2.length(), overflow); + sumWithOverflow(length, adapter3.length(), overflow); + sumWithOverflow(length, adapter4.length(), overflow); + if (overflow) + return 0; + PassRefPtr<StringImpl> resultImpl = StringImpl::tryCreateUninitialized(length, buffer); + if (!resultImpl) + return 0; + + UChar* result = buffer; + adapter1.writeTo(result); + result += adapter1.length(); + adapter2.writeTo(result); + result += adapter2.length(); + adapter3.writeTo(result); + result += adapter3.length(); + adapter4.writeTo(result); + + return resultImpl; +} + +template<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5> +PassRefPtr<StringImpl> tryMakeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5) +{ + StringTypeAdapter<StringType1> adapter1(string1); + StringTypeAdapter<StringType2> adapter2(string2); + StringTypeAdapter<StringType3> adapter3(string3); + StringTypeAdapter<StringType4> adapter4(string4); + StringTypeAdapter<StringType5> adapter5(string5); + + UChar* buffer; + bool overflow = false; + unsigned length = adapter1.length(); + sumWithOverflow(length, adapter2.length(), overflow); + sumWithOverflow(length, adapter3.length(), overflow); + sumWithOverflow(length, adapter4.length(), overflow); + sumWithOverflow(length, adapter5.length(), overflow); + if (overflow) + return 0; + PassRefPtr<StringImpl> resultImpl = StringImpl::tryCreateUninitialized(length, buffer); + if (!resultImpl) + return 0; + + UChar* result = buffer; + adapter1.writeTo(result); + result += adapter1.length(); + adapter2.writeTo(result); + result += adapter2.length(); + adapter3.writeTo(result); + result += adapter3.length(); + adapter4.writeTo(result); + result += adapter4.length(); + adapter5.writeTo(result); + + return resultImpl; +} + +template<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5, typename StringType6> +PassRefPtr<StringImpl> tryMakeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5, StringType6 string6) +{ + StringTypeAdapter<StringType1> adapter1(string1); + StringTypeAdapter<StringType2> adapter2(string2); + StringTypeAdapter<StringType3> adapter3(string3); + StringTypeAdapter<StringType4> adapter4(string4); + StringTypeAdapter<StringType5> adapter5(string5); + StringTypeAdapter<StringType6> adapter6(string6); + + UChar* buffer; + bool overflow = false; + unsigned length = adapter1.length(); + sumWithOverflow(length, adapter2.length(), overflow); + sumWithOverflow(length, adapter3.length(), overflow); + sumWithOverflow(length, adapter4.length(), overflow); + sumWithOverflow(length, adapter5.length(), overflow); + sumWithOverflow(length, adapter6.length(), overflow); + if (overflow) + return 0; + PassRefPtr<StringImpl> resultImpl = StringImpl::tryCreateUninitialized(length, buffer); + if (!resultImpl) + return 0; + + UChar* result = buffer; + adapter1.writeTo(result); + result += adapter1.length(); + adapter2.writeTo(result); + result += adapter2.length(); + adapter3.writeTo(result); + result += adapter3.length(); + adapter4.writeTo(result); + result += adapter4.length(); + adapter5.writeTo(result); + result += adapter5.length(); + adapter6.writeTo(result); + + return resultImpl; +} + +template<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5, typename StringType6, typename StringType7> +PassRefPtr<StringImpl> tryMakeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5, StringType6 string6, StringType7 string7) +{ + StringTypeAdapter<StringType1> adapter1(string1); + StringTypeAdapter<StringType2> adapter2(string2); + StringTypeAdapter<StringType3> adapter3(string3); + StringTypeAdapter<StringType4> adapter4(string4); + StringTypeAdapter<StringType5> adapter5(string5); + StringTypeAdapter<StringType6> adapter6(string6); + StringTypeAdapter<StringType7> adapter7(string7); + + UChar* buffer; + bool overflow = false; + unsigned length = adapter1.length(); + sumWithOverflow(length, adapter2.length(), overflow); + sumWithOverflow(length, adapter3.length(), overflow); + sumWithOverflow(length, adapter4.length(), overflow); + sumWithOverflow(length, adapter5.length(), overflow); + sumWithOverflow(length, adapter6.length(), overflow); + sumWithOverflow(length, adapter7.length(), overflow); + if (overflow) + return 0; + PassRefPtr<StringImpl> resultImpl = StringImpl::tryCreateUninitialized(length, buffer); + if (!resultImpl) + return 0; + + UChar* result = buffer; + adapter1.writeTo(result); + result += adapter1.length(); + adapter2.writeTo(result); + result += adapter2.length(); + adapter3.writeTo(result); + result += adapter3.length(); + adapter4.writeTo(result); + result += adapter4.length(); + adapter5.writeTo(result); + result += adapter5.length(); + adapter6.writeTo(result); + result += adapter6.length(); + adapter7.writeTo(result); + + return resultImpl; +} + +template<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5, typename StringType6, typename StringType7, typename StringType8> +PassRefPtr<StringImpl> tryMakeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5, StringType6 string6, StringType7 string7, StringType8 string8) +{ + StringTypeAdapter<StringType1> adapter1(string1); + StringTypeAdapter<StringType2> adapter2(string2); + StringTypeAdapter<StringType3> adapter3(string3); + StringTypeAdapter<StringType4> adapter4(string4); + StringTypeAdapter<StringType5> adapter5(string5); + StringTypeAdapter<StringType6> adapter6(string6); + StringTypeAdapter<StringType7> adapter7(string7); + StringTypeAdapter<StringType8> adapter8(string8); + + UChar* buffer; + bool overflow = false; + unsigned length = adapter1.length(); + sumWithOverflow(length, adapter2.length(), overflow); + sumWithOverflow(length, adapter3.length(), overflow); + sumWithOverflow(length, adapter4.length(), overflow); + sumWithOverflow(length, adapter5.length(), overflow); + sumWithOverflow(length, adapter6.length(), overflow); + sumWithOverflow(length, adapter7.length(), overflow); + sumWithOverflow(length, adapter8.length(), overflow); + if (overflow) + return 0; + PassRefPtr<StringImpl> resultImpl = StringImpl::tryCreateUninitialized(length, buffer); + if (!resultImpl) + return 0; + + UChar* result = buffer; + adapter1.writeTo(result); + result += adapter1.length(); + adapter2.writeTo(result); + result += adapter2.length(); + adapter3.writeTo(result); + result += adapter3.length(); + adapter4.writeTo(result); + result += adapter4.length(); + adapter5.writeTo(result); + result += adapter5.length(); + adapter6.writeTo(result); + result += adapter6.length(); + adapter7.writeTo(result); + result += adapter7.length(); + adapter8.writeTo(result); + + return resultImpl; +} + +template<typename StringType1, typename StringType2> +UString makeString(StringType1 string1, StringType2 string2) +{ + PassRefPtr<StringImpl> resultImpl = tryMakeString(string1, string2); + if (!resultImpl) + CRASH(); + return resultImpl; +} + +template<typename StringType1, typename StringType2, typename StringType3> +UString makeString(StringType1 string1, StringType2 string2, StringType3 string3) +{ + PassRefPtr<StringImpl> resultImpl = tryMakeString(string1, string2, string3); + if (!resultImpl) + CRASH(); + return resultImpl; +} + +template<typename StringType1, typename StringType2, typename StringType3, typename StringType4> +UString makeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4) +{ + PassRefPtr<StringImpl> resultImpl = tryMakeString(string1, string2, string3, string4); + if (!resultImpl) + CRASH(); + return resultImpl; +} + +template<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5> +UString makeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5) +{ + PassRefPtr<StringImpl> resultImpl = tryMakeString(string1, string2, string3, string4, string5); + if (!resultImpl) + CRASH(); + return resultImpl; +} + +template<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5, typename StringType6> +UString makeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5, StringType6 string6) +{ + PassRefPtr<StringImpl> resultImpl = tryMakeString(string1, string2, string3, string4, string5, string6); + if (!resultImpl) + CRASH(); + return resultImpl; +} + +template<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5, typename StringType6, typename StringType7> +UString makeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5, StringType6 string6, StringType7 string7) +{ + PassRefPtr<StringImpl> resultImpl = tryMakeString(string1, string2, string3, string4, string5, string6, string7); + if (!resultImpl) + CRASH(); + return resultImpl; +} + +template<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5, typename StringType6, typename StringType7, typename StringType8> +UString makeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5, StringType6 string6, StringType7 string7, StringType8 string8) +{ + PassRefPtr<StringImpl> resultImpl = tryMakeString(string1, string2, string3, string4, string5, string6, string7, string8); + if (!resultImpl) + CRASH(); + return resultImpl; +} + +} // namespace JSC + +#endif diff --git a/JavaScriptCore/runtime/StringConstructor.cpp b/JavaScriptCore/runtime/StringConstructor.cpp index f02ab09..159386d 100644 --- a/JavaScriptCore/runtime/StringConstructor.cpp +++ b/JavaScriptCore/runtime/StringConstructor.cpp @@ -34,7 +34,7 @@ static NEVER_INLINE JSValue stringFromCharCodeSlowCase(ExecState* exec) { unsigned length = exec->argumentCount(); UChar* buf; - PassRefPtr<UStringImpl> impl = UStringImpl::createUninitialized(length, buf); + PassRefPtr<StringImpl> impl = StringImpl::createUninitialized(length, buf); for (unsigned i = 0; i < length; ++i) buf[i] = static_cast<UChar>(exec->argument(i).toUInt32(exec)); return jsString(exec, impl); diff --git a/JavaScriptCore/runtime/StringObject.cpp b/JavaScriptCore/runtime/StringObject.cpp index f8e0e87..dc27618 100644 --- a/JavaScriptCore/runtime/StringObject.cpp +++ b/JavaScriptCore/runtime/StringObject.cpp @@ -80,7 +80,7 @@ bool StringObject::deleteProperty(ExecState* exec, const Identifier& propertyNam if (propertyName == exec->propertyNames().length) return false; bool isStrictUInt32; - unsigned i = propertyName.toStrictUInt32(&isStrictUInt32); + unsigned i = propertyName.toUInt32(isStrictUInt32); if (isStrictUInt32 && internalValue()->canGetIndex(i)) return false; return JSObject::deleteProperty(exec, propertyName); @@ -90,7 +90,7 @@ void StringObject::getOwnPropertyNames(ExecState* exec, PropertyNameArray& prope { int size = internalValue()->length(); for (int i = 0; i < size; ++i) - propertyNames.add(Identifier(exec, UString::from(i))); + propertyNames.add(Identifier(exec, UString::number(i))); if (mode == IncludeDontEnumProperties) propertyNames.add(exec->propertyNames().length); return JSObject::getOwnPropertyNames(exec, propertyNames, mode); diff --git a/JavaScriptCore/runtime/StringPrototype.cpp b/JavaScriptCore/runtime/StringPrototype.cpp index fb6e0f3..cfbb3be 100644 --- a/JavaScriptCore/runtime/StringPrototype.cpp +++ b/JavaScriptCore/runtime/StringPrototype.cpp @@ -151,19 +151,19 @@ bool StringPrototype::getOwnPropertyDescriptor(ExecState* exec, const Identifier // ------------------------------ Functions -------------------------- -static NEVER_INLINE UString substituteBackreferencesSlow(const UString& replacement, const UString& source, const int* ovector, RegExp* reg, unsigned i) +static NEVER_INLINE UString substituteBackreferencesSlow(const UString& replacement, const UString& source, const int* ovector, RegExp* reg, size_t i) { Vector<UChar> substitutedReplacement; int offset = 0; do { - if (i + 1 == replacement.size()) + if (i + 1 == replacement.length()) break; UChar ref = replacement[i + 1]; if (ref == '$') { // "$$" -> "$" ++i; - substitutedReplacement.append(replacement.data() + offset, i - offset); + substitutedReplacement.append(replacement.characters() + offset, i - offset); offset = i + 1; continue; } @@ -179,13 +179,13 @@ static NEVER_INLINE UString substituteBackreferencesSlow(const UString& replacem backrefLength = ovector[0]; } else if (ref == '\'') { backrefStart = ovector[1]; - backrefLength = source.size() - backrefStart; + backrefLength = source.length() - backrefStart; } else if (reg && ref >= '0' && ref <= '9') { // 1- and 2-digit back references are allowed unsigned backrefIndex = ref - '0'; if (backrefIndex > reg->numSubpatterns()) continue; - if (replacement.size() > i + 2) { + if (replacement.length() > i + 2) { ref = replacement[i + 2]; if (ref >= '0' && ref <= '9') { backrefIndex = 10 * backrefIndex + ref - '0'; @@ -203,14 +203,14 @@ static NEVER_INLINE UString substituteBackreferencesSlow(const UString& replacem continue; if (i - offset) - substitutedReplacement.append(replacement.data() + offset, i - offset); + substitutedReplacement.append(replacement.characters() + offset, i - offset); i += 1 + advance; offset = i + 1; - substitutedReplacement.append(source.data() + backrefStart, backrefLength); - } while ((i = replacement.find('$', i + 1)) != UString::NotFound); + substitutedReplacement.append(source.characters() + backrefStart, backrefLength); + } while ((i = replacement.find('$', i + 1)) != notFound); - if (replacement.size() - offset) - substitutedReplacement.append(replacement.data() + offset, replacement.size() - offset); + if (replacement.length() - offset) + substitutedReplacement.append(replacement.characters() + offset, replacement.length() - offset); substitutedReplacement.shrinkToFit(); return UString::adopt(substitutedReplacement); @@ -218,15 +218,15 @@ static NEVER_INLINE UString substituteBackreferencesSlow(const UString& replacem static inline UString substituteBackreferences(const UString& replacement, const UString& source, const int* ovector, RegExp* reg) { - unsigned i = replacement.find('$', 0); - if (UNLIKELY(i != UString::NotFound)) + size_t i = replacement.find('$', 0); + if (UNLIKELY(i != notFound)) return substituteBackreferencesSlow(replacement, source, ovector, reg, i); return replacement; } static inline int localeCompare(const UString& a, const UString& b) { - return Collator::userDefault()->collate(reinterpret_cast<const ::UChar*>(a.data()), a.size(), reinterpret_cast<const ::UChar*>(b.data()), b.size()); + return Collator::userDefault()->collate(reinterpret_cast<const ::UChar*>(a.characters()), a.length(), reinterpret_cast<const ::UChar*>(b.characters()), b.length()); } struct StringRange { @@ -248,26 +248,26 @@ public: static ALWAYS_INLINE JSValue jsSpliceSubstringsWithSeparators(ExecState* exec, JSString* sourceVal, const UString& source, const StringRange* substringRanges, int rangeCount, const UString* separators, int separatorCount) { if (rangeCount == 1 && separatorCount == 0) { - int sourceSize = source.size(); + int sourceSize = source.length(); int position = substringRanges[0].position; int length = substringRanges[0].length; if (position <= 0 && length >= sourceSize) return sourceVal; // We could call UString::substr, but this would result in redundant checks - return jsString(exec, UStringImpl::create(source.rep(), max(0, position), min(sourceSize, length))); + return jsString(exec, StringImpl::create(source.impl(), max(0, position), min(sourceSize, length))); } int totalLength = 0; for (int i = 0; i < rangeCount; i++) totalLength += substringRanges[i].length; for (int i = 0; i < separatorCount; i++) - totalLength += separators[i].size(); + totalLength += separators[i].length(); if (totalLength == 0) return jsString(exec, ""); UChar* buffer; - PassRefPtr<UStringImpl> impl = UStringImpl::tryCreateUninitialized(totalLength, buffer); + PassRefPtr<StringImpl> impl = StringImpl::tryCreateUninitialized(totalLength, buffer); if (!impl) return throwOutOfMemoryError(exec); @@ -275,12 +275,12 @@ static ALWAYS_INLINE JSValue jsSpliceSubstringsWithSeparators(ExecState* exec, J int bufferPos = 0; for (int i = 0; i < maxCount; i++) { if (i < rangeCount) { - UStringImpl::copyChars(buffer + bufferPos, source.data() + substringRanges[i].position, substringRanges[i].length); + StringImpl::copyChars(buffer + bufferPos, source.characters() + substringRanges[i].position, substringRanges[i].length); bufferPos += substringRanges[i].length; } if (i < separatorCount) { - UStringImpl::copyChars(buffer + bufferPos, separators[i].data(), separators[i].size()); - bufferPos += separators[i].size(); + StringImpl::copyChars(buffer + bufferPos, separators[i].characters(), separators[i].length()); + bufferPos += separators[i].length(); } } @@ -363,7 +363,7 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncReplace(ExecState* exec) // special case of empty match if (matchLen == 0) { startPosition++; - if (startPosition > source.size()) + if (startPosition > source.length()) break; } } @@ -407,7 +407,7 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncReplace(ExecState* exec) // special case of empty match if (matchLen == 0) { startPosition++; - if (startPosition > source.size()) + if (startPosition > source.length()) break; } } while (global); @@ -416,8 +416,8 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncReplace(ExecState* exec) if (!lastIndex && replacements.isEmpty()) return JSValue::encode(sourceVal); - if (static_cast<unsigned>(lastIndex) < source.size()) - sourceRanges.append(StringRange(lastIndex, source.size() - lastIndex)); + if (static_cast<unsigned>(lastIndex) < source.length()) + sourceRanges.append(StringRange(lastIndex, source.length() - lastIndex)); return JSValue::encode(jsSpliceSubstringsWithSeparators(exec, sourceVal, source, sourceRanges.data(), sourceRanges.size(), replacements.data(), replacements.size())); } @@ -425,16 +425,16 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncReplace(ExecState* exec) // Not a regular expression, so treat the pattern as a string. UString patternString = pattern.toString(exec); - if (patternString.size() == 1 && callType == CallTypeNone) + if (patternString.length() == 1 && callType == CallTypeNone) return JSValue::encode(sourceVal->replaceCharacter(exec, patternString[0], replacementString)); const UString& source = sourceVal->value(exec); - unsigned matchPos = source.find(patternString); + size_t matchPos = source.find(patternString); - if (matchPos == UString::NotFound) + if (matchPos == notFound) return JSValue::encode(sourceVal); - int matchLen = patternString.size(); + int matchLen = patternString.length(); if (callType != CallTypeNone) { MarkedArgumentBuffer args; args.append(jsSubstring(exec, source, matchPos, matchLen)); @@ -446,7 +446,7 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncReplace(ExecState* exec) size_t matchEnd = matchPos + matchLen; int ovector[2] = { matchPos, matchEnd }; - return JSValue::encode(jsString(exec, source.substr(0, matchPos), substituteBackreferences(replacementString, source, ovector, 0), source.substr(matchEnd))); + return JSValue::encode(jsString(exec, source.substringSharingImpl(0, matchPos), substituteBackreferences(replacementString, source, ovector, 0), source.substringSharingImpl(matchEnd))); } EncodedJSValue JSC_HOST_CALL stringProtoFuncToString(ExecState* exec) @@ -469,7 +469,7 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncCharAt(ExecState* exec) if (thisValue.isUndefinedOrNull()) // CheckObjectCoercible return throwVMTypeError(exec); UString s = thisValue.toThisString(exec); - unsigned len = s.size(); + unsigned len = s.length(); JSValue a0 = exec->argument(0); if (a0.isUInt32()) { uint32_t i = a0.asUInt32(); @@ -489,12 +489,12 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncCharCodeAt(ExecState* exec) if (thisValue.isUndefinedOrNull()) // CheckObjectCoercible return throwVMTypeError(exec); UString s = thisValue.toThisString(exec); - unsigned len = s.size(); + unsigned len = s.length(); JSValue a0 = exec->argument(0); if (a0.isUInt32()) { uint32_t i = a0.asUInt32(); if (i < len) - return JSValue::encode(jsNumber(exec, s.data()[i])); + return JSValue::encode(jsNumber(exec, s.characters()[i])); return JSValue::encode(jsNaN(exec)); } double dpos = a0.toInteger(exec); @@ -523,7 +523,7 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncIndexOf(ExecState* exec) if (thisValue.isUndefinedOrNull()) // CheckObjectCoercible return throwVMTypeError(exec); UString s = thisValue.toThisString(exec); - int len = s.size(); + int len = s.length(); JSValue a0 = exec->argument(0); JSValue a1 = exec->argument(1); @@ -542,8 +542,8 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncIndexOf(ExecState* exec) pos = static_cast<int>(dpos); } - unsigned result = s.find(u2, pos); - if (result == UString::NotFound) + size_t result = s.find(u2, pos); + if (result == notFound) return JSValue::encode(jsNumber(exec, -1)); return JSValue::encode(jsNumber(exec, result)); } @@ -554,7 +554,7 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncLastIndexOf(ExecState* exec) if (thisValue.isUndefinedOrNull()) // CheckObjectCoercible return throwVMTypeError(exec); UString s = thisValue.toThisString(exec); - int len = s.size(); + int len = s.length(); JSValue a0 = exec->argument(0); JSValue a1 = exec->argument(1); @@ -571,8 +571,8 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncLastIndexOf(ExecState* exec) dpos = len; #endif - unsigned result = s.rfind(u2, static_cast<unsigned>(dpos)); - if (result == UString::NotFound) + size_t result = s.reverseFind(u2, static_cast<unsigned>(dpos)); + if (result == notFound) return JSValue::encode(jsNumber(exec, -1)); return JSValue::encode(jsNumber(exec, result)); } @@ -597,7 +597,7 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncMatch(ExecState* exec) * If regexp is not an object whose [[Class]] property is "RegExp", it is * replaced with the result of the expression new RegExp(regexp). */ - reg = exec->globalData().regExpCache()->lookupOrCreate(a0.toString(exec), UString::null()); + reg = exec->globalData().regExpCache()->lookupOrCreate(a0.toString(exec), UString()); } RegExpConstructor* regExpConstructor = exec->lexicalGlobalObject()->regExpConstructor(); int pos; @@ -650,7 +650,7 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncSearch(ExecState* exec) * If regexp is not an object whose [[Class]] property is "RegExp", it is * replaced with the result of the expression new RegExp(regexp). */ - reg = exec->globalData().regExpCache()->lookupOrCreate(a0.toString(exec), UString::null()); + reg = exec->globalData().regExpCache()->lookupOrCreate(a0.toString(exec), UString()); } RegExpConstructor* regExpConstructor = exec->lexicalGlobalObject()->regExpConstructor(); int pos; @@ -665,7 +665,7 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncSlice(ExecState* exec) if (thisValue.isUndefinedOrNull()) // CheckObjectCoercible return throwVMTypeError(exec); UString s = thisValue.toThisString(exec); - int len = s.size(); + int len = s.length(); JSValue a0 = exec->argument(0); JSValue a1 = exec->argument(1); @@ -707,7 +707,7 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncSplit(ExecState* exec) return JSValue::encode(result); } unsigned pos = 0; - while (i != limit && pos < s.size()) { + while (i != limit && pos < s.length()) { Vector<int, 32> ovector; int mpos = reg->match(s, pos, &ovector); if (mpos < 0) @@ -733,21 +733,20 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncSplit(ExecState* exec) // empty separator matches empty string -> empty array return JSValue::encode(result); } - while (i != limit && p0 < s.size() - 1) + while (i != limit && p0 < s.length() - 1) result->put(exec, i++, jsSingleCharacterSubstring(exec, s, p0++)); } else { - unsigned pos; - - while (i != limit && (pos = s.find(u2, p0)) != UString::NotFound) { + size_t pos; + while (i != limit && (pos = s.find(u2, p0)) != notFound) { result->put(exec, i++, jsSubstring(exec, s, p0, pos - p0)); - p0 = pos + u2.size(); + p0 = pos + u2.length(); } } } // add remaining string if (i != limit) - result->put(exec, i++, jsSubstring(exec, s, p0, s.size() - p0)); + result->put(exec, i++, jsSubstring(exec, s, p0, s.length() - p0)); return JSValue::encode(result); } @@ -758,7 +757,7 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncSubstr(ExecState* exec) if (thisValue.isUndefinedOrNull()) // CheckObjectCoercible return throwVMTypeError(exec); UString s = thisValue.toThisString(exec); - int len = s.size(); + int len = s.length(); JSValue a0 = exec->argument(0); JSValue a1 = exec->argument(1); @@ -783,7 +782,7 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncSubstring(ExecState* exec) if (thisValue.isUndefinedOrNull()) // CheckObjectCoercible return throwVMTypeError(exec); UString s = thisValue.toThisString(exec); - int len = s.size(); + int len = s.length(); JSValue a0 = exec->argument(0); JSValue a1 = exec->argument(1); @@ -819,11 +818,11 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncToLowerCase(ExecState* exec) JSString* sVal = thisValue.toThisJSString(exec); const UString& s = sVal->value(exec); - int sSize = s.size(); + int sSize = s.length(); if (!sSize) return JSValue::encode(sVal); - const UChar* sData = s.data(); + const UChar* sData = s.characters(); Vector<UChar> buffer(sSize); UChar ored = 0; @@ -859,11 +858,11 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncToUpperCase(ExecState* exec) JSString* sVal = thisValue.toThisJSString(exec); const UString& s = sVal->value(exec); - int sSize = s.size(); + int sSize = s.length(); if (!sSize) return JSValue::encode(sVal); - const UChar* sData = s.data(); + const UChar* sData = s.characters(); Vector<UChar> buffer(sSize); UChar ored = 0; @@ -984,10 +983,10 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncFontsize(ExecState* exec) uint32_t smallInteger; if (a0.getUInt32(smallInteger) && smallInteger <= 9) { - unsigned stringSize = s.size(); + unsigned stringSize = s.length(); unsigned bufferSize = 22 + stringSize; UChar* buffer; - PassRefPtr<UStringImpl> impl = UStringImpl::tryCreateUninitialized(bufferSize, buffer); + PassRefPtr<StringImpl> impl = StringImpl::tryCreateUninitialized(bufferSize, buffer); if (!impl) return JSValue::encode(jsUndefined()); buffer[0] = '<'; @@ -1005,7 +1004,7 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncFontsize(ExecState* exec) buffer[12] = '0' + smallInteger; buffer[13] = '"'; buffer[14] = '>'; - memcpy(&buffer[15], s.data(), stringSize * sizeof(UChar)); + memcpy(&buffer[15], s.characters(), stringSize * sizeof(UChar)); buffer[15 + stringSize] = '<'; buffer[16 + stringSize] = '/'; buffer[17 + stringSize] = 'f'; @@ -1034,11 +1033,11 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncLink(ExecState* exec) JSValue a0 = exec->argument(0); UString linkText = a0.toString(exec); - unsigned linkTextSize = linkText.size(); - unsigned stringSize = s.size(); + unsigned linkTextSize = linkText.length(); + unsigned stringSize = s.length(); unsigned bufferSize = 15 + linkTextSize + stringSize; UChar* buffer; - PassRefPtr<UStringImpl> impl = UStringImpl::tryCreateUninitialized(bufferSize, buffer); + PassRefPtr<StringImpl> impl = StringImpl::tryCreateUninitialized(bufferSize, buffer); if (!impl) return JSValue::encode(jsUndefined()); buffer[0] = '<'; @@ -1050,10 +1049,10 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncLink(ExecState* exec) buffer[6] = 'f'; buffer[7] = '='; buffer[8] = '"'; - memcpy(&buffer[9], linkText.data(), linkTextSize * sizeof(UChar)); + memcpy(&buffer[9], linkText.characters(), linkTextSize * sizeof(UChar)); buffer[9 + linkTextSize] = '"'; buffer[10 + linkTextSize] = '>'; - memcpy(&buffer[11 + linkTextSize], s.data(), stringSize * sizeof(UChar)); + memcpy(&buffer[11 + linkTextSize], s.characters(), stringSize * sizeof(UChar)); buffer[11 + linkTextSize + stringSize] = '<'; buffer[12 + linkTextSize + stringSize] = '/'; buffer[13 + linkTextSize + stringSize] = 'a'; @@ -1078,20 +1077,20 @@ static inline JSValue trimString(ExecState* exec, JSValue thisValue, int trimKin UString str = thisValue.toThisString(exec); unsigned left = 0; if (trimKind & TrimLeft) { - while (left < str.size() && isTrimWhitespace(str[left])) + while (left < str.length() && isTrimWhitespace(str[left])) left++; } - unsigned right = str.size(); + unsigned right = str.length(); if (trimKind & TrimRight) { while (right > left && isTrimWhitespace(str[right - 1])) right--; } // Don't gc allocate a new string if we don't have to. - if (left == 0 && right == str.size() && thisValue.isString()) + if (left == 0 && right == str.length() && thisValue.isString()) return thisValue; - return jsString(exec, str.substr(left, right - left)); + return jsString(exec, str.substringSharingImpl(left, right - left)); } EncodedJSValue JSC_HOST_CALL stringProtoFuncTrim(ExecState* exec) diff --git a/JavaScriptCore/runtime/Structure.cpp b/JavaScriptCore/runtime/Structure.cpp index 6d13f4b..d06a239 100644 --- a/JavaScriptCore/runtime/Structure.cpp +++ b/JavaScriptCore/runtime/Structure.cpp @@ -270,7 +270,7 @@ Structure::~Structure() if (m_propertyTable) { unsigned entryCount = m_propertyTable->keyCount + m_propertyTable->deletedSentinelCount; for (unsigned i = 1; i <= entryCount; i++) { - if (UString::Rep* key = m_propertyTable->entries()[i].key) + if (StringImpl* key = m_propertyTable->entries()[i].key) key->deref(); } @@ -395,7 +395,7 @@ void Structure::growPropertyStorageCapacity() void Structure::despecifyDictionaryFunction(const Identifier& propertyName) { - const UString::Rep* rep = propertyName._ustring.rep(); + const StringImpl* rep = propertyName.impl(); materializePropertyMapIfNecessary(); @@ -444,7 +444,7 @@ PassRefPtr<Structure> Structure::addPropertyTransitionToExistingStructure(Struct ASSERT(!structure->isDictionary()); ASSERT(structure->typeInfo().type() == ObjectType); - if (Structure* existingTransition = structure->transitionTableGet(make_pair(propertyName.ustring().rep(), attributes), specificValue)) { + if (Structure* existingTransition = structure->transitionTableGet(make_pair(propertyName.impl(), attributes), specificValue)) { ASSERT(existingTransition->m_offset != noOffset); offset = existingTransition->m_offset + existingTransition->m_anonymousSlotCount; ASSERT(offset >= structure->m_anonymousSlotCount); @@ -479,7 +479,7 @@ PassRefPtr<Structure> Structure::addPropertyTransition(Structure* structure, con transition->m_cachedPrototypeChain = structure->m_cachedPrototypeChain; transition->m_previous = structure; - transition->m_nameInPrevious = propertyName.ustring().rep(); + transition->m_nameInPrevious = propertyName.impl(); transition->m_attributesInPrevious = attributes; transition->m_specificValueInPrevious = specificValue; transition->m_propertyStorageCapacity = structure->m_propertyStorageCapacity; @@ -509,7 +509,7 @@ PassRefPtr<Structure> Structure::addPropertyTransition(Structure* structure, con transition->m_offset = offset - structure->m_anonymousSlotCount; ASSERT(structure->anonymousSlotCount() == transition->anonymousSlotCount()); - structure->transitionTableAdd(make_pair(propertyName.ustring().rep(), attributes), transition.get(), specificValue); + structure->transitionTableAdd(make_pair(propertyName.impl(), attributes), transition.get(), specificValue); return transition.release(); } @@ -738,7 +738,7 @@ PropertyMapHashTable* Structure::copyPropertyTable() unsigned entryCount = m_propertyTable->keyCount + m_propertyTable->deletedSentinelCount; for (unsigned i = 1; i <= entryCount; ++i) { - if (UString::Rep* key = newTable->entries()[i].key) + if (StringImpl* key = newTable->entries()[i].key) key->ref(); } @@ -749,7 +749,7 @@ PropertyMapHashTable* Structure::copyPropertyTable() return newTable; } -size_t Structure::get(const UString::Rep* rep, unsigned& attributes, JSCell*& specificValue) +size_t Structure::get(const StringImpl* rep, unsigned& attributes, JSCell*& specificValue) { materializePropertyMapIfNecessary(); if (!m_propertyTable) @@ -806,7 +806,7 @@ bool Structure::despecifyFunction(const Identifier& propertyName) if (!m_propertyTable) return false; - UString::Rep* rep = propertyName._ustring.rep(); + StringImpl* rep = propertyName.impl(); unsigned i = rep->existingHash(); @@ -870,7 +870,7 @@ size_t Structure::put(const Identifier& propertyName, unsigned attributes, JSCel if (attributes & DontEnum) m_hasNonEnumerableProperties = true; - UString::Rep* rep = propertyName._ustring.rep(); + StringImpl* rep = propertyName.impl(); if (!m_propertyTable) createPropertyMapHashTable(); @@ -954,7 +954,7 @@ size_t Structure::put(const Identifier& propertyName, unsigned attributes, JSCel return newOffset; } -bool Structure::hasTransition(UString::Rep* rep, unsigned attributes) +bool Structure::hasTransition(StringImpl* rep, unsigned attributes) { return transitionTableHasTransition(make_pair(rep, attributes)); } @@ -965,7 +965,7 @@ size_t Structure::remove(const Identifier& propertyName) checkConsistency(); - UString::Rep* rep = propertyName._ustring.rep(); + StringImpl* rep = propertyName.impl(); if (!m_propertyTable) return notFound; @@ -979,7 +979,7 @@ size_t Structure::remove(const Identifier& propertyName) unsigned i = rep->existingHash(); unsigned k = 0; unsigned entryIndex; - UString::Rep* key = 0; + StringImpl* key = 0; while (1) { entryIndex = m_propertyTable->entryIndices[i & m_propertyTable->sizeMask]; if (entryIndex == emptyEntryIndex) @@ -1241,7 +1241,7 @@ void Structure::checkConsistency() unsigned nonEmptyEntryCount = 0; for (unsigned c = 1; c <= m_propertyTable->keyCount + m_propertyTable->deletedSentinelCount; ++c) { ASSERT(m_hasNonEnumerableProperties || !(m_propertyTable->entries()[c].attributes & DontEnum)); - UString::Rep* rep = m_propertyTable->entries()[c].key; + StringImpl* rep = m_propertyTable->entries()[c].key; ASSERT(m_propertyTable->entries()[c].offset >= m_anonymousSlotCount); if (!rep) continue; diff --git a/JavaScriptCore/runtime/Structure.h b/JavaScriptCore/runtime/Structure.h index 968443a..f480051 100644 --- a/JavaScriptCore/runtime/Structure.h +++ b/JavaScriptCore/runtime/Structure.h @@ -106,20 +106,20 @@ namespace JSC { bool isUsingInlineStorage() const; size_t get(const Identifier& propertyName); - size_t get(const UString::Rep* rep, unsigned& attributes, JSCell*& specificValue); + size_t get(const StringImpl* rep, unsigned& attributes, JSCell*& specificValue); size_t get(const Identifier& propertyName, unsigned& attributes, JSCell*& specificValue) { ASSERT(!propertyName.isNull()); - return get(propertyName.ustring().rep(), attributes, specificValue); + return get(propertyName.impl(), attributes, specificValue); } bool transitionedFor(const JSCell* specificValue) { return m_specificValueInPrevious == specificValue; } - bool hasTransition(UString::Rep*, unsigned attributes); + bool hasTransition(StringImpl*, unsigned attributes); bool hasTransition(const Identifier& propertyName, unsigned attributes) { - return hasTransition(propertyName._ustring.rep(), attributes); + return hasTransition(propertyName.impl(), attributes); } bool hasGetterSetterProperties() const { return m_hasGetterSetterProperties; } @@ -210,7 +210,7 @@ namespace JSC { mutable RefPtr<StructureChain> m_cachedPrototypeChain; RefPtr<Structure> m_previous; - RefPtr<UString::Rep> m_nameInPrevious; + RefPtr<StringImpl> m_nameInPrevious; JSCell* m_specificValueInPrevious; // 'm_isUsingSingleSlot' indicates whether we are using the single transition optimisation. @@ -254,7 +254,7 @@ namespace JSC { if (!m_propertyTable) return WTF::notFound; - UString::Rep* rep = propertyName._ustring.rep(); + StringImpl* rep = propertyName.impl(); unsigned i = rep->existingHash(); diff --git a/JavaScriptCore/runtime/StructureTransitionTable.h b/JavaScriptCore/runtime/StructureTransitionTable.h index d1dc2d9..7e9d7ff 100644 --- a/JavaScriptCore/runtime/StructureTransitionTable.h +++ b/JavaScriptCore/runtime/StructureTransitionTable.h @@ -38,7 +38,7 @@ namespace JSC { class Structure; struct StructureTransitionTableHash { - typedef std::pair<RefPtr<UString::Rep>, unsigned> Key; + typedef std::pair<RefPtr<StringImpl>, unsigned> Key; static unsigned hash(const Key& p) { return p.first->existingHash(); @@ -53,7 +53,7 @@ namespace JSC { }; struct StructureTransitionTableHashTraits { - typedef WTF::HashTraits<RefPtr<UString::Rep> > FirstTraits; + typedef WTF::HashTraits<RefPtr<StringImpl> > FirstTraits; typedef WTF::GenericHashTraits<unsigned> SecondTraits; typedef std::pair<FirstTraits::TraitType, SecondTraits::TraitType > TraitType; diff --git a/JavaScriptCore/runtime/SymbolTable.h b/JavaScriptCore/runtime/SymbolTable.h index 2717075..1b1636d 100644 --- a/JavaScriptCore/runtime/SymbolTable.h +++ b/JavaScriptCore/runtime/SymbolTable.h @@ -119,7 +119,7 @@ namespace JSC { static const bool needsDestruction = false; }; - typedef HashMap<RefPtr<UString::Rep>, SymbolTableEntry, IdentifierRepHash, HashTraits<RefPtr<UString::Rep> >, SymbolTableIndexHashTraits> SymbolTable; + typedef HashMap<RefPtr<StringImpl>, SymbolTableEntry, IdentifierRepHash, HashTraits<RefPtr<StringImpl> >, SymbolTableIndexHashTraits> SymbolTable; class SharedSymbolTable : public SymbolTable, public RefCounted<SharedSymbolTable> { public: diff --git a/JavaScriptCore/runtime/UString.cpp b/JavaScriptCore/runtime/UString.cpp index c442500..ac3acfd 100644 --- a/JavaScriptCore/runtime/UString.cpp +++ b/JavaScriptCore/runtime/UString.cpp @@ -54,36 +54,40 @@ namespace JSC { extern const double NaN; extern const double Inf; -// The null string is immutable, except for refCount. -UString* UString::s_nullUString; - COMPILE_ASSERT(sizeof(UString) == sizeof(void*), UString_should_stay_small); -void initializeUString() +// Construct a string with UTF-16 data. +UString::UString(const UChar* characters, unsigned length) + : m_impl(characters ? StringImpl::create(characters, length) : 0) { - // UStringImpl::empty() does not construct its static string in a threadsafe fashion, - // so ensure it has been initialized from here. - UStringImpl::empty(); - - UString::s_nullUString = new UString; } -UString::UString(const char* c) - : m_rep(Rep::create(c)) +// Construct a string with UTF-16 data, from a null-terminated source. +UString::UString(const UChar* characters) { + if (!characters) + return; + + int length = 0; + while (characters[length] != UChar(0)) + ++length; + + m_impl = StringImpl::create(characters, length); } -UString::UString(const char* c, unsigned length) - : m_rep(Rep::create(c, length)) +// Construct a string with latin1 data. +UString::UString(const char* characters, unsigned length) + : m_impl(characters ? StringImpl::create(characters, length) : 0) { } -UString::UString(const UChar* c, unsigned length) - : m_rep(Rep::create(c, length)) +// Construct a string with latin1 data, from a null-terminated source. +UString::UString(const char* characters) + : m_impl(characters ? StringImpl::create(characters) : 0) { } -UString UString::from(int i) +UString UString::number(int i) { UChar buf[1 + sizeof(i) * 3]; UChar* end = buf + sizeof(buf) / sizeof(UChar); @@ -112,7 +116,7 @@ UString UString::from(int i) return UString(p, static_cast<unsigned>(end - p)); } -UString UString::from(long long i) +UString UString::number(long long i) { UChar buf[1 + sizeof(i) * 3]; UChar* end = buf + sizeof(buf) / sizeof(UChar); @@ -145,7 +149,7 @@ UString UString::from(long long i) return UString(p, static_cast<unsigned>(end - p)); } -UString UString::from(unsigned u) +UString UString::number(unsigned u) { UChar buf[sizeof(u) * 3]; UChar* end = buf + sizeof(buf) / sizeof(UChar); @@ -163,7 +167,7 @@ UString UString::from(unsigned u) return UString(p, static_cast<unsigned>(end - p)); } -UString UString::from(long l) +UString UString::number(long l) { UChar buf[1 + sizeof(l) * 3]; UChar* end = buf + sizeof(buf) / sizeof(UChar); @@ -192,7 +196,7 @@ UString UString::from(long l) return UString(p, end - p); } -UString UString::from(double d) +UString UString::number(double d) { DtoaBuffer buffer; unsigned length; @@ -200,359 +204,17 @@ UString UString::from(double d) return UString(buffer, length); } -char* UString::ascii() const -{ - static char* asciiBuffer = 0; - - unsigned length = size(); - unsigned neededSize = length + 1; - delete[] asciiBuffer; - asciiBuffer = new char[neededSize]; - - const UChar* p = data(); - char* q = asciiBuffer; - const UChar* limit = p + length; - while (p != limit) { - *q = static_cast<char>(p[0]); - ++p; - ++q; - } - *q = '\0'; - - return asciiBuffer; -} - -bool UString::is8Bit() const -{ - const UChar* u = data(); - const UChar* limit = u + size(); - while (u < limit) { - if (u[0] > 0xFF) - return false; - ++u; - } - - return true; -} - -UChar UString::operator[](unsigned pos) const +UString UString::substringSharingImpl(unsigned offset, unsigned length) const { - if (pos >= size()) - return '\0'; - return data()[pos]; -} - -static inline bool isInfinity(double number) -{ - return number == Inf || number == -Inf; -} - -static bool isInfinity(const UChar* data, const UChar* end) -{ - return data + 7 < end - && data[0] == 'I' - && data[1] == 'n' - && data[2] == 'f' - && data[3] == 'i' - && data[4] == 'n' - && data[5] == 'i' - && data[6] == 't' - && data[7] == 'y'; -} - -double UString::toDouble(bool tolerateTrailingJunk, bool tolerateEmptyString) const -{ - unsigned size = this->size(); - - if (size == 1) { - UChar c = data()[0]; - if (isASCIIDigit(c)) - return c - '0'; - if (isStrWhiteSpace(c) && tolerateEmptyString) - return 0; - return NaN; - } - - // FIXME: If tolerateTrailingJunk is true, then we want to tolerate junk - // after the number, even if it contains invalid UTF-16 sequences. So we - // shouldn't use the UTF8String function, which returns null when it - // encounters invalid UTF-16. Further, we have no need to convert the - // non-ASCII characters to UTF-8, so the UTF8String does quite a bit of - // unnecessary work. - - // FIXME: The space skipping code below skips only ASCII spaces, but callers - // need to skip all StrWhiteSpace. The isStrWhiteSpace function does the - // right thing but requires UChar, not char, for its argument. - - const UChar* data = this->data(); - const UChar* end = data + size; - - // Skip leading white space. - for (; data < end; ++data) { - if (!isStrWhiteSpace(*data)) - break; - } - - // Empty string. - if (data == end) - return tolerateEmptyString ? 0.0 : NaN; - - double number; - - if (data[0] == '0' && data + 2 < end && (data[1] | 0x20) == 'x' && isASCIIHexDigit(data[2])) { - // Hex number. - data += 2; - const UChar* firstDigitPosition = data; - number = 0; - while (true) { - number = number * 16 + toASCIIHexValue(*data); - ++data; - if (data == end) - break; - if (!isASCIIHexDigit(*data)) - break; - } - if (number >= mantissaOverflowLowerBound) - number = parseIntOverflow(firstDigitPosition, data - firstDigitPosition, 16); - } else { - // Decimal number. - - // Put into a null-terminated byte buffer. - Vector<char, 32> byteBuffer; - for (const UChar* characters = data; characters < end; ++characters) { - UChar character = *characters; - byteBuffer.append(isASCII(character) ? character : 0); - } - byteBuffer.append(0); - - char* byteBufferEnd; - number = WTF::strtod(byteBuffer.data(), &byteBufferEnd); - const UChar* pastNumber = data + (byteBufferEnd - byteBuffer.data()); - - if ((number || pastNumber != data) && !isInfinity(number)) - data = pastNumber; - else { - // We used strtod() to do the conversion. However, strtod() handles - // infinite values slightly differently than JavaScript in that it - // converts the string "inf" with any capitalization to infinity, - // whereas the ECMA spec requires that it be converted to NaN. - - double signedInfinity = Inf; - if (data < end) { - if (*data == '+') - data++; - else if (*data == '-') { - signedInfinity = -Inf; - data++; - } - } - if (isInfinity(data, end)) { - number = signedInfinity; - data += 8; - } else if (isInfinity(number) && data < end && (*data | 0x20) != 'i') - data = pastNumber; - else - return NaN; - } - } - - // Look for trailing junk. - if (!tolerateTrailingJunk) { - // Allow trailing white space. - for (; data < end; ++data) { - if (!isStrWhiteSpace(*data)) - break; - } - if (data != end) - return NaN; - } - - return number; -} - -double UString::toDouble(bool tolerateTrailingJunk) const -{ - return toDouble(tolerateTrailingJunk, true); -} - -double UString::toDouble() const -{ - return toDouble(false, true); -} - -uint32_t UString::toUInt32(bool* ok) const -{ - double d = toDouble(); - bool b = true; - - if (d != static_cast<uint32_t>(d)) { - b = false; - d = 0; - } - - if (ok) - *ok = b; - - return static_cast<uint32_t>(d); -} - -uint32_t UString::toUInt32(bool* ok, bool tolerateEmptyString) const -{ - double d = toDouble(false, tolerateEmptyString); - bool b = true; - - if (d != static_cast<uint32_t>(d)) { - b = false; - d = 0; - } + // FIXME: We used to check against a limit of Heap::minExtraCost / sizeof(UChar). - if (ok) - *ok = b; + unsigned stringLength = this->length(); + offset = min(offset, stringLength); + length = min(length, stringLength - offset); - return static_cast<uint32_t>(d); -} - -uint32_t UString::toStrictUInt32(bool* ok) const -{ - if (ok) - *ok = false; - - // Empty string is not OK. - unsigned len = m_rep->length(); - if (len == 0) - return 0; - const UChar* p = m_rep->characters(); - unsigned short c = p[0]; - - // If the first digit is 0, only 0 itself is OK. - if (c == '0') { - if (len == 1 && ok) - *ok = true; - return 0; - } - - // Convert to UInt32, checking for overflow. - uint32_t i = 0; - while (1) { - // Process character, turning it into a digit. - if (c < '0' || c > '9') - return 0; - const unsigned d = c - '0'; - - // Multiply by 10, checking for overflow out of 32 bits. - if (i > 0xFFFFFFFFU / 10) - return 0; - i *= 10; - - // Add in the digit, checking for overflow out of 32 bits. - const unsigned max = 0xFFFFFFFFU - d; - if (i > max) - return 0; - i += d; - - // Handle end of string. - if (--len == 0) { - if (ok) - *ok = true; - return i; - } - - // Get next character. - c = *(++p); - } -} - -unsigned UString::find(const UString& f, unsigned pos) const -{ - unsigned fsz = f.size(); - - if (fsz == 1) { - UChar ch = f[0]; - const UChar* end = data() + size(); - for (const UChar* c = data() + pos; c < end; c++) { - if (*c == ch) - return static_cast<unsigned>(c - data()); - } - return NotFound; - } - - unsigned sz = size(); - if (sz < fsz) - return NotFound; - if (fsz == 0) - return pos; - const UChar* end = data() + sz - fsz; - unsigned fsizeminusone = (fsz - 1) * sizeof(UChar); - const UChar* fdata = f.data(); - unsigned short fchar = fdata[0]; - ++fdata; - for (const UChar* c = data() + pos; c <= end; c++) { - if (c[0] == fchar && !memcmp(c + 1, fdata, fsizeminusone)) - return static_cast<unsigned>(c - data()); - } - - return NotFound; -} - -unsigned UString::find(UChar ch, unsigned pos) const -{ - const UChar* end = data() + size(); - for (const UChar* c = data() + pos; c < end; c++) { - if (*c == ch) - return static_cast<unsigned>(c - data()); - } - - return NotFound; -} - -unsigned UString::rfind(const UString& f, unsigned pos) const -{ - unsigned sz = size(); - unsigned fsz = f.size(); - if (sz < fsz) - return NotFound; - if (pos > sz - fsz) - pos = sz - fsz; - if (fsz == 0) - return pos; - unsigned fsizeminusone = (fsz - 1) * sizeof(UChar); - const UChar* fdata = f.data(); - for (const UChar* c = data() + pos; c >= data(); c--) { - if (*c == *fdata && !memcmp(c + 1, fdata + 1, fsizeminusone)) - return static_cast<unsigned>(c - data()); - } - - return NotFound; -} - -unsigned UString::rfind(UChar ch, unsigned pos) const -{ - if (isEmpty()) - return NotFound; - if (pos + 1 >= size()) - pos = size() - 1; - for (const UChar* c = data() + pos; c >= data(); c--) { - if (*c == ch) - return static_cast<unsigned>(c - data()); - } - - return NotFound; -} - -UString UString::substr(unsigned pos, unsigned len) const -{ - unsigned s = size(); - - if (pos >= s) - pos = s; - unsigned limit = s - pos; - if (len > limit) - len = limit; - - if (pos == 0 && len == s) + if (!offset && length == stringLength) return *this; - - return UString(Rep::create(m_rep, pos, len)); + return UString(StringImpl::create(m_impl, offset, length)); } bool operator==(const UString& s1, const char *s2) @@ -560,8 +222,8 @@ bool operator==(const UString& s1, const char *s2) if (s2 == 0) return s1.isEmpty(); - const UChar* u = s1.data(); - const UChar* uend = u + s1.size(); + const UChar* u = s1.characters(); + const UChar* uend = u + s1.length(); while (u != uend && *s2) { if (u[0] != (unsigned char)*s2) return false; @@ -574,11 +236,11 @@ bool operator==(const UString& s1, const char *s2) bool operator<(const UString& s1, const UString& s2) { - const unsigned l1 = s1.size(); - const unsigned l2 = s2.size(); + const unsigned l1 = s1.length(); + const unsigned l2 = s2.length(); const unsigned lmin = l1 < l2 ? l1 : l2; - const UChar* c1 = s1.data(); - const UChar* c2 = s2.data(); + const UChar* c1 = s1.characters(); + const UChar* c2 = s2.characters(); unsigned l = 0; while (l < lmin && *c1 == *c2) { c1++; @@ -593,11 +255,11 @@ bool operator<(const UString& s1, const UString& s2) bool operator>(const UString& s1, const UString& s2) { - const unsigned l1 = s1.size(); - const unsigned l2 = s2.size(); + const unsigned l1 = s1.length(); + const unsigned l2 = s2.length(); const unsigned lmin = l1 < l2 ? l1 : l2; - const UChar* c1 = s1.data(); - const UChar* c2 = s2.data(); + const UChar* c1 = s1.characters(); + const UChar* c2 = s2.characters(); unsigned l = 0; while (l < lmin && *c1 == *c2) { c1++; @@ -610,20 +272,94 @@ bool operator>(const UString& s1, const UString& s2) return (l1 > l2); } -CString UString::UTF8String(bool strict) const +CString UString::ascii() const { - // Allocate a buffer big enough to hold all the characters. - const unsigned length = size(); - Vector<char, 1024> buffer(length * 3); - - // Convert to runs of 8-bit characters. - char* p = buffer.data(); - const UChar* d = reinterpret_cast<const UChar*>(&data()[0]); - ConversionResult result = convertUTF16ToUTF8(&d, d + length, &p, p + buffer.size(), strict); - if (result != conversionOK) + // Basic Latin1 (ISO) encoding - Unicode characters 0..255 are + // preserved, characters outside of this range are converted to '?'. + + unsigned length = this->length(); + const UChar* characters = this->characters(); + + char* characterBuffer; + CString result = CString::newUninitialized(length, characterBuffer); + + for (unsigned i = 0; i < length; ++i) { + UChar ch = characters[i]; + characterBuffer[i] = ch && (ch < 0x20 || ch >= 0x7f) ? '?' : ch; + } + + return result; +} + +CString UString::latin1() const +{ + // Basic Latin1 (ISO) encoding - Unicode characters 0..255 are + // preserved, characters outside of this range are converted to '?'. + + unsigned length = this->length(); + const UChar* characters = this->characters(); + + char* characterBuffer; + CString result = CString::newUninitialized(length, characterBuffer); + + for (unsigned i = 0; i < length; ++i) { + UChar ch = characters[i]; + characterBuffer[i] = ch > 0xff ? '?' : ch; + } + + return result; +} + +// Helper to write a three-byte UTF-8 code point to the buffer, caller must check room is available. +static inline void putUTF8Triple(char*& buffer, UChar ch) +{ + ASSERT(ch >= 0x0800); + *buffer++ = static_cast<char>(((ch >> 12) & 0x0F) | 0xE0); + *buffer++ = static_cast<char>(((ch >> 6) & 0x3F) | 0x80); + *buffer++ = static_cast<char>((ch & 0x3F) | 0x80); +} + +CString UString::utf8(bool strict) const +{ + unsigned length = this->length(); + const UChar* characters = this->characters(); + + // Allocate a buffer big enough to hold all the characters + // (an individual UTF-16 UChar can only expand to 3 UTF-8 bytes). + // Optimization ideas, if we find this function is hot: + // * We could speculatively create a CStringBuffer to contain 'length' + // characters, and resize if necessary (i.e. if the buffer contains + // non-ascii characters). (Alternatively, scan the buffer first for + // ascii characters, so we know this will be sufficient). + // * We could allocate a CStringBuffer with an appropriate size to + // have a good chance of being able to write the string into the + // buffer without reallocing (say, 1.5 x length). + Vector<char, 1024> bufferVector(length * 3); + + char* buffer = bufferVector.data(); + ConversionResult result = convertUTF16ToUTF8(&characters, characters + length, &buffer, buffer + bufferVector.size(), strict); + ASSERT(result != targetExhausted); // (length * 3) should be sufficient for any conversion + + // Only produced from strict conversion. + if (result == sourceIllegal) return CString(); - return CString(buffer.data(), p - buffer.data()); + // Check for an unconverted high surrogate. + if (result == sourceExhausted) { + if (strict) + return CString(); + // This should be one unpaired high surrogate. Treat it the same + // was as an unpaired high surrogate would have been handled in + // the middle of a string with non-strict conversion - which is + // to say, simply encode it to UTF-8. + ASSERT((characters + 1) == (this->characters() + length)); + ASSERT((*characters >= 0xD800) && (*characters <= 0xDBFF)); + // There should be room left, since one UChar hasn't been converted. + ASSERT((buffer + 3) <= (buffer + bufferVector.size())); + putUTF8Triple(buffer, *characters); + } + + return CString(bufferVector.data(), buffer - bufferVector.data()); } } // namespace JSC diff --git a/JavaScriptCore/runtime/UString.h b/JavaScriptCore/runtime/UString.h index bae9265..cd73c28 100644 --- a/JavaScriptCore/runtime/UString.h +++ b/JavaScriptCore/runtime/UString.h @@ -1,678 +1,263 @@ /* - * Copyright (C) 1999-2000 Harri Porten (porten@kde.org) - * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. - * Copyright (C) 2009 Google Inc. All rights reserved. + * Copyright (C) 1999-2000 Harri Porten (porten@kde.org) + * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. + * Copyright (C) 2009 Google 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 - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. * */ #ifndef UString_h #define UString_h -#include "Collector.h" -#include "UStringImpl.h" -#include <stdint.h> -#include <string.h> -#include <wtf/Assertions.h> -#include <wtf/CrossThreadRefCounted.h> -#include <wtf/OwnFastMallocPtr.h> -#include <wtf/PassRefPtr.h> -#include <wtf/RefPtr.h> -#include <wtf/Vector.h> -#include <wtf/text/CString.h> -#include <wtf/unicode/Unicode.h> +#include <wtf/text/StringImpl.h> namespace JSC { - using WTF::PlacementNewAdoptType; - using WTF::PlacementNewAdopt; +class UString { +public: + // Construct a null string, distinguishable from an empty string. + UString() { } - class UString { - friend class JIT; + // Construct a string with UTF-16 data. + UString(const UChar* characters, unsigned length); - public: - typedef UStringImpl Rep; - - public: - UString() {} - UString(const char*); // Constructor for null-terminated string. - UString(const char*, unsigned length); - UString(const UChar*, unsigned length); - UString(const Vector<UChar>& buffer); - - UString(const UString& s) - : m_rep(s.m_rep) - { - } - - // Special constructor for cases where we overwrite an object in place. - UString(PlacementNewAdoptType) - : m_rep(PlacementNewAdopt) - { - } - - template<size_t inlineCapacity> - static PassRefPtr<UStringImpl> adopt(Vector<UChar, inlineCapacity>& vector) - { - return Rep::adopt(vector); - } - - static UString from(int); - static UString from(long long); - static UString from(unsigned); - static UString from(long); - static UString from(double); - - // NOTE: This method should only be used for *debugging* purposes as it - // is neither Unicode safe nor free from side effects nor thread-safe. - char* ascii() const; - - /** - * Convert the string to UTF-8, assuming it is UTF-16 encoded. - * In non-strict mode, this function is tolerant of badly formed UTF-16, it - * can create UTF-8 strings that are invalid because they have characters in - * the range U+D800-U+DDFF, U+FFFE, or U+FFFF, but the UTF-8 string is - * guaranteed to be otherwise valid. - * In strict mode, error is returned as null CString. - */ - CString UTF8String(bool strict = false) const; - - const UChar* data() const - { - if (!m_rep) - return 0; - return m_rep->characters(); - } - - unsigned size() const - { - if (!m_rep) - return 0; - return m_rep->length(); - } - - bool isNull() const { return !m_rep; } - bool isEmpty() const { return !m_rep || !m_rep->length(); } - - bool is8Bit() const; - - UChar operator[](unsigned pos) const; - - double toDouble(bool tolerateTrailingJunk, bool tolerateEmptyString) const; - double toDouble(bool tolerateTrailingJunk) const; - double toDouble() const; - - uint32_t toUInt32(bool* ok = 0) const; - uint32_t toUInt32(bool* ok, bool tolerateEmptyString) const; - uint32_t toStrictUInt32(bool* ok = 0) const; - - unsigned toArrayIndex(bool* ok = 0) const; + // Construct a string with UTF-16 data, from a null-terminated source. + UString(const UChar*); - static const unsigned NotFound = 0xFFFFFFFFu; - unsigned find(const UString& f, unsigned pos = 0) const; - unsigned find(UChar, unsigned pos = 0) const; - unsigned rfind(const UString& f, unsigned pos) const; - unsigned rfind(UChar, unsigned pos) const; + // Construct a string with latin1 data. + UString(const char* characters, unsigned length); - UString substr(unsigned pos = 0, unsigned len = 0xFFFFFFFF) const; + // Construct a string with latin1 data, from a null-terminated source. + UString(const char* characters); - static const UString& null() { return *s_nullUString; } + // Construct a string referencing an existing StringImpl. + UString(StringImpl* impl) : m_impl(impl) { } + UString(PassRefPtr<StringImpl> impl) : m_impl(impl) { } + UString(RefPtr<StringImpl> impl) : m_impl(impl) { } - Rep* rep() const { return m_rep.get(); } + // Inline the destructor. + ALWAYS_INLINE ~UString() { } - UString(PassRefPtr<Rep> r) - : m_rep(r) - { - } - - size_t cost() const - { - if (!m_rep) - return 0; - return m_rep->cost(); - } + void swap(UString& o) { m_impl.swap(o.m_impl); } - ALWAYS_INLINE ~UString() { } - private: - RefPtr<Rep> m_rep; + template<size_t inlineCapacity> + static UString adopt(Vector<UChar, inlineCapacity>& vector) { return StringImpl::adopt(vector); } - static UString* s_nullUString; + bool isNull() const { return !m_impl; } + bool isEmpty() const { return !m_impl || !m_impl->length(); } - friend void initializeUString(); - friend bool operator==(const UString&, const UString&); - }; + StringImpl* impl() const { return m_impl.get(); } - ALWAYS_INLINE bool operator==(const UString& s1, const UString& s2) + unsigned length() const { - UString::Rep* rep1 = s1.rep(); - UString::Rep* rep2 = s2.rep(); - unsigned size1 = 0; - unsigned size2 = 0; - - if (rep1 == rep2) // If they're the same rep, they're equal. - return true; - - if (rep1) - size1 = rep1->length(); - - if (rep2) - size2 = rep2->length(); - - if (size1 != size2) // If the lengths are not the same, we're done. - return false; - - if (!size1) - return true; - - // At this point we know - // (a) that the strings are the same length and - // (b) that they are greater than zero length. - const UChar* d1 = rep1->characters(); - const UChar* d2 = rep2->characters(); - - if (d1 == d2) // Check to see if the data pointers are the same. - return true; - - // Do quick checks for sizes 1 and 2. - switch (size1) { - case 1: - return d1[0] == d2[0]; - case 2: - return (d1[0] == d2[0]) & (d1[1] == d2[1]); - default: - return memcmp(d1, d2, size1 * sizeof(UChar)) == 0; - } - } - - - inline bool operator!=(const UString& s1, const UString& s2) - { - return !JSC::operator==(s1, s2); - } - - bool operator<(const UString& s1, const UString& s2); - bool operator>(const UString& s1, const UString& s2); - - bool operator==(const UString& s1, const char* s2); - - inline bool operator!=(const UString& s1, const char* s2) - { - return !JSC::operator==(s1, s2); - } - - inline bool operator==(const char *s1, const UString& s2) - { - return operator==(s2, s1); - } - - inline bool operator!=(const char *s1, const UString& s2) - { - return !JSC::operator==(s1, s2); - } - - inline int codePointCompare(const UString& s1, const UString& s2) - { - return codePointCompare(s1.rep(), s2.rep()); - } - - // Rule from ECMA 15.2 about what an array index is. - // Must exactly match string form of an unsigned integer, and be less than 2^32 - 1. - inline unsigned UString::toArrayIndex(bool* ok) const - { - unsigned i = toStrictUInt32(ok); - if (ok && i >= 0xFFFFFFFFU) - *ok = false; - return i; - } - - // We'd rather not do shared substring append for small strings, since - // this runs too much risk of a tiny initial string holding down a - // huge buffer. - static const unsigned minShareSize = Heap::minExtraCost / sizeof(UChar); - - struct IdentifierRepHash : PtrHash<RefPtr<JSC::UString::Rep> > { - static unsigned hash(const RefPtr<JSC::UString::Rep>& key) { return key->existingHash(); } - static unsigned hash(JSC::UString::Rep* key) { return key->existingHash(); } - }; - - void initializeUString(); - - template<typename StringType> - class StringTypeAdapter { - }; - - template<> - class StringTypeAdapter<char*> { - public: - StringTypeAdapter<char*>(char* buffer) - : m_buffer((unsigned char*)buffer) - , m_length(strlen(buffer)) - { - } - - unsigned length() { return m_length; } - - void writeTo(UChar* destination) - { - for (unsigned i = 0; i < m_length; ++i) - destination[i] = m_buffer[i]; - } - - private: - const unsigned char* m_buffer; - unsigned m_length; - }; - - template<> - class StringTypeAdapter<const char*> { - public: - StringTypeAdapter<const char*>(const char* buffer) - : m_buffer((unsigned char*)buffer) - , m_length(strlen(buffer)) - { - } - - unsigned length() { return m_length; } - - void writeTo(UChar* destination) - { - for (unsigned i = 0; i < m_length; ++i) - destination[i] = m_buffer[i]; - } - - private: - const unsigned char* m_buffer; - unsigned m_length; - }; - - template<> - class StringTypeAdapter<UString> { - public: - StringTypeAdapter<UString>(UString& string) - : m_data(string.data()) - , m_length(string.size()) - { - } - - unsigned length() { return m_length; } - - void writeTo(UChar* destination) - { - for (unsigned i = 0; i < m_length; ++i) - destination[i] = m_data[i]; - } - - private: - const UChar* m_data; - unsigned m_length; - }; - - inline void sumWithOverflow(unsigned& total, unsigned addend, bool& overflow) - { - unsigned oldTotal = total; - total = oldTotal + addend; - if (total < oldTotal) - overflow = true; - } - - template<typename StringType1, typename StringType2> - PassRefPtr<UStringImpl> tryMakeString(StringType1 string1, StringType2 string2) - { - StringTypeAdapter<StringType1> adapter1(string1); - StringTypeAdapter<StringType2> adapter2(string2); - - UChar* buffer; - bool overflow = false; - unsigned length = adapter1.length(); - sumWithOverflow(length, adapter2.length(), overflow); - if (overflow) + if (!m_impl) return 0; - PassRefPtr<UStringImpl> resultImpl = UStringImpl::tryCreateUninitialized(length, buffer); - if (!resultImpl) - return 0; - - UChar* result = buffer; - adapter1.writeTo(result); - result += adapter1.length(); - adapter2.writeTo(result); - - return resultImpl; + return m_impl->length(); } - template<typename StringType1, typename StringType2, typename StringType3> - PassRefPtr<UStringImpl> tryMakeString(StringType1 string1, StringType2 string2, StringType3 string3) + const UChar* characters() const { - StringTypeAdapter<StringType1> adapter1(string1); - StringTypeAdapter<StringType2> adapter2(string2); - StringTypeAdapter<StringType3> adapter3(string3); - - UChar* buffer = 0; - bool overflow = false; - unsigned length = adapter1.length(); - sumWithOverflow(length, adapter2.length(), overflow); - sumWithOverflow(length, adapter3.length(), overflow); - if (overflow) - return 0; - PassRefPtr<UStringImpl> resultImpl = UStringImpl::tryCreateUninitialized(length, buffer); - if (!resultImpl) + if (!m_impl) return 0; - - UChar* result = buffer; - adapter1.writeTo(result); - result += adapter1.length(); - adapter2.writeTo(result); - result += adapter2.length(); - adapter3.writeTo(result); - - return resultImpl; + return m_impl->characters(); } - template<typename StringType1, typename StringType2, typename StringType3, typename StringType4> - PassRefPtr<UStringImpl> tryMakeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4) + CString ascii() const; + CString latin1() const; + CString utf8(bool strict = false) const; + + UChar operator[](unsigned index) const { - StringTypeAdapter<StringType1> adapter1(string1); - StringTypeAdapter<StringType2> adapter2(string2); - StringTypeAdapter<StringType3> adapter3(string3); - StringTypeAdapter<StringType4> adapter4(string4); - - UChar* buffer; - bool overflow = false; - unsigned length = adapter1.length(); - sumWithOverflow(length, adapter2.length(), overflow); - sumWithOverflow(length, adapter3.length(), overflow); - sumWithOverflow(length, adapter4.length(), overflow); - if (overflow) - return 0; - PassRefPtr<UStringImpl> resultImpl = UStringImpl::tryCreateUninitialized(length, buffer); - if (!resultImpl) + if (!m_impl || index >= m_impl->length()) return 0; + return m_impl->characters()[index]; + } - UChar* result = buffer; - adapter1.writeTo(result); - result += adapter1.length(); - adapter2.writeTo(result); - result += adapter2.length(); - adapter3.writeTo(result); - result += adapter3.length(); - adapter4.writeTo(result); - - return resultImpl; + static UString number(int); + static UString number(unsigned); + static UString number(long); + static UString number(long long); + static UString number(double); + + // Find a single character or string, also with match function & latin1 forms. + size_t find(UChar c, unsigned start = 0) const + { return m_impl ? m_impl->find(c, start) : notFound; } + size_t find(const UString& str, unsigned start = 0) const + { return m_impl ? m_impl->find(str.impl(), start) : notFound; } + size_t find(const char* str, unsigned start = 0) const + { return m_impl ? m_impl->find(str, start) : notFound; } + + // Find the last instance of a single character or string. + size_t reverseFind(UChar c, unsigned start = UINT_MAX) const + { return m_impl ? m_impl->reverseFind(c, start) : notFound; } + size_t reverseFind(const UString& str, unsigned start = UINT_MAX) const + { return m_impl ? m_impl->reverseFind(str.impl(), start) : notFound; } + + UString substringSharingImpl(unsigned pos, unsigned len = UINT_MAX) const; + +private: + RefPtr<StringImpl> m_impl; +}; + +ALWAYS_INLINE bool operator==(const UString& s1, const UString& s2) +{ + StringImpl* rep1 = s1.impl(); + StringImpl* rep2 = s2.impl(); + unsigned size1 = 0; + unsigned size2 = 0; + + if (rep1 == rep2) // If they're the same rep, they're equal. + return true; + + if (rep1) + size1 = rep1->length(); + + if (rep2) + size2 = rep2->length(); + + if (size1 != size2) // If the lengths are not the same, we're done. + return false; + + if (!size1) + return true; + + // At this point we know + // (a) that the strings are the same length and + // (b) that they are greater than zero length. + const UChar* d1 = rep1->characters(); + const UChar* d2 = rep2->characters(); + + if (d1 == d2) // Check to see if the data pointers are the same. + return true; + + // Do quick checks for sizes 1 and 2. + switch (size1) { + case 1: + return d1[0] == d2[0]; + case 2: + return (d1[0] == d2[0]) & (d1[1] == d2[1]); + default: + return memcmp(d1, d2, size1 * sizeof(UChar)) == 0; } +} - template<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5> - PassRefPtr<UStringImpl> tryMakeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5) - { - StringTypeAdapter<StringType1> adapter1(string1); - StringTypeAdapter<StringType2> adapter2(string2); - StringTypeAdapter<StringType3> adapter3(string3); - StringTypeAdapter<StringType4> adapter4(string4); - StringTypeAdapter<StringType5> adapter5(string5); - - UChar* buffer; - bool overflow = false; - unsigned length = adapter1.length(); - sumWithOverflow(length, adapter2.length(), overflow); - sumWithOverflow(length, adapter3.length(), overflow); - sumWithOverflow(length, adapter4.length(), overflow); - sumWithOverflow(length, adapter5.length(), overflow); - if (overflow) - return 0; - PassRefPtr<UStringImpl> resultImpl = UStringImpl::tryCreateUninitialized(length, buffer); - if (!resultImpl) - return 0; - UChar* result = buffer; - adapter1.writeTo(result); - result += adapter1.length(); - adapter2.writeTo(result); - result += adapter2.length(); - adapter3.writeTo(result); - result += adapter3.length(); - adapter4.writeTo(result); - result += adapter4.length(); - adapter5.writeTo(result); - - return resultImpl; - } +inline bool operator!=(const UString& s1, const UString& s2) +{ + return !JSC::operator==(s1, s2); +} - template<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5, typename StringType6> - PassRefPtr<UStringImpl> tryMakeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5, StringType6 string6) - { - StringTypeAdapter<StringType1> adapter1(string1); - StringTypeAdapter<StringType2> adapter2(string2); - StringTypeAdapter<StringType3> adapter3(string3); - StringTypeAdapter<StringType4> adapter4(string4); - StringTypeAdapter<StringType5> adapter5(string5); - StringTypeAdapter<StringType6> adapter6(string6); - - UChar* buffer; - bool overflow = false; - unsigned length = adapter1.length(); - sumWithOverflow(length, adapter2.length(), overflow); - sumWithOverflow(length, adapter3.length(), overflow); - sumWithOverflow(length, adapter4.length(), overflow); - sumWithOverflow(length, adapter5.length(), overflow); - sumWithOverflow(length, adapter6.length(), overflow); - if (overflow) - return 0; - PassRefPtr<UStringImpl> resultImpl = UStringImpl::tryCreateUninitialized(length, buffer); - if (!resultImpl) - return 0; +bool operator<(const UString& s1, const UString& s2); +bool operator>(const UString& s1, const UString& s2); - UChar* result = buffer; - adapter1.writeTo(result); - result += adapter1.length(); - adapter2.writeTo(result); - result += adapter2.length(); - adapter3.writeTo(result); - result += adapter3.length(); - adapter4.writeTo(result); - result += adapter4.length(); - adapter5.writeTo(result); - result += adapter5.length(); - adapter6.writeTo(result); - - return resultImpl; - } +bool operator==(const UString& s1, const char* s2); - template<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5, typename StringType6, typename StringType7> - PassRefPtr<UStringImpl> tryMakeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5, StringType6 string6, StringType7 string7) - { - StringTypeAdapter<StringType1> adapter1(string1); - StringTypeAdapter<StringType2> adapter2(string2); - StringTypeAdapter<StringType3> adapter3(string3); - StringTypeAdapter<StringType4> adapter4(string4); - StringTypeAdapter<StringType5> adapter5(string5); - StringTypeAdapter<StringType6> adapter6(string6); - StringTypeAdapter<StringType7> adapter7(string7); - - UChar* buffer; - bool overflow = false; - unsigned length = adapter1.length(); - sumWithOverflow(length, adapter2.length(), overflow); - sumWithOverflow(length, adapter3.length(), overflow); - sumWithOverflow(length, adapter4.length(), overflow); - sumWithOverflow(length, adapter5.length(), overflow); - sumWithOverflow(length, adapter6.length(), overflow); - sumWithOverflow(length, adapter7.length(), overflow); - if (overflow) - return 0; - PassRefPtr<UStringImpl> resultImpl = UStringImpl::tryCreateUninitialized(length, buffer); - if (!resultImpl) - return 0; +inline bool operator!=(const UString& s1, const char* s2) +{ + return !JSC::operator==(s1, s2); +} - UChar* result = buffer; - adapter1.writeTo(result); - result += adapter1.length(); - adapter2.writeTo(result); - result += adapter2.length(); - adapter3.writeTo(result); - result += adapter3.length(); - adapter4.writeTo(result); - result += adapter4.length(); - adapter5.writeTo(result); - result += adapter5.length(); - adapter6.writeTo(result); - result += adapter6.length(); - adapter7.writeTo(result); - - return resultImpl; - } +inline bool operator==(const char *s1, const UString& s2) +{ + return operator==(s2, s1); +} - template<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5, typename StringType6, typename StringType7, typename StringType8> - PassRefPtr<UStringImpl> tryMakeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5, StringType6 string6, StringType7 string7, StringType8 string8) - { - StringTypeAdapter<StringType1> adapter1(string1); - StringTypeAdapter<StringType2> adapter2(string2); - StringTypeAdapter<StringType3> adapter3(string3); - StringTypeAdapter<StringType4> adapter4(string4); - StringTypeAdapter<StringType5> adapter5(string5); - StringTypeAdapter<StringType6> adapter6(string6); - StringTypeAdapter<StringType7> adapter7(string7); - StringTypeAdapter<StringType8> adapter8(string8); - - UChar* buffer; - bool overflow = false; - unsigned length = adapter1.length(); - sumWithOverflow(length, adapter2.length(), overflow); - sumWithOverflow(length, adapter3.length(), overflow); - sumWithOverflow(length, adapter4.length(), overflow); - sumWithOverflow(length, adapter5.length(), overflow); - sumWithOverflow(length, adapter6.length(), overflow); - sumWithOverflow(length, adapter7.length(), overflow); - sumWithOverflow(length, adapter8.length(), overflow); - if (overflow) - return 0; - PassRefPtr<UStringImpl> resultImpl = UStringImpl::tryCreateUninitialized(length, buffer); - if (!resultImpl) - return 0; +inline bool operator!=(const char *s1, const UString& s2) +{ + return !JSC::operator==(s1, s2); +} - UChar* result = buffer; - adapter1.writeTo(result); - result += adapter1.length(); - adapter2.writeTo(result); - result += adapter2.length(); - adapter3.writeTo(result); - result += adapter3.length(); - adapter4.writeTo(result); - result += adapter4.length(); - adapter5.writeTo(result); - result += adapter5.length(); - adapter6.writeTo(result); - result += adapter6.length(); - adapter7.writeTo(result); - result += adapter7.length(); - adapter8.writeTo(result); - - return resultImpl; - } +inline int codePointCompare(const UString& s1, const UString& s2) +{ + return codePointCompare(s1.impl(), s2.impl()); +} - template<typename StringType1, typename StringType2> - UString makeString(StringType1 string1, StringType2 string2) +struct UStringHash { + static unsigned hash(StringImpl* key) { return key->hash(); } + static bool equal(const StringImpl* a, const StringImpl* b) { - PassRefPtr<UStringImpl> resultImpl = tryMakeString(string1, string2); - if (!resultImpl) - CRASH(); - return resultImpl; - } + if (a == b) + return true; + if (!a || !b) + return false; - template<typename StringType1, typename StringType2, typename StringType3> - UString makeString(StringType1 string1, StringType2 string2, StringType3 string3) - { - PassRefPtr<UStringImpl> resultImpl = tryMakeString(string1, string2, string3); - if (!resultImpl) - CRASH(); - return resultImpl; - } + unsigned aLength = a->length(); + unsigned bLength = b->length(); + if (aLength != bLength) + return false; - template<typename StringType1, typename StringType2, typename StringType3, typename StringType4> - UString makeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4) - { - PassRefPtr<UStringImpl> resultImpl = tryMakeString(string1, string2, string3, string4); - if (!resultImpl) - CRASH(); - return resultImpl; - } + // FIXME: perhaps we should have a more abstract macro that indicates when + // going 4 bytes at a time is unsafe +#if CPU(ARM) || CPU(SH4) + const UChar* aChars = a->characters(); + const UChar* bChars = b->characters(); + for (unsigned i = 0; i != aLength; ++i) { + if (*aChars++ != *bChars++) + return false; + } + return true; +#else + /* Do it 4-bytes-at-a-time on architectures where it's safe */ + const uint32_t* aChars = reinterpret_cast<const uint32_t*>(a->characters()); + const uint32_t* bChars = reinterpret_cast<const uint32_t*>(b->characters()); + + unsigned halfLength = aLength >> 1; + for (unsigned i = 0; i != halfLength; ++i) + if (*aChars++ != *bChars++) + return false; + + if (aLength & 1 && *reinterpret_cast<const uint16_t*>(aChars) != *reinterpret_cast<const uint16_t*>(bChars)) + return false; - template<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5> - UString makeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5) - { - PassRefPtr<UStringImpl> resultImpl = tryMakeString(string1, string2, string3, string4, string5); - if (!resultImpl) - CRASH(); - return resultImpl; + return true; +#endif } - template<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5, typename StringType6> - UString makeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5, StringType6 string6) + static unsigned hash(const RefPtr<StringImpl>& key) { return key->hash(); } + static bool equal(const RefPtr<StringImpl>& a, const RefPtr<StringImpl>& b) { - PassRefPtr<UStringImpl> resultImpl = tryMakeString(string1, string2, string3, string4, string5, string6); - if (!resultImpl) - CRASH(); - return resultImpl; + return equal(a.get(), b.get()); } - template<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5, typename StringType6, typename StringType7> - UString makeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5, StringType6 string6, StringType7 string7) + static unsigned hash(const UString& key) { return key.impl()->hash(); } + static bool equal(const UString& a, const UString& b) { - PassRefPtr<UStringImpl> resultImpl = tryMakeString(string1, string2, string3, string4, string5, string6, string7); - if (!resultImpl) - CRASH(); - return resultImpl; + return equal(a.impl(), b.impl()); } - template<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5, typename StringType6, typename StringType7, typename StringType8> - UString makeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5, StringType6 string6, StringType7 string7, StringType8 string8) - { - PassRefPtr<UStringImpl> resultImpl = tryMakeString(string1, string2, string3, string4, string5, string6, string7, string8); - if (!resultImpl) - CRASH(); - return resultImpl; - } + static const bool safeToCompareToEmptyOrDeleted = false; +}; } // namespace JSC namespace WTF { - template<typename T> struct DefaultHash; - template<typename T> struct StrHash; - - template<> struct StrHash<JSC::UString::Rep*> { - static unsigned hash(const JSC::UString::Rep* key) { return key->hash(); } - static bool equal(const JSC::UString::Rep* a, const JSC::UString::Rep* b) { return ::equal(a, b); } - static const bool safeToCompareToEmptyOrDeleted = false; - }; - - template<> struct StrHash<RefPtr<JSC::UString::Rep> > : public StrHash<JSC::UString::Rep*> { - using StrHash<JSC::UString::Rep*>::hash; - static unsigned hash(const RefPtr<JSC::UString::Rep>& key) { return key->hash(); } - using StrHash<JSC::UString::Rep*>::equal; - static bool equal(const RefPtr<JSC::UString::Rep>& a, const RefPtr<JSC::UString::Rep>& b) { return ::equal(a.get(), b.get()); } - static bool equal(const JSC::UString::Rep* a, const RefPtr<JSC::UString::Rep>& b) { return ::equal(a, b.get()); } - static bool equal(const RefPtr<JSC::UString::Rep>& a, const JSC::UString::Rep* b) { return ::equal(a.get(), b); } +// UStringHash is the default hash for UString +template<typename T> struct DefaultHash; +template<> struct DefaultHash<JSC::UString> { + typedef JSC::UStringHash Hash; +}; - static const bool safeToCompareToEmptyOrDeleted = false; - }; +template <> struct VectorTraits<JSC::UString> : SimpleClassVectorTraits +{ + static const bool canInitializeWithMemset = true; +}; - template <> struct VectorTraits<JSC::UString> : SimpleClassVectorTraits - { - static const bool canInitializeWithMemset = true; - }; - } // namespace WTF #endif + diff --git a/JavaScriptCore/runtime/UStringImpl.h b/JavaScriptCore/runtime/UStringImpl.h deleted file mode 100644 index 6401d3b..0000000 --- a/JavaScriptCore/runtime/UStringImpl.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright (C) 1999 Lars Knoll (knoll@kde.org) - * Copyright (C) 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. - * Copyright (C) 2009 Google 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 - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#ifndef UStringImpl_h -#define UStringImpl_h - -// FIXME: Remove this redundant name! -#include <wtf/text/StringImpl.h> -namespace JSC { typedef StringImpl UStringImpl; } - -#endif diff --git a/JavaScriptCore/wscript b/JavaScriptCore/wscript index 8f62349..e50b18d 100644 --- a/JavaScriptCore/wscript +++ b/JavaScriptCore/wscript @@ -29,7 +29,7 @@ import commands from settings import * -jscore_excludes = ['jsc.cpp', 'ucptable.cpp','ProfilerServer.mm', 'ExecutableAllocatorPosix.cpp'] +jscore_excludes = ['chartables.c', 'jsc.cpp', 'ucptable.cpp','ProfilerServer.mm', 'ExecutableAllocatorPosix.cpp'] jscore_excludes.extend(get_excludes(jscore_dir, ['*Brew.cpp', '*CF.cpp', '*Symbian.cpp'])) sources = [] @@ -42,35 +42,6 @@ if building_on_win32: else: jscore_excludes.append('JSStringRefBSTR.cpp') jscore_excludes.extend(get_excludes(jscore_dir, ['*Win.cpp'])) - -def generate_jscore_derived_sources(): - # build the derived sources - js_dir = jscore_dir - if building_on_win32: - js_dir = get_output('cygpath --unix "%s"' % js_dir) - derived_sources_dir = os.path.join(jscore_dir, 'DerivedSources') - if not os.path.exists(derived_sources_dir): - os.mkdir(derived_sources_dir) - - olddir = os.getcwd() - os.chdir(derived_sources_dir) - - # DerivedSources.make expects Cygwin (i.e. Unix-style) python, so use that instead. - if building_on_win32: - oldpath = os.environ["PATH"] - os.environ["PATH"] = "/usr/bin" + os.pathsep + os.environ["PATH"] - command = 'make -f %s/DerivedSources.make JavaScriptCore=%s BUILT_PRODUCTS_DIR=%s all FEATURE_DEFINES="%s"' % (js_dir, js_dir, js_dir, ' '.join(feature_defines)) - os.system(command) - if building_on_win32: - os.environ["PATH"] = oldpath - os.chdir(olddir) - -def set_options(opt): - common_set_options(opt) - -def configure(conf): - common_configure(conf) - generate_jscore_derived_sources() def build(bld): import Options @@ -91,9 +62,8 @@ def build(bld): uselib_local = '', install_path = output_dir) - jscore.find_sources_in_dirs(full_dirs, excludes = jscore_excludes) - - + jscore.find_sources_in_dirs(full_dirs, excludes = jscore_excludes) + obj = bld.new_task_gen( features = 'cxx cprogram', includes = '. .. assembler DerivedSources ForwardingHeaders ' + ' '.join(includes), diff --git a/JavaScriptCore/wtf/ByteArray.cpp b/JavaScriptCore/wtf/ByteArray.cpp index 526f147..910af59 100644 --- a/JavaScriptCore/wtf/ByteArray.cpp +++ b/JavaScriptCore/wtf/ByteArray.cpp @@ -25,12 +25,13 @@ #include "config.h" #include "ByteArray.h" +#include "StdLibExtras.h" namespace WTF { PassRefPtr<ByteArray> ByteArray::create(size_t size) { - unsigned char* buffer = new unsigned char[size + sizeof(ByteArray) - sizeof(size_t)]; + unsigned char* buffer = new unsigned char[size + OBJECT_OFFSETOF(ByteArray, m_data)]; ASSERT((reinterpret_cast<size_t>(buffer) & 3) == 0); return adoptRef(new (buffer) ByteArray(size)); } diff --git a/JavaScriptCore/wtf/CMakeLists.txt b/JavaScriptCore/wtf/CMakeLists.txt index 5cf108f..896794e 100644 --- a/JavaScriptCore/wtf/CMakeLists.txt +++ b/JavaScriptCore/wtf/CMakeLists.txt @@ -39,7 +39,9 @@ ADD_DEFINITIONS(-DBUILDING_WTF) ADD_LIBRARY(${WTF_LIBRARY_NAME} ${WTF_LIBRARY_TYPE} ${WTF_SOURCES}) TARGET_LINK_LIBRARIES(${WTF_LIBRARY_NAME} ${WTF_LIBRARIES}) -ADD_TARGET_PROPERTIES(${WTF_LIBRARY_NAME} LINK_FLAGS ${WTF_LINK_FLAGS}) +IF (WTF_LINK_FLAGS) + ADD_TARGET_PROPERTIES(${WTF_LIBRARY_NAME} LINK_FLAGS "${WTF_LINK_FLAGS}") +ENDIF () IF (SHARED_CORE) SET_TARGET_PROPERTIES(${WTF_LIBRARY_NAME} PROPERTIES VERSION ${PROJECT_VERSION} SOVERSION ${PROJECT_VERSION_MAJOR}) diff --git a/JavaScriptCore/wtf/FastMalloc.cpp b/JavaScriptCore/wtf/FastMalloc.cpp index c440417..39cd324 100644 --- a/JavaScriptCore/wtf/FastMalloc.cpp +++ b/JavaScriptCore/wtf/FastMalloc.cpp @@ -82,6 +82,7 @@ #if ENABLE(JSC_MULTIPLE_THREADS) #include <pthread.h> #endif +#include <wtf/StdLibExtras.h> #ifndef NO_TCMALLOC_SAMPLES #ifdef WTF_CHANGES @@ -415,16 +416,18 @@ extern "C" const int jscore_fastmalloc_introspection = 0; #include "TCSpinLock.h" #include "TCSystemAlloc.h" #include <algorithm> -#include <errno.h> #include <limits> #include <pthread.h> #include <stdarg.h> #include <stddef.h> #include <stdio.h> +#if HAVE(ERRNO_H) +#include <errno.h> +#endif #if OS(UNIX) #include <unistd.h> #endif -#if COMPILER(MSVC) +#if OS(WINDOWS) #ifndef WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN #endif @@ -1015,7 +1018,7 @@ class PageHeapAllocator { if (!new_allocation) CRASH(); - *(void**)new_allocation = allocated_regions_; + *reinterpret_cast_ptr<void**>(new_allocation) = allocated_regions_; allocated_regions_ = new_allocation; free_area_ = new_allocation + kAlignedSize; free_avail_ = kAllocIncrement - kAlignedSize; @@ -2687,7 +2690,13 @@ ALWAYS_INLINE void TCMalloc_Central_FreeList::Populate() { if (span) pageheap->RegisterSizeClass(span, size_class_); } if (span == NULL) { +#if HAVE(ERRNO_H) MESSAGE("allocation failed: %d\n", errno); +#elif OS(WINDOWS) + MESSAGE("allocation failed: %d\n", ::GetLastError()); +#else + MESSAGE("allocation failed\n"); +#endif lock_.Lock(); return; } @@ -2710,7 +2719,7 @@ ALWAYS_INLINE void TCMalloc_Central_FreeList::Populate() { char* nptr; while ((nptr = ptr + size) <= limit) { *tail = ptr; - tail = reinterpret_cast<void**>(ptr); + tail = reinterpret_cast_ptr<void**>(ptr); ptr = nptr; num++; } @@ -3054,7 +3063,7 @@ void TCMalloc_ThreadCache::BecomeIdle() { if (heap->in_setspecific_) return; // Do not disturb the active caller heap->in_setspecific_ = true; - pthread_setspecific(heap_key, NULL); + setThreadHeap(NULL); #ifdef HAVE_TLS // Also update the copy in __thread threadlocal_heap = NULL; diff --git a/JavaScriptCore/wtf/Forward.h b/JavaScriptCore/wtf/Forward.h index a2cc75b..32435c8 100644 --- a/JavaScriptCore/wtf/Forward.h +++ b/JavaScriptCore/wtf/Forward.h @@ -34,6 +34,7 @@ namespace WTF { class AtomicString; class AtomicStringImpl; + class CString; class String; class StringBuffer; class StringImpl; @@ -49,6 +50,7 @@ using WTF::Vector; using WTF::AtomicString; using WTF::AtomicStringImpl; +using WTF::CString; using WTF::String; using WTF::StringBuffer; using WTF::StringImpl; diff --git a/JavaScriptCore/wtf/MD5.cpp b/JavaScriptCore/wtf/MD5.cpp index e995102..375446e 100644 --- a/JavaScriptCore/wtf/MD5.cpp +++ b/JavaScriptCore/wtf/MD5.cpp @@ -54,6 +54,7 @@ #include "StringExtras.h" #include "text/CString.h" #endif +#include <wtf/StdLibExtras.h> namespace WTF { @@ -103,7 +104,7 @@ static void reverseBytes(uint8_t* buf, unsigned longs) do { uint32_t t = static_cast<uint32_t>(buf[3] << 8 | buf[2]) << 16 | buf[1] << 8 | buf[0]; ASSERT_WITH_MESSAGE(!(reinterpret_cast<uintptr_t>(buf) % sizeof(t)), "alignment error of buf"); - *reinterpret_cast<uint32_t *>(buf) = t; + *reinterpret_cast_ptr<uint32_t *>(buf) = t; buf += 4; } while (--longs); } @@ -238,7 +239,7 @@ void MD5::addBytes(const uint8_t* input, size_t length) } memcpy(p, buf, t); reverseBytes(m_in, 16); - MD5Transform(m_buf, reinterpret_cast<uint32_t*>(m_in)); // m_in is 4-byte aligned. + MD5Transform(m_buf, reinterpret_cast_ptr<uint32_t*>(m_in)); // m_in is 4-byte aligned. buf += t; length -= t; } @@ -248,7 +249,7 @@ void MD5::addBytes(const uint8_t* input, size_t length) while (length >= 64) { memcpy(m_in, buf, 64); reverseBytes(m_in, 16); - MD5Transform(m_buf, reinterpret_cast<uint32_t*>(m_in)); // m_in is 4-byte aligned. + MD5Transform(m_buf, reinterpret_cast_ptr<uint32_t*>(m_in)); // m_in is 4-byte aligned. buf += 64; length -= 64; } @@ -275,7 +276,7 @@ void MD5::checksum(Vector<uint8_t, 16>& digest) // Two lots of padding: Pad the first block to 64 bytes memset(p, 0, count); reverseBytes(m_in, 16); - MD5Transform(m_buf, reinterpret_cast<uint32_t *>(m_in)); // m_in is 4-byte aligned. + MD5Transform(m_buf, reinterpret_cast_ptr<uint32_t *>(m_in)); // m_in is 4-byte aligned. // Now fill the next block with 56 bytes memset(m_in, 0, 56); @@ -287,10 +288,10 @@ void MD5::checksum(Vector<uint8_t, 16>& digest) // Append length in bits and transform // m_in is 4-byte aligned. - (reinterpret_cast<uint32_t*>(m_in))[14] = m_bits[0]; - (reinterpret_cast<uint32_t*>(m_in))[15] = m_bits[1]; + (reinterpret_cast_ptr<uint32_t*>(m_in))[14] = m_bits[0]; + (reinterpret_cast_ptr<uint32_t*>(m_in))[15] = m_bits[1]; - MD5Transform(m_buf, reinterpret_cast<uint32_t*>(m_in)); + MD5Transform(m_buf, reinterpret_cast_ptr<uint32_t*>(m_in)); reverseBytes(reinterpret_cast<uint8_t*>(m_buf), 4); // Now, m_buf contains checksum result. diff --git a/JavaScriptCore/wtf/PassRefPtr.h b/JavaScriptCore/wtf/PassRefPtr.h index 54fa14c..b43c5ba 100644 --- a/JavaScriptCore/wtf/PassRefPtr.h +++ b/JavaScriptCore/wtf/PassRefPtr.h @@ -67,8 +67,8 @@ namespace WTF { // It somewhat breaks the type system to allow transfer of ownership out of // a const PassRefPtr. However, it makes it much easier to work with PassRefPtr // temporaries, and we don't have a need to use real const PassRefPtrs anyway. - PassRefPtr(const PassRefPtr& o) : m_ptr(o.releaseRef()) { } - template<typename U> PassRefPtr(const PassRefPtr<U>& o) : m_ptr(o.releaseRef()) { } + PassRefPtr(const PassRefPtr& o) : m_ptr(o.leakRef()) { } + template<typename U> PassRefPtr(const PassRefPtr<U>& o) : m_ptr(o.leakRef()) { } ALWAYS_INLINE ~PassRefPtr() { derefIfNotNull(m_ptr); } @@ -106,7 +106,7 @@ namespace WTF { }; // NonNullPassRefPtr: Optimized for passing non-null pointers. A NonNullPassRefPtr - // begins life non-null, and can only become null through a call to releaseRef() + // begins life non-null, and can only become null through a call to leakRef() // or clear(). // FIXME: NonNullPassRefPtr could just inherit from PassRefPtr. However, @@ -130,19 +130,19 @@ namespace WTF { } NonNullPassRefPtr(const NonNullPassRefPtr& o) - : m_ptr(o.releaseRef()) + : m_ptr(o.leakRef()) { ASSERT(m_ptr); } template<typename U> NonNullPassRefPtr(const NonNullPassRefPtr<U>& o) - : m_ptr(o.releaseRef()) + : m_ptr(o.leakRef()) { ASSERT(m_ptr); } template<typename U> NonNullPassRefPtr(const PassRefPtr<U>& o) - : m_ptr(o.releaseRef()) + : m_ptr(o.leakRef()) { ASSERT(m_ptr); } @@ -207,7 +207,7 @@ namespace WTF { template<typename T> inline PassRefPtr<T>& PassRefPtr<T>::operator=(const PassRefPtr<T>& ref) { T* ptr = m_ptr; - m_ptr = ref.releaseRef(); + m_ptr = ref.leakRef(); derefIfNotNull(ptr); return *this; } @@ -215,7 +215,7 @@ namespace WTF { template<typename T> template<typename U> inline PassRefPtr<T>& PassRefPtr<T>::operator=(const PassRefPtr<U>& ref) { T* ptr = m_ptr; - m_ptr = ref.releaseRef(); + m_ptr = ref.leakRef(); derefIfNotNull(ptr); return *this; } @@ -278,12 +278,12 @@ namespace WTF { template<typename T, typename U> inline PassRefPtr<T> static_pointer_cast(const PassRefPtr<U>& p) { - return adoptRef(static_cast<T*>(p.releaseRef())); + return adoptRef(static_cast<T*>(p.leakRef())); } template<typename T, typename U> inline PassRefPtr<T> const_pointer_cast(const PassRefPtr<U>& p) { - return adoptRef(const_cast<T*>(p.releaseRef())); + return adoptRef(const_cast<T*>(p.leakRef())); } template<typename T> inline T* getPtr(const PassRefPtr<T>& p) diff --git a/JavaScriptCore/wtf/Platform.h b/JavaScriptCore/wtf/Platform.h index 95eb67f..727616f 100644 --- a/JavaScriptCore/wtf/Platform.h +++ b/JavaScriptCore/wtf/Platform.h @@ -541,7 +541,7 @@ #endif -#if OS(WINCE) && PLATFORM(QT) +#if OS(WINCE) #include <ce_time.h> #endif @@ -1068,6 +1068,10 @@ on MinGW. See https://bugs.webkit.org/show_bug.cgi?id=29268 */ #define WTF_USE_ACCELERATED_COMPOSITING 1 #endif +#if PLATFORM(QT) +#define WTF_USE_ACCELERATED_COMPOSITING 1 +#endif + /* FIXME: Defining ENABLE_3D_RENDERING here isn't really right, but it's always used with with WTF_USE_ACCELERATED_COMPOSITING, and it allows the feature to be turned on and off in one place. */ diff --git a/JavaScriptCore/wtf/RefPtr.h b/JavaScriptCore/wtf/RefPtr.h index f0c3091..8bd1ac3 100644 --- a/JavaScriptCore/wtf/RefPtr.h +++ b/JavaScriptCore/wtf/RefPtr.h @@ -32,19 +32,21 @@ namespace WTF { enum PlacementNewAdoptType { PlacementNewAdopt }; - template <typename T> class PassRefPtr; - template <typename T> class NonNullPassRefPtr; + template<typename T> class PassRefPtr; + template<typename T> class NonNullPassRefPtr; enum HashTableDeletedValueType { HashTableDeletedValue }; - template <typename T> class RefPtr : public FastAllocBase { + template<typename T> class RefPtr : public FastAllocBase { public: ALWAYS_INLINE RefPtr() : m_ptr(0) { } ALWAYS_INLINE RefPtr(T* ptr) : m_ptr(ptr) { refIfNotNull(ptr); } - ALWAYS_INLINE RefPtr(const RefPtr& o) : m_ptr(o.m_ptr) { T* ptr = m_ptr; refIfNotNull(ptr); } - // see comment in PassRefPtr.h for why this takes const reference - template <typename U> RefPtr(const PassRefPtr<U>&); - template <typename U> RefPtr(const NonNullPassRefPtr<U>&); + ALWAYS_INLINE RefPtr(const RefPtr& o) : m_ptr(o.m_ptr) { refIfNotNull(m_ptr); } + template<typename U> RefPtr(const RefPtr<U>& o) : m_ptr(o.get()) { refIfNotNull(m_ptr); } + + // See comments in PassRefPtr.h for an explanation of why these takes const references. + template<typename U> RefPtr(const PassRefPtr<U>&); + template<typename U> RefPtr(const NonNullPassRefPtr<U>&); // Special constructor for cases where we overwrite an object in place. ALWAYS_INLINE RefPtr(PlacementNewAdoptType) { } @@ -54,9 +56,7 @@ namespace WTF { bool isHashTableDeletedValue() const { return m_ptr == hashTableDeletedValue(); } ALWAYS_INLINE ~RefPtr() { derefIfNotNull(m_ptr); } - - template <typename U> RefPtr(const RefPtr<U>& o) : m_ptr(o.get()) { T* ptr = m_ptr; refIfNotNull(ptr); } - + T* get() const { return m_ptr; } void clear(); @@ -75,9 +75,9 @@ namespace WTF { RefPtr& operator=(T*); RefPtr& operator=(const PassRefPtr<T>&); RefPtr& operator=(const NonNullPassRefPtr<T>&); - template <typename U> RefPtr& operator=(const RefPtr<U>&); - template <typename U> RefPtr& operator=(const PassRefPtr<U>&); - template <typename U> RefPtr& operator=(const NonNullPassRefPtr<U>&); + template<typename U> RefPtr& operator=(const RefPtr<U>&); + template<typename U> RefPtr& operator=(const PassRefPtr<U>&); + template<typename U> RefPtr& operator=(const NonNullPassRefPtr<U>&); void swap(RefPtr&); @@ -87,24 +87,24 @@ namespace WTF { T* m_ptr; }; - template <typename T> template <typename U> inline RefPtr<T>::RefPtr(const PassRefPtr<U>& o) - : m_ptr(o.releaseRef()) + template<typename T> template<typename U> inline RefPtr<T>::RefPtr(const PassRefPtr<U>& o) + : m_ptr(o.leakRef()) { } - template <typename T> template <typename U> inline RefPtr<T>::RefPtr(const NonNullPassRefPtr<U>& o) - : m_ptr(o.releaseRef()) + template<typename T> template<typename U> inline RefPtr<T>::RefPtr(const NonNullPassRefPtr<U>& o) + : m_ptr(o.leakRef()) { } - template <typename T> inline void RefPtr<T>::clear() + template<typename T> inline void RefPtr<T>::clear() { T* ptr = m_ptr; m_ptr = 0; derefIfNotNull(ptr); } - template <typename T> inline RefPtr<T>& RefPtr<T>::operator=(const RefPtr<T>& o) + template<typename T> inline RefPtr<T>& RefPtr<T>::operator=(const RefPtr<T>& o) { T* optr = o.get(); refIfNotNull(optr); @@ -114,7 +114,7 @@ namespace WTF { return *this; } - template <typename T> template <typename U> inline RefPtr<T>& RefPtr<T>::operator=(const RefPtr<U>& o) + template<typename T> template<typename U> inline RefPtr<T>& RefPtr<T>::operator=(const RefPtr<U>& o) { T* optr = o.get(); refIfNotNull(optr); @@ -124,7 +124,7 @@ namespace WTF { return *this; } - template <typename T> inline RefPtr<T>& RefPtr<T>::operator=(T* optr) + template<typename T> inline RefPtr<T>& RefPtr<T>::operator=(T* optr) { refIfNotNull(optr); T* ptr = m_ptr; @@ -133,89 +133,89 @@ namespace WTF { return *this; } - template <typename T> inline RefPtr<T>& RefPtr<T>::operator=(const PassRefPtr<T>& o) + template<typename T> inline RefPtr<T>& RefPtr<T>::operator=(const PassRefPtr<T>& o) { T* ptr = m_ptr; - m_ptr = o.releaseRef(); + m_ptr = o.leakRef(); derefIfNotNull(ptr); return *this; } - template <typename T> inline RefPtr<T>& RefPtr<T>::operator=(const NonNullPassRefPtr<T>& o) + template<typename T> inline RefPtr<T>& RefPtr<T>::operator=(const NonNullPassRefPtr<T>& o) { T* ptr = m_ptr; - m_ptr = o.releaseRef(); + m_ptr = o.leakRef(); derefIfNotNull(ptr); return *this; } - template <typename T> template <typename U> inline RefPtr<T>& RefPtr<T>::operator=(const PassRefPtr<U>& o) + template<typename T> template<typename U> inline RefPtr<T>& RefPtr<T>::operator=(const PassRefPtr<U>& o) { T* ptr = m_ptr; - m_ptr = o.releaseRef(); + m_ptr = o.leakRef(); derefIfNotNull(ptr); return *this; } - template <typename T> template <typename U> inline RefPtr<T>& RefPtr<T>::operator=(const NonNullPassRefPtr<U>& o) + template<typename T> template<typename U> inline RefPtr<T>& RefPtr<T>::operator=(const NonNullPassRefPtr<U>& o) { T* ptr = m_ptr; - m_ptr = o.releaseRef(); + m_ptr = o.leakRef(); derefIfNotNull(ptr); return *this; } - template <class T> inline void RefPtr<T>::swap(RefPtr<T>& o) + template<class T> inline void RefPtr<T>::swap(RefPtr<T>& o) { std::swap(m_ptr, o.m_ptr); } - template <class T> inline void swap(RefPtr<T>& a, RefPtr<T>& b) + template<class T> inline void swap(RefPtr<T>& a, RefPtr<T>& b) { a.swap(b); } - template <typename T, typename U> inline bool operator==(const RefPtr<T>& a, const RefPtr<U>& b) + template<typename T, typename U> inline bool operator==(const RefPtr<T>& a, const RefPtr<U>& b) { return a.get() == b.get(); } - template <typename T, typename U> inline bool operator==(const RefPtr<T>& a, U* b) + template<typename T, typename U> inline bool operator==(const RefPtr<T>& a, U* b) { return a.get() == b; } - template <typename T, typename U> inline bool operator==(T* a, const RefPtr<U>& b) + template<typename T, typename U> inline bool operator==(T* a, const RefPtr<U>& b) { return a == b.get(); } - template <typename T, typename U> inline bool operator!=(const RefPtr<T>& a, const RefPtr<U>& b) + template<typename T, typename U> inline bool operator!=(const RefPtr<T>& a, const RefPtr<U>& b) { return a.get() != b.get(); } - template <typename T, typename U> inline bool operator!=(const RefPtr<T>& a, U* b) + template<typename T, typename U> inline bool operator!=(const RefPtr<T>& a, U* b) { return a.get() != b; } - template <typename T, typename U> inline bool operator!=(T* a, const RefPtr<U>& b) + template<typename T, typename U> inline bool operator!=(T* a, const RefPtr<U>& b) { return a != b.get(); } - template <typename T, typename U> inline RefPtr<T> static_pointer_cast(const RefPtr<U>& p) + template<typename T, typename U> inline RefPtr<T> static_pointer_cast(const RefPtr<U>& p) { return RefPtr<T>(static_cast<T*>(p.get())); } - template <typename T, typename U> inline RefPtr<T> const_pointer_cast(const RefPtr<U>& p) + template<typename T, typename U> inline RefPtr<T> const_pointer_cast(const RefPtr<U>& p) { return RefPtr<T>(const_cast<T*>(p.get())); } - template <typename T> inline T* getPtr(const RefPtr<T>& p) + template<typename T> inline T* getPtr(const RefPtr<T>& p) { return p.get(); } diff --git a/JavaScriptCore/wtf/RetainPtr.h b/JavaScriptCore/wtf/RetainPtr.h index f5a027e..68b5a04 100644 --- a/JavaScriptCore/wtf/RetainPtr.h +++ b/JavaScriptCore/wtf/RetainPtr.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2005, 2006, 2007, 2008 Apple Inc. All rights reserved. + * Copyright (C) 2005, 2006, 2007, 2008, 2010 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 @@ -48,7 +48,7 @@ namespace WTF { } #endif - template <typename T> class RetainPtr { + template<typename T> class RetainPtr { public: typedef typename RemovePointer<T>::Type ValueType; typedef ValueType* PtrType; @@ -67,12 +67,13 @@ namespace WTF { ~RetainPtr() { if (PtrType ptr = m_ptr) CFRelease(ptr); } - template <typename U> RetainPtr(const RetainPtr<U>& o) : m_ptr(o.get()) { if (PtrType ptr = m_ptr) CFRetain(ptr); } + template<typename U> RetainPtr(const RetainPtr<U>&); PtrType get() const { return m_ptr; } - - PtrType releaseRef() { PtrType tmp = m_ptr; m_ptr = 0; return tmp; } - + + void clear(); + PtrType leakRef() WARN_UNUSED_RETURN; + PtrType operator->() const { return m_ptr; } bool operator!() const { return !m_ptr; } @@ -82,22 +83,47 @@ namespace WTF { operator UnspecifiedBoolType() const { return m_ptr ? &RetainPtr::m_ptr : 0; } RetainPtr& operator=(const RetainPtr&); - template <typename U> RetainPtr& operator=(const RetainPtr<U>&); + template<typename U> RetainPtr& operator=(const RetainPtr<U>&); RetainPtr& operator=(PtrType); - template <typename U> RetainPtr& operator=(U*); + template<typename U> RetainPtr& operator=(U*); void adoptCF(PtrType); void adoptNS(PtrType); void swap(RetainPtr&); + // FIXME: Remove releaseRef once we change all callers to call leakRef instead. + PtrType releaseRef() { return leakRef(); } + private: static T* hashTableDeletedValue() { return reinterpret_cast<T*>(-1); } PtrType m_ptr; }; - template <typename T> inline RetainPtr<T>& RetainPtr<T>::operator=(const RetainPtr<T>& o) + template<typename T> template<typename U> inline RetainPtr<T>::RetainPtr(const RetainPtr<U>& o) + : m_ptr(o.get()) + { + if (PtrType ptr = m_ptr) + CFRetain(ptr); + } + + template<typename T> inline void RetainPtr<T>::clear() + { + if (PtrType ptr = m_ptr) { + m_ptr = 0; + CFRelease(ptr); + } + } + + template<typename T> inline typename RetainPtr<T>::PtrType RetainPtr<T>::leakRef() + { + PtrType ptr = m_ptr; + m_ptr = 0; + return ptr; + } + + template<typename T> inline RetainPtr<T>& RetainPtr<T>::operator=(const RetainPtr<T>& o) { PtrType optr = o.get(); if (optr) @@ -109,7 +135,7 @@ namespace WTF { return *this; } - template <typename T> template <typename U> inline RetainPtr<T>& RetainPtr<T>::operator=(const RetainPtr<U>& o) + template<typename T> template<typename U> inline RetainPtr<T>& RetainPtr<T>::operator=(const RetainPtr<U>& o) { PtrType optr = o.get(); if (optr) @@ -121,7 +147,7 @@ namespace WTF { return *this; } - template <typename T> inline RetainPtr<T>& RetainPtr<T>::operator=(PtrType optr) + template<typename T> inline RetainPtr<T>& RetainPtr<T>::operator=(PtrType optr) { if (optr) CFRetain(optr); @@ -132,7 +158,7 @@ namespace WTF { return *this; } - template <typename T> inline void RetainPtr<T>::adoptCF(PtrType optr) + template<typename T> inline void RetainPtr<T>::adoptCF(PtrType optr) { PtrType ptr = m_ptr; m_ptr = optr; @@ -140,7 +166,7 @@ namespace WTF { CFRelease(ptr); } - template <typename T> inline void RetainPtr<T>::adoptNS(PtrType optr) + template<typename T> inline void RetainPtr<T>::adoptNS(PtrType optr) { adoptNSReference(optr); @@ -150,7 +176,7 @@ namespace WTF { CFRelease(ptr); } - template <typename T> template <typename U> inline RetainPtr<T>& RetainPtr<T>::operator=(U* optr) + template<typename T> template<typename U> inline RetainPtr<T>& RetainPtr<T>::operator=(U* optr) { if (optr) CFRetain(optr); @@ -161,42 +187,42 @@ namespace WTF { return *this; } - template <class T> inline void RetainPtr<T>::swap(RetainPtr<T>& o) + template<typename T> inline void RetainPtr<T>::swap(RetainPtr<T>& o) { std::swap(m_ptr, o.m_ptr); } - template <class T> inline void swap(RetainPtr<T>& a, RetainPtr<T>& b) + template<typename T> inline void swap(RetainPtr<T>& a, RetainPtr<T>& b) { a.swap(b); } - template <typename T, typename U> inline bool operator==(const RetainPtr<T>& a, const RetainPtr<U>& b) + template<typename T, typename U> inline bool operator==(const RetainPtr<T>& a, const RetainPtr<U>& b) { return a.get() == b.get(); } - template <typename T, typename U> inline bool operator==(const RetainPtr<T>& a, U* b) + template<typename T, typename U> inline bool operator==(const RetainPtr<T>& a, U* b) { return a.get() == b; } - template <typename T, typename U> inline bool operator==(T* a, const RetainPtr<U>& b) + template<typename T, typename U> inline bool operator==(T* a, const RetainPtr<U>& b) { return a == b.get(); } - template <typename T, typename U> inline bool operator!=(const RetainPtr<T>& a, const RetainPtr<U>& b) + template<typename T, typename U> inline bool operator!=(const RetainPtr<T>& a, const RetainPtr<U>& b) { return a.get() != b.get(); } - template <typename T, typename U> inline bool operator!=(const RetainPtr<T>& a, U* b) + template<typename T, typename U> inline bool operator!=(const RetainPtr<T>& a, U* b) { return a.get() != b; } - template <typename T, typename U> inline bool operator!=(T* a, const RetainPtr<U>& b) + template<typename T, typename U> inline bool operator!=(T* a, const RetainPtr<U>& b) { return a != b.get(); } diff --git a/JavaScriptCore/wtf/StdLibExtras.h b/JavaScriptCore/wtf/StdLibExtras.h index 96a929c..d594c17 100644 --- a/JavaScriptCore/wtf/StdLibExtras.h +++ b/JavaScriptCore/wtf/StdLibExtras.h @@ -51,6 +51,40 @@ #define STRINGIZE(exp) #exp #define STRINGIZE_VALUE_OF(exp) STRINGIZE(exp) +/* + * The reinterpret_cast<Type1*>([pointer to Type2]) expressions - where + * sizeof(Type1) > sizeof(Type2) - cause the following warning on ARM with GCC: + * increases required alignment of target type. + * + * An implicit or an extra static_cast<void*> bypasses the warning. + * For more info see the following bugzilla entries: + * - https://bugs.webkit.org/show_bug.cgi?id=38045 + * - http://gcc.gnu.org/bugzilla/show_bug.cgi?id=43976 + */ +#if CPU(ARM) && COMPILER(GCC) +template<typename Type> +bool isPointerTypeAlignmentOkay(Type* ptr) +{ + return !(reinterpret_cast<intptr_t>(ptr) % __alignof__(Type)); +} + +template<typename TypePtr> +TypePtr reinterpret_cast_ptr(void* ptr) +{ + ASSERT(isPointerTypeAlignmentOkay(reinterpret_cast<TypePtr>(ptr))); + return reinterpret_cast<TypePtr>(ptr); +} + +template<typename TypePtr> +TypePtr reinterpret_cast_ptr(const void* ptr) +{ + ASSERT(isPointerTypeAlignmentOkay(reinterpret_cast<TypePtr>(ptr))); + return reinterpret_cast<TypePtr>(ptr); +} +#else +#define reinterpret_cast_ptr reinterpret_cast +#endif + namespace WTF { /* diff --git a/JavaScriptCore/wtf/Vector.h b/JavaScriptCore/wtf/Vector.h index c60de15..f73793f 100644 --- a/JavaScriptCore/wtf/Vector.h +++ b/JavaScriptCore/wtf/Vector.h @@ -24,6 +24,7 @@ #include "FastAllocBase.h" #include "Noncopyable.h" #include "NotFound.h" +#include "StdLibExtras.h" #include "ValueCheck.h" #include "VectorTraits.h" #include <limits> @@ -481,7 +482,7 @@ namespace WTF { using Base::m_capacity; static const size_t m_inlineBufferSize = inlineCapacity * sizeof(T); - T* inlineBuffer() { return reinterpret_cast<T*>(m_inlineBuffer.buffer); } + T* inlineBuffer() { return reinterpret_cast_ptr<T*>(m_inlineBuffer.buffer); } AlignedBuffer<m_inlineBufferSize, WTF_ALIGN_OF(T)> m_inlineBuffer; }; diff --git a/JavaScriptCore/wtf/dtoa.cpp b/JavaScriptCore/wtf/dtoa.cpp index 2c478a0..f7e19bf 100644 --- a/JavaScriptCore/wtf/dtoa.cpp +++ b/JavaScriptCore/wtf/dtoa.cpp @@ -88,21 +88,6 @@ * #define Bad_float_h if your system lacks a float.h or if it does not * define some or all of DBL_DIG, DBL_MAX_10_EXP, DBL_MAX_EXP, * FLT_RADIX, FLT_ROUNDS, and DBL_MAX. - * #define INFNAN_CHECK on IEEE systems to cause strtod to check for - * Infinity and NaN (case insensitively). On some systems (e.g., - * some HP systems), it may be necessary to #define NAN_WORD0 - * appropriately -- to the most significant word of a quiet NaN. - * (On HP Series 700/800 machines, -DNAN_WORD0=0x7ff40000 works.) - * When INFNAN_CHECK is #defined and No_Hex_NaN is not #defined, - * strtod also accepts (case insensitively) strings of the form - * NaN(x), where x is a string of hexadecimal digits and spaces; - * if there is only one string of hexadecimal digits, it is taken - * for the 52 fraction bits of the resulting NaN; if there are two - * or more strings of hex digits, the first is for the high 20 bits, - * the second and subsequent for the low 32 bits, with intervening - * white space ignored; but if this results in none of the 52 - * fraction bits being on (an IEEE Infinity symbol), then NAN_WORD0 - * and NAN_WORD1 are used instead. * #define NO_IEEE_Scale to disable new (Feb. 1997) logic in strtod that * avoids underflows on inputs whose result does not underflow. * If you #define NO_IEEE_Scale on a machine that uses IEEE-format @@ -166,9 +151,6 @@ #define IEEE_8087 #endif -#define INFNAN_CHECK -#define No_Hex_NaN - #if defined(IEEE_8087) + defined(IEEE_MC68k) + defined(IEEE_ARM) != 1 Exactly one of IEEE_8087, IEEE_ARM or IEEE_MC68k should be defined. #endif @@ -1040,78 +1022,6 @@ static const double tinytens[] = { 1e-16, 1e-32, 1e-64, 1e-128, #define Scale_Bit 0x10 #define n_bigtens 5 -#if defined(INFNAN_CHECK) - -#ifndef NAN_WORD0 -#define NAN_WORD0 0x7ff80000 -#endif - -#ifndef NAN_WORD1 -#define NAN_WORD1 0 -#endif - -static int match(const char** sp, const char* t) -{ - int c, d; - const char* s = *sp; - - while ((d = *t++)) { - if ((c = *++s) >= 'A' && c <= 'Z') - c += 'a' - 'A'; - if (c != d) - return 0; - } - *sp = s + 1; - return 1; -} - -#ifndef No_Hex_NaN -static void hexnan(U* rvp, const char** sp) -{ - uint32_t c, x[2]; - const char* s; - int havedig, udx0, xshift; - - x[0] = x[1] = 0; - havedig = xshift = 0; - udx0 = 1; - s = *sp; - while ((c = *(const unsigned char*)++s)) { - if (c >= '0' && c <= '9') - c -= '0'; - else if (c >= 'a' && c <= 'f') - c += 10 - 'a'; - else if (c >= 'A' && c <= 'F') - c += 10 - 'A'; - else if (c <= ' ') { - if (udx0 && havedig) { - udx0 = 0; - xshift = 1; - } - continue; - } else if (/*(*/ c == ')' && havedig) { - *sp = s + 1; - break; - } else - return; /* invalid form: don't change *sp */ - havedig = 1; - if (xshift) { - xshift = 0; - x[0] = x[1]; - x[1] = 0; - } - if (udx0) - x[0] = (x[0] << 4) | (x[1] >> 28); - x[1] = (x[1] << 4) | c; - } - if ((x[0] &= 0xfffff) || x[1]) { - word0(rvp) = Exp_mask | x[0]; - word1(rvp) = x[1]; - } -} -#endif /*No_Hex_NaN*/ -#endif /* INFNAN_CHECK */ - double strtod(const char* s00, char** se) { #ifdef Avoid_Underflow @@ -1236,33 +1146,6 @@ digDone: } if (!nd) { if (!nz && !nz0) { -#ifdef INFNAN_CHECK - /* Check for Nan and Infinity */ - switch (c) { - case 'i': - case 'I': - if (match(&s, "nf")) { - --s; - if (!match(&s, "inity")) - ++s; - word0(&rv) = 0x7ff00000; - word1(&rv) = 0; - goto ret; - } - break; - case 'n': - case 'N': - if (match(&s, "an")) { - word0(&rv) = NAN_WORD0; - word1(&rv) = NAN_WORD1; -#ifndef No_Hex_NaN - if (*s == '(') /*)*/ - hexnan(&rv, &s); -#endif - goto ret; - } - } -#endif /* INFNAN_CHECK */ ret0: s = s00; sign = 0; diff --git a/JavaScriptCore/wtf/gobject/GRefPtr.cpp b/JavaScriptCore/wtf/gobject/GRefPtr.cpp index e7cf34b..9d16cb5 100644 --- a/JavaScriptCore/wtf/gobject/GRefPtr.cpp +++ b/JavaScriptCore/wtf/gobject/GRefPtr.cpp @@ -35,4 +35,18 @@ template <> void derefGPtr(GHashTable* ptr) g_hash_table_unref(ptr); } +#if GLIB_CHECK_VERSION(2, 24, 0) +template <> GVariant* refGPtr(GVariant* ptr) +{ + if (ptr) + g_variant_ref(ptr); + return ptr; +} + +template <> void derefGPtr(GVariant* ptr) +{ + g_variant_unref(ptr); +} +#endif + } // namespace WTF diff --git a/JavaScriptCore/wtf/gobject/GRefPtr.h b/JavaScriptCore/wtf/gobject/GRefPtr.h index c4d4107..9a07d93 100644 --- a/JavaScriptCore/wtf/gobject/GRefPtr.h +++ b/JavaScriptCore/wtf/gobject/GRefPtr.h @@ -25,11 +25,7 @@ #include "AlwaysInline.h" #include <algorithm> - -typedef struct _GHashTable GHashTable; -typedef void* gpointer; -extern "C" void g_object_unref(gpointer object); -extern "C" gpointer g_object_ref_sink(gpointer object); +#include <glib.h> namespace WTF { @@ -41,6 +37,11 @@ template <typename T> GRefPtr<T> adoptGRef(T*); template <> GHashTable* refGPtr(GHashTable* ptr); template <> void derefGPtr(GHashTable* ptr); +#if GLIB_CHECK_VERSION(2, 24, 0) +template <> GVariant* refGPtr(GVariant* ptr); +template <> void derefGPtr(GVariant* ptr); +#endif + template <typename T> class GRefPtr { public: GRefPtr() : m_ptr(0) { } diff --git a/JavaScriptCore/wtf/qt/StringQt.cpp b/JavaScriptCore/wtf/qt/StringQt.cpp index c02505a..16dd439 100644 --- a/JavaScriptCore/wtf/qt/StringQt.cpp +++ b/JavaScriptCore/wtf/qt/StringQt.cpp @@ -25,6 +25,7 @@ #include "config.h" +#include <wtf/StdLibExtras.h> #include <wtf/text/WTFString.h> #include <QString> @@ -36,14 +37,14 @@ String::String(const QString& qstr) { if (qstr.isNull()) return; - m_impl = StringImpl::create(reinterpret_cast<const UChar*>(qstr.constData()), qstr.length()); + m_impl = StringImpl::create(reinterpret_cast_ptr<const UChar*>(qstr.constData()), qstr.length()); } String::String(const QStringRef& ref) { if (!ref.string()) return; - m_impl = StringImpl::create(reinterpret_cast<const UChar*>(ref.unicode()), ref.length()); + m_impl = StringImpl::create(reinterpret_cast_ptr<const UChar*>(ref.unicode()), ref.length()); } String::operator QString() const diff --git a/JavaScriptCore/wtf/text/AtomicString.h b/JavaScriptCore/wtf/text/AtomicString.h index d29981a..cfabde7 100644 --- a/JavaScriptCore/wtf/text/AtomicString.h +++ b/JavaScriptCore/wtf/text/AtomicString.h @@ -32,14 +32,10 @@ #define ATOMICSTRING_CONVERSION #endif -// FIXME: this should be in WTF, too! -namespace WebCore { -struct AtomicStringHash; -} -using WebCore::AtomicStringHash; - namespace WTF { +struct AtomicStringHash; + class AtomicString { public: static void init(); @@ -75,10 +71,10 @@ public: bool contains(const String& s, bool caseSensitive = true) const { return m_string.contains(s, caseSensitive); } - int find(UChar c, int start = 0) const { return m_string.find(c, start); } - int find(const char* s, int start = 0, bool caseSentitive = true) const + size_t find(UChar c, size_t start = 0) const { return m_string.find(c, start); } + size_t find(const char* s, size_t start = 0, bool caseSentitive = true) const { return m_string.find(s, start, caseSentitive); } - int find(const String& s, int start = 0, bool caseSentitive = true) const + size_t find(const String& s, size_t start = 0, bool caseSentitive = true) const { return m_string.find(s, start, caseSentitive); } bool startsWith(const String& s, bool caseSensitive = true) const diff --git a/JavaScriptCore/wtf/text/AtomicStringHash.h b/JavaScriptCore/wtf/text/AtomicStringHash.h new file mode 100644 index 0000000..f6e4ad1 --- /dev/null +++ b/JavaScriptCore/wtf/text/AtomicStringHash.h @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2008 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef AtomicStringHash_h +#define AtomicStringHash_h + +#include <wtf/text/AtomicString.h> +#include <wtf/HashTraits.h> + +namespace WTF { + + struct AtomicStringHash { + static unsigned hash(const AtomicString& key) + { + return key.impl()->existingHash(); + } + + static bool equal(const AtomicString& a, const AtomicString& b) + { + return a == b; + } + + static const bool safeToCompareToEmptyOrDeleted = false; + }; + + // AtomicStringHash is the default hash for AtomicString + template<> struct HashTraits<WTF::AtomicString> : GenericHashTraits<WTF::AtomicString> { + static const bool emptyValueIsZero = true; + static void constructDeletedValue(WTF::AtomicString& slot) { new (&slot) WTF::AtomicString(HashTableDeletedValue); } + static bool isDeletedValue(const WTF::AtomicString& slot) { return slot.isHashTableDeletedValue(); } + }; + +} + +using WTF::AtomicStringHash; + +#endif diff --git a/JavaScriptCore/wtf/text/StringImpl.cpp b/JavaScriptCore/wtf/text/StringImpl.cpp index 3669628..ab0f009 100644 --- a/JavaScriptCore/wtf/text/StringImpl.cpp +++ b/JavaScriptCore/wtf/text/StringImpl.cpp @@ -498,175 +498,250 @@ int codePointCompare(const StringImpl* s1, const StringImpl* s2) return (l1 > l2) ? 1 : -1; } -int StringImpl::find(const char* chs, int index, bool caseSensitive) +size_t StringImpl::find(UChar c, unsigned start) { - if (!chs || index < 0) - return -1; + return WTF::find(m_data, m_length, c, start); +} - int chsLength = strlen(chs); - int n = m_length - index; - if (n < 0) - return -1; - n -= chsLength - 1; - if (n <= 0) - return -1; +size_t StringImpl::find(CharacterMatchFunctionPtr matchFunction, unsigned start) +{ + return WTF::find(m_data, m_length, matchFunction, start); +} - const char* chsPlusOne = chs + 1; - int chsLengthMinusOne = chsLength - 1; - - const UChar* ptr = m_data + index - 1; - if (caseSensitive) { - UChar c = *chs; - do { - if (*++ptr == c && equal(ptr + 1, chsPlusOne, chsLengthMinusOne)) - return m_length - chsLength - n + 1; - } while (--n); - } else { - UChar lc = Unicode::foldCase(*chs); - do { - if (Unicode::foldCase(*++ptr) == lc && equalIgnoringCase(ptr + 1, chsPlusOne, chsLengthMinusOne)) - return m_length - chsLength - n + 1; - } while (--n); +size_t StringImpl::find(const char* matchString, unsigned index) +{ + // Check for null or empty string to match against + if (!matchString) + return notFound; + unsigned matchLength = strlen(matchString); + if (!matchLength) + return min(index, length()); + + // Optimization 1: fast case for strings of length 1. + if (matchLength == 1) + return WTF::find(characters(), length(), *(const unsigned char*)matchString, index); + + // Check index & matchLength are in range. + if (index > length()) + return notFound; + unsigned searchLength = length() - index; + if (matchLength > searchLength) + return notFound; + // delta is the number of additional times to test; delta == 0 means test only once. + unsigned delta = searchLength - matchLength; + + const UChar* searchCharacters = characters() + index; + const unsigned char* matchCharacters = (const unsigned char*)matchString; + + // Optimization 2: keep a running hash of the strings, + // only call memcmp if the hashes match. + unsigned searchHash = 0; + unsigned matchHash = 0; + for (unsigned i = 0; i < matchLength; ++i) { + searchHash += searchCharacters[i]; + matchHash += matchCharacters[i]; } - return -1; + unsigned i = 0; + // keep looping until we match + while (searchHash != matchHash || !equal(searchCharacters + i, matchString, matchLength)) { + if (i == delta) + return notFound; + searchHash += searchCharacters[i + matchLength]; + searchHash -= searchCharacters[i]; + ++i; + } + return index + i; } -int StringImpl::find(UChar c, int start) +size_t StringImpl::findIgnoringCase(const char* matchString, unsigned index) { - return WTF::find(m_data, m_length, c, start); + // Check for null or empty string to match against + if (!matchString) + return notFound; + unsigned matchLength = strlen(matchString); + if (!matchLength) + return min(index, length()); + + // Check index & matchLength are in range. + if (index > length()) + return notFound; + unsigned searchLength = length() - index; + if (matchLength > searchLength) + return notFound; + // delta is the number of additional times to test; delta == 0 means test only once. + unsigned delta = searchLength - matchLength; + + const UChar* searchCharacters = characters() + index; + + unsigned i = 0; + // keep looping until we match + while (!equalIgnoringCase(searchCharacters + i, matchString, matchLength)) { + if (i == delta) + return notFound; + ++i; + } + return index + i; } -int StringImpl::find(CharacterMatchFunctionPtr matchFunction, int start) +size_t StringImpl::find(StringImpl* matchString, unsigned index) { - return WTF::find(m_data, m_length, matchFunction, start); + // Check for null or empty string to match against + if (!matchString) + return notFound; + unsigned matchLength = matchString->length(); + if (!matchLength) + return min(index, length()); + + // Optimization 1: fast case for strings of length 1. + if (matchLength == 1) + return WTF::find(characters(), length(), matchString->characters()[0], index); + + // Check index & matchLength are in range. + if (index > length()) + return notFound; + unsigned searchLength = length() - index; + if (matchLength > searchLength) + return notFound; + // delta is the number of additional times to test; delta == 0 means test only once. + unsigned delta = searchLength - matchLength; + + const UChar* searchCharacters = characters() + index; + const UChar* matchCharacters = matchString->characters(); + + // Optimization 2: keep a running hash of the strings, + // only call memcmp if the hashes match. + unsigned searchHash = 0; + unsigned matchHash = 0; + for (unsigned i = 0; i < matchLength; ++i) { + searchHash += searchCharacters[i]; + matchHash += matchCharacters[i]; + } + + unsigned i = 0; + // keep looping until we match + while (searchHash != matchHash || memcmp(searchCharacters + i, matchCharacters, matchLength * sizeof(UChar))) { + if (i == delta) + return notFound; + searchHash += searchCharacters[i + matchLength]; + searchHash -= searchCharacters[i]; + ++i; + } + return index + i; } -int StringImpl::find(StringImpl* str, int index, bool caseSensitive) -{ - /* - We use a simple trick for efficiency's sake. Instead of - comparing strings, we compare the sum of str with that of - a part of this string. Only if that matches, we call memcmp - or ucstrnicmp. - */ - ASSERT(str); - if (index < 0) - index += m_length; - int lstr = str->m_length; - int lthis = m_length - index; - if ((unsigned)lthis > m_length) - return -1; - int delta = lthis - lstr; - if (delta < 0) - return -1; - - const UChar* uthis = m_data + index; - const UChar* ustr = str->m_data; - unsigned hthis = 0; - unsigned hstr = 0; - if (caseSensitive) { - for (int i = 0; i < lstr; i++) { - hthis += uthis[i]; - hstr += ustr[i]; - } - int i = 0; - while (1) { - if (hthis == hstr && memcmp(uthis + i, ustr, lstr * sizeof(UChar)) == 0) - return index + i; - if (i == delta) - return -1; - hthis += uthis[i + lstr]; - hthis -= uthis[i]; - i++; - } - } else { - for (int i = 0; i < lstr; i++ ) { - hthis += toASCIILower(uthis[i]); - hstr += toASCIILower(ustr[i]); - } - int i = 0; - while (1) { - if (hthis == hstr && equalIgnoringCase(uthis + i, ustr, lstr)) - return index + i; - if (i == delta) - return -1; - hthis += toASCIILower(uthis[i + lstr]); - hthis -= toASCIILower(uthis[i]); - i++; - } +size_t StringImpl::findIgnoringCase(StringImpl* matchString, unsigned index) +{ + // Check for null or empty string to match against + if (!matchString) + return notFound; + unsigned matchLength = matchString->length(); + if (!matchLength) + return min(index, length()); + + // Check index & matchLength are in range. + if (index > length()) + return notFound; + unsigned searchLength = length() - index; + if (matchLength > searchLength) + return notFound; + // delta is the number of additional times to test; delta == 0 means test only once. + unsigned delta = searchLength - matchLength; + + const UChar* searchCharacters = characters() + index; + const UChar* matchCharacters = matchString->characters(); + + unsigned i = 0; + // keep looping until we match + while (!equalIgnoringCase(searchCharacters + i, matchCharacters, matchLength)) { + if (i == delta) + return notFound; + ++i; } + return index + i; } -int StringImpl::reverseFind(UChar c, int index) +size_t StringImpl::reverseFind(UChar c, unsigned index) { return WTF::reverseFind(m_data, m_length, c, index); } -int StringImpl::reverseFind(StringImpl* str, int index, bool caseSensitive) +size_t StringImpl::reverseFind(StringImpl* matchString, unsigned index) { - /* - See StringImpl::find() for explanations. - */ - ASSERT(str); - int lthis = m_length; - if (index < 0) - index += lthis; - - int lstr = str->m_length; - int delta = lthis - lstr; - if ( index < 0 || index > lthis || delta < 0 ) - return -1; - if ( index > delta ) - index = delta; - - const UChar *uthis = m_data; - const UChar *ustr = str->m_data; - unsigned hthis = 0; - unsigned hstr = 0; - int i; - if (caseSensitive) { - for ( i = 0; i < lstr; i++ ) { - hthis += uthis[index + i]; - hstr += ustr[i]; - } - i = index; - while (1) { - if (hthis == hstr && memcmp(uthis + i, ustr, lstr * sizeof(UChar)) == 0) - return i; - if (i == 0) - return -1; - i--; - hthis -= uthis[i + lstr]; - hthis += uthis[i]; - } - } else { - for (i = 0; i < lstr; i++) { - hthis += toASCIILower(uthis[index + i]); - hstr += toASCIILower(ustr[i]); - } - i = index; - while (1) { - if (hthis == hstr && equalIgnoringCase(uthis + i, ustr, lstr) ) - return i; - if (i == 0) - return -1; - i--; - hthis -= toASCIILower(uthis[i + lstr]); - hthis += toASCIILower(uthis[i]); - } + // Check for null or empty string to match against + if (!matchString) + return notFound; + unsigned matchLength = matchString->length(); + if (!matchLength) + return min(index, length()); + + // Optimization 1: fast case for strings of length 1. + if (matchLength == 1) + return WTF::reverseFind(characters(), length(), matchString->characters()[0], index); + + // Check index & matchLength are in range. + if (matchLength > length()) + return notFound; + // delta is the number of additional times to test; delta == 0 means test only once. + unsigned delta = min(index, length() - matchLength); + + const UChar *searchCharacters = characters(); + const UChar *matchCharacters = matchString->characters(); + + // Optimization 2: keep a running hash of the strings, + // only call memcmp if the hashes match. + unsigned searchHash = 0; + unsigned matchHash = 0; + for (unsigned i = 0; i < matchLength; ++i) { + searchHash += searchCharacters[delta + i]; + matchHash += matchCharacters[i]; + } + + // keep looping until we match + while (searchHash != matchHash || memcmp(searchCharacters + delta, matchCharacters, matchLength * sizeof(UChar))) { + if (!delta) + return notFound; + delta--; + searchHash -= searchCharacters[delta + matchLength]; + searchHash += searchCharacters[delta]; } + return delta; +} + +size_t StringImpl::reverseFindIgnoringCase(StringImpl* matchString, unsigned index) +{ + // Check for null or empty string to match against + if (!matchString) + return notFound; + unsigned matchLength = matchString->length(); + if (!matchLength) + return min(index, length()); + + // Check index & matchLength are in range. + if (matchLength > length()) + return notFound; + // delta is the number of additional times to test; delta == 0 means test only once. + unsigned delta = min(index, length() - matchLength); - // Should never get here. - return -1; + const UChar *searchCharacters = characters(); + const UChar *matchCharacters = matchString->characters(); + + // keep looping until we match + while (!equalIgnoringCase(searchCharacters + delta, matchCharacters, matchLength)) { + if (!delta) + return notFound; + delta--; + } + return delta; } bool StringImpl::endsWith(StringImpl* m_data, bool caseSensitive) { ASSERT(m_data); - int start = m_length - m_data->m_length; - if (start >= 0) - return (find(m_data, start, caseSensitive) == start); + if (m_length >= m_data->m_length) { + unsigned start = m_length - m_data->m_length; + return (caseSensitive ? find(m_data, start) : findIgnoringCase(m_data, start)) == start; + } return false; } @@ -716,12 +791,12 @@ PassRefPtr<StringImpl> StringImpl::replace(UChar pattern, StringImpl* replacemen if (!replacement) return this; - int repStrLength = replacement->length(); - int srcSegmentStart = 0; - int matchCount = 0; + unsigned repStrLength = replacement->length(); + size_t srcSegmentStart = 0; + unsigned matchCount = 0; // Count the matches - while ((srcSegmentStart = find(pattern, srcSegmentStart)) >= 0) { + while ((srcSegmentStart = find(pattern, srcSegmentStart)) != notFound) { ++matchCount; ++srcSegmentStart; } @@ -735,12 +810,12 @@ PassRefPtr<StringImpl> StringImpl::replace(UChar pattern, StringImpl* replacemen createUninitialized(m_length - matchCount + (matchCount * repStrLength), data); // Construct the new data - int srcSegmentEnd; - int srcSegmentLength; + size_t srcSegmentEnd; + unsigned srcSegmentLength; srcSegmentStart = 0; - int dstOffset = 0; + unsigned dstOffset = 0; - while ((srcSegmentEnd = find(pattern, srcSegmentStart)) >= 0) { + while ((srcSegmentEnd = find(pattern, srcSegmentStart)) != notFound) { srcSegmentLength = srcSegmentEnd - srcSegmentStart; memcpy(data + dstOffset, m_data + srcSegmentStart, srcSegmentLength * sizeof(UChar)); dstOffset += srcSegmentLength; @@ -752,7 +827,7 @@ PassRefPtr<StringImpl> StringImpl::replace(UChar pattern, StringImpl* replacemen srcSegmentLength = m_length - srcSegmentStart; memcpy(data + dstOffset, m_data + srcSegmentStart, srcSegmentLength * sizeof(UChar)); - ASSERT(dstOffset + srcSegmentLength == static_cast<int>(newImpl->length())); + ASSERT(dstOffset + srcSegmentLength == newImpl->length()); return newImpl; } @@ -762,16 +837,16 @@ PassRefPtr<StringImpl> StringImpl::replace(StringImpl* pattern, StringImpl* repl if (!pattern || !replacement) return this; - int patternLength = pattern->length(); + unsigned patternLength = pattern->length(); if (!patternLength) return this; - int repStrLength = replacement->length(); - int srcSegmentStart = 0; - int matchCount = 0; + unsigned repStrLength = replacement->length(); + size_t srcSegmentStart = 0; + unsigned matchCount = 0; // Count the matches - while ((srcSegmentStart = find(pattern, srcSegmentStart)) >= 0) { + while ((srcSegmentStart = find(pattern, srcSegmentStart)) != notFound) { ++matchCount; srcSegmentStart += patternLength; } @@ -785,12 +860,12 @@ PassRefPtr<StringImpl> StringImpl::replace(StringImpl* pattern, StringImpl* repl createUninitialized(m_length + matchCount * (repStrLength - patternLength), data); // Construct the new data - int srcSegmentEnd; - int srcSegmentLength; + size_t srcSegmentEnd; + unsigned srcSegmentLength; srcSegmentStart = 0; - int dstOffset = 0; + unsigned dstOffset = 0; - while ((srcSegmentEnd = find(pattern, srcSegmentStart)) >= 0) { + while ((srcSegmentEnd = find(pattern, srcSegmentStart)) != notFound) { srcSegmentLength = srcSegmentEnd - srcSegmentStart; memcpy(data + dstOffset, m_data + srcSegmentStart, srcSegmentLength * sizeof(UChar)); dstOffset += srcSegmentLength; @@ -802,7 +877,7 @@ PassRefPtr<StringImpl> StringImpl::replace(StringImpl* pattern, StringImpl* repl srcSegmentLength = m_length - srcSegmentStart; memcpy(data + dstOffset, m_data + srcSegmentStart, srcSegmentLength * sizeof(UChar)); - ASSERT(dstOffset + srcSegmentLength == static_cast<int>(newImpl->length())); + ASSERT(dstOffset + srcSegmentLength == newImpl->length()); return newImpl; } @@ -883,20 +958,6 @@ bool equalIgnoringNullity(StringImpl* a, StringImpl* b) return false; } -Vector<char> StringImpl::ascii() -{ - Vector<char> buffer(m_length + 1); - for (unsigned i = 0; i != m_length; ++i) { - UChar c = m_data[i]; - if ((c >= 0x20 && c < 0x7F) || c == 0x00) - buffer[i] = static_cast<char>(c); - else - buffer[i] = '?'; - } - buffer[m_length] = '\0'; - return buffer; -} - WTF::Unicode::Direction StringImpl::defaultWritingDirection() { for (unsigned i = 0; i < m_length; ++i) { diff --git a/JavaScriptCore/wtf/text/StringImpl.h b/JavaScriptCore/wtf/text/StringImpl.h index 6080474..cec0b80 100644 --- a/JavaScriptCore/wtf/text/StringImpl.h +++ b/JavaScriptCore/wtf/text/StringImpl.h @@ -290,15 +290,18 @@ public: PassRefPtr<StringImpl> removeCharacters(CharacterMatchFunctionPtr); - int find(const char*, int index = 0, bool caseSensitive = true); - int find(UChar, int index = 0); - int find(CharacterMatchFunctionPtr, int index = 0); - int find(StringImpl*, int index, bool caseSensitive = true); - - int reverseFind(UChar, int index); - int reverseFind(StringImpl*, int index, bool caseSensitive = true); - - bool startsWith(StringImpl* str, bool caseSensitive = true) { return reverseFind(str, 0, caseSensitive) == 0; } + size_t find(UChar, unsigned index = 0); + size_t find(CharacterMatchFunctionPtr, unsigned index = 0); + size_t find(const char*, unsigned index = 0); + size_t find(StringImpl*, unsigned index = 0); + size_t findIgnoringCase(const char*, unsigned index = 0); + size_t findIgnoringCase(StringImpl*, unsigned index = 0); + + size_t reverseFind(UChar, unsigned index = UINT_MAX); + size_t reverseFind(StringImpl*, unsigned index = UINT_MAX); + size_t reverseFindIgnoringCase(StringImpl*, unsigned index = UINT_MAX); + + bool startsWith(StringImpl* str, bool caseSensitive = true) { return (caseSensitive ? reverseFind(str, 0) : reverseFindIgnoringCase(str, 0)) == 0; } bool endsWith(StringImpl*, bool caseSensitive = true); PassRefPtr<StringImpl> replace(UChar, UChar); @@ -306,8 +309,6 @@ public: PassRefPtr<StringImpl> replace(StringImpl*, StringImpl*); PassRefPtr<StringImpl> replace(unsigned index, unsigned len, StringImpl*); - Vector<char> ascii(); - WTF::Unicode::Direction defaultWritingDirection(); #if PLATFORM(CF) diff --git a/JavaScriptCore/wtf/text/WTFString.cpp b/JavaScriptCore/wtf/text/WTFString.cpp index 6c4de6e..7d44d21 100644 --- a/JavaScriptCore/wtf/text/WTFString.cpp +++ b/JavaScriptCore/wtf/text/WTFString.cpp @@ -36,6 +36,13 @@ namespace WTF { using namespace Unicode; +// Construct a string with UTF-16 data. +String::String(const UChar* characters, unsigned length) + : m_impl(characters ? StringImpl::create(characters, length) : 0) +{ +} + +// Construct a string with UTF-16 data, from a null-terminated source. String::String(const UChar* str) { if (!str) @@ -48,6 +55,18 @@ String::String(const UChar* str) m_impl = StringImpl::create(str, len); } +// Construct a string with latin1 data. +String::String(const char* characters, unsigned length) + : m_impl(characters ? StringImpl::create(characters, length) : 0) +{ +} + +// Construct a string with latin1 data, from a null-terminated source. +String::String(const char* characters) + : m_impl(characters ? StringImpl::create(characters) : 0) +{ +} + void String::append(const String& str) { if (str.isEmpty()) @@ -226,6 +245,19 @@ String String::substring(unsigned pos, unsigned len) const return m_impl->substring(pos, len); } +String String::substringSharingImpl(unsigned offset, unsigned length) const +{ + // FIXME: We used to check against a limit of Heap::minExtraCost / sizeof(UChar). + + unsigned stringLength = this->length(); + offset = min(offset, stringLength); + length = min(length, stringLength - offset); + + if (!offset && length == stringLength) + return *this; + return String(StringImpl::create(m_impl, offset, length)); +} + String String::lower() const { if (!m_impl) @@ -557,14 +589,14 @@ void String::split(const String& separator, bool allowEmptyEntries, Vector<Strin { result.clear(); - int startPos = 0; - int endPos; - while ((endPos = find(separator, startPos)) != -1) { + unsigned startPos = 0; + size_t endPos; + while ((endPos = find(separator, startPos)) != notFound) { if (allowEmptyEntries || startPos != endPos) result.append(substring(startPos, endPos - startPos)); startPos = endPos + separator.length(); } - if (allowEmptyEntries || startPos != static_cast<int>(length())) + if (allowEmptyEntries || startPos != length()) result.append(substring(startPos)); } @@ -577,14 +609,14 @@ void String::split(UChar separator, bool allowEmptyEntries, Vector<String>& resu { result.clear(); - int startPos = 0; - int endPos; - while ((endPos = find(separator, startPos)) != -1) { + unsigned startPos = 0; + size_t endPos; + while ((endPos = find(separator, startPos)) != notFound) { if (allowEmptyEntries || startPos != endPos) result.append(substring(startPos, endPos - startPos)); startPos = endPos + 1; } - if (allowEmptyEntries || startPos != static_cast<int>(length())) + if (allowEmptyEntries || startPos != length()) result.append(substring(startPos)); } @@ -593,18 +625,23 @@ void String::split(UChar separator, Vector<String>& result) const return split(String(&separator, 1), false, result); } -Vector<char> String::ascii() const +CString String::ascii() const { - if (m_impl) - return m_impl->ascii(); - - const char* nullMsg = "(null impl)"; - Vector<char, 2048> buffer; - for (int i = 0; nullMsg[i]; ++i) - buffer.append(nullMsg[i]); - - buffer.append('\0'); - return buffer; + // Basic Latin1 (ISO) encoding - Unicode characters 0..255 are + // preserved, characters outside of this range are converted to '?'. + + unsigned length = this->length(); + const UChar* characters = this->characters(); + + char* characterBuffer; + CString result = CString::newUninitialized(length, characterBuffer); + + for (unsigned i = 0; i < length; ++i) { + UChar ch = characters[i]; + characterBuffer[i] = ch && (ch < 0x20 || ch > 0x7f) ? '?' : ch; + } + + return result; } CString String::latin1() const @@ -620,7 +657,7 @@ CString String::latin1() const for (unsigned i = 0; i < length; ++i) { UChar ch = characters[i]; - characterBuffer[i] = ch > 255 ? '?' : ch; + characterBuffer[i] = ch > 0xff ? '?' : ch; } return result; @@ -635,7 +672,7 @@ static inline void putUTF8Triple(char*& buffer, UChar ch) *buffer++ = static_cast<char>((ch & 0x3F) | 0x80); } -CString String::utf8() const +CString String::utf8(bool strict) const { unsigned length = this->length(); const UChar* characters = this->characters(); @@ -653,15 +690,21 @@ CString String::utf8() const Vector<char, 1024> bufferVector(length * 3); char* buffer = bufferVector.data(); - ConversionResult result = convertUTF16ToUTF8(&characters, characters + length, &buffer, buffer + bufferVector.size(), false); - ASSERT(result != sourceIllegal); // Only produced from strict conversion. + ConversionResult result = convertUTF16ToUTF8(&characters, characters + length, &buffer, buffer + bufferVector.size(), strict); ASSERT(result != targetExhausted); // (length * 3) should be sufficient for any conversion - // If a high surrogate is left unconverted, treat it the same was as an unpaired high surrogate - // would have been handled in the middle of a string with non-strict conversion - which is to say, - // simply encode it to UTF-8. + // Only produced from strict conversion. + if (result == sourceIllegal) + return CString(); + + // Check for an unconverted high surrogate. if (result == sourceExhausted) { - // This should be one unpaired high surrogate. + if (strict) + return CString(); + // This should be one unpaired high surrogate. Treat it the same + // was as an unpaired high surrogate would have been handled in + // the middle of a string with non-strict conversion - which is + // to say, simply encode it to UTF-8. ASSERT((characters + 1) == (this->characters() + length)); ASSERT((*characters >= 0xD800) && (*characters <= 0xDBFF)); // There should be room left, since one UChar hasn't been converted. diff --git a/JavaScriptCore/wtf/text/WTFString.h b/JavaScriptCore/wtf/text/WTFString.h index 6af519c..fafef12 100644 --- a/JavaScriptCore/wtf/text/WTFString.h +++ b/JavaScriptCore/wtf/text/WTFString.h @@ -1,6 +1,6 @@ /* * (C) 1999 Lars Knoll (knoll@kde.org) - * Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved. + * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010 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 @@ -72,45 +72,43 @@ intptr_t charactersToIntPtr(const UChar*, size_t, bool* ok = 0); // ignores trai double charactersToDouble(const UChar*, size_t, bool* ok = 0); float charactersToFloat(const UChar*, size_t, bool* ok = 0); -int find(const UChar*, size_t, UChar, int startPosition = 0); -int reverseFind(const UChar*, size_t, UChar, int startPosition = -1); - class String { public: - String() { } // gives null string, distinguishable from an empty string - String(const UChar* str, unsigned len) - { - if (!str) - return; - m_impl = StringImpl::create(str, len); - } - String(const char* str) - { - if (!str) - return; - m_impl = StringImpl::create(str); - } - String(const char* str, unsigned length) - { - if (!str) - return; - m_impl = StringImpl::create(str, length); - } - String(const UChar*); // Specifically for null terminated UTF-16 - String(StringImpl* i) : m_impl(i) { } - String(PassRefPtr<StringImpl> i) : m_impl(i) { } - String(RefPtr<StringImpl> i) : m_impl(i) { } + // Construct a null string, distinguishable from an empty string. + String() { } - void swap(String& o) { m_impl.swap(o.m_impl); } + // Construct a string with UTF-16 data. + String(const UChar* characters, unsigned length); - // Hash table deleted values, which are only constructed and never copied or destroyed. - String(WTF::HashTableDeletedValueType) : m_impl(WTF::HashTableDeletedValue) { } - bool isHashTableDeletedValue() const { return m_impl.isHashTableDeletedValue(); } + // Construct a string with UTF-16 data, from a null-terminated source. + String(const UChar*); + + // Construct a string with latin1 data. + String(const char* characters, unsigned length); + + // Construct a string with latin1 data, from a null-terminated source. + String(const char* characters); + + // Construct a string referencing an existing StringImpl. + String(StringImpl* impl) : m_impl(impl) { } + String(PassRefPtr<StringImpl> impl) : m_impl(impl) { } + String(RefPtr<StringImpl> impl) : m_impl(impl) { } + + // Inline the destructor. + ALWAYS_INLINE ~String() { } + + void swap(String& o) { m_impl.swap(o.m_impl); } static String adopt(StringBuffer& buffer) { return StringImpl::adopt(buffer); } - static String adopt(Vector<UChar>& vector) { return StringImpl::adopt(vector); } + template<size_t inlineCapacity> + static String adopt(Vector<UChar, inlineCapacity>& vector) { return StringImpl::adopt(vector); } - ALWAYS_INLINE unsigned length() const + bool isNull() const { return !m_impl; } + bool isEmpty() const { return !m_impl || !m_impl->length(); } + + StringImpl* impl() const { return m_impl.get(); } + + unsigned length() const { if (!m_impl) return 0; @@ -124,34 +122,67 @@ public: return m_impl->characters(); } - const UChar* charactersWithNullTermination(); - - UChar operator[](unsigned i) const // if i >= length(), returns 0 + CString ascii() const; + CString latin1() const; + CString utf8(bool strict = false) const; + + UChar operator[](unsigned index) const { - if (!m_impl || i >= m_impl->length()) + if (!m_impl || index >= m_impl->length()) return 0; - return m_impl->characters()[i]; + return m_impl->characters()[index]; } - UChar32 characterStartingAt(unsigned) const; // Ditto. + + static String number(short); + static String number(unsigned short); + static String number(int); + static String number(unsigned); + static String number(long); + static String number(unsigned long); + static String number(long long); + static String number(unsigned long long); + static String number(double); + + // Find a single character or string, also with match function & latin1 forms. + size_t find(UChar c, unsigned start = 0) const + { return m_impl ? m_impl->find(c, start) : notFound; } + size_t find(const String& str, unsigned start = 0) const + { return m_impl ? m_impl->find(str.impl(), start) : notFound; } + size_t find(CharacterMatchFunctionPtr matchFunction, unsigned start = 0) const + { return m_impl ? m_impl->find(matchFunction, start) : notFound; } + size_t find(const char* str, unsigned start = 0) const + { return m_impl ? m_impl->find(str, start) : notFound; } + + // Find the last instance of a single character or string. + size_t reverseFind(UChar c, unsigned start = UINT_MAX) const + { return m_impl ? m_impl->reverseFind(c, start) : notFound; } + size_t reverseFind(const String& str, unsigned start = UINT_MAX) const + { return m_impl ? m_impl->reverseFind(str.impl(), start) : notFound; } + + // Case insensitive string matching. + size_t findIgnoringCase(const char* str, unsigned start = 0) const + { return m_impl ? m_impl->findIgnoringCase(str, start) : notFound; } + size_t findIgnoringCase(const String& str, unsigned start = 0) const + { return m_impl ? m_impl->findIgnoringCase(str.impl(), start) : notFound; } + size_t reverseFindIgnoringCase(const String& str, unsigned start = UINT_MAX) const + { return m_impl ? m_impl->reverseFindIgnoringCase(str.impl(), start) : notFound; } + + // Wrappers for find & reverseFind adding dynamic sensitivity check. + size_t find(const char* str, unsigned start, bool caseSensitive) const + { return caseSensitive ? find(str, start) : findIgnoringCase(str, start); } + size_t find(const String& str, unsigned start, bool caseSensitive) const + { return caseSensitive ? find(str, start) : findIgnoringCase(str, start); } + size_t reverseFind(const String& str, unsigned start, bool caseSensitive) const + { return caseSensitive ? reverseFind(str, start) : reverseFindIgnoringCase(str, start); } + + const UChar* charactersWithNullTermination(); - bool contains(UChar c) const { return find(c) != -1; } - bool contains(const char* str, bool caseSensitive = true) const { return find(str, 0, caseSensitive) != -1; } - bool contains(const String& str, bool caseSensitive = true) const { return find(str, 0, caseSensitive) != -1; } - - int find(UChar c, int start = 0) const - { return m_impl ? m_impl->find(c, start) : -1; } - int find(CharacterMatchFunctionPtr matchFunction, int start = 0) const - { return m_impl ? m_impl->find(matchFunction, start) : -1; } - int find(const char* str, int start = 0, bool caseSensitive = true) const - { return m_impl ? m_impl->find(str, start, caseSensitive) : -1; } - int find(const String& str, int start = 0, bool caseSensitive = true) const - { return m_impl ? m_impl->find(str.impl(), start, caseSensitive) : -1; } - - int reverseFind(UChar c, int start = -1) const - { return m_impl ? m_impl->reverseFind(c, start) : -1; } - int reverseFind(const String& str, int start = -1, bool caseSensitive = true) const - { return m_impl ? m_impl->reverseFind(str.impl(), start, caseSensitive) : -1; } + UChar32 characterStartingAt(unsigned) const; // Ditto. + bool contains(UChar c) const { return find(c) != notFound; } + bool contains(const char* str, bool caseSensitive = true) const { return find(str, 0, caseSensitive) != notFound; } + bool contains(const String& str, bool caseSensitive = true) const { return find(str, 0, caseSensitive) != notFound; } + bool startsWith(const String& s, bool caseSensitive = true) const { return m_impl ? m_impl->startsWith(s.impl(), caseSensitive) : s.isEmpty(); } bool endsWith(const String& s, bool caseSensitive = true) const @@ -177,6 +208,7 @@ public: void remove(unsigned pos, int len = 1); String substring(unsigned pos, unsigned len = UINT_MAX) const; + String substringSharingImpl(unsigned pos, unsigned len = UINT_MAX) const; String left(unsigned len) const { return substring(0, len); } String right(unsigned len) const { return substring(length() - len, len); } @@ -192,17 +224,11 @@ public: // Return the string with case folded for case insensitive comparison. String foldCase() const; - static String number(short); - static String number(unsigned short); - static String number(int); - static String number(unsigned); - static String number(long); - static String number(unsigned long); - static String number(long long); - static String number(unsigned long long); - static String number(double); - +#if !PLATFORM(QT) static String format(const char *, ...) WTF_ATTRIBUTE_PRINTF(1, 2); +#else + static String format(const char *, ...); +#endif // Returns an uninitialized string. The characters needs to be written // into the buffer returned in data before the returned string is used. @@ -238,11 +264,6 @@ public: // to ever prefer copy() over plain old assignment. String threadsafeCopy() const; - bool isNull() const { return !m_impl; } - ALWAYS_INLINE bool isEmpty() const { return !m_impl || !m_impl->length(); } - - StringImpl* impl() const { return m_impl.get(); } - #if PLATFORM(CF) String(CFStringRef); CFStringRef createCFString() const; @@ -272,11 +293,6 @@ public: operator BString() const; #endif - Vector<char> ascii() const; - - CString latin1() const; - CString utf8() const; - static String fromUTF8(const char*, size_t); static String fromUTF8(const char*); @@ -288,6 +304,10 @@ public: bool containsOnlyASCII() const { return charactersAreAllASCII(characters(), length()); } + // Hash table deleted values, which are only constructed and never copied or destroyed. + String(WTF::HashTableDeletedValueType) : m_impl(WTF::HashTableDeletedValue) { } + bool isHashTableDeletedValue() const { return m_impl.isHashTableDeletedValue(); } + private: RefPtr<StringImpl> m_impl; }; @@ -345,43 +365,37 @@ inline bool charactersAreAllASCII(const UChar* characters, size_t length) int codePointCompare(const String&, const String&); -inline int find(const UChar* characters, size_t length, UChar character, int startPosition) +inline size_t find(const UChar* characters, unsigned length, UChar matchCharacter, unsigned index = 0) { - if (startPosition >= static_cast<int>(length)) - return -1; - for (size_t i = startPosition; i < length; ++i) { - if (characters[i] == character) - return static_cast<int>(i); + while (index < length) { + if (characters[index] == matchCharacter) + return index; + ++index; } - return -1; + return notFound; } -inline int find(const UChar* characters, size_t length, CharacterMatchFunctionPtr matchFunction, int startPosition) +inline size_t find(const UChar* characters, unsigned length, CharacterMatchFunctionPtr matchFunction, unsigned index = 0) { - if (startPosition >= static_cast<int>(length)) - return -1; - for (size_t i = startPosition; i < length; ++i) { - if (matchFunction(characters[i])) - return static_cast<int>(i); + while (index < length) { + if (matchFunction(characters[index])) + return index; + ++index; } - return -1; + return notFound; } -inline int reverseFind(const UChar* characters, size_t length, UChar character, int startPosition) +inline size_t reverseFind(const UChar* characters, unsigned length, UChar matchCharacter, unsigned index = UINT_MAX) { - if (startPosition >= static_cast<int>(length) || !length) - return -1; - if (startPosition < 0) - startPosition += static_cast<int>(length); - while (true) { - if (characters[startPosition] == character) - return startPosition; - if (!startPosition) - return -1; - startPosition--; + if (!length) + return notFound; + if (index >= length) + index = length - 1; + while (characters[index] != matchCharacter) { + if (!index--) + return notFound; } - ASSERT_NOT_REACHED(); - return -1; + return index; } inline void append(Vector<UChar>& vector, const String& string) @@ -417,6 +431,11 @@ template<> struct DefaultHash<String> { typedef StringHash Hash; }; +template <> struct VectorTraits<String> : SimpleClassVectorTraits +{ + static const bool canInitializeWithMemset = true; +}; + } using WTF::CString; @@ -433,6 +452,5 @@ using WTF::charactersAreAllASCII; using WTF::charactersToInt; using WTF::charactersToFloat; using WTF::charactersToDouble; -using WTF::operator+; #endif diff --git a/JavaScriptCore/yarr/RegexJIT.cpp b/JavaScriptCore/yarr/RegexJIT.cpp index 5a53ced..4c21547 100644 --- a/JavaScriptCore/yarr/RegexJIT.cpp +++ b/JavaScriptCore/yarr/RegexJIT.cpp @@ -1416,6 +1416,9 @@ class RegexGenerator : private MacroAssembler { push(ARMRegisters::r4); push(ARMRegisters::r5); push(ARMRegisters::r6); +#if CPU(ARM_TRADITIONAL) + push(ARMRegisters::r8); // scratch register +#endif move(ARMRegisters::r3, output); #elif CPU(MIPS) // Do nothing. @@ -1433,6 +1436,9 @@ class RegexGenerator : private MacroAssembler { pop(X86Registers::ebx); pop(X86Registers::ebp); #elif CPU(ARM) +#if CPU(ARM_TRADITIONAL) + pop(ARMRegisters::r8); // scratch register +#endif pop(ARMRegisters::r6); pop(ARMRegisters::r5); pop(ARMRegisters::r4); @@ -1511,7 +1517,7 @@ void jitCompileRegex(JSGlobalData* globalData, RegexCodeBlock& jitObject, const JSRegExpIgnoreCaseOption ignoreCaseOption = ignoreCase ? JSRegExpIgnoreCase : JSRegExpDoNotIgnoreCase; JSRegExpMultilineOption multilineOption = multiline ? JSRegExpMultiline : JSRegExpSingleLine; - jitObject.setFallback(jsRegExpCompile(reinterpret_cast<const UChar*>(patternString.data()), patternString.size(), ignoreCaseOption, multilineOption, &numSubpatterns, &error)); + jitObject.setFallback(jsRegExpCompile(reinterpret_cast<const UChar*>(patternString.characters()), patternString.length(), ignoreCaseOption, multilineOption, &numSubpatterns, &error)); } }} diff --git a/JavaScriptCore/yarr/RegexParser.h b/JavaScriptCore/yarr/RegexParser.h index c946c2e..8a5eeba 100644 --- a/JavaScriptCore/yarr/RegexParser.h +++ b/JavaScriptCore/yarr/RegexParser.h @@ -193,8 +193,8 @@ private: : m_delegate(delegate) , m_backReferenceLimit(backReferenceLimit) , m_err(NoError) - , m_data(pattern.data()) - , m_size(pattern.size()) + , m_data(pattern.characters()) + , m_size(pattern.length()) , m_index(0) , m_parenthesesNestingDepth(0) { |