summaryrefslogtreecommitdiffstats
path: root/WebCore/bridge/objc
diff options
context:
space:
mode:
Diffstat (limited to 'WebCore/bridge/objc')
-rw-r--r--WebCore/bridge/objc/objc_instance.h16
-rw-r--r--WebCore/bridge/objc/objc_instance.mm38
-rw-r--r--WebCore/bridge/objc/objc_runtime.h1
-rw-r--r--WebCore/bridge/objc/objc_runtime.mm9
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();