Ignore:
Timestamp:
Jul 1, 2006, 9:06:07 PM (19 years ago)
Author:
ggaren
Message:

Reviewed by Maciej.


  • Phase 2 in the JS API.


  • Added support for specifying static tables of values -- this should obviate the need for using complicated callbacks for most lookups.


  • API objects are now created with classes (JSClassRef) -- in order to support static values, and in order to prevent API objects from storing their data inline, and thus falling into the oversized (read: slow and prone to giving Maciej the frowny face) heap.


  • Added two specialized JSObject subclasses -- JSCallbackFunction and JSCallbackConstructor -- to allow JSFunctionMake and JSConstructorMake to continue to work with the new class model. Another solution to this problem would be to create a custom class object for each function and constructor you make. This solution is more code but also more efficient.


  • Substantially beefed up the minidom example to demonstrate and test a lot of these techniques. Its output is still pretty haphazard, though.


  • Gave the <kjs/ preface to some includes -- I'm told this matters to building on some versions of Linux.


  • Implemented JSValueIsInstanceOf and JSValueIsObjectOfClass


  • Removed GetDescription callback. Something in the class datastructure should take care of this.
  • API/JSBase.h:
  • API/JSCallbackConstructor.cpp: Added. (KJS::): (KJS::JSCallbackConstructor::JSCallbackConstructor): (KJS::JSCallbackConstructor::implementsConstruct): (KJS::JSCallbackConstructor::construct): (KJS::JSCallbackConstructor::setPrivate): (KJS::JSCallbackConstructor::getPrivate):
  • API/JSCallbackConstructor.h: Added. (KJS::JSCallbackConstructor::classInfo):
  • API/JSCallbackFunction.cpp: Added. (KJS::): (KJS::JSCallbackFunction::JSCallbackFunction): (KJS::JSCallbackFunction::implementsCall): (KJS::JSCallbackFunction::callAsFunction): (KJS::JSCallbackFunction::setPrivate): (KJS::JSCallbackFunction::getPrivate):
  • API/JSCallbackFunction.h: Added. (KJS::JSCallbackFunction::classInfo):
  • API/JSCallbackObject.cpp: (KJS::): (KJS::JSCallbackObject::JSCallbackObject): (KJS::JSCallbackObject::init): (KJS::JSCallbackObject::~JSCallbackObject): (KJS::JSCallbackObject::className): (KJS::JSCallbackObject::getOwnPropertySlot): (KJS::JSCallbackObject::put): (KJS::JSCallbackObject::deleteProperty): (KJS::JSCallbackObject::implementsConstruct): (KJS::JSCallbackObject::construct): (KJS::JSCallbackObject::implementsCall): (KJS::JSCallbackObject::callAsFunction): (KJS::JSCallbackObject::getPropertyList): (KJS::JSCallbackObject::toBoolean): (KJS::JSCallbackObject::toNumber): (KJS::JSCallbackObject::toString): (KJS::JSCallbackObject::inherits): (KJS::JSCallbackObject::staticValueGetter): (KJS::JSCallbackObject::staticFunctionGetter): (KJS::JSCallbackObject::callbackGetter):
  • API/JSCallbackObject.h:
  • API/JSCharBufferRef.cpp:
  • API/JSClassRef.cpp: Added. (JSClassCreate): (JSClassRetain): (JSClassRelease):
  • API/JSClassRef.h: Added. (StaticValueEntry::StaticValueEntry): (StaticFunctionEntry::StaticFunctionEntry): (JSClass::JSClass):
  • API/JSContextRef.cpp: (JSContextCreate): (JSEvaluate):
  • API/JSContextRef.h:
  • API/JSNode.c: Added. (JSNodePrototype_appendChild): (JSNodePrototype_removeChild): (JSNodePrototype_replaceChild): (JSNodePrototype_class): (JSNode_getNodeType): (JSNode_getChildNodes): (JSNode_getFirstChild): (JSNode_finalize): (JSNode_class): (JSNode_prototype): (JSNode_new): (JSNode_construct):
  • API/JSNode.h: Added.
  • API/JSNodeList.c: Added. (JSNodeListPrototype_item): (JSNodeListPrototype_class): (JSNodeList_length): (JSNodeList_getProperty): (JSNodeList_finalize): (JSNodeList_class): (JSNodeList_prototype): (JSNodeList_new):
  • API/JSNodeList.h: Added.
  • API/JSObjectRef.cpp: (JSObjectMake): (JSFunctionMake): (JSConstructorMake): (JSPropertyEnumerator::JSPropertyEnumerator): (JSObjectCreatePropertyEnumerator): (JSPropertyEnumeratorGetNext): (JSPropertyEnumeratorRetain): (JSPropertyEnumeratorRelease):
  • API/JSObjectRef.h: (JSObjectCallbacks::):
  • API/JSValueRef.cpp: (JSValueIsObjectOfClass): (JSValueIsInstanceOf):
  • API/JSValueRef.h:
  • API/Node.c: Added. (Node_new): (Node_appendChild): (Node_removeChild): (Node_replaceChild): (Node_ref): (Node_deref):
  • API/Node.h: Added.
  • API/NodeList.c: Added. (NodeList_new): (NodeList_length): (NodeList_item): (NodeList_ref): (NodeList_deref):
  • API/NodeList.h: Added.
  • API/minidom.c: (main): (print): (createStringWithContentsOfFile):
  • API/minidom.js:
  • API/testapi.c: (assertEqualsAsCharacters): (MyObject_getProperty): (MyObject_class): (myConstructor_callAsConstructor): (main):
  • API/testapi.js:
  • JavaScriptCore.xcodeproj/project.pbxproj:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/API/JSCallbackObject.cpp

    r14951 r15133  
    2828#include "JSCallbackObject.h"
    2929#include "JSCharBufferRef.h"
     30#include "JSClassRef.h"
    3031#include "JSObjectRef.h"
    3132#include "internal.h"
     33#include "reference.h"
    3234#include "reference_list.h"
    3335
    3436namespace KJS {
    3537
    36 const ClassInfo JSCallbackObject::info = { "JSCallbackObject", 0, 0, 0 };
    37 
    38 JSCallbackObject::JSCallbackObject(const JSObjectCallbacks* callbacks)
     38const ClassInfo JSCallbackObject::info = { "CallbackObject", 0, 0, 0 };
     39
     40JSCallbackObject::JSCallbackObject(JSClassRef jsClass)
    3941    : JSObject()
    40     , m_privateData(0)
    41     , m_callbacks(*callbacks)
    42 {
     42{
     43    init(jsClass);
     44}
     45
     46JSCallbackObject::JSCallbackObject(JSClassRef jsClass, JSObject* prototype)
     47    : JSObject(prototype)
     48{
     49    init(jsClass);
     50}
     51
     52void JSCallbackObject::init(JSClassRef jsClass)
     53{
     54    m_privateData = 0;
     55    m_class = JSClassRetain(jsClass);
     56
    4357    JSObjectRef thisRef = toRef(this);
    4458   
    4559    do {
    46         if (JSInitializeCallback initialize = callbacks->initialize)
     60        if (JSInitializeCallback initialize = jsClass->callbacks.initialize)
    4761            initialize(thisRef);
    48     } while ((callbacks = callbacks->parentCallbacks));
    49 }
    50 
    51 JSCallbackObject::JSCallbackObject(const JSObjectCallbacks* callbacks, JSObject* prototype)
    52     : JSObject(prototype)
    53     , m_privateData(0)
    54     , m_callbacks(*callbacks)
    55 {
    56     JSObjectRef thisRef = toRef(this);
    57    
    58     do {
    59         if (JSInitializeCallback initialize = callbacks->initialize)
    60             initialize(thisRef);
    61     } while ((callbacks = callbacks->parentCallbacks));
     62    } while ((jsClass = jsClass->parent));
    6263}
    6364
     
    6667    JSObjectRef thisRef = toRef(this);
    6768   
    68     for (JSObjectCallbacks* callbacks = &m_callbacks; callbacks; callbacks = callbacks->parentCallbacks)
    69         if (JSFinalizeCallback finalize = callbacks->finalize)
     69    for (JSClassRef jsClass = m_class; jsClass; jsClass = jsClass->parent)
     70        if (JSFinalizeCallback finalize = jsClass->callbacks.finalize)
    7071            finalize(thisRef);
     72   
     73    JSClassRelease(m_class);
    7174}
    7275
    7376UString JSCallbackObject::className() const
    7477{
    75     JSObjectRef thisRef = toRef(this);
    76    
    77     for (const JSObjectCallbacks* callbacks = &m_callbacks; callbacks; callbacks = callbacks->parentCallbacks) {
    78         if (JSCopyDescriptionCallback copyDescriptionCallback = callbacks->copyDescription) {
    79             JSCharBufferRef descriptionBuf = copyDescriptionCallback(thisRef);
    80             UString description(toJS(descriptionBuf));
    81             JSCharBufferRelease(descriptionBuf);
    82             return description;
    83         }
    84     }
    85    
    86     return JSObject::className();
     78    return classInfo()->className;
    8779}
    8880
     
    9183    JSObjectRef thisRef = toRef(this);
    9284    JSCharBufferRef propertyNameRef = toRef(propertyName.ustring().rep());
    93 
    94     // optional optimization for cases when we only need to know if the property exists, not its value
    95     for (const JSObjectCallbacks* callbacks = &m_callbacks; callbacks; callbacks = callbacks->parentCallbacks) {
    96         if (JSHasPropertyCallback hasPropertyCallback = callbacks->hasProperty) {
     85   
     86    for (JSClassRef jsClass = m_class; jsClass; jsClass = jsClass->parent) {
     87        // optional optimization to bypass getProperty in cases when we only need to know if the property exists
     88        if (JSHasPropertyCallback hasPropertyCallback = jsClass->callbacks.hasProperty) {
    9789            if (hasPropertyCallback(thisRef, propertyNameRef)) {
    98                 slot.setCustom(0, callbackGetter);
    99                 return true;
    100             }
    101         }
    102     }
    103    
    104     for (const JSObjectCallbacks* callbacks = &m_callbacks; callbacks; callbacks = callbacks->parentCallbacks) {
    105         if (JSGetPropertyCallback getPropertyCallback = callbacks->getProperty) {
     90                slot.setCustom(this, callbackGetter);
     91                return true;
     92            }
     93        } else if (JSGetPropertyCallback getPropertyCallback = jsClass->callbacks.getProperty) {
    10694            JSValueRef returnValue;
    107             if (getPropertyCallback(thisRef, propertyNameRef, &returnValue)) {
    108                 slot.setCustom(reinterpret_cast<JSObject*>(returnValue), cachedValueGetter); // cache the value so we don't have to compute it again
    109                 return true;
    110             }
    111         }
    112     }
     95            if (getPropertyCallback(toRef(exec), thisRef, propertyNameRef, &returnValue)) {
     96                // cache the value so we don't have to compute it again
     97                // FIXME: This violates the PropertySlot design a little bit.
     98                // We should either use this optimization everywhere, or nowhere.
     99                slot.setCustom(reinterpret_cast<JSObject*>(returnValue), cachedValueGetter);
     100                return true;
     101            }
     102        }
     103
     104        if (__JSClass::StaticValuesTable* staticValues = jsClass->staticValues) {
     105            if (StaticValueEntry* entry = staticValues->get(propertyName.ustring().rep())) {
     106                if (entry->getProperty) {
     107                    slot.setCustom(this, staticValueGetter);
     108                    return true;
     109                }
     110            }
     111        }
     112       
     113        if (__JSClass::StaticFunctionsTable* staticFunctions = jsClass->staticFunctions) {
     114            if (staticFunctions->contains(propertyName.ustring().rep())) {
     115                slot.setCustom(this, staticFunctionGetter);
     116                return true;
     117            }
     118        }
     119    }
     120
    113121    return JSObject::getOwnPropertySlot(exec, propertyName, slot);
    114122}
     
    124132    JSCharBufferRef propertyNameRef = toRef(propertyName.ustring().rep());
    125133
    126     for (const JSObjectCallbacks* callbacks = &m_callbacks; callbacks; callbacks = callbacks->parentCallbacks) {
    127         if (JSSetPropertyCallback setPropertyCallback = callbacks->setProperty) {
     134    for (JSClassRef jsClass = m_class; jsClass; jsClass = jsClass->parent) {
     135        if (JSSetPropertyCallback setPropertyCallback = jsClass->callbacks.setProperty) {
    128136            if (setPropertyCallback(thisRef, propertyNameRef, value))
    129137                return;
    130138        }
     139   
     140        if (__JSClass::StaticValuesTable* staticValues = jsClass->staticValues) {
     141            if (StaticValueEntry* entry = staticValues->get(propertyName.ustring().rep())) {
     142                if (entry->attributes & kJSPropertyAttributeReadOnly)
     143                    return;
     144                if (JSSetPropertyCallback setPropertyCallback = entry->setProperty) {
     145                    if (setPropertyCallback(thisRef, propertyNameRef, value))
     146                        return;
     147                }
     148            }
     149        }
     150       
     151        if (__JSClass::StaticFunctionsTable* staticFunctions = jsClass->staticFunctions) {
     152            if (StaticFunctionEntry* entry = staticFunctions->get(propertyName.ustring().rep())) {
     153                if (entry->attributes & kJSPropertyAttributeReadOnly)
     154                    return;
     155                putDirect(propertyName, value, attr); // put as override property
     156                return;
     157            }
     158        }
    131159    }
    132160    return JSObject::put(exec, propertyName, value, attr);
     
    143171    JSCharBufferRef propertyNameRef = toRef(propertyName.ustring().rep());
    144172   
    145     for (const JSObjectCallbacks* callbacks = &m_callbacks; callbacks; callbacks = callbacks->parentCallbacks) {
    146         if (JSDeletePropertyCallback deletePropertyCallback = callbacks->deleteProperty) {
     173    for (JSClassRef jsClass = m_class; jsClass; jsClass = jsClass->parent) {
     174        if (JSDeletePropertyCallback deletePropertyCallback = jsClass->callbacks.deleteProperty) {
    147175            if (deletePropertyCallback(thisRef, propertyNameRef))
    148176                return true;
    149177        }
     178
     179        if (__JSClass::StaticValuesTable* staticValues = jsClass->staticValues) {
     180            if (StaticValueEntry* entry = staticValues->get(propertyName.ustring().rep())) {
     181                if (entry->attributes & kJSPropertyAttributeDontDelete)
     182                    return false;
     183                return true;
     184            }
     185        }
     186       
     187        if (__JSClass::StaticFunctionsTable* staticFunctions = jsClass->staticFunctions) {
     188            if (StaticFunctionEntry* entry = staticFunctions->get(propertyName.ustring().rep())) {
     189                if (entry->attributes & kJSPropertyAttributeDontDelete)
     190                    return false;
     191                return true;
     192            }
     193        }
    150194    }
    151195    return JSObject::deleteProperty(exec, propertyName);
     
    159203bool JSCallbackObject::implementsConstruct() const
    160204{
    161     for (const JSObjectCallbacks* callbacks = &m_callbacks; callbacks; callbacks = callbacks->parentCallbacks)
    162         if (callbacks->callAsConstructor)
     205    for (JSClassRef jsClass = m_class; jsClass; jsClass = jsClass->parent)
     206        if (jsClass->callbacks.callAsConstructor)
    163207            return true;
    164208
     
    171215    JSObjectRef thisRef = toRef(this);
    172216   
    173     for (const JSObjectCallbacks* callbacks = &m_callbacks; callbacks; callbacks = callbacks->parentCallbacks) {
    174         if (JSCallAsConstructorCallback callAsConstructorCallback = callbacks->callAsConstructor) {
     217    for (JSClassRef jsClass = m_class; jsClass; jsClass = jsClass->parent) {
     218        if (JSCallAsConstructorCallback callAsConstructorCallback = jsClass->callbacks.callAsConstructor) {
    175219            size_t argc = args.size();
    176220            JSValueRef argv[argc];
     
    181225    }
    182226   
    183     ASSERT(false);
     227    ASSERT(0); // implementsConstruct should prevent us from reaching here
    184228    return 0;
    185229}
     
    187231bool JSCallbackObject::implementsCall() const
    188232{
    189     for (const JSObjectCallbacks* callbacks = &m_callbacks; callbacks; callbacks = callbacks->parentCallbacks)
    190         if (callbacks->callAsFunction)
     233    for (JSClassRef jsClass = m_class; jsClass; jsClass = jsClass->parent)
     234        if (jsClass->callbacks.callAsFunction)
    191235            return true;
    192236   
     
    200244    JSObjectRef thisObjRef = toRef(thisObj);
    201245
    202     for (const JSObjectCallbacks* callbacks = &m_callbacks; callbacks; callbacks = callbacks->parentCallbacks) {
    203         if (JSCallAsFunctionCallback callAsFunctionCallback = callbacks->callAsFunction) {
     246    for (JSClassRef jsClass = m_class; jsClass; jsClass = jsClass->parent) {
     247        if (JSCallAsFunctionCallback callAsFunctionCallback = jsClass->callbacks.callAsFunction) {
    204248            size_t argc = args.size();
    205249            JSValueRef argv[argc];
     
    210254    }
    211255
    212     ASSERT(false);
     256    ASSERT(0); // implementsCall should prevent us from reaching here
    213257    return 0;
    214258}
     
    218262    JSObjectRef thisRef = toRef(this);
    219263
    220     for (const JSObjectCallbacks* callbacks = &m_callbacks; callbacks; callbacks = callbacks->parentCallbacks)
    221         if (JSGetPropertyListCallback getPropertyListCallback = callbacks->getPropertyList)
     264    for (JSClassRef jsClass = m_class; jsClass; jsClass = jsClass->parent) {
     265        if (JSGetPropertyListCallback getPropertyListCallback = jsClass->callbacks.getPropertyList)
    222266            getPropertyListCallback(thisRef, toRef(&propertyList));
    223267
     268        if (__JSClass::StaticValuesTable* staticValues = jsClass->staticValues) {
     269            typedef __JSClass::StaticValuesTable::const_iterator iterator;
     270            iterator end = staticValues->end();
     271            for (iterator it = staticValues->begin(); it != end; ++it) {
     272                UString::Rep* name = it->first.get();
     273                StaticValueEntry* entry = it->second;
     274                if (entry->getProperty && !(entry->attributes & kJSPropertyAttributeDontEnum))
     275                    propertyList.append(Reference(this, Identifier(name)));
     276            }
     277        }
     278
     279        if (__JSClass::StaticFunctionsTable* staticFunctions = jsClass->staticFunctions) {
     280            typedef __JSClass::StaticFunctionsTable::const_iterator iterator;
     281            iterator end = staticFunctions->end();
     282            for (iterator it = staticFunctions->begin(); it != end; ++it) {
     283                UString::Rep* name = it->first.get();
     284                StaticFunctionEntry* entry = it->second;
     285                if (!(entry->attributes & kJSPropertyAttributeDontEnum))
     286                    propertyList.append(Reference(this, Identifier(name)));
     287            }
     288        }
     289    }
     290
    224291    JSObject::getPropertyList(exec, propertyList, recursive);
    225292}
     
    229296    JSObjectRef thisRef = toRef(this);
    230297
    231     for (const JSObjectCallbacks* callbacks = &m_callbacks; callbacks; callbacks = callbacks->parentCallbacks) {
    232         if (JSConvertToTypeCallback convertToTypeCallback = callbacks->convertToType) {
     298    for (JSClassRef jsClass = m_class; jsClass; jsClass = jsClass->parent) {
     299        if (JSConvertToTypeCallback convertToTypeCallback = jsClass->callbacks.convertToType) {
    233300            JSValueRef returnValue;
    234301            if (convertToTypeCallback(thisRef, kJSTypeBoolean, &returnValue))
     
    243310    JSObjectRef thisRef = toRef(this);
    244311
    245     for (const JSObjectCallbacks* callbacks = &m_callbacks; callbacks; callbacks = callbacks->parentCallbacks) {
    246         if (JSConvertToTypeCallback convertToTypeCallback = callbacks->convertToType) {
     312    for (JSClassRef jsClass = m_class; jsClass; jsClass = jsClass->parent) {
     313        if (JSConvertToTypeCallback convertToTypeCallback = jsClass->callbacks.convertToType) {
    247314            JSValueRef returnValue;
    248315            if (convertToTypeCallback(thisRef, kJSTypeNumber, &returnValue))
     
    257324    JSObjectRef thisRef = toRef(this);
    258325
    259     for (const JSObjectCallbacks* callbacks = &m_callbacks; callbacks; callbacks = callbacks->parentCallbacks) {
    260         if (JSConvertToTypeCallback convertToTypeCallback = callbacks->convertToType) {
     326    for (JSClassRef jsClass = m_class; jsClass; jsClass = jsClass->parent) {
     327        if (JSConvertToTypeCallback convertToTypeCallback = jsClass->callbacks.convertToType) {
    261328            JSValueRef returnValue;
    262329            if (convertToTypeCallback(thisRef, kJSTypeString, &returnValue))
     
    277344}
    278345
     346bool JSCallbackObject::inherits(JSClassRef c) const
     347{
     348    for (JSClassRef jsClass = m_class; jsClass; jsClass = jsClass->parent)
     349        if (jsClass == c)
     350            return true;
     351    return false;
     352}
     353
    279354JSValue* JSCallbackObject::cachedValueGetter(ExecState*, JSObject*, const Identifier&, const PropertySlot& slot)
    280355{
     
    284359}
    285360
    286 JSValue* JSCallbackObject::callbackGetter(ExecState*, JSObject* originalObject, const Identifier& propertyName, const PropertySlot&)
    287 {
    288     ASSERT(originalObject->inherits(&JSCallbackObject::info));
    289     JSObjectRef thisRef = toRef(originalObject);
    290     JSCharBufferRef propertyNameRef= toRef(propertyName.ustring().rep());
    291 
    292     for (const JSObjectCallbacks* callbacks = &static_cast<JSCallbackObject*>(originalObject)->m_callbacks; callbacks; callbacks = callbacks->parentCallbacks) {
    293         if (JSGetPropertyCallback getPropertyCallback = callbacks->getProperty) {
    294             JSValueRef returnValue;
    295             if (getPropertyCallback(thisRef, propertyNameRef, &returnValue)) {
     361JSValue* JSCallbackObject::staticValueGetter(ExecState* exec, JSObject*, const Identifier& propertyName, const PropertySlot& slot)
     362{
     363    ASSERT(slot.slotBase()->inherits(&JSCallbackObject::info));
     364    JSCallbackObject* thisObj = static_cast<JSCallbackObject*>(slot.slotBase());
     365
     366    JSObjectRef thisRef = toRef(thisObj);
     367    JSCharBufferRef propertyNameRef = toRef(propertyName.ustring().rep());
     368
     369    for (JSClassRef jsClass = thisObj->m_class; jsClass; jsClass = jsClass->parent) {
     370        JSValueRef returnValue;
     371       
     372        if (__JSClass::StaticValuesTable* staticValues = jsClass->staticValues)
     373            if (StaticValueEntry* entry = staticValues->get(propertyName.ustring().rep()))
     374                if (JSGetPropertyCallback getPropertyCallback = entry->getProperty)
     375                    if (getPropertyCallback(toRef(exec), thisRef, propertyNameRef, &returnValue))
     376                        return toJS(returnValue);
     377    }
     378
     379    return jsUndefined();
     380}
     381
     382JSValue* JSCallbackObject::staticFunctionGetter(ExecState* exec, JSObject*, const Identifier& propertyName, const PropertySlot& slot)
     383{
     384    ASSERT(slot.slotBase()->inherits(&JSCallbackObject::info));
     385    JSCallbackObject* thisObj = static_cast<JSCallbackObject*>(slot.slotBase());
     386
     387    if (JSValue* cachedOrOverrideValue = thisObj->getDirect(propertyName))
     388        return toJS(cachedOrOverrideValue);
     389
     390    for (JSClassRef jsClass = thisObj->m_class; jsClass; jsClass = jsClass->parent) {
     391        if (__JSClass::StaticFunctionsTable* staticFunctions = jsClass->staticFunctions) {
     392            if (StaticFunctionEntry* entry = staticFunctions->get(propertyName.ustring().rep())) {
     393                JSValue* v = toJS(JSFunctionMake(toRef(exec), entry->callAsFunction));
     394                thisObj->putDirect(propertyName, v, entry->attributes);
     395                return v;
     396            }
     397        }
     398    }
     399
     400    return jsUndefined();
     401}
     402
     403JSValue* JSCallbackObject::callbackGetter(ExecState* exec, JSObject*, const Identifier& propertyName, const PropertySlot& slot)
     404{
     405    ASSERT(slot.slotBase()->inherits(&JSCallbackObject::info));
     406    JSCallbackObject* thisObj = static_cast<JSCallbackObject*>(slot.slotBase());
     407
     408    JSObjectRef thisRef = toRef(thisObj);
     409    JSCharBufferRef propertyNameRef = toRef(propertyName.ustring().rep());
     410
     411    for (JSClassRef jsClass = thisObj->m_class; jsClass; jsClass = jsClass->parent) {
     412        JSValueRef returnValue;
     413
     414        if (JSGetPropertyCallback getPropertyCallback = jsClass->callbacks.getProperty)
     415            if (getPropertyCallback(toRef(exec), thisRef, propertyNameRef, &returnValue))
    296416                return toJS(returnValue);
    297             }
    298         }
    299417    }
    300418
Note: See TracChangeset for help on using the changeset viewer.