Commit a7c03d48 authored by raymes's avatar raymes Committed by Commit bot

Revert of Replace NPObject usage in ppapi with gin (patchset #27 of...

Revert of Replace NPObject usage in ppapi with gin (patchset #27 of https://codereview.chromium.org/459553003/)

Reason for revert:
Failed memory tests:
http://build.chromium.org/p/chromium.memory/builders/Linux%20ASan%20LSan%20Tests%20%282%29/builds/6791

Original issue's description:
> Replace NPObject usage in ppapi with gin
>
> This replaces usage of NPObject in pepper with gin-backed V8 objects. It is unfortunate that this CL is so large, but there isn't a nice way to have the old implementation and the new one side-by-side.
>
> There are 4 major parts to this CL:
> 1) Changing the HostVarTracker to track V8ObjectVars rather than NPObjectVars (host_var_tracker.cc).
> 2) Changing plugin elements (in plugin_object.cc) to be gin-backed objects.
> 3) Changing postMessage bindings (message_channel.cc) be gin-backed objects.
> 4) Changing the implementation of PPB_Var_Deprecated (ppb_var_deprecated_impl.cc) to call directly into V8.
>
>
> BUG=351636
>
> Committed: https://chromium.googlesource.com/chromium/src/+/21f446ae855d60cc896b40cb9a3249ed07f150b3
>
> Committed: https://chromium.googlesource.com/chromium/src/+/ee49e63baf57e503bd71dfe61c8a80df63eac9aa

TBR=jochen@chromium.org,dmichael@chromium.org,kolczyk@opera.com
NOTREECHECKS=true
NOTRY=true
BUG=351636

Review URL: https://codereview.chromium.org/522583002

Cr-Commit-Position: refs/heads/master@{#292574}
parent d4a0b1d5
...@@ -479,6 +479,10 @@ ...@@ -479,6 +479,10 @@
'renderer/pepper/host_var_tracker.h', 'renderer/pepper/host_var_tracker.h',
'renderer/pepper/message_channel.cc', 'renderer/pepper/message_channel.cc',
'renderer/pepper/message_channel.h', 'renderer/pepper/message_channel.h',
'renderer/pepper/npapi_glue.cc',
'renderer/pepper/npapi_glue.h',
'renderer/pepper/npobject_var.cc',
'renderer/pepper/npobject_var.h',
'renderer/pepper/pepper_audio_input_host.cc', 'renderer/pepper/pepper_audio_input_host.cc',
'renderer/pepper/pepper_audio_input_host.h', 'renderer/pepper/pepper_audio_input_host.h',
'renderer/pepper/pepper_broker.cc', 'renderer/pepper/pepper_broker.cc',
......
...@@ -6,37 +6,16 @@ ...@@ -6,37 +6,16 @@
#include "base/logging.h" #include "base/logging.h"
#include "content/renderer/pepper/host_array_buffer_var.h" #include "content/renderer/pepper/host_array_buffer_var.h"
#include "content/renderer/pepper/host_globals.h"
#include "content/renderer/pepper/host_resource_var.h" #include "content/renderer/pepper/host_resource_var.h"
#include "content/renderer/pepper/npobject_var.h"
#include "content/renderer/pepper/pepper_plugin_instance_impl.h" #include "content/renderer/pepper/pepper_plugin_instance_impl.h"
#include "content/renderer/pepper/v8object_var.h"
#include "ppapi/c/pp_var.h" #include "ppapi/c/pp_var.h"
using ppapi::ArrayBufferVar; using ppapi::ArrayBufferVar;
using ppapi::V8ObjectVar; using ppapi::NPObjectVar;
namespace content { namespace content {
HostVarTracker::V8ObjectVarKey::V8ObjectVarKey(V8ObjectVar* object_var)
: instance(object_var->instance()->pp_instance()) {
v8::Local<v8::Object> object = object_var->GetHandle();
hash = object.IsEmpty() ? 0 : object->GetIdentityHash();
}
HostVarTracker::V8ObjectVarKey::V8ObjectVarKey(PP_Instance instance,
v8::Handle<v8::Object> object)
: instance(instance),
hash(object.IsEmpty() ? 0 : object->GetIdentityHash()) {}
HostVarTracker::V8ObjectVarKey::~V8ObjectVarKey() {}
bool HostVarTracker::V8ObjectVarKey::operator<(
const V8ObjectVarKey& other) const {
if (instance == other.instance)
return hash < other.hash;
return instance < other.instance;
}
HostVarTracker::HostVarTracker() HostVarTracker::HostVarTracker()
: VarTracker(SINGLE_THREADED), last_shared_memory_map_id_(0) {} : VarTracker(SINGLE_THREADED), last_shared_memory_map_id_(0) {}
...@@ -52,44 +31,74 @@ ArrayBufferVar* HostVarTracker::CreateShmArrayBuffer( ...@@ -52,44 +31,74 @@ ArrayBufferVar* HostVarTracker::CreateShmArrayBuffer(
return new HostArrayBufferVar(size_in_bytes, handle); return new HostArrayBufferVar(size_in_bytes, handle);
} }
void HostVarTracker::AddV8ObjectVar(V8ObjectVar* object_var) { void HostVarTracker::AddNPObjectVar(NPObjectVar* object_var) {
CheckThreadingPreconditions(); CheckThreadingPreconditions();
v8::HandleScope handle_scope(object_var->instance()->GetIsolate());
DCHECK(GetForV8Object(object_var->instance()->pp_instance(), InstanceMap::iterator found_instance =
object_var->GetHandle()) == object_map_.end()); instance_map_.find(object_var->pp_instance());
object_map_.insert(std::make_pair(V8ObjectVarKey(object_var), object_var)); if (found_instance == instance_map_.end()) {
// Lazily create the instance map.
DCHECK(object_var->pp_instance() != 0);
found_instance =
instance_map_.insert(std::make_pair(
object_var->pp_instance(),
linked_ptr<NPObjectToNPObjectVarMap>(
new NPObjectToNPObjectVarMap))).first;
}
NPObjectToNPObjectVarMap* np_object_map = found_instance->second.get();
DCHECK(np_object_map->find(object_var->np_object()) == np_object_map->end())
<< "NPObjectVar already in map";
np_object_map->insert(std::make_pair(object_var->np_object(), object_var));
} }
void HostVarTracker::RemoveV8ObjectVar(V8ObjectVar* object_var) { void HostVarTracker::RemoveNPObjectVar(NPObjectVar* object_var) {
CheckThreadingPreconditions(); CheckThreadingPreconditions();
v8::HandleScope handle_scope(object_var->instance()->GetIsolate());
ObjectMap::iterator it = GetForV8Object( InstanceMap::iterator found_instance =
object_var->instance()->pp_instance(), object_var->GetHandle()); instance_map_.find(object_var->pp_instance());
DCHECK(it != object_map_.end()); if (found_instance == instance_map_.end()) {
object_map_.erase(it); NOTREACHED() << "NPObjectVar has invalid instance.";
return;
}
NPObjectToNPObjectVarMap* np_object_map = found_instance->second.get();
NPObjectToNPObjectVarMap::iterator found_object =
np_object_map->find(object_var->np_object());
if (found_object == np_object_map->end()) {
NOTREACHED() << "NPObjectVar not registered.";
return;
}
if (found_object->second != object_var) {
NOTREACHED() << "NPObjectVar doesn't match.";
return;
}
np_object_map->erase(found_object);
} }
PP_Var HostVarTracker::V8ObjectVarForV8Object(PP_Instance instance, NPObjectVar* HostVarTracker::NPObjectVarForNPObject(PP_Instance instance,
v8::Handle<v8::Object> object) { NPObject* np_object) {
CheckThreadingPreconditions(); CheckThreadingPreconditions();
ObjectMap::const_iterator it = GetForV8Object(instance, object);
if (it == object_map_.end()) InstanceMap::iterator found_instance = instance_map_.find(instance);
return (new V8ObjectVar(instance, object))->GetPPVar(); if (found_instance == instance_map_.end())
return it->second->GetPPVar(); return NULL; // No such instance.
NPObjectToNPObjectVarMap* np_object_map = found_instance->second.get();
NPObjectToNPObjectVarMap::iterator found_object =
np_object_map->find(np_object);
if (found_object == np_object_map->end())
return NULL; // No such object.
return found_object->second;
} }
int HostVarTracker::GetLiveV8ObjectVarsForTest(PP_Instance instance) { int HostVarTracker::GetLiveNPObjectVarsForInstance(PP_Instance instance) const {
CheckThreadingPreconditions(); CheckThreadingPreconditions();
int count = 0;
// Use a key with an empty handle to find the v8 object var in the map with InstanceMap::const_iterator found = instance_map_.find(instance);
// the given instance and the lowest hash. if (found == instance_map_.end())
V8ObjectVarKey key(instance, v8::Handle<v8::Object>()); return 0;
ObjectMap::const_iterator it = object_map_.lower_bound(key); return static_cast<int>(found->second->size());
while (it != object_map_.end() && it->first.instance == instance) {
++count;
++it;
}
return count;
} }
PP_Var HostVarTracker::MakeResourcePPVarFromMessage( PP_Var HostVarTracker::MakeResourcePPVarFromMessage(
...@@ -107,27 +116,27 @@ ppapi::ResourceVar* HostVarTracker::MakeResourceVar(PP_Resource pp_resource) { ...@@ -107,27 +116,27 @@ ppapi::ResourceVar* HostVarTracker::MakeResourceVar(PP_Resource pp_resource) {
return new HostResourceVar(pp_resource); return new HostResourceVar(pp_resource);
} }
void HostVarTracker::DidDeleteInstance(PP_Instance pp_instance) { void HostVarTracker::DidDeleteInstance(PP_Instance instance) {
CheckThreadingPreconditions(); CheckThreadingPreconditions();
PepperPluginInstanceImpl* instance = InstanceMap::iterator found_instance = instance_map_.find(instance);
HostGlobals::Get()->GetInstance(pp_instance); if (found_instance == instance_map_.end())
v8::HandleScope handle_scope(instance->GetIsolate()); return; // Nothing to do.
// Force delete all var references. ForceReleaseV8Object() will cause NPObjectToNPObjectVarMap* np_object_map = found_instance->second.get();
// Force delete all var references. ForceReleaseNPObject() will cause
// this object, and potentially others it references, to be removed from // this object, and potentially others it references, to be removed from
// |live_vars_|. // |np_object_map|.
while (!np_object_map->empty()) {
// Use a key with an empty handle to find the v8 object var in the map with ForceReleaseNPObject(np_object_map->begin()->second);
// the given instance and the lowest hash.
V8ObjectVarKey key(pp_instance, v8::Handle<v8::Object>());
ObjectMap::iterator it = object_map_.lower_bound(key);
while (it != object_map_.end() && it->first.instance == pp_instance) {
ForceReleaseV8Object(it->second);
object_map_.erase(it++);
} }
// Remove the record for this instance since it should be empty.
DCHECK(np_object_map->empty());
instance_map_.erase(found_instance);
} }
void HostVarTracker::ForceReleaseV8Object(ppapi::V8ObjectVar* object_var) { void HostVarTracker::ForceReleaseNPObject(ppapi::NPObjectVar* object_var) {
object_var->InstanceDeleted(); object_var->InstanceDeleted();
VarMap::iterator iter = live_vars_.find(object_var->GetExistingVarID()); VarMap::iterator iter = live_vars_.find(object_var->GetExistingVarID());
if (iter == live_vars_.end()) { if (iter == live_vars_.end()) {
...@@ -139,19 +148,6 @@ void HostVarTracker::ForceReleaseV8Object(ppapi::V8ObjectVar* object_var) { ...@@ -139,19 +148,6 @@ void HostVarTracker::ForceReleaseV8Object(ppapi::V8ObjectVar* object_var) {
DeleteObjectInfoIfNecessary(iter); DeleteObjectInfoIfNecessary(iter);
} }
HostVarTracker::ObjectMap::iterator HostVarTracker::GetForV8Object(
PP_Instance instance,
v8::Handle<v8::Object> object) {
std::pair<ObjectMap::iterator, ObjectMap::iterator> range =
object_map_.equal_range(V8ObjectVarKey(instance, object));
for (ObjectMap::iterator it = range.first; it != range.second; ++it) {
if (object == it->second->GetHandle())
return it;
}
return object_map_.end();
}
int HostVarTracker::TrackSharedMemoryHandle(PP_Instance instance, int HostVarTracker::TrackSharedMemoryHandle(PP_Instance instance,
base::SharedMemoryHandle handle, base::SharedMemoryHandle handle,
uint32 size_in_bytes) { uint32 size_in_bytes) {
......
...@@ -20,30 +20,52 @@ ...@@ -20,30 +20,52 @@
#include "ppapi/shared_impl/var_tracker.h" #include "ppapi/shared_impl/var_tracker.h"
#include "v8/include/v8.h" #include "v8/include/v8.h"
typedef struct NPObject NPObject;
namespace ppapi { namespace ppapi {
class ArrayBufferVar; class ArrayBufferVar;
class NPObjectVar;
class V8ObjectVar; class V8ObjectVar;
class Var; class Var;
} }
namespace content { namespace content {
// Adds NPObject var tracking to the standard PPAPI VarTracker for use in the
// renderer.
class HostVarTracker : public ppapi::VarTracker { class HostVarTracker : public ppapi::VarTracker {
public: public:
HostVarTracker(); HostVarTracker();
virtual ~HostVarTracker(); virtual ~HostVarTracker();
// Tracks all live NPObjectVar. This is so we can map between instance +
// NPObject and get the NPObjectVar corresponding to it. This Add/Remove
// function is called by the NPObjectVar when it is created and
// destroyed.
void AddNPObjectVar(ppapi::NPObjectVar* object_var);
void RemoveNPObjectVar(ppapi::NPObjectVar* object_var);
// Looks up a previously registered NPObjectVar for the given NPObject and
// instance. Returns NULL if there is no NPObjectVar corresponding to the
// given NPObject for the given instance. See AddNPObjectVar above.
ppapi::NPObjectVar* NPObjectVarForNPObject(PP_Instance instance,
NPObject* np_object);
// Returns the number of NPObjectVar's associated with the given instance.
// Returns 0 if the instance isn't known.
CONTENT_EXPORT int GetLiveNPObjectVarsForInstance(PP_Instance instance) const;
// Tracks all live V8ObjectVar. This is so we can map between instance + // Tracks all live V8ObjectVar. This is so we can map between instance +
// V8Object and get the V8ObjectVar corresponding to it. This Add/Remove // V8Object and get the V8ObjectVar corresponding to it. This Add/Remove
// function is called by the V8ObjectVar when it is created and destroyed. // function is called by the V8ObjectVar when it is created and destroyed.
void AddV8ObjectVar(ppapi::V8ObjectVar* object_var); void AddV8ObjectVar(ppapi::V8ObjectVar* object_var) { NOTIMPLEMENTED(); }
void RemoveV8ObjectVar(ppapi::V8ObjectVar* object_var); void RemoveV8ObjectVar(ppapi::V8ObjectVar* object_var) { NOTIMPLEMENTED(); }
// Creates or retrieves a V8ObjectVar. // Creates or retrieves a V8ObjectVar.
PP_Var V8ObjectVarForV8Object(PP_Instance instance, PP_Var V8ObjectVarForV8Object(PP_Instance instance,
v8::Handle<v8::Object> object); v8::Handle<v8::Object> object) {
// Returns the number of V8ObjectVars associated with the given instance. NOTIMPLEMENTED();
// Returns 0 if the instance isn't known. return PP_MakeUndefined();
CONTENT_EXPORT int GetLiveV8ObjectVarsForTest(PP_Instance instance); }
// VarTracker public implementation. // VarTracker public implementation.
virtual PP_Var MakeResourcePPVarFromMessage( virtual PP_Var MakeResourcePPVarFromMessage(
...@@ -52,7 +74,7 @@ class HostVarTracker : public ppapi::VarTracker { ...@@ -52,7 +74,7 @@ class HostVarTracker : public ppapi::VarTracker {
int pending_renderer_id, int pending_renderer_id,
int pending_browser_id) OVERRIDE; int pending_browser_id) OVERRIDE;
virtual ppapi::ResourceVar* MakeResourceVar(PP_Resource pp_resource) OVERRIDE; virtual ppapi::ResourceVar* MakeResourceVar(PP_Resource pp_resource) OVERRIDE;
virtual void DidDeleteInstance(PP_Instance pp_instance) OVERRIDE; virtual void DidDeleteInstance(PP_Instance instance) OVERRIDE;
virtual int TrackSharedMemoryHandle(PP_Instance instance, virtual int TrackSharedMemoryHandle(PP_Instance instance,
base::SharedMemoryHandle file, base::SharedMemoryHandle file,
...@@ -72,30 +94,20 @@ class HostVarTracker : public ppapi::VarTracker { ...@@ -72,30 +94,20 @@ class HostVarTracker : public ppapi::VarTracker {
// Clear the reference count of the given object and remove it from // Clear the reference count of the given object and remove it from
// live_vars_. // live_vars_.
void ForceReleaseV8Object(ppapi::V8ObjectVar* object_var); void ForceReleaseNPObject(ppapi::NPObjectVar* object_var);
// A non-unique, ordered key for a V8ObjectVar. Contains the hash of the v8 typedef std::map<NPObject*, ppapi::NPObjectVar*> NPObjectToNPObjectVarMap;
// and the instance it is associated with.
struct V8ObjectVarKey { // Lists all known NPObjects, first indexed by the corresponding instance,
explicit V8ObjectVarKey(ppapi::V8ObjectVar* object_var); // then by the NPObject*. This allows us to look up an NPObjectVar given
V8ObjectVarKey(PP_Instance i, v8::Handle<v8::Object> object); // these two pieces of information.
~V8ObjectVarKey(); //
// The instance map is lazily managed, so we'll add the
bool operator<(const V8ObjectVarKey& other) const; // NPObjectToNPObjectVarMap lazily when the first NPObject var is created,
// and delete it when it's empty.
PP_Instance instance; typedef std::map<PP_Instance, linked_ptr<NPObjectToNPObjectVarMap> >
int hash; InstanceMap;
}; InstanceMap instance_map_;
typedef std::multimap<V8ObjectVarKey, ppapi::V8ObjectVar*> ObjectMap;
// Returns an iterator into |object_map| which points to V8Object which
// is associated with the given instance and object.
ObjectMap::iterator GetForV8Object(PP_Instance instance,
v8::Handle<v8::Object> object);
// A multimap of V8ObjectVarKey -> ObjectMap.
ObjectMap object_map_;
// Tracks all shared memory handles used for transmitting array buffers. // Tracks all shared memory handles used for transmitting array buffers.
struct SharedMemoryMapEntry { struct SharedMemoryMapEntry {
......
...@@ -2,133 +2,115 @@ ...@@ -2,133 +2,115 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
#include "base/basictypes.h"
#include "base/memory/scoped_ptr.h" #include "base/memory/scoped_ptr.h"
#include "content/renderer/pepper/host_globals.h" #include "content/renderer/pepper/host_globals.h"
#include "content/renderer/pepper/host_var_tracker.h" #include "content/renderer/pepper/host_var_tracker.h"
#include "content/renderer/pepper/mock_resource.h" #include "content/renderer/pepper/mock_resource.h"
#include "content/renderer/pepper/npapi_glue.h"
#include "content/renderer/pepper/npobject_var.h"
#include "content/renderer/pepper/pepper_plugin_instance_impl.h" #include "content/renderer/pepper/pepper_plugin_instance_impl.h"
#include "content/renderer/pepper/pepper_try_catch.h"
#include "content/renderer/pepper/v8object_var.h"
#include "content/test/ppapi_unittest.h" #include "content/test/ppapi_unittest.h"
#include "gin/handle.h"
#include "gin/wrappable.h"
#include "ppapi/c/pp_var.h" #include "ppapi/c/pp_var.h"
#include "ppapi/c/ppp_instance.h" #include "ppapi/c/ppp_instance.h"
#include "third_party/npapi/bindings/npruntime.h"
#include "third_party/WebKit/public/web/WebBindings.h" #include "third_party/WebKit/public/web/WebBindings.h"
using ppapi::V8ObjectVar; using ppapi::NPObjectVar;
namespace content { namespace content {
namespace { namespace {
int g_v8objects_alive = 0; // Tracked NPObjects -----------------------------------------------------------
class MyObject : public gin::Wrappable<MyObject> { int g_npobjects_alive = 0;
public:
static gin::WrapperInfo kWrapperInfo;
static v8::Handle<v8::Value> Create(v8::Isolate* isolate) {
return gin::CreateHandle(isolate, new MyObject()).ToV8();
}
private:
MyObject() { ++g_v8objects_alive; }
virtual ~MyObject() { --g_v8objects_alive; }
DISALLOW_COPY_AND_ASSIGN(MyObject); void TrackedClassDeallocate(NPObject* npobject) {
}; g_npobjects_alive--;
delete npobject;
}
gin::WrapperInfo MyObject::kWrapperInfo = {gin::kEmbedderNativeGin}; NPClass g_tracked_npclass = {
NP_CLASS_STRUCT_VERSION, NULL, &TrackedClassDeallocate, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, };
class PepperTryCatchForTest : public PepperTryCatch { // Returns a new tracked NPObject with a refcount of 1. You'll want to put this
public: // in a NPObjectReleaser to free this ref when the test completes.
explicit PepperTryCatchForTest(PepperPluginInstanceImpl* instance) NPObject* NewTrackedNPObject() {
: PepperTryCatch(instance, V8VarConverter::kAllowObjectVars), NPObject* object = new NPObject;
handle_scope_(instance->GetIsolate()), object->_class = &g_tracked_npclass;
context_scope_(v8::Context::New(instance->GetIsolate())) {} object->referenceCount = 1;
virtual void SetException(const char* message) OVERRIDE { NOTREACHED(); }
virtual v8::Handle<v8::Context> GetContext() OVERRIDE {
return instance_->GetIsolate()->GetCurrentContext();
}
private: g_npobjects_alive++;
v8::HandleScope handle_scope_; return object;
v8::Context::Scope context_scope_; }
DISALLOW_COPY_AND_ASSIGN(PepperTryCatchForTest); struct ReleaseNPObject {
void operator()(NPObject* o) const { blink::WebBindings::releaseObject(o); }
}; };
// Handles automatically releasing a reference to the NPObject on destruction.
// It's assumed the input has a ref already taken.
typedef scoped_ptr<NPObject, ReleaseNPObject> NPObjectReleaser;
} // namespace } // namespace
class HostVarTrackerTest : public PpapiUnittest { class HostVarTrackerTest : public PpapiUnittest {
public: public:
HostVarTrackerTest() {} HostVarTrackerTest() {}
virtual void TearDown() OVERRIDE {
v8::Isolate::GetCurrent()->RequestGarbageCollectionForTesting(
v8::Isolate::kFullGarbageCollection);
EXPECT_EQ(0, g_v8objects_alive);
PpapiUnittest::TearDown();
}
HostVarTracker& tracker() { return *HostGlobals::Get()->host_var_tracker(); } HostVarTracker& tracker() { return *HostGlobals::Get()->host_var_tracker(); }
}; };
TEST_F(HostVarTrackerTest, DeleteObjectVarWithInstance) { TEST_F(HostVarTrackerTest, DeleteObjectVarWithInstance) {
v8::Isolate* test_isolate = v8::Isolate::GetCurrent();
// Make a second instance (the test harness already creates & manages one). // Make a second instance (the test harness already creates & manages one).
scoped_refptr<PepperPluginInstanceImpl> instance2( scoped_refptr<PepperPluginInstanceImpl> instance2(
PepperPluginInstanceImpl::Create(NULL, module(), NULL, GURL())); PepperPluginInstanceImpl::Create(NULL, module(), NULL, GURL()));
PP_Instance pp_instance2 = instance2->pp_instance(); PP_Instance pp_instance2 = instance2->pp_instance();
{ // Make an object var.
PepperTryCatchForTest try_catch(instance2.get()); NPObjectReleaser npobject(NewTrackedNPObject());
// Make an object var. NPObjectToPPVarForTest(instance2.get(), npobject.get());
ppapi::ScopedPPVar var = try_catch.FromV8(MyObject::Create(test_isolate));
EXPECT_EQ(1, g_v8objects_alive); EXPECT_EQ(1, g_npobjects_alive);
EXPECT_EQ(1, tracker().GetLiveV8ObjectVarsForTest(pp_instance2)); EXPECT_EQ(1, tracker().GetLiveNPObjectVarsForInstance(pp_instance2));
// Purposely leak the var.
var.Release();
}
// Free the instance, this should release the ObjectVar. // Free the instance, this should release the ObjectVar.
instance2 = NULL; instance2 = NULL;
EXPECT_EQ(0, tracker().GetLiveV8ObjectVarsForTest(pp_instance2)); EXPECT_EQ(0, tracker().GetLiveNPObjectVarsForInstance(pp_instance2));
} }
// Make sure that using the same NPObject should give the same PP_Var // Make sure that using the same NPObject should give the same PP_Var
// each time. // each time.
TEST_F(HostVarTrackerTest, ReuseVar) { TEST_F(HostVarTrackerTest, ReuseVar) {
PepperTryCatchForTest try_catch(instance()); NPObjectReleaser npobject(NewTrackedNPObject());
v8::Handle<v8::Value> v8_object = MyObject::Create(v8::Isolate::GetCurrent()); PP_Var pp_object1 = NPObjectToPPVarForTest(instance(), npobject.get());
ppapi::ScopedPPVar pp_object1 = try_catch.FromV8(v8_object); PP_Var pp_object2 = NPObjectToPPVarForTest(instance(), npobject.get());
ppapi::ScopedPPVar pp_object2 = try_catch.FromV8(v8_object);
// The two results should be the same. // The two results should be the same.
EXPECT_EQ(pp_object1.get().value.as_id, pp_object2.get().value.as_id); EXPECT_EQ(pp_object1.value.as_id, pp_object2.value.as_id);
// The objects should be able to get us back to the associated v8 object. // The objects should be able to get us back to the associated NPObject.
// This ObjectVar must be released before we do NPObjectToPPVarForTest again
// below so it gets freed and we get a new identifier.
{ {
scoped_refptr<V8ObjectVar> check_object( scoped_refptr<NPObjectVar> check_object(NPObjectVar::FromPPVar(pp_object1));
V8ObjectVar::FromPPVar(pp_object1.get()));
ASSERT_TRUE(check_object.get()); ASSERT_TRUE(check_object.get());
EXPECT_EQ(instance(), check_object->instance()); EXPECT_EQ(instance()->pp_instance(), check_object->pp_instance());
EXPECT_EQ(v8_object, check_object->GetHandle()); EXPECT_EQ(npobject.get(), check_object->np_object());
} }
// Remove both of the refs we made above. // Remove both of the refs we made above.
pp_object1 = ppapi::ScopedPPVar(); ppapi::VarTracker* var_tracker = ppapi::PpapiGlobals::Get()->GetVarTracker();
pp_object2 = ppapi::ScopedPPVar(); var_tracker->ReleaseVar(static_cast<int32_t>(pp_object2.value.as_id));
var_tracker->ReleaseVar(static_cast<int32_t>(pp_object1.value.as_id));
// Releasing the resource should free the internal ref, and so making a new // Releasing the resource should free the internal ref, and so making a new
// one now should generate a new ID. // one now should generate a new ID.
ppapi::ScopedPPVar pp_object3 = try_catch.FromV8(v8_object); PP_Var pp_object3 = NPObjectToPPVarForTest(instance(), npobject.get());
EXPECT_NE(pp_object1.get().value.as_id, pp_object3.get().value.as_id); EXPECT_NE(pp_object1.value.as_id, pp_object3.value.as_id);
var_tracker->ReleaseVar(static_cast<int32_t>(pp_object3.value.as_id));
} }
} // namespace content } // namespace content
This diff is collapsed.
...@@ -9,29 +9,20 @@ ...@@ -9,29 +9,20 @@
#include <list> #include <list>
#include <map> #include <map>
#include "base/basictypes.h"
#include "base/memory/weak_ptr.h" #include "base/memory/weak_ptr.h"
#include "gin/handle.h"
#include "gin/interceptor.h"
#include "gin/wrappable.h"
#include "ppapi/shared_impl/resource.h" #include "ppapi/shared_impl/resource.h"
#include "third_party/WebKit/public/web/WebSerializedScriptValue.h" #include "third_party/WebKit/public/web/WebSerializedScriptValue.h"
#include "v8/include/v8.h" #include "third_party/npapi/bindings/npruntime.h"
struct PP_Var; struct PP_Var;
namespace gin {
class Arguments;
} // namespace gin
namespace ppapi { namespace ppapi {
class ScopedPPVar; class ScopedPPVar;
} // namespace ppapi }
namespace content { namespace content {
class PepperPluginInstanceImpl; class PepperPluginInstanceImpl;
class PluginObject;
// MessageChannel implements bidirectional postMessage functionality, allowing // MessageChannel implements bidirectional postMessage functionality, allowing
// calls from JavaScript to plugins and vice-versa. See // calls from JavaScript to plugins and vice-versa. See
...@@ -46,77 +37,64 @@ class PluginObject; ...@@ -46,77 +37,64 @@ class PluginObject;
// - The message target won't be limited to instance, and should support // - The message target won't be limited to instance, and should support
// either plugin-provided or JS objects. // either plugin-provided or JS objects.
// TODO(dmichael): Add support for separate MessagePorts. // TODO(dmichael): Add support for separate MessagePorts.
class MessageChannel : public gin::Wrappable<MessageChannel>, class MessageChannel {
public gin::NamedPropertyInterceptor {
public: public:
static gin::WrapperInfo kWrapperInfo; // MessageChannelNPObject is a simple struct that adds a pointer back to a
// MessageChannel instance. This way, we can use an NPObject to allow
// Creates a MessageChannel, returning a pointer to it and sets |result| to // JavaScript interactions without forcing MessageChannel to inherit from
// the v8 object which is backed by the message channel. The returned pointer // NPObject.
// is only valid as long as the object in |result| is alive. struct MessageChannelNPObject : public NPObject {
static MessageChannel* Create(PepperPluginInstanceImpl* instance, MessageChannelNPObject();
v8::Persistent<v8::Object>* result); ~MessageChannelNPObject();
virtual ~MessageChannel(); base::WeakPtr<MessageChannel> message_channel;
};
// Called when the instance is deleted. The MessageChannel might outlive the
// plugin instance because it is garbage collected.
void InstanceDeleted();
// Post a message to the onmessage handler for this channel's instance explicit MessageChannel(PepperPluginInstanceImpl* instance);
// asynchronously. ~MessageChannel();
void PostMessageToJavaScript(PP_Var message_data);
// Messages are queued initially. After the PepperPluginInstanceImpl is ready // Messages are queued initially. After the PepperPluginInstanceImpl is ready
// to send and handle messages, users of MessageChannel should call // to send and handle messages, users of MessageChannel should call
// Start(). // Start().
void Start(); void Start();
// Set the V8Object to which we should forward any calls which aren't // Return the NPObject* to which we should forward any calls which aren't
// related to postMessage. Note that this can be empty; it only gets set if // related to postMessage. Note that this can be NULL; it only gets set if
// there is a scriptable 'InstanceObject' associated with this channel's // there is a scriptable 'InstanceObject' associated with this channel's
// instance. // instance.
void SetPassthroughObject(v8::Handle<v8::Object> passthrough); NPObject* passthrough_object() { return passthrough_object_; }
void SetPassthroughObject(NPObject* passthrough);
NPObject* np_object() { return np_object_; }
PepperPluginInstanceImpl* instance() { return instance_; } PepperPluginInstanceImpl* instance() { return instance_; }
bool GetReadOnlyProperty(NPIdentifier key, NPVariant* value) const;
void SetReadOnlyProperty(PP_Var key, PP_Var value); void SetReadOnlyProperty(PP_Var key, PP_Var value);
private: // Post a message to the onmessage handler for this channel's instance
// Struct for storing the result of a v8 object being converted to a PP_Var. // asynchronously.
struct VarConversionResult; void PostMessageToJavaScript(PP_Var message_data);
explicit MessageChannel(PepperPluginInstanceImpl* instance);
// gin::NamedPropertyInterceptor
virtual v8::Local<v8::Value> GetNamedProperty(
v8::Isolate* isolate,
const std::string& property) OVERRIDE;
virtual bool SetNamedProperty(v8::Isolate* isolate,
const std::string& property,
v8::Local<v8::Value> value) OVERRIDE;
virtual std::vector<std::string> EnumerateNamedProperties(
v8::Isolate* isolate) OVERRIDE;
// gin::Wrappable
virtual gin::ObjectTemplateBuilder GetObjectTemplateBuilder(
v8::Isolate* isolate) OVERRIDE;
// Post a message to the plugin's HandleMessage function for this channel's // Post a message to the plugin's HandleMessage function for this channel's
// instance. // instance.
void PostMessageToNative(gin::Arguments* args); void PostMessageToNative(const NPVariant* message_data);
// Post a message to the plugin's HandleBlocking Message function for this // Post a message to the plugin's HandleBlocking Message function for this
// channel's instance synchronously, and return a result. // channel's instance synchronously, and return a result.
void PostBlockingMessageToNative(gin::Arguments* args); void PostBlockingMessageToNative(const NPVariant* message_data,
NPVariant* np_result);
private:
// Struct for storing the result of a NPVariant being converted to a PP_Var.
struct VarConversionResult;
// Post a message to the onmessage handler for this channel's instance // Post a message to the onmessage handler for this channel's instance
// synchronously. This is used by PostMessageToJavaScript. // synchronously. This is used by PostMessageToJavaScript.
void PostMessageToJavaScriptImpl( void PostMessageToJavaScriptImpl(
const blink::WebSerializedScriptValue& message_data); const blink::WebSerializedScriptValue& message_data);
PluginObject* GetPluginObject(v8::Isolate* isolate); void EnqueuePluginMessage(const NPVariant* variant);
void EnqueuePluginMessage(v8::Handle<v8::Value> v8_value);
void FromV8ValueComplete(VarConversionResult* result_holder, void FromV8ValueComplete(VarConversionResult* result_holder,
const ppapi::ScopedPPVar& result_var, const ppapi::ScopedPPVar& result_var,
...@@ -132,7 +110,10 @@ class MessageChannel : public gin::Wrappable<MessageChannel>, ...@@ -132,7 +110,10 @@ class MessageChannel : public gin::Wrappable<MessageChannel>,
// postMessage. This is necessary to support backwards-compatibility, and // postMessage. This is necessary to support backwards-compatibility, and
// also trusted plugins for which we will continue to support synchronous // also trusted plugins for which we will continue to support synchronous
// scripting. // scripting.
v8::Persistent<v8::Object> passthrough_object_; NPObject* passthrough_object_;
// The NPObject we use to expose postMessage to JavaScript.
MessageChannelNPObject* np_object_;
std::deque<blink::WebSerializedScriptValue> early_message_queue_; std::deque<blink::WebSerializedScriptValue> early_message_queue_;
enum EarlyMessageQueueState { enum EarlyMessageQueueState {
...@@ -151,7 +132,7 @@ class MessageChannel : public gin::Wrappable<MessageChannel>, ...@@ -151,7 +132,7 @@ class MessageChannel : public gin::Wrappable<MessageChannel>,
// probably also work, but is less clearly specified). // probably also work, but is less clearly specified).
std::list<VarConversionResult> plugin_message_queue_; std::list<VarConversionResult> plugin_message_queue_;
std::map<std::string, ppapi::ScopedPPVar> internal_named_properties_; std::map<NPIdentifier, ppapi::ScopedPPVar> internal_properties_;
// This is used to ensure pending tasks will not fire after this object is // This is used to ensure pending tasks will not fire after this object is
// destroyed. // destroyed.
......
...@@ -33,12 +33,12 @@ ...@@ -33,12 +33,12 @@
#include "content/renderer/pepper/host_dispatcher_wrapper.h" #include "content/renderer/pepper/host_dispatcher_wrapper.h"
#include "content/renderer/pepper/host_globals.h" #include "content/renderer/pepper/host_globals.h"
#include "content/renderer/pepper/message_channel.h" #include "content/renderer/pepper/message_channel.h"
#include "content/renderer/pepper/npapi_glue.h"
#include "content/renderer/pepper/pepper_browser_connection.h" #include "content/renderer/pepper/pepper_browser_connection.h"
#include "content/renderer/pepper/pepper_compositor_host.h" #include "content/renderer/pepper/pepper_compositor_host.h"
#include "content/renderer/pepper/pepper_file_ref_renderer_host.h" #include "content/renderer/pepper/pepper_file_ref_renderer_host.h"
#include "content/renderer/pepper/pepper_graphics_2d_host.h" #include "content/renderer/pepper/pepper_graphics_2d_host.h"
#include "content/renderer/pepper/pepper_in_process_router.h" #include "content/renderer/pepper/pepper_in_process_router.h"
#include "content/renderer/pepper/pepper_try_catch.h"
#include "content/renderer/pepper/pepper_url_loader_host.h" #include "content/renderer/pepper/pepper_url_loader_host.h"
#include "content/renderer/pepper/plugin_module.h" #include "content/renderer/pepper/plugin_module.h"
#include "content/renderer/pepper/plugin_object.h" #include "content/renderer/pepper/plugin_object.h"
...@@ -115,7 +115,6 @@ ...@@ -115,7 +115,6 @@
#include "third_party/WebKit/public/web/WebPrintParams.h" #include "third_party/WebKit/public/web/WebPrintParams.h"
#include "third_party/WebKit/public/web/WebPrintScalingOption.h" #include "third_party/WebKit/public/web/WebPrintScalingOption.h"
#include "third_party/WebKit/public/web/WebScopedUserGesture.h" #include "third_party/WebKit/public/web/WebScopedUserGesture.h"
#include "third_party/WebKit/public/web/WebScriptSource.h"
#include "third_party/WebKit/public/web/WebSecurityOrigin.h" #include "third_party/WebKit/public/web/WebSecurityOrigin.h"
#include "third_party/WebKit/public/web/WebUserGestureIndicator.h" #include "third_party/WebKit/public/web/WebUserGestureIndicator.h"
#include "third_party/WebKit/public/web/WebView.h" #include "third_party/WebKit/public/web/WebView.h"
...@@ -556,6 +555,7 @@ PepperPluginInstanceImpl::PepperPluginInstanceImpl( ...@@ -556,6 +555,7 @@ PepperPluginInstanceImpl::PepperPluginInstanceImpl(
pending_user_gesture_(0.0), pending_user_gesture_(0.0),
document_loader_(NULL), document_loader_(NULL),
external_document_load_(false), external_document_load_(false),
npp_(new NPP_t),
isolate_(v8::Isolate::GetCurrent()), isolate_(v8::Isolate::GetCurrent()),
is_deleted_(false), is_deleted_(false),
last_input_number_(0), last_input_number_(0),
...@@ -616,8 +616,8 @@ PepperPluginInstanceImpl::PepperPluginInstanceImpl( ...@@ -616,8 +616,8 @@ PepperPluginInstanceImpl::PepperPluginInstanceImpl(
PepperPluginInstanceImpl::~PepperPluginInstanceImpl() { PepperPluginInstanceImpl::~PepperPluginInstanceImpl() {
DCHECK(!fullscreen_container_); DCHECK(!fullscreen_container_);
// Notify all the plugin objects of deletion. This will prevent blink from // Free all the plugin objects. This will automatically clear the back-
// calling into the plugin any more. // pointer from the NPObject so WebKit can't call into the plugin any more.
// //
// Swap out the set so we can delete from it (the objects will try to // Swap out the set so we can delete from it (the objects will try to
// unregister themselves inside the delete call). // unregister themselves inside the delete call).
...@@ -625,15 +625,8 @@ PepperPluginInstanceImpl::~PepperPluginInstanceImpl() { ...@@ -625,15 +625,8 @@ PepperPluginInstanceImpl::~PepperPluginInstanceImpl() {
live_plugin_objects_.swap(plugin_object_copy); live_plugin_objects_.swap(plugin_object_copy);
for (PluginObjectSet::iterator i = plugin_object_copy.begin(); for (PluginObjectSet::iterator i = plugin_object_copy.begin();
i != plugin_object_copy.end(); i != plugin_object_copy.end();
++i) { ++i)
(*i)->InstanceDeleted(); delete *i;
}
if (message_channel_) {
message_channel_->InstanceDeleted();
message_channel_object_.Reset();
message_channel_ = NULL;
}
if (TrackedCallback::IsPending(lock_mouse_callback_)) if (TrackedCallback::IsPending(lock_mouse_callback_))
lock_mouse_callback_->Abort(); lock_mouse_callback_->Abort();
...@@ -664,10 +657,6 @@ PepperPluginInstanceImpl::~PepperPluginInstanceImpl() { ...@@ -664,10 +657,6 @@ PepperPluginInstanceImpl::~PepperPluginInstanceImpl() {
// If a method needs to access a member of the instance after the call has // If a method needs to access a member of the instance after the call has
// returned, then it needs to keep its own reference on the stack. // returned, then it needs to keep its own reference on the stack.
v8::Local<v8::Object> PepperPluginInstanceImpl::GetMessageChannelObject() {
return v8::Local<v8::Object>::New(isolate_, message_channel_object_);
}
v8::Local<v8::Context> PepperPluginInstanceImpl::GetContext() { v8::Local<v8::Context> PepperPluginInstanceImpl::GetContext() {
if (!container_) if (!container_)
return v8::Handle<v8::Context>(); return v8::Handle<v8::Context>();
...@@ -694,7 +683,7 @@ void PepperPluginInstanceImpl::Delete() { ...@@ -694,7 +683,7 @@ void PepperPluginInstanceImpl::Delete() {
// release our last reference to the "InstanceObject" and will probably // release our last reference to the "InstanceObject" and will probably
// destroy it. We want to do this prior to calling DidDestroy in case the // destroy it. We want to do this prior to calling DidDestroy in case the
// destructor of the instance object tries to use the instance. // destructor of the instance object tries to use the instance.
message_channel_->SetPassthroughObject(v8::Handle<v8::Object>()); message_channel_->SetPassthroughObject(NULL);
// If this is a NaCl plugin instance, shut down the NaCl plugin by calling // If this is a NaCl plugin instance, shut down the NaCl plugin by calling
// its DidDestroy. Don't call DidDestroy on the untrusted plugin instance, // its DidDestroy. Don't call DidDestroy on the untrusted plugin instance,
// since there is little that it can do at this point. // since there is little that it can do at this point.
...@@ -856,7 +845,7 @@ bool PepperPluginInstanceImpl::Initialize( ...@@ -856,7 +845,7 @@ bool PepperPluginInstanceImpl::Initialize(
bool full_frame) { bool full_frame) {
if (!render_frame_) if (!render_frame_)
return false; return false;
message_channel_ = MessageChannel::Create(this, &message_channel_object_); message_channel_.reset(new MessageChannel(this));
full_frame_ = full_frame; full_frame_ = full_frame;
...@@ -1225,12 +1214,10 @@ bool PepperPluginInstanceImpl::HandleBlockingMessage(ScopedPPVar message, ...@@ -1225,12 +1214,10 @@ bool PepperPluginInstanceImpl::HandleBlockingMessage(ScopedPPVar message,
return was_handled; return was_handled;
} }
PP_Var PepperPluginInstanceImpl::GetInstanceObject(v8::Isolate* isolate) { PP_Var PepperPluginInstanceImpl::GetInstanceObject() {
// Keep a reference on the stack. See NOTE above. // Keep a reference on the stack. See NOTE above.
scoped_refptr<PepperPluginInstanceImpl> ref(this); scoped_refptr<PepperPluginInstanceImpl> ref(this);
DCHECK_EQ(isolate, isolate_);
// If the plugin supports the private instance interface, try to retrieve its // If the plugin supports the private instance interface, try to retrieve its
// instance object. // instance object.
if (LoadPrivateInterface()) if (LoadPrivateInterface())
...@@ -2365,67 +2352,70 @@ PP_Var PepperPluginInstanceImpl::GetWindowObject(PP_Instance instance) { ...@@ -2365,67 +2352,70 @@ PP_Var PepperPluginInstanceImpl::GetWindowObject(PP_Instance instance) {
if (!container_) if (!container_)
return PP_MakeUndefined(); return PP_MakeUndefined();
PepperTryCatchVar try_catch(this, NULL);
WebLocalFrame* frame = container_->element().document().frame(); WebLocalFrame* frame = container_->element().document().frame();
if (!frame) { if (!frame)
try_catch.SetException("No frame exists for window object.");
return PP_MakeUndefined(); return PP_MakeUndefined();
}
ScopedPPVar result = return NPObjectToPPVar(this, frame->windowObject());
try_catch.FromV8(frame->mainWorldScriptContext()->Global());
DCHECK(!try_catch.HasException());
return result.Release();
} }
PP_Var PepperPluginInstanceImpl::GetOwnerElementObject(PP_Instance instance) { PP_Var PepperPluginInstanceImpl::GetOwnerElementObject(PP_Instance instance) {
if (!container_) if (!container_)
return PP_MakeUndefined(); return PP_MakeUndefined();
PepperTryCatchVar try_catch(this, NULL); return NPObjectToPPVar(this, container_->scriptableObjectForElement());
ScopedPPVar result = try_catch.FromV8(container_->v8ObjectForElement());
DCHECK(!try_catch.HasException());
return result.Release();
} }
PP_Var PepperPluginInstanceImpl::ExecuteScript(PP_Instance instance, PP_Var PepperPluginInstanceImpl::ExecuteScript(PP_Instance instance,
PP_Var script_var, PP_Var script,
PP_Var* exception) { PP_Var* exception) {
if (!container_)
return PP_MakeUndefined();
// Executing the script may remove the plugin from the DOM, so we need to keep // Executing the script may remove the plugin from the DOM, so we need to keep
// a reference to ourselves so that we can still process the result after the // a reference to ourselves so that we can still process the result after the
// WebBindings::evaluate() below. // WebBindings::evaluate() below.
scoped_refptr<PepperPluginInstanceImpl> ref(this); scoped_refptr<PepperPluginInstanceImpl> ref(this);
PepperTryCatchVar try_catch(this, exception); TryCatch try_catch(exception);
WebLocalFrame* frame = container_->element().document().frame(); if (try_catch.has_exception())
if (!frame) {
try_catch.SetException("No frame to execute script in.");
return PP_MakeUndefined(); return PP_MakeUndefined();
}
StringVar* script_string_var = StringVar::FromPPVar(script_var); // Convert the script into an inconvenient NPString object.
if (!script_string_var) { StringVar* script_string = StringVar::FromPPVar(script);
if (!script_string) {
try_catch.SetException("Script param to ExecuteScript must be a string."); try_catch.SetException("Script param to ExecuteScript must be a string.");
return PP_MakeUndefined(); return PP_MakeUndefined();
} }
NPString np_script;
np_script.UTF8Characters = script_string->value().c_str();
np_script.UTF8Length = script_string->value().length();
// Get the current frame to pass to the evaluate function.
WebLocalFrame* frame = NULL;
if (container_)
frame = container_->element().document().frame();
if (!frame || !frame->windowObject()) {
try_catch.SetException("No context in which to execute script.");
return PP_MakeUndefined();
}
std::string script_string = script_string_var->value(); NPVariant result;
blink::WebScriptSource script( bool ok = false;
blink::WebString::fromUTF8(script_string.c_str()));
v8::Handle<v8::Value> result;
if (IsProcessingUserGesture()) { if (IsProcessingUserGesture()) {
blink::WebScopedUserGesture user_gesture(CurrentUserGestureToken()); blink::WebScopedUserGesture user_gesture(CurrentUserGestureToken());
result = frame->executeScriptAndReturnValue(script); ok =
WebBindings::evaluate(NULL, frame->windowObject(), &np_script, &result);
} else { } else {
result = frame->executeScriptAndReturnValue(script); ok =
} WebBindings::evaluate(NULL, frame->windowObject(), &np_script, &result);
}
ScopedPPVar var_result = try_catch.FromV8(result); if (!ok) {
if (try_catch.HasException()) // TryCatch doesn't catch the exceptions properly. Since this is only for
// a trusted API, just set to a general exception message.
try_catch.SetException("Exception caught");
WebBindings::releaseVariantValue(&result);
return PP_MakeUndefined(); return PP_MakeUndefined();
}
return var_result.Release(); PP_Var ret = NPVariantToPPVar(this, &result);
WebBindings::releaseVariantValue(&result);
return ret;
} }
uint32_t PepperPluginInstanceImpl::GetAudioHardwareOutputSampleRate( uint32_t PepperPluginInstanceImpl::GetAudioHardwareOutputSampleRate(
...@@ -2983,6 +2973,8 @@ bool PepperPluginInstanceImpl::IsValidInstanceOf(PluginModule* module) { ...@@ -2983,6 +2973,8 @@ bool PepperPluginInstanceImpl::IsValidInstanceOf(PluginModule* module) {
return module == module_.get() || module == original_module_.get(); return module == module_.get() || module == original_module_.get();
} }
NPP PepperPluginInstanceImpl::instanceNPP() { return npp_.get(); }
PepperPluginInstance* PepperPluginInstance::Get(PP_Instance instance_id) { PepperPluginInstance* PepperPluginInstance::Get(PP_Instance instance_id) {
return HostGlobals::Get()->GetInstance(instance_id); return HostGlobals::Get()->GetInstance(instance_id);
} }
......
...@@ -23,7 +23,6 @@ ...@@ -23,7 +23,6 @@
#include "content/public/renderer/pepper_plugin_instance.h" #include "content/public/renderer/pepper_plugin_instance.h"
#include "content/public/renderer/render_frame_observer.h" #include "content/public/renderer/render_frame_observer.h"
#include "content/renderer/mouse_lock_dispatcher.h" #include "content/renderer/mouse_lock_dispatcher.h"
#include "gin/handle.h"
#include "ppapi/c/dev/pp_cursor_type_dev.h" #include "ppapi/c/dev/pp_cursor_type_dev.h"
#include "ppapi/c/dev/ppp_printing_dev.h" #include "ppapi/c/dev/ppp_printing_dev.h"
#include "ppapi/c/dev/ppp_selection_dev.h" #include "ppapi/c/dev/ppp_selection_dev.h"
...@@ -132,6 +131,7 @@ class CONTENT_EXPORT PepperPluginInstanceImpl ...@@ -132,6 +131,7 @@ class CONTENT_EXPORT PepperPluginInstanceImpl
const GURL& plugin_url); const GURL& plugin_url);
RenderFrameImpl* render_frame() const { return render_frame_; } RenderFrameImpl* render_frame() const { return render_frame_; }
PluginModule* module() const { return module_.get(); } PluginModule* module() const { return module_.get(); }
MessageChannel& message_channel() { return *message_channel_; }
blink::WebPluginContainer* container() const { return container_; } blink::WebPluginContainer* container() const { return container_; }
...@@ -143,9 +143,6 @@ class CONTENT_EXPORT PepperPluginInstanceImpl ...@@ -143,9 +143,6 @@ class CONTENT_EXPORT PepperPluginInstanceImpl
return *resource_creation_.get(); return *resource_creation_.get();
} }
MessageChannel* message_channel() { return message_channel_; }
v8::Local<v8::Object> GetMessageChannelObject();
// Return the v8 context that the plugin is in. // Return the v8 context that the plugin is in.
v8::Local<v8::Context> GetContext(); v8::Local<v8::Context> GetContext();
...@@ -192,7 +189,7 @@ class CONTENT_EXPORT PepperPluginInstanceImpl ...@@ -192,7 +189,7 @@ class CONTENT_EXPORT PepperPluginInstanceImpl
bool HandleDocumentLoad(const blink::WebURLResponse& response); bool HandleDocumentLoad(const blink::WebURLResponse& response);
bool HandleInputEvent(const blink::WebInputEvent& event, bool HandleInputEvent(const blink::WebInputEvent& event,
blink::WebCursorInfo* cursor_info); blink::WebCursorInfo* cursor_info);
PP_Var GetInstanceObject(v8::Isolate* isolate); PP_Var GetInstanceObject();
void ViewChanged(const gfx::Rect& position, void ViewChanged(const gfx::Rect& position,
const gfx::Rect& clip, const gfx::Rect& clip,
const std::vector<gfx::Rect>& cut_outs_rects); const std::vector<gfx::Rect>& cut_outs_rects);
...@@ -521,6 +518,10 @@ class CONTENT_EXPORT PepperPluginInstanceImpl ...@@ -521,6 +518,10 @@ class CONTENT_EXPORT PepperPluginInstanceImpl
// the given module. // the given module.
bool IsValidInstanceOf(PluginModule* module); bool IsValidInstanceOf(PluginModule* module);
// Returns the plugin NPP identifier that this plugin will use to identify
// itself when making NPObject scripting calls to WebBindings.
struct _NPP* instanceNPP();
// cc::TextureLayerClient implementation. // cc::TextureLayerClient implementation.
virtual bool PrepareTextureMailbox( virtual bool PrepareTextureMailbox(
cc::TextureMailbox* mailbox, cc::TextureMailbox* mailbox,
...@@ -829,11 +830,7 @@ class CONTENT_EXPORT PepperPluginInstanceImpl ...@@ -829,11 +830,7 @@ class CONTENT_EXPORT PepperPluginInstanceImpl
// The MessageChannel used to implement bidirectional postMessage for the // The MessageChannel used to implement bidirectional postMessage for the
// instance. // instance.
v8::Persistent<v8::Object> message_channel_object_; scoped_ptr<MessageChannel> message_channel_;
// A pointer to the MessageChannel underlying |message_channel_object_|. It is
// only valid as long as |message_channel_object_| is alive.
MessageChannel* message_channel_;
// Bitmap for crashed plugin. Lazily initialized, non-owning pointer. // Bitmap for crashed plugin. Lazily initialized, non-owning pointer.
SkBitmap* sad_plugin_; SkBitmap* sad_plugin_;
...@@ -883,6 +880,10 @@ class CONTENT_EXPORT PepperPluginInstanceImpl ...@@ -883,6 +880,10 @@ class CONTENT_EXPORT PepperPluginInstanceImpl
// The link currently under the cursor. // The link currently under the cursor.
base::string16 link_under_cursor_; base::string16 link_under_cursor_;
// Dummy NPP value used when calling in to WebBindings, to allow the bindings
// to correctly track NPObjects belonging to this plugin instance.
scoped_ptr<struct _NPP> npp_;
// We store the isolate at construction so that we can be sure to use the // We store the isolate at construction so that we can be sure to use the
// Isolate in which this Instance was created when interacting with v8. // Isolate in which this Instance was created when interacting with v8.
v8::Isolate* isolate_; v8::Isolate* isolate_;
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
#include "content/renderer/pepper/pepper_try_catch.h" #include "content/renderer/pepper/pepper_try_catch.h"
#include "content/renderer/pepper/pepper_plugin_instance_impl.h" #include "content/renderer/pepper/pepper_plugin_instance_impl.h"
#include "content/renderer/pepper/v8_var_converter.h"
#include "gin/converter.h" #include "gin/converter.h"
#include "ppapi/shared_impl/ppapi_globals.h" #include "ppapi/shared_impl/ppapi_globals.h"
#include "ppapi/shared_impl/var_tracker.h" #include "ppapi/shared_impl/var_tracker.h"
...@@ -20,7 +21,7 @@ const char kInvalidException[] = "Error: An invalid exception was thrown."; ...@@ -20,7 +21,7 @@ const char kInvalidException[] = "Error: An invalid exception was thrown.";
} // namespace } // namespace
PepperTryCatch::PepperTryCatch(PepperPluginInstanceImpl* instance, PepperTryCatch::PepperTryCatch(PepperPluginInstanceImpl* instance,
V8VarConverter::AllowObjectVars convert_objects) bool convert_objects)
: instance_(instance), : instance_(instance),
convert_objects_(convert_objects) {} convert_objects_(convert_objects) {}
...@@ -56,10 +57,9 @@ ppapi::ScopedPPVar PepperTryCatch::FromV8(v8::Handle<v8::Value> v8_value) { ...@@ -56,10 +57,9 @@ ppapi::ScopedPPVar PepperTryCatch::FromV8(v8::Handle<v8::Value> v8_value) {
return result; return result;
} }
PepperTryCatchV8::PepperTryCatchV8( PepperTryCatchV8::PepperTryCatchV8(PepperPluginInstanceImpl* instance,
PepperPluginInstanceImpl* instance, bool convert_objects,
V8VarConverter::AllowObjectVars convert_objects, v8::Isolate* isolate)
v8::Isolate* isolate)
: PepperTryCatch(instance, convert_objects), : PepperTryCatch(instance, convert_objects),
exception_(PP_MakeUndefined()) { exception_(PP_MakeUndefined()) {
// Typically when using PepperTryCatchV8 we are passed an isolate. We verify // Typically when using PepperTryCatchV8 we are passed an isolate. We verify
...@@ -107,8 +107,9 @@ void PepperTryCatchV8::SetException(const char* message) { ...@@ -107,8 +107,9 @@ void PepperTryCatchV8::SetException(const char* message) {
} }
PepperTryCatchVar::PepperTryCatchVar(PepperPluginInstanceImpl* instance, PepperTryCatchVar::PepperTryCatchVar(PepperPluginInstanceImpl* instance,
bool convert_objects,
PP_Var* exception) PP_Var* exception)
: PepperTryCatch(instance, V8VarConverter::kAllowObjectVars), : PepperTryCatch(instance, convert_objects),
handle_scope_(instance_->GetIsolate()), handle_scope_(instance_->GetIsolate()),
exception_(exception), exception_(exception),
exception_is_set_(false) { exception_is_set_(false) {
......
...@@ -7,7 +7,6 @@ ...@@ -7,7 +7,6 @@
#include "base/basictypes.h" #include "base/basictypes.h"
#include "content/common/content_export.h" #include "content/common/content_export.h"
#include "content/renderer/pepper/v8_var_converter.h"
#include "ppapi/c/pp_var.h" #include "ppapi/c/pp_var.h"
#include "ppapi/shared_impl/scoped_pp_var.h" #include "ppapi/shared_impl/scoped_pp_var.h"
#include "v8/include/v8.h" #include "v8/include/v8.h"
...@@ -20,7 +19,7 @@ class PepperPluginInstanceImpl; ...@@ -20,7 +19,7 @@ class PepperPluginInstanceImpl;
class CONTENT_EXPORT PepperTryCatch { class CONTENT_EXPORT PepperTryCatch {
public: public:
PepperTryCatch(PepperPluginInstanceImpl* instance, PepperTryCatch(PepperPluginInstanceImpl* instance,
V8VarConverter::AllowObjectVars convert_objects); bool convert_objects);
virtual ~PepperTryCatch(); virtual ~PepperTryCatch();
virtual void SetException(const char* message) = 0; virtual void SetException(const char* message) = 0;
...@@ -35,17 +34,16 @@ class CONTENT_EXPORT PepperTryCatch { ...@@ -35,17 +34,16 @@ class CONTENT_EXPORT PepperTryCatch {
protected: protected:
PepperPluginInstanceImpl* instance_; PepperPluginInstanceImpl* instance_;
// Whether To/FromV8 should convert object vars. If set to // Whether To/FromV8 should convert object vars. If set to false, an exception
// kDisallowObjectVars, an exception should be set if they are encountered // should be set if they are encountered during conversion.
// during conversion. bool convert_objects_;
V8VarConverter::AllowObjectVars convert_objects_;
}; };
// Catches var exceptions and emits a v8 exception. // Catches var exceptions and emits a v8 exception.
class PepperTryCatchV8 : public PepperTryCatch { class PepperTryCatchV8 : public PepperTryCatch {
public: public:
PepperTryCatchV8(PepperPluginInstanceImpl* instance, PepperTryCatchV8(PepperPluginInstanceImpl* instance,
V8VarConverter::AllowObjectVars convert_objects, bool convert_objects,
v8::Isolate* isolate); v8::Isolate* isolate);
virtual ~PepperTryCatchV8(); virtual ~PepperTryCatchV8();
...@@ -70,6 +68,7 @@ class PepperTryCatchVar : public PepperTryCatch { ...@@ -70,6 +68,7 @@ class PepperTryCatchVar : public PepperTryCatch {
// is responsible for managing the lifetime of the exception. It is valid to // is responsible for managing the lifetime of the exception. It is valid to
// pass NULL for |exception| in which case no exception will be set. // pass NULL for |exception| in which case no exception will be set.
PepperTryCatchVar(PepperPluginInstanceImpl* instance, PepperTryCatchVar(PepperPluginInstanceImpl* instance,
bool convert_objects,
PP_Var* exception); PP_Var* exception);
virtual ~PepperTryCatchVar(); virtual ~PepperTryCatchVar();
......
...@@ -11,9 +11,9 @@ ...@@ -11,9 +11,9 @@
#include "content/public/common/page_zoom.h" #include "content/public/common/page_zoom.h"
#include "content/public/renderer/content_renderer_client.h" #include "content/public/renderer/content_renderer_client.h"
#include "content/renderer/pepper/message_channel.h" #include "content/renderer/pepper/message_channel.h"
#include "content/renderer/pepper/npobject_var.h"
#include "content/renderer/pepper/pepper_plugin_instance_impl.h" #include "content/renderer/pepper/pepper_plugin_instance_impl.h"
#include "content/renderer/pepper/plugin_module.h" #include "content/renderer/pepper/plugin_module.h"
#include "content/renderer/pepper/v8object_var.h"
#include "content/renderer/render_frame_impl.h" #include "content/renderer/render_frame_impl.h"
#include "ppapi/shared_impl/ppapi_globals.h" #include "ppapi/shared_impl/ppapi_globals.h"
#include "ppapi/shared_impl/var_tracker.h" #include "ppapi/shared_impl/var_tracker.h"
...@@ -31,7 +31,7 @@ ...@@ -31,7 +31,7 @@
#include "third_party/WebKit/public/web/WebPrintScalingOption.h" #include "third_party/WebKit/public/web/WebPrintScalingOption.h"
#include "url/gurl.h" #include "url/gurl.h"
using ppapi::V8ObjectVar; using ppapi::NPObjectVar;
using blink::WebCanvas; using blink::WebCanvas;
using blink::WebPlugin; using blink::WebPlugin;
using blink::WebPluginContainer; using blink::WebPluginContainer;
...@@ -126,28 +126,30 @@ void PepperWebPluginImpl::destroy() { ...@@ -126,28 +126,30 @@ void PepperWebPluginImpl::destroy() {
base::MessageLoop::current()->DeleteSoon(FROM_HERE, this); base::MessageLoop::current()->DeleteSoon(FROM_HERE, this);
} }
v8::Local<v8::Object> PepperWebPluginImpl::v8ScriptableObject( NPObject* PepperWebPluginImpl::scriptableObject() {
v8::Isolate* isolate) {
// Call through the plugin to get its instance object. The plugin should pass // Call through the plugin to get its instance object. The plugin should pass
// us a reference which we release in destroy(). // us a reference which we release in destroy().
if (instance_object_.type == PP_VARTYPE_UNDEFINED) if (instance_object_.type == PP_VARTYPE_UNDEFINED)
instance_object_ = instance_->GetInstanceObject(isolate); instance_object_ = instance_->GetInstanceObject();
// GetInstanceObject talked to the plugin which may have removed the instance // GetInstanceObject talked to the plugin which may have removed the instance
// from the DOM, in which case instance_ would be NULL now. // from the DOM, in which case instance_ would be NULL now.
if (!instance_.get()) if (!instance_.get())
return v8::Local<v8::Object>(); return NULL;
scoped_refptr<V8ObjectVar> object_var( scoped_refptr<NPObjectVar> object(NPObjectVar::FromPPVar(instance_object_));
V8ObjectVar::FromPPVar(instance_object_));
// If there's an InstanceObject, tell the Instance's MessageChannel to pass // If there's an InstanceObject, tell the Instance's MessageChannel to pass
// any non-postMessage calls to it. // any non-postMessage calls to it.
if (object_var.get()) if (object.get()) {
instance_->message_channel()->SetPassthroughObject(object_var->GetHandle()); instance_->message_channel().SetPassthroughObject(object->np_object());
}
v8::Handle<v8::Object> result = instance_->GetMessageChannelObject(); NPObject* message_channel_np_object(instance_->message_channel().np_object());
return result; // The object is expected to be retained before it is returned.
blink::WebBindings::retainObject(message_channel_np_object);
return message_channel_np_object;
} }
NPP PepperWebPluginImpl::pluginNPP() { return instance_->instanceNPP(); }
bool PepperWebPluginImpl::getFormValue(WebString& value) { return false; } bool PepperWebPluginImpl::getFormValue(WebString& value) { return false; }
void PepperWebPluginImpl::paint(WebCanvas* canvas, const WebRect& rect) { void PepperWebPluginImpl::paint(WebCanvas* canvas, const WebRect& rect) {
......
...@@ -41,8 +41,8 @@ class PepperWebPluginImpl : public blink::WebPlugin { ...@@ -41,8 +41,8 @@ class PepperWebPluginImpl : public blink::WebPlugin {
virtual blink::WebPluginContainer* container() const; virtual blink::WebPluginContainer* container() const;
virtual bool initialize(blink::WebPluginContainer* container); virtual bool initialize(blink::WebPluginContainer* container);
virtual void destroy(); virtual void destroy();
virtual v8::Local<v8::Object> v8ScriptableObject( virtual NPObject* scriptableObject();
v8::Isolate* isolate) OVERRIDE; virtual struct _NPP* pluginNPP();
virtual bool getFormValue(blink::WebString& value); virtual bool getFormValue(blink::WebString& value);
virtual void paint(blink::WebCanvas* canvas, const blink::WebRect& rect); virtual void paint(blink::WebCanvas* canvas, const blink::WebRect& rect);
virtual void updateGeometry( virtual void updateGeometry(
......
This diff is collapsed.
...@@ -8,16 +8,11 @@ ...@@ -8,16 +8,11 @@
#include <string> #include <string>
#include "base/basictypes.h" #include "base/basictypes.h"
#include "base/memory/weak_ptr.h"
#include "gin/interceptor.h"
#include "gin/wrappable.h"
#include "ppapi/c/pp_var.h"
struct PP_Var;
struct PPP_Class_Deprecated; struct PPP_Class_Deprecated;
typedef struct NPObject NPObject;
namespace gin { typedef struct _NPVariant NPVariant;
class Arguments;
} // namespace gin
namespace content { namespace content {
...@@ -27,59 +22,71 @@ class PepperPluginInstanceImpl; ...@@ -27,59 +22,71 @@ class PepperPluginInstanceImpl;
// //
// In contrast, a var of type PP_VARTYPE_OBJECT is a reference to a JS object, // 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. // which might be implemented by the plugin (here) or by the JS engine.
class PluginObject : public gin::Wrappable<PluginObject>, class PluginObject {
public gin::NamedPropertyInterceptor {
public: public:
static gin::WrapperInfo kWrapperInfo;
virtual ~PluginObject(); virtual ~PluginObject();
// Returns the PluginObject which is contained in the given v8 object, or NULL
// if the object isn't backed by a PluginObject.
static PluginObject* FromV8Object(v8::Isolate* isolate,
v8::Handle<v8::Object> v8_object);
// Allocates a new PluginObject and returns it as a PP_Var with a // Allocates a new PluginObject and returns it as a PP_Var with a
// refcount of 1. // refcount of 1.
static PP_Var Create(PepperPluginInstanceImpl* instance, static PP_Var Create(PepperPluginInstanceImpl* instance,
const PPP_Class_Deprecated* ppp_class, const PPP_Class_Deprecated* ppp_class,
void* ppp_class_data); void* ppp_class_data);
// gin::NamedPropertyInterceptor PepperPluginInstanceImpl* instance() const { return instance_; }
virtual v8::Local<v8::Value> GetNamedProperty(
v8::Isolate* isolate,
const std::string& property) OVERRIDE;
virtual std::vector<std::string> EnumerateNamedProperties(
v8::Isolate* isolate) OVERRIDE;
const PPP_Class_Deprecated* ppp_class() { return ppp_class_; } const PPP_Class_Deprecated* ppp_class() { return ppp_class_; }
void* ppp_class_data() { return ppp_class_data_; } void* ppp_class_data() {
return ppp_class_data_;
// Called when the instance is destroyed. };
void InstanceDeleted();
NPObject* GetNPObject() const;
// Returns true if the given var is an object implemented by the same plugin
// that owns the var object, and that the class matches. If it matches,
// returns true and places the class data into |*ppp_class_data| (which can
// optionally be NULL if no class data is desired).
static bool IsInstanceOf(NPObject* np_object,
const PPP_Class_Deprecated* ppp_class,
void** ppp_class_data);
// Converts the given NPObject to the corresponding ObjectVar.
//
// The given NPObject must be one corresponding to a PluginObject or this
// will crash. If the object is a PluginObject but the plugin has gone
// away (the object could still be alive because of a reference from JS),
// then the return value will be NULL.
static PluginObject* FromNPObject(NPObject* object);
// Allocates a plugin wrapper object and returns it as an NPObject. This is
// used internally only.
static NPObject* AllocateObjectWrapper();
private: private:
struct NPObjectWrapper;
// This object must be created using the CreateObject function of the which
// will set up the correct NPObject.
//
// The NPObjectWrapper (an NPObject) should already have the reference
// incremented on it, and this class will take ownership of that reference.
PluginObject(PepperPluginInstanceImpl* instance, PluginObject(PepperPluginInstanceImpl* instance,
NPObjectWrapper* object_wrapper,
const PPP_Class_Deprecated* ppp_class, const PPP_Class_Deprecated* ppp_class,
void* ppp_class_data); void* ppp_class_data);
// gin::Wrappable
virtual gin::ObjectTemplateBuilder GetObjectTemplateBuilder(
v8::Isolate* isolate) OVERRIDE;
// Helper method to get named properties.
v8::Local<v8::Value> GetPropertyOrMethod(v8::Isolate* isolate,
PP_Var identifier_var);
void Call(const std::string& identifier, gin::Arguments* args);
PepperPluginInstanceImpl* instance_; PepperPluginInstanceImpl* instance_;
// Holds a pointer to the NPObject wrapper backing the var. This class
// derives from NPObject and we hold a reference to it, so it must be
// refcounted. When the type is not an object, this value will be NULL.
//
// We don't actually own this pointer, it's the NPObject that actually
// owns us.
NPObjectWrapper* object_wrapper_;
const PPP_Class_Deprecated* ppp_class_; const PPP_Class_Deprecated* ppp_class_;
void* ppp_class_data_; void* ppp_class_data_;
base::WeakPtrFactory<PluginObject> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(PluginObject); DISALLOW_COPY_AND_ASSIGN(PluginObject);
}; };
......
...@@ -83,7 +83,7 @@ typedef base::hash_set<HashedHandle> ParentHandleSet; ...@@ -83,7 +83,7 @@ typedef base::hash_set<HashedHandle> ParentHandleSet;
// value was created as a result of calling the function. // value was created as a result of calling the function.
bool GetOrCreateV8Value(v8::Handle<v8::Context> context, bool GetOrCreateV8Value(v8::Handle<v8::Context> context,
const PP_Var& var, const PP_Var& var,
V8VarConverter::AllowObjectVars object_vars_allowed, bool object_vars_allowed,
v8::Handle<v8::Value>* result, v8::Handle<v8::Value>* result,
bool* did_create, bool* did_create,
VarHandleMap* visited_ids, VarHandleMap* visited_ids,
...@@ -155,7 +155,7 @@ bool GetOrCreateV8Value(v8::Handle<v8::Context> context, ...@@ -155,7 +155,7 @@ bool GetOrCreateV8Value(v8::Handle<v8::Context> context,
*result = v8::Object::New(isolate); *result = v8::Object::New(isolate);
break; break;
case PP_VARTYPE_OBJECT: { case PP_VARTYPE_OBJECT: {
DCHECK(object_vars_allowed == V8VarConverter::kAllowObjectVars); DCHECK(object_vars_allowed);
scoped_refptr<V8ObjectVar> v8_object_var = V8ObjectVar::FromPPVar(var); scoped_refptr<V8ObjectVar> v8_object_var = V8ObjectVar::FromPPVar(var);
if (!v8_object_var.get()) { if (!v8_object_var.get()) {
NOTREACHED(); NOTREACHED();
...@@ -187,7 +187,7 @@ bool GetOrCreateV8Value(v8::Handle<v8::Context> context, ...@@ -187,7 +187,7 @@ bool GetOrCreateV8Value(v8::Handle<v8::Context> context,
bool GetOrCreateVar(v8::Handle<v8::Value> val, bool GetOrCreateVar(v8::Handle<v8::Value> val,
v8::Handle<v8::Context> context, v8::Handle<v8::Context> context,
PP_Instance instance, PP_Instance instance,
V8VarConverter::AllowObjectVars object_vars_allowed, bool object_vars_allowed,
PP_Var* result, PP_Var* result,
bool* did_create, bool* did_create,
HandleVarMap* visited_handles, HandleVarMap* visited_handles,
...@@ -234,7 +234,7 @@ bool GetOrCreateVar(v8::Handle<v8::Value> val, ...@@ -234,7 +234,7 @@ bool GetOrCreateVar(v8::Handle<v8::Value> val,
scoped_refptr<HostArrayBufferVar> buffer_var( scoped_refptr<HostArrayBufferVar> buffer_var(
new HostArrayBufferVar(*web_array_buffer)); new HostArrayBufferVar(*web_array_buffer));
*result = buffer_var->GetPPVar(); *result = buffer_var->GetPPVar();
} else if (object_vars_allowed == V8VarConverter::kAllowObjectVars) { } else if (object_vars_allowed) {
v8::Handle<v8::Object> object = val->ToObject(); v8::Handle<v8::Object> object = val->ToObject();
*result = content::HostGlobals::Get()-> *result = content::HostGlobals::Get()->
host_var_tracker()->V8ObjectVarForV8Object(instance, object); host_var_tracker()->V8ObjectVarForV8Object(instance, object);
...@@ -271,14 +271,13 @@ bool CanHaveChildren(PP_Var var) { ...@@ -271,14 +271,13 @@ bool CanHaveChildren(PP_Var var) {
V8VarConverter::V8VarConverter(PP_Instance instance) V8VarConverter::V8VarConverter(PP_Instance instance)
: instance_(instance), : instance_(instance),
object_vars_allowed_(kDisallowObjectVars), object_vars_allowed_(false),
message_loop_proxy_(base::MessageLoopProxy::current()) { message_loop_proxy_(base::MessageLoopProxy::current()) {
resource_converter_.reset(new ResourceConverterImpl( resource_converter_.reset(new ResourceConverterImpl(
instance, RendererPpapiHost::GetForPPInstance(instance))); instance, RendererPpapiHost::GetForPPInstance(instance)));
} }
V8VarConverter::V8VarConverter(PP_Instance instance, V8VarConverter::V8VarConverter(PP_Instance instance, bool object_vars_allowed)
AllowObjectVars object_vars_allowed)
: instance_(instance), : instance_(instance),
object_vars_allowed_(object_vars_allowed), object_vars_allowed_(object_vars_allowed),
message_loop_proxy_(base::MessageLoopProxy::current()) { message_loop_proxy_(base::MessageLoopProxy::current()) {
...@@ -289,7 +288,7 @@ V8VarConverter::V8VarConverter(PP_Instance instance, ...@@ -289,7 +288,7 @@ V8VarConverter::V8VarConverter(PP_Instance instance,
V8VarConverter::V8VarConverter(PP_Instance instance, V8VarConverter::V8VarConverter(PP_Instance instance,
scoped_ptr<ResourceConverter> resource_converter) scoped_ptr<ResourceConverter> resource_converter)
: instance_(instance), : instance_(instance),
object_vars_allowed_(kDisallowObjectVars), object_vars_allowed_(false),
message_loop_proxy_(base::MessageLoopProxy::current()), message_loop_proxy_(base::MessageLoopProxy::current()),
resource_converter_(resource_converter.release()) {} resource_converter_(resource_converter.release()) {}
......
...@@ -21,14 +21,8 @@ class ResourceConverter; ...@@ -21,14 +21,8 @@ class ResourceConverter;
class CONTENT_EXPORT V8VarConverter { class CONTENT_EXPORT V8VarConverter {
public: public:
// Whether or not to allow converting object vars. If they are not allowed
// and they are passed in, conversion will fail.
enum AllowObjectVars {
kDisallowObjectVars,
kAllowObjectVars
};
explicit V8VarConverter(PP_Instance instance); explicit V8VarConverter(PP_Instance instance);
V8VarConverter(PP_Instance instance, AllowObjectVars object_vars_allowed); V8VarConverter(PP_Instance instance, bool object_vars_allowed);
// Constructor for testing. // Constructor for testing.
V8VarConverter(PP_Instance instance, V8VarConverter(PP_Instance instance,
...@@ -82,7 +76,7 @@ class CONTENT_EXPORT V8VarConverter { ...@@ -82,7 +76,7 @@ class CONTENT_EXPORT V8VarConverter {
PP_Instance instance_; PP_Instance instance_;
// Whether or not to support conversion to PP_VARTYPE_OBJECT. // Whether or not to support conversion to PP_VARTYPE_OBJECT.
AllowObjectVars object_vars_allowed_; bool object_vars_allowed_;
// The message loop to run the callback to |FromV8Value| from. // The message loop to run the callback to |FromV8Value| from.
scoped_refptr<base::MessageLoopProxy> message_loop_proxy_; scoped_refptr<base::MessageLoopProxy> message_loop_proxy_;
......
...@@ -28,7 +28,7 @@ namespace ppapi { ...@@ -28,7 +28,7 @@ namespace ppapi {
// PP_Var IDs) for each module. This allows us to track all references owned by // PP_Var IDs) for each module. This allows us to track all references owned by
// a given module and free them when the plugin exits independently of other // a given module and free them when the plugin exits independently of other
// plugins that may be running at the same time. // plugins that may be running at the same time.
class CONTENT_EXPORT V8ObjectVar : public Var { class V8ObjectVar : public Var {
public: public:
V8ObjectVar(PP_Instance instance, v8::Handle<v8::Object> v8_object); V8ObjectVar(PP_Instance instance, v8::Handle<v8::Object> v8_object);
...@@ -49,7 +49,7 @@ class CONTENT_EXPORT V8ObjectVar : public Var { ...@@ -49,7 +49,7 @@ class CONTENT_EXPORT V8ObjectVar : public Var {
// Helper function that converts a PP_Var to an object. This will return NULL // 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. // if the PP_Var is not of object type or the object is invalid.
static scoped_refptr<V8ObjectVar> FromPPVar(PP_Var var); CONTENT_EXPORT static scoped_refptr<V8ObjectVar> FromPPVar(PP_Var var);
private: private:
virtual ~V8ObjectVar(); virtual ~V8ObjectVar();
......
...@@ -21,14 +21,14 @@ ...@@ -21,14 +21,14 @@
namespace ppapi { namespace ppapi {
// A fake version of V8ObjectVar for testing. // A fake version of NPObjectVar for testing.
class V8ObjectVar : public ppapi::Var { class NPObjectVar : public ppapi::Var {
public: public:
V8ObjectVar() {} NPObjectVar() {}
virtual ~V8ObjectVar() {} virtual ~NPObjectVar() {}
// Var overrides. // Var overrides.
virtual V8ObjectVar* AsV8ObjectVar() OVERRIDE { return this; } virtual NPObjectVar* AsNPObjectVar() OVERRIDE { return this; }
virtual PP_VarType GetType() const OVERRIDE { return PP_VARTYPE_OBJECT; } virtual PP_VarType GetType() const OVERRIDE { return PP_VARTYPE_OBJECT; }
}; };
...@@ -111,7 +111,7 @@ PPP_Instance_1_0 ppp_instance_mock = { &DidCreate, &DidDestroy }; ...@@ -111,7 +111,7 @@ PPP_Instance_1_0 ppp_instance_mock = { &DidCreate, &DidDestroy };
PP_Var CreateObject(PP_Instance /*instance*/, PP_Var CreateObject(PP_Instance /*instance*/,
const PPP_Class_Deprecated* /*ppp_class*/, const PPP_Class_Deprecated* /*ppp_class*/,
void* /*ppp_class_data*/) { void* /*ppp_class_data*/) {
V8ObjectVar* obj_var = new V8ObjectVar; NPObjectVar* obj_var = new NPObjectVar;
return obj_var->GetPPVar(); return obj_var->GetPPVar();
} }
......
...@@ -73,18 +73,20 @@ ScopedPPVarArray::~ScopedPPVarArray() { ...@@ -73,18 +73,20 @@ ScopedPPVarArray::~ScopedPPVarArray() {
} }
PP_Var* ScopedPPVarArray::Release(const PassPPBMemoryAllocatedArray&) { PP_Var* ScopedPPVarArray::Release(const PassPPBMemoryAllocatedArray&,
size_t* size) {
PP_Var* result = array_; PP_Var* result = array_;
*size = size_;
array_ = NULL; array_ = NULL;
size_ = 0; size_ = 0;
return result; return result;
} }
void ScopedPPVarArray::Set(size_t index, const ScopedPPVar& var) { void ScopedPPVarArray::Set(size_t index, PP_Var var) {
DCHECK(index < size_); DCHECK(index < size_);
CallAddRef(var.get()); CallAddRef(var);
CallRelease(array_[index]); CallRelease(array_[index]);
array_[index] = var.get(); array_[index] = var;
} }
} // namespace ppapi } // namespace ppapi
...@@ -63,13 +63,13 @@ class PPAPI_SHARED_EXPORT ScopedPPVarArray { ...@@ -63,13 +63,13 @@ class PPAPI_SHARED_EXPORT ScopedPPVarArray {
// Passes ownership of the vars and the underlying array memory to the caller. // Passes ownership of the vars and the underlying array memory to the caller.
// Note that the memory has been allocated with PPB_Memory_Dev. // Note that the memory has been allocated with PPB_Memory_Dev.
PP_Var* Release(const PassPPBMemoryAllocatedArray&); PP_Var* Release(const PassPPBMemoryAllocatedArray&, size_t* size);
PP_Var* get() { return array_; } PP_Var* get() { return array_; }
size_t size() { return size_; } size_t size() { return size_; }
// Takes a ref to |var|. The refcount of the existing var will be decremented. // Adds a ref to |var|. The refcount of the existing var will be decremented.
void Set(size_t index, const ScopedPPVar& var); void Set(size_t index, PP_Var var);
const PP_Var& operator[](size_t index) { return array_[index]; } const PP_Var& operator[](size_t index) { return array_[index]; }
private: private:
......
...@@ -172,14 +172,6 @@ TestPostMessage::~TestPostMessage() { ...@@ -172,14 +172,6 @@ TestPostMessage::~TestPostMessage() {
bool TestPostMessage::Init() { bool TestPostMessage::Init() {
bool success = CheckTestingInterface(); bool success = CheckTestingInterface();
// Add a post condition to tests which caches the postMessage function and
// then calls it after the instance is destroyed. The ensures that no UAF
// occurs because the MessageChannel may still be alive after the plugin
// instance is destroyed (it will get garbage collected eventually).
instance_->EvalScript("window.pluginPostMessage = "
"document.getElementById('plugin').postMessage");
instance_->AddPostCondition("window.pluginPostMessage('') === undefined");
// Set up a special listener that only responds to a FINISHED_WAITING string. // Set up a special listener that only responds to a FINISHED_WAITING string.
// This is for use by WaitForMessages. // This is for use by WaitForMessages.
std::string js_code; std::string js_code;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment