X-Git-Url: https://git.saurik.com/apple/javascriptcore.git/blobdiff_plain/4e4e5a6f2694187498445a6ac6f1634ce8141119..6fe7ccc865dc7d7541b93c5bcaf6368d2c98a174:/API/JSClassRef.cpp?ds=sidebyside diff --git a/API/JSClassRef.cpp b/API/JSClassRef.cpp index 3e65b75..08fa5c5 100644 --- a/API/JSClassRef.cpp +++ b/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 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()); } @@ -71,37 +71,25 @@ OpaqueJSClass::OpaqueJSClass(const JSClassDefinition* definition, OpaqueJSClass* , hasInstance(definition->hasInstance) , convertToType(definition->convertToType) , m_className(tryCreateStringFromUTF8(definition->className)) - , m_staticValues(0) - , m_staticFunctions(0) { initializeThreading(); if (const JSStaticValue* staticValue = definition->staticValues) { - m_staticValues = new OpaqueJSClassStaticValuesTable(); + m_staticValues = adoptPtr(new OpaqueJSClassStaticValuesTable); while (staticValue->name) { UString valueName = tryCreateStringFromUTF8(staticValue->name); - 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(); - impl->ref(); - m_staticValues->add(impl, entry); - } + if (!valueName.isNull()) + m_staticValues->set(valueName.impl(), adoptPtr(new StaticValueEntry(staticValue->getProperty, staticValue->setProperty, staticValue->attributes))); ++staticValue; } } if (const JSStaticFunction* staticFunction = definition->staticFunctions) { - m_staticFunctions = new OpaqueJSClassStaticFunctionsTable(); + m_staticFunctions = adoptPtr(new OpaqueJSClassStaticFunctionsTable); while (staticFunction->name) { UString functionName = tryCreateStringFromUTF8(staticFunction->name); - 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(); - impl->ref(); - m_staticFunctions->add(impl, entry); - } + if (!functionName.isNull()) + m_staticFunctions->set(functionName.impl(), adoptPtr(new StaticFunctionEntry(staticFunction->callAsFunction, staticFunction->attributes))); ++staticFunction; } } @@ -113,25 +101,21 @@ 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()); +#ifndef NDEBUG if (m_staticValues) { OpaqueJSClassStaticValuesTable::const_iterator end = m_staticValues->end(); - for (OpaqueJSClassStaticValuesTable::const_iterator it = m_staticValues->begin(); it != end; ++it) { + for (OpaqueJSClassStaticValuesTable::const_iterator it = m_staticValues->begin(); it != end; ++it) ASSERT(!it->first->isIdentifier()); - delete it->second; - } - delete m_staticValues; } if (m_staticFunctions) { OpaqueJSClassStaticFunctionsTable::const_iterator end = m_staticFunctions->end(); - for (OpaqueJSClassStaticFunctionsTable::const_iterator it = m_staticFunctions->begin(); it != end; ++it) { + for (OpaqueJSClassStaticFunctionsTable::const_iterator it = m_staticFunctions->begin(); it != end; ++it) ASSERT(!it->first->isIdentifier()); - delete it->second; - } - delete m_staticFunctions; } +#endif if (prototypeClass) JSClassRelease(prototypeClass); @@ -142,19 +126,12 @@ PassRefPtr OpaqueJSClass::createNoAutomaticPrototype(const JSClas return adoptRef(new OpaqueJSClass(definition, 0)); } -static void clearReferenceToPrototype(JSObjectRef prototype) -{ - OpaqueJSClassContextData* jsClassData = static_cast(JSObjectGetPrivate(prototype)); - ASSERT(jsClassData); - jsClassData->cachedPrototype.clear(toJS(prototype)); -} - PassRefPtr OpaqueJSClass::create(const JSClassDefinition* clientDefinition) { JSClassDefinition definition = *clientDefinition; // Avoid modifying client copy. JSClassDefinition protoDefinition = kJSClassDefinitionEmpty; - protoDefinition.finalize = clearReferenceToPrototype; + protoDefinition.finalize = 0; swap(definition.staticFunctions, protoDefinition.staticFunctions); // Move static functions to the prototype. // We are supposed to use JSClassRetain/Release but since we know that we currently have @@ -163,72 +140,50 @@ PassRefPtr OpaqueJSClass::create(const JSClassDefinition* clientD return adoptRef(new OpaqueJSClass(&definition, protoClass.get())); } -OpaqueJSClassContextData::OpaqueJSClassContextData(OpaqueJSClass* jsClass) +OpaqueJSClassContextData::OpaqueJSClassContextData(JSC::JSGlobalData&, OpaqueJSClass* jsClass) : m_class(jsClass) { if (jsClass->m_staticValues) { - staticValues = new OpaqueJSClassStaticValuesTable; + staticValues = adoptPtr(new OpaqueJSClassStaticValuesTable); OpaqueJSClassStaticValuesTable::const_iterator end = jsClass->m_staticValues->end(); for (OpaqueJSClassStaticValuesTable::const_iterator it = jsClass->m_staticValues->begin(); it != end; ++it) { 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()), adoptPtr(new StaticValueEntry(it->second->getProperty, it->second->setProperty, it->second->attributes))); } - } else - staticValues = 0; + } if (jsClass->m_staticFunctions) { - staticFunctions = new OpaqueJSClassStaticFunctionsTable; + staticFunctions = adoptPtr(new OpaqueJSClassStaticFunctionsTable); OpaqueJSClassStaticFunctionsTable::const_iterator end = jsClass->m_staticFunctions->end(); for (OpaqueJSClassStaticFunctionsTable::const_iterator it = jsClass->m_staticFunctions->begin(); it != end; ++it) { 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()), adoptPtr(new StaticFunctionEntry(it->second->callAsFunction, it->second->attributes))); } - - } else - staticFunctions = 0; -} - -OpaqueJSClassContextData::~OpaqueJSClassContextData() -{ - if (staticValues) { - deleteAllValues(*staticValues); - delete staticValues; - } - - if (staticFunctions) { - deleteAllValues(*staticFunctions); - delete staticFunctions; } } OpaqueJSClassContextData& OpaqueJSClass::contextData(ExecState* exec) { - OpaqueJSClassContextData*& contextData = exec->globalData().opaqueJSClassData.add(this, 0).first->second; + OwnPtr& contextData = exec->globalData().opaqueJSClassData.add(this, nullptr).iterator->second; if (!contextData) - contextData = new OpaqueJSClassContextData(this); + contextData = adoptPtr(new OpaqueJSClassContextData(exec->globalData(), this)); return *contextData; } 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) { - OpaqueJSClassContextData& jsClassData = contextData(exec); - return jsClassData.staticValues; + return contextData(exec).staticValues.get(); } OpaqueJSClassStaticFunctionsTable* OpaqueJSClass::staticFunctions(JSC::ExecState* exec) { - OpaqueJSClassContextData& jsClassData = contextData(exec); - return jsClassData.staticFunctions; + return contextData(exec).staticFunctions.get(); } /*! @@ -248,7 +203,7 @@ JSObject* OpaqueJSClass::prototype(ExecState* exec) * | | | * DerivedClass | DerivedClassPrototype */ - + if (!prototypeClass) return 0; @@ -256,10 +211,10 @@ JSObject* OpaqueJSClass::prototype(ExecState* exec) if (!jsClassData.cachedPrototype) { // Recursive, but should be good enough for our purposes - jsClassData.cachedPrototype = new (exec) JSCallbackObject(exec, exec->lexicalGlobalObject()->callbackObjectStructure(), prototypeClass, &jsClassData); // set jsClassData as the object's private data, so it can clear our reference on destruction + jsClassData.cachedPrototype = PassWeak(JSCallbackObject::create(exec, exec->lexicalGlobalObject(), exec->lexicalGlobalObject()->callbackObjectStructure(), prototypeClass, &jsClassData), 0); // set jsClassData as the object's private data, so it can clear our reference on destruction if (parentClass) { if (JSObject* prototype = parentClass->prototype(exec)) - jsClassData.cachedPrototype->setPrototype(prototype); + jsClassData.cachedPrototype->setPrototype(exec->globalData(), prototype); } } return jsClassData.cachedPrototype.get();