Changeset 53657 in webkit for trunk/JavaScriptCore/API


Ignore:
Timestamp:
Jan 21, 2010, 4:06:00 PM (15 years ago)
Author:
[email protected]
Message:

2010-01-21 Geoffrey Garen <[email protected]>

Reviewed by Oliver Hunt.

Always create a prototype for automatically managed classes.


This fixes some errors where prototype chains were not correctly hooked
up, and also ensures that API classes work correctly with features like
instanceof.

  • API/JSClassRef.cpp: (OpaqueJSClass::create): Cleaned up some of this code. Also changed it to always create a prototype class.
  • API/tests/testapi.c: (Derived2_class): (main): Fixed a null value crash in the exception checking code.
  • API/tests/testapi.js: Added some tests for the case where a prototype chain would not be hooked up correctly.
Location:
trunk/JavaScriptCore/API
Files:
3 edited

Legend:

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

    r53642 r53657  
    3535#include <runtime/Identifier.h>
    3636
     37using namespace std;
    3738using namespace JSC;
    3839
     
    121122}
    122123
    123 PassRefPtr<OpaqueJSClass> OpaqueJSClass::create(const JSClassDefinition* definition)
    124 {
    125     const JSStaticFunction* staticFunctions = definition->staticFunctions;
    126     if (staticFunctions || definition->parentClass) {
    127         // copy functions into a prototype class
    128         JSClassDefinition protoDefinition = kJSClassDefinitionEmpty;
    129         protoDefinition.staticFunctions = staticFunctions;
    130         protoDefinition.finalize = clearReferenceToPrototype;
    131        
    132         // We are supposed to use JSClassRetain/Release but since we know that we currently have
    133         // the only reference to this class object we cheat and use a RefPtr instead.
    134         RefPtr<OpaqueJSClass> protoClass = adoptRef(new OpaqueJSClass(&protoDefinition, 0));
    135 
    136         // remove functions from the original class
    137         JSClassDefinition objectDefinition = *definition;
    138         objectDefinition.staticFunctions = 0;
    139 
    140         return adoptRef(new OpaqueJSClass(&objectDefinition, protoClass.get()));
    141     }
    142 
    143     return adoptRef(new OpaqueJSClass(definition, 0));
     124PassRefPtr<OpaqueJSClass> OpaqueJSClass::create(const JSClassDefinition* clientDefinition)
     125{
     126    JSClassDefinition definition = *clientDefinition; // Avoid modifying client copy.
     127
     128    JSClassDefinition protoDefinition = kJSClassDefinitionEmpty;
     129    protoDefinition.finalize = clearReferenceToPrototype;
     130    swap(definition.staticFunctions, protoDefinition.staticFunctions); // Move static functions to the prototype.
     131   
     132    // We are supposed to use JSClassRetain/Release but since we know that we currently have
     133    // the only reference to this class object we cheat and use a RefPtr instead.
     134    RefPtr<OpaqueJSClass> protoClass = adoptRef(new OpaqueJSClass(&protoDefinition, 0));
     135    return adoptRef(new OpaqueJSClass(&definition, protoClass.get()));
    144136}
    145137
  • trunk/JavaScriptCore/API/tests/testapi.c

    r51068 r53657  
    624624}
    625625
     626static JSClassRef Derived2_class(JSContextRef context)
     627{
     628    static JSClassRef jsClass;
     629    if (!jsClass) {
     630        JSClassDefinition definition = kJSClassDefinitionEmpty;
     631        definition.parentClass = Derived_class(context);
     632        jsClass = JSClassCreate(&definition);
     633    }
     634    return jsClass;
     635}
     636
    626637static JSValueRef print_callAsFunction(JSContextRef ctx, JSObjectRef functionObject, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
    627638{
     
    10711082    ASSERT(!JSObjectGetPrivate(myConstructor));
    10721083   
     1084    string = JSStringCreateWithUTF8CString("Base");
     1085    JSObjectRef baseConstructor = JSObjectMakeConstructor(context, Base_class(context), NULL);
     1086    JSObjectSetProperty(context, globalObject, string, baseConstructor, kJSPropertyAttributeNone, NULL);
     1087    JSStringRelease(string);
     1088   
    10731089    string = JSStringCreateWithUTF8CString("Derived");
    10741090    JSObjectRef derivedConstructor = JSObjectMakeConstructor(context, Derived_class(context), NULL);
     
    10761092    JSStringRelease(string);
    10771093   
     1094    string = JSStringCreateWithUTF8CString("Derived2");
     1095    JSObjectRef derived2Constructor = JSObjectMakeConstructor(context, Derived2_class(context), NULL);
     1096    JSObjectSetProperty(context, globalObject, string, derived2Constructor, kJSPropertyAttributeNone, NULL);
     1097    JSStringRelease(string);
     1098
    10781099    o = JSObjectMake(context, NULL, NULL);
    10791100    JSObjectSetProperty(context, o, jsOneIString, JSValueMakeNumber(context, 1), kJSPropertyAttributeNone, NULL);
     
    11741195        script = JSStringCreateWithUTF8CString(scriptUTF8);
    11751196        result = JSEvaluateScript(context, script, NULL, NULL, 1, &exception);
    1176         if (JSValueIsUndefined(context, result))
     1197        if (result && JSValueIsUndefined(context, result))
    11771198            printf("PASS: Test script executed successfully.\n");
    11781199        else {
  • trunk/JavaScriptCore/API/tests/testapi.js

    r53638 r53657  
    170170derived = new Derived();
    171171
     172shouldBe("derived instanceof Derived", true);
     173shouldBe("derived instanceof Base", true);
     174
    172175// base properties and functions return 1 when called/gotten; derived, 2
    173176shouldBe("derived.baseProtoDup()", 2);
     
    184187shouldBe("derived.derivedOnly = 0", 2)
    185188shouldBe("derived.protoDup = 0", 2);
     189
     190derived2 = new Derived2();
     191
     192shouldBe("derived2 instanceof Derived2", true);
     193shouldBe("derived2 instanceof Derived", true);
     194shouldBe("derived2 instanceof Base", true);
     195
     196// base properties and functions return 1 when called/gotten; derived, 2
     197shouldBe("derived2.baseProtoDup()", 2);
     198shouldBe("derived2.baseProto()", 1);
     199shouldBe("derived2.baseDup", 2);
     200shouldBe("derived2.baseOnly", 1);
     201shouldBe("derived2.protoOnly()", 2);
     202shouldBe("derived2.protoDup", 2);
     203shouldBe("derived2.derivedOnly", 2)
     204
     205// base properties throw 1 when set; derived, 2
     206shouldBe("derived2.baseDup = 0", 2);
     207shouldBe("derived2.baseOnly = 0", 1);
     208shouldBe("derived2.derivedOnly = 0", 2)
     209shouldBe("derived2.protoDup = 0", 2);
    186210
    187211shouldBe('Object.getOwnPropertyDescriptor(derived, "baseProto")', undefined);
Note: See TracChangeset for help on using the changeset viewer.