Changeset 15484 in webkit for trunk/JavaScriptCore/API


Ignore:
Timestamp:
Jul 17, 2006, 3:49:28 AM (19 years ago)
Author:
ggaren
Message:

Reviewed by Maciej.


  • Removed the exception parameter from the initialize callback and, by extension, JSObjectMake. We have never had a need for exceptions when iniitializing, so the parameter seemed likely to "get in the way."


Also, an exception in JavaScript is thrown in response to input --
"invalid URL", "index not a number", etc., so it's the job of the
constructor function, not the initialize method, to throw.


If initialize *really* wants to throw, it can communicate the throw to
the constructor through the constructed object's private data (e.g., set
it to NULL, signaling to the consntructor that initialization failed.)


  • Added JSObjectMakeWithData, which enables a constructor to set private data on an object *before* it has been initialized. That way, the initialize methods can properly operate on the data.
  • API/JSNode.c: Moved ref into the initialize method, for better encapsulation, now that it's possible.
  • API/JSNodeList.c: ditto
  • API/minidom.c: (main): Do more aggressive garbage collection to test ref/deref and initialize/finalize.
  • API/minidom.js: store childNodes in a temporary so it doesn't get re-created like a thousand times. This makes debugging ref/deref easier
Location:
trunk/JavaScriptCore/API
Files:
10 edited

Legend:

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

    r15483 r15484  
    3838const ClassInfo JSCallbackObject::info = { "CallbackObject", 0, 0, 0 };
    3939
    40 JSCallbackObject::JSCallbackObject(ExecState* exec, JSClassRef jsClass)
    41     : JSObject()
    42 {
    43     init(exec, jsClass);
    44 }
    45 
    46 JSCallbackObject::JSCallbackObject(ExecState* exec, JSClassRef jsClass, JSValue* prototype)
     40JSCallbackObject::JSCallbackObject(ExecState* exec, JSClassRef jsClass, JSValue* prototype, void* data)
    4741    : JSObject(prototype)
    4842{
    49     init(exec, jsClass);
    50 }
    51 
    52 void JSCallbackObject::init(ExecState* exec, JSClassRef jsClass)
    53 {
    54     m_privateData = 0;
     43    init(exec, jsClass, data);
     44}
     45
     46void JSCallbackObject::init(ExecState* exec, JSClassRef jsClass, void* data)
     47{
     48    m_privateData = data;
    5549    m_class = JSClassRetain(jsClass);
    5650
     
    6458    for (int i = initRoutines.size() - 1; i >= 0; i--) {
    6559        JSObjectInitializeCallback initialize = initRoutines[i];
    66         initialize(toRef(exec), toRef(this), toRef(exec->exceptionSlot()));
     60        initialize(toRef(exec), toRef(this));
    6761    }
    6862}
  • trunk/JavaScriptCore/API/JSCallbackObject.h

    r15483 r15484  
    3737{
    3838public:
    39     JSCallbackObject(ExecState*, JSClassRef);
    40     JSCallbackObject(ExecState*, JSClassRef, JSValue* prototype);
     39    JSCallbackObject(ExecState*, JSClassRef, JSValue* prototype, void* data);
    4140    virtual ~JSCallbackObject();
    4241       
     
    7877    JSCallbackObject(const JSCallbackObject&);
    7978
    80     void init(ExecState*, JSClassRef);
     79    void init(ExecState*, JSClassRef jsClass, void*);
    8180   
    8281    static JSValue* cachedValueGetter(ExecState*, JSObject*, const Identifier&, const PropertySlot&);
  • trunk/JavaScriptCore/API/JSContextRef.cpp

    r15481 r15484  
    4242    if (globalObjectClass)
    4343        // FIXME: We need to pass a real ExecState here to support an initialize callback in globalObjectClass
    44         globalObject = new JSCallbackObject(0, globalObjectClass);
     44        globalObject = new JSCallbackObject(0, globalObjectClass, 0, 0);
    4545    else
    4646        globalObject = new JSObject();
  • trunk/JavaScriptCore/API/JSNode.c

    r15483 r15484  
    157157};
    158158
     159static void JSNode_initialize(JSContextRef context, JSObjectRef object)
     160{
     161    Node* node = JSObjectGetPrivate(object);
     162    assert(node);
     163
     164    Node_ref(node);
     165}
     166
    159167static void JSNode_finalize(JSObjectRef object)
    160168{
     
    171179        JSClassDefinition definition = kJSClassDefinitionNull;
    172180        definition.staticValues = JSNode_staticValues;
     181        definition.initialize = JSNode_initialize;
    173182        definition.finalize = JSNode_finalize;
    174183
     
    182191    static JSObjectRef prototype;
    183192    if (!prototype) {
    184         prototype = JSObjectMake(context, JSNodePrototype_class(context), NULL, NULL);
     193        prototype = JSObjectMake(context, JSNodePrototype_class(context), NULL);
    185194        JSValueProtect(context, prototype);
    186195    }
     
    190199JSObjectRef JSNode_new(JSContextRef context, Node* node)
    191200{
    192     Node_ref(node);
    193 
    194     JSObjectRef jsNode = JSObjectMake(context, JSNode_class(context), JSNode_prototype(context), NULL);
    195     JSObjectSetPrivate(jsNode, node);
    196     return jsNode;
     201    return JSObjectMakeWithData(context, JSNode_class(context), JSNode_prototype(context), node);
    197202}
    198203
  • trunk/JavaScriptCore/API/JSNodeList.c

    r15483 r15484  
    8989}
    9090
     91static void JSNodeList_initialize(JSContextRef context, JSObjectRef thisObject)
     92{
     93    NodeList* nodeList = JSObjectGetPrivate(thisObject);
     94    assert(nodeList);
     95   
     96    NodeList_ref(nodeList);
     97}
     98
    9199static void JSNodeList_finalize(JSObjectRef thisObject)
    92100{
    93101    NodeList* nodeList = JSObjectGetPrivate(thisObject);
    94102    assert(nodeList);
     103
    95104    NodeList_deref(nodeList);
    96105}
     
    103112        definition.staticValues = JSNodeList_staticValues;
    104113        definition.getProperty = JSNodeList_getProperty;
     114        definition.initialize = JSNodeList_initialize;
    105115        definition.finalize = JSNodeList_finalize;
    106116
     
    115125    static JSObjectRef prototype;
    116126    if (!prototype) {
    117         prototype = JSObjectMake(context, JSNodeListPrototype_class(context), NULL, NULL);
     127        prototype = JSObjectMake(context, JSNodeListPrototype_class(context), NULL);
    118128        JSValueProtect(context, prototype);
    119129    }
     
    123133JSObjectRef JSNodeList_new(JSContextRef context, NodeList* nodeList)
    124134{
    125     NodeList_ref(nodeList);
    126    
    127     JSObjectRef jsNodeList = JSObjectMake(context, JSNodeList_class(context), JSNodeList_prototype(context), NULL);
    128     JSObjectSetPrivate(jsNodeList, nodeList);
    129     return jsNodeList;
     135    return JSObjectMakeWithData(context, JSNodeList_class(context), JSNodeList_prototype(context), nodeList);
    130136}
  • trunk/JavaScriptCore/API/JSObjectRef.cpp

    r15483 r15484  
    6060}
    6161
    62 JSObjectRef JSObjectMake(JSContextRef ctx, JSClassRef jsClass, JSValueRef prototype, JSValueRef* exception)
     62JSObjectRef JSObjectMake(JSContextRef ctx, JSClassRef jsClass, JSValueRef prototype)
     63{
     64    return JSObjectMakeWithData(ctx, jsClass, prototype, 0);
     65}
     66
     67JSObjectRef JSObjectMakeWithData(JSContextRef ctx, JSClassRef jsClass, JSValueRef prototype, void* data)
    6368{
    6469    JSLock lock;
     
    7075        jsPrototype = exec->lexicalInterpreter()->builtinObjectPrototype();
    7176
    72     JSObjectRef result;
    73     if (jsClass) {
    74         result = toRef(new JSCallbackObject(exec, jsClass, jsPrototype));
    75         if (exec->hadException()) {
    76             if (exception)
    77                 *exception = toRef(exec->exception());
    78             exec->clearException();
    79         }
    80     } else
    81         result = toRef(new JSObject(jsPrototype)); // slightly more efficient -- and can't throw
    82        
    83     return result;
     77    if (!jsClass)
     78        return toRef(new JSObject(jsPrototype)); // slightly more efficient
     79   
     80    return toRef(new JSCallbackObject(exec, jsClass, jsPrototype, data)); // initialize can't throw
    8481}
    8582
  • trunk/JavaScriptCore/API/JSObjectRef.h

    r15483 r15484  
    6363@param ctx The execution context to use.
    6464@param object The JSObject being created.
    65 @param exception A pointer to a JSValueRef in which to return an exception, if any.
    6665@discussion If you named your function Initialize, you would declare it like this:
    6766
    68 void Initialize(JSContextRef ctx, JSObjectRef object, JSValueRef* exception);
     67void Initialize(JSContextRef ctx, JSObjectRef object);
    6968
    7069Unlike the other object callbacks, the initialize callback is called on the least
     
    7271*/
    7372typedef void
    74 (*JSObjectInitializeCallback) (JSContextRef ctx, JSObjectRef object, JSValueRef* exception);
     73(*JSObjectInitializeCallback) (JSContextRef ctx, JSObjectRef object);
    7574
    7675/*!
     
    380379/*!
    381380@function
    382 @abstract Creates a JavaScript object with a given class and prototype.
     381@abstract Creates a JavaScript object.
    383382@param ctx The execution context to use.
    384383@param jsClass The JSClass to assign to the object. Pass NULL to use the default object class.
    385384@param prototype The prototype to assign to the object. Pass NULL to use the default object prototype.
    386 @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.
    387 @result A JSObject with the given class and prototype.
    388 */
    389 JSObjectRef JSObjectMake(JSContextRef ctx, JSClassRef jsClass, JSValueRef prototype, JSValueRef* exception);
     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*/
     388JSObjectRef JSObjectMake(JSContextRef ctx, JSClassRef jsClass, JSValueRef prototype);
     389
     390/*!
     391@function
     392@abstract Creates a JavaScript object.
     393@param ctx The execution context to use.
     394@param jsClass The JSClass to assign to the object. Pass NULL to use the default object class.
     395@param prototype The prototype to assign to the object. Pass NULL to use the default object prototype.
     396@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.
     400 
     401data 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*/
     403JSObjectRef JSObjectMakeWithData(JSContextRef ctx, JSClassRef jsClass, JSValueRef prototype, void* data);
    390404
    391405/*!
     
    512526/*!
    513527@function
    514 @abstract Gets a pointer to private data from an object.
     528@abstract Gets an object's private data.
    515529@param object A JSObject whose private data you want to get.
    516 @result A void* that points to the object's private data, if the object has private data, otherwise NULL.
     530@result A void* that is the object's private data, if the object has private data, otherwise NULL.
    517531*/
    518532void* JSObjectGetPrivate(JSObjectRef object);
     
    522536@abstract Sets a pointer to private data on an object.
    523537@param object A JSObject whose private data you want to set.
    524 @param data A void* that points to the object's private data.
     538@param data A void* to set as the object's private data.
    525539@result true if the object can store private data, otherwise false.
    526 @discussion Only custom objects created with a JSClass can store private data.
     540@discussion The default object class does not allocate storage for private data. Only objects created with a non-NULL JSClass can store private data.
    527541*/
    528542bool JSObjectSetPrivate(JSObjectRef object, void* data);
  • trunk/JavaScriptCore/API/minidom.c

    r15482 r15484  
    6565    free(scriptUTF8);
    6666
    67 #if 0 // used for leak/finalize debugging   
    68     int i;
    69     for (i = 0; i < 1000; i++) {
    70         JSObjectRef o = JSObjectMake(context, NULL, NULL);
    71         (void)o;
    72     }
    73     JSGarbageCollect();
    74 #endif
    75    
     67    globalObject = 0;
    7668    JSGlobalContextRelease(context);
     69    JSGarbageCollect(context);
    7770    printf("PASS: Program exited normally.\n");
    7871    return 0;
  • trunk/JavaScriptCore/API/minidom.js

    r15482 r15484  
    199199    node.appendChild(child2);
    200200
    201     for (var i = 0; i < node.childNodes.length + 1; i++) {
    202         print("item " + i + ": " + node.childNodes.item(i));
    203     }
    204    
    205     for (var i = 0; i < node.childNodes.length + 1; i++) {
    206         print(i + ": " + node.childNodes[i]);
     201    var childNodes = node.childNodes;
     202   
     203    for (var i = 0; i < childNodes.length + 1; i++) {
     204        print("item " + i + ": " + childNodes.item(i));
     205    }
     206   
     207    for (var i = 0; i < childNodes.length + 1; i++) {
     208        print(i + ": " + childNodes[i]);
    207209    }
    208210
     
    210212    node.replaceChild(child3, child2);
    211213   
    212     for (var i = 0; i < node.childNodes.length + 1; i++) {
    213         print("item " + i + ": " + node.childNodes.item(i));
    214     }
    215 
    216     for (var i = 0; i < node.childNodes.length + 1; i++) {
    217         print(i + ": " + node.childNodes[i]);
     214    for (var i = 0; i < childNodes.length + 1; i++) {
     215        print("item " + i + ": " + childNodes.item(i));
     216    }
     217
     218    for (var i = 0; i < childNodes.length + 1; i++) {
     219        print(i + ": " + childNodes[i]);
    218220    }
    219221
  • trunk/JavaScriptCore/API/testapi.c

    r15483 r15484  
    101101
    102102static bool didInitialize = false;
    103 static void MyObject_initialize(JSContextRef context, JSObjectRef object, JSValueRef* exception)
     103static void MyObject_initialize(JSContextRef context, JSObjectRef object)
    104104{
    105105    UNUSED_PARAM(context);
     
    291291}
    292292
    293 static void Base_initialize(JSContextRef context, JSObjectRef object, JSValueRef* exception)
     293static void Base_initialize(JSContextRef context, JSObjectRef object)
    294294{
    295295    assert(!JSObjectGetPrivate(object));
     
    316316}
    317317
    318 static void Derived_initialize(JSContextRef context, JSObjectRef object, JSValueRef* exception)
     318static void Derived_initialize(JSContextRef context, JSObjectRef object)
    319319{
    320320    assert((void*)1 == JSObjectGetPrivate(object));
     
    362362    UNUSED_PARAM(constructorObject);
    363363   
    364     JSObjectRef result = JSObjectMake(context, NULL, 0, NULL);
     364    JSObjectRef result = JSObjectMake(context, NULL, NULL);
    365365    if (argumentCount > 0) {
    366366        JSStringRef value = JSStringCreateWithUTF8CString("value");
     
    391391    JSValueRef jsOne = JSValueMakeNumber(context, 1);
    392392    JSValueRef jsOneThird = JSValueMakeNumber(context, 1.0 / 3.0);
    393     JSObjectRef jsObjectNoProto = JSObjectMake(context, NULL, JSValueMakeNull(context), NULL);
     393    JSObjectRef jsObjectNoProto = JSObjectMake(context, NULL, JSValueMakeNull(context));
    394394
    395395    // FIXME: test funny utf8 characters
     
    445445#endif // __APPLE__
    446446
    447     JSObjectRef myObject = JSObjectMake(context, MyObject_class(context), NULL, NULL);
     447    JSObjectRef myObject = JSObjectMake(context, MyObject_class(context), NULL);
    448448    assert(didInitialize);
    449449    JSStringRef myObjectIString = JSStringCreateWithUTF8CString("MyObject");
     
    559559#endif // __APPLE__
    560560   
    561     jsGlobalValue = JSObjectMake(context, NULL, NULL, NULL);
     561    jsGlobalValue = JSObjectMake(context, NULL, NULL);
    562562    JSValueProtect(context, jsGlobalValue);
    563563    JSGarbageCollect(context);
     
    667667    assert(!JSObjectGetPrivate(myConstructor));
    668668   
    669     o = JSObjectMake(context, NULL, NULL, NULL);
     669    o = JSObjectMake(context, NULL, NULL);
    670670    JSObjectSetProperty(context, o, jsOneIString, JSValueMakeNumber(context, 1), kJSPropertyAttributeNone, NULL);
    671671    JSObjectSetProperty(context, o, jsCFIString,  JSValueMakeNumber(context, 1), kJSPropertyAttributeDontEnum, NULL);
     
    690690    assert(JSValueIsEqual(context, v, o, NULL));
    691691   
    692     exception = NULL;
    693     o = JSObjectMake(context, Derived_class(context), NULL, &exception);
    694     assert(!exception);
     692    o = JSObjectMake(context, Derived_class(context), NULL);
    695693    assert(JSObjectGetPrivate(o) == (void*)2);
    696694    o = NULL;
     
    713711
    714712    // Allocate a few dummies so that at least one will be collected
    715     JSObjectMake(context, MyObject_class(context), NULL, NULL);
    716     JSObjectMake(context, MyObject_class(context), NULL, NULL);
     713    JSObjectMake(context, MyObject_class(context), NULL);
     714    JSObjectMake(context, MyObject_class(context), NULL);
    717715    JSGarbageCollect(context);
    718716    assert(MyObject_didFinalize);
Note: See TracChangeset for help on using the changeset viewer.