Changeset 54783 in webkit
- Timestamp:
- Feb 15, 2010, 11:16:21 AM (15 years ago)
- Location:
- trunk
- Files:
-
- 3 added
- 13 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r54780 r54783 1 2010-02-12 Alexey Proskuryakov <ap@apple.com> 2 3 Reviewed by Kevin Decker. 4 5 <rdar://problem/7130641> Browser objects identity is not preserved by Safari 6 7 * plugins/netscape-browser-object-identity-expected.txt: Added. 8 * plugins/netscape-browser-object-identity.html: Added. 9 * plugins/script-tests/netscape-browser-object-identity.js: Added. 10 1 11 2010-02-15 Pavel Feldman <pfeldman@chromium.org> 2 12 -
trunk/WebCore/ChangeLog
r54782 r54783 1 2010-02-12 Alexey Proskuryakov <ap@apple.com> 2 3 Reviewed by Kevin Decker. 4 5 <rdar://problem/7130641> Browser objects identity is not preserved by Safari 6 7 Test: plugins/netscape-browser-object-identity.html 8 9 * bridge/runtime_root.h: (JSC::Bindings::RootObject::addInvalidationCallback): 10 RootObject can now call out during invalidation, making it possible for other code to know 11 when this happens. 12 13 * bridge/runtime_root.cpp: 14 (JSC::Bindings::RootObject::InvalidationCallback::~InvalidationCallback): Empty destructor, 15 in cpp file since it's virtual. 16 (JSC::Bindings::RootObject::invalidate): Invoke invalidation callbacks. 17 18 * bridge/NP_jsobject.cpp: 19 (ObjectMap): Keep a JSObject->NPObject map for each RootObject. It somewhat cleaner to 20 keep it outside RootObject, because (1) it is agnostic of what kinds of objects can wrap 21 JSObject, and (2) out of process NPAPI implementation also keeps its corresponding map 22 separately, due to supporting per-instance granularity (as opposed to per-RootObject here). 23 (jsDeallocate): Remove the corresponding map entry. 24 (_NPN_CreateScriptObject): Try to fetch existing object from the map, incrementing refcount. 25 1 26 2010-02-15 Philippe Normand <pnormand@igalia.com> 2 27 -
trunk/WebCore/bridge/NP_jsobject.cpp
r54614 r54783 52 52 using namespace WebCore; 53 53 54 class ObjectMap { 55 public: 56 NPObject* get(RootObject* rootObject, JSObject* jsObject) 57 { 58 return m_map.get(rootObject).get(jsObject); 59 } 60 61 void add(RootObject* rootObject, JSObject* jsObject, NPObject* npObject) 62 { 63 HashMap<RootObject*, JSToNPObjectMap>::iterator iter = m_map.find(rootObject); 64 if (iter == m_map.end()) { 65 rootObject->addInvalidationCallback(&m_invalidationCallback); 66 iter = m_map.add(rootObject, JSToNPObjectMap()).first; 67 } 68 69 ASSERT(iter->second.find(jsObject) == iter->second.end()); 70 iter->second.add(jsObject, npObject); 71 } 72 73 void remove(RootObject* rootObject) 74 { 75 HashMap<RootObject*, JSToNPObjectMap>::iterator iter = m_map.find(rootObject); 76 ASSERT(iter != m_map.end()); 77 m_map.remove(iter); 78 } 79 80 void remove(RootObject* rootObject, JSObject* jsObject) 81 { 82 HashMap<RootObject*, JSToNPObjectMap>::iterator iter = m_map.find(rootObject); 83 ASSERT(iter != m_map.end()); 84 ASSERT(iter->second.find(jsObject) != iter->second.end()); 85 86 iter->second.remove(jsObject); 87 } 88 89 private: 90 struct RootObjectInvalidationCallback : public RootObject::InvalidationCallback { 91 virtual void operator()(RootObject*); 92 }; 93 RootObjectInvalidationCallback m_invalidationCallback; 94 95 // JSObjects are protected by RootObject. 96 typedef HashMap<JSObject*, NPObject*> JSToNPObjectMap; 97 HashMap<RootObject*, JSToNPObjectMap> m_map; 98 }; 99 100 101 static ObjectMap& objectMap() 102 { 103 DEFINE_STATIC_LOCAL(ObjectMap, map, ()); 104 return map; 105 } 106 107 void ObjectMap::RootObjectInvalidationCallback::operator()(RootObject* rootObject) 108 { 109 objectMap().remove(rootObject); 110 } 111 54 112 static void getListFromVariantArgs(ExecState* exec, const NPVariant* args, unsigned argCount, RootObject* rootObject, MarkedArgumentBuffer& aList) 55 113 { … … 67 125 JavaScriptObject* obj = reinterpret_cast<JavaScriptObject*>(npObj); 68 126 69 if (obj->rootObject && obj->rootObject->isValid()) 127 if (obj->rootObject && obj->rootObject->isValid()) { 128 objectMap().remove(obj->rootObject, obj->imp); 70 129 obj->rootObject->gcUnprotect(obj->imp); 130 } 71 131 72 132 if (obj->rootObject) … … 84 144 NPObject* _NPN_CreateScriptObject(NPP npp, JSObject* imp, PassRefPtr<RootObject> rootObject) 85 145 { 146 if (NPObject* object = objectMap().get(rootObject.get(), imp)) 147 return _NPN_RetainObject(object); 148 86 149 JavaScriptObject* obj = reinterpret_cast<JavaScriptObject*>(_NPN_CreateObject(npp, NPScriptObjectClass)); 87 150 88 151 obj->rootObject = rootObject.releaseRef(); 89 152 90 if (obj->rootObject) 153 if (obj->rootObject) { 91 154 obj->rootObject->gcProtect(imp); 155 objectMap().add(obj->rootObject, imp, reinterpret_cast<NPObject*>(obj)); 156 } 157 92 158 obj->imp = imp; 93 159 -
trunk/WebCore/bridge/runtime_root.cpp
r53464 r54783 72 72 } 73 73 74 RootObject::InvalidationCallback::~InvalidationCallback() 75 { 76 } 77 74 78 PassRefPtr<RootObject> RootObject::create(const void* nativeHandle, JSGlobalObject* globalObject) 75 79 { … … 109 113 m_nativeHandle = 0; 110 114 m_globalObject = 0; 115 116 { 117 HashSet<InvalidationCallback*>::iterator end = m_invalidationCallbacks.end(); 118 for (HashSet<InvalidationCallback*>::iterator iter = m_invalidationCallbacks.begin(); iter != end; ++iter) 119 (**iter)(this); 120 121 m_invalidationCallbacks.clear(); 122 } 111 123 112 124 ProtectCountSet::iterator end = m_protectCountSet.end(); -
trunk/WebCore/bridge/runtime_root.h
r49754 r54783 73 73 void addRuntimeObject(RuntimeObjectImp*); 74 74 void removeRuntimeObject(RuntimeObjectImp*); 75 76 struct InvalidationCallback { 77 virtual void operator()(RootObject*) = 0; 78 virtual ~InvalidationCallback(); 79 }; 80 void addInvalidationCallback(InvalidationCallback* callback) { m_invalidationCallbacks.add(callback); } 81 75 82 private: 76 83 RootObject(const void* nativeHandle, JSGlobalObject*); … … 80 87 const void* m_nativeHandle; 81 88 ProtectedPtr<JSGlobalObject> m_globalObject; 89 82 90 ProtectCountSet m_protectCountSet; 91 HashSet<RuntimeObjectImp*> m_runtimeObjects; 83 92 84 HashSet< RuntimeObjectImp*> m_runtimeObjects;93 HashSet<InvalidationCallback*> m_invalidationCallbacks; 85 94 }; 86 95 -
trunk/WebKit/mac/ChangeLog
r54733 r54783 1 2010-02-12 Alexey Proskuryakov <ap@apple.com> 2 3 Reviewed by Kevin Decker. 4 5 <rdar://problem/7130641> Browser objects identity is not preserved by Safari 6 7 Out of process part. 8 9 To avoid excessive IPC, plugin process doesn't send each NPObject release/retain call to 10 Safari. It only sends one when the last one is removed, and it can destroy the proxy 11 NPObject. 12 13 However, the browser may be sending the same object out to plug-in as a function call 14 argument at the same time - neither side can know what the other one is up to. The solution 15 is to make the "destroying object" call return a boolean result, making it possible for 16 the browser to make plugin host keep the proxy with zero refcount for a little longer. 17 18 * Plugins/Hosted/NetscapePluginHostProxy.mm: 19 (WKPCForgetBrowserObject): This function (that used to be named ReleaseObject) is only 20 called when plug-in releases all of its references, so renamed it. Its boolean result 21 is returned as call success or failure. 22 23 * Plugins/Hosted/NetscapePluginInstanceProxy.h: 24 (WebKit::NetscapePluginInstanceProxy::LocalObjectMap): Made the numeric ID to JSObject map 25 two-way. 26 27 * Plugins/Hosted/NetscapePluginInstanceProxy.mm: 28 (WebKit::NetscapePluginInstanceProxy::LocalObjectMap::idForObject): This method is tricky 29 in that it creates objects with refcount of 1, but doesn't increase refcount when returning 30 found objects. This extra count accounts for the "reference" kept by plugin process. 31 (WebKit::NetscapePluginInstanceProxy::LocalObjectMap::retain): Only retaining for the 32 duration of calls out to plug-in, which means that refcount is almost always equal to 1. 33 Note that we can't use "++" here, due to how std::pair works! 34 (WebKit::NetscapePluginInstanceProxy::LocalObjectMap::release): Ditto. 35 (WebKit::NetscapePluginInstanceProxy::LocalObjectMap::clear): Clear all references when 36 stopping plug-in. 37 (WebKit::NetscapePluginInstanceProxy::LocalObjectMap::forget): Like release(), but only 38 functional when recount is 1 (meaning that the object is not being sent out to plug-in at 39 the moment). 40 (WebKit::NetscapePluginInstanceProxy::NetscapePluginInstanceProxy): Updated for other changes. 41 (WebKit::NetscapePluginInstanceProxy::cleanup): Ditto. 42 (WebKit::NetscapePluginInstanceProxy::getWindowNPObject): Ditto. 43 (WebKit::NetscapePluginInstanceProxy::getPluginElementNPObject): Ditto. 44 (WebKit::NetscapePluginInstanceProxy::forgetBrowserObjectID): Ditto. 45 (WebKit::NetscapePluginInstanceProxy::evaluate): Ditto. 46 (WebKit::NetscapePluginInstanceProxy::invoke): Ditto. 47 (WebKit::NetscapePluginInstanceProxy::invokeDefault): Ditto. 48 (WebKit::NetscapePluginInstanceProxy::construct): Ditto. 49 (WebKit::NetscapePluginInstanceProxy::getProperty): Ditto. 50 (WebKit::NetscapePluginInstanceProxy::setProperty): Ditto. 51 (WebKit::NetscapePluginInstanceProxy::removeProperty): Ditto. 52 (WebKit::NetscapePluginInstanceProxy::hasProperty): Ditto. 53 (WebKit::NetscapePluginInstanceProxy::hasMethod): Ditto. 54 (WebKit::NetscapePluginInstanceProxy::enumerate): Ditto. 55 (WebKit::NetscapePluginInstanceProxy::addValueToArray): Ditto. 56 (WebKit::NetscapePluginInstanceProxy::demarshalValueFromArray): Ditto. 57 (WebKit::NetscapePluginInstanceProxy::retainLocalObject): Helper for calling retain when 58 making calls out to plug-in. No-op for objects that aren't wrapped to be sent (i.e. for 59 objects wrapping ProxyInstance wrappers for plug-in objects being sent bak). 60 (WebKit::NetscapePluginInstanceProxy::releaseLocalObject): Ditto. 61 62 * Plugins/Hosted/ProxyInstance.mm: 63 (WebKit::ProxyInstance::invoke): Retain/release arguments during call. 64 (WebKit::ProxyInstance::setFieldValue): Ditto. 65 66 * Plugins/Hosted/WebKitPluginClient.defs: Renamed PCReleaseObject to PCForgetBrowserObject. 67 1 68 2010-02-12 Darin Adler <darin@apple.com> 2 69 -
trunk/WebKit/mac/Plugins/Hosted/NetscapePluginHostProxy.mm
r54516 r54783 547 547 } 548 548 549 kern_return_t WKPCReleaseObject(mach_port_t clientPort, uint32_t pluginID, uint32_t objectID) 550 { 551 NetscapePluginHostProxy* hostProxy = pluginProxyMap().get(clientPort); 552 if (!hostProxy) 553 return KERN_FAILURE; 554 555 NetscapePluginInstanceProxy* instanceProxy = hostProxy->pluginInstance(pluginID); 556 if (!instanceProxy) 557 return KERN_FAILURE; 558 559 instanceProxy->releaseObject(objectID); 560 return KERN_SUCCESS; 549 kern_return_t WKPCForgetBrowserObject(mach_port_t clientPort, uint32_t pluginID, uint32_t objectID) 550 { 551 NetscapePluginHostProxy* hostProxy = pluginProxyMap().get(clientPort); 552 if (!hostProxy) 553 return KERN_FAILURE; 554 555 NetscapePluginInstanceProxy* instanceProxy = hostProxy->pluginInstance(pluginID); 556 if (!instanceProxy) 557 return KERN_FAILURE; 558 559 return instanceProxy->forgetBrowserObjectID(objectID) ? KERN_SUCCESS : KERN_FAILURE; 561 560 } 562 561 -
trunk/WebKit/mac/Plugins/Hosted/NetscapePluginInstanceProxy.h
r54504 r54783 112 112 bool getWindowNPObject(uint32_t& objectID); 113 113 bool getPluginElementNPObject(uint32_t& objectID); 114 void releaseObject(uint32_t objectID);115 114 bool forgetBrowserObjectID(uint32_t objectID); // Will fail if the ID is being sent to plug-in right now (i.e., retain/release calls aren't balanced). 115 116 116 bool evaluate(uint32_t objectID, const WebCore::String& script, data_t& resultData, mach_msg_type_number_t& resultLength, bool allowPopups); 117 117 bool invoke(uint32_t objectID, const JSC::Identifier& methodName, data_t argumentsData, mach_msg_type_number_t argumentsLength, data_t& resultData, mach_msg_type_number_t& resultLength); … … 144 144 PassRefPtr<JSC::Bindings::Instance> createBindingsInstance(PassRefPtr<JSC::Bindings::RootObject>); 145 145 RetainPtr<NSData *> marshalValues(JSC::ExecState*, const JSC::ArgList& args); 146 void marshalValue(JSC::ExecState*, JSC::JSValue value, data_t& resultData, mach_msg_type_number_t& resultLength);146 void marshalValue(JSC::ExecState*, JSC::JSValue, data_t& resultData, mach_msg_type_number_t& resultLength); 147 147 JSC::JSValue demarshalValue(JSC::ExecState*, const char* valueData, mach_msg_type_number_t valueLength); 148 149 // No-op if the value does not contain a local object. 150 void retainLocalObject(JSC::JSValue); 151 void releaseLocalObject(JSC::JSValue); 148 152 149 153 void addInstance(ProxyInstance*); … … 301 305 302 306 // NPRuntime 303 uint32_t idForObject(JSC::JSObject*); 304 307 305 308 void addValueToArray(NSMutableArray *, JSC::ExecState* exec, JSC::JSValue value); 306 309 … … 308 311 void demarshalValues(JSC::ExecState*, data_t valuesData, mach_msg_type_number_t valuesLength, JSC::MarkedArgumentBuffer& result); 309 312 310 uint32_t m_objectIDCounter; 311 typedef HashMap<uint32_t, JSC::ProtectedPtr<JSC::JSObject> > ObjectMap; 312 ObjectMap m_objects; 313 313 class LocalObjectMap { 314 public: 315 LocalObjectMap(); 316 uint32_t idForObject(JSC::JSObject*); 317 void retain(JSC::JSObject*); 318 void release(JSC::JSObject*); 319 void clear(); 320 bool forget(uint32_t); 321 bool contains(uint32_t objectID) const { return m_idToJSObjectMap.contains(objectID); } 322 JSC::JSObject* get(uint32_t objectID) const { return m_idToJSObjectMap.get(objectID); } 323 324 private: 325 HashMap<uint32_t, JSC::ProtectedPtr<JSC::JSObject> > m_idToJSObjectMap; 326 // The pair consists of object ID and a reference count. One reference belongs to remote plug-in, 327 // and the proxy will add transient references for arguments that are being sent out. 328 HashMap<JSC::JSObject*, pair<uint32_t, uint32_t> > m_jsObjectToIDMap; 329 uint32_t m_objectIDCounter; 330 }; 331 332 LocalObjectMap m_localObjects; 333 314 334 typedef HashSet<ProxyInstance*> ProxyInstanceSet; 315 335 ProxyInstanceSet m_instances; -
trunk/WebKit/mac/Plugins/Hosted/NetscapePluginInstanceProxy.mm
r54504 r54783 101 101 }; 102 102 103 NetscapePluginInstanceProxy::LocalObjectMap::LocalObjectMap() 104 : m_objectIDCounter(0) 105 { 106 } 107 108 uint32_t NetscapePluginInstanceProxy::LocalObjectMap::idForObject(JSObject* object) 109 { 110 // This method creates objects with refcount of 1, but doesn't increase refcount when returning 111 // found objects. This extra count accounts for the main "reference" kept by plugin process. 112 113 // To avoid excessive IPC, plugin process doesn't send each NPObject release/retain call to 114 // Safari. It only sends one when the last reference is removed, and it can destroy the proxy 115 // NPObject. 116 117 // However, the browser may be sending the same object out to plug-in as a function call 118 // argument at the same time - neither side can know what the other one is doing. So, 119 // is to make PCForgetBrowserObject call return a boolean result, making it possible for 120 // the browser to make plugin host keep the proxy with zero refcount for a little longer. 121 122 uint32_t objectID = 0; 123 124 HashMap<JSC::JSObject*, pair<uint32_t, uint32_t> >::iterator iter = m_jsObjectToIDMap.find(object); 125 if (iter != m_jsObjectToIDMap.end()) 126 return iter->second.first; 127 128 do { 129 objectID = ++m_objectIDCounter; 130 } while (!m_objectIDCounter || m_objectIDCounter == static_cast<uint32_t>(-1) || m_idToJSObjectMap.contains(objectID)); 131 132 m_idToJSObjectMap.set(objectID, object); 133 m_jsObjectToIDMap.set(object, make_pair<uint32_t, uint32_t>(objectID, 1)); 134 135 return objectID; 136 } 137 138 void NetscapePluginInstanceProxy::LocalObjectMap::retain(JSC::JSObject* object) 139 { 140 HashMap<JSC::JSObject*, pair<uint32_t, uint32_t> >::iterator iter = m_jsObjectToIDMap.find(object); 141 ASSERT(iter != m_jsObjectToIDMap.end()); 142 143 iter->second.second = iter->second.second + 1; 144 } 145 146 void NetscapePluginInstanceProxy::LocalObjectMap::release(JSC::JSObject* object) 147 { 148 HashMap<JSC::JSObject*, pair<uint32_t, uint32_t> >::iterator iter = m_jsObjectToIDMap.find(object); 149 ASSERT(iter != m_jsObjectToIDMap.end()); 150 151 ASSERT(iter->second.second > 0); 152 iter->second.second = iter->second.second - 1; 153 if (!iter->second.second) { 154 m_idToJSObjectMap.remove(iter->second.first); 155 m_jsObjectToIDMap.remove(iter); 156 } 157 } 158 159 void NetscapePluginInstanceProxy::LocalObjectMap::clear() 160 { 161 m_idToJSObjectMap.clear(); 162 m_jsObjectToIDMap.clear(); 163 } 164 165 bool NetscapePluginInstanceProxy::LocalObjectMap::forget(uint32_t objectID) 166 { 167 HashMap<uint32_t, JSC::ProtectedPtr<JSC::JSObject> >::iterator iter = m_idToJSObjectMap.find(objectID); 168 ASSERT(iter != m_idToJSObjectMap.end()); 169 170 HashMap<JSC::JSObject*, pair<uint32_t, uint32_t> >::iterator rIter = m_jsObjectToIDMap.find(iter->second.get()); 171 172 // If the object is being sent to plug-in right now, then it's not the time to forget. 173 if (rIter->second.second != 1) 174 return false; 175 176 m_jsObjectToIDMap.remove(rIter); 177 m_idToJSObjectMap.remove(iter); 178 return true; 179 } 180 103 181 static uint32_t pluginIDCounter; 104 182 … … 115 193 , m_useSoftwareRenderer(false) 116 194 , m_waitingForReply(false) 117 , m_objectIDCounter(0)118 195 , m_urlCheckCounter(0) 119 196 , m_pluginFunctionCallDepth(0) … … 186 263 // Clear the object map, this will cause any outstanding JS objects that the plug-in had a reference to 187 264 // to go away when the next garbage collection takes place. 188 m_ objects.clear();265 m_localObjects.clear(); 189 266 190 267 if (Frame* frame = core([m_pluginView webFrame])) … … 684 761 } 685 762 686 uint32_t NetscapePluginInstanceProxy::idForObject(JSObject* object)687 {688 uint32_t objectID = 0;689 690 // Assign an object ID.691 do {692 objectID = ++m_objectIDCounter;693 } while (!m_objectIDCounter || m_objectIDCounter == static_cast<uint32_t>(-1) || m_objects.contains(objectID));694 695 m_objects.set(objectID, object);696 697 return objectID;698 }699 700 763 // NPRuntime support 701 764 bool NetscapePluginInstanceProxy::getWindowNPObject(uint32_t& objectID) … … 708 771 objectID = 0; 709 772 else 710 objectID = idForObject(frame->script()->windowShell(pluginWorld())->window());773 objectID = m_localObjects.idForObject(frame->script()->windowShell(pluginWorld())->window()); 711 774 712 775 return true; … … 720 783 721 784 if (JSObject* object = frame->script()->jsObjectForPluginElement([m_pluginView element])) 722 objectID = idForObject(object);785 objectID = m_localObjects.idForObject(object); 723 786 else 724 787 objectID = 0; … … 727 790 } 728 791 729 void NetscapePluginInstanceProxy::releaseObject(uint32_t objectID)730 { 731 m_objects.remove(objectID);792 bool NetscapePluginInstanceProxy::forgetBrowserObjectID(uint32_t objectID) 793 { 794 return m_localObjects.forget(objectID); 732 795 } 733 796 … … 737 800 resultLength = 0; 738 801 739 if (!m_ objects.contains(objectID))802 if (!m_localObjects.contains(objectID)) 740 803 return false; 741 804 … … 779 842 return false; 780 843 781 JSObject* object = m_ objects.get(objectID);844 JSObject* object = m_localObjects.get(objectID); 782 845 if (!object) 783 846 return false; … … 813 876 return false; 814 877 815 JSObject* object = m_ objects.get(objectID);878 JSObject* object = m_localObjects.get(objectID); 816 879 if (!object) 817 880 return false; … … 846 909 return false; 847 910 848 JSObject* object = m_ objects.get(objectID);911 JSObject* object = m_localObjects.get(objectID); 849 912 if (!object) 850 913 return false; … … 880 943 return false; 881 944 882 JSObject* object = m_ objects.get(objectID);945 JSObject* object = m_localObjects.get(objectID); 883 946 if (!object) 884 947 return false; … … 899 962 bool NetscapePluginInstanceProxy::getProperty(uint32_t objectID, unsigned propertyName, data_t& resultData, mach_msg_type_number_t& resultLength) 900 963 { 901 JSObject* object = m_ objects.get(objectID);964 JSObject* object = m_localObjects.get(objectID); 902 965 if (!object) 903 966 return false; … … 921 984 return false; 922 985 923 JSObject* object = m_ objects.get(objectID);986 JSObject* object = m_localObjects.get(objectID); 924 987 if (!object) 925 988 return false; … … 945 1008 return false; 946 1009 947 JSObject* object = m_ objects.get(objectID);1010 JSObject* object = m_localObjects.get(objectID); 948 1011 if (!object) 949 1012 return false; … … 968 1031 return false; 969 1032 970 JSObject* object = m_ objects.get(objectID);1033 JSObject* object = m_localObjects.get(objectID); 971 1034 if (!object) 972 1035 return false; … … 993 1056 return false; 994 1057 995 JSObject* object = m_ objects.get(objectID);1058 JSObject* object = m_localObjects.get(objectID); 996 1059 if (!object) 997 1060 return false; … … 1018 1081 return false; 1019 1082 1020 JSObject* object = m_ objects.get(objectID);1083 JSObject* object = m_localObjects.get(objectID); 1021 1084 if (!object) 1022 1085 return false; … … 1038 1101 return false; 1039 1102 1040 JSObject* object = m_ objects.get(objectID);1103 JSObject* object = m_localObjects.get(objectID); 1041 1104 if (!object) 1042 1105 return false; … … 1058 1121 return false; 1059 1122 1060 JSObject* object = m_ objects.get(objectID);1123 JSObject* object = m_localObjects.get(objectID); 1061 1124 if (!object) 1062 1125 return false; … … 1078 1141 return false; 1079 1142 1080 JSObject* object = m_ objects.get(objectID);1143 JSObject* object = m_localObjects.get(objectID); 1081 1144 if (!object) 1082 1145 return false; … … 1137 1200 } else { 1138 1201 [array addObject:[NSNumber numberWithInt:JSObjectValueType]]; 1139 [array addObject:[NSNumber numberWithInt: idForObject(object)]];1202 [array addObject:[NSNumber numberWithInt:m_localObjects.idForObject(object)]]; 1140 1203 } 1141 1204 } else … … 1199 1262 uint32_t objectID = [[array objectAtIndex:index++] intValue]; 1200 1263 1201 result = m_ objects.get(objectID);1264 result = m_localObjects.get(objectID); 1202 1265 ASSERT(result); 1203 1266 return true; … … 1254 1317 while (demarshalValueFromArray(exec, array.get(), position, value)) 1255 1318 result.append(value); 1319 } 1320 1321 void NetscapePluginInstanceProxy::retainLocalObject(JSC::JSValue value) 1322 { 1323 if (!value.isObject()) 1324 return; 1325 1326 JSObject* object = asObject(value); 1327 if (object->classInfo() == &RuntimeObjectImp::s_info) 1328 return; 1329 1330 m_localObjects.retain(object); 1331 } 1332 1333 void NetscapePluginInstanceProxy::releaseLocalObject(JSC::JSValue value) 1334 { 1335 if (!value.isObject()) 1336 return; 1337 1338 JSObject* object = asObject(value); 1339 if (object->classInfo() == &RuntimeObjectImp::s_info) 1340 return; 1341 1342 m_localObjects.release(object); 1256 1343 } 1257 1344 -
trunk/WebKit/mac/Plugins/Hosted/ProxyInstance.mm
r54504 r54783 138 138 if (!m_instanceProxy) 139 139 return jsUndefined(); 140 140 141 141 RetainPtr<NSData*> arguments(m_instanceProxy->marshalValues(exec, args)); 142 142 143 143 uint32_t requestID = m_instanceProxy->nextRequestID(); 144 144 145 for (unsigned i = 0; i < args.size(); i++) 146 m_instanceProxy->retainLocalObject(args.at(i)); 147 145 148 if (_WKPHNPObjectInvoke(m_instanceProxy->hostProxy()->port(), m_instanceProxy->pluginID(), requestID, m_objectID, 146 type, identifier, (char*)[arguments.get() bytes], [arguments.get() length]) != KERN_SUCCESS) 147 return jsUndefined(); 149 type, identifier, (char*)[arguments.get() bytes], [arguments.get() length]) != KERN_SUCCESS) { 150 for (unsigned i = 0; i < args.size(); i++) 151 m_instanceProxy->releaseLocalObject(args.at(i)); 152 return jsUndefined(); 153 } 148 154 149 155 auto_ptr<NetscapePluginInstanceProxy::BooleanAndDataReply> reply = waitForReply<NetscapePluginInstanceProxy::BooleanAndDataReply>(requestID); 150 156 NetscapePluginInstanceProxy::moveGlobalExceptionToExecState(exec); 157 158 for (unsigned i = 0; i < args.size(); i++) 159 m_instanceProxy->releaseLocalObject(args.at(i)); 160 151 161 if (!reply.get() || !reply->m_returnValue) 152 162 return jsUndefined(); … … 382 392 383 393 m_instanceProxy->marshalValue(exec, value, valueData, valueLength); 394 m_instanceProxy->retainLocalObject(value); 384 395 kern_return_t kr = _WKPHNPObjectSetProperty(m_instanceProxy->hostProxy()->port(), 385 396 m_instanceProxy->pluginID(), requestID, 386 397 m_objectID, serverIdentifier, valueData, valueLength); 387 398 mig_deallocate(reinterpret_cast<vm_address_t>(valueData), valueLength); 399 m_instanceProxy->releaseLocalObject(value); 388 400 if (kr != KERN_SUCCESS) 389 401 return; -
trunk/WebKit/mac/Plugins/Hosted/WebKitPluginClient.defs
r54516 r54783 113 113 out objectID :uint32_t); 114 114 115 routine PC ReleaseObject(clientPort :mach_port_t;115 routine PCForgetBrowserObject(clientPort :mach_port_t; 116 116 pluginID :uint32_t; 117 117 objectID :uint32_t); -
trunk/WebKitTools/ChangeLog
r54772 r54783 1 2010-02-12 Alexey Proskuryakov <ap@apple.com> 2 3 Reviewed by Kevin Decker. 4 5 <rdar://problem/7130641> Browser objects identity is not preserved by Safari 6 7 * DumpRenderTree/TestNetscapePlugIn.subproj/PluginObject.cpp: 8 (pluginInvoke): Added methods for checking object identity (via refcount). 9 1 10 2010-02-15 Robert Hogan <robert@roberthogan.net> 2 11 -
trunk/WebKitTools/DumpRenderTree/TestNetscapePlugIn.subproj/PluginObject.cpp
r54516 r54783 177 177 ID_TEST_GET_BROWSER_PROPERTY, 178 178 ID_TEST_SET_BROWSER_PROPERTY, 179 ID_REMEMBER, 180 ID_GET_REMEMBERED_OBJECT, 181 ID_GET_AND_FORGET_REMEMBERED_OBJECT, 182 ID_REF_COUNT, 179 183 NUM_METHOD_IDENTIFIERS 180 184 }; … … 206 210 "reloadPluginsAndPages", 207 211 "testGetBrowserProperty", 208 "testSetBrowserProperty" 212 "testSetBrowserProperty", 213 "remember", 214 "getRememberedObject", 215 "getAndForgetRememberedObject", 216 "refCount" 209 217 }; 210 218 … … 747 755 return false; 748 756 } 757 758 static NPObject* rememberedObject; 749 759 750 760 static bool pluginInvoke(NPObject* header, NPIdentifier name, const NPVariant* args, uint32_t argCount, NPVariant* result) … … 808 818 browser->setproperty(plugin->npp, NPVARIANT_TO_OBJECT(args[0]), stringVariantToIdentifier(args[1]), &args[2]); 809 819 return true; 820 } else if (name == pluginMethodIdentifiers[ID_REMEMBER]) { 821 if (rememberedObject) 822 browser->releaseobject(rememberedObject); 823 rememberedObject = NPVARIANT_TO_OBJECT(args[0]); 824 browser->retainobject(rememberedObject); 825 VOID_TO_NPVARIANT(*result); 826 return true; 827 } else if (name == pluginMethodIdentifiers[ID_GET_REMEMBERED_OBJECT]) { 828 assert(rememberedObject); 829 browser->retainobject(rememberedObject); 830 OBJECT_TO_NPVARIANT(rememberedObject, *result); 831 return true; 832 } else if (name == pluginMethodIdentifiers[ID_GET_AND_FORGET_REMEMBERED_OBJECT]) { 833 assert(rememberedObject); 834 OBJECT_TO_NPVARIANT(rememberedObject, *result); 835 rememberedObject = 0; 836 return true; 837 } else if (name == pluginMethodIdentifiers[ID_REF_COUNT]) { 838 uint32_t refCount = NPVARIANT_TO_OBJECT(args[0])->referenceCount; 839 INT32_TO_NPVARIANT(refCount, *result); 840 return true; 810 841 } 811 842
Note:
See TracChangeset
for help on using the changeset viewer.