| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "content/renderer/pepper/plugin_object.h" | 5 #include "content/renderer/pepper/plugin_object.h" |
| 6 | 6 |
| 7 #include "base/logging.h" | 7 #include "base/logging.h" |
| 8 #include "base/memory/ref_counted.h" | 8 #include "base/memory/ref_counted.h" |
| 9 #include "base/memory/scoped_ptr.h" | 9 #include "base/memory/scoped_ptr.h" |
| 10 #include "base/strings/string_number_conversions.h" | 10 #include "base/strings/string_number_conversions.h" |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 42 } | 42 } |
| 43 | 43 |
| 44 void WrapperClass_Deallocate(NPObject* np_object) { | 44 void WrapperClass_Deallocate(NPObject* np_object) { |
| 45 PluginObject* plugin_object = PluginObject::FromNPObject(np_object); | 45 PluginObject* plugin_object = PluginObject::FromNPObject(np_object); |
| 46 if (!plugin_object) | 46 if (!plugin_object) |
| 47 return; | 47 return; |
| 48 plugin_object->ppp_class()->Deallocate(plugin_object->ppp_class_data()); | 48 plugin_object->ppp_class()->Deallocate(plugin_object->ppp_class_data()); |
| 49 delete plugin_object; | 49 delete plugin_object; |
| 50 } | 50 } |
| 51 | 51 |
| 52 void WrapperClass_Invalidate(NPObject* object) { | 52 void WrapperClass_Invalidate(NPObject* object) {} |
| 53 } | |
| 54 | 53 |
| 55 bool WrapperClass_HasMethod(NPObject* object, NPIdentifier method_name) { | 54 bool WrapperClass_HasMethod(NPObject* object, NPIdentifier method_name) { |
| 56 NPObjectAccessorWithIdentifier accessor(object, method_name, false); | 55 NPObjectAccessorWithIdentifier accessor(object, method_name, false); |
| 57 if (!accessor.is_valid()) | 56 if (!accessor.is_valid()) |
| 58 return false; | 57 return false; |
| 59 | 58 |
| 60 PPResultAndExceptionToNPResult result_converter( | 59 PPResultAndExceptionToNPResult result_converter( |
| 61 accessor.object()->GetNPObject(), NULL); | 60 accessor.object()->GetNPObject(), NULL); |
| 62 bool rv = accessor.object()->ppp_class()->HasMethod( | 61 bool rv = accessor.object()->ppp_class()->HasMethod( |
| 63 accessor.object()->ppp_class_data(), accessor.identifier(), | 62 accessor.object()->ppp_class_data(), |
| 63 accessor.identifier(), |
| 64 result_converter.exception()); | 64 result_converter.exception()); |
| 65 result_converter.CheckExceptionForNoResult(); | 65 result_converter.CheckExceptionForNoResult(); |
| 66 return rv; | 66 return rv; |
| 67 } | 67 } |
| 68 | 68 |
| 69 bool WrapperClass_Invoke(NPObject* object, NPIdentifier method_name, | 69 bool WrapperClass_Invoke(NPObject* object, |
| 70 const NPVariant* argv, uint32_t argc, | 70 NPIdentifier method_name, |
| 71 const NPVariant* argv, |
| 72 uint32_t argc, |
| 71 NPVariant* result) { | 73 NPVariant* result) { |
| 72 NPObjectAccessorWithIdentifier accessor(object, method_name, false); | 74 NPObjectAccessorWithIdentifier accessor(object, method_name, false); |
| 73 if (!accessor.is_valid()) | 75 if (!accessor.is_valid()) |
| 74 return false; | 76 return false; |
| 75 | 77 |
| 76 PPResultAndExceptionToNPResult result_converter( | 78 PPResultAndExceptionToNPResult result_converter( |
| 77 accessor.object()->GetNPObject(), result); | 79 accessor.object()->GetNPObject(), result); |
| 78 PPVarArrayFromNPVariantArray args(accessor.object()->instance(), | 80 PPVarArrayFromNPVariantArray args(accessor.object()->instance(), argc, argv); |
| 79 argc, argv); | |
| 80 | 81 |
| 81 // For the OOP plugin case we need to grab a reference on the plugin module | 82 // For the OOP plugin case we need to grab a reference on the plugin module |
| 82 // object to ensure that it is not destroyed courtsey an incoming | 83 // object to ensure that it is not destroyed courtsey an incoming |
| 83 // ExecuteScript call which destroys the plugin module and in turn the | 84 // ExecuteScript call which destroys the plugin module and in turn the |
| 84 // dispatcher. | 85 // dispatcher. |
| 85 scoped_refptr<PluginModule> ref(accessor.object()->instance()->module()); | 86 scoped_refptr<PluginModule> ref(accessor.object()->instance()->module()); |
| 86 | 87 |
| 87 return result_converter.SetResult(accessor.object()->ppp_class()->Call( | 88 return result_converter.SetResult( |
| 88 accessor.object()->ppp_class_data(), accessor.identifier(), | 89 accessor.object()->ppp_class()->Call(accessor.object()->ppp_class_data(), |
| 89 argc, args.array(), result_converter.exception())); | 90 accessor.identifier(), |
| 91 argc, |
| 92 args.array(), |
| 93 result_converter.exception())); |
| 90 } | 94 } |
| 91 | 95 |
| 92 bool WrapperClass_InvokeDefault(NPObject* np_object, const NPVariant* argv, | 96 bool WrapperClass_InvokeDefault(NPObject* np_object, |
| 93 uint32_t argc, NPVariant* result) { | 97 const NPVariant* argv, |
| 98 uint32_t argc, |
| 99 NPVariant* result) { |
| 94 PluginObject* obj = PluginObject::FromNPObject(np_object); | 100 PluginObject* obj = PluginObject::FromNPObject(np_object); |
| 95 if (!obj) | 101 if (!obj) |
| 96 return false; | 102 return false; |
| 97 | 103 |
| 98 PPVarArrayFromNPVariantArray args(obj->instance(), argc, argv); | 104 PPVarArrayFromNPVariantArray args(obj->instance(), argc, argv); |
| 99 PPResultAndExceptionToNPResult result_converter(obj->GetNPObject(), result); | 105 PPResultAndExceptionToNPResult result_converter(obj->GetNPObject(), result); |
| 100 | 106 |
| 101 // For the OOP plugin case we need to grab a reference on the plugin module | 107 // For the OOP plugin case we need to grab a reference on the plugin module |
| 102 // object to ensure that it is not destroyed courtsey an incoming | 108 // object to ensure that it is not destroyed courtsey an incoming |
| 103 // ExecuteScript call which destroys the plugin module and in turn the | 109 // ExecuteScript call which destroys the plugin module and in turn the |
| 104 // dispatcher. | 110 // dispatcher. |
| 105 scoped_refptr<PluginModule> ref(obj->instance()->module()); | 111 scoped_refptr<PluginModule> ref(obj->instance()->module()); |
| 106 | 112 |
| 107 result_converter.SetResult(obj->ppp_class()->Call( | 113 result_converter.SetResult( |
| 108 obj->ppp_class_data(), PP_MakeUndefined(), argc, args.array(), | 114 obj->ppp_class()->Call(obj->ppp_class_data(), |
| 109 result_converter.exception())); | 115 PP_MakeUndefined(), |
| 116 argc, |
| 117 args.array(), |
| 118 result_converter.exception())); |
| 110 return result_converter.success(); | 119 return result_converter.success(); |
| 111 } | 120 } |
| 112 | 121 |
| 113 bool WrapperClass_HasProperty(NPObject* object, NPIdentifier property_name) { | 122 bool WrapperClass_HasProperty(NPObject* object, NPIdentifier property_name) { |
| 114 NPObjectAccessorWithIdentifier accessor(object, property_name, true); | 123 NPObjectAccessorWithIdentifier accessor(object, property_name, true); |
| 115 if (!accessor.is_valid()) | 124 if (!accessor.is_valid()) |
| 116 return false; | 125 return false; |
| 117 | 126 |
| 118 PPResultAndExceptionToNPResult result_converter( | 127 PPResultAndExceptionToNPResult result_converter( |
| 119 accessor.object()->GetNPObject(), NULL); | 128 accessor.object()->GetNPObject(), NULL); |
| 120 bool rv = accessor.object()->ppp_class()->HasProperty( | 129 bool rv = accessor.object()->ppp_class()->HasProperty( |
| 121 accessor.object()->ppp_class_data(), accessor.identifier(), | 130 accessor.object()->ppp_class_data(), |
| 131 accessor.identifier(), |
| 122 result_converter.exception()); | 132 result_converter.exception()); |
| 123 result_converter.CheckExceptionForNoResult(); | 133 result_converter.CheckExceptionForNoResult(); |
| 124 return rv; | 134 return rv; |
| 125 } | 135 } |
| 126 | 136 |
| 127 bool WrapperClass_GetProperty(NPObject* object, NPIdentifier property_name, | 137 bool WrapperClass_GetProperty(NPObject* object, |
| 138 NPIdentifier property_name, |
| 128 NPVariant* result) { | 139 NPVariant* result) { |
| 129 NPObjectAccessorWithIdentifier accessor(object, property_name, true); | 140 NPObjectAccessorWithIdentifier accessor(object, property_name, true); |
| 130 if (!accessor.is_valid()) | 141 if (!accessor.is_valid()) |
| 131 return false; | 142 return false; |
| 132 | 143 |
| 133 PPResultAndExceptionToNPResult result_converter( | 144 PPResultAndExceptionToNPResult result_converter( |
| 134 accessor.object()->GetNPObject(), result); | 145 accessor.object()->GetNPObject(), result); |
| 135 return result_converter.SetResult(accessor.object()->ppp_class()->GetProperty( | 146 return result_converter.SetResult(accessor.object()->ppp_class()->GetProperty( |
| 136 accessor.object()->ppp_class_data(), accessor.identifier(), | 147 accessor.object()->ppp_class_data(), |
| 148 accessor.identifier(), |
| 137 result_converter.exception())); | 149 result_converter.exception())); |
| 138 } | 150 } |
| 139 | 151 |
| 140 bool WrapperClass_SetProperty(NPObject* object, NPIdentifier property_name, | 152 bool WrapperClass_SetProperty(NPObject* object, |
| 153 NPIdentifier property_name, |
| 141 const NPVariant* value) { | 154 const NPVariant* value) { |
| 142 NPObjectAccessorWithIdentifier accessor(object, property_name, true); | 155 NPObjectAccessorWithIdentifier accessor(object, property_name, true); |
| 143 if (!accessor.is_valid()) | 156 if (!accessor.is_valid()) |
| 144 return false; | 157 return false; |
| 145 | 158 |
| 146 PPResultAndExceptionToNPResult result_converter( | 159 PPResultAndExceptionToNPResult result_converter( |
| 147 accessor.object()->GetNPObject(), NULL); | 160 accessor.object()->GetNPObject(), NULL); |
| 148 PP_Var value_var = NPVariantToPPVar(accessor.object()->instance(), value); | 161 PP_Var value_var = NPVariantToPPVar(accessor.object()->instance(), value); |
| 149 accessor.object()->ppp_class()->SetProperty( | 162 accessor.object()->ppp_class()->SetProperty( |
| 150 accessor.object()->ppp_class_data(), accessor.identifier(), value_var, | 163 accessor.object()->ppp_class_data(), |
| 164 accessor.identifier(), |
| 165 value_var, |
| 151 result_converter.exception()); | 166 result_converter.exception()); |
| 152 PpapiGlobals::Get()->GetVarTracker()->ReleaseVar(value_var); | 167 PpapiGlobals::Get()->GetVarTracker()->ReleaseVar(value_var); |
| 153 return result_converter.CheckExceptionForNoResult(); | 168 return result_converter.CheckExceptionForNoResult(); |
| 154 } | 169 } |
| 155 | 170 |
| 156 bool WrapperClass_RemoveProperty(NPObject* object, NPIdentifier property_name) { | 171 bool WrapperClass_RemoveProperty(NPObject* object, NPIdentifier property_name) { |
| 157 NPObjectAccessorWithIdentifier accessor(object, property_name, true); | 172 NPObjectAccessorWithIdentifier accessor(object, property_name, true); |
| 158 if (!accessor.is_valid()) | 173 if (!accessor.is_valid()) |
| 159 return false; | 174 return false; |
| 160 | 175 |
| 161 PPResultAndExceptionToNPResult result_converter( | 176 PPResultAndExceptionToNPResult result_converter( |
| 162 accessor.object()->GetNPObject(), NULL); | 177 accessor.object()->GetNPObject(), NULL); |
| 163 accessor.object()->ppp_class()->RemoveProperty( | 178 accessor.object()->ppp_class()->RemoveProperty( |
| 164 accessor.object()->ppp_class_data(), accessor.identifier(), | 179 accessor.object()->ppp_class_data(), |
| 180 accessor.identifier(), |
| 165 result_converter.exception()); | 181 result_converter.exception()); |
| 166 return result_converter.CheckExceptionForNoResult(); | 182 return result_converter.CheckExceptionForNoResult(); |
| 167 } | 183 } |
| 168 | 184 |
| 169 bool WrapperClass_Enumerate(NPObject* object, NPIdentifier** values, | 185 bool WrapperClass_Enumerate(NPObject* object, |
| 186 NPIdentifier** values, |
| 170 uint32_t* count) { | 187 uint32_t* count) { |
| 171 *values = NULL; | 188 *values = NULL; |
| 172 *count = 0; | 189 *count = 0; |
| 173 PluginObject* obj = PluginObject::FromNPObject(object); | 190 PluginObject* obj = PluginObject::FromNPObject(object); |
| 174 if (!obj) | 191 if (!obj) |
| 175 return false; | 192 return false; |
| 176 | 193 |
| 177 uint32_t property_count = 0; | 194 uint32_t property_count = 0; |
| 178 PP_Var* properties = NULL; // Must be freed! | 195 PP_Var* properties = NULL; // Must be freed! |
| 179 PPResultAndExceptionToNPResult result_converter(obj->GetNPObject(), NULL); | 196 PPResultAndExceptionToNPResult result_converter(obj->GetNPObject(), NULL); |
| 180 obj->ppp_class()->GetAllPropertyNames(obj->ppp_class_data(), | 197 obj->ppp_class()->GetAllPropertyNames(obj->ppp_class_data(), |
| 181 &property_count, &properties, | 198 &property_count, |
| 199 &properties, |
| 182 result_converter.exception()); | 200 result_converter.exception()); |
| 183 | 201 |
| 184 // Convert the array of PP_Var to an array of NPIdentifiers. If any | 202 // Convert the array of PP_Var to an array of NPIdentifiers. If any |
| 185 // conversions fail, we will set the exception. | 203 // conversions fail, we will set the exception. |
| 186 if (!result_converter.has_exception()) { | 204 if (!result_converter.has_exception()) { |
| 187 if (property_count > 0) { | 205 if (property_count > 0) { |
| 188 *values = static_cast<NPIdentifier*>( | 206 *values = static_cast<NPIdentifier*>( |
| 189 calloc(property_count, sizeof(NPIdentifier))); | 207 calloc(property_count, sizeof(NPIdentifier))); |
| 190 *count = 0; // Will be the number of items successfully converted. | 208 *count = 0; // Will be the number of items successfully converted. |
| 191 for (uint32_t i = 0; i < property_count; ++i) { | 209 for (uint32_t i = 0; i < property_count; ++i) { |
| (...skipping 22 matching lines...) Expand all Loading... |
| 214 | 232 |
| 215 // Release the PP_Var that the plugin allocated. On success, they will all | 233 // Release the PP_Var that the plugin allocated. On success, they will all |
| 216 // be converted to NPVariants, and on failure, we want them to just go away. | 234 // be converted to NPVariants, and on failure, we want them to just go away. |
| 217 ppapi::VarTracker* var_tracker = PpapiGlobals::Get()->GetVarTracker(); | 235 ppapi::VarTracker* var_tracker = PpapiGlobals::Get()->GetVarTracker(); |
| 218 for (uint32_t i = 0; i < property_count; ++i) | 236 for (uint32_t i = 0; i < property_count; ++i) |
| 219 var_tracker->ReleaseVar(properties[i]); | 237 var_tracker->ReleaseVar(properties[i]); |
| 220 free(properties); | 238 free(properties); |
| 221 return result_converter.success(); | 239 return result_converter.success(); |
| 222 } | 240 } |
| 223 | 241 |
| 224 bool WrapperClass_Construct(NPObject* object, const NPVariant* argv, | 242 bool WrapperClass_Construct(NPObject* object, |
| 225 uint32_t argc, NPVariant* result) { | 243 const NPVariant* argv, |
| 244 uint32_t argc, |
| 245 NPVariant* result) { |
| 226 PluginObject* obj = PluginObject::FromNPObject(object); | 246 PluginObject* obj = PluginObject::FromNPObject(object); |
| 227 if (!obj) | 247 if (!obj) |
| 228 return false; | 248 return false; |
| 229 | 249 |
| 230 PPVarArrayFromNPVariantArray args(obj->instance(), argc, argv); | 250 PPVarArrayFromNPVariantArray args(obj->instance(), argc, argv); |
| 231 PPResultAndExceptionToNPResult result_converter(obj->GetNPObject(), result); | 251 PPResultAndExceptionToNPResult result_converter(obj->GetNPObject(), result); |
| 232 return result_converter.SetResult(obj->ppp_class()->Construct( | 252 return result_converter.SetResult(obj->ppp_class()->Construct( |
| 233 obj->ppp_class_data(), argc, args.array(), | 253 obj->ppp_class_data(), argc, args.array(), result_converter.exception())); |
| 234 result_converter.exception())); | |
| 235 } | 254 } |
| 236 | 255 |
| 237 const NPClass wrapper_class = { | 256 const NPClass wrapper_class = { |
| 238 NP_CLASS_STRUCT_VERSION, | 257 NP_CLASS_STRUCT_VERSION, WrapperClass_Allocate, |
| 239 WrapperClass_Allocate, | 258 WrapperClass_Deallocate, WrapperClass_Invalidate, |
| 240 WrapperClass_Deallocate, | 259 WrapperClass_HasMethod, WrapperClass_Invoke, |
| 241 WrapperClass_Invalidate, | 260 WrapperClass_InvokeDefault, WrapperClass_HasProperty, |
| 242 WrapperClass_HasMethod, | 261 WrapperClass_GetProperty, WrapperClass_SetProperty, |
| 243 WrapperClass_Invoke, | 262 WrapperClass_RemoveProperty, WrapperClass_Enumerate, |
| 244 WrapperClass_InvokeDefault, | 263 WrapperClass_Construct}; |
| 245 WrapperClass_HasProperty, | |
| 246 WrapperClass_GetProperty, | |
| 247 WrapperClass_SetProperty, | |
| 248 WrapperClass_RemoveProperty, | |
| 249 WrapperClass_Enumerate, | |
| 250 WrapperClass_Construct | |
| 251 }; | |
| 252 | 264 |
| 253 } // namespace | 265 } // namespace |
| 254 | 266 |
| 255 // PluginObject ---------------------------------------------------------------- | 267 // PluginObject ---------------------------------------------------------------- |
| 256 | 268 |
| 257 struct PluginObject::NPObjectWrapper : public NPObject { | 269 struct PluginObject::NPObjectWrapper : public NPObject { |
| 258 // Points to the var object that owns this wrapper. This value may be NULL | 270 // Points to the var object that owns this wrapper. This value may be NULL |
| 259 // if there is no var owning this wrapper. This can happen if the plugin | 271 // if there is no var owning this wrapper. This can happen if the plugin |
| 260 // releases all references to the var, but a reference to the underlying | 272 // releases all references to the var, but a reference to the underlying |
| 261 // NPObject is still held by script on the page. | 273 // NPObject is still held by script on the page. |
| (...skipping 24 matching lines...) Expand all Loading... |
| 286 object_wrapper_->obj = NULL; | 298 object_wrapper_->obj = NULL; |
| 287 instance_->RemovePluginObject(this); | 299 instance_->RemovePluginObject(this); |
| 288 } | 300 } |
| 289 | 301 |
| 290 PP_Var PluginObject::Create(PepperPluginInstanceImpl* instance, | 302 PP_Var PluginObject::Create(PepperPluginInstanceImpl* instance, |
| 291 const PPP_Class_Deprecated* ppp_class, | 303 const PPP_Class_Deprecated* ppp_class, |
| 292 void* ppp_class_data) { | 304 void* ppp_class_data) { |
| 293 // This will internally end up calling our AllocateObjectWrapper via the | 305 // This will internally end up calling our AllocateObjectWrapper via the |
| 294 // WrapperClass_Allocated function which will have created an object wrapper | 306 // WrapperClass_Allocated function which will have created an object wrapper |
| 295 // appropriate for this class (derived from NPObject). | 307 // appropriate for this class (derived from NPObject). |
| 296 NPObjectWrapper* wrapper = static_cast<NPObjectWrapper*>( | 308 NPObjectWrapper* wrapper = |
| 297 WebBindings::createObject(instance->instanceNPP(), | 309 static_cast<NPObjectWrapper*>(WebBindings::createObject( |
| 298 const_cast<NPClass*>(&wrapper_class))); | 310 instance->instanceNPP(), const_cast<NPClass*>(&wrapper_class))); |
| 299 | 311 |
| 300 // This object will register itself both with the NPObject and with the | 312 // This object will register itself both with the NPObject and with the |
| 301 // PluginModule. The NPObject will normally handle its lifetime, and it | 313 // PluginModule. The NPObject will normally handle its lifetime, and it |
| 302 // will get deleted in the destroy method. It may also get deleted when the | 314 // will get deleted in the destroy method. It may also get deleted when the |
| 303 // plugin module is deallocated. | 315 // plugin module is deallocated. |
| 304 new PluginObject(instance, wrapper, ppp_class, ppp_class_data); | 316 new PluginObject(instance, wrapper, ppp_class, ppp_class_data); |
| 305 | 317 |
| 306 // We can just use a normal ObjectVar to refer to this object from the | 318 // We can just use a normal ObjectVar to refer to this object from the |
| 307 // plugin. It will hold a ref to the underlying NPObject which will in turn | 319 // plugin. It will hold a ref to the underlying NPObject which will in turn |
| 308 // hold our pluginObject. | 320 // hold our pluginObject. |
| 309 PP_Var obj_var(NPObjectToPPVar(instance, wrapper)); | 321 PP_Var obj_var(NPObjectToPPVar(instance, wrapper)); |
| 310 | 322 |
| 311 // Note that the ObjectVar constructor incremented the reference count, and so | 323 // Note that the ObjectVar constructor incremented the reference count, and so |
| 312 // did WebBindings::createObject above. Now that the PP_Var has taken | 324 // did WebBindings::createObject above. Now that the PP_Var has taken |
| 313 // ownership, we need to release to balance out the createObject reference | 325 // ownership, we need to release to balance out the createObject reference |
| 314 // count bump. | 326 // count bump. |
| 315 WebBindings::releaseObject(wrapper); | 327 WebBindings::releaseObject(wrapper); |
| 316 return obj_var; | 328 return obj_var; |
| 317 } | 329 } |
| 318 | 330 |
| 319 NPObject* PluginObject::GetNPObject() const { | 331 NPObject* PluginObject::GetNPObject() const { return object_wrapper_; } |
| 320 return object_wrapper_; | |
| 321 } | |
| 322 | 332 |
| 323 // static | 333 // static |
| 324 bool PluginObject::IsInstanceOf(NPObject* np_object, | 334 bool PluginObject::IsInstanceOf(NPObject* np_object, |
| 325 const PPP_Class_Deprecated* ppp_class, | 335 const PPP_Class_Deprecated* ppp_class, |
| 326 void** ppp_class_data) { | 336 void** ppp_class_data) { |
| 327 // Validate that this object is implemented by our wrapper class before | 337 // Validate that this object is implemented by our wrapper class before |
| 328 // trying to get the PluginObject. | 338 // trying to get the PluginObject. |
| 329 if (np_object->_class != &wrapper_class) | 339 if (np_object->_class != &wrapper_class) |
| 330 return false; | 340 return false; |
| 331 | 341 |
| (...skipping 14 matching lines...) Expand all Loading... |
| 346 } | 356 } |
| 347 | 357 |
| 348 // static | 358 // static |
| 349 NPObject* PluginObject::AllocateObjectWrapper() { | 359 NPObject* PluginObject::AllocateObjectWrapper() { |
| 350 NPObjectWrapper* wrapper = new NPObjectWrapper; | 360 NPObjectWrapper* wrapper = new NPObjectWrapper; |
| 351 memset(wrapper, 0, sizeof(NPObjectWrapper)); | 361 memset(wrapper, 0, sizeof(NPObjectWrapper)); |
| 352 return wrapper; | 362 return wrapper; |
| 353 } | 363 } |
| 354 | 364 |
| 355 } // namespace content | 365 } // namespace content |
| 356 | |
| OLD | NEW |