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
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
|
// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef WEBKIT_PLUGINS_PPAPI_NPAPI_GLUE_H_
#define WEBKIT_PLUGINS_PPAPI_NPAPI_GLUE_H_
#include "base/basictypes.h"
#include "base/memory/scoped_ptr.h"
#include "ppapi/c/pp_module.h"
#include "ppapi/c/pp_var.h"
#include "webkit/plugins/webkit_plugins_export.h"
struct NPObject;
typedef struct _NPVariant NPVariant;
typedef void* NPIdentifier;
namespace webkit {
namespace ppapi {
class PluginInstance;
class PluginObject;
// Utilities -------------------------------------------------------------------
// Converts the given PP_Var to an NPVariant, returning true on success.
// False means that the given variant is invalid. In this case, the result
// NPVariant will be set to a void one.
//
// The contents of the PP_Var will be copied unless the PP_Var corresponds to
// an object.
bool PPVarToNPVariant(PP_Var var, NPVariant* result);
// Returns a PP_Var that corresponds to the given NPVariant. The contents of
// the NPVariant will be copied unless the NPVariant corresponds to an
// object. This will handle all Variant types including POD, strings, and
// objects.
//
// The returned PP_Var will have a refcount of 1, this passing ownership of
// the reference to the caller. This is suitable for returning to a plugin.
WEBKIT_PLUGINS_EXPORT PP_Var NPVariantToPPVar(PluginInstance* instance,
const NPVariant* variant);
// Returns a NPIdentifier that corresponds to the given PP_Var. The contents
// of the PP_Var will be copied. Returns 0 if the given PP_Var is not a a
// string or integer type.
NPIdentifier PPVarToNPIdentifier(PP_Var var);
// Returns a PP_Var corresponding to the given identifier. In the case of
// a string identifier, the returned string will have a reference count of 1.
PP_Var NPIdentifierToPPVar(NPIdentifier id);
// Helper function to create a PP_Var of type object that contains the given
// NPObject for use byt he given module. Calling this function multiple times
// given the same module + NPObject results in the same PP_Var, assuming that
// there is still a PP_Var with a reference open to it from the previous
// call.
//
// The instance is necessary because we can have different instances pointing to
// the same NPObject, and we want to keep their refs separate.
//
// If no ObjectVar currently exists corresponding to the NPObject, one is
// created associated with the given module.
//
// Note: this could easily be changed to take a PP_Instance instead if that
// makes certain calls in the future easier. Currently all callers have a
// PluginInstance so that's what we use here.
WEBKIT_PLUGINS_EXPORT PP_Var NPObjectToPPVar(PluginInstance* instance,
NPObject* object);
// PPResultAndExceptionToNPResult ----------------------------------------------
// Convenience object for converting a PPAPI call that can throw an exception
// and optionally return a value, back to the NPAPI layer which expects a
// NPVariant as a result.
//
// Normal usage is that you will pass the result of exception() to the
// PPAPI function as the exception output parameter. Then you will either
// call SetResult with the result of the PPAPI call, or
// CheckExceptionForNoResult if the PPAPI call doesn't return a PP_Var.
//
// Both SetResult and CheckExceptionForNoResult will throw an exception to
// the JavaScript library if the plugin reported an exception. SetResult
// will additionally convert the result to an NPVariant and write it to the
// output parameter given in the constructor.
class PPResultAndExceptionToNPResult {
public:
// The object_var parameter is the object to associate any exception with.
// It may not be NULL.
//
// The np_result parameter is the NPAPI result output parameter. This may be
// NULL if there is no NPVariant result (like for HasProperty). If this is
// specified, you must call SetResult() to set it. If it is not, you must
// call CheckExceptionForNoResult to do the exception checking with no result
// conversion.
PPResultAndExceptionToNPResult(NPObject* object_var, NPVariant* np_result);
~PPResultAndExceptionToNPResult();
// Returns true if an exception has been set.
bool has_exception() const { return exception_.type != PP_VARTYPE_UNDEFINED; }
// Returns a pointer to the exception. You would pass this to the PPAPI
// function as the exception parameter. If it is set to non-void, this object
// will take ownership of destroying it.
PP_Var* exception() { return &exception_; }
// Returns true if everything succeeded with no exception. This is valid only
// after calling SetResult/CheckExceptionForNoResult.
bool success() const {
return success_;
}
// Call this with the return value of the PPAPI function. It will convert
// the result to the NPVariant output parameter and pass any exception on to
// the JS engine. It will update the success flag and return it.
bool SetResult(PP_Var result);
// Call this after calling a PPAPI function that could have set the
// exception. It will pass the exception on to the JS engine and update
// the success flag.
//
// The success flag will be returned.
bool CheckExceptionForNoResult();
// Call this to ignore any exception. This prevents the DCHECK from failing
// in the destructor.
void IgnoreException();
private:
// Throws the current exception to JS. The exception must be set.
void ThrowException();
NPObject* object_var_; // Non-owning ref (see constructor).
NPVariant* np_result_; // Output value, possibly NULL (see constructor).
PP_Var exception_; // Exception set by the PPAPI call. We own a ref to it.
bool success_; // See the success() function above.
bool checked_exception_; // SetResult/CheckExceptionForNoResult was called.
DISALLOW_COPY_AND_ASSIGN(PPResultAndExceptionToNPResult);
};
// PPVarArrayFromNPVariantArray ------------------------------------------------
// Converts an array of NPVariants to an array of PP_Var, and scopes the
// ownership of the PP_Var. This is used when converting argument lists from
// WebKit to the plugin.
class PPVarArrayFromNPVariantArray {
public:
PPVarArrayFromNPVariantArray(PluginInstance* instance,
size_t size,
const NPVariant* variants);
~PPVarArrayFromNPVariantArray();
PP_Var* array() { return array_.get(); }
private:
size_t size_;
scoped_ptr<PP_Var[]> array_;
DISALLOW_COPY_AND_ASSIGN(PPVarArrayFromNPVariantArray);
};
// PPVarFromNPObject -----------------------------------------------------------
// Converts an NPObject tp PP_Var, and scopes the ownership of the PP_Var. This
// is used when converting 'this' pointer from WebKit to the plugin.
class PPVarFromNPObject {
public:
PPVarFromNPObject(PluginInstance* instance, NPObject* object);
~PPVarFromNPObject();
PP_Var var() const { return var_; }
private:
const PP_Var var_;
DISALLOW_COPY_AND_ASSIGN(PPVarFromNPObject);
};
// NPObjectAccessorWithIdentifier ----------------------------------------------
// Helper class for our NPObject wrapper. This converts a call from WebKit
// where it gives us an NPObject and an NPIdentifier to an easily-accessible
// ObjectVar (corresponding to the NPObject) and PP_Var (corresponding to the
// NPIdentifier).
//
// If the NPObject or identifier is invalid, we'll set is_valid() to false.
// The caller should check is_valid() before doing anything with the class.
//
// JS can't have integer functions, so when dealing with these, we don't want
// to allow integer identifiers. The calling code can decode if it wants to
// allow integer identifiers (like for property access) or prohibit them
// (like for method calling) by setting |allow_integer_identifier|. If this
// is false and the identifier is an integer, we'll set is_valid() to false.
//
// Getting an integer identifier in this case should be impossible. V8
// shouldn't be allowing this, and the Pepper Var calls from the plugin are
// supposed to error out before calling into V8 (which will then call us back).
// Aside from an egregious error, the only time this could happen is an NPAPI
// plugin calling us.
class NPObjectAccessorWithIdentifier {
public:
NPObjectAccessorWithIdentifier(NPObject* object,
NPIdentifier identifier,
bool allow_integer_identifier);
~NPObjectAccessorWithIdentifier();
// Returns true if both the object and identifier are valid.
bool is_valid() const {
return object_ && identifier_.type != PP_VARTYPE_UNDEFINED;
}
PluginObject* object() { return object_; }
PP_Var identifier() const { return identifier_; }
private:
PluginObject* object_;
PP_Var identifier_;
DISALLOW_COPY_AND_ASSIGN(NPObjectAccessorWithIdentifier);
};
// TryCatch --------------------------------------------------------------------
// Instantiate this object on the stack to catch V8 exceptions and pass them
// to an optional out parameter supplied by the plugin.
class TryCatch {
public:
// The given exception may be NULL if the consumer isn't interested in
// catching exceptions. If non-NULL, the given var will be updated if any
// exception is thrown (so it must outlive the TryCatch object).
TryCatch(PP_Var* exception);
~TryCatch();
// Returns true is an exception has been thrown. This can be true immediately
// after construction if the var passed to the constructor is non-void.
bool has_exception() const { return has_exception_; }
// Sets the given exception. If an exception has been previously set, this
// function will do nothing (normally you want only the first exception).
void SetException(const char* message);
private:
static void Catch(void* self, const char* message);
// True if an exception has been thrown. Since the exception itself may be
// NULL if the plugin isn't interested in getting the exception, this will
// always indicate if SetException has been called, regardless of whether
// the exception itself has been stored.
bool has_exception_;
// May be null if the consumer isn't interesting in catching exceptions.
PP_Var* exception_;
};
} // namespace ppapi
} // namespace webkit
#endif // WEBKIT_PLUGINS_PPAPI_NPAPI_GLUE_H_
|