| // Copyright (c) 2012 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 "ppapi/proxy/ppb_var_deprecated_proxy.h" | 
 |  | 
 | #include <stdlib.h>  // For malloc | 
 |  | 
 | #include "base/bind.h" | 
 | #include "base/logging.h" | 
 | #include "ppapi/c/dev/ppb_var_deprecated.h" | 
 | #include "ppapi/c/pp_var.h" | 
 | #include "ppapi/c/ppb_core.h" | 
 | #include "ppapi/c/ppb_var.h" | 
 | #include "ppapi/proxy/host_dispatcher.h" | 
 | #include "ppapi/proxy/plugin_dispatcher.h" | 
 | #include "ppapi/proxy/plugin_globals.h" | 
 | #include "ppapi/proxy/plugin_resource_tracker.h" | 
 | #include "ppapi/proxy/plugin_var_tracker.h" | 
 | #include "ppapi/proxy/ppapi_messages.h" | 
 | #include "ppapi/proxy/ppp_class_proxy.h" | 
 | #include "ppapi/proxy/proxy_object_var.h" | 
 | #include "ppapi/proxy/serialized_var.h" | 
 | #include "ppapi/shared_impl/ppapi_globals.h" | 
 | #include "ppapi/shared_impl/ppb_var_shared.h" | 
 | #include "ppapi/shared_impl/proxy_lock.h" | 
 | #include "ppapi/shared_impl/var.h" | 
 |  | 
 | namespace ppapi { | 
 | namespace proxy { | 
 |  | 
 | namespace { | 
 |  | 
 | // Used to do get the set-up information for calling a var object. If the | 
 | // exception is set, returns NULL. Otherwise, computes the dispatcher for the | 
 | // given var object. If the var is not a valid object, returns NULL and sets | 
 | // the exception. | 
 | PluginDispatcher* CheckExceptionAndGetDispatcher(const PP_Var& object, | 
 |                                                  PP_Var* exception) { | 
 |   // If an exception is already set, we don't need to do anything, just return | 
 |   // an error to the caller. | 
 |   if (exception && exception->type != PP_VARTYPE_UNDEFINED) | 
 |     return NULL; | 
 |  | 
 |  | 
 |   if (object.type == PP_VARTYPE_OBJECT) { | 
 |     // Get the dispatcher for the object. | 
 |     PluginDispatcher* dispatcher = | 
 |         PluginGlobals::Get()->plugin_var_tracker()-> | 
 |             DispatcherForPluginObject(object); | 
 |     if (dispatcher) | 
 |       return dispatcher; | 
 |   } | 
 |  | 
 |   // The object is invalid. This means we can't figure out which dispatcher | 
 |   // to use, which is OK because the call will fail anyway. Set the exception. | 
 |   if (exception) { | 
 |     *exception = StringVar::StringToPPVar( | 
 |         std::string("Attempting to use an invalid object")); | 
 |   } | 
 |   return NULL; | 
 | } | 
 |  | 
 | // PPB_Var_Deprecated plugin --------------------------------------------------- | 
 |  | 
 | bool HasProperty(PP_Var var, | 
 |                  PP_Var name, | 
 |                  PP_Var* exception) { | 
 |   ProxyAutoLock lock; | 
 |   Dispatcher* dispatcher = CheckExceptionAndGetDispatcher(var, exception); | 
 |   if (!dispatcher) | 
 |     return false; | 
 |  | 
 |   ReceiveSerializedException se(dispatcher, exception); | 
 |   PP_Bool result = PP_FALSE; | 
 |   if (!se.IsThrown()) { | 
 |     dispatcher->Send(new PpapiHostMsg_PPBVar_HasProperty( | 
 |         API_ID_PPB_VAR_DEPRECATED, | 
 |         SerializedVarSendInput(dispatcher, var), | 
 |         SerializedVarSendInput(dispatcher, name), &se, &result)); | 
 |   } | 
 |   return PP_ToBool(result); | 
 | } | 
 |  | 
 | bool HasMethod(PP_Var var, | 
 |                PP_Var name, | 
 |                PP_Var* exception) { | 
 |   ProxyAutoLock lock; | 
 |   Dispatcher* dispatcher = CheckExceptionAndGetDispatcher(var, exception); | 
 |   if (!dispatcher) | 
 |     return false; | 
 |  | 
 |   ReceiveSerializedException se(dispatcher, exception); | 
 |   PP_Bool result = PP_FALSE; | 
 |   if (!se.IsThrown()) { | 
 |     dispatcher->Send(new PpapiHostMsg_PPBVar_HasMethodDeprecated( | 
 |         API_ID_PPB_VAR_DEPRECATED, | 
 |         SerializedVarSendInput(dispatcher, var), | 
 |         SerializedVarSendInput(dispatcher, name), &se, &result)); | 
 |   } | 
 |   return PP_ToBool(result); | 
 | } | 
 |  | 
 | PP_Var GetProperty(PP_Var var, | 
 |                    PP_Var name, | 
 |                    PP_Var* exception) { | 
 |   ProxyAutoLock lock; | 
 |   Dispatcher* dispatcher = CheckExceptionAndGetDispatcher(var, exception); | 
 |   if (!dispatcher) | 
 |     return PP_MakeUndefined(); | 
 |  | 
 |   ReceiveSerializedException se(dispatcher, exception); | 
 |   ReceiveSerializedVarReturnValue result; | 
 |   if (!se.IsThrown()) { | 
 |     dispatcher->Send(new PpapiHostMsg_PPBVar_GetProperty( | 
 |         API_ID_PPB_VAR_DEPRECATED, | 
 |         SerializedVarSendInput(dispatcher, var), | 
 |         SerializedVarSendInput(dispatcher, name), &se, &result)); | 
 |   } | 
 |   return result.Return(dispatcher); | 
 | } | 
 |  | 
 | void EnumerateProperties(PP_Var var, | 
 |                          uint32_t* property_count, | 
 |                          PP_Var** properties, | 
 |                          PP_Var* exception) { | 
 |   ProxyAutoLock lock; | 
 |   Dispatcher* dispatcher = CheckExceptionAndGetDispatcher(var, exception); | 
 |   if (!dispatcher) { | 
 |     *property_count = 0; | 
 |     *properties = NULL; | 
 |     return; | 
 |   } | 
 |  | 
 |   ReceiveSerializedVarVectorOutParam out_vector(dispatcher, | 
 |                                                 property_count, properties); | 
 |   ReceiveSerializedException se(dispatcher, exception); | 
 |   if (!se.IsThrown()) { | 
 |     dispatcher->Send(new PpapiHostMsg_PPBVar_EnumerateProperties( | 
 |         API_ID_PPB_VAR_DEPRECATED, | 
 |         SerializedVarSendInput(dispatcher, var), | 
 |         out_vector.OutParam(), &se)); | 
 |   } | 
 | } | 
 |  | 
 | void SetProperty(PP_Var var, | 
 |                  PP_Var name, | 
 |                  PP_Var value, | 
 |                  PP_Var* exception) { | 
 |   ProxyAutoLock lock; | 
 |   Dispatcher* dispatcher = CheckExceptionAndGetDispatcher(var, exception); | 
 |   if (!dispatcher) | 
 |     return; | 
 |  | 
 |   ReceiveSerializedException se(dispatcher, exception); | 
 |   if (!se.IsThrown()) { | 
 |     dispatcher->Send(new PpapiHostMsg_PPBVar_SetPropertyDeprecated( | 
 |         API_ID_PPB_VAR_DEPRECATED, | 
 |         SerializedVarSendInput(dispatcher, var), | 
 |         SerializedVarSendInput(dispatcher, name), | 
 |         SerializedVarSendInput(dispatcher, value), &se)); | 
 |   } | 
 | } | 
 |  | 
 | void RemoveProperty(PP_Var var, | 
 |                     PP_Var name, | 
 |                     PP_Var* exception) { | 
 |   ProxyAutoLock lock; | 
 |   Dispatcher* dispatcher = CheckExceptionAndGetDispatcher(var, exception); | 
 |   if (!dispatcher) | 
 |     return; | 
 |  | 
 |   ReceiveSerializedException se(dispatcher, exception); | 
 |   PP_Bool result = PP_FALSE; | 
 |   if (!se.IsThrown()) { | 
 |     dispatcher->Send(new PpapiHostMsg_PPBVar_DeleteProperty( | 
 |         API_ID_PPB_VAR_DEPRECATED, | 
 |         SerializedVarSendInput(dispatcher, var), | 
 |         SerializedVarSendInput(dispatcher, name), &se, &result)); | 
 |   } | 
 | } | 
 |  | 
 | PP_Var Call(PP_Var object, | 
 |             PP_Var method_name, | 
 |             uint32_t argc, | 
 |             PP_Var* argv, | 
 |             PP_Var* exception) { | 
 |   ProxyAutoLock lock; | 
 |   Dispatcher* dispatcher = CheckExceptionAndGetDispatcher(object, exception); | 
 |   if (!dispatcher) | 
 |     return PP_MakeUndefined(); | 
 |  | 
 |   ReceiveSerializedVarReturnValue result; | 
 |   ReceiveSerializedException se(dispatcher, exception); | 
 |   if (!se.IsThrown()) { | 
 |     std::vector<SerializedVar> argv_vect; | 
 |     SerializedVarSendInput::ConvertVector(dispatcher, argv, argc, &argv_vect); | 
 |  | 
 |     dispatcher->Send(new PpapiHostMsg_PPBVar_CallDeprecated( | 
 |         API_ID_PPB_VAR_DEPRECATED, | 
 |         SerializedVarSendInput(dispatcher, object), | 
 |         SerializedVarSendInput(dispatcher, method_name), argv_vect, | 
 |         &se, &result)); | 
 |   } | 
 |   return result.Return(dispatcher); | 
 | } | 
 |  | 
 | PP_Var Construct(PP_Var object, | 
 |                  uint32_t argc, | 
 |                  PP_Var* argv, | 
 |                  PP_Var* exception) { | 
 |   ProxyAutoLock lock; | 
 |   Dispatcher* dispatcher = CheckExceptionAndGetDispatcher(object, exception); | 
 |   if (!dispatcher) | 
 |     return PP_MakeUndefined(); | 
 |  | 
 |   ReceiveSerializedVarReturnValue result; | 
 |   ReceiveSerializedException se(dispatcher, exception); | 
 |   if (!se.IsThrown()) { | 
 |     std::vector<SerializedVar> argv_vect; | 
 |     SerializedVarSendInput::ConvertVector(dispatcher, argv, argc, &argv_vect); | 
 |  | 
 |     dispatcher->Send(new PpapiHostMsg_PPBVar_Construct( | 
 |         API_ID_PPB_VAR_DEPRECATED, | 
 |         SerializedVarSendInput(dispatcher, object), | 
 |         argv_vect, &se, &result)); | 
 |   } | 
 |   return result.Return(dispatcher); | 
 | } | 
 |  | 
 | bool IsInstanceOf(PP_Var var, | 
 |                   const PPP_Class_Deprecated* ppp_class, | 
 |                   void** ppp_class_data) { | 
 |   ProxyAutoLock lock; | 
 |   Dispatcher* dispatcher = CheckExceptionAndGetDispatcher(var, NULL); | 
 |   if (!dispatcher) | 
 |     return false; | 
 |  | 
 |   PP_Bool result = PP_FALSE; | 
 |   int64_t class_int = | 
 |       static_cast<int64_t>(reinterpret_cast<intptr_t>(ppp_class)); | 
 |   int64_t class_data_int = 0; | 
 |   dispatcher->Send(new PpapiHostMsg_PPBVar_IsInstanceOfDeprecated( | 
 |       API_ID_PPB_VAR_DEPRECATED, SerializedVarSendInput(dispatcher, var), | 
 |       class_int, &class_data_int, &result)); | 
 |   *ppp_class_data = | 
 |       reinterpret_cast<void*>(static_cast<intptr_t>(class_data_int)); | 
 |   return PP_ToBool(result); | 
 | } | 
 |  | 
 | PP_Var CreateObject(PP_Instance instance, | 
 |                     const PPP_Class_Deprecated* ppp_class, | 
 |                     void* ppp_class_data) { | 
 |   ProxyAutoLock lock; | 
 |   Dispatcher* dispatcher = PluginDispatcher::GetForInstance(instance); | 
 |   if (!dispatcher) | 
 |     return PP_MakeUndefined(); | 
 |  | 
 |   PluginVarTracker* tracker = PluginGlobals::Get()->plugin_var_tracker(); | 
 |   if (tracker->IsPluginImplementedObjectAlive(ppp_class_data)) | 
 |     return PP_MakeUndefined();  // Object already exists with this user data. | 
 |  | 
 |   ReceiveSerializedVarReturnValue result; | 
 |   int64_t class_int = | 
 |       static_cast<int64_t>(reinterpret_cast<intptr_t>(ppp_class)); | 
 |   int64_t data_int = | 
 |       static_cast<int64_t>(reinterpret_cast<intptr_t>(ppp_class_data)); | 
 |   dispatcher->Send(new PpapiHostMsg_PPBVar_CreateObjectDeprecated( | 
 |       API_ID_PPB_VAR_DEPRECATED, instance, class_int, data_int, | 
 |       &result)); | 
 |   PP_Var ret_var = result.Return(dispatcher); | 
 |  | 
 |   // Register this object as being implemented by the plugin. | 
 |   if (ret_var.type == PP_VARTYPE_OBJECT) { | 
 |     tracker->PluginImplementedObjectCreated(instance, ret_var, | 
 |                                             ppp_class, ppp_class_data); | 
 |   } | 
 |   return ret_var; | 
 | } | 
 |  | 
 | }  // namespace | 
 |  | 
 | PPB_Var_Deprecated_Proxy::PPB_Var_Deprecated_Proxy( | 
 |     Dispatcher* dispatcher) | 
 |     : InterfaceProxy(dispatcher), | 
 |       ppb_var_impl_(NULL), | 
 |       task_factory_(this) { | 
 |   if (!dispatcher->IsPlugin()) { | 
 |     ppb_var_impl_ = static_cast<const PPB_Var_Deprecated*>( | 
 |         dispatcher->local_get_interface()(PPB_VAR_DEPRECATED_INTERFACE)); | 
 |   } | 
 | } | 
 |  | 
 | PPB_Var_Deprecated_Proxy::~PPB_Var_Deprecated_Proxy() { | 
 | } | 
 |  | 
 | // static | 
 | const PPB_Var_Deprecated* PPB_Var_Deprecated_Proxy::GetProxyInterface() { | 
 |   static const PPB_Var_Deprecated var_deprecated_interface = { | 
 |     ppapi::PPB_Var_Shared::GetVarInterface1_0()->AddRef, | 
 |     ppapi::PPB_Var_Shared::GetVarInterface1_0()->Release, | 
 |     ppapi::PPB_Var_Shared::GetVarInterface1_0()->VarFromUtf8, | 
 |     ppapi::PPB_Var_Shared::GetVarInterface1_0()->VarToUtf8, | 
 |     &HasProperty, | 
 |     &HasMethod, | 
 |     &GetProperty, | 
 |     &EnumerateProperties, | 
 |     &SetProperty, | 
 |     &RemoveProperty, | 
 |     &Call, | 
 |     &Construct, | 
 |     &IsInstanceOf, | 
 |     &CreateObject | 
 |   }; | 
 |   return &var_deprecated_interface; | 
 | } | 
 |  | 
 | bool PPB_Var_Deprecated_Proxy::OnMessageReceived(const IPC::Message& msg) { | 
 |   if (!dispatcher()->permissions().HasPermission(PERMISSION_FLASH)) | 
 |     return false; | 
 |  | 
 |   // Prevent the dispatcher from going away during a call to Call or other | 
 |   // function that could mutate the DOM. This must happen OUTSIDE of | 
 |   // the message handlers since the SerializedVars use the dispatcher upon | 
 |   // return of the function (converting the SerializedVarReturnValue/OutParam | 
 |   // to a SerializedVar in the destructor). | 
 |   ScopedModuleReference death_grip(dispatcher()); | 
 |  | 
 |   bool handled = true; | 
 |   IPC_BEGIN_MESSAGE_MAP(PPB_Var_Deprecated_Proxy, msg) | 
 |     IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBVar_AddRefObject, OnMsgAddRefObject) | 
 |     IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBVar_ReleaseObject, OnMsgReleaseObject) | 
 |     IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBVar_HasProperty, | 
 |                         OnMsgHasProperty) | 
 |     IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBVar_HasMethodDeprecated, | 
 |                         OnMsgHasMethodDeprecated) | 
 |     IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBVar_GetProperty, | 
 |                         OnMsgGetProperty) | 
 |     IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBVar_DeleteProperty, | 
 |                         OnMsgDeleteProperty) | 
 |     IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBVar_EnumerateProperties, | 
 |                         OnMsgEnumerateProperties) | 
 |     IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBVar_SetPropertyDeprecated, | 
 |                         OnMsgSetPropertyDeprecated) | 
 |     IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBVar_CallDeprecated, | 
 |                         OnMsgCallDeprecated) | 
 |     IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBVar_Construct, | 
 |                         OnMsgConstruct) | 
 |     IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBVar_IsInstanceOfDeprecated, | 
 |                         OnMsgIsInstanceOfDeprecated) | 
 |     IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBVar_CreateObjectDeprecated, | 
 |                         OnMsgCreateObjectDeprecated) | 
 |     IPC_MESSAGE_UNHANDLED(handled = false) | 
 |   IPC_END_MESSAGE_MAP() | 
 |   // TODO(brettw) handle bad messages! | 
 |   return handled; | 
 | } | 
 |  | 
 | void PPB_Var_Deprecated_Proxy::OnMsgAddRefObject(int64_t object_id) { | 
 |   PP_Var var = { PP_VARTYPE_OBJECT }; | 
 |   var.value.as_id = object_id; | 
 |   ppb_var_impl_->AddRef(var); | 
 | } | 
 |  | 
 | void PPB_Var_Deprecated_Proxy::OnMsgReleaseObject(int64_t object_id) { | 
 |   // Ok, so this is super subtle. | 
 |   // When the browser side sends a sync IPC message that returns a var, and the | 
 |   // plugin wants to give ownership of that var to the browser, dropping all | 
 |   // references, it may call ReleaseObject right after returning the result. | 
 |   // However, the IPC system doesn't enforce strict ordering of messages in that | 
 |   // case, where a message that is set to unblock (e.g. a sync message, or in | 
 |   // our case all messages coming from the plugin) that is sent *after* the | 
 |   // result may be dispatched on the browser side *before* the sync send | 
 |   // returned (see ipc_sync_channel.cc). In this case, that means it could | 
 |   // release the object before it is AddRef'ed on the browser side. | 
 |   // To work around this, we post a task here, that will not execute before | 
 |   // control goes back to the main message loop, that will ensure the sync send | 
 |   // has returned and the browser side can take its reference before we Release. | 
 |   // Note: if the instance is gone by the time the task is executed, then it | 
 |   // will Release the objects itself and this Release will be a NOOP (aside of a | 
 |   // spurious warning). | 
 |   // TODO(piman): See if we can fix the IPC code to enforce strict ordering, and | 
 |   // then remove this. | 
 |   PpapiGlobals::Get()->GetMainThreadMessageLoop()->PostNonNestableTask( | 
 |       FROM_HERE, | 
 |       RunWhileLocked(base::Bind(&PPB_Var_Deprecated_Proxy::DoReleaseObject, | 
 |                                 task_factory_.GetWeakPtr(), | 
 |                                 object_id))); | 
 | } | 
 |  | 
 | void PPB_Var_Deprecated_Proxy::OnMsgHasProperty( | 
 |     SerializedVarReceiveInput var, | 
 |     SerializedVarReceiveInput name, | 
 |     SerializedVarOutParam exception, | 
 |     PP_Bool* result) { | 
 |   SetAllowPluginReentrancy(); | 
 |   *result = PP_FromBool(ppb_var_impl_->HasProperty( | 
 |       var.Get(dispatcher()), | 
 |       name.Get(dispatcher()), | 
 |       exception.OutParam(dispatcher()))); | 
 | } | 
 |  | 
 | void PPB_Var_Deprecated_Proxy::OnMsgHasMethodDeprecated( | 
 |     SerializedVarReceiveInput var, | 
 |     SerializedVarReceiveInput name, | 
 |     SerializedVarOutParam exception, | 
 |     PP_Bool* result) { | 
 |   SetAllowPluginReentrancy(); | 
 |   *result = PP_FromBool(ppb_var_impl_->HasMethod( | 
 |       var.Get(dispatcher()), | 
 |       name.Get(dispatcher()), | 
 |       exception.OutParam(dispatcher()))); | 
 | } | 
 |  | 
 | void PPB_Var_Deprecated_Proxy::OnMsgGetProperty( | 
 |     SerializedVarReceiveInput var, | 
 |     SerializedVarReceiveInput name, | 
 |     SerializedVarOutParam exception, | 
 |     SerializedVarReturnValue result) { | 
 |   SetAllowPluginReentrancy(); | 
 |   result.Return(dispatcher(), ppb_var_impl_->GetProperty( | 
 |       var.Get(dispatcher()), name.Get(dispatcher()), | 
 |       exception.OutParam(dispatcher()))); | 
 | } | 
 |  | 
 | void PPB_Var_Deprecated_Proxy::OnMsgEnumerateProperties( | 
 |     SerializedVarReceiveInput var, | 
 |     SerializedVarVectorOutParam props, | 
 |     SerializedVarOutParam exception) { | 
 |   SetAllowPluginReentrancy(); | 
 |   ppb_var_impl_->GetAllPropertyNames(var.Get(dispatcher()), | 
 |       props.CountOutParam(), props.ArrayOutParam(dispatcher()), | 
 |       exception.OutParam(dispatcher())); | 
 | } | 
 |  | 
 | void PPB_Var_Deprecated_Proxy::OnMsgSetPropertyDeprecated( | 
 |     SerializedVarReceiveInput var, | 
 |     SerializedVarReceiveInput name, | 
 |     SerializedVarReceiveInput value, | 
 |     SerializedVarOutParam exception) { | 
 |   SetAllowPluginReentrancy(); | 
 |   ppb_var_impl_->SetProperty(var.Get(dispatcher()), | 
 |                                 name.Get(dispatcher()), | 
 |                                 value.Get(dispatcher()), | 
 |                                 exception.OutParam(dispatcher())); | 
 | } | 
 |  | 
 | void PPB_Var_Deprecated_Proxy::OnMsgDeleteProperty( | 
 |     SerializedVarReceiveInput var, | 
 |     SerializedVarReceiveInput name, | 
 |     SerializedVarOutParam exception, | 
 |     PP_Bool* result) { | 
 |   SetAllowPluginReentrancy(); | 
 |   ppb_var_impl_->RemoveProperty(var.Get(dispatcher()), | 
 |                                    name.Get(dispatcher()), | 
 |                                    exception.OutParam(dispatcher())); | 
 |   // This deprecated function doesn't actually return a value, but we re-use | 
 |   // the message from the non-deprecated interface with the return value. | 
 |   *result = PP_TRUE; | 
 | } | 
 |  | 
 | void PPB_Var_Deprecated_Proxy::OnMsgCallDeprecated( | 
 |     SerializedVarReceiveInput object, | 
 |     SerializedVarReceiveInput method_name, | 
 |     SerializedVarVectorReceiveInput arg_vector, | 
 |     SerializedVarOutParam exception, | 
 |     SerializedVarReturnValue result) { | 
 |   SetAllowPluginReentrancy(); | 
 |   uint32_t arg_count = 0; | 
 |   PP_Var* args = arg_vector.Get(dispatcher(), &arg_count); | 
 |   result.Return(dispatcher(), ppb_var_impl_->Call( | 
 |       object.Get(dispatcher()), | 
 |       method_name.Get(dispatcher()), | 
 |       arg_count, args, | 
 |       exception.OutParam(dispatcher()))); | 
 | } | 
 |  | 
 | void PPB_Var_Deprecated_Proxy::OnMsgConstruct( | 
 |     SerializedVarReceiveInput var, | 
 |     SerializedVarVectorReceiveInput arg_vector, | 
 |     SerializedVarOutParam exception, | 
 |     SerializedVarReturnValue result) { | 
 |   SetAllowPluginReentrancy(); | 
 |   uint32_t arg_count = 0; | 
 |   PP_Var* args = arg_vector.Get(dispatcher(), &arg_count); | 
 |   result.Return(dispatcher(), ppb_var_impl_->Construct( | 
 |       var.Get(dispatcher()), arg_count, args, | 
 |       exception.OutParam(dispatcher()))); | 
 | } | 
 |  | 
 | void PPB_Var_Deprecated_Proxy::OnMsgIsInstanceOfDeprecated( | 
 |     SerializedVarReceiveInput var, | 
 |     int64_t ppp_class, | 
 |     int64_t* ppp_class_data, | 
 |     PP_Bool* result) { | 
 |   SetAllowPluginReentrancy(); | 
 |   *result = PPP_Class_Proxy::IsInstanceOf(ppb_var_impl_, | 
 |                                           var.Get(dispatcher()), | 
 |                                           ppp_class, | 
 |                                           ppp_class_data); | 
 | } | 
 |  | 
 | void PPB_Var_Deprecated_Proxy::OnMsgCreateObjectDeprecated( | 
 |     PP_Instance instance, | 
 |     int64_t ppp_class, | 
 |     int64_t class_data, | 
 |     SerializedVarReturnValue result) { | 
 |   SetAllowPluginReentrancy(); | 
 |   result.Return(dispatcher(), PPP_Class_Proxy::CreateProxiedObject( | 
 |       ppb_var_impl_, dispatcher(), instance, ppp_class, class_data)); | 
 | } | 
 |  | 
 | void PPB_Var_Deprecated_Proxy::SetAllowPluginReentrancy() { | 
 |   if (dispatcher()->IsPlugin()) | 
 |     NOTREACHED(); | 
 |   else | 
 |     static_cast<HostDispatcher*>(dispatcher())->set_allow_plugin_reentrancy(); | 
 | } | 
 |  | 
 | void PPB_Var_Deprecated_Proxy::DoReleaseObject(int64_t object_id) { | 
 |   PP_Var var = { PP_VARTYPE_OBJECT }; | 
 |   var.value.as_id = object_id; | 
 |   ppb_var_impl_->Release(var); | 
 | } | 
 |  | 
 | }  // namespace proxy | 
 | }  // namespace ppapi |