| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #ifndef WEBKIT_PLUGINS_PPAPI_NPAPI_GLUE_H_ | |
| 6 #define WEBKIT_PLUGINS_PPAPI_NPAPI_GLUE_H_ | |
| 7 | |
| 8 #include "base/basictypes.h" | |
| 9 #include "base/memory/scoped_ptr.h" | |
| 10 #include "ppapi/c/pp_module.h" | |
| 11 #include "ppapi/c/pp_var.h" | |
| 12 #include "webkit/plugins/webkit_plugins_export.h" | |
| 13 | |
| 14 struct NPObject; | |
| 15 typedef struct _NPVariant NPVariant; | |
| 16 typedef void* NPIdentifier; | |
| 17 | |
| 18 namespace webkit { | |
| 19 namespace ppapi { | |
| 20 | |
| 21 class PluginInstanceImpl; | |
| 22 class PluginObject; | |
| 23 | |
| 24 // Utilities ------------------------------------------------------------------- | |
| 25 | |
| 26 // Converts the given PP_Var to an NPVariant, returning true on success. | |
| 27 // False means that the given variant is invalid. In this case, the result | |
| 28 // NPVariant will be set to a void one. | |
| 29 // | |
| 30 // The contents of the PP_Var will be copied unless the PP_Var corresponds to | |
| 31 // an object. | |
| 32 bool PPVarToNPVariant(PP_Var var, NPVariant* result); | |
| 33 | |
| 34 // Returns a PP_Var that corresponds to the given NPVariant. The contents of | |
| 35 // the NPVariant will be copied unless the NPVariant corresponds to an | |
| 36 // object. This will handle all Variant types including POD, strings, and | |
| 37 // objects. | |
| 38 // | |
| 39 // The returned PP_Var will have a refcount of 1, this passing ownership of | |
| 40 // the reference to the caller. This is suitable for returning to a plugin. | |
| 41 WEBKIT_PLUGINS_EXPORT PP_Var NPVariantToPPVar(PluginInstanceImpl* instance, | |
| 42 const NPVariant* variant); | |
| 43 | |
| 44 // Returns a NPIdentifier that corresponds to the given PP_Var. The contents | |
| 45 // of the PP_Var will be copied. Returns 0 if the given PP_Var is not a a | |
| 46 // string or integer type. | |
| 47 NPIdentifier PPVarToNPIdentifier(PP_Var var); | |
| 48 | |
| 49 // Returns a PP_Var corresponding to the given identifier. In the case of | |
| 50 // a string identifier, the returned string will have a reference count of 1. | |
| 51 PP_Var NPIdentifierToPPVar(NPIdentifier id); | |
| 52 | |
| 53 // Helper function to create a PP_Var of type object that contains the given | |
| 54 // NPObject for use byt he given module. Calling this function multiple times | |
| 55 // given the same module + NPObject results in the same PP_Var, assuming that | |
| 56 // there is still a PP_Var with a reference open to it from the previous | |
| 57 // call. | |
| 58 // | |
| 59 // The instance is necessary because we can have different instances pointing to | |
| 60 // the same NPObject, and we want to keep their refs separate. | |
| 61 // | |
| 62 // If no ObjectVar currently exists corresponding to the NPObject, one is | |
| 63 // created associated with the given module. | |
| 64 // | |
| 65 // Note: this could easily be changed to take a PP_Instance instead if that | |
| 66 // makes certain calls in the future easier. Currently all callers have a | |
| 67 // PluginInstance so that's what we use here. | |
| 68 WEBKIT_PLUGINS_EXPORT PP_Var NPObjectToPPVar(PluginInstanceImpl* instance, | |
| 69 NPObject* object); | |
| 70 | |
| 71 // This version creates a default v8::Context rather than using the one from | |
| 72 // the container of |instance|. It is only for use in unit tests, where we don't | |
| 73 // have a real container for |instance|. | |
| 74 WEBKIT_PLUGINS_EXPORT PP_Var NPObjectToPPVarForTest( | |
| 75 PluginInstanceImpl* instance, | |
| 76 NPObject* object); | |
| 77 | |
| 78 // PPResultAndExceptionToNPResult ---------------------------------------------- | |
| 79 | |
| 80 // Convenience object for converting a PPAPI call that can throw an exception | |
| 81 // and optionally return a value, back to the NPAPI layer which expects a | |
| 82 // NPVariant as a result. | |
| 83 // | |
| 84 // Normal usage is that you will pass the result of exception() to the | |
| 85 // PPAPI function as the exception output parameter. Then you will either | |
| 86 // call SetResult with the result of the PPAPI call, or | |
| 87 // CheckExceptionForNoResult if the PPAPI call doesn't return a PP_Var. | |
| 88 // | |
| 89 // Both SetResult and CheckExceptionForNoResult will throw an exception to | |
| 90 // the JavaScript library if the plugin reported an exception. SetResult | |
| 91 // will additionally convert the result to an NPVariant and write it to the | |
| 92 // output parameter given in the constructor. | |
| 93 class PPResultAndExceptionToNPResult { | |
| 94 public: | |
| 95 // The object_var parameter is the object to associate any exception with. | |
| 96 // It may not be NULL. | |
| 97 // | |
| 98 // The np_result parameter is the NPAPI result output parameter. This may be | |
| 99 // NULL if there is no NPVariant result (like for HasProperty). If this is | |
| 100 // specified, you must call SetResult() to set it. If it is not, you must | |
| 101 // call CheckExceptionForNoResult to do the exception checking with no result | |
| 102 // conversion. | |
| 103 PPResultAndExceptionToNPResult(NPObject* object_var, NPVariant* np_result); | |
| 104 | |
| 105 ~PPResultAndExceptionToNPResult(); | |
| 106 | |
| 107 // Returns true if an exception has been set. | |
| 108 bool has_exception() const { return exception_.type != PP_VARTYPE_UNDEFINED; } | |
| 109 | |
| 110 // Returns a pointer to the exception. You would pass this to the PPAPI | |
| 111 // function as the exception parameter. If it is set to non-void, this object | |
| 112 // will take ownership of destroying it. | |
| 113 PP_Var* exception() { return &exception_; } | |
| 114 | |
| 115 // Returns true if everything succeeded with no exception. This is valid only | |
| 116 // after calling SetResult/CheckExceptionForNoResult. | |
| 117 bool success() const { | |
| 118 return success_; | |
| 119 } | |
| 120 | |
| 121 // Call this with the return value of the PPAPI function. It will convert | |
| 122 // the result to the NPVariant output parameter and pass any exception on to | |
| 123 // the JS engine. It will update the success flag and return it. | |
| 124 bool SetResult(PP_Var result); | |
| 125 | |
| 126 // Call this after calling a PPAPI function that could have set the | |
| 127 // exception. It will pass the exception on to the JS engine and update | |
| 128 // the success flag. | |
| 129 // | |
| 130 // The success flag will be returned. | |
| 131 bool CheckExceptionForNoResult(); | |
| 132 | |
| 133 // Call this to ignore any exception. This prevents the DCHECK from failing | |
| 134 // in the destructor. | |
| 135 void IgnoreException(); | |
| 136 | |
| 137 private: | |
| 138 // Throws the current exception to JS. The exception must be set. | |
| 139 void ThrowException(); | |
| 140 | |
| 141 NPObject* object_var_; // Non-owning ref (see constructor). | |
| 142 NPVariant* np_result_; // Output value, possibly NULL (see constructor). | |
| 143 PP_Var exception_; // Exception set by the PPAPI call. We own a ref to it. | |
| 144 bool success_; // See the success() function above. | |
| 145 bool checked_exception_; // SetResult/CheckExceptionForNoResult was called. | |
| 146 | |
| 147 DISALLOW_COPY_AND_ASSIGN(PPResultAndExceptionToNPResult); | |
| 148 }; | |
| 149 | |
| 150 // PPVarArrayFromNPVariantArray ------------------------------------------------ | |
| 151 | |
| 152 // Converts an array of NPVariants to an array of PP_Var, and scopes the | |
| 153 // ownership of the PP_Var. This is used when converting argument lists from | |
| 154 // WebKit to the plugin. | |
| 155 class PPVarArrayFromNPVariantArray { | |
| 156 public: | |
| 157 PPVarArrayFromNPVariantArray(PluginInstanceImpl* instance, | |
| 158 size_t size, | |
| 159 const NPVariant* variants); | |
| 160 ~PPVarArrayFromNPVariantArray(); | |
| 161 | |
| 162 PP_Var* array() { return array_.get(); } | |
| 163 | |
| 164 private: | |
| 165 size_t size_; | |
| 166 scoped_ptr<PP_Var[]> array_; | |
| 167 | |
| 168 DISALLOW_COPY_AND_ASSIGN(PPVarArrayFromNPVariantArray); | |
| 169 }; | |
| 170 | |
| 171 // PPVarFromNPObject ----------------------------------------------------------- | |
| 172 | |
| 173 // Converts an NPObject tp PP_Var, and scopes the ownership of the PP_Var. This | |
| 174 // is used when converting 'this' pointer from WebKit to the plugin. | |
| 175 class PPVarFromNPObject { | |
| 176 public: | |
| 177 PPVarFromNPObject(PluginInstanceImpl* instance, NPObject* object); | |
| 178 ~PPVarFromNPObject(); | |
| 179 | |
| 180 PP_Var var() const { return var_; } | |
| 181 | |
| 182 private: | |
| 183 const PP_Var var_; | |
| 184 | |
| 185 DISALLOW_COPY_AND_ASSIGN(PPVarFromNPObject); | |
| 186 }; | |
| 187 | |
| 188 // NPObjectAccessorWithIdentifier ---------------------------------------------- | |
| 189 | |
| 190 // Helper class for our NPObject wrapper. This converts a call from WebKit | |
| 191 // where it gives us an NPObject and an NPIdentifier to an easily-accessible | |
| 192 // ObjectVar (corresponding to the NPObject) and PP_Var (corresponding to the | |
| 193 // NPIdentifier). | |
| 194 // | |
| 195 // If the NPObject or identifier is invalid, we'll set is_valid() to false. | |
| 196 // The caller should check is_valid() before doing anything with the class. | |
| 197 // | |
| 198 // JS can't have integer functions, so when dealing with these, we don't want | |
| 199 // to allow integer identifiers. The calling code can decode if it wants to | |
| 200 // allow integer identifiers (like for property access) or prohibit them | |
| 201 // (like for method calling) by setting |allow_integer_identifier|. If this | |
| 202 // is false and the identifier is an integer, we'll set is_valid() to false. | |
| 203 // | |
| 204 // Getting an integer identifier in this case should be impossible. V8 | |
| 205 // shouldn't be allowing this, and the Pepper Var calls from the plugin are | |
| 206 // supposed to error out before calling into V8 (which will then call us back). | |
| 207 // Aside from an egregious error, the only time this could happen is an NPAPI | |
| 208 // plugin calling us. | |
| 209 class NPObjectAccessorWithIdentifier { | |
| 210 public: | |
| 211 NPObjectAccessorWithIdentifier(NPObject* object, | |
| 212 NPIdentifier identifier, | |
| 213 bool allow_integer_identifier); | |
| 214 ~NPObjectAccessorWithIdentifier(); | |
| 215 | |
| 216 // Returns true if both the object and identifier are valid. | |
| 217 bool is_valid() const { | |
| 218 return object_ && identifier_.type != PP_VARTYPE_UNDEFINED; | |
| 219 } | |
| 220 | |
| 221 PluginObject* object() { return object_; } | |
| 222 PP_Var identifier() const { return identifier_; } | |
| 223 | |
| 224 private: | |
| 225 PluginObject* object_; | |
| 226 PP_Var identifier_; | |
| 227 | |
| 228 DISALLOW_COPY_AND_ASSIGN(NPObjectAccessorWithIdentifier); | |
| 229 }; | |
| 230 | |
| 231 // TryCatch -------------------------------------------------------------------- | |
| 232 | |
| 233 // Instantiate this object on the stack to catch V8 exceptions and pass them | |
| 234 // to an optional out parameter supplied by the plugin. | |
| 235 class TryCatch { | |
| 236 public: | |
| 237 // The given exception may be NULL if the consumer isn't interested in | |
| 238 // catching exceptions. If non-NULL, the given var will be updated if any | |
| 239 // exception is thrown (so it must outlive the TryCatch object). | |
| 240 TryCatch(PP_Var* exception); | |
| 241 ~TryCatch(); | |
| 242 | |
| 243 // Returns true is an exception has been thrown. This can be true immediately | |
| 244 // after construction if the var passed to the constructor is non-void. | |
| 245 bool has_exception() const { return has_exception_; } | |
| 246 | |
| 247 // Sets the given exception. If an exception has been previously set, this | |
| 248 // function will do nothing (normally you want only the first exception). | |
| 249 void SetException(const char* message); | |
| 250 | |
| 251 private: | |
| 252 static void Catch(void* self, const char* message); | |
| 253 | |
| 254 // True if an exception has been thrown. Since the exception itself may be | |
| 255 // NULL if the plugin isn't interested in getting the exception, this will | |
| 256 // always indicate if SetException has been called, regardless of whether | |
| 257 // the exception itself has been stored. | |
| 258 bool has_exception_; | |
| 259 | |
| 260 // May be null if the consumer isn't interesting in catching exceptions. | |
| 261 PP_Var* exception_; | |
| 262 }; | |
| 263 | |
| 264 } // namespace ppapi | |
| 265 } // namespace webkit | |
| 266 | |
| 267 #endif // WEBKIT_PLUGINS_PPAPI_NPAPI_GLUE_H_ | |
| OLD | NEW |