serialized_var.cc revision 2a99a7e74a7f215066514fe81d2bfa6639d9eddd
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/proxy/serialized_var.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ipc/ipc_message_utils.h"
92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ppapi/c/pp_instance.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/proxy/dispatcher.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/proxy/interface_proxy.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/proxy/ppapi_param_traits.h"
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ppapi/proxy/ppb_buffer_proxy.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/shared_impl/ppapi_globals.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/shared_impl/var.h"
162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ppapi/thunk/enter.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace ppapi {
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace proxy {
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// When sending array buffers, if the size is over 256K, we use shared
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// memory instead of sending the data over IPC. Light testing suggests
232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// shared memory is much faster for 256K and larger messages.
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)static const uint32 kMinimumArrayBufferSizeForShmem = 256 * 1024;
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// SerializedVar::Inner --------------------------------------------------------
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SerializedVar::Inner::Inner()
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : serialization_rules_(NULL),
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      var_(PP_MakeUndefined()),
312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      instance_(0),
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      cleanup_mode_(CLEANUP_NONE) {
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef NDEBUG
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  has_been_serialized_ = false;
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  has_been_deserialized_ = false;
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SerializedVar::Inner::Inner(VarSerializationRules* serialization_rules)
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : serialization_rules_(serialization_rules),
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      var_(PP_MakeUndefined()),
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      instance_(0),
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      cleanup_mode_(CLEANUP_NONE) {
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef NDEBUG
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  has_been_serialized_ = false;
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  has_been_deserialized_ = false;
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SerializedVar::Inner::~Inner() {
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  switch (cleanup_mode_) {
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case END_SEND_PASS_REF:
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      serialization_rules_->EndSendPassRef(var_);
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case END_RECEIVE_CALLER_OWNED:
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      serialization_rules_->EndReceiveCallerOwned(var_);
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    default:
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PP_Var SerializedVar::Inner::GetVar() {
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(serialization_rules_);
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConvertRawVarData();
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return var_;
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SerializedVar::Inner::SetVar(PP_Var var) {
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Sanity check, when updating the var we should have received a
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // serialization rules pointer already.
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(serialization_rules_);
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  var_ = var;
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  raw_var_data_.reset(NULL);
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void SerializedVar::Inner::SetInstance(PP_Instance instance) {
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  instance_ = instance;
802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SerializedVar::Inner::ForceSetVarValueForTest(PP_Var value) {
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  var_ = value;
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  raw_var_data_.reset(NULL);
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void SerializedVar::Inner::WriteRawVarHeader(IPC::Message* m) const {
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Write raw_var_data_ when we're called from
892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // chrome/nacl/nacl_ipc_adapter.cc.
902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(raw_var_data_.get());
912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK_EQ(PP_VARTYPE_ARRAY_BUFFER, raw_var_data_->type);
922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(raw_var_data_->shmem_size != 0);
932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The serialization for this message MUST MATCH the implementation at
952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // SerializedVar::Inner::WriteToMessage for ARRAY_BUFFER_SHMEM_PLUGIN.
962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  m->WriteInt(static_cast<int>(raw_var_data_->type));
972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  m->WriteInt(ARRAY_BUFFER_SHMEM_PLUGIN);
982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  m->WriteInt(raw_var_data_->shmem_size);
992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // NaClIPCAdapter will write the handles for us.
1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SerializedVar::Inner::WriteToMessage(IPC::Message* m) const {
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // When writing to the IPC messages, a serialization rules handler should
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // always have been set.
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // When sending a message, it should be difficult to trigger this if you're
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // using the SerializedVarSendInput class and giving a non-NULL dispatcher.
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Make sure you're using the proper "Send" helper class.
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // It should be more common to see this when handling an incoming message
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // that returns a var. This means the message handler didn't write to the
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // output parameter, or possibly you used the wrong helper class
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // (normally SerializedVarReturnValue).
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(serialization_rules_);
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef NDEBUG
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We should only be serializing something once.
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(!has_been_serialized_);
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  has_been_serialized_ = true;
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(!raw_var_data_.get());
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  m->WriteInt(static_cast<int>(var_.type));
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  switch (var_.type) {
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case PP_VARTYPE_UNDEFINED:
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case PP_VARTYPE_NULL:
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // These don't need any data associated with them other than the type we
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // just serialized.
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case PP_VARTYPE_BOOL:
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      m->WriteBool(PP_ToBool(var_.value.as_bool));
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case PP_VARTYPE_INT32:
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      m->WriteInt(var_.value.as_int);
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case PP_VARTYPE_DOUBLE:
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      IPC::ParamTraits<double>::Write(m, var_.value.as_double);
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case PP_VARTYPE_STRING: {
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // TODO(brettw) in the case of an invalid string ID, it would be nice
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // to send something to the other side such that a 0 ID would be
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // generated there. Then the function implementing the interface can
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // handle the invalid string as if it was in process rather than seeing
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // what looks like a valid empty string.
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      StringVar* string_var = StringVar::FromPPVar(var_);
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      m->WriteString(string_var ? *string_var->ptr() : std::string());
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case PP_VARTYPE_ARRAY_BUFFER: {
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // TODO(dmichael) in the case of an invalid var ID, it would be nice
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // to send something to the other side such that a 0 ID would be
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // generated there. Then the function implementing the interface can
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // handle the invalid string as if it was in process rather than seeing
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // what looks like a valid empty ArraryBuffer.
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ArrayBufferVar* buffer_var = ArrayBufferVar::FromPPVar(var_);
1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      bool using_shmem = false;
1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      if (buffer_var &&
1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          buffer_var->ByteLength() >= kMinimumArrayBufferSizeForShmem &&
1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          instance_ != 0) {
1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        int host_shm_handle_id;
1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        base::SharedMemoryHandle plugin_shm_handle;
1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        using_shmem = buffer_var->CopyToNewShmem(instance_,
1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                                 &host_shm_handle_id,
1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                                 &plugin_shm_handle);
1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        if (using_shmem) {
1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          // The serialization for this message MUST MATCH the implementation
1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          // at SerializedVar::Inner::WriteRawVarHeader for
1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          // ARRAY_BUFFER_SHMEM_PLUGIN.
1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          if (host_shm_handle_id != -1) {
1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            DCHECK(!base::SharedMemory::IsHandleValid(plugin_shm_handle));
1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            DCHECK(PpapiGlobals::Get()->IsPluginGlobals());
1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            m->WriteInt(ARRAY_BUFFER_SHMEM_HOST);
1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            m->WriteInt(host_shm_handle_id);
1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          } else {
1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            DCHECK(base::SharedMemory::IsHandleValid(plugin_shm_handle));
1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            DCHECK(PpapiGlobals::Get()->IsHostGlobals());
1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            m->WriteInt(ARRAY_BUFFER_SHMEM_PLUGIN);
1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            m->WriteInt(buffer_var->ByteLength());
1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            SerializedHandle handle(plugin_shm_handle,
1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                    buffer_var->ByteLength());
1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            IPC::ParamTraits<SerializedHandle>::Write(m, handle);
1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          }
1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        }
1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      }
1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      if (!using_shmem) {
1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        if (buffer_var) {
1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          m->WriteInt(ARRAY_BUFFER_NO_SHMEM);
1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          m->WriteData(static_cast<const char*>(buffer_var->Map()),
1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                       buffer_var->ByteLength());
1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        } else {
1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          // TODO(teravest): Introduce an ARRAY_BUFFER_EMPTY message type.
1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          m->WriteBool(ARRAY_BUFFER_NO_SHMEM);
1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          m->WriteData(NULL, 0);
1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        }
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case PP_VARTYPE_OBJECT:
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      m->WriteInt64(var_.value.as_id);
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case PP_VARTYPE_ARRAY:
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case PP_VARTYPE_DICTIONARY:
2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      // TODO(yzshen) when these are supported, implement this.
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NOTIMPLEMENTED();
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool SerializedVar::Inner::ReadFromMessage(const IPC::Message* m,
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                           PickleIterator* iter) {
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef NDEBUG
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We should only deserialize something once or will end up with leaked
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // references.
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // One place this has happened in the past is using
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // std::vector<SerializedVar>.resize(). If you're doing this manually instead
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // of using the helper classes for handling in/out vectors of vars, be
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // sure you use the same pattern as the SerializedVarVector classes.
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(!has_been_deserialized_);
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  has_been_deserialized_ = true;
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // When reading, the dispatcher should be set when we get a Deserialize
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // call (which will supply a dispatcher).
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int type;
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!m->ReadInt(iter, &type))
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool success = false;
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  switch (type) {
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case PP_VARTYPE_UNDEFINED:
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case PP_VARTYPE_NULL:
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // These don't have any data associated with them other than the type we
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // just serialized.
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      success = true;
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case PP_VARTYPE_BOOL: {
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      bool bool_value;
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      success = m->ReadBool(iter, &bool_value);
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      var_.value.as_bool = PP_FromBool(bool_value);
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case PP_VARTYPE_INT32:
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      success = m->ReadInt(iter, &var_.value.as_int);
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case PP_VARTYPE_DOUBLE:
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      success = IPC::ParamTraits<double>::Read(m, iter, &var_.value.as_double);
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case PP_VARTYPE_STRING: {
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      raw_var_data_.reset(new RawVarData);
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      raw_var_data_->type = PP_VARTYPE_STRING;
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      success = m->ReadString(iter, &raw_var_data_->data);
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (!success)
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        raw_var_data_.reset(NULL);
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case PP_VARTYPE_ARRAY_BUFFER: {
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      int length = 0;
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const char* message_bytes = NULL;
2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      int shmem_type;
2602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      success = m->ReadInt(iter, &shmem_type);
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (success) {
2622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        if (shmem_type == ARRAY_BUFFER_NO_SHMEM) {
2632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          success = m->ReadData(iter, &message_bytes, &length);
2642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          if (success) {
2652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            raw_var_data_.reset(new RawVarData);
2662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            raw_var_data_->type = PP_VARTYPE_ARRAY_BUFFER;
2672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            raw_var_data_->shmem_type = static_cast<ShmemType>(shmem_type);
2682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            raw_var_data_->shmem_size = 0;
2692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            raw_var_data_->data.assign(message_bytes, length);
2702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          }
2712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        } else if (shmem_type == ARRAY_BUFFER_SHMEM_HOST) {
2722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          int host_handle_id;
2732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          success = m->ReadInt(iter, &host_handle_id);
2742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          if (success) {
2752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            raw_var_data_.reset(new RawVarData);
2762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            raw_var_data_->type = PP_VARTYPE_ARRAY_BUFFER;
2772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            raw_var_data_->shmem_type = static_cast<ShmemType>(shmem_type);
2782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            raw_var_data_->host_handle_id = host_handle_id;
2792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          }
2802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        } else if (shmem_type == ARRAY_BUFFER_SHMEM_PLUGIN) {
2812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          SerializedHandle plugin_handle;
2822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          success = m->ReadInt(iter, &length);
2832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          success &= IPC::ParamTraits<SerializedHandle>::Read(
2842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              m, iter, &plugin_handle);
2852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          if (success) {
2862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            raw_var_data_.reset(new RawVarData);
2872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            raw_var_data_->type = PP_VARTYPE_ARRAY_BUFFER;
2882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            raw_var_data_->shmem_type = static_cast<ShmemType>(shmem_type);
2892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            raw_var_data_->shmem_size = length;
2902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            raw_var_data_->plugin_handle = plugin_handle;
2912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          }
2922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        }
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case PP_VARTYPE_OBJECT:
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      success = m->ReadInt64(iter, &var_.value.as_id);
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case PP_VARTYPE_ARRAY:
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case PP_VARTYPE_DICTIONARY:
3012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      // TODO(yzshen) when these types are supported, implement this.
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NOTIMPLEMENTED();
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    default:
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Leave success as false.
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // All success cases get here. We avoid writing the type above so that the
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // output param is untouched (defaults to VARTYPE_UNDEFINED) even in the
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // failure case.
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We also don't write the type if |raw_var_data_| is set. |var_| will be
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // updated lazily when GetVar() is called.
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (success && !raw_var_data_.get())
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    var_.type = static_cast<PP_VarType>(type);
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return success;
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SerializedVar::Inner::SetCleanupModeToEndSendPassRef() {
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  cleanup_mode_ = END_SEND_PASS_REF;
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SerializedVar::Inner::SetCleanupModeToEndReceiveCallerOwned() {
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  cleanup_mode_ = END_RECEIVE_CALLER_OWNED;
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SerializedVar::Inner::ConvertRawVarData() {
3282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(NACL_WIN64)
3292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  NOTREACHED();
3302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#else
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!raw_var_data_.get())
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK_EQ(PP_VARTYPE_UNDEFINED, var_.type);
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  switch (raw_var_data_->type) {
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case PP_VARTYPE_STRING: {
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      var_ = StringVar::SwapValidatedUTF8StringIntoPPVar(
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          &raw_var_data_->data);
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case PP_VARTYPE_ARRAY_BUFFER: {
3422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      if (raw_var_data_->shmem_type == ARRAY_BUFFER_SHMEM_HOST) {
3432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        base::SharedMemoryHandle host_handle;
3442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        uint32 size_in_bytes;
3452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        bool ok =
3462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            PpapiGlobals::Get()->GetVarTracker()->
3472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            StopTrackingSharedMemoryHandle(raw_var_data_->host_handle_id,
3482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                           instance_,
3492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                           &host_handle,
3502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                           &size_in_bytes);
3512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        if (ok) {
3522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          var_ = PpapiGlobals::Get()->GetVarTracker()->MakeArrayBufferPPVar(
3532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              size_in_bytes, host_handle);
3542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        } else {
3552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          LOG(ERROR) << "Couldn't find array buffer id: "
3562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                     <<  raw_var_data_->host_handle_id;
3572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          var_ = PP_MakeUndefined();
3582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        }
3592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      } else if (raw_var_data_->shmem_type == ARRAY_BUFFER_SHMEM_PLUGIN) {
3602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        var_ = PpapiGlobals::Get()->GetVarTracker()->MakeArrayBufferPPVar(
3612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            raw_var_data_->shmem_size,
3622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            raw_var_data_->plugin_handle.shmem());
3632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      } else {
3642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        var_ = PpapiGlobals::Get()->GetVarTracker()->MakeArrayBufferPPVar(
3652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            static_cast<uint32>(raw_var_data_->data.size()),
3662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            raw_var_data_->data.data());
3672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      }
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    default:
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NOTREACHED();
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  raw_var_data_.reset(NULL);
3742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
3752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)SerializedHandle* SerializedVar::Inner::GetPluginShmemHandle() const {
3782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (raw_var_data_.get()) {
3792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (raw_var_data_->type == PP_VARTYPE_ARRAY_BUFFER) {
3802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      if (raw_var_data_->shmem_size != 0)
3812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        return &raw_var_data_->plugin_handle;
3822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
3832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return NULL;
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// SerializedVar ---------------------------------------------------------------
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SerializedVar::SerializedVar() : inner_(new Inner) {
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SerializedVar::SerializedVar(VarSerializationRules* serialization_rules)
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : inner_(new Inner(serialization_rules)) {
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SerializedVar::~SerializedVar() {
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// SerializedVarSendInput ------------------------------------------------------
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SerializedVarSendInput::SerializedVarSendInput(Dispatcher* dispatcher,
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                               const PP_Var& var)
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : SerializedVar(dispatcher->serialization_rules()) {
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  inner_->SetVar(dispatcher->serialization_rules()->SendCallerOwned(var));
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SerializedVarSendInput::ConvertVector(Dispatcher* dispatcher,
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                           const PP_Var* input,
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                           size_t input_count,
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                           std::vector<SerializedVar>* output) {
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  output->reserve(input_count);
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < input_count; i++)
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    output->push_back(SerializedVarSendInput(dispatcher, input[i]));
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// SerializedVarSendInputShmem -------------------------------------------------
4182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)SerializedVarSendInputShmem::SerializedVarSendInputShmem(
4202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    Dispatcher* dispatcher,
4212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const PP_Var& var,
4222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const PP_Instance& instance)
4232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    : SerializedVar(dispatcher->serialization_rules()) {
4242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  inner_->SetVar(dispatcher->serialization_rules()->SendCallerOwned(var));
4252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  inner_->SetInstance(instance);
4262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ReceiveSerializedVarReturnValue ---------------------------------------------
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ReceiveSerializedVarReturnValue::ReceiveSerializedVarReturnValue() {
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ReceiveSerializedVarReturnValue::ReceiveSerializedVarReturnValue(
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const SerializedVar& serialized)
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : SerializedVar(serialized) {
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PP_Var ReceiveSerializedVarReturnValue::Return(Dispatcher* dispatcher) {
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  inner_->set_serialization_rules(dispatcher->serialization_rules());
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  inner_->SetVar(inner_->serialization_rules()->ReceivePassRef(
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      inner_->GetVar()));
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return inner_->GetVar();
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ReceiveSerializedException --------------------------------------------------
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ReceiveSerializedException::ReceiveSerializedException(Dispatcher* dispatcher,
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                       PP_Var* exception)
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : SerializedVar(dispatcher->serialization_rules()),
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      exception_(exception) {
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ReceiveSerializedException::~ReceiveSerializedException() {
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (exception_) {
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // When an output exception is specified, it will take ownership of the
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // reference.
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    inner_->SetVar(
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        inner_->serialization_rules()->ReceivePassRef(inner_->GetVar()));
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *exception_ = inner_->GetVar();
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // When no output exception is specified, the browser thinks we have a ref
4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // to an object that we don't want (this will happen only in the plugin
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // since the browser will always specify an out exception for the plugin to
4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // write into).
4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //
4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Strings don't need this handling since we can just avoid creating a
4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Var from the std::string in the first place.
4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (inner_->GetVar().type == PP_VARTYPE_OBJECT)
4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      inner_->serialization_rules()->ReleaseObjectRef(inner_->GetVar());
4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ReceiveSerializedException::IsThrown() const {
4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return exception_ && exception_->type != PP_VARTYPE_UNDEFINED;
4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ReceiveSerializedVarVectorOutParam ------------------------------------------
4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ReceiveSerializedVarVectorOutParam::ReceiveSerializedVarVectorOutParam(
4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Dispatcher* dispatcher,
4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    uint32_t* output_count,
4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PP_Var** output)
4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : dispatcher_(dispatcher),
4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      output_count_(output_count),
4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      output_(output) {
4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ReceiveSerializedVarVectorOutParam::~ReceiveSerializedVarVectorOutParam() {
4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  *output_count_ = static_cast<uint32_t>(vector_.size());
4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!vector_.size()) {
4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *output_ = NULL;
4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  *output_ = static_cast<PP_Var*>(malloc(vector_.size() * sizeof(PP_Var)));
4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < vector_.size(); i++) {
4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Here we just mimic what happens when returning a value.
4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ReceiveSerializedVarReturnValue converted;
4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SerializedVar* serialized = &converted;
5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *serialized = vector_[i];
5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    (*output_)[i] = converted.Return(dispatcher_);
5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::vector<SerializedVar>* ReceiveSerializedVarVectorOutParam::OutParam() {
5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return &vector_;
5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// SerializedVarReceiveInput ---------------------------------------------------
5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SerializedVarReceiveInput::SerializedVarReceiveInput(
5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const SerializedVar& serialized)
5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : serialized_(serialized) {
5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SerializedVarReceiveInput::~SerializedVarReceiveInput() {
5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PP_Var SerializedVarReceiveInput::Get(Dispatcher* dispatcher) {
5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  serialized_.inner_->set_serialization_rules(
5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      dispatcher->serialization_rules());
5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Ensure that when the serialized var goes out of scope it cleans up the
5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // stuff we're making in BeginReceiveCallerOwned.
5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  serialized_.inner_->SetCleanupModeToEndReceiveCallerOwned();
5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  serialized_.inner_->SetVar(
5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      serialized_.inner_->serialization_rules()->BeginReceiveCallerOwned(
5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          serialized_.inner_->GetVar()));
5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return serialized_.inner_->GetVar();
5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)PP_Var SerializedVarReceiveInput::GetForInstance(Dispatcher* dispatcher,
5352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                                 PP_Instance instance) {
5362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  serialized_.inner_->SetInstance(instance);
5372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return Get(dispatcher);
5382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// SerializedVarVectorReceiveInput ---------------------------------------------
5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SerializedVarVectorReceiveInput::SerializedVarVectorReceiveInput(
5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::vector<SerializedVar>& serialized)
5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : serialized_(serialized) {
5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SerializedVarVectorReceiveInput::~SerializedVarVectorReceiveInput() {
5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < deserialized_.size(); i++) {
5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    serialized_[i].inner_->serialization_rules()->EndReceiveCallerOwned(
5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        deserialized_[i]);
5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PP_Var* SerializedVarVectorReceiveInput::Get(Dispatcher* dispatcher,
5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                             uint32_t* array_size) {
5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  deserialized_.resize(serialized_.size());
5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < serialized_.size(); i++) {
5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // The vectors must be able to clean themselves up after this call is
5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // torn down.
5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    serialized_[i].inner_->set_serialization_rules(
5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        dispatcher->serialization_rules());
5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    serialized_[i].inner_->SetVar(
5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        serialized_[i].inner_->serialization_rules()->BeginReceiveCallerOwned(
5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            serialized_[i].inner_->GetVar()));
5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    deserialized_[i] = serialized_[i].inner_->GetVar();
5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  *array_size = static_cast<uint32_t>(serialized_.size());
5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return deserialized_.empty() ? NULL : &deserialized_[0];
5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// SerializedVarReturnValue ----------------------------------------------------
5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SerializedVarReturnValue::SerializedVarReturnValue(SerializedVar* serialized)
5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : serialized_(serialized) {
5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SerializedVarReturnValue::Return(Dispatcher* dispatcher,
5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                      const PP_Var& var) {
5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  serialized_->inner_->set_serialization_rules(
5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      dispatcher->serialization_rules());
5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Var must clean up after our BeginSendPassRef call.
5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  serialized_->inner_->SetCleanupModeToEndSendPassRef();
5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  serialized_->inner_->SetVar(
5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      dispatcher->serialization_rules()->BeginSendPassRef(var));
5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SerializedVar SerializedVarReturnValue::Convert(Dispatcher* dispatcher,
5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                const PP_Var& var) {
5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Mimic what happens in the normal case.
5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SerializedVar result;
5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SerializedVarReturnValue retvalue(&result);
5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  retvalue.Return(dispatcher, var);
5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return result;
5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// SerializedVarOutParam -------------------------------------------------------
6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SerializedVarOutParam::SerializedVarOutParam(SerializedVar* serialized)
6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : serialized_(serialized),
6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      writable_var_(PP_MakeUndefined()),
6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      dispatcher_(NULL) {
6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SerializedVarOutParam::~SerializedVarOutParam() {
6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (serialized_->inner_->serialization_rules()) {
6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // When unset, OutParam wasn't called. We'll just leave the var untouched
6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // in that case.
6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    serialized_->inner_->SetVar(
6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        serialized_->inner_->serialization_rules()->BeginSendPassRef(
6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            writable_var_));
6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Normally the current object will be created on the stack to wrap a
6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // SerializedVar and won't have a scope around the actual IPC send. So we
6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // need to tell the SerializedVar to do the begin/end send pass ref calls.
6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    serialized_->inner_->SetCleanupModeToEndSendPassRef();
6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PP_Var* SerializedVarOutParam::OutParam(Dispatcher* dispatcher) {
6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  dispatcher_ = dispatcher;
6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  serialized_->inner_->set_serialization_rules(
6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      dispatcher->serialization_rules());
6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return &writable_var_;
6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// SerializedVarVectorOutParam -------------------------------------------------
6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SerializedVarVectorOutParam::SerializedVarVectorOutParam(
6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::vector<SerializedVar>* serialized)
6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : dispatcher_(NULL),
6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      serialized_(serialized),
6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      count_(0),
6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      array_(NULL) {
6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SerializedVarVectorOutParam::~SerializedVarVectorOutParam() {
6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(dispatcher_);
6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Convert the array written by the pepper code to the serialized structure.
6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Note we can't use resize here, we have to allocate a new SerializedVar
6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // for each serialized item. See ParamTraits<vector<SerializedVar>>::Read.
6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  serialized_->reserve(count_);
6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (uint32_t i = 0; i < count_; i++) {
6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Just mimic what we do for regular OutParams.
6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SerializedVar var;
6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SerializedVarOutParam out(&var);
6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *out.OutParam(dispatcher_) = array_[i];
6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    serialized_->push_back(var);
6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // When returning arrays, the pepper code expects the caller to take
6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // ownership of the array.
6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  free(array_);
6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PP_Var** SerializedVarVectorOutParam::ArrayOutParam(Dispatcher* dispatcher) {
6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(!dispatcher_);  // Should only be called once.
6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  dispatcher_ = dispatcher;
6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return &array_;
6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SerializedVarTestConstructor::SerializedVarTestConstructor(
6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const PP_Var& pod_var) {
6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(pod_var.type != PP_VARTYPE_STRING);
6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  inner_->ForceSetVarValueForTest(pod_var);
6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SerializedVarTestConstructor::SerializedVarTestConstructor(
6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& str) {
6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  inner_->ForceSetVarValueForTest(StringVar::StringToPPVar(str));
6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SerializedVarTestReader::SerializedVarTestReader(const SerializedVar& var)
6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : SerializedVar(var) {
6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace proxy
6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace ppapi
684