diff options
Diffstat (limited to 'WebCore/bridge/objc')
-rw-r--r-- | WebCore/bridge/objc/objc_instance.h | 16 | ||||
-rw-r--r-- | WebCore/bridge/objc/objc_instance.mm | 38 | ||||
-rw-r--r-- | WebCore/bridge/objc/objc_runtime.h | 1 | ||||
-rw-r--r-- | WebCore/bridge/objc/objc_runtime.mm | 9 |
4 files changed, 49 insertions, 15 deletions
diff --git a/WebCore/bridge/objc/objc_instance.h b/WebCore/bridge/objc/objc_instance.h index 6f1eb0d..64cd491 100644 --- a/WebCore/bridge/objc/objc_instance.h +++ b/WebCore/bridge/objc/objc_instance.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003 Apple Computer, Inc. All rights reserved. + * Copyright (C) 2003, 2009 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -37,16 +37,12 @@ class ObjcClass; class ObjcInstance : public Instance { public: - static PassRefPtr<ObjcInstance> create(ObjectStructPtr instance, PassRefPtr<RootObject> rootObject) - { - return adoptRef(new ObjcInstance(instance, rootObject)); - } - + static PassRefPtr<ObjcInstance> create(ObjectStructPtr, PassRefPtr<RootObject>); + virtual ~ObjcInstance(); + static void setGlobalException(NSString*, JSGlobalObject* exceptionEnvironment = 0); // A null exceptionEnvironment means the exception should propogate to any execution environment. - ~ObjcInstance(); - - virtual Class *getClass() const; + virtual Class* getClass() const; virtual JSValue valueOf(ExecState*) const; virtual JSValue defaultValue(ExecState*, PreferredPrimitiveType) const; @@ -71,7 +67,7 @@ protected: private: static void moveGlobalExceptionToExecState(ExecState*); - ObjcInstance(ObjectStructPtr instance, PassRefPtr<RootObject>); + ObjcInstance(ObjectStructPtr, PassRefPtr<RootObject>); RetainPtr<ObjectStructPtr> _instance; mutable ObjcClass *_class; diff --git a/WebCore/bridge/objc/objc_instance.mm b/WebCore/bridge/objc/objc_instance.mm index b84f7bb..f7550e4 100644 --- a/WebCore/bridge/objc/objc_instance.mm +++ b/WebCore/bridge/objc/objc_instance.mm @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004, 2008 Apple Computer, Inc. All rights reserved. + * Copyright (C) 2004, 2008, 2009 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -44,8 +44,21 @@ using namespace JSC::Bindings; using namespace JSC; -static NSString* s_exception; +static NSString *s_exception; static JSGlobalObject* s_exceptionEnvironment; // No need to protect this value, since we just use it for a pointer comparison. +static NSMapTable *s_instanceWrapperCache; + +static NSMapTable *createInstanceWrapperCache() +{ +#ifdef BUILDING_ON_TIGER + return NSCreateMapTable(NSNonRetainedObjectMapKeyCallBacks, NSNonOwnedPointerMapValueCallBacks, 0); +#else + // NSMapTable with zeroing weak pointers is the recommended way to build caches like this under garbage collection. + NSPointerFunctionsOptions keyOptions = NSPointerFunctionsZeroingWeakMemory | NSPointerFunctionsObjectPersonality; + NSPointerFunctionsOptions valueOptions = NSPointerFunctionsOpaqueMemory | NSPointerFunctionsOpaquePersonality; + return [[NSMapTable alloc] initWithKeyOptions:keyOptions valueOptions:valueOptions capacity:0]; +#endif +} void ObjcInstance::setGlobalException(NSString* exception, JSGlobalObject* exceptionEnvironment) { @@ -74,7 +87,7 @@ void ObjcInstance::moveGlobalExceptionToExecState(ExecState* exec) s_exceptionEnvironment = 0; } -ObjcInstance::ObjcInstance(ObjectStructPtr instance, PassRefPtr<RootObject> rootObject) +ObjcInstance::ObjcInstance(id instance, PassRefPtr<RootObject> rootObject) : Instance(rootObject) , _instance(instance) , _class(0) @@ -83,13 +96,30 @@ ObjcInstance::ObjcInstance(ObjectStructPtr instance, PassRefPtr<RootObject> root { } +PassRefPtr<ObjcInstance> ObjcInstance::create(id instance, PassRefPtr<RootObject> rootObject) +{ + if (!s_instanceWrapperCache) + s_instanceWrapperCache = createInstanceWrapperCache(); + if (void* existingWrapper = NSMapGet(s_instanceWrapperCache, instance)) + return static_cast<ObjcInstance*>(existingWrapper); + RefPtr<ObjcInstance> wrapper = adoptRef(new ObjcInstance(instance, rootObject)); + NSMapInsert(s_instanceWrapperCache, instance, wrapper.get()); + return wrapper.release(); +} + ObjcInstance::~ObjcInstance() { - // -finalizeForWebScript and -dealloc/-finalize may require autorelease pools. + // Both -finalizeForWebScript and -dealloc/-finalize of _instance may require autorelease pools. NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; + + ASSERT(s_instanceWrapperCache); + ASSERT(_instance); + NSMapRemove(s_instanceWrapperCache, _instance.get()); + if ([_instance.get() respondsToSelector:@selector(finalizeForWebScript)]) [_instance.get() performSelector:@selector(finalizeForWebScript)]; _instance = 0; + [pool drain]; } diff --git a/WebCore/bridge/objc/objc_runtime.h b/WebCore/bridge/objc/objc_runtime.h index 82d563b..7c772a6 100644 --- a/WebCore/bridge/objc/objc_runtime.h +++ b/WebCore/bridge/objc/objc_runtime.h @@ -109,6 +109,7 @@ public: private: virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&); + virtual bool getOwnPropertyDescriptor(ExecState*, const Identifier&, PropertyDescriptor&); virtual void put(ExecState*, const Identifier& propertyName, JSValue, PutPropertySlot&); virtual CallType getCallData(CallData&); virtual bool deleteProperty(ExecState*, const Identifier& propertyName); diff --git a/WebCore/bridge/objc/objc_runtime.mm b/WebCore/bridge/objc/objc_runtime.mm index 2d69c1c..5efc865 100644 --- a/WebCore/bridge/objc/objc_runtime.mm +++ b/WebCore/bridge/objc/objc_runtime.mm @@ -203,13 +203,20 @@ bool ObjcFallbackObjectImp::getOwnPropertySlot(ExecState*, const Identifier&, Pr return true; } +bool ObjcFallbackObjectImp::getOwnPropertyDescriptor(ExecState*, const Identifier&, PropertyDescriptor& descriptor) +{ + // keep the prototype from getting called instead of just returning false + descriptor.setUndefined(); + return true; +} + void ObjcFallbackObjectImp::put(ExecState*, const Identifier&, JSValue, PutPropertySlot&) { } static JSValue JSC_HOST_CALL callObjCFallbackObject(ExecState* exec, JSObject* function, JSValue thisValue, const ArgList& args) { - if (!thisValue.isObject(&RuntimeObjectImp::s_info)) + if (!thisValue.inherits(&RuntimeObjectImp::s_info)) return throwError(exec, TypeError); JSValue result = jsUndefined(); |