DXR is a code search and navigation tool aimed at making sense of large projects. It supports full-text and regex searches as well as structural queries.

Implementation

Mercurial (27a812186ff4)

VCS Links

Line Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
 * vim: sw=2 ts=2 et :
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#ifndef dom_plugins_PluginIdentifierChild_h
#define dom_plugins_PluginIdentifierChild_h

#include "mozilla/plugins/PPluginIdentifierChild.h"
#include "npapi.h"
#include "npruntime.h"

#include "nsString.h"

namespace mozilla {
namespace plugins {

class PluginModuleChild;

/**
 * Plugin identifiers may be "temporary", see the comment on the
 * PPluginIdentifier constructor for details. This means that any IPDL method
 * which receives a PPluginIdentifierChild* parameter must use StackIdentifier
 * to track it.
 */
class PluginIdentifierChild : public PPluginIdentifierChild
{
  friend class PluginModuleChild;
public:
  bool IsString()
  {
    return mIsString;
  }

  NPIdentifier ToNPIdentifier()
  {
    if (mCanonicalIdentifier) {
      return mCanonicalIdentifier;
    }

    NS_ASSERTION(mHashed, "Handing out an unhashed identifier?");
    return this;
  }

  void MakePermanent();

  class MOZ_STACK_CLASS StackIdentifier
  {
  public:
    StackIdentifier(PPluginIdentifierChild* actor)
      : mIdentifier(static_cast<PluginIdentifierChild*>(actor))
    {
      if (mIdentifier)
        mIdentifier->StartTemporary();
    }

    ~StackIdentifier() {
      if (mIdentifier)
        mIdentifier->FinishTemporary();
    }

    PluginIdentifierChild* operator->() { return mIdentifier; }

  private:
    PluginIdentifierChild* mIdentifier;
  };

protected:
  PluginIdentifierChild(bool aIsString)
    : mCanonicalIdentifier(nullptr)
    , mHashed(false)
    , mTemporaryRefs(0)
    , mIsString(aIsString)
  {
    MOZ_COUNT_CTOR(PluginIdentifierChild);
  }

  virtual ~PluginIdentifierChild()
  {
    MOZ_COUNT_DTOR(PluginIdentifierChild);
  }

  // The following functions are implemented by the subclasses for their
  // identifier maps.
  virtual PluginIdentifierChild* GetCanonical() = 0;
  virtual void Hash() = 0;
  virtual void Unhash() = 0;

private:
  void StartTemporary();
  void FinishTemporary();

  // There's a possibility that we already have an actor that wraps the same
  // string or int because we do all this identifier construction
  // asynchronously. In this case we need to hand out the canonical version
  // created by the child side.
  //
  // In order to deal with temporary identifiers which appear on the stack,
  // identifiers use the following state invariants:
  //
  // * mCanonicalIdentifier is non-nullptr: this is a duplicate identifier, no
  //   further information is necessary.
  // * mHashed is false: this identifier is a newborn, non-permanent identifier
  // * mHashed is true, mTemporaryRefs is 0: this identifier is permanent
  // * mHashed is true, mTemporaryRefs is non-0: this identifier is temporary;
  //   if NPN_GetFooIdentifier is called for it, we need to retain it. If
  //   all stack references are lost, unhash it because it will soon be 
  //   deleted.

  PluginIdentifierChild* mCanonicalIdentifier;
  bool mHashed;
  unsigned int mTemporaryRefs;
  bool mIsString;
};

class PluginIdentifierChildString : public PluginIdentifierChild
{
  friend class PluginModuleChild;
public:
  NPUTF8* ToString()
  {
    return ToNewCString(mString);
  }

protected:
  PluginIdentifierChildString(const nsCString& aString)
    : PluginIdentifierChild(true),
      mString(aString)
  { }

  virtual PluginIdentifierChild* GetCanonical();
  virtual void Hash();
  virtual void Unhash();

  nsCString mString;
};

class PluginIdentifierChildInt : public PluginIdentifierChild
{
  friend class PluginModuleChild;
public:
  int32_t ToInt()
  {
    return mInt;
  }

protected:
  PluginIdentifierChildInt(int32_t aInt)
    : PluginIdentifierChild(false),
      mInt(aInt)
  { }

  virtual PluginIdentifierChild* GetCanonical();
  virtual void Hash();
  virtual void Unhash();

  int32_t mInt;
};

} // namespace plugins
} // namespace mozilla

#endif // dom_plugins_PluginIdentifierChild_h