Ignore:
Timestamp:
Jul 17, 2006, 9:33:46 PM (19 years ago)
Author:
ggaren
Message:

Reviewed by Maciej.


  • Added automatic prototype creation for classes.


A class stores a weak reference to a prototype, which is cleared when
the prototype is garbage collected, to avoid a reference cycle.


We now have an attributes field in JSClassDefinition, that currently is
used only to override automatic prototype creation when you want to manage your
own prototypes, but can be extended in the future for other nefarious purposes.


Similarly, we have JSObjectMake and JSObjectMakeWithPrototype, the latter
allowing you to manage your own prototypes.


JSObjectMakeConstructor is more interesting now, able to make a constructor
on your behalf if you just give it a class.


  • Removed bogus old code from minidom.js.


  • Tweaked the headerdocs.


  • Added more GC testing, which caught some leaks, and tested more funny edge cases in lookup, which caught a lookup bug. Removed some testing we used to do with MyObject because it was redundant with the new, cool stuff.


While fixing the lookup bug I retracted this change:


"If a static setProperty callback returns 'false', to indicate that the
property was not set, we no longer forward the set request up the class
chain, because that's almost certainly not what the programmer expected."

Returning false when setting a static property is a little silly, but you can see
it being useful when shadowing a base class's static properties, and, regardless
of usefullness, this is the defined behavior of the setProperty callback.


  • Plus a little ASCII art, for the kids.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/API/JSObjectRef.h

    r15486 r15497  
    5858typedef unsigned JSPropertyAttributes;
    5959
     60/*!
     61@enum JSClassAttribute
     62@constant kJSClassAttributeNone Specifies that a class has no special attributes.
     63@constant kJSClassAttributeNoPrototype Specifies that a class should not generate a prototype object. Use kJSClassAttributeNoPrototype in combination with JSObjectMakeWithPrototype to manage prototypes manually.
     64*/
     65enum {
     66    kJSClassAttributeNone = 0,
     67    kJSClassAttributeNoPrototype = 1 << 1
     68};
     69
     70/*!
     71@typedef JSClassAttributes
     72@abstract A set of JSClassAttributes. Combine multiple attributes by logically ORing them together.
     73*/
     74typedef unsigned JSClassAttributes;
     75
    6076/*!
    6177@typedef JSObjectInitializeCallback
     
    161177/*!
    162178@typedef JSObjectGetPropertyNamesCallback
    163 @abstract The callback invoked to get the names of an object's properties.
    164 @param ctx The execution context to use.
    165 @param object The JSObject whose property names need to be appended to propertyNames.
    166 @param accumulator A JavaScript property name accumulator, to which the object should add the names of its properties.
     179@abstract The callback invoked when collecting the names of an object's properties.
     180@param ctx The execution context to use.
     181@param object The JSObject whose property names are being collected.
     182@param accumulator A JavaScript property name accumulator in which to accumulate the names of object's properties.
    167183@discussion If you named your function GetPropertyNames, you would declare it like this:
    168184
    169185void GetPropertyNames(JSContextRef ctx, JSObjectRef object, JSPropertyNameAccumulatorRef accumulator);
    170186
    171 Use JSPropertyNameAccumulatorAddName to add property names to accumulator.
    172 
    173 Property lists are used by JSPropertyEnumerators and JavaScript for...in loops.
    174 
    175 It's only necessary to add names of properties that you handle
    176 specially in your own get / set callbacks. Static property names,
    177 names of standard JS properties, and properties from the prototype
    178 will be added automatically.
     187Property name accumulators are used by JSObjectCopyPropertyNames and JavaScript for...in loops.
     188
     189Use JSPropertyNameAccumulatorAddName to add property names to accumulator. A class's getPropertyNames callback only needs to provide the names of properties that the class vends through a custom getProperty or setProperty callback. Other properties, including statically declared properties, properties vended by other classes, and properties belonging to object's prototype, are added independently.
    179190*/
    180191typedef void
     
    195206JSValueRef CallAsFunction(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception);
    196207
    197 If your callback were invoked by the JavaScript expression 'myObject.myMemberFunction()', function would be set to myMemberFunction, and thisObject would be set to myObject.
     208If your callback were invoked by the JavaScript expression 'myObject.myFunction()', function would be set to myFunction, and thisObject would be set to myObject.
    198209
    199210If this callback is NULL, calling your object as a function will throw an exception.
     
    215226JSObjectRef CallAsConstructor(JSContextRef ctx, JSObjectRef constructor, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception);
    216227
    217 If your callback were invoked by the JavaScript expression 'new myConstructorFunction()', constructor would be set to myConstructorFunction.
     228If your callback were invoked by the JavaScript expression 'new myConstructor()', constructor would be set to myConstructor.
    218229
    219230If this callback is NULL, using your object as a constructor in a 'new' expression will throw an exception.
     
    292303/*!
    293304@struct JSClassDefinition
    294 @abstract This structure contains properties and callbacks that define a type of object. All fields are optional. Any field may be NULL.
     305@abstract This structure contains properties and callbacks that define a type of object. All fields other than the version field are optional. Any pointer may be NULL.
    295306@field version The version number of this structure. The current version is 0.
     307@field attributes A logically ORed set of JSClassAttributes to give to the class.
    296308@field className A null-terminated UTF8 string containing the class's name.
    297309@field parentClass A JSClass to set as the class's parent class. Pass NULL use the default object class.
     
    304316@field setProperty The callback invoked when setting a property's value.
    305317@field deleteProperty The callback invoked when deleting a property.
    306 @field addPropertiesToList The callback invoked when adding an object's properties to a property list.
     318@field getPropertyNames The callback invoked when collecting the names of an object's properties.
    307319@field callAsFunction The callback invoked when an object is called as a function.
    308320@field hasInstance The callback invoked when an object is used as the target of an 'instanceof' expression.
    309321@field callAsConstructor The callback invoked when an object is used as a constructor in a 'new' expression.
    310322@field convertToType The callback invoked when converting an object to a particular JavaScript type.
    311 @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.
     323@discussion The staticValues and staticFunctions arrays are the simplest and most efficient means for vending custom properties. Statically declared properties autmatically service requests like getProperty, setProperty, and getPropertyNames. Property access callbacks are required only to implement unusual properties, like array indexes, whose names are not known at compile-time.
    312324
    313325If you named your getter function "GetX" and your setter function "SetX", you would declare a JSStaticValue array containing "X" like this:
     
    318330};
    319331
    320 Standard 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.
     332Standard JavaScript practice calls for storing functions in prototype objects, so derived objects can share them. Therefore, it is common for prototypes to have function properties but no value properties, and for objects to have value properties but no function properties. The default behavior of JSClassCreate is to follow this idiom, automatically generating a prototype in which to store the class's function properties. The kJSClassAttributeNoPrototype attribute overrides the idiom, specifying that all supplied function and value properties should be stored directly in the object.
    321333
    322334A NULL callback specifies that the default object callback should substitute, except in the case of hasProperty, where it specifies that getProperty should substitute.
     
    324336typedef struct {
    325337    int                                 version; // current (and only) version is 0
     338    JSClassAttributes                   attributes;
    326339
    327340    const char*                         className;
     
    345358
    346359/*!
    347 @const kJSClassDefinitionNull
    348 @abstract A JSClassDefinition structure of the current version, filled with NULL pointers.
     360@const kJSClassDefinitionEmpty
     361@abstract A JSClassDefinition structure of the current version, filled with NULL pointers and having no attributes.
    349362@discussion Use this constant as a convenience when creating class definitions. For example, to create a class definition with only a finalize method:
    350363
    351 JSClassDefinition definition = kJSClassDefinitionNull;
     364JSClassDefinition definition = kJSClassDefinitionEmpty;
    352365
    353366definition.finalize = Finalize;
    354367*/
    355 extern const JSClassDefinition kJSClassDefinitionNull;
     368extern const JSClassDefinition kJSClassDefinitionEmpty;
    356369
    357370/*!
     
    359372@abstract Creates a JavaScript class suitable for use with JSObjectMake.
    360373@param definition A JSClassDefinition that defines the class.
    361 @result A JSClass with the given definition's name, properties, callbacks, and parent class. Ownership follows the Create Rule.
     374@result A JSClass with the given definition. Ownership follows the Create Rule.
    362375*/
    363376JSClassRef JSClassCreate(JSClassDefinition* definition);
     
    370383*/
    371384JSClassRef JSClassRetain(JSClassRef jsClass);
     385
    372386/*!
    373387@function
     
    382396@param ctx The execution context to use.
    383397@param jsClass The JSClass to assign to the object. Pass NULL to use the default object class.
    384 @param prototype The prototype to assign to the object. Pass NULL to use the default object prototype.
    385 @result A JSObject with the given class, prototype, and private data.
    386 @discussion The default object class does not allocate storage for private data, so you must provide a non-NULL JSClass if you want your object to be able to store private data.
    387 */
    388 JSObjectRef JSObjectMake(JSContextRef ctx, JSClassRef jsClass, JSValueRef prototype);
    389 
    390 /*!
    391 @function
    392 @abstract Creates a JavaScript object.
     398@param data A void* to set as the object's private data. Pass NULL to specify no private data.
     399@result A JSObject with the given class and private data.
     400@discussion JSObjectMake assigns jsClass's automatically generated prototype to the object it creates. If jsClass has no automatically generated prototype, JSObjectMake uses the default object prototype.
     401
     402data is set on the created object before the intialize methods in its class chain are called. This enables the initialize methods to retrieve and manipulate data through JSObjectGetPrivate.
     403
     404The default object class does not allocate storage for private data, so you must provide a non-NULL jsClass if you want your object to be able to store private data.
     405*/
     406JSObjectRef JSObjectMake(JSContextRef ctx, JSClassRef jsClass, void* data);
     407
     408/*!
     409@function
     410@abstract Creates a JavaScript object with a given prototype.
    393411@param ctx The execution context to use.
    394412@param jsClass The JSClass to assign to the object. Pass NULL to use the default object class.
    395413@param prototype The prototype to assign to the object. Pass NULL to use the default object prototype.
    396414@param data A void* to set as the object's private data. Pass NULL to specify no private data.
    397 @param exception A pointer to a JSValueRef in which to store an exception, if any. Pass NULL if you do not care to store an exception.
    398 @result A JSObject with the given class, prototype, and private data.
    399 @discussion The default object class does not allocate storage for private data, so you must provide a non-NULL JSClass if you want your object to be able to store private data.
     415@result A JSObject with the given class, private data, and prototype.
     416@discussion Use JSObjectMakeWithPrototype in combination with kJSClassAttributeNoPrototype to manage prototypes manually.
    400417 
    401 data will be set on the created object before the intialize methods in its class chain are called. This enables the initialize methods to retrieve and manipulate data through JSObjectGetPrivate.
    402 */
    403 JSObjectRef JSObjectMakeWithData(JSContextRef ctx, JSClassRef jsClass, JSValueRef prototype, void* data);
     418data is set on the created object before the intialize methods in its class chain are called. This enables the initialize methods to retrieve and manipulate data through JSObjectGetPrivate.
     419
     420The default object class does not allocate storage for private data, so you must provide a non-NULL JSClass if you want your object to be able to store private data.
     421*/
     422JSObjectRef JSObjectMakeWithPrototype(JSContextRef ctx, JSClassRef jsClass, void* data, JSValueRef prototype);
    404423
    405424/*!
     
    415434/*!
    416435@function
    417 @abstract Convenience method for creating a JavaScript constructor with a given callback as its implementation.
    418 @param ctx The execution context to use.
    419 @param prototype A JSValue to use as the constructor's .prototype property. This should be the same value your constructor will set as the prototype of the objects it constructs.
    420 @param callAsConstructor The JSObjectCallAsConstructorCallback to invoke when the constructor is used in a 'new' expression.
     436@abstract Convenience method for creating a JavaScript constructor.
     437@param ctx The execution context to use.
     438@param jsClass A JSClass that is the class your constructor will assign to the objects its constructs. jsClass will be used to set the constructor's .prototype property, and to evaluate 'instanceof' expressions. Pass NULL to use the default object class.
     439@param callAsConstructor A JSObjectCallAsConstructorCallback to invoke when your constructor is used in a 'new' expression. Pass NULL to use the default object constructor.
    421440@result A JSObject that is a constructor. The object's prototype will be the default object prototype.
    422 */
    423 JSObjectRef JSObjectMakeConstructorWithCallback(JSContextRef ctx, JSValueRef prototype, JSObjectCallAsConstructorCallback callAsConstructor);
     441@discussion The default object constructor takes no arguments and constructs an object of class jsClass with no private data.
     442*/
     443JSObjectRef JSObjectMakeConstructor(JSContextRef ctx, JSClassRef jsClass, JSObjectCallAsConstructorCallback callAsConstructor);
    424444
    425445/*!
     
    444464@param ctx  The execution context to use.
    445465@param object A JSObject whose prototype you want to get.
    446 @result A JSValue containing the object's prototype.
     466@result A JSValue that is the object's prototype.
    447467*/
    448468JSValueRef JSObjectGetPrototype(JSContextRef ctx, JSObjectRef object);
     
    505525@param ctx The execution context to use.
    506526@param object The JSObject whose property you want to get.
    507 @param propertyIndex The property's name as a number.
     527@param propertyIndex An integer value that is the property's name.
    508528@param exception A pointer to a JSValueRef in which to store an exception, if any. Pass NULL if you do not care to store an exception.
    509529@result The property's value if object has the property, otherwise the undefined value.
    510 @discussion Calling JSObjectGetPropertyAtIndex is equivalent to calling JSObjectGetProperty with a string containing propertyIndex, but it enables optimized access to JavaScript arrays.
     530@discussion Calling JSObjectGetPropertyAtIndex is equivalent to calling JSObjectGetProperty with a string containing propertyIndex, but JSObjectGetPropertyAtIndex provides optimized access to numeric properties.
    511531*/
    512532JSValueRef JSObjectGetPropertyAtIndex(JSContextRef ctx, JSObjectRef object, unsigned propertyIndex, JSValueRef* exception);
     
    520540@param value A JSValue to use as the property's value.
    521541@param exception A pointer to a JSValueRef in which to store an exception, if any. Pass NULL if you do not care to store an exception.
    522 @discussion Calling JSObjectSetPropertyAtIndex is equivalent to calling JSObjectSetProperty with a string containing propertyIndex, but it enables optimized access to JavaScript arrays.
     542@discussion Calling JSObjectSetPropertyAtIndex is equivalent to calling JSObjectSetProperty with a string containing propertyIndex, but JSObjectSetPropertyAtIndex provides optimized access to numeric properties.
    523543*/
    524544void JSObjectSetPropertyAtIndex(JSContextRef ctx, JSObjectRef object, unsigned propertyIndex, JSValueRef value, JSValueRef* exception);
     
    535555@function
    536556@abstract Sets a pointer to private data on an object.
    537 @param object A JSObject whose private data you want to set.
     557@param object The JSObject whose private data you want to set.
    538558@param data A void* to set as the object's private data.
    539 @result true if the object can store private data, otherwise false.
     559@result true if object can store private data, otherwise false.
    540560@discussion The default object class does not allocate storage for private data. Only objects created with a non-NULL JSClass can store private data.
    541561*/
     
    558578@param thisObject The object to use as "this," or NULL to use the global object as "this."
    559579@param argumentCount An integer count of the number of arguments in arguments.
    560 @param arguments A JSValue array of the  arguments to pass to the function. Pass NULL if argumentCount is 0.
     580@param arguments A JSValue array of arguments to pass to the function. Pass NULL if argumentCount is 0.
    561581@param exception A pointer to a JSValueRef in which to store an exception, if any. Pass NULL if you do not care to store an exception.
    562582@result The JSValue that results from calling object as a function, or NULL if an exception is thrown or object is not a function.
     
    579599@param object The JSObject to call as a constructor.
    580600@param argumentCount An integer count of the number of arguments in arguments.
    581 @param arguments A JSValue array of the  arguments to pass to the function. Pass NULL if argumentCount is 0.
     601@param arguments A JSValue array of arguments to pass to the constructor. Pass NULL if argumentCount is 0.
    582602@param exception A pointer to a JSValueRef in which to store an exception, if any. Pass NULL if you do not care to store an exception.
    583603@result The JSObject that results from calling object as a constructor, or NULL if an exception is thrown or object is not a constructor.
     
    587607/*!
    588608@function
    589 @abstract Get the names of all enumerable properties of an object.
    590 @param ctx The execution context to use.
    591 @param object The object from which to get property names.
    592 @result A JSPropertyNameArray containing the names of all the object's enumerable properties.
     609@abstract Gets the names of an object's enumerable properties.
     610@param ctx The execution context to use.
     611@param object The object whose property names you want to get.
     612@result A JSPropertyNameArray containing the names object's enumerable properties.
    593613*/
    594614JSPropertyNameArrayRef JSObjectCopyPropertyNames(JSContextRef ctx, JSObjectRef object);
     
    611631/*!
    612632@function
    613 @abstract Get the number of items in a JavaScript property name array.
     633@abstract Gets a count of the number of items in a JavaScript property name array.
    614634@param array The array from which to retrieve the count.
    615 @result The count of items in the array.
     635@result An integer count of the number of names in array.
    616636*/
    617637size_t JSPropertyNameArrayGetCount(JSPropertyNameArrayRef array);
     
    619639/*!
    620640@function
    621 @abstract Get a single item from a JavaScript property name array.
    622 @param array The array from which to retrieve a property name.
     641@abstract Gets a property name at a given index in a JavaScript property name array.
     642@param array The array from which to retrieve the property name.
    623643@param index The index of the property name to retrieve.
    624 @result A JSStringRef containing the name of the property.
     644@result A JSStringRef containing the property name.
    625645*/
    626646JSStringRef JSPropertyNameArrayGetNameAtIndex(JSPropertyNameArrayRef array, size_t index);
     
    628648/*!
    629649@function
    630 @abstract Add a property name - useful while getting the property names for an object.
    631 @param accumulator The accumulator object to which to add the property.
    632 @param propertyName The new property to add.
     650@abstract Adds a property name to a JavaScript property name accumulator.
     651@param accumulator The accumulator object to which to add the property name.
     652@param propertyName The property name to add.
    633653*/
    634654void JSPropertyNameAccumulatorAddName(JSPropertyNameAccumulatorRef accumulator, JSStringRef propertyName);
Note: See TracChangeset for help on using the changeset viewer.