summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--webkit/glue/webkit_glue.gypi2
-rw-r--r--webkit/plugins/ppapi/message_channel.cc3
-rw-r--r--webkit/plugins/ppapi/npapi_glue.cc69
-rw-r--r--webkit/plugins/ppapi/npapi_glue.h37
-rw-r--r--webkit/plugins/ppapi/plugin_module.cc5
-rw-r--r--webkit/plugins/ppapi/plugin_object.cc7
-rw-r--r--webkit/plugins/ppapi/plugin_object.h4
-rw-r--r--webkit/plugins/ppapi/ppapi_plugin_instance.cc36
-rw-r--r--webkit/plugins/ppapi/ppapi_plugin_instance.h18
-rw-r--r--webkit/plugins/ppapi/ppb_url_util_impl.cc28
-rw-r--r--webkit/plugins/ppapi/ppb_var_impl.cc456
-rw-r--r--webkit/plugins/ppapi/ppb_var_impl.h23
-rw-r--r--webkit/plugins/ppapi/resource_tracker.cc95
-rw-r--r--webkit/plugins/ppapi/resource_tracker.h18
-rw-r--r--webkit/plugins/ppapi/resource_tracker_unittest.cc11
-rw-r--r--webkit/plugins/ppapi/var.cc526
-rw-r--r--webkit/plugins/ppapi/var.h79
17 files changed, 741 insertions, 676 deletions
diff --git a/webkit/glue/webkit_glue.gypi b/webkit/glue/webkit_glue.gypi
index 1573e1d..8db2606 100644
--- a/webkit/glue/webkit_glue.gypi
+++ b/webkit/glue/webkit_glue.gypi
@@ -296,6 +296,8 @@
'../plugins/ppapi/ppb_url_response_info_impl.h',
'../plugins/ppapi/ppb_url_util_impl.cc',
'../plugins/ppapi/ppb_url_util_impl.h',
+ '../plugins/ppapi/ppb_var_impl.cc',
+ '../plugins/ppapi/ppb_var_impl.h',
'../plugins/ppapi/ppb_video_decoder_impl.cc',
'../plugins/ppapi/ppb_video_decoder_impl.h',
'../plugins/ppapi/ppb_video_layer_impl.cc',
diff --git a/webkit/plugins/ppapi/message_channel.cc b/webkit/plugins/ppapi/message_channel.cc
index 759f8175..2edfe13 100644
--- a/webkit/plugins/ppapi/message_channel.cc
+++ b/webkit/plugins/ppapi/message_channel.cc
@@ -150,8 +150,7 @@ bool MessageChannelInvoke(NPObject* np_obj, NPIdentifier name,
// We only handle a function called postMessage.
if (IdentifierIsPostMessage(name) && (arg_count == 1)) {
MessageChannel& message_channel(ToMessageChannel(np_obj));
- PP_Var argument(Var::NPVariantToPPVar(message_channel.instance(),
- &args[0]));
+ PP_Var argument(NPVariantToPPVar(message_channel.instance(), &args[0]));
message_channel.PostMessageToNative(argument);
return true;
}
diff --git a/webkit/plugins/ppapi/npapi_glue.cc b/webkit/plugins/ppapi/npapi_glue.cc
index ad9f248..2d2c342 100644
--- a/webkit/plugins/ppapi/npapi_glue.cc
+++ b/webkit/plugins/ppapi/npapi_glue.cc
@@ -10,6 +10,7 @@
#include "webkit/plugins/ppapi/plugin_module.h"
#include "webkit/plugins/ppapi/plugin_object.h"
#include "webkit/plugins/ppapi/ppapi_plugin_instance.h"
+#include "webkit/plugins/ppapi/resource_tracker.h"
#include "webkit/plugins/ppapi/var.h"
#include "third_party/npapi/bindings/npapi.h"
#include "third_party/npapi/bindings/npruntime.h"
@@ -75,6 +76,68 @@ bool PPVarToNPVariant(PP_Var var, NPVariant* result) {
return true;
}
+PP_Var NPVariantToPPVar(PluginInstance* instance, const NPVariant* variant) {
+ switch (variant->type) {
+ case NPVariantType_Void:
+ return PP_MakeUndefined();
+ case NPVariantType_Null:
+ return PP_MakeNull();
+ case NPVariantType_Bool:
+ return PP_MakeBool(PP_FromBool(NPVARIANT_TO_BOOLEAN(*variant)));
+ case NPVariantType_Int32:
+ return PP_MakeInt32(NPVARIANT_TO_INT32(*variant));
+ case NPVariantType_Double:
+ return PP_MakeDouble(NPVARIANT_TO_DOUBLE(*variant));
+ case NPVariantType_String:
+ return StringVar::StringToPPVar(
+ instance->module()->pp_module(),
+ NPVARIANT_TO_STRING(*variant).UTF8Characters,
+ NPVARIANT_TO_STRING(*variant).UTF8Length);
+ case NPVariantType_Object:
+ return NPObjectToPPVar(instance, NPVARIANT_TO_OBJECT(*variant));
+ }
+ NOTREACHED();
+ return PP_MakeUndefined();
+}
+
+NPIdentifier PPVarToNPIdentifier(PP_Var var) {
+ switch (var.type) {
+ case PP_VARTYPE_STRING: {
+ scoped_refptr<StringVar> string(StringVar::FromPPVar(var));
+ if (!string)
+ return NULL;
+ return WebBindings::getStringIdentifier(string->value().c_str());
+ }
+ case PP_VARTYPE_INT32:
+ return WebBindings::getIntIdentifier(var.value.as_int);
+ default:
+ return NULL;
+ }
+}
+
+PP_Var NPIdentifierToPPVar(PP_Module module, NPIdentifier id) {
+ const NPUTF8* string_value = NULL;
+ int32_t int_value = 0;
+ bool is_string = false;
+ WebBindings::extractIdentifierData(id, string_value, int_value, is_string);
+ if (is_string)
+ return StringVar::StringToPPVar(module, string_value);
+
+ return PP_MakeInt32(int_value);
+}
+
+PP_Var NPObjectToPPVar(PluginInstance* instance, NPObject* object) {
+ DCHECK(object);
+ scoped_refptr<ObjectVar> object_var(
+ ResourceTracker::Get()->ObjectVarForNPObject(instance->pp_instance(),
+ object));
+ if (!object_var) { // No object for this module yet, make a new one.
+ object_var = new ObjectVar(instance->module()->pp_module(),
+ instance->pp_instance(), object);
+ }
+ return object_var->GetPPVar();
+}
+
// PPResultAndExceptionToNPResult ----------------------------------------------
PPResultAndExceptionToNPResult::PPResultAndExceptionToNPResult(
@@ -166,7 +229,7 @@ PPVarArrayFromNPVariantArray::PPVarArrayFromNPVariantArray(
if (size_ > 0) {
array_.reset(new PP_Var[size_]);
for (size_t i = 0; i < size_; i++)
- array_[i] = Var::NPVariantToPPVar(instance, &variants[i]);
+ array_[i] = NPVariantToPPVar(instance, &variants[i]);
}
}
@@ -178,7 +241,7 @@ PPVarArrayFromNPVariantArray::~PPVarArrayFromNPVariantArray() {
// PPVarFromNPObject -----------------------------------------------------------
PPVarFromNPObject::PPVarFromNPObject(PluginInstance* instance, NPObject* object)
- : var_(ObjectVar::NPObjectToPPVar(instance, object)) {
+ : var_(NPObjectToPPVar(instance, object)) {
}
PPVarFromNPObject::~PPVarFromNPObject() {
@@ -194,7 +257,7 @@ NPObjectAccessorWithIdentifier::NPObjectAccessorWithIdentifier(
: object_(PluginObject::FromNPObject(object)),
identifier_(PP_MakeUndefined()) {
if (object_) {
- identifier_ = Var::NPIdentifierToPPVar(
+ identifier_ = NPIdentifierToPPVar(
object_->instance()->module()->pp_module(), identifier);
if (identifier_.type == PP_VARTYPE_INT32 && !allow_integer_identifier)
identifier_.type = PP_VARTYPE_UNDEFINED; // Mark it invalid.
diff --git a/webkit/plugins/ppapi/npapi_glue.h b/webkit/plugins/ppapi/npapi_glue.h
index f0dfd43..ced0fe6 100644
--- a/webkit/plugins/ppapi/npapi_glue.h
+++ b/webkit/plugins/ppapi/npapi_glue.h
@@ -7,6 +7,7 @@
#include "base/basictypes.h"
#include "base/memory/scoped_ptr.h"
+#include "ppapi/c/pp_module.h"
#include "ppapi/c/pp_var.h"
struct NPObject;
@@ -30,6 +31,42 @@ class PluginObject;
// an object.
bool PPVarToNPVariant(PP_Var var, NPVariant* result);
+// Returns a PP_Var that corresponds to the given NPVariant. The contents of
+// the NPVariant will be copied unless the NPVariant corresponds to an
+// object. This will handle all Variant types including POD, strings, and
+// objects.
+//
+// The returned PP_Var will have a refcount of 1, this passing ownership of
+// the reference to the caller. This is suitable for returning to a plugin.
+PP_Var NPVariantToPPVar(PluginInstance* instance, const NPVariant* variant);
+
+// Returns a NPIdentifier that corresponds to the given PP_Var. The contents
+// of the PP_Var will be copied. Returns 0 if the given PP_Var is not a a
+// string or integer type.
+NPIdentifier PPVarToNPIdentifier(PP_Var var);
+
+// Returns a PP_Var corresponding to the given identifier. In the case of
+// a string identifier, the string will be allocated associated with the
+// given module. A returned string will have a reference count of 1.
+PP_Var NPIdentifierToPPVar(PP_Module module, NPIdentifier id);
+
+// Helper function to create a PP_Var of type object that contains the given
+// NPObject for use byt he given module. Calling this function multiple times
+// given the same module + NPObject results in the same PP_Var, assuming that
+// there is still a PP_Var with a reference open to it from the previous
+// call.
+//
+// The module is necessary because we can have different modules pointing to
+// the same NPObject, and we want to keep their refs separate.
+//
+// If no ObjectVar currently exists corresponding to the NPObject, one is
+// created associated with the given module.
+//
+// Note: this could easily be changed to take a PP_Instance instead if that
+// makes certain calls in the future easier. Currently all callers have a
+// PluginInstance so that's what we use here.
+PP_Var NPObjectToPPVar(PluginInstance* instance, NPObject* object);
+
// PPResultAndExceptionToNPResult ----------------------------------------------
// Convenience object for converting a PPAPI call that can throw an exception
diff --git a/webkit/plugins/ppapi/plugin_module.cc b/webkit/plugins/ppapi/plugin_module.cc
index 6337ad2..bff83f1 100644
--- a/webkit/plugins/ppapi/plugin_module.cc
+++ b/webkit/plugins/ppapi/plugin_module.cc
@@ -100,6 +100,7 @@
#include "webkit/plugins/ppapi/ppb_scrollbar_impl.h"
#include "webkit/plugins/ppapi/ppb_uma_private_impl.h"
#include "webkit/plugins/ppapi/ppb_url_util_impl.h"
+#include "webkit/plugins/ppapi/ppb_var_impl.h"
#include "webkit/plugins/ppapi/ppb_video_decoder_impl.h"
#include "webkit/plugins/ppapi/ppb_video_layer_impl.h"
#include "webkit/plugins/ppapi/resource_tracker.h"
@@ -322,9 +323,9 @@ const void* GetInterface(const char* name) {
if (strcmp(name, PPB_URLUTIL_DEV_INTERFACE) == 0)
return PPB_URLUtil_Impl::GetInterface();
if (strcmp(name, PPB_VAR_DEPRECATED_INTERFACE) == 0)
- return Var::GetDeprecatedInterface();
+ return PPB_Var_Impl::GetVarDeprecatedInterface();
if (strcmp(name, PPB_VAR_INTERFACE_1_0) == 0)
- return Var::GetInterface();
+ return PPB_Var_Impl::GetVarInterface();
if (strcmp(name, PPB_VIDEODECODER_DEV_INTERFACE) == 0)
return ::ppapi::thunk::GetPPB_VideoDecoder_Thunk();
if (strcmp(name, PPB_VIDEOLAYER_DEV_INTERFACE) == 0)
diff --git a/webkit/plugins/ppapi/plugin_object.cc b/webkit/plugins/ppapi/plugin_object.cc
index e24e1b2..b20b9ff 100644
--- a/webkit/plugins/ppapi/plugin_object.cc
+++ b/webkit/plugins/ppapi/plugin_object.cc
@@ -130,8 +130,7 @@ bool WrapperClass_SetProperty(NPObject* object, NPIdentifier property_name,
PPResultAndExceptionToNPResult result_converter(
accessor.object()->GetNPObject(), NULL);
- PP_Var value_var = Var::NPVariantToPPVar(accessor.object()->instance(),
- value);
+ PP_Var value_var = NPVariantToPPVar(accessor.object()->instance(), value);
accessor.object()->ppp_class()->SetProperty(
accessor.object()->ppp_class_data(), accessor.identifier(), value_var,
result_converter.exception());
@@ -175,7 +174,7 @@ bool WrapperClass_Enumerate(NPObject* object, NPIdentifier** values,
malloc(sizeof(NPIdentifier) * property_count));
*count = 0; // Will be the number of items successfully converted.
for (uint32_t i = 0; i < property_count; ++i) {
- if (!((*values)[i] = Var::PPVarToNPIdentifier(properties[i]))) {
+ if (!((*values)[i] = PPVarToNPIdentifier(properties[i]))) {
// Throw an exception for the failed convertion.
*result_converter.exception() = StringVar::StringToPPVar(
obj->instance()->module()->pp_module(), kInvalidValueException);
@@ -290,7 +289,7 @@ PP_Var PluginObject::Create(PluginInstance* instance,
// We can just use a normal ObjectVar to refer to this object from the
// plugin. It will hold a ref to the underlying NPObject which will in turn
// hold our pluginObject.
- PP_Var obj_var(ObjectVar::NPObjectToPPVar(instance, wrapper));
+ PP_Var obj_var(NPObjectToPPVar(instance, wrapper));
// Note that the ObjectVar constructor incremented the reference count, and so
// did WebBindings::createObject above. Now that the PP_Var has taken
diff --git a/webkit/plugins/ppapi/plugin_object.h b/webkit/plugins/ppapi/plugin_object.h
index 9f4b607..55d054f 100644
--- a/webkit/plugins/ppapi/plugin_object.h
+++ b/webkit/plugins/ppapi/plugin_object.h
@@ -19,6 +19,10 @@ namespace ppapi {
class PluginInstance;
+// A PluginObject is a JS-accessible object implemented by the plugin.
+//
+// In contrast, a var of type PP_VARTYPE_OBJECT is a reference to a JS object,
+// which might be implemented by the plugin (here) or by the JS engine.
class PluginObject {
public:
virtual ~PluginObject();
diff --git a/webkit/plugins/ppapi/ppapi_plugin_instance.cc b/webkit/plugins/ppapi/ppapi_plugin_instance.cc
index 17756c2..44c908f 100644
--- a/webkit/plugins/ppapi/ppapi_plugin_instance.cc
+++ b/webkit/plugins/ppapi/ppapi_plugin_instance.cc
@@ -50,6 +50,7 @@
#include "webkit/plugins/ppapi/event_conversion.h"
#include "webkit/plugins/ppapi/fullscreen_container.h"
#include "webkit/plugins/ppapi/message_channel.h"
+#include "webkit/plugins/ppapi/npapi_glue.h"
#include "webkit/plugins/ppapi/plugin_delegate.h"
#include "webkit/plugins/ppapi/plugin_module.h"
#include "webkit/plugins/ppapi/plugin_object.h"
@@ -1304,34 +1305,6 @@ void PluginInstance::RemovePluginObject(PluginObject* plugin_object) {
live_plugin_objects_.erase(plugin_object);
}
-void PluginInstance::AddNPObjectVar(ObjectVar* object_var) {
- DCHECK(np_object_to_object_var_.find(object_var->np_object()) ==
- np_object_to_object_var_.end()) << "ObjectVar already in map";
- np_object_to_object_var_[object_var->np_object()] = object_var;
-}
-
-void PluginInstance::RemoveNPObjectVar(ObjectVar* object_var) {
- NPObjectToObjectVarMap::iterator found =
- np_object_to_object_var_.find(object_var->np_object());
- if (found == np_object_to_object_var_.end()) {
- NOTREACHED() << "ObjectVar not registered.";
- return;
- }
- if (found->second != object_var) {
- NOTREACHED() << "ObjectVar doesn't match.";
- return;
- }
- np_object_to_object_var_.erase(found);
-}
-
-ObjectVar* PluginInstance::ObjectVarForNPObject(NPObject* np_object) const {
- NPObjectToObjectVarMap::const_iterator found =
- np_object_to_object_var_.find(np_object);
- if (found == np_object_to_object_var_.end())
- return NULL;
- return found->second;
-}
-
bool PluginInstance::IsFullPagePlugin() const {
WebFrame* frame = container()->element().document().frame();
return frame->view()->mainFrame()->document().isPluginDocument();
@@ -1424,14 +1397,13 @@ PP_Var PluginInstance::GetWindowObject(PP_Instance instance) {
if (!frame)
return PP_MakeUndefined();
- return ObjectVar::NPObjectToPPVar(this, frame->windowObject());
+ return NPObjectToPPVar(this, frame->windowObject());
}
PP_Var PluginInstance::GetOwnerElementObject(PP_Instance instance) {
if (!container_)
return PP_MakeUndefined();
- return ObjectVar::NPObjectToPPVar(this,
- container_->scriptableObjectForElement());
+ return NPObjectToPPVar(this, container_->scriptableObjectForElement());
}
PP_Var PluginInstance::ExecuteScript(PP_Instance instance,
@@ -1471,7 +1443,7 @@ PP_Var PluginInstance::ExecuteScript(PP_Instance instance,
return PP_MakeUndefined();
}
- PP_Var ret = Var::NPVariantToPPVar(this, &result);
+ PP_Var ret = NPVariantToPPVar(this, &result);
WebBindings::releaseVariantValue(&result);
return ret;
}
diff --git a/webkit/plugins/ppapi/ppapi_plugin_instance.h b/webkit/plugins/ppapi/ppapi_plugin_instance.h
index f3e71a2..1380039 100644
--- a/webkit/plugins/ppapi/ppapi_plugin_instance.h
+++ b/webkit/plugins/ppapi/ppapi_plugin_instance.h
@@ -33,7 +33,6 @@
#include "ui/gfx/rect.h"
#include "webkit/plugins/ppapi/plugin_delegate.h"
-typedef struct NPObject NPObject;
struct PP_Var;
struct PPP_Find_Dev;
struct PPP_InputEvent;
@@ -237,18 +236,6 @@ class PluginInstance : public base::RefCounted<PluginInstance>,
PluginDelegate::PlatformContext3D* CreateContext3D();
- // Tracks all live ObjectVar. This is so we can map between PluginModule +
- // NPObject and get the ObjectVar corresponding to it. This Add/Remove
- // function should be called by the ObjectVar when it is created and
- // destroyed.
- void AddNPObjectVar(ObjectVar* object_var);
- void RemoveNPObjectVar(ObjectVar* object_var);
-
- // Looks up a previously registered ObjectVar for the given NPObject and
- // module. Returns NULL if there is no ObjectVar corresponding to the given
- // NPObject for the given module. See AddNPObjectVar above.
- ObjectVar* ObjectVarForNPObject(NPObject* np_object) const;
-
// Returns true iff the plugin is a full-page plugin (i.e. not in an iframe or
// embedded in a page).
bool IsFullPagePlugin() const;
@@ -491,11 +478,6 @@ class PluginInstance : public base::RefCounted<PluginInstance>,
typedef std::set<PluginObject*> PluginObjectSet;
PluginObjectSet live_plugin_objects_;
- // Tracks all live ObjectVars used by this module so we can map NPObjects to
- // the corresponding object. These are non-owning references.
- typedef std::map<NPObject*, ObjectVar*> NPObjectToObjectVarMap;
- NPObjectToObjectVarMap np_object_to_object_var_;
-
// Classes of events that the plugin has registered for, both for filtering
// and not. The bits are PP_INPUTEVENT_CLASS_*.
uint32_t input_event_mask_;
diff --git a/webkit/plugins/ppapi/ppb_url_util_impl.cc b/webkit/plugins/ppapi/ppb_url_util_impl.cc
index 64625f4..6791de1 100644
--- a/webkit/plugins/ppapi/ppb_url_util_impl.cc
+++ b/webkit/plugins/ppapi/ppb_url_util_impl.cc
@@ -18,6 +18,7 @@
#include "webkit/plugins/ppapi/common.h"
#include "webkit/plugins/ppapi/plugin_module.h"
#include "webkit/plugins/ppapi/ppapi_plugin_instance.h"
+#include "webkit/plugins/ppapi/ppb_var_impl.h"
#include "webkit/plugins/ppapi/resource_tracker.h"
#include "webkit/plugins/ppapi/string.h"
#include "webkit/plugins/ppapi/var.h"
@@ -61,7 +62,7 @@ bool SecurityOriginForInstance(PP_Instance instance_id,
PP_Var Canonicalize(PP_Var url, PP_URLComponents_Dev* components) {
return URLUtilImpl::Canonicalize(&StringFromVar,
- Var::GetInterface()->VarFromUtf8,
+ PPB_Var_Impl::GetVarInterface()->VarFromUtf8,
GetModuleFromVar(url),
url, components);
}
@@ -69,10 +70,11 @@ PP_Var Canonicalize(PP_Var url, PP_URLComponents_Dev* components) {
PP_Var ResolveRelativeToURL(PP_Var base_url,
PP_Var relative,
PP_URLComponents_Dev* components) {
- return URLUtilImpl::ResolveRelativeToURL(&StringFromVar,
- Var::GetInterface()->VarFromUtf8,
- GetModuleFromVar(base_url),
- base_url, relative, components);
+ return URLUtilImpl::ResolveRelativeToURL(
+ &StringFromVar,
+ PPB_Var_Impl::GetVarInterface()->VarFromUtf8,
+ GetModuleFromVar(base_url),
+ base_url, relative, components);
}
PP_Var ResolveRelativeToDocument(PP_Instance instance_id,
@@ -89,7 +91,7 @@ PP_Var ResolveRelativeToDocument(PP_Instance instance_id,
WebKit::WebElement plugin_element = instance->container()->element();
GURL document_url = plugin_element.document().baseURL();
return URLUtilImpl::GenerateURLReturn(
- Var::GetInterface()->VarFromUtf8,
+ PPB_Var_Impl::GetVarInterface()->VarFromUtf8,
instance->module()->pp_module(),
document_url.Resolve(relative_string->value()),
components);
@@ -134,9 +136,10 @@ PP_Var GetDocumentURL(PP_Instance instance_id,
return PP_MakeNull();
WebKit::WebDocument document = instance->container()->element().document();
- return URLUtilImpl::GenerateURLReturn(Var::GetInterface()->VarFromUtf8,
- instance->module()->pp_module(),
- document.url(), components);
+ return URLUtilImpl::GenerateURLReturn(
+ PPB_Var_Impl::GetVarInterface()->VarFromUtf8,
+ instance->module()->pp_module(),
+ document.url(), components);
}
PP_Var GetPluginInstanceURL(PP_Instance instance_id,
@@ -146,9 +149,10 @@ PP_Var GetPluginInstanceURL(PP_Instance instance_id,
return PP_MakeNull();
const GURL& url = instance->plugin_url();
- return URLUtilImpl::GenerateURLReturn(Var::GetInterface()->VarFromUtf8,
- instance->module()->pp_module(),
- url, components);
+ return URLUtilImpl::GenerateURLReturn(
+ PPB_Var_Impl::GetVarInterface()->VarFromUtf8,
+ instance->module()->pp_module(),
+ url, components);
}
const PPB_URLUtil_Dev ppb_url_util = {
diff --git a/webkit/plugins/ppapi/ppb_var_impl.cc b/webkit/plugins/ppapi/ppb_var_impl.cc
new file mode 100644
index 0000000..a3cf3d5d
--- /dev/null
+++ b/webkit/plugins/ppapi/ppb_var_impl.cc
@@ -0,0 +1,456 @@
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "webkit/plugins/ppapi/ppb_var_impl.h"
+
+#include <limits>
+
+#include "ppapi/c/dev/ppb_var_deprecated.h"
+#include "ppapi/c/ppb_var.h"
+#include "ppapi/c/pp_var.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/WebBindings.h"
+#include "webkit/plugins/ppapi/common.h"
+#include "webkit/plugins/ppapi/npapi_glue.h"
+#include "webkit/plugins/ppapi/plugin_module.h"
+#include "webkit/plugins/ppapi/plugin_object.h"
+#include "webkit/plugins/ppapi/ppapi_plugin_instance.h"
+#include "webkit/plugins/ppapi/resource_tracker.h"
+#include "webkit/plugins/ppapi/var.h"
+#include "v8/include/v8.h"
+
+using WebKit::WebBindings;
+
+namespace webkit {
+namespace ppapi {
+
+namespace {
+
+const char kInvalidObjectException[] = "Error: Invalid object";
+const char kInvalidPropertyException[] = "Error: Invalid property";
+const char kInvalidValueException[] = "Error: Invalid value";
+const char kUnableToGetPropertyException[] = "Error: Unable to get property";
+const char kUnableToSetPropertyException[] = "Error: Unable to set property";
+const char kUnableToRemovePropertyException[] =
+ "Error: Unable to remove property";
+const char kUnableToGetAllPropertiesException[] =
+ "Error: Unable to get all properties";
+const char kUnableToCallMethodException[] = "Error: Unable to call method";
+const char kUnableToConstructException[] = "Error: Unable to construct";
+
+// ---------------------------------------------------------------------------
+// Utilities
+
+// Converts the given PP_Var to an NPVariant, returning true on success.
+// False means that the given variant is invalid. In this case, the result
+// NPVariant will be set to a void one.
+//
+// The contents of the PP_Var will NOT be copied, so you need to ensure that
+// the PP_Var remains valid while the resultant NPVariant is in use.
+bool PPVarToNPVariantNoCopy(PP_Var var, NPVariant* result) {
+ switch (var.type) {
+ case PP_VARTYPE_UNDEFINED:
+ VOID_TO_NPVARIANT(*result);
+ break;
+ case PP_VARTYPE_NULL:
+ NULL_TO_NPVARIANT(*result);
+ break;
+ case PP_VARTYPE_BOOL:
+ BOOLEAN_TO_NPVARIANT(var.value.as_bool, *result);
+ break;
+ case PP_VARTYPE_INT32:
+ INT32_TO_NPVARIANT(var.value.as_int, *result);
+ break;
+ case PP_VARTYPE_DOUBLE:
+ DOUBLE_TO_NPVARIANT(var.value.as_double, *result);
+ break;
+ case PP_VARTYPE_STRING: {
+ scoped_refptr<StringVar> string(StringVar::FromPPVar(var));
+ if (!string) {
+ VOID_TO_NPVARIANT(*result);
+ return false;
+ }
+ const std::string& value = string->value();
+ STRINGN_TO_NPVARIANT(value.c_str(), value.size(), *result);
+ break;
+ }
+ case PP_VARTYPE_OBJECT: {
+ scoped_refptr<ObjectVar> object(ObjectVar::FromPPVar(var));
+ if (!object) {
+ VOID_TO_NPVARIANT(*result);
+ return false;
+ }
+ OBJECT_TO_NPVARIANT(object->np_object(), *result);
+ break;
+ }
+ default:
+ VOID_TO_NPVARIANT(*result);
+ return false;
+ }
+ return true;
+}
+
+// ObjectAccessorTryCatch ------------------------------------------------------
+
+// Automatically sets up a TryCatch for accessing the object identified by the
+// given PP_Var. The module from the object will be used for the exception
+// strings generated by the TryCatch.
+//
+// This will automatically retrieve the ObjectVar from the object and throw
+// an exception if it's invalid. At the end of construction, if there is no
+// exception, you know that there is no previously set exception, that the
+// object passed in is valid and ready to use (via the object() getter), and
+// that the TryCatch's pp_module() getter is also set up properly and ready to
+// use.
+class ObjectAccessorTryCatch : public TryCatch {
+ public:
+ ObjectAccessorTryCatch(PP_Var object, PP_Var* exception)
+ : TryCatch(0, exception),
+ object_(ObjectVar::FromPPVar(object)) {
+ if (!object_) {
+ // No object or an invalid object was given. This means we have no module
+ // to associated with the exception text, so use the magic invalid object
+ // exception.
+ SetInvalidObjectException();
+ } else {
+ // When the object is valid, we have a valid module to associate
+ set_pp_module(object_->pp_module());
+ }
+ }
+
+ ObjectVar* object() { return object_.get(); }
+
+ PluginInstance* GetPluginInstance() {
+ return ResourceTracker::Get()->GetInstance(object()->pp_instance());
+ }
+
+ protected:
+ scoped_refptr<ObjectVar> object_;
+
+ DISALLOW_COPY_AND_ASSIGN(ObjectAccessorTryCatch);
+};
+
+// ObjectAccessiorWithIdentifierTryCatch ---------------------------------------
+
+// Automatically sets up a TryCatch for accessing the identifier on the given
+// object. This just extends ObjectAccessorTryCatch to additionally convert
+// the given identifier to an NPIdentifier and validate it, throwing an
+// exception if it's invalid.
+//
+// At the end of construction, if there is no exception, you know that there is
+// no previously set exception, that the object passed in is valid and ready to
+// use (via the object() getter), that the identifier is valid and ready to
+// use (via the identifier() getter), and that the TryCatch's pp_module() getter
+// is also set up properly and ready to use.
+class ObjectAccessorWithIdentifierTryCatch : public ObjectAccessorTryCatch {
+ public:
+ ObjectAccessorWithIdentifierTryCatch(PP_Var object,
+ PP_Var identifier,
+ PP_Var* exception)
+ : ObjectAccessorTryCatch(object, exception),
+ identifier_(0) {
+ if (!has_exception()) {
+ identifier_ = PPVarToNPIdentifier(identifier);
+ if (!identifier_)
+ SetException(kInvalidPropertyException);
+ }
+ }
+
+ NPIdentifier identifier() const { return identifier_; }
+
+ private:
+ NPIdentifier identifier_;
+
+ DISALLOW_COPY_AND_ASSIGN(ObjectAccessorWithIdentifierTryCatch);
+};
+
+// PPB_Var methods -------------------------------------------------------------
+
+PP_Var VarFromUtf8(PP_Module module, const char* data, uint32_t len) {
+ return StringVar::StringToPPVar(module, data, len);
+}
+
+const char* VarToUtf8(PP_Var var, uint32_t* len) {
+ scoped_refptr<StringVar> str(StringVar::FromPPVar(var));
+ if (!str) {
+ *len = 0;
+ return NULL;
+ }
+ *len = static_cast<uint32_t>(str->value().size());
+ if (str->value().empty())
+ return ""; // Don't return NULL on success.
+ return str->value().data();
+}
+
+PP_Bool HasProperty(PP_Var var,
+ PP_Var name,
+ PP_Var* exception) {
+ ObjectAccessorWithIdentifierTryCatch accessor(var, name, exception);
+ if (accessor.has_exception())
+ return PP_FALSE;
+ return BoolToPPBool(WebBindings::hasProperty(NULL,
+ accessor.object()->np_object(),
+ accessor.identifier()));
+}
+
+bool HasPropertyDeprecated(PP_Var var,
+ PP_Var name,
+ PP_Var* exception) {
+ return PPBoolToBool(HasProperty(var, name, exception));
+}
+
+bool HasMethodDeprecated(PP_Var var,
+ PP_Var name,
+ PP_Var* exception) {
+ ObjectAccessorWithIdentifierTryCatch accessor(var, name, exception);
+ if (accessor.has_exception())
+ return false;
+ return WebBindings::hasMethod(NULL, accessor.object()->np_object(),
+ accessor.identifier());
+}
+
+PP_Var GetProperty(PP_Var var,
+ PP_Var name,
+ PP_Var* exception) {
+ ObjectAccessorWithIdentifierTryCatch accessor(var, name, exception);
+ if (accessor.has_exception())
+ return PP_MakeUndefined();
+
+ NPVariant result;
+ if (!WebBindings::getProperty(NULL, accessor.object()->np_object(),
+ accessor.identifier(), &result)) {
+ // An exception may have been raised.
+ accessor.SetException(kUnableToGetPropertyException);
+ return PP_MakeUndefined();
+ }
+
+ PP_Var ret = NPVariantToPPVar(accessor.GetPluginInstance(), &result);
+ WebBindings::releaseVariantValue(&result);
+ return ret;
+}
+
+void EnumerateProperties(PP_Var var,
+ uint32_t* property_count,
+ PP_Var** properties,
+ PP_Var* exception) {
+ *properties = NULL;
+ *property_count = 0;
+
+ ObjectAccessorTryCatch accessor(var, exception);
+ if (accessor.has_exception())
+ return;
+
+ NPIdentifier* identifiers = NULL;
+ uint32_t count = 0;
+ if (!WebBindings::enumerate(NULL, accessor.object()->np_object(),
+ &identifiers, &count)) {
+ accessor.SetException(kUnableToGetAllPropertiesException);
+ return;
+ }
+
+ if (count == 0)
+ return;
+
+ *property_count = count;
+ *properties = static_cast<PP_Var*>(malloc(sizeof(PP_Var) * count));
+ for (uint32_t i = 0; i < count; ++i) {
+ (*properties)[i] = NPIdentifierToPPVar(
+ accessor.GetPluginInstance()->module()->pp_module(),
+ identifiers[i]);
+ }
+ free(identifiers);
+}
+
+void SetPropertyDeprecated(PP_Var var,
+ PP_Var name,
+ PP_Var value,
+ PP_Var* exception) {
+ ObjectAccessorWithIdentifierTryCatch accessor(var, name, exception);
+ if (accessor.has_exception())
+ return;
+
+ NPVariant variant;
+ if (!PPVarToNPVariantNoCopy(value, &variant)) {
+ accessor.SetException(kInvalidValueException);
+ return;
+ }
+ if (!WebBindings::setProperty(NULL, accessor.object()->np_object(),
+ accessor.identifier(), &variant))
+ accessor.SetException(kUnableToSetPropertyException);
+}
+
+void DeletePropertyDeprecated(PP_Var var,
+ PP_Var name,
+ PP_Var* exception) {
+ ObjectAccessorWithIdentifierTryCatch accessor(var, name, exception);
+ if (accessor.has_exception())
+ return;
+
+ if (!WebBindings::removeProperty(NULL, accessor.object()->np_object(),
+ accessor.identifier()))
+ accessor.SetException(kUnableToRemovePropertyException);
+}
+
+PP_Var CallDeprecated(PP_Var var,
+ PP_Var method_name,
+ uint32_t argc,
+ PP_Var* argv,
+ PP_Var* exception) {
+ ObjectAccessorTryCatch accessor(var, exception);
+ if (accessor.has_exception())
+ return PP_MakeUndefined();
+
+ NPIdentifier identifier;
+ if (method_name.type == PP_VARTYPE_UNDEFINED) {
+ identifier = NULL;
+ } else if (method_name.type == PP_VARTYPE_STRING) {
+ // Specifically allow only string functions to be called.
+ identifier = PPVarToNPIdentifier(method_name);
+ if (!identifier) {
+ accessor.SetException(kInvalidPropertyException);
+ return PP_MakeUndefined();
+ }
+ } else {
+ accessor.SetException(kInvalidPropertyException);
+ return PP_MakeUndefined();
+ }
+
+ scoped_array<NPVariant> args;
+ if (argc) {
+ args.reset(new NPVariant[argc]);
+ for (uint32_t i = 0; i < argc; ++i) {
+ if (!PPVarToNPVariantNoCopy(argv[i], &args[i])) {
+ // This argument was invalid, throw an exception & give up.
+ accessor.SetException(kInvalidValueException);
+ return PP_MakeUndefined();
+ }
+ }
+ }
+
+ bool ok;
+
+ NPVariant result;
+ if (identifier) {
+ ok = WebBindings::invoke(NULL, accessor.object()->np_object(),
+ identifier, args.get(), argc, &result);
+ } else {
+ ok = WebBindings::invokeDefault(NULL, accessor.object()->np_object(),
+ args.get(), argc, &result);
+ }
+
+ if (!ok) {
+ // An exception may have been raised.
+ accessor.SetException(kUnableToCallMethodException);
+ return PP_MakeUndefined();
+ }
+
+ PP_Var ret = NPVariantToPPVar(accessor.GetPluginInstance(), &result);
+ WebBindings::releaseVariantValue(&result);
+ return ret;
+}
+
+PP_Var Construct(PP_Var var,
+ uint32_t argc,
+ PP_Var* argv,
+ PP_Var* exception) {
+ ObjectAccessorTryCatch accessor(var, exception);
+ if (accessor.has_exception())
+ return PP_MakeUndefined();
+
+ scoped_array<NPVariant> args;
+ if (argc) {
+ args.reset(new NPVariant[argc]);
+ for (uint32_t i = 0; i < argc; ++i) {
+ if (!PPVarToNPVariantNoCopy(argv[i], &args[i])) {
+ // This argument was invalid, throw an exception & give up.
+ accessor.SetException(kInvalidValueException);
+ return PP_MakeUndefined();
+ }
+ }
+ }
+
+ NPVariant result;
+ if (!WebBindings::construct(NULL, accessor.object()->np_object(),
+ args.get(), argc, &result)) {
+ // An exception may have been raised.
+ accessor.SetException(kUnableToConstructException);
+ return PP_MakeUndefined();
+ }
+
+ PP_Var ret = NPVariantToPPVar(accessor.GetPluginInstance(), &result);
+ WebBindings::releaseVariantValue(&result);
+ return ret;
+}
+
+bool IsInstanceOfDeprecated(PP_Var var,
+ const PPP_Class_Deprecated* ppp_class,
+ void** ppp_class_data) {
+ scoped_refptr<ObjectVar> object(ObjectVar::FromPPVar(var));
+ if (!object)
+ return false; // Not an object at all.
+
+ return PluginObject::IsInstanceOf(object->np_object(),
+ ppp_class, ppp_class_data);
+}
+
+PP_Var CreateObjectDeprecated(PP_Instance instance_id,
+ const PPP_Class_Deprecated* ppp_class,
+ void* ppp_class_data) {
+ PluginInstance* instance = ResourceTracker::Get()->GetInstance(instance_id);
+ if (!instance) {
+ DLOG(ERROR) << "Create object passed an invalid instance.";
+ return PP_MakeNull();
+ }
+ return PluginObject::Create(instance, ppp_class, ppp_class_data);
+}
+
+PP_Var CreateObjectWithModuleDeprecated(PP_Module module_id,
+ const PPP_Class_Deprecated* ppp_class,
+ void* ppp_class_data) {
+ PluginModule* module = ResourceTracker::Get()->GetModule(module_id);
+ if (!module)
+ return PP_MakeNull();
+ return PluginObject::Create(module->GetSomeInstance(),
+ ppp_class, ppp_class_data);
+}
+
+const PPB_Var_Deprecated var_deprecated_interface = {
+ &Var::PluginAddRefPPVar,
+ &Var::PluginReleasePPVar,
+ &VarFromUtf8,
+ &VarToUtf8,
+ &HasPropertyDeprecated,
+ &HasMethodDeprecated,
+ &GetProperty,
+ &EnumerateProperties,
+ &SetPropertyDeprecated,
+ &DeletePropertyDeprecated,
+ &CallDeprecated,
+ &Construct,
+ &IsInstanceOfDeprecated,
+ &CreateObjectDeprecated,
+ &CreateObjectWithModuleDeprecated,
+};
+
+const PPB_Var var_interface = {
+ &Var::PluginAddRefPPVar,
+ &Var::PluginReleasePPVar,
+ &VarFromUtf8,
+ &VarToUtf8
+};
+
+} // namespace
+
+// static
+const PPB_Var* PPB_Var_Impl::GetVarInterface() {
+ return &var_interface;
+}
+
+// static
+const PPB_Var_Deprecated* PPB_Var_Impl::GetVarDeprecatedInterface() {
+ return &var_deprecated_interface;
+}
+
+} // namespace ppapi
+} // namespace webkit
+
diff --git a/webkit/plugins/ppapi/ppb_var_impl.h b/webkit/plugins/ppapi/ppb_var_impl.h
new file mode 100644
index 0000000..d2c63a1
--- /dev/null
+++ b/webkit/plugins/ppapi/ppb_var_impl.h
@@ -0,0 +1,23 @@
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef WEBKIT_PLUGINS_PPAPI_PPB_VAR_IMPL_H_
+#define WEBKIT_PLUGINS_PPAPI_PPB_VAR_IMPL_H_
+
+struct PPB_Var;
+struct PPB_Var_Deprecated;
+
+namespace webkit {
+namespace ppapi {
+
+class PPB_Var_Impl {
+ public:
+ static const PPB_Var* GetVarInterface();
+ static const PPB_Var_Deprecated* GetVarDeprecatedInterface();
+};
+
+} // namespace ppapi
+} // namespace webkit
+
+#endif // WEBKIT_PLUGINS_PPAPI_PPB_VAR_IMPL_H_
diff --git a/webkit/plugins/ppapi/resource_tracker.cc b/webkit/plugins/ppapi/resource_tracker.cc
index edd103b..7e75fe9 100644
--- a/webkit/plugins/ppapi/resource_tracker.cc
+++ b/webkit/plugins/ppapi/resource_tracker.cc
@@ -58,6 +58,8 @@ namespace {
} // namespace
+typedef std::map<NPObject*, ObjectVar*> NPObjectToObjectVarMap;
+
struct ResourceTracker::InstanceData {
InstanceData() : instance(0) {}
@@ -65,10 +67,14 @@ struct ResourceTracker::InstanceData {
// destroyed, it will notify us and we'll delete all associated data.
PluginInstance* instance;
- // Resources and object vars associated with the instance.
+ // Resources associated with the instance.
ResourceSet ref_resources;
std::set<Resource*> assoc_resources;
- VarSet object_vars;
+
+ // Tracks all live ObjectVars used by this module so we can map NPObjects to
+ // the corresponding object, and also release these properly if the instance
+ // goes away when there are still refs. These are non-owning references.
+ NPObjectToObjectVarMap np_object_to_object_var;
// Lazily allocated function proxies for the different interfaces.
scoped_ptr< ::ppapi::FunctionGroupBase >
@@ -159,14 +165,6 @@ int32 ResourceTracker::AddVar(Var* var) {
int32 new_id = MakeTypedId(++last_var_id_, PP_ID_TYPE_VAR);
live_vars_.insert(std::make_pair(new_id, std::make_pair(var, 1)));
- // Object vars must be associated with the instance.
- ObjectVar* object_var = var->AsObjectVar();
- if (object_var) {
- PP_Instance instance = object_var->instance()->pp_instance();
- DCHECK(instance_map_.find(instance) != instance_map_.end());
- instance_map_[instance]->object_vars.insert(new_id);
- }
-
return new_id;
}
@@ -241,24 +239,23 @@ void ResourceTracker::CleanupInstanceData(PP_Instance instance,
}
DCHECK(data.ref_resources.empty());
- // Force delete all var references.
- VarSet::iterator cur_var = data.object_vars.begin();
- while (cur_var != data.object_vars.end()) {
- VarSet::iterator current = cur_var++;
-
- // Tell the corresponding ObjectVar that the instance is gone.
- PP_Var object_pp_var;
- object_pp_var.type = PP_VARTYPE_OBJECT;
- object_pp_var.value.as_id = *current;
- scoped_refptr<ObjectVar> object_var(ObjectVar::FromPPVar(object_pp_var));
- if (object_var.get())
- object_var->InstanceDeleted();
+ // Force delete all var references. Need to make a copy so we can iterate over
+ // the map while deleting stuff from it.
+ NPObjectToObjectVarMap np_object_map_copy = data.np_object_to_object_var;
+ NPObjectToObjectVarMap::iterator cur_var =
+ np_object_map_copy.begin();
+ while (cur_var != np_object_map_copy.end()) {
+ NPObjectToObjectVarMap::iterator current = cur_var++;
// Clear the object from the var mapping and the live instance object list.
- live_vars_.erase(*current);
- data.object_vars.erase(*current);
+ int32 var_id = current->second->GetExistingVarID();
+ if (var_id)
+ live_vars_.erase(var_id);
+
+ current->second->InstanceDeleted();
+ data.np_object_to_object_var.erase(current->first);
}
- DCHECK(data.object_vars.empty());
+ DCHECK(data.np_object_to_object_var.empty());
// Clear any resources that still reference this instance.
for (std::set<Resource*>::iterator res = data.assoc_resources.begin();
@@ -277,7 +274,7 @@ uint32 ResourceTracker::GetLiveObjectsForInstance(
if (found == instance_map_.end())
return 0;
return static_cast<uint32>(found->second->ref_resources.size() +
- found->second->object_vars.size());
+ found->second->np_object_to_object_var.size());
}
::ppapi::ResourceObjectBase* ResourceTracker::GetResourceAPI(
@@ -367,19 +364,51 @@ bool ResourceTracker::UnrefVar(int32 var_id) {
<< var_id << " is not a PP_Var ID.";
VarMap::iterator i = live_vars_.find(var_id);
if (i != live_vars_.end()) {
- if (!--i->second.second) {
- ObjectVar* object_var = i->second.first->AsObjectVar();
- if (object_var) {
- instance_map_[object_var->instance()->pp_instance()]->object_vars.erase(
- var_id);
- }
+ if (!--i->second.second)
live_vars_.erase(i);
- }
return true;
}
return false;
}
+void ResourceTracker::AddNPObjectVar(ObjectVar* object_var) {
+ DCHECK(instance_map_.find(object_var->pp_instance()) != instance_map_.end());
+ InstanceData& data = *instance_map_[object_var->pp_instance()].get();
+
+ DCHECK(data.np_object_to_object_var.find(object_var->np_object()) ==
+ data.np_object_to_object_var.end()) << "ObjectVar already in map";
+ data.np_object_to_object_var[object_var->np_object()] = object_var;
+}
+
+void ResourceTracker::RemoveNPObjectVar(ObjectVar* object_var) {
+ DCHECK(instance_map_.find(object_var->pp_instance()) != instance_map_.end());
+ InstanceData& data = *instance_map_[object_var->pp_instance()].get();
+
+ NPObjectToObjectVarMap::iterator found =
+ data.np_object_to_object_var.find(object_var->np_object());
+ if (found == data.np_object_to_object_var.end()) {
+ NOTREACHED() << "ObjectVar not registered.";
+ return;
+ }
+ if (found->second != object_var) {
+ NOTREACHED() << "ObjectVar doesn't match.";
+ return;
+ }
+ data.np_object_to_object_var.erase(found);
+}
+
+ObjectVar* ResourceTracker::ObjectVarForNPObject(PP_Instance instance,
+ NPObject* np_object) {
+ DCHECK(instance_map_.find(instance) != instance_map_.end());
+ InstanceData& data = *instance_map_[instance].get();
+
+ NPObjectToObjectVarMap::iterator found =
+ data.np_object_to_object_var.find(np_object);
+ if (found == data.np_object_to_object_var.end())
+ return NULL;
+ return found->second;
+}
+
PP_Instance ResourceTracker::AddInstance(PluginInstance* instance) {
DCHECK(instance_map_.find(instance->pp_instance()) == instance_map_.end());
diff --git a/webkit/plugins/ppapi/resource_tracker.h b/webkit/plugins/ppapi/resource_tracker.h
index 84669e1..a079c02 100644
--- a/webkit/plugins/ppapi/resource_tracker.h
+++ b/webkit/plugins/ppapi/resource_tracker.h
@@ -22,9 +22,12 @@
#include "ppapi/shared_impl/function_group_base.h"
#include "ppapi/shared_impl/tracker_base.h"
+typedef struct NPObject NPObject;
+
namespace webkit {
namespace ppapi {
+class ObjectVar;
class PluginInstance;
class PluginModule;
class Resource;
@@ -72,6 +75,18 @@ class ResourceTracker : public ::ppapi::TrackerBase {
bool AddRefVar(int32 var_id);
bool UnrefVar(int32 var_id);
+ // Tracks all live ObjectVar. This is so we can map between instance +
+ // NPObject and get the ObjectVar corresponding to it. This Add/Remove
+ // function is called by the ObjectVar when it is created and
+ // destroyed.
+ void AddNPObjectVar(ObjectVar* object_var);
+ void RemoveNPObjectVar(ObjectVar* object_var);
+
+ // Looks up a previously registered ObjectVar for the given NPObject and
+ // instance. Returns NULL if there is no ObjectVar corresponding to the given
+ // NPObject for the given instance. See AddNPObjectVar above.
+ ObjectVar* ObjectVarForNPObject(PP_Instance instance, NPObject* np_object);
+
// PP_Modules ----------------------------------------------------------------
// Adds a new plugin module to the list of tracked module, and returns a new
@@ -110,9 +125,6 @@ class ResourceTracker : public ::ppapi::TrackerBase {
typedef std::set<PP_Resource> ResourceSet;
- // Indexed by the var ID.
- typedef std::set<int32> VarSet;
-
// Per-instance data we track.
struct InstanceData;
diff --git a/webkit/plugins/ppapi/resource_tracker_unittest.cc b/webkit/plugins/ppapi/resource_tracker_unittest.cc
index 75ea9983..c1199dd 100644
--- a/webkit/plugins/ppapi/resource_tracker_unittest.cc
+++ b/webkit/plugins/ppapi/resource_tracker_unittest.cc
@@ -10,6 +10,7 @@
#include "third_party/npapi/bindings/npruntime.h"
#include "webkit/plugins/ppapi/mock_plugin_delegate.h"
#include "webkit/plugins/ppapi/mock_resource.h"
+#include "webkit/plugins/ppapi/npapi_glue.h"
#include "webkit/plugins/ppapi/ppapi_plugin_instance.h"
#include "webkit/plugins/ppapi/resource_tracker.h"
#include "webkit/plugins/ppapi/var.h"
@@ -181,7 +182,7 @@ TEST_F(ResourceTrackerTest, DeleteObjectVarWithInstance) {
// Make an object var.
scoped_ptr<NPObject> npobject(NewTrackedNPObject());
- ObjectVar::NPObjectToPPVar(instance2.get(), npobject.get());
+ NPObjectToPPVar(instance2.get(), npobject.get());
EXPECT_EQ(1, g_npobjects_alive);
EXPECT_EQ(1u, tracker().GetLiveObjectsForInstance(pp_instance2));
@@ -196,8 +197,8 @@ TEST_F(ResourceTrackerTest, DeleteObjectVarWithInstance) {
TEST_F(ResourceTrackerTest, ReuseVar) {
scoped_ptr<NPObject> npobject(NewTrackedNPObject());
- PP_Var pp_object1 = ObjectVar::NPObjectToPPVar(instance(), npobject.get());
- PP_Var pp_object2 = ObjectVar::NPObjectToPPVar(instance(), npobject.get());
+ PP_Var pp_object1 = NPObjectToPPVar(instance(), npobject.get());
+ PP_Var pp_object2 = NPObjectToPPVar(instance(), npobject.get());
// The two results should be the same.
EXPECT_EQ(pp_object1.value.as_id, pp_object2.value.as_id);
@@ -208,7 +209,7 @@ TEST_F(ResourceTrackerTest, ReuseVar) {
{
scoped_refptr<ObjectVar> check_object(ObjectVar::FromPPVar(pp_object1));
ASSERT_TRUE(check_object.get());
- EXPECT_EQ(instance(), check_object->instance());
+ EXPECT_EQ(instance()->pp_instance(), check_object->pp_instance());
EXPECT_EQ(npobject.get(), check_object->np_object());
}
@@ -218,7 +219,7 @@ TEST_F(ResourceTrackerTest, ReuseVar) {
// Releasing the resource should free the internal ref, and so making a new
// one now should generate a new ID.
- PP_Var pp_object3 = ObjectVar::NPObjectToPPVar(instance(), npobject.get());
+ PP_Var pp_object3 = NPObjectToPPVar(instance(), npobject.get());
EXPECT_NE(pp_object1.value.as_id, pp_object3.value.as_id);
tracker().UnrefVar(static_cast<int32_t>(pp_object3.value.as_id));
}
diff --git a/webkit/plugins/ppapi/var.cc b/webkit/plugins/ppapi/var.cc
index 98ccc23..b061a55 100644
--- a/webkit/plugins/ppapi/var.cc
+++ b/webkit/plugins/ppapi/var.cc
@@ -19,431 +19,12 @@
#include "webkit/plugins/ppapi/plugin_object.h"
#include "webkit/plugins/ppapi/ppapi_plugin_instance.h"
#include "webkit/plugins/ppapi/resource_tracker.h"
-#include "v8/include/v8.h"
using WebKit::WebBindings;
namespace webkit {
namespace ppapi {
-namespace {
-
-const char kInvalidObjectException[] = "Error: Invalid object";
-const char kInvalidPropertyException[] = "Error: Invalid property";
-const char kInvalidValueException[] = "Error: Invalid value";
-const char kUnableToGetPropertyException[] = "Error: Unable to get property";
-const char kUnableToSetPropertyException[] = "Error: Unable to set property";
-const char kUnableToRemovePropertyException[] =
- "Error: Unable to remove property";
-const char kUnableToGetAllPropertiesException[] =
- "Error: Unable to get all properties";
-const char kUnableToCallMethodException[] = "Error: Unable to call method";
-const char kUnableToConstructException[] = "Error: Unable to construct";
-
-// ---------------------------------------------------------------------------
-// Utilities
-
-// Converts the given PP_Var to an NPVariant, returning true on success.
-// False means that the given variant is invalid. In this case, the result
-// NPVariant will be set to a void one.
-//
-// The contents of the PP_Var will NOT be copied, so you need to ensure that
-// the PP_Var remains valid while the resultant NPVariant is in use.
-bool PPVarToNPVariantNoCopy(PP_Var var, NPVariant* result) {
- switch (var.type) {
- case PP_VARTYPE_UNDEFINED:
- VOID_TO_NPVARIANT(*result);
- break;
- case PP_VARTYPE_NULL:
- NULL_TO_NPVARIANT(*result);
- break;
- case PP_VARTYPE_BOOL:
- BOOLEAN_TO_NPVARIANT(var.value.as_bool, *result);
- break;
- case PP_VARTYPE_INT32:
- INT32_TO_NPVARIANT(var.value.as_int, *result);
- break;
- case PP_VARTYPE_DOUBLE:
- DOUBLE_TO_NPVARIANT(var.value.as_double, *result);
- break;
- case PP_VARTYPE_STRING: {
- scoped_refptr<StringVar> string(StringVar::FromPPVar(var));
- if (!string) {
- VOID_TO_NPVARIANT(*result);
- return false;
- }
- const std::string& value = string->value();
- STRINGN_TO_NPVARIANT(value.c_str(), value.size(), *result);
- break;
- }
- case PP_VARTYPE_OBJECT: {
- scoped_refptr<ObjectVar> object(ObjectVar::FromPPVar(var));
- if (!object) {
- VOID_TO_NPVARIANT(*result);
- return false;
- }
- OBJECT_TO_NPVARIANT(object->np_object(), *result);
- break;
- }
- default:
- VOID_TO_NPVARIANT(*result);
- return false;
- }
- return true;
-}
-
-// ObjectAccessorTryCatch ------------------------------------------------------
-
-// Automatically sets up a TryCatch for accessing the object identified by the
-// given PP_Var. The module from the object will be used for the exception
-// strings generated by the TryCatch.
-//
-// This will automatically retrieve the ObjectVar from the object and throw
-// an exception if it's invalid. At the end of construction, if there is no
-// exception, you know that there is no previously set exception, that the
-// object passed in is valid and ready to use (via the object() getter), and
-// that the TryCatch's pp_module() getter is also set up properly and ready to
-// use.
-class ObjectAccessorTryCatch : public TryCatch {
- public:
- ObjectAccessorTryCatch(PP_Var object, PP_Var* exception)
- : TryCatch(0, exception),
- object_(ObjectVar::FromPPVar(object)) {
- if (!object_) {
- // No object or an invalid object was given. This means we have no module
- // to associated with the exception text, so use the magic invalid object
- // exception.
- SetInvalidObjectException();
- } else {
- // When the object is valid, we have a valid module to associate
- set_pp_module(object_->pp_module());
- }
- }
-
- ObjectVar* object() { return object_.get(); }
-
- protected:
- scoped_refptr<ObjectVar> object_;
-
- DISALLOW_COPY_AND_ASSIGN(ObjectAccessorTryCatch);
-};
-
-// ObjectAccessiorWithIdentifierTryCatch ---------------------------------------
-
-// Automatically sets up a TryCatch for accessing the identifier on the given
-// object. This just extends ObjectAccessorTryCatch to additionally convert
-// the given identifier to an NPIdentifier and validate it, throwing an
-// exception if it's invalid.
-//
-// At the end of construction, if there is no exception, you know that there is
-// no previously set exception, that the object passed in is valid and ready to
-// use (via the object() getter), that the identifier is valid and ready to
-// use (via the identifier() getter), and that the TryCatch's pp_module() getter
-// is also set up properly and ready to use.
-class ObjectAccessorWithIdentifierTryCatch : public ObjectAccessorTryCatch {
- public:
- ObjectAccessorWithIdentifierTryCatch(PP_Var object,
- PP_Var identifier,
- PP_Var* exception)
- : ObjectAccessorTryCatch(object, exception),
- identifier_(0) {
- if (!has_exception()) {
- identifier_ = Var::PPVarToNPIdentifier(identifier);
- if (!identifier_)
- SetException(kInvalidPropertyException);
- }
- }
-
- NPIdentifier identifier() const { return identifier_; }
-
- private:
- NPIdentifier identifier_;
-
- DISALLOW_COPY_AND_ASSIGN(ObjectAccessorWithIdentifierTryCatch);
-};
-
-// PPB_Var methods -------------------------------------------------------------
-
-PP_Var VarFromUtf8(PP_Module module, const char* data, uint32_t len) {
- return StringVar::StringToPPVar(module, data, len);
-}
-
-const char* VarToUtf8(PP_Var var, uint32_t* len) {
- scoped_refptr<StringVar> str(StringVar::FromPPVar(var));
- if (!str) {
- *len = 0;
- return NULL;
- }
- *len = static_cast<uint32_t>(str->value().size());
- if (str->value().empty())
- return ""; // Don't return NULL on success.
- return str->value().data();
-}
-
-PP_Var BoolToPPVar(bool value) {
- return PP_MakeBool(BoolToPPBool(value));
-}
-
-PP_Bool HasProperty(PP_Var var,
- PP_Var name,
- PP_Var* exception) {
- ObjectAccessorWithIdentifierTryCatch accessor(var, name, exception);
- if (accessor.has_exception())
- return PP_FALSE;
- return BoolToPPBool(WebBindings::hasProperty(NULL,
- accessor.object()->np_object(),
- accessor.identifier()));
-}
-
-bool HasPropertyDeprecated(PP_Var var,
- PP_Var name,
- PP_Var* exception) {
- return PPBoolToBool(HasProperty(var, name, exception));
-}
-
-bool HasMethodDeprecated(PP_Var var,
- PP_Var name,
- PP_Var* exception) {
- ObjectAccessorWithIdentifierTryCatch accessor(var, name, exception);
- if (accessor.has_exception())
- return false;
- return WebBindings::hasMethod(NULL, accessor.object()->np_object(),
- accessor.identifier());
-}
-
-PP_Var GetProperty(PP_Var var,
- PP_Var name,
- PP_Var* exception) {
- ObjectAccessorWithIdentifierTryCatch accessor(var, name, exception);
- if (accessor.has_exception())
- return PP_MakeUndefined();
-
- NPVariant result;
- if (!WebBindings::getProperty(NULL, accessor.object()->np_object(),
- accessor.identifier(), &result)) {
- // An exception may have been raised.
- accessor.SetException(kUnableToGetPropertyException);
- return PP_MakeUndefined();
- }
-
- PP_Var ret = Var::NPVariantToPPVar(accessor.object()->instance(), &result);
- WebBindings::releaseVariantValue(&result);
- return ret;
-}
-
-void EnumerateProperties(PP_Var var,
- uint32_t* property_count,
- PP_Var** properties,
- PP_Var* exception) {
- *properties = NULL;
- *property_count = 0;
-
- ObjectAccessorTryCatch accessor(var, exception);
- if (accessor.has_exception())
- return;
-
- NPIdentifier* identifiers = NULL;
- uint32_t count = 0;
- if (!WebBindings::enumerate(NULL, accessor.object()->np_object(),
- &identifiers, &count)) {
- accessor.SetException(kUnableToGetAllPropertiesException);
- return;
- }
-
- if (count == 0)
- return;
-
- *property_count = count;
- *properties = static_cast<PP_Var*>(malloc(sizeof(PP_Var) * count));
- for (uint32_t i = 0; i < count; ++i) {
- (*properties)[i] = Var::NPIdentifierToPPVar(
- accessor.object()->instance()->module()->pp_module(),
- identifiers[i]);
- }
- free(identifiers);
-}
-
-void SetPropertyDeprecated(PP_Var var,
- PP_Var name,
- PP_Var value,
- PP_Var* exception) {
- ObjectAccessorWithIdentifierTryCatch accessor(var, name, exception);
- if (accessor.has_exception())
- return;
-
- NPVariant variant;
- if (!PPVarToNPVariantNoCopy(value, &variant)) {
- accessor.SetException(kInvalidValueException);
- return;
- }
- if (!WebBindings::setProperty(NULL, accessor.object()->np_object(),
- accessor.identifier(), &variant))
- accessor.SetException(kUnableToSetPropertyException);
-}
-
-void DeletePropertyDeprecated(PP_Var var,
- PP_Var name,
- PP_Var* exception) {
- ObjectAccessorWithIdentifierTryCatch accessor(var, name, exception);
- if (accessor.has_exception())
- return;
-
- if (!WebBindings::removeProperty(NULL, accessor.object()->np_object(),
- accessor.identifier()))
- accessor.SetException(kUnableToRemovePropertyException);
-}
-
-PP_Var CallDeprecated(PP_Var var,
- PP_Var method_name,
- uint32_t argc,
- PP_Var* argv,
- PP_Var* exception) {
- ObjectAccessorTryCatch accessor(var, exception);
- if (accessor.has_exception())
- return PP_MakeUndefined();
-
- NPIdentifier identifier;
- if (method_name.type == PP_VARTYPE_UNDEFINED) {
- identifier = NULL;
- } else if (method_name.type == PP_VARTYPE_STRING) {
- // Specifically allow only string functions to be called.
- identifier = Var::PPVarToNPIdentifier(method_name);
- if (!identifier) {
- accessor.SetException(kInvalidPropertyException);
- return PP_MakeUndefined();
- }
- } else {
- accessor.SetException(kInvalidPropertyException);
- return PP_MakeUndefined();
- }
-
- scoped_array<NPVariant> args;
- if (argc) {
- args.reset(new NPVariant[argc]);
- for (uint32_t i = 0; i < argc; ++i) {
- if (!PPVarToNPVariantNoCopy(argv[i], &args[i])) {
- // This argument was invalid, throw an exception & give up.
- accessor.SetException(kInvalidValueException);
- return PP_MakeUndefined();
- }
- }
- }
-
- bool ok;
-
- NPVariant result;
- if (identifier) {
- ok = WebBindings::invoke(NULL, accessor.object()->np_object(),
- identifier, args.get(), argc, &result);
- } else {
- ok = WebBindings::invokeDefault(NULL, accessor.object()->np_object(),
- args.get(), argc, &result);
- }
-
- if (!ok) {
- // An exception may have been raised.
- accessor.SetException(kUnableToCallMethodException);
- return PP_MakeUndefined();
- }
-
- PP_Var ret = Var::NPVariantToPPVar(accessor.object()->instance(), &result);
- WebBindings::releaseVariantValue(&result);
- return ret;
-}
-
-PP_Var Construct(PP_Var var,
- uint32_t argc,
- PP_Var* argv,
- PP_Var* exception) {
- ObjectAccessorTryCatch accessor(var, exception);
- if (accessor.has_exception())
- return PP_MakeUndefined();
-
- scoped_array<NPVariant> args;
- if (argc) {
- args.reset(new NPVariant[argc]);
- for (uint32_t i = 0; i < argc; ++i) {
- if (!PPVarToNPVariantNoCopy(argv[i], &args[i])) {
- // This argument was invalid, throw an exception & give up.
- accessor.SetException(kInvalidValueException);
- return PP_MakeUndefined();
- }
- }
- }
-
- NPVariant result;
- if (!WebBindings::construct(NULL, accessor.object()->np_object(),
- args.get(), argc, &result)) {
- // An exception may have been raised.
- accessor.SetException(kUnableToConstructException);
- return PP_MakeUndefined();
- }
-
- PP_Var ret = Var::NPVariantToPPVar(accessor.object()->instance(), &result);
- WebBindings::releaseVariantValue(&result);
- return ret;
-}
-
-bool IsInstanceOfDeprecated(PP_Var var,
- const PPP_Class_Deprecated* ppp_class,
- void** ppp_class_data) {
- scoped_refptr<ObjectVar> object(ObjectVar::FromPPVar(var));
- if (!object)
- return false; // Not an object at all.
-
- return PluginObject::IsInstanceOf(object->np_object(),
- ppp_class, ppp_class_data);
-}
-
-PP_Var CreateObjectDeprecated(PP_Instance instance_id,
- const PPP_Class_Deprecated* ppp_class,
- void* ppp_class_data) {
- PluginInstance* instance = ResourceTracker::Get()->GetInstance(instance_id);
- if (!instance) {
- DLOG(ERROR) << "Create object passed an invalid instance.";
- return PP_MakeNull();
- }
- return PluginObject::Create(instance, ppp_class, ppp_class_data);
-}
-
-PP_Var CreateObjectWithModuleDeprecated(PP_Module module_id,
- const PPP_Class_Deprecated* ppp_class,
- void* ppp_class_data) {
- PluginModule* module = ResourceTracker::Get()->GetModule(module_id);
- if (!module)
- return PP_MakeNull();
- return PluginObject::Create(module->GetSomeInstance(),
- ppp_class, ppp_class_data);
-}
-
-const PPB_Var_Deprecated var_deprecated_interface = {
- &Var::PluginAddRefPPVar,
- &Var::PluginReleasePPVar,
- &VarFromUtf8,
- &VarToUtf8,
- &HasPropertyDeprecated,
- &HasMethodDeprecated,
- &GetProperty,
- &EnumerateProperties,
- &SetPropertyDeprecated,
- &DeletePropertyDeprecated,
- &CallDeprecated,
- &Construct,
- &IsInstanceOfDeprecated,
- &CreateObjectDeprecated,
- &CreateObjectWithModuleDeprecated,
-};
-
-const PPB_Var var_interface = {
- &Var::PluginAddRefPPVar,
- &Var::PluginReleasePPVar,
- &VarFromUtf8,
- &VarToUtf8
-};
-
-
-} // namespace
-
// Var -------------------------------------------------------------------------
Var::Var(PP_Module module) : pp_module_(module), var_id_(0) {
@@ -453,61 +34,6 @@ Var::~Var() {
}
// static
-PP_Var Var::NPVariantToPPVar(PluginInstance* instance,
- const NPVariant* variant) {
- switch (variant->type) {
- case NPVariantType_Void:
- return PP_MakeUndefined();
- case NPVariantType_Null:
- return PP_MakeNull();
- case NPVariantType_Bool:
- return BoolToPPVar(NPVARIANT_TO_BOOLEAN(*variant));
- case NPVariantType_Int32:
- return PP_MakeInt32(NPVARIANT_TO_INT32(*variant));
- case NPVariantType_Double:
- return PP_MakeDouble(NPVARIANT_TO_DOUBLE(*variant));
- case NPVariantType_String:
- return StringVar::StringToPPVar(
- instance->module()->pp_module(),
- NPVARIANT_TO_STRING(*variant).UTF8Characters,
- NPVARIANT_TO_STRING(*variant).UTF8Length);
- case NPVariantType_Object:
- return ObjectVar::NPObjectToPPVar(instance,
- NPVARIANT_TO_OBJECT(*variant));
- }
- NOTREACHED();
- return PP_MakeUndefined();
-}
-
-// static
-NPIdentifier Var::PPVarToNPIdentifier(PP_Var var) {
- switch (var.type) {
- case PP_VARTYPE_STRING: {
- scoped_refptr<StringVar> string(StringVar::FromPPVar(var));
- if (!string)
- return NULL;
- return WebBindings::getStringIdentifier(string->value().c_str());
- }
- case PP_VARTYPE_INT32:
- return WebBindings::getIntIdentifier(var.value.as_int);
- default:
- return NULL;
- }
-}
-
-// static
-PP_Var Var::NPIdentifierToPPVar(PP_Module module, NPIdentifier id) {
- const NPUTF8* string_value = NULL;
- int32_t int_value = 0;
- bool is_string = false;
- WebBindings::extractIdentifierData(id, string_value, int_value, is_string);
- if (is_string)
- return StringVar::StringToPPVar(module, string_value);
-
- return PP_MakeInt32(int_value);
-}
-
-// static
std::string Var::PPVarToLogString(PP_Var var) {
switch (var.type) {
case PP_VARTYPE_UNDEFINED:
@@ -555,15 +81,6 @@ void Var::PluginReleasePPVar(PP_Var var) {
}
}
-// static
-const PPB_Var_Deprecated* Var::GetDeprecatedInterface() {
- return &var_deprecated_interface;
-}
-
-const PPB_Var* Var::GetInterface() {
- return &var_interface;
-}
-
StringVar* Var::AsStringVar() {
return NULL;
}
@@ -572,7 +89,11 @@ ObjectVar* Var::AsObjectVar() {
return NULL;
}
-int32 Var::GetID() {
+int32 Var::GetExistingVarID() const {
+ return var_id_;
+}
+
+int32 Var::GetOrCreateVarID() {
ResourceTracker *tracker = ResourceTracker::Get();
if (var_id_) {
if (!tracker->AddRefVar(var_id_))
@@ -600,7 +121,7 @@ StringVar* StringVar::AsStringVar() {
}
PP_Var StringVar::GetPPVar() {
- int32 id = GetID();
+ int32 id = GetOrCreateVarID();
if (!id)
return PP_MakeNull();
@@ -635,19 +156,22 @@ scoped_refptr<StringVar> StringVar::FromPPVar(PP_Var var) {
return scoped_refptr<StringVar>(var_object->AsStringVar());
}
-// ObjectVar -------------------------------------------------------------
+// ObjectVar -------------------------------------------------------------------
-ObjectVar::ObjectVar(PluginInstance* instance, NPObject* np_object)
- : Var(instance->module()->pp_module()),
- instance_(instance),
+ObjectVar::ObjectVar(PP_Module module,
+ PP_Instance instance,
+ NPObject* np_object)
+ : Var(module),
+ pp_instance_(instance),
np_object_(np_object) {
WebBindings::retainObject(np_object_);
- instance->AddNPObjectVar(this);
+ ResourceTracker::Get()->AddNPObjectVar(this);
}
ObjectVar::~ObjectVar() {
- if (instance_)
- instance_->RemoveNPObjectVar(this);
+ if (pp_instance_)
+ ResourceTracker::Get()->RemoveNPObjectVar(this);
+
WebBindings::releaseObject(np_object_);
}
@@ -656,7 +180,7 @@ ObjectVar* ObjectVar::AsObjectVar() {
}
PP_Var ObjectVar::GetPPVar() {
- int32 id = GetID();
+ int32 id = GetOrCreateVarID();
if (!id)
return PP_MakeNull();
@@ -667,20 +191,8 @@ PP_Var ObjectVar::GetPPVar() {
}
void ObjectVar::InstanceDeleted() {
- DCHECK(instance_);
- instance_ = NULL;
-}
-
-// static
-PP_Var ObjectVar::NPObjectToPPVar(PluginInstance* instance, NPObject* object) {
- DCHECK(object);
- scoped_refptr<ObjectVar> object_var(instance->ObjectVarForNPObject(object));
- if (!object_var) // No object for this module yet, make a new one.
- object_var = new ObjectVar(instance, object);
-
- if (!object_var)
- return PP_MakeUndefined();
- return object_var->GetPPVar();
+ DCHECK(pp_instance_);
+ pp_instance_ = NULL;
}
// static
diff --git a/webkit/plugins/ppapi/var.h b/webkit/plugins/ppapi/var.h
index 730d87e..edbcec7 100644
--- a/webkit/plugins/ppapi/var.h
+++ b/webkit/plugins/ppapi/var.h
@@ -9,6 +9,7 @@
#include "base/compiler_specific.h"
#include "base/memory/ref_counted.h"
+#include "ppapi/c/pp_instance.h"
#include "ppapi/c/pp_module.h"
struct PP_Var;
@@ -22,7 +23,6 @@ namespace webkit {
namespace ppapi {
class ObjectVar;
-class PluginInstance;
class StringVar;
// Var -------------------------------------------------------------------------
@@ -34,26 +34,6 @@ class Var : public base::RefCounted<Var> {
public:
virtual ~Var();
- // Returns a PP_Var that corresponds to the given NPVariant. The contents of
- // the NPVariant will be copied unless the NPVariant corresponds to an
- // object. This will handle all Variant types including POD, strings, and
- // objects.
- //
- // The returned PP_Var will have a refcount of 1, this passing ownership of
- // the reference to the caller. This is suitable for returning to a plugin.
- static PP_Var NPVariantToPPVar(PluginInstance* instance,
- const NPVariant* variant);
-
- // Returns a NPIdentifier that corresponds to the given PP_Var. The contents
- // of the PP_Var will be copied. Returns 0 if the given PP_Var is not a a
- // string or integer type.
- static NPIdentifier PPVarToNPIdentifier(PP_Var var);
-
- // Returns a PP_Var corresponding to the given identifier. In the case of
- // a string identifier, the string will be allocated associated with the
- // given module. A returned string will have a reference count of 1.
- static PP_Var NPIdentifierToPPVar(PP_Module module, NPIdentifier id);
-
// Returns a string representing the given var for logging purposes.
static std::string PPVarToLogString(PP_Var var);
@@ -87,12 +67,6 @@ class Var : public base::RefCounted<Var> {
static void PluginAddRefPPVar(PP_Var var);
static void PluginReleasePPVar(PP_Var var);
- // Returns the PPB_Var_Deprecated interface for the plugin to use.
- static const PPB_Var_Deprecated* GetDeprecatedInterface();
-
- // Returns the PPB_Var interface for the plugin to use.
- static const PPB_Var* GetInterface();
-
virtual StringVar* AsStringVar();
virtual ObjectVar* AsObjectVar();
@@ -100,18 +74,27 @@ class Var : public base::RefCounted<Var> {
// one reference addrefed on behalf of the caller.
virtual PP_Var GetPPVar() = 0;
+ // Returns the ID corresponing to the string or object if it exists already,
+ // or 0 if an ID hasn't been generated for this object (the plugin is holding
+ // no refs).
+ //
+ // Contrast to GetOrCreateVarID which creates the ID and a ref on behalf of
+ // the plugin.
+ int32 GetExistingVarID() const;
+
PP_Module pp_module() const { return pp_module_; }
protected:
// This can only be constructed as a StringVar or an ObjectVar.
explicit Var(PP_Module module);
- // Returns the unique ID associated with this string or object. The return
- // value will be 0 if the string or object is invalid.
+ // Returns the unique ID associated with this string or object, creating it
+ // if necessary. The return value will be 0 if the string or object is
+ // invalid.
//
// This function will take a reference to the var that will be passed to the
// caller.
- int32 GetID();
+ int32 GetOrCreateVarID();
private:
PP_Module pp_module_;
@@ -179,6 +162,11 @@ class StringVar : public Var {
// strings.
class ObjectVar : public Var {
public:
+ // You should always use FromNPObject to create an ObjectVar. This function
+ // guarantees that we maintain the 1:1 mapping between NPObject and
+ // ObjectVar.
+ ObjectVar(PP_Module module, PP_Instance instance, NPObject* np_object);
+
virtual ~ObjectVar();
// Var overrides.
@@ -189,39 +177,20 @@ class ObjectVar : public Var {
// Guaranteed non-NULL.
NPObject* np_object() const { return np_object_; }
- // Notification that the instance was deleted, the internal pointer will be
- // NULLed out.
+ // Notification that the instance was deleted, the internal reference will be
+ // zeroed out.
void InstanceDeleted();
- // Possibly NULL if the object has outlived its instance.
- PluginInstance* instance() const { return instance_; }
-
- // Helper function to create a PP_Var of type object that contains the given
- // NPObject for use byt he given module. Calling this function multiple times
- // given the same module + NPObject results in the same PP_Var, assuming that
- // there is still a PP_Var with a reference open to it from the previous
- // call.
- //
- // The module is necessary because we can have different modules pointing to
- // the same NPObject, and we want to keep their refs separate.
- //
- // If no ObjectVar currently exists corresponding to the NPObject, one is
- // created associated with the given module.
- static PP_Var NPObjectToPPVar(PluginInstance* instance, NPObject* object);
+ // Possibly 0 if the object has outlived its instance.
+ PP_Instance pp_instance() const { return pp_instance_; }
// Helper function that converts a PP_Var to an object. This will return NULL
// if the PP_Var is not of object type or the object is invalid.
static scoped_refptr<ObjectVar> FromPPVar(PP_Var var);
- protected:
- // You should always use FromNPObject to create an ObjectVar. This function
- // guarantees that we maintain the 1:1 mapping between NPObject and
- // ObjectVar.
- ObjectVar(PluginInstance* instance, NPObject* np_object);
-
private:
- // Possibly NULL if the object has outlived its instance.
- PluginInstance* instance_;
+ // Possibly 0 if the object has outlived its instance.
+ PP_Instance pp_instance_;
// Guaranteed non-NULL, this is the underlying object used by WebKit. We
// hold a reference to this object.