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.
5 #ifndef WEBKIT_PLUGINS_PPAPI_NPAPI_GLUE_H_
6 #define WEBKIT_PLUGINS_PPAPI_NPAPI_GLUE_H_
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"
15 typedef struct _NPVariant NPVariant
;
16 typedef void* NPIdentifier
;
24 // Utilities -------------------------------------------------------------------
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.
30 // The contents of the PP_Var will be copied unless the PP_Var corresponds to
32 bool PPVarToNPVariant(PP_Var var
, NPVariant
* result
);
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
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(PluginInstance
* instance
,
42 const NPVariant
* variant
);
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
);
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
);
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
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.
62 // If no ObjectVar currently exists corresponding to the NPObject, one is
63 // created associated with the given module.
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(PluginInstance
* instance
,
71 // PPResultAndExceptionToNPResult ----------------------------------------------
73 // Convenience object for converting a PPAPI call that can throw an exception
74 // and optionally return a value, back to the NPAPI layer which expects a
75 // NPVariant as a result.
77 // Normal usage is that you will pass the result of exception() to the
78 // PPAPI function as the exception output parameter. Then you will either
79 // call SetResult with the result of the PPAPI call, or
80 // CheckExceptionForNoResult if the PPAPI call doesn't return a PP_Var.
82 // Both SetResult and CheckExceptionForNoResult will throw an exception to
83 // the JavaScript library if the plugin reported an exception. SetResult
84 // will additionally convert the result to an NPVariant and write it to the
85 // output parameter given in the constructor.
86 class PPResultAndExceptionToNPResult
{
88 // The object_var parameter is the object to associate any exception with.
89 // It may not be NULL.
91 // The np_result parameter is the NPAPI result output parameter. This may be
92 // NULL if there is no NPVariant result (like for HasProperty). If this is
93 // specified, you must call SetResult() to set it. If it is not, you must
94 // call CheckExceptionForNoResult to do the exception checking with no result
96 PPResultAndExceptionToNPResult(NPObject
* object_var
, NPVariant
* np_result
);
98 ~PPResultAndExceptionToNPResult();
100 // Returns true if an exception has been set.
101 bool has_exception() const { return exception_
.type
!= PP_VARTYPE_UNDEFINED
; }
103 // Returns a pointer to the exception. You would pass this to the PPAPI
104 // function as the exception parameter. If it is set to non-void, this object
105 // will take ownership of destroying it.
106 PP_Var
* exception() { return &exception_
; }
108 // Returns true if everything succeeded with no exception. This is valid only
109 // after calling SetResult/CheckExceptionForNoResult.
110 bool success() const {
114 // Call this with the return value of the PPAPI function. It will convert
115 // the result to the NPVariant output parameter and pass any exception on to
116 // the JS engine. It will update the success flag and return it.
117 bool SetResult(PP_Var result
);
119 // Call this after calling a PPAPI function that could have set the
120 // exception. It will pass the exception on to the JS engine and update
123 // The success flag will be returned.
124 bool CheckExceptionForNoResult();
126 // Call this to ignore any exception. This prevents the DCHECK from failing
127 // in the destructor.
128 void IgnoreException();
131 // Throws the current exception to JS. The exception must be set.
132 void ThrowException();
134 NPObject
* object_var_
; // Non-owning ref (see constructor).
135 NPVariant
* np_result_
; // Output value, possibly NULL (see constructor).
136 PP_Var exception_
; // Exception set by the PPAPI call. We own a ref to it.
137 bool success_
; // See the success() function above.
138 bool checked_exception_
; // SetResult/CheckExceptionForNoResult was called.
140 DISALLOW_COPY_AND_ASSIGN(PPResultAndExceptionToNPResult
);
143 // PPVarArrayFromNPVariantArray ------------------------------------------------
145 // Converts an array of NPVariants to an array of PP_Var, and scopes the
146 // ownership of the PP_Var. This is used when converting argument lists from
147 // WebKit to the plugin.
148 class PPVarArrayFromNPVariantArray
{
150 PPVarArrayFromNPVariantArray(PluginInstance
* instance
,
152 const NPVariant
* variants
);
153 ~PPVarArrayFromNPVariantArray();
155 PP_Var
* array() { return array_
.get(); }
159 scoped_array
<PP_Var
> array_
;
161 DISALLOW_COPY_AND_ASSIGN(PPVarArrayFromNPVariantArray
);
164 // PPVarFromNPObject -----------------------------------------------------------
166 // Converts an NPObject tp PP_Var, and scopes the ownership of the PP_Var. This
167 // is used when converting 'this' pointer from WebKit to the plugin.
168 class PPVarFromNPObject
{
170 PPVarFromNPObject(PluginInstance
* instance
, NPObject
* object
);
171 ~PPVarFromNPObject();
173 PP_Var
var() const { return var_
; }
178 DISALLOW_COPY_AND_ASSIGN(PPVarFromNPObject
);
181 // NPObjectAccessorWithIdentifier ----------------------------------------------
183 // Helper class for our NPObject wrapper. This converts a call from WebKit
184 // where it gives us an NPObject and an NPIdentifier to an easily-accessible
185 // ObjectVar (corresponding to the NPObject) and PP_Var (corresponding to the
188 // If the NPObject or identifier is invalid, we'll set is_valid() to false.
189 // The caller should check is_valid() before doing anything with the class.
191 // JS can't have integer functions, so when dealing with these, we don't want
192 // to allow integer identifiers. The calling code can decode if it wants to
193 // allow integer identifiers (like for property access) or prohibit them
194 // (like for method calling) by setting |allow_integer_identifier|. If this
195 // is false and the identifier is an integer, we'll set is_valid() to false.
197 // Getting an integer identifier in this case should be impossible. V8
198 // shouldn't be allowing this, and the Pepper Var calls from the plugin are
199 // supposed to error out before calling into V8 (which will then call us back).
200 // Aside from an egregious error, the only time this could happen is an NPAPI
201 // plugin calling us.
202 class NPObjectAccessorWithIdentifier
{
204 NPObjectAccessorWithIdentifier(NPObject
* object
,
205 NPIdentifier identifier
,
206 bool allow_integer_identifier
);
207 ~NPObjectAccessorWithIdentifier();
209 // Returns true if both the object and identifier are valid.
210 bool is_valid() const {
211 return object_
&& identifier_
.type
!= PP_VARTYPE_UNDEFINED
;
214 PluginObject
* object() { return object_
; }
215 PP_Var
identifier() const { return identifier_
; }
218 PluginObject
* object_
;
221 DISALLOW_COPY_AND_ASSIGN(NPObjectAccessorWithIdentifier
);
224 // TryCatch --------------------------------------------------------------------
226 // Instantiate this object on the stack to catch V8 exceptions and pass them
227 // to an optional out parameter supplied by the plugin.
230 // The given exception may be NULL if the consumer isn't interested in
231 // catching exceptions. If non-NULL, the given var will be updated if any
232 // exception is thrown (so it must outlive the TryCatch object).
233 TryCatch(PP_Var
* exception
);
236 // Returns true is an exception has been thrown. This can be true immediately
237 // after construction if the var passed to the constructor is non-void.
238 bool has_exception() const { return has_exception_
; }
240 // Sets the given exception. If an exception has been previously set, this
241 // function will do nothing (normally you want only the first exception).
242 void SetException(const char* message
);
245 static void Catch(void* self
, const char* message
);
247 // True if an exception has been thrown. Since the exception itself may be
248 // NULL if the plugin isn't interested in getting the exception, this will
249 // always indicate if SetException has been called, regardless of whether
250 // the exception itself has been stored.
253 // May be null if the consumer isn't interesting in catching exceptions.
258 } // namespace webkit
260 #endif // WEBKIT_PLUGINS_PPAPI_NPAPI_GLUE_H_