1324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/* 2324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * Copyright (C) 2006, 2007 Apple Inc. All rights reserved. 3324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * 4324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * Redistribution and use in source and binary forms, with or without 5324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * modification, are permitted provided that the following conditions 6324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * are met: 7324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * 1. Redistributions of source code must retain the above copyright 8324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * notice, this list of conditions and the following disclaimer. 9324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * 2. Redistributions in binary form must reproduce the above copyright 10324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * notice, this list of conditions and the following disclaimer in the 11324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * documentation and/or other materials provided with the distribution. 12324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * 13324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY 14324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 16324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR 17324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 18324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 19324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 20324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 21324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 23324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 25324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 26324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#include "config.h" 27324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#include "JSClassRef.h" 28324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 29324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#include "APICast.h" 30324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#include "JSCallbackObject.h" 31324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#include "JSObjectRef.h" 32324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#include <runtime/InitializeThreading.h> 33324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#include <runtime/JSGlobalObject.h> 34324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#include <runtime/ObjectPrototype.h> 35324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#include <runtime/Identifier.h> 36324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#include <wtf/text/StringHash.h> 37324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#include <wtf/unicode/UTF8.h> 38324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 39324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverusing namespace std; 40324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverusing namespace JSC; 41324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverusing namespace WTF::Unicode; 42324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 43324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverconst JSClassDefinition kJSClassDefinitionEmpty = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; 44324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 45324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverstatic inline UString tryCreateStringFromUTF8(const char* string) 46324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver{ 47324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (!string) 48324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return UString(); 49324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 50324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver size_t length = strlen(string); 51324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver Vector<UChar, 1024> buffer(length); 52324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver UChar* p = buffer.data(); 53324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (conversionOK != convertUTF8ToUTF16(&string, string + length, &p, p + length)) 54324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return UString(); 55324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 56324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return UString(buffer.data(), p - buffer.data()); 57324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver} 58324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 59324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverOpaqueJSClass::OpaqueJSClass(const JSClassDefinition* definition, OpaqueJSClass* protoClass) 60324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver : parentClass(definition->parentClass) 61324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver , prototypeClass(0) 62324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver , initialize(definition->initialize) 63324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver , finalize(definition->finalize) 64324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver , hasProperty(definition->hasProperty) 65324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver , getProperty(definition->getProperty) 66324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver , setProperty(definition->setProperty) 67324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver , deleteProperty(definition->deleteProperty) 68324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver , getPropertyNames(definition->getPropertyNames) 69324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver , callAsFunction(definition->callAsFunction) 70324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver , callAsConstructor(definition->callAsConstructor) 71324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver , hasInstance(definition->hasInstance) 72324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver , convertToType(definition->convertToType) 73324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver , m_className(tryCreateStringFromUTF8(definition->className)) 74324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver , m_staticValues(0) 75324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver , m_staticFunctions(0) 76324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver{ 77324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver initializeThreading(); 78324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 79324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (const JSStaticValue* staticValue = definition->staticValues) { 80324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver m_staticValues = new OpaqueJSClassStaticValuesTable(); 81324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver while (staticValue->name) { 82324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver UString valueName = tryCreateStringFromUTF8(staticValue->name); 83324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (!valueName.isNull()) { 84324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // Use a local variable here to sidestep an RVCT compiler bug. 85324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver StaticValueEntry* entry = new StaticValueEntry(staticValue->getProperty, staticValue->setProperty, staticValue->attributes); 86324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver StringImpl* impl = valueName.impl(); 87324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver StaticValueEntry* existingEntry = m_staticValues->get(impl); 88324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver m_staticValues->set(impl, entry); 89324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver delete existingEntry; 90324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 91324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver ++staticValue; 92324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 93324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 94324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 95324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (const JSStaticFunction* staticFunction = definition->staticFunctions) { 96324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver m_staticFunctions = new OpaqueJSClassStaticFunctionsTable(); 97324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver while (staticFunction->name) { 98324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver UString functionName = tryCreateStringFromUTF8(staticFunction->name); 99324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (!functionName.isNull()) { 100324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // Use a local variable here to sidestep an RVCT compiler bug. 101324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver StaticFunctionEntry* entry = new StaticFunctionEntry(staticFunction->callAsFunction, staticFunction->attributes); 102324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver StringImpl* impl = functionName.impl(); 103324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver StaticFunctionEntry* existingEntry = m_staticFunctions->get(impl); 104324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver m_staticFunctions->set(impl, entry); 105324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver delete existingEntry; 106324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 107324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver ++staticFunction; 108324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 109324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 110324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 111324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (protoClass) 112324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver prototypeClass = JSClassRetain(protoClass); 113324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver} 114324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 115324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverOpaqueJSClass::~OpaqueJSClass() 116324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver{ 117324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // The empty string is shared across threads & is an identifier, in all other cases we should have done a deep copy in className(), below. 118324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver ASSERT(!m_className.length() || !m_className.impl()->isIdentifier()); 119324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 120324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (m_staticValues) { 121324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver OpaqueJSClassStaticValuesTable::const_iterator end = m_staticValues->end(); 122324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver for (OpaqueJSClassStaticValuesTable::const_iterator it = m_staticValues->begin(); it != end; ++it) { 123324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver ASSERT(!it->first->isIdentifier()); 124324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver delete it->second; 125324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 126324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver delete m_staticValues; 127324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 128324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 129324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (m_staticFunctions) { 130324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver OpaqueJSClassStaticFunctionsTable::const_iterator end = m_staticFunctions->end(); 131324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver for (OpaqueJSClassStaticFunctionsTable::const_iterator it = m_staticFunctions->begin(); it != end; ++it) { 132324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver ASSERT(!it->first->isIdentifier()); 133324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver delete it->second; 134324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 135324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver delete m_staticFunctions; 136324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 137324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 138324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (prototypeClass) 139324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver JSClassRelease(prototypeClass); 140324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver} 141324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 142324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverPassRefPtr<OpaqueJSClass> OpaqueJSClass::createNoAutomaticPrototype(const JSClassDefinition* definition) 143324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver{ 144324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return adoptRef(new OpaqueJSClass(definition, 0)); 145324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver} 146324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 147324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverPassRefPtr<OpaqueJSClass> OpaqueJSClass::create(const JSClassDefinition* clientDefinition) 148324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver{ 149324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver JSClassDefinition definition = *clientDefinition; // Avoid modifying client copy. 150324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 151324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver JSClassDefinition protoDefinition = kJSClassDefinitionEmpty; 152324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver protoDefinition.finalize = 0; 153324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver swap(definition.staticFunctions, protoDefinition.staticFunctions); // Move static functions to the prototype. 154324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 155324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // We are supposed to use JSClassRetain/Release but since we know that we currently have 156324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // the only reference to this class object we cheat and use a RefPtr instead. 157324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver RefPtr<OpaqueJSClass> protoClass = adoptRef(new OpaqueJSClass(&protoDefinition, 0)); 158324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return adoptRef(new OpaqueJSClass(&definition, protoClass.get())); 159324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver} 160324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 161324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverOpaqueJSClassContextData::OpaqueJSClassContextData(JSC::JSGlobalData&, OpaqueJSClass* jsClass) 162324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver : m_class(jsClass) 163324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver{ 164324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (jsClass->m_staticValues) { 165324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver staticValues = new OpaqueJSClassStaticValuesTable; 166324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver OpaqueJSClassStaticValuesTable::const_iterator end = jsClass->m_staticValues->end(); 167324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver for (OpaqueJSClassStaticValuesTable::const_iterator it = jsClass->m_staticValues->begin(); it != end; ++it) { 168324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver ASSERT(!it->first->isIdentifier()); 169324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // Use a local variable here to sidestep an RVCT compiler bug. 170324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver StaticValueEntry* entry = new StaticValueEntry(it->second->getProperty, it->second->setProperty, it->second->attributes); 171324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver staticValues->add(StringImpl::create(it->first->characters(), it->first->length()), entry); 172324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 173324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } else 174324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver staticValues = 0; 175324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 176324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (jsClass->m_staticFunctions) { 177324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver staticFunctions = new OpaqueJSClassStaticFunctionsTable; 178324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver OpaqueJSClassStaticFunctionsTable::const_iterator end = jsClass->m_staticFunctions->end(); 179324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver for (OpaqueJSClassStaticFunctionsTable::const_iterator it = jsClass->m_staticFunctions->begin(); it != end; ++it) { 180324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver ASSERT(!it->first->isIdentifier()); 181324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // Use a local variable here to sidestep an RVCT compiler bug. 182324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver StaticFunctionEntry* entry = new StaticFunctionEntry(it->second->callAsFunction, it->second->attributes); 183324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver staticFunctions->add(StringImpl::create(it->first->characters(), it->first->length()), entry); 184324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 185324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 186324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } else 187324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver staticFunctions = 0; 188324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver} 189324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 190324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverOpaqueJSClassContextData::~OpaqueJSClassContextData() 191324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver{ 192324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (staticValues) { 193324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver deleteAllValues(*staticValues); 194324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver delete staticValues; 195324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 196324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 197324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (staticFunctions) { 198324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver deleteAllValues(*staticFunctions); 199324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver delete staticFunctions; 200324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 201324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver} 202324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 203324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverOpaqueJSClassContextData& OpaqueJSClass::contextData(ExecState* exec) 204324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver{ 205324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver OpaqueJSClassContextData*& contextData = exec->globalData().opaqueJSClassData.add(this, 0).first->second; 206324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (!contextData) 207324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver contextData = new OpaqueJSClassContextData(exec->globalData(), this); 208324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return *contextData; 209324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver} 210324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 211324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverUString OpaqueJSClass::className() 212324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver{ 213324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // Make a deep copy, so that the caller has no chance to put the original into IdentifierTable. 214324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return UString(m_className.characters(), m_className.length()); 215324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver} 216324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 217324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverOpaqueJSClassStaticValuesTable* OpaqueJSClass::staticValues(JSC::ExecState* exec) 218324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver{ 219324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver OpaqueJSClassContextData& jsClassData = contextData(exec); 220324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return jsClassData.staticValues; 221324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver} 222324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 223324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverOpaqueJSClassStaticFunctionsTable* OpaqueJSClass::staticFunctions(JSC::ExecState* exec) 224324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver{ 225324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver OpaqueJSClassContextData& jsClassData = contextData(exec); 226324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return jsClassData.staticFunctions; 227324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver} 228324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 229324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/*! 230324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver// Doc here in case we make this public. (Hopefully we won't.) 231324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver@function 232324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @abstract Returns the prototype that will be used when constructing an object with a given class. 233324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @param ctx The execution context to use. 234324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @param jsClass A JSClass whose prototype you want to get. 235324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @result The JSObject prototype that was automatically generated for jsClass, or NULL if no prototype was automatically generated. This is the prototype that will be used when constructing an object using jsClass. 236324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver*/ 237324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverJSObject* OpaqueJSClass::prototype(ExecState* exec) 238324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver{ 239324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /* Class (C++) and prototype (JS) inheritance are parallel, so: 240324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * (C++) | (JS) 241324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * ParentClass | ParentClassPrototype 242324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * ^ | ^ 243324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * | | | 244324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * DerivedClass | DerivedClassPrototype 245324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 246324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 247324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (!prototypeClass) 248324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return 0; 249324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 250324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver OpaqueJSClassContextData& jsClassData = contextData(exec); 251324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 252324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (!jsClassData.cachedPrototype) { 253324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // Recursive, but should be good enough for our purposes 254324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver jsClassData.cachedPrototype.set(exec->globalData(), new (exec) JSCallbackObject<JSObjectWithGlobalObject>(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 255324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (parentClass) { 256324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (JSObject* prototype = parentClass->prototype(exec)) 257324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver jsClassData.cachedPrototype->setPrototype(exec->globalData(), prototype); 258324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 259324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 260324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return jsClassData.cachedPrototype.get(); 261324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver} 262324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver