Changeset 15462 in webkit for trunk/JavaScriptCore


Ignore:
Timestamp:
Jul 15, 2006, 6:28:25 PM (19 years ago)
Author:
ggaren
Message:

Reviewed by Maciej.

  • Moved the arguments passed to JSClassCreate into a single structure, called JSClassDefinition. This will enable easier structure migration/versioning in the future, if necessary.


  • Added support for class names.


  • kJSClassDefinitionNull replaces kJSObjectCallbacksNone.


  • JSClass is becoming a fairly complex struct, so I migrated all of its implementation other than reference counting to the sruct.


  • Also moved JSClass* functions in the API to JSObjectRef.cpp, since they're declared in JSObjectRef.h


  • Also added some more informative explanation to the class structure doc.
Location:
trunk/JavaScriptCore
Files:
11 edited

Legend:

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

    r15444 r15462  
    6060   
    6161    do {
    62         if (JSObjectInitializeCallback initialize = jsClass->callbacks.initialize)
     62        if (JSObjectInitializeCallback initialize = jsClass->initialize)
    6363            initialize(context, thisRef, toRef(exec->exceptionSlot()));
    64     } while ((jsClass = jsClass->parent));
     64    } while ((jsClass = jsClass->parentClass));
    6565}
    6666
     
    6969    JSObjectRef thisRef = toRef(this);
    7070   
    71     for (JSClassRef jsClass = m_class; jsClass; jsClass = jsClass->parent)
    72         if (JSObjectFinalizeCallback finalize = jsClass->callbacks.finalize)
     71    for (JSClassRef jsClass = m_class; jsClass; jsClass = jsClass->parentClass)
     72        if (JSObjectFinalizeCallback finalize = jsClass->finalize)
    7373            finalize(thisRef);
    7474   
     
    7878UString JSCallbackObject::className() const
    7979{
    80     return classInfo()->className;
     80    if (!m_class->className.isNull())
     81        return m_class->className;
     82   
     83    return JSObject::className();
    8184}
    8285
     
    8790    JSStringRef propertyNameRef = toRef(propertyName.ustring().rep());
    8891
    89     for (JSClassRef jsClass = m_class; jsClass; jsClass = jsClass->parent) {
     92    for (JSClassRef jsClass = m_class; jsClass; jsClass = jsClass->parentClass) {
    9093        // optional optimization to bypass getProperty in cases when we only need to know if the property exists
    91         if (JSObjectHasPropertyCallback hasProperty = jsClass->callbacks.hasProperty) {
     94        if (JSObjectHasPropertyCallback hasProperty = jsClass->hasProperty) {
    9295            if (hasProperty(context, thisRef, propertyNameRef)) {
    9396                slot.setCustom(this, callbackGetter);
    9497                return true;
    9598            }
    96         } else if (JSObjectGetPropertyCallback getProperty = jsClass->callbacks.getProperty) {
     99        } else if (JSObjectGetPropertyCallback getProperty = jsClass->getProperty) {
    97100            if (JSValueRef value = getProperty(context, thisRef, propertyNameRef, toRef(exec->exceptionSlot()))) {
    98101                // cache the value so we don't have to compute it again
     
    136139    JSValueRef valueRef = toRef(value);
    137140
    138     for (JSClassRef jsClass = m_class; jsClass; jsClass = jsClass->parent) {
    139         if (JSObjectSetPropertyCallback setProperty = jsClass->callbacks.setProperty) {
     141    for (JSClassRef jsClass = m_class; jsClass; jsClass = jsClass->parentClass) {
     142        if (JSObjectSetPropertyCallback setProperty = jsClass->setProperty) {
    140143            if (setProperty(context, thisRef, propertyNameRef, valueRef, toRef(exec->exceptionSlot())))
    141144                return;
     
    177180    JSStringRef propertyNameRef = toRef(propertyName.ustring().rep());
    178181   
    179     for (JSClassRef jsClass = m_class; jsClass; jsClass = jsClass->parent) {
    180         if (JSObjectDeletePropertyCallback deleteProperty = jsClass->callbacks.deleteProperty) {
     182    for (JSClassRef jsClass = m_class; jsClass; jsClass = jsClass->parentClass) {
     183        if (JSObjectDeletePropertyCallback deleteProperty = jsClass->deleteProperty) {
    181184            if (deleteProperty(context, thisRef, propertyNameRef, toRef(exec->exceptionSlot())))
    182185                return true;
     
    210213bool JSCallbackObject::implementsConstruct() const
    211214{
    212     for (JSClassRef jsClass = m_class; jsClass; jsClass = jsClass->parent)
    213         if (jsClass->callbacks.callAsConstructor)
     215    for (JSClassRef jsClass = m_class; jsClass; jsClass = jsClass->parentClass)
     216        if (jsClass->callAsConstructor)
    214217            return true;
    215218
     
    222225    JSObjectRef thisRef = toRef(this);
    223226   
    224     for (JSClassRef jsClass = m_class; jsClass; jsClass = jsClass->parent) {
    225         if (JSObjectCallAsConstructorCallback callAsConstructor = jsClass->callbacks.callAsConstructor) {
     227    for (JSClassRef jsClass = m_class; jsClass; jsClass = jsClass->parentClass) {
     228        if (JSObjectCallAsConstructorCallback callAsConstructor = jsClass->callAsConstructor) {
    226229            size_t argumentCount = args.size();
    227230            JSValueRef arguments[argumentCount];
     
    238241bool JSCallbackObject::implementsHasInstance() const
    239242{
    240     for (JSClassRef jsClass = m_class; jsClass; jsClass = jsClass->parent)
    241         if (jsClass->callbacks.hasInstance)
     243    for (JSClassRef jsClass = m_class; jsClass; jsClass = jsClass->parentClass)
     244        if (jsClass->hasInstance)
    242245            return true;
    243246
     
    250253    JSObjectRef thisRef = toRef(this);
    251254
    252     for (JSClassRef jsClass = m_class; jsClass; jsClass = jsClass->parent)
    253         if (JSObjectHasInstanceCallback hasInstance = jsClass->callbacks.hasInstance)
     255    for (JSClassRef jsClass = m_class; jsClass; jsClass = jsClass->parentClass)
     256        if (JSObjectHasInstanceCallback hasInstance = jsClass->hasInstance)
    254257            return hasInstance(execRef, thisRef, toRef(value), toRef(exec->exceptionSlot()));
    255258
     
    261264bool JSCallbackObject::implementsCall() const
    262265{
    263     for (JSClassRef jsClass = m_class; jsClass; jsClass = jsClass->parent)
    264         if (jsClass->callbacks.callAsFunction)
     266    for (JSClassRef jsClass = m_class; jsClass; jsClass = jsClass->parentClass)
     267        if (jsClass->callAsFunction)
    265268            return true;
    266269   
     
    274277    JSObjectRef thisObjRef = toRef(thisObj);
    275278
    276     for (JSClassRef jsClass = m_class; jsClass; jsClass = jsClass->parent) {
    277         if (JSObjectCallAsFunctionCallback callAsFunction = jsClass->callbacks.callAsFunction) {
     279    for (JSClassRef jsClass = m_class; jsClass; jsClass = jsClass->parentClass) {
     280        if (JSObjectCallAsFunctionCallback callAsFunction = jsClass->callAsFunction) {
    278281            size_t argumentCount = args.size();
    279282            JSValueRef arguments[argumentCount];
     
    292295    JSObjectRef thisRef = toRef(this);
    293296
    294     for (JSClassRef jsClass = m_class; jsClass; jsClass = jsClass->parent) {
    295         if (JSObjectAddPropertiesToListCallback addPropertiesToList = jsClass->callbacks.addPropertiesToList)
     297    for (JSClassRef jsClass = m_class; jsClass; jsClass = jsClass->parentClass) {
     298        if (JSObjectAddPropertiesToListCallback addPropertiesToList = jsClass->addPropertiesToList)
    296299            addPropertiesToList(thisRef, toRef(&propertyList));
    297300
     
    327330    JSObjectRef thisRef = toRef(this);
    328331
    329     for (JSClassRef jsClass = m_class; jsClass; jsClass = jsClass->parent)
    330         if (JSObjectConvertToTypeCallback convertToType = jsClass->callbacks.convertToType)
     332    for (JSClassRef jsClass = m_class; jsClass; jsClass = jsClass->parentClass)
     333        if (JSObjectConvertToTypeCallback convertToType = jsClass->convertToType)
    331334            if (JSValueRef value = convertToType(context, thisRef, kJSTypeNumber, toRef(exec->exceptionSlot())))
    332335                return toJS(value)->getNumber();
     
    340343    JSObjectRef thisRef = toRef(this);
    341344
    342     for (JSClassRef jsClass = m_class; jsClass; jsClass = jsClass->parent)
    343         if (JSObjectConvertToTypeCallback convertToType = jsClass->callbacks.convertToType)
     345    for (JSClassRef jsClass = m_class; jsClass; jsClass = jsClass->parentClass)
     346        if (JSObjectConvertToTypeCallback convertToType = jsClass->convertToType)
    344347            if (JSValueRef value = convertToType(context, thisRef, kJSTypeString, toRef(exec->exceptionSlot())))
    345348                return toJS(value)->getString();
     
    360363bool JSCallbackObject::inherits(JSClassRef c) const
    361364{
    362     for (JSClassRef jsClass = m_class; jsClass; jsClass = jsClass->parent)
     365    for (JSClassRef jsClass = m_class; jsClass; jsClass = jsClass->parentClass)
    363366        if (jsClass == c)
    364367            return true;
     
    382385    JSStringRef propertyNameRef = toRef(propertyName.ustring().rep());
    383386
    384     for (JSClassRef jsClass = thisObj->m_class; jsClass; jsClass = jsClass->parent)
     387    for (JSClassRef jsClass = thisObj->m_class; jsClass; jsClass = jsClass->parentClass)
    385388        if (__JSClass::StaticValuesTable* staticValues = jsClass->staticValues)
    386389            if (StaticValueEntry* entry = staticValues->get(propertyName.ustring().rep()))
     
    400403        return cachedOrOverrideValue;
    401404
    402     for (JSClassRef jsClass = thisObj->m_class; jsClass; jsClass = jsClass->parent) {
     405    for (JSClassRef jsClass = thisObj->m_class; jsClass; jsClass = jsClass->parentClass) {
    403406        if (__JSClass::StaticFunctionsTable* staticFunctions = jsClass->staticFunctions) {
    404407            if (StaticFunctionEntry* entry = staticFunctions->get(propertyName.ustring().rep())) {
     
    421424    JSStringRef propertyNameRef = toRef(propertyName.ustring().rep());
    422425
    423     for (JSClassRef jsClass = thisObj->m_class; jsClass; jsClass = jsClass->parent)
    424         if (JSObjectGetPropertyCallback getProperty = jsClass->callbacks.getProperty)
     426    for (JSClassRef jsClass = thisObj->m_class; jsClass; jsClass = jsClass->parentClass)
     427        if (JSObjectGetPropertyCallback getProperty = jsClass->getProperty)
    425428            if (JSValueRef value = getProperty(toRef(exec), thisRef, propertyNameRef, toRef(exec->exceptionSlot())))
    426429                return toJS(value);
  • trunk/JavaScriptCore/API/JSClassRef.cpp

    r15384 r15462  
    3131using namespace KJS;
    3232
    33 const JSObjectCallbacks kJSObjectCallbacksNone = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
     33const JSClassDefinition kJSClassDefinitionNull = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
    3434
    35 JSClassRef JSClassCreate(JSStaticValue* staticValues, JSStaticFunction* staticFunctions, const JSObjectCallbacks* callbacks, JSClassRef parentClass)
     35__JSClass::__JSClass(JSClassDefinition* definition)
     36    : refCount(0)
     37    , className(definition->className)
     38    , parentClass(definition->parentClass)
     39    , staticValues(0)
     40    , staticFunctions(0)
     41    , initialize(definition->initialize)
     42    , finalize(definition->finalize)
     43    , hasProperty(definition->hasProperty)
     44    , getProperty(definition->getProperty)
     45    , setProperty(definition->setProperty)
     46    , deleteProperty(definition->deleteProperty)
     47    , addPropertiesToList(definition->addPropertiesToList)
     48    , callAsFunction(definition->callAsFunction)
     49    , callAsConstructor(definition->callAsConstructor)
     50    , hasInstance(definition->hasInstance)
     51    , convertToType(definition->convertToType)
    3652{
    37     JSClassRef jsClass = new __JSClass;
    38     if (staticValues) {
    39         jsClass->staticValues = new __JSClass::StaticValuesTable();
    40         while (staticValues->name) {
    41             jsClass->staticValues->add(Identifier(staticValues->name).ustring().rep(),
    42                                        new StaticValueEntry(staticValues->getProperty, staticValues->setProperty, staticValues->attributes));
    43             ++staticValues;
     53    if (JSStaticValue* staticValue = definition->staticValues) {
     54        staticValues = new StaticValuesTable();
     55        while (staticValue->name) {
     56            staticValues->add(Identifier(staticValue->name).ustring().rep(),
     57                              new StaticValueEntry(staticValue->getProperty, staticValue->setProperty, staticValue->attributes));
     58            ++staticValue;
    4459        }
    4560    }
    4661   
    47     if (staticFunctions) {
    48         jsClass->staticFunctions = new __JSClass::StaticFunctionsTable();
    49         while (staticFunctions->name) {
    50             jsClass->staticFunctions->add(Identifier(staticFunctions->name).ustring().rep(),
    51                                           new StaticFunctionEntry(staticFunctions->callAsFunction, staticFunctions->attributes));
    52             ++staticFunctions;
     62    if (JSStaticFunction* staticFunction = definition->staticFunctions) {
     63        staticFunctions = new StaticFunctionsTable();
     64        while (staticFunction->name) {
     65            staticFunctions->add(Identifier(staticFunction->name).ustring().rep(),
     66                                 new StaticFunctionEntry(staticFunction->callAsFunction, staticFunction->attributes));
     67            ++staticFunction;
    5368        }
    5469    }
    55    
    56     if (callbacks)
    57         jsClass->callbacks = *callbacks;
    58     else
    59         jsClass->callbacks = kJSObjectCallbacksNone;
    60    
    61     jsClass->parent = parentClass;
    62    
    63     return JSClassRetain(jsClass);
    6470}
    6571
    66 JSClassRef JSClassRetain(JSClassRef jsClass)
     72__JSClass::~__JSClass()
    6773{
    68     ++jsClass->refCount;
    69     return jsClass;
    70 }
     74    if (staticValues) {
     75        deleteAllValues(*staticValues);
     76        delete staticValues;
     77    }
    7178
    72 void JSClassRelease(JSClassRef jsClass)
    73 {
    74     if (--jsClass->refCount == 0) {
    75         if (jsClass->staticValues) {
    76             deleteAllValues(*jsClass->staticValues);
    77             delete jsClass->staticValues;
    78         }
    79 
    80         if (jsClass->staticFunctions) {
    81             deleteAllValues(*jsClass->staticFunctions);
    82             delete jsClass->staticFunctions;
    83         }
    84 
    85         delete jsClass;
     79    if (staticFunctions) {
     80        deleteAllValues(*staticFunctions);
     81        delete staticFunctions;
    8682    }
    8783}
  • trunk/JavaScriptCore/API/JSClassRef.h

    r15376 r15462  
    5454
    5555struct __JSClass {
    56     __JSClass()
    57         : refCount(0), staticValues(0), staticFunctions(0)
    58     {
    59     }
    60    
    61     unsigned refCount;
     56    __JSClass(JSClassDefinition*);
     57    ~__JSClass();
    6258   
    6359    typedef HashMap<RefPtr<KJS::UString::Rep>, StaticValueEntry*> StaticValuesTable;
     60    typedef HashMap<RefPtr<KJS::UString::Rep>, StaticFunctionEntry*> StaticFunctionsTable;
     61
     62    unsigned refCount;
     63
     64    KJS::UString className;
     65    __JSClass* parentClass;
     66       
    6467    StaticValuesTable* staticValues;
    65 
    66     typedef HashMap<RefPtr<KJS::UString::Rep>, StaticFunctionEntry*> StaticFunctionsTable;
    6768    StaticFunctionsTable* staticFunctions;
    68 
    69     KJS::UString name; // FIXME: Not used yet
    70     JSObjectCallbacks callbacks;
    71     __JSClass* parent;
     69   
     70    JSObjectInitializeCallback initialize;
     71    JSObjectFinalizeCallback finalize;
     72    JSObjectHasPropertyCallback hasProperty;
     73    JSObjectGetPropertyCallback getProperty;
     74    JSObjectSetPropertyCallback setProperty;
     75    JSObjectDeletePropertyCallback deleteProperty;
     76    JSObjectAddPropertiesToListCallback addPropertiesToList;
     77    JSObjectCallAsFunctionCallback callAsFunction;
     78    JSObjectCallAsConstructorCallback callAsConstructor;
     79    JSObjectHasInstanceCallback hasInstance;
     80    JSObjectConvertToTypeCallback convertToType;
    7281};
    7382
  • trunk/JavaScriptCore/API/JSNode.c

    r15444 r15462  
    108108static JSClassRef JSNodePrototype_class(JSContextRef context)
    109109{
    110     static JSClassRef nodePrototypeClass;
    111     if (!nodePrototypeClass)
    112         nodePrototypeClass = JSClassCreate(NULL, JSNodePrototype_staticFunctions, &kJSObjectCallbacksNone, NULL);
    113     return nodePrototypeClass;
     110    static JSClassRef jsClass;
     111    if (!jsClass) {
     112        JSClassDefinition definition = kJSClassDefinitionNull;
     113        definition.staticFunctions = JSNodePrototype_staticFunctions;
     114        jsClass = JSClassCreate(&definition);
     115    }
     116    return jsClass;
    114117}
    115118
     
    164167static JSClassRef JSNode_class(JSContextRef context)
    165168{
    166     static JSClassRef nodeClass;
    167     if (!nodeClass) {
    168         JSObjectCallbacks JSNode_callbacks = kJSObjectCallbacksNone;
    169         JSNode_callbacks.finalize = JSNode_finalize;
    170        
    171         nodeClass = JSClassCreate(JSNode_staticValues, NULL, &JSNode_callbacks, NULL);
    172     }
    173     return nodeClass;
     169    static JSClassRef jsClass;
     170    if (!jsClass) {
     171        JSClassDefinition definition = kJSClassDefinitionNull;
     172        definition.staticValues = JSNode_staticValues;
     173        definition.finalize = JSNode_finalize;
     174
     175        jsClass = JSClassCreate(&definition);
     176    }
     177    return jsClass;
    174178}
    175179
  • trunk/JavaScriptCore/API/JSNodeList.c

    r15444 r15462  
    5151    static JSClassRef jsClass;
    5252    if (!jsClass) {
    53         jsClass = JSClassCreate(NULL, JSNodeListPrototype_staticFunctions, &kJSObjectCallbacksNone, NULL);
     53        JSClassDefinition definition = kJSClassDefinitionNull;
     54        definition.staticFunctions = JSNodeListPrototype_staticFunctions;
     55        jsClass = JSClassCreate(&definition);
    5456    }
    5557   
     
    98100    static JSClassRef jsClass;
    99101    if (!jsClass) {
    100         JSObjectCallbacks callbacks = kJSObjectCallbacksNone;
    101         callbacks.getProperty = JSNodeList_getProperty;
    102         callbacks.finalize = JSNodeList_finalize;
    103        
    104         jsClass = JSClassCreate(JSNodeList_staticValues, NULL, &callbacks, NULL);
     102        JSClassDefinition definition = kJSClassDefinitionNull;
     103        definition.staticValues = JSNodeList_staticValues;
     104        definition.getProperty = JSNodeList_getProperty;
     105        definition.finalize = JSNodeList_finalize;
     106
     107        jsClass = JSClassCreate(&definition);
    105108    }
    106109   
  • trunk/JavaScriptCore/API/JSObjectRef.cpp

    r15444 r15462  
    3131#include "JSCallbackFunction.h"
    3232#include "JSCallbackObject.h"
     33#include "JSClassRef.h"
    3334
    3435#include "identifier.h"
     
    4142using namespace KJS;
    4243
     44JSClassRef JSClassCreate(JSClassDefinition* definition)
     45{
     46    JSClassRef jsClass = new __JSClass(definition);
     47    return JSClassRetain(jsClass);
     48}
     49
     50JSClassRef JSClassRetain(JSClassRef jsClass)
     51{
     52    ++jsClass->refCount;
     53    return jsClass;
     54}
     55
     56void JSClassRelease(JSClassRef jsClass)
     57{
     58    if (--jsClass->refCount == 0)
     59        delete jsClass;
     60}
     61
    4362JSObjectRef JSObjectMake(JSContextRef context, JSClassRef jsClass, JSValueRef prototype)
    4463{
  • trunk/JavaScriptCore/API/JSObjectRef.h

    r15444 r15462  
    8484/*!
    8585@typedef JSObjectHasPropertyCallback
    86 @abstract The callback invoked when determining whether an object has a given property.
     86@abstract The callback invoked when determining whether an object has a property.
    8787@param context The current execution context.
    8888@param object The JSObject to search for the property.
     
    9393bool HasProperty(JSContextRef context, JSObjectRef object, JSStringRef propertyName);
    9494
    95 If this function returns false, the hasProperty request forwards to object's static property table, then its parent class chain (which includes the default object class), then its prototype chain.
     95If this function returns false, the hasProperty request forwards to object's statically declared properties, then its parent class chain (which includes the default object class), then its prototype chain.
    9696
    9797This callback enables optimization in cases where only a property's existence needs to be known, not its value, and computing its value would be expensive.
     
    104104/*!
    105105@typedef JSObjectGetPropertyCallback
    106 @abstract The callback invoked when getting a property from an object.
     106@abstract The callback invoked when getting a property's value.
    107107@param context The current execution context.
    108108@param object The JSObject to search for the property.
     
    114114JSValueRef GetProperty(JSContextRef context, JSObjectRef object, JSStringRef propertyName, JSValueRef* exception);
    115115
    116 If this function returns NULL, the get request forwards to object's static property table, then its parent class chain (which includes the default object class), then its prototype chain.
     116If this function returns NULL, the get request forwards to object's statically declared properties, then its parent class chain (which includes the default object class), then its prototype chain.
    117117*/
    118118typedef JSValueRef
     
    121121/*!
    122122@typedef JSObjectSetPropertyCallback
    123 @abstract The callback invoked when setting the value of a given property.
     123@abstract The callback invoked when setting a property's value.
    124124@param context The current execution context.
    125125@param object The JSObject on which to set the property's value.
     
    132132bool SetProperty(JSContextRef context, JSObjectRef object, JSStringRef propertyName, JSValueRef value, JSValueRef* exception);
    133133
    134 If this function returns false, the set request forwards to object's static property table, then its parent class chain (which includes the default object class).
     134If this function returns false, the set request forwards to object's statically declared properties, then its parent class chain (which includes the default object class).
    135135*/
    136136typedef bool
     
    139139/*!
    140140@typedef JSObjectDeletePropertyCallback
    141 @abstract The callback invoked when deleting a given property.
     141@abstract The callback invoked when deleting a property.
    142142@param context The current execution context.
    143143@param object The JSObject in which to delete the property.
     
    149149bool DeleteProperty(JSContextRef context, JSObjectRef object, JSStringRef propertyName, JSValueRef* exception);
    150150
    151 If this function returns false, the delete request forwards to object's static property table, then its parent class chain (which includes the default object class).
     151If this function returns false, the delete request forwards to object's statically declared properties, then its parent class chain (which includes the default object class).
    152152*/
    153153typedef bool
     
    252252(*JSObjectConvertToTypeCallback) (JSContextRef context, JSObjectRef object, JSType type, JSValueRef* exception);
    253253
    254 /*!
    255 @struct JSObjectCallbacks
    256 @abstract This structure contains optional callbacks for supplementing default object behavior. Any callback field can be NULL.
     254/*!
     255@struct JSStaticValue
     256@abstract This structure describes a statically declared value property.
     257@field name A null-terminated UTF8 string containing the property's name.
     258@field getProperty A JSObjectGetPropertyCallback to invoke when getting the property's value.
     259@field setProperty A JSObjectSetPropertyCallback to invoke when setting the property's value.
     260@field attributes A logically ORed set of JSPropertyAttributes to give to the property.
     261*/
     262typedef struct {
     263    const char* const name; // FIXME: convert UTF8
     264    JSObjectGetPropertyCallback getProperty;
     265    JSObjectSetPropertyCallback setProperty;
     266    JSPropertyAttributes attributes;
     267} JSStaticValue;
     268
     269/*!
     270@struct JSStaticFunction
     271@abstract This structure describes a statically declared function property.
     272@field name A null-terminated UTF8 string containing the property's name.
     273@field callAsFunction A JSObjectCallAsFunctionCallback to invoke when the property is called as a function.
     274@field attributes A logically ORed set of JSPropertyAttributes to give to the property.
     275*/
     276typedef struct {
     277    const char* const name; // FIXME: convert UTF8
     278    JSObjectCallAsFunctionCallback callAsFunction;
     279    JSPropertyAttributes attributes;
     280} JSStaticFunction;
     281
     282/*!
     283@struct JSClassDefinition
     284@abstract This structure contains properties and callbacks that define a type of object. All fields are optional. Any field may be NULL.
    257285@field version The version number of this structure. The current version is 0.
    258 @field initialize The callback invoked when an object is first created. Use this callback in conjunction with JSObjectSetPrivate to initialize private data in your object.
    259 @field finalize The callback invoked when an object is finalized (prepared for garbage collection). Use this callback to release resources allocated for your object, and perform other cleanup.
    260 @field hasProperty The callback invoked when determining whether an object has a given property. If this field is NULL, getProperty will be called instead. The hasProperty callback enables optimization in cases where only a property's existence needs to be known, not its value, and computing its value would be expensive.
    261 @field getProperty The callback invoked when getting the value of a given property.
    262 @field setProperty The callback invoked when setting the value of a given property.
    263 @field deleteProperty The callback invoked when deleting a given property.
     286@field className A null-terminated UTF8 string containing the class's name.
     287@field parentClass A JSClass to set as the class's parent class. Pass NULL use the default object class.
     288@field staticValues A JSStaticValue array containing the class's statically declared value properties. Pass NULL to specify no statically declared value properties. The array must be terminated by a JSStaticValue whose name field is NULL.
     289@field staticFunctions A JSStaticFunction array containing the class's statically declared function properties. Pass NULL to specify no statically declared function properties. The array must be terminated by a JSStaticFunction whose name field is NULL.
     290@field initialize The callback invoked when an object is first created. Use this callback to initialize the object.
     291@field finalize The callback invoked when an object is finalized (prepared for garbage collection). Use this callback to release resources allocated for the object, and perform other cleanup.
     292@field hasProperty The callback invoked when determining whether an object has a property. If this field is NULL, getProperty is called instead. The hasProperty callback enables optimization in cases where only a property's existence needs to be known, not its value, and computing its value is expensive.
     293@field getProperty The callback invoked when getting a property's value.
     294@field setProperty The callback invoked when setting a property's value.
     295@field deleteProperty The callback invoked when deleting a property.
    264296@field addPropertiesToList The callback invoked when adding an object's properties to a property list.
    265297@field callAsFunction The callback invoked when an object is called as a function.
     
    267299@field callAsConstructor The callback invoked when an object is used as a constructor in a 'new' expression.
    268300@field convertToType The callback invoked when converting an object to a particular JavaScript type.
     301@discussion The staticValues and staticFunctions arrays are the simplest and most efficient means for vending custom properties. Statically declared properties autmatically service requests like get, set, and enumerate. Property access callbacks are required only to implement unusual properties, like array indexes, whose names are not known at compile-time.
     302
     303If you named your getter function "GetX" and your setter function "SetX", you would declare a JSStaticValue array containing "X" like this:
     304
     305JSStaticValue StaticValueArray[] = {
     306    { "X", GetX, SetX, kJSPropertyAttributeNone },
     307    { 0, 0, 0, 0 }
     308};
     309
     310Standard JavaScript practice calls for storing functions in prototype objects, so derived objects can share them. Therefore, it is common for prototype classes to have function properties but no value properties, and for object classes to have value properties but no function properties.
     311
     312A NULL callback specifies that the default object callback should substitute, except in the case of hasProperty, where it specifies that getProperty should substitute.
    269313*/
    270314typedef struct {
    271315    int                                 version; // current (and only) version is 0
     316
     317    const char*                         className;
     318    JSClassRef                          parentClass;
     319       
     320    JSStaticValue*                      staticValues;
     321    JSStaticFunction*                   staticFunctions;
     322   
    272323    JSObjectInitializeCallback          initialize;
    273324    JSObjectFinalizeCallback            finalize;
     
    281332    JSObjectHasInstanceCallback         hasInstance;
    282333    JSObjectConvertToTypeCallback       convertToType;
    283 } JSObjectCallbacks;
    284 
    285 /*!
    286 @const kJSObjectCallbacksNone
    287 @abstract A JSObjectCallbacks structure of the current version, filled with NULL callbacks.
    288 @discussion Use this constant as a convenience when creating callback structures. For example, to create a callback structure that has only a finalize method:
    289 
    290 JSObjectCallbacks callbacks = kJSObjectCallbacksNone;
    291 
    292 callbacks.finalize = Finalize;
    293 */
    294 extern const JSObjectCallbacks kJSObjectCallbacksNone;
    295 
    296 /*!
    297 @struct JSStaticValue
    298 @abstract This structure describes a static value property.
    299 @field name A null-terminated UTF8 string containing the property's name.
    300 @field getProperty A JSObjectGetPropertyCallback to invoke when getting the property's value.
    301 @field setProperty A JSObjectSetPropertyCallback to invoke when setting the property's value.
    302 @field attributes A logically ORed set of JSPropertyAttributes to give to the property.
    303 */
    304 typedef struct {
    305     const char* const name; // FIXME: convert UTF8
    306     JSObjectGetPropertyCallback getProperty;
    307     JSObjectSetPropertyCallback setProperty;
    308     JSPropertyAttributes attributes;
    309 } JSStaticValue;
    310 
    311 /*!
    312 @struct JSStaticFunction
    313 @abstract This structure describes a static function property.
    314 @field name A null-terminated UTF8 string containing the property's name.
    315 @field callAsFunction A JSObjectCallAsFunctionCallback to invoke when the property is called as a function.
    316 @field attributes A logically ORed set of JSPropertyAttributes to give to the property.
    317 */
    318 typedef struct {
    319     const char* const name; // FIXME: convert UTF8
    320     JSObjectCallAsFunctionCallback callAsFunction;
    321     JSPropertyAttributes attributes;
    322 } JSStaticFunction;
    323 
    324 /*!
    325 @function
    326 @abstract Creates a JavaScript class suitable for use with JSObjectMake
    327 @param staticValues A JSStaticValue array representing the class's static value properties. Pass NULL to specify no static value properties. The array must be terminated by a JSStaticValue whose name field is NULL.
    328 @param staticFunctions A JSStaticFunction array representing the class's static function properties. Pass NULL to specify no static function properties. The array must be terminated by a JSStaticFunction whose name field is NULL.
    329 @param callbacks A pointer to a JSObjectCallbacks structure holding custom callbacks for supplementing default object behavior. Pass NULL to specify no custom behavior.
    330 @param parentClass A JSClass to set as the class's parent class. Pass NULL use the default object class.
    331 @result A JSClass with the given properties, callbacks, and parent class. Ownership follows the Create Rule.
    332 @discussion The simplest and most efficient way to add custom properties to a class is by specifying static values and functions. Standard JavaScript practice calls for functions to be placed in prototype objects, so that they can be shared among objects.
    333 */
    334 JSClassRef JSClassCreate(JSStaticValue* staticValues, JSStaticFunction* staticFunctions, const JSObjectCallbacks* callbacks, JSClassRef parentClass);
     334} JSClassDefinition;
     335
     336/*!
     337@const kJSClassDefinitionNull
     338@abstract A JSClassDefinition structure of the current version, filled with NULL pointers.
     339@discussion Use this constant as a convenience when creating class definitions. For example, to create a class definition with only a finalize method:
     340
     341JSClassDefinition definition = kJSClassDefinitionNull;
     342
     343definition.finalize = Finalize;
     344*/
     345extern const JSClassDefinition kJSClassDefinitionNull;
     346
     347/*!
     348@function
     349@abstract Creates a JavaScript class suitable for use with JSObjectMake.
     350@param definition A JSClassDefinition that defines the class.
     351@result A JSClass with the given definition's name, properties, callbacks, and parent class. Ownership follows the Create Rule.
     352*/
     353JSClassRef JSClassCreate(JSClassDefinition* definition);
     354
    335355/*!
    336356@function
     
    404424/*!
    405425@function
    406 @abstract Tests whether an object has a certain property.
     426@abstract Tests whether an object has a given property.
    407427@param object The JSObject to test.
    408428@param propertyName A JSString containing the property's name.
     
    473493@param object A JSObject whose private data you want to get.
    474494@result A void* that points to the object's private data, if the object has private data, otherwise NULL.
    475 @discussion JSObjectGetPrivate and JSObjectSetPrivate only work on custom objects created by JSObjectMake, JSObjectMakeFunction, and JSObjectMakeConstructor.
     495@discussion JSObjectGetPrivate and JSObjectSetPrivate only work on objects created by JSObjectMake, JSObjectMakeFunction, and JSObjectMakeConstructor.
    476496*/
    477497void* JSObjectGetPrivate(JSObjectRef object);
     
    483503@param data A void* that points to the object's private data.
    484504@result true if the set operation succeeds, otherwise false.
    485 @discussion JSObjectGetPrivate and JSObjectSetPrivate only work on custom objects created by JSObjectMake, JSObjectMakeFunction, and JSObjectMakeConstructor.
     505@discussion JSObjectGetPrivate and JSObjectSetPrivate only work on objects created by JSObjectMake, JSObjectMakeFunction, and JSObjectMakeConstructor.
    486506*/
    487507bool JSObjectSetPrivate(JSObjectRef object, void* data);
     
    556576@function
    557577@abstract Adds a property to a property list.
    558 @discussion Use this method inside a JSObjectAddPropertiesToListCallback to add a custom property to an object's property list.
     578@discussion Use this method inside a JSObjectAddPropertiesToListCallback to add a property to an object's property list.
    559579@param propertyList The JSPropertyList to which you want to add a property.
    560580@param thisObject The JSObject to which the property belongs.
  • trunk/JavaScriptCore/API/testapi.c

    r15444 r15462  
    241241}
    242242
    243 JSObjectCallbacks MyObject_callbacks = {
     243JSClassDefinition MyObject_definition = {
    244244    0,
     245   
     246    "MyObject",
     247    NULL,
     248   
     249    NULL,
     250    NULL,
     251   
    245252    MyObject_initialize,
    246253    MyObject_finalize,
     
    259266{
    260267    static JSClassRef jsClass;
    261     if (!jsClass) {
    262         jsClass = JSClassCreate(NULL, NULL, &MyObject_callbacks, NULL);
    263     }
     268    if (!jsClass)
     269        jsClass = JSClassCreate(&MyObject_definition);
    264270   
    265271    return jsClass;
     
    561567    assert(count == 1); // jsCFString should not be enumerated
    562568
    563     JSClassRef nullCallbacksClass = JSClassCreate(NULL, NULL, NULL, NULL);
    564     JSClassRelease(nullCallbacksClass);
     569    JSClassDefinition nullDefinition = kJSClassDefinitionNull;
     570    JSClassRef nullClass = JSClassCreate(&nullDefinition);
     571    JSClassRelease(nullClass);
    565572   
    566573    functionBody = JSStringCreateWithUTF8CString("return this;");
  • trunk/JavaScriptCore/API/testapi.js

    r15443 r15462  
    7676shouldBe("MyObject ? 1 : 0", true); // toBoolean
    7777shouldBe("+MyObject", 1); // toNumber
    78 shouldBe("(MyObject.toString())", "[object CallbackObject]"); // toString
     78shouldBe("(MyObject.toString())", "[object MyObject]"); // toString
    7979shouldBe("MyObject - 0", NaN); // toPrimitive
    8080
  • trunk/JavaScriptCore/ChangeLog

    r15455 r15462  
     12006-07-15  Geoffrey Garen  <[email protected]>
     2
     3        Reviewed by Maciej.
     4
     5        - Moved the arguments passed to JSClassCreate into a single structure,
     6        called JSClassDefinition. This will enable easier structure
     7        migration/versioning in the future, if necessary.
     8       
     9        - Added support for class names.
     10       
     11        - kJSClassDefinitionNull replaces kJSObjectCallbacksNone.
     12       
     13        - JSClass is becoming a fairly complex struct, so I migrated all of its
     14        implementation other than reference counting to the sruct.
     15       
     16        - Also moved JSClass* functions in the API to JSObjectRef.cpp, since they're
     17        declared in JSObjectRef.h
     18       
     19        - Also added some more informative explanation to the class structure doc.
     20       
    1212006-07-15  Darin Adler  <[email protected]>
    222
  • trunk/JavaScriptCore/JavaScriptCore.exp

    r15437 r15462  
    261261__ZTVN3KJS19InternalFunctionImpE
    262262__ZTVN3KJS8JSObjectE
    263 _kJSObjectCallbacksNone
     263_kJSClassDefinitionNull
    264264_kjs_pcre_compile
    265265_kjs_pcre_exec
Note: See TracChangeset for help on using the changeset viewer.