Adding DoNotRunWith annotation to failing JUnit test; possible HtmlUnit bug.
Review at http://gwt-code-reviews.appspot.com/1469803
Review by: conroy@google.com
git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@10438 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/plugins/npapi/LocalObjectTable.h b/plugins/npapi/LocalObjectTable.h
index acfbf2f..57a5887 100644
--- a/plugins/npapi/LocalObjectTable.h
+++ b/plugins/npapi/LocalObjectTable.h
@@ -21,24 +21,43 @@
#include "Debug.h"
#include "mozincludes.h"
+#include "NPVariantUtil.h"
class LocalObjectTable {
private:
+ /* The host expects Value objects to have int's for JSO id's, hence the
+ * dual mapping. ObjectMap is for host communication (Value.getJsObjectId)
+ * and the IdMap is for browser communication (NPObject to ID).
+ */
typedef std::map<int, NPObject*> ObjectMap;
+ typedef std::map<NPObject*,int> IdMap;
+
+ NPP npp;
int nextId;
ObjectMap objects;
+ IdMap ids;
bool dontFree;
+ bool jsIdentitySafe;
+
+ const NPIdentifier gwtId;
+
void setFree(int id) {
- if (objects.erase(id) != 1) {
+ NPObject *obj = getById(id);
+ if(!obj) {
Debug::log(Debug::Error) << "setFree(id=" << id << "): object not in table"
<< Debug::flush;
+ return;
}
+ ids.erase(obj);
+ objects.erase(id);
}
public:
- LocalObjectTable(): nextId(0), dontFree(false) {
+ LocalObjectTable(NPP npp, bool jsIdentitySafe):
+ nextId(0), dontFree(false), jsIdentitySafe(jsIdentitySafe),
+ gwtId(NPN_GetStringIdentifier("__gwt_ObjectId")) {
}
virtual ~LocalObjectTable();
@@ -49,29 +68,67 @@
int add(NPObject* obj) {
int id = nextId++;
set(id, obj);
+
+ if (!jsIdentitySafe) {
+ NPVariant idVariant;
+ Debug::log(Debug::Debugging) << "LocalObjectTable::set(): setting expando("
+ << id << ")" << Debug::flush;
+ INT32_TO_NPVARIANT(id,idVariant);
+ if (!NPN_SetProperty(npp, obj, gwtId, &idVariant)) {
+ Debug::log(Debug::Error) << "Setting GWT id on object failed" << Debug::flush;
+ }
+ }
+
return id;
}
void set(int id, NPObject* obj) {
- Debug::log(Debug::Spam) << "LocalObjectTable::set(id=" << id << ",obj=" << (void*)obj
+ Debug::log(Debug::Debugging) << "LocalObjectTable::set(id=" << id << ",obj=" << (void*)obj
<< ")" << Debug::flush;
+ if (!jsIdentitySafe) {
+ ObjectMap::iterator it;
+ it = objects.find(id);
+ if( it != objects.end() ) {
+ if (it->second != obj) {
+ //The JSO has changed and we need to update the map, releasing
+ //the old and remembering the new object.
+ ids.erase(it->second);
+ NPN_ReleaseObject(it->second);
+ NPN_RetainObject(obj);
+ } else {
+ //do nothing; object exists and is already mapped
+ return;
+ }
+ } else {
+ //New insertion, retain the object in the table
+ NPN_RetainObject(obj);
+ }
+ } else {
+ //Not dealing with identity hack, retain
+ NPN_RetainObject(obj);
+ }
objects[id] = obj;
+ ids[obj] = id;
+
// keep track that we hold a reference in the table
- NPN_RetainObject(obj);
}
void free(int id) {
- Debug::log(Debug::Spam) << "LocalObjectTable::free(id=" << id << ")" << Debug::flush;
+ Debug::log(Debug::Debugging) << "LocalObjectTable::free(id=" << id << ")" << Debug::flush;
ObjectMap::iterator it = objects.find(id);
if (it == objects.end()) {
Debug::log(Debug::Error) << "Freeing freed object slot " << id << Debug::flush;
return;
}
+ if (!jsIdentitySafe) {
+ Debug::log(Debug::Debugging) << "removing expando!" << Debug::flush;
+ NPN_RemoveProperty(npp, it->second, gwtId);
+ }
+ setFree(id);
if (!dontFree) {
NPObject* obj = it->second;
NPN_ReleaseObject(obj);
}
- setFree(id);
}
void freeAll() {
@@ -85,7 +142,7 @@
objects.clear();
}
- NPObject* get(int id) {
+ NPObject* getById(int id) {
ObjectMap::iterator it = objects.find(id);
if (it == objects.end()) {
Debug::log(Debug::Error) << "LocalObjectTable::get(id=" << id
@@ -94,6 +151,30 @@
return it->second;
}
+ int getObjectId(NPObject* jsObject) {
+ int id = -1;
+ if(!jsIdentitySafe) {
+ NPVariant idVariant;
+ VOID_TO_NPVARIANT(idVariant);
+ Debug::log(Debug::Debugging) << "LocalObjectTable::get(): expando test"
+ << Debug::flush;
+ if (NPN_GetProperty(npp, jsObject, gwtId, &idVariant) &&
+ NPVariantUtil::isInt(idVariant)) {
+ id = NPVariantUtil::getAsInt(idVariant);
+ Debug::log(Debug::Debugging) << "LocalObjectTable::get(): expando: "
+ << id << Debug::flush;
+ set(id, jsObject);
+ }
+ NPN_ReleaseVariantValue(&idVariant);
+ } else {
+ IdMap::iterator it = ids.find(jsObject);
+ if (it != ids.end()) {
+ id = it->second;
+ }
+ }
+ return id;
+ }
+
void setDontFree(bool dontFree) {
this->dontFree = dontFree;
}