1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/dom/plugins/ipc/PluginScriptableObjectParent.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,1251 @@ 1.4 +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- 1.5 + * vim: sw=2 ts=2 et : 1.6 + * This Source Code Form is subject to the terms of the Mozilla Public 1.7 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.8 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.9 + 1.10 +#include "PluginScriptableObjectParent.h" 1.11 + 1.12 +#include "mozilla/DebugOnly.h" 1.13 +#include "mozilla/plugins/PluginIdentifierParent.h" 1.14 +#include "mozilla/unused.h" 1.15 +#include "nsCxPusher.h" 1.16 +#include "nsNPAPIPlugin.h" 1.17 +#include "PluginScriptableObjectUtils.h" 1.18 + 1.19 +using namespace mozilla::plugins; 1.20 +using namespace mozilla::plugins::parent; 1.21 + 1.22 +namespace { 1.23 + 1.24 +inline void 1.25 +ReleaseVariant(NPVariant& aVariant, 1.26 + PluginInstanceParent* aInstance) 1.27 +{ 1.28 + const NPNetscapeFuncs* npn = GetNetscapeFuncs(aInstance); 1.29 + if (npn) { 1.30 + npn->releasevariantvalue(&aVariant); 1.31 + } 1.32 +} 1.33 + 1.34 +} // anonymous namespace 1.35 + 1.36 +// static 1.37 +NPObject* 1.38 +PluginScriptableObjectParent::ScriptableAllocate(NPP aInstance, 1.39 + NPClass* aClass) 1.40 +{ 1.41 + if (aClass != GetClass()) { 1.42 + NS_ERROR("Huh?! Wrong class!"); 1.43 + return nullptr; 1.44 + } 1.45 + 1.46 + return new ParentNPObject(); 1.47 +} 1.48 + 1.49 +// static 1.50 +void 1.51 +PluginScriptableObjectParent::ScriptableInvalidate(NPObject* aObject) 1.52 +{ 1.53 + if (aObject->_class != GetClass()) { 1.54 + NS_ERROR("Don't know what kind of object this is!"); 1.55 + return; 1.56 + } 1.57 + 1.58 + ParentNPObject* object = reinterpret_cast<ParentNPObject*>(aObject); 1.59 + if (object->invalidated) { 1.60 + // This can happen more than once, and is just fine. 1.61 + return; 1.62 + } 1.63 + 1.64 + object->invalidated = true; 1.65 + 1.66 + // |object->parent| may be null already if the instance has gone away. 1.67 + if (object->parent && !object->parent->CallInvalidate()) { 1.68 + NS_ERROR("Failed to send message!"); 1.69 + } 1.70 +} 1.71 + 1.72 +// static 1.73 +void 1.74 +PluginScriptableObjectParent::ScriptableDeallocate(NPObject* aObject) 1.75 +{ 1.76 + if (aObject->_class != GetClass()) { 1.77 + NS_ERROR("Don't know what kind of object this is!"); 1.78 + return; 1.79 + } 1.80 + 1.81 + ParentNPObject* object = reinterpret_cast<ParentNPObject*>(aObject); 1.82 + PluginScriptableObjectParent* actor = object->parent; 1.83 + if (actor) { 1.84 + NS_ASSERTION(actor->Type() == Proxy, "Bad type!"); 1.85 + actor->DropNPObject(); 1.86 + } 1.87 + 1.88 + delete object; 1.89 +} 1.90 + 1.91 +// static 1.92 +bool 1.93 +PluginScriptableObjectParent::ScriptableHasMethod(NPObject* aObject, 1.94 + NPIdentifier aName) 1.95 +{ 1.96 + if (aObject->_class != GetClass()) { 1.97 + NS_ERROR("Don't know what kind of object this is!"); 1.98 + return false; 1.99 + } 1.100 + 1.101 + ParentNPObject* object = reinterpret_cast<ParentNPObject*>(aObject); 1.102 + if (object->invalidated) { 1.103 + NS_WARNING("Calling method on an invalidated object!"); 1.104 + return false; 1.105 + } 1.106 + 1.107 + ProtectedActor<PluginScriptableObjectParent> actor(object->parent); 1.108 + if (!actor) { 1.109 + return false; 1.110 + } 1.111 + 1.112 + PluginIdentifierParent::StackIdentifier identifier(aObject, aName); 1.113 + if (!identifier) { 1.114 + return false; 1.115 + } 1.116 + 1.117 + NS_ASSERTION(actor->Type() == Proxy, "Bad type!"); 1.118 + 1.119 + bool result; 1.120 + if (!actor->CallHasMethod(identifier, &result)) { 1.121 + NS_WARNING("Failed to send message!"); 1.122 + return false; 1.123 + } 1.124 + 1.125 + return result; 1.126 +} 1.127 + 1.128 +// static 1.129 +bool 1.130 +PluginScriptableObjectParent::ScriptableInvoke(NPObject* aObject, 1.131 + NPIdentifier aName, 1.132 + const NPVariant* aArgs, 1.133 + uint32_t aArgCount, 1.134 + NPVariant* aResult) 1.135 +{ 1.136 + if (aObject->_class != GetClass()) { 1.137 + NS_ERROR("Don't know what kind of object this is!"); 1.138 + return false; 1.139 + } 1.140 + 1.141 + ParentNPObject* object = reinterpret_cast<ParentNPObject*>(aObject); 1.142 + if (object->invalidated) { 1.143 + NS_WARNING("Calling method on an invalidated object!"); 1.144 + return false; 1.145 + } 1.146 + 1.147 + ProtectedActor<PluginScriptableObjectParent> actor(object->parent); 1.148 + if (!actor) { 1.149 + return false; 1.150 + } 1.151 + 1.152 + PluginIdentifierParent::StackIdentifier identifier(aObject, aName); 1.153 + if (!identifier) { 1.154 + return false; 1.155 + } 1.156 + 1.157 + NS_ASSERTION(actor->Type() == Proxy, "Bad type!"); 1.158 + 1.159 + ProtectedVariantArray args(aArgs, aArgCount, actor->GetInstance()); 1.160 + if (!args.IsOk()) { 1.161 + NS_ERROR("Failed to convert arguments!"); 1.162 + return false; 1.163 + } 1.164 + 1.165 + Variant remoteResult; 1.166 + bool success; 1.167 + if (!actor->CallInvoke(identifier, args, &remoteResult, 1.168 + &success)) { 1.169 + NS_WARNING("Failed to send message!"); 1.170 + return false; 1.171 + } 1.172 + 1.173 + if (!success) { 1.174 + return false; 1.175 + } 1.176 + 1.177 + if (!ConvertToVariant(remoteResult, *aResult, actor->GetInstance())) { 1.178 + NS_WARNING("Failed to convert result!"); 1.179 + return false; 1.180 + } 1.181 + return true; 1.182 +} 1.183 + 1.184 +// static 1.185 +bool 1.186 +PluginScriptableObjectParent::ScriptableInvokeDefault(NPObject* aObject, 1.187 + const NPVariant* aArgs, 1.188 + uint32_t aArgCount, 1.189 + NPVariant* aResult) 1.190 +{ 1.191 + if (aObject->_class != GetClass()) { 1.192 + NS_ERROR("Don't know what kind of object this is!"); 1.193 + return false; 1.194 + } 1.195 + 1.196 + ParentNPObject* object = reinterpret_cast<ParentNPObject*>(aObject); 1.197 + if (object->invalidated) { 1.198 + NS_WARNING("Calling method on an invalidated object!"); 1.199 + return false; 1.200 + } 1.201 + 1.202 + ProtectedActor<PluginScriptableObjectParent> actor(object->parent); 1.203 + if (!actor) { 1.204 + return false; 1.205 + } 1.206 + 1.207 + NS_ASSERTION(actor->Type() == Proxy, "Bad type!"); 1.208 + 1.209 + ProtectedVariantArray args(aArgs, aArgCount, actor->GetInstance()); 1.210 + if (!args.IsOk()) { 1.211 + NS_ERROR("Failed to convert arguments!"); 1.212 + return false; 1.213 + } 1.214 + 1.215 + Variant remoteResult; 1.216 + bool success; 1.217 + if (!actor->CallInvokeDefault(args, &remoteResult, &success)) { 1.218 + NS_WARNING("Failed to send message!"); 1.219 + return false; 1.220 + } 1.221 + 1.222 + if (!success) { 1.223 + return false; 1.224 + } 1.225 + 1.226 + if (!ConvertToVariant(remoteResult, *aResult, actor->GetInstance())) { 1.227 + NS_WARNING("Failed to convert result!"); 1.228 + return false; 1.229 + } 1.230 + return true; 1.231 +} 1.232 + 1.233 +// static 1.234 +bool 1.235 +PluginScriptableObjectParent::ScriptableHasProperty(NPObject* aObject, 1.236 + NPIdentifier aName) 1.237 +{ 1.238 + if (aObject->_class != GetClass()) { 1.239 + NS_ERROR("Don't know what kind of object this is!"); 1.240 + return false; 1.241 + } 1.242 + 1.243 + ParentNPObject* object = reinterpret_cast<ParentNPObject*>(aObject); 1.244 + if (object->invalidated) { 1.245 + NS_WARNING("Calling method on an invalidated object!"); 1.246 + return false; 1.247 + } 1.248 + 1.249 + ProtectedActor<PluginScriptableObjectParent> actor(object->parent); 1.250 + if (!actor) { 1.251 + return false; 1.252 + } 1.253 + 1.254 + PluginIdentifierParent::StackIdentifier identifier(aObject, aName); 1.255 + if (!identifier) { 1.256 + return false; 1.257 + } 1.258 + 1.259 + NS_ASSERTION(actor->Type() == Proxy, "Bad type!"); 1.260 + 1.261 + bool result; 1.262 + if (!actor->CallHasProperty(identifier, &result)) { 1.263 + NS_WARNING("Failed to send message!"); 1.264 + return false; 1.265 + } 1.266 + 1.267 + return result; 1.268 +} 1.269 + 1.270 +// static 1.271 +bool 1.272 +PluginScriptableObjectParent::ScriptableGetProperty(NPObject* aObject, 1.273 + NPIdentifier aName, 1.274 + NPVariant* aResult) 1.275 +{ 1.276 + // See GetPropertyHelper below. 1.277 + NS_NOTREACHED("Shouldn't ever call this directly!"); 1.278 + return false; 1.279 +} 1.280 + 1.281 +// static 1.282 +bool 1.283 +PluginScriptableObjectParent::ScriptableSetProperty(NPObject* aObject, 1.284 + NPIdentifier aName, 1.285 + const NPVariant* aValue) 1.286 +{ 1.287 + if (aObject->_class != GetClass()) { 1.288 + NS_ERROR("Don't know what kind of object this is!"); 1.289 + return false; 1.290 + } 1.291 + 1.292 + ParentNPObject* object = reinterpret_cast<ParentNPObject*>(aObject); 1.293 + if (object->invalidated) { 1.294 + NS_WARNING("Calling method on an invalidated object!"); 1.295 + return false; 1.296 + } 1.297 + 1.298 + ProtectedActor<PluginScriptableObjectParent> actor(object->parent); 1.299 + if (!actor) { 1.300 + return false; 1.301 + } 1.302 + 1.303 + PluginIdentifierParent::StackIdentifier identifier(aObject, aName); 1.304 + if (!identifier) { 1.305 + return false; 1.306 + } 1.307 + 1.308 + NS_ASSERTION(actor->Type() == Proxy, "Bad type!"); 1.309 + 1.310 + ProtectedVariant value(*aValue, actor->GetInstance()); 1.311 + if (!value.IsOk()) { 1.312 + NS_WARNING("Failed to convert variant!"); 1.313 + return false; 1.314 + } 1.315 + 1.316 + bool success; 1.317 + if (!actor->CallSetProperty(identifier, value, &success)) { 1.318 + NS_WARNING("Failed to send message!"); 1.319 + return false; 1.320 + } 1.321 + 1.322 + return success; 1.323 +} 1.324 + 1.325 +// static 1.326 +bool 1.327 +PluginScriptableObjectParent::ScriptableRemoveProperty(NPObject* aObject, 1.328 + NPIdentifier aName) 1.329 +{ 1.330 + if (aObject->_class != GetClass()) { 1.331 + NS_ERROR("Don't know what kind of object this is!"); 1.332 + return false; 1.333 + } 1.334 + 1.335 + ParentNPObject* object = reinterpret_cast<ParentNPObject*>(aObject); 1.336 + if (object->invalidated) { 1.337 + NS_WARNING("Calling method on an invalidated object!"); 1.338 + return false; 1.339 + } 1.340 + 1.341 + ProtectedActor<PluginScriptableObjectParent> actor(object->parent); 1.342 + if (!actor) { 1.343 + return false; 1.344 + } 1.345 + 1.346 + PluginIdentifierParent::StackIdentifier identifier(aObject, aName); 1.347 + if (!identifier) { 1.348 + return false; 1.349 + } 1.350 + 1.351 + NS_ASSERTION(actor->Type() == Proxy, "Bad type!"); 1.352 + 1.353 + bool success; 1.354 + if (!actor->CallRemoveProperty(identifier, &success)) { 1.355 + NS_WARNING("Failed to send message!"); 1.356 + return false; 1.357 + } 1.358 + 1.359 + return success; 1.360 +} 1.361 + 1.362 +// static 1.363 +bool 1.364 +PluginScriptableObjectParent::ScriptableEnumerate(NPObject* aObject, 1.365 + NPIdentifier** aIdentifiers, 1.366 + uint32_t* aCount) 1.367 +{ 1.368 + if (aObject->_class != GetClass()) { 1.369 + NS_ERROR("Don't know what kind of object this is!"); 1.370 + return false; 1.371 + } 1.372 + 1.373 + ParentNPObject* object = reinterpret_cast<ParentNPObject*>(aObject); 1.374 + if (object->invalidated) { 1.375 + NS_WARNING("Calling method on an invalidated object!"); 1.376 + return false; 1.377 + } 1.378 + 1.379 + ProtectedActor<PluginScriptableObjectParent> actor(object->parent); 1.380 + if (!actor) { 1.381 + return false; 1.382 + } 1.383 + 1.384 + NS_ASSERTION(actor->Type() == Proxy, "Bad type!"); 1.385 + 1.386 + const NPNetscapeFuncs* npn = GetNetscapeFuncs(aObject); 1.387 + if (!npn) { 1.388 + NS_ERROR("No netscape funcs!"); 1.389 + return false; 1.390 + } 1.391 + 1.392 + AutoInfallibleTArray<PPluginIdentifierParent*, 10> identifiers; 1.393 + bool success; 1.394 + if (!actor->CallEnumerate(&identifiers, &success)) { 1.395 + NS_WARNING("Failed to send message!"); 1.396 + return false; 1.397 + } 1.398 + 1.399 + if (!success) { 1.400 + return false; 1.401 + } 1.402 + 1.403 + *aCount = identifiers.Length(); 1.404 + if (!*aCount) { 1.405 + *aIdentifiers = nullptr; 1.406 + return true; 1.407 + } 1.408 + 1.409 + *aIdentifiers = (NPIdentifier*)npn->memalloc(*aCount * sizeof(NPIdentifier)); 1.410 + if (!*aIdentifiers) { 1.411 + NS_ERROR("Out of memory!"); 1.412 + return false; 1.413 + } 1.414 + 1.415 + for (uint32_t index = 0; index < *aCount; index++) { 1.416 + PluginIdentifierParent* id = 1.417 + static_cast<PluginIdentifierParent*>(identifiers[index]); 1.418 + (*aIdentifiers)[index] = id->ToNPIdentifier(); 1.419 + } 1.420 + return true; 1.421 +} 1.422 + 1.423 +// static 1.424 +bool 1.425 +PluginScriptableObjectParent::ScriptableConstruct(NPObject* aObject, 1.426 + const NPVariant* aArgs, 1.427 + uint32_t aArgCount, 1.428 + NPVariant* aResult) 1.429 +{ 1.430 + if (aObject->_class != GetClass()) { 1.431 + NS_ERROR("Don't know what kind of object this is!"); 1.432 + return false; 1.433 + } 1.434 + 1.435 + ParentNPObject* object = reinterpret_cast<ParentNPObject*>(aObject); 1.436 + if (object->invalidated) { 1.437 + NS_WARNING("Calling method on an invalidated object!"); 1.438 + return false; 1.439 + } 1.440 + 1.441 + ProtectedActor<PluginScriptableObjectParent> actor(object->parent); 1.442 + if (!actor) { 1.443 + return false; 1.444 + } 1.445 + 1.446 + NS_ASSERTION(actor->Type() == Proxy, "Bad type!"); 1.447 + 1.448 + ProtectedVariantArray args(aArgs, aArgCount, actor->GetInstance()); 1.449 + if (!args.IsOk()) { 1.450 + NS_ERROR("Failed to convert arguments!"); 1.451 + return false; 1.452 + } 1.453 + 1.454 + Variant remoteResult; 1.455 + bool success; 1.456 + if (!actor->CallConstruct(args, &remoteResult, &success)) { 1.457 + NS_WARNING("Failed to send message!"); 1.458 + return false; 1.459 + } 1.460 + 1.461 + if (!success) { 1.462 + return false; 1.463 + } 1.464 + 1.465 + if (!ConvertToVariant(remoteResult, *aResult, actor->GetInstance())) { 1.466 + NS_WARNING("Failed to convert result!"); 1.467 + return false; 1.468 + } 1.469 + return true; 1.470 +} 1.471 + 1.472 +const NPClass PluginScriptableObjectParent::sNPClass = { 1.473 + NP_CLASS_STRUCT_VERSION, 1.474 + PluginScriptableObjectParent::ScriptableAllocate, 1.475 + PluginScriptableObjectParent::ScriptableDeallocate, 1.476 + PluginScriptableObjectParent::ScriptableInvalidate, 1.477 + PluginScriptableObjectParent::ScriptableHasMethod, 1.478 + PluginScriptableObjectParent::ScriptableInvoke, 1.479 + PluginScriptableObjectParent::ScriptableInvokeDefault, 1.480 + PluginScriptableObjectParent::ScriptableHasProperty, 1.481 + PluginScriptableObjectParent::ScriptableGetProperty, 1.482 + PluginScriptableObjectParent::ScriptableSetProperty, 1.483 + PluginScriptableObjectParent::ScriptableRemoveProperty, 1.484 + PluginScriptableObjectParent::ScriptableEnumerate, 1.485 + PluginScriptableObjectParent::ScriptableConstruct 1.486 +}; 1.487 + 1.488 +PluginScriptableObjectParent::PluginScriptableObjectParent( 1.489 + ScriptableObjectType aType) 1.490 +: mInstance(nullptr), 1.491 + mObject(nullptr), 1.492 + mProtectCount(0), 1.493 + mType(aType) 1.494 +{ 1.495 +} 1.496 + 1.497 +PluginScriptableObjectParent::~PluginScriptableObjectParent() 1.498 +{ 1.499 + if (mObject) { 1.500 + if (mObject->_class == GetClass()) { 1.501 + NS_ASSERTION(mType == Proxy, "Wrong type!"); 1.502 + static_cast<ParentNPObject*>(mObject)->parent = nullptr; 1.503 + } 1.504 + else { 1.505 + NS_ASSERTION(mType == LocalObject, "Wrong type!"); 1.506 + GetInstance()->GetNPNIface()->releaseobject(mObject); 1.507 + } 1.508 + } 1.509 +} 1.510 + 1.511 +void 1.512 +PluginScriptableObjectParent::InitializeProxy() 1.513 +{ 1.514 + NS_ASSERTION(mType == Proxy, "Bad type!"); 1.515 + NS_ASSERTION(!mObject, "Calling Initialize more than once!"); 1.516 + 1.517 + mInstance = static_cast<PluginInstanceParent*>(Manager()); 1.518 + NS_ASSERTION(mInstance, "Null manager?!"); 1.519 + 1.520 + NPObject* object = CreateProxyObject(); 1.521 + NS_ASSERTION(object, "Failed to create object!"); 1.522 + 1.523 + if (!mInstance->RegisterNPObjectForActor(object, this)) { 1.524 + NS_ERROR("Out of memory?"); 1.525 + } 1.526 + 1.527 + mObject = object; 1.528 +} 1.529 + 1.530 +void 1.531 +PluginScriptableObjectParent::InitializeLocal(NPObject* aObject) 1.532 +{ 1.533 + NS_ASSERTION(mType == LocalObject, "Bad type!"); 1.534 + NS_ASSERTION(!(mInstance && mObject), "Calling Initialize more than once!"); 1.535 + 1.536 + mInstance = static_cast<PluginInstanceParent*>(Manager()); 1.537 + NS_ASSERTION(mInstance, "Null manager?!"); 1.538 + 1.539 + mInstance->GetNPNIface()->retainobject(aObject); 1.540 + 1.541 + NS_ASSERTION(!mProtectCount, "Should be zero!"); 1.542 + mProtectCount++; 1.543 + 1.544 + if (!mInstance->RegisterNPObjectForActor(aObject, this)) { 1.545 + NS_ERROR("Out of memory?"); 1.546 + } 1.547 + 1.548 + mObject = aObject; 1.549 +} 1.550 + 1.551 +NPObject* 1.552 +PluginScriptableObjectParent::CreateProxyObject() 1.553 +{ 1.554 + NS_ASSERTION(mInstance, "Must have an instance!"); 1.555 + NS_ASSERTION(mType == Proxy, "Shouldn't call this for non-proxy object!"); 1.556 + 1.557 + const NPNetscapeFuncs* npn = GetNetscapeFuncs(mInstance); 1.558 + 1.559 + NPObject* npobject = npn->createobject(mInstance->GetNPP(), 1.560 + const_cast<NPClass*>(GetClass())); 1.561 + NS_ASSERTION(npobject, "Failed to create object?!"); 1.562 + NS_ASSERTION(npobject->_class == GetClass(), "Wrong kind of object!"); 1.563 + NS_ASSERTION(npobject->referenceCount == 1, "Some kind of live object!"); 1.564 + 1.565 + ParentNPObject* object = static_cast<ParentNPObject*>(npobject); 1.566 + NS_ASSERTION(!object->invalidated, "Bad object!"); 1.567 + NS_ASSERTION(!object->parent, "Bad object!"); 1.568 + 1.569 + // We don't want to have the actor own this object but rather let the object 1.570 + // own this actor. Set the reference count to 0 here so that when the object 1.571 + // dies we will send the destructor message to the child. 1.572 + object->referenceCount = 0; 1.573 + NS_LOG_RELEASE(object, 0, "BrowserNPObject"); 1.574 + 1.575 + object->parent = const_cast<PluginScriptableObjectParent*>(this); 1.576 + return object; 1.577 +} 1.578 + 1.579 +bool 1.580 +PluginScriptableObjectParent::ResurrectProxyObject() 1.581 +{ 1.582 + NS_ASSERTION(mInstance, "Must have an instance already!"); 1.583 + NS_ASSERTION(!mObject, "Should not have an object already!"); 1.584 + NS_ASSERTION(mType == Proxy, "Shouldn't call this for non-proxy object!"); 1.585 + 1.586 + InitializeProxy(); 1.587 + NS_ASSERTION(mObject, "Initialize failed!"); 1.588 + 1.589 + if (!SendProtect()) { 1.590 + NS_WARNING("Failed to send message!"); 1.591 + return false; 1.592 + } 1.593 + 1.594 + return true; 1.595 +} 1.596 + 1.597 +NPObject* 1.598 +PluginScriptableObjectParent::GetObject(bool aCanResurrect) 1.599 +{ 1.600 + if (!mObject && aCanResurrect && !ResurrectProxyObject()) { 1.601 + NS_ERROR("Null object!"); 1.602 + return nullptr; 1.603 + } 1.604 + return mObject; 1.605 +} 1.606 + 1.607 +void 1.608 +PluginScriptableObjectParent::Protect() 1.609 +{ 1.610 + NS_ASSERTION(mObject, "No object!"); 1.611 + NS_ASSERTION(mProtectCount >= 0, "Negative protect count?!"); 1.612 + 1.613 + if (mType == LocalObject) { 1.614 + ++mProtectCount; 1.615 + } 1.616 +} 1.617 + 1.618 +void 1.619 +PluginScriptableObjectParent::Unprotect() 1.620 +{ 1.621 + NS_ASSERTION(mObject, "No object!"); 1.622 + NS_ASSERTION(mProtectCount >= 0, "Negative protect count?!"); 1.623 + 1.624 + if (mType == LocalObject) { 1.625 + if (--mProtectCount == 0) { 1.626 + unused << PluginScriptableObjectParent::Send__delete__(this); 1.627 + } 1.628 + } 1.629 +} 1.630 + 1.631 +void 1.632 +PluginScriptableObjectParent::DropNPObject() 1.633 +{ 1.634 + NS_ASSERTION(mObject, "Invalidated object!"); 1.635 + NS_ASSERTION(mObject->_class == GetClass(), "Wrong type of object!"); 1.636 + NS_ASSERTION(mType == Proxy, "Shouldn't call this for non-proxy object!"); 1.637 + 1.638 + // We think we're about to be deleted, but we could be racing with the other 1.639 + // process. 1.640 + PluginInstanceParent* instance = GetInstance(); 1.641 + NS_ASSERTION(instance, "Must have an instance!"); 1.642 + 1.643 + instance->UnregisterNPObject(mObject); 1.644 + mObject = nullptr; 1.645 + 1.646 + unused << SendUnprotect(); 1.647 +} 1.648 + 1.649 +bool 1.650 +PluginScriptableObjectParent::AnswerHasMethod(PPluginIdentifierParent* aId, 1.651 + bool* aHasMethod) 1.652 +{ 1.653 + if (!mObject) { 1.654 + NS_WARNING("Calling AnswerHasMethod with an invalidated object!"); 1.655 + *aHasMethod = false; 1.656 + return true; 1.657 + } 1.658 + 1.659 + NS_ASSERTION(mObject->_class != GetClass(), "Bad object type!"); 1.660 + NS_ASSERTION(mType == LocalObject, "Bad type!"); 1.661 + 1.662 + PluginInstanceParent* instance = GetInstance(); 1.663 + if (!instance) { 1.664 + NS_ERROR("No instance?!"); 1.665 + *aHasMethod = false; 1.666 + return true; 1.667 + } 1.668 + 1.669 + const NPNetscapeFuncs* npn = GetNetscapeFuncs(instance); 1.670 + if (!npn) { 1.671 + NS_ERROR("No netscape funcs?!"); 1.672 + *aHasMethod = false; 1.673 + return true; 1.674 + } 1.675 + 1.676 + PluginIdentifierParent* id = static_cast<PluginIdentifierParent*>(aId); 1.677 + *aHasMethod = npn->hasmethod(instance->GetNPP(), mObject, id->ToNPIdentifier()); 1.678 + return true; 1.679 +} 1.680 + 1.681 +bool 1.682 +PluginScriptableObjectParent::AnswerInvoke(PPluginIdentifierParent* aId, 1.683 + const InfallibleTArray<Variant>& aArgs, 1.684 + Variant* aResult, 1.685 + bool* aSuccess) 1.686 +{ 1.687 + if (!mObject) { 1.688 + NS_WARNING("Calling AnswerInvoke with an invalidated object!"); 1.689 + *aResult = void_t(); 1.690 + *aSuccess = false; 1.691 + return true; 1.692 + } 1.693 + 1.694 + NS_ASSERTION(mObject->_class != GetClass(), "Bad object type!"); 1.695 + NS_ASSERTION(mType == LocalObject, "Bad type!"); 1.696 + 1.697 + PluginInstanceParent* instance = GetInstance(); 1.698 + if (!instance) { 1.699 + NS_ERROR("No instance?!"); 1.700 + *aResult = void_t(); 1.701 + *aSuccess = false; 1.702 + return true; 1.703 + } 1.704 + 1.705 + const NPNetscapeFuncs* npn = GetNetscapeFuncs(instance); 1.706 + if (!npn) { 1.707 + NS_ERROR("No netscape funcs?!"); 1.708 + *aResult = void_t(); 1.709 + *aSuccess = false; 1.710 + return true; 1.711 + } 1.712 + 1.713 + AutoFallibleTArray<NPVariant, 10> convertedArgs; 1.714 + uint32_t argCount = aArgs.Length(); 1.715 + 1.716 + if (!convertedArgs.SetLength(argCount)) { 1.717 + *aResult = void_t(); 1.718 + *aSuccess = false; 1.719 + return true; 1.720 + } 1.721 + 1.722 + for (uint32_t index = 0; index < argCount; index++) { 1.723 + if (!ConvertToVariant(aArgs[index], convertedArgs[index], instance)) { 1.724 + // Don't leak things we've already converted! 1.725 + while (index-- > 0) { 1.726 + ReleaseVariant(convertedArgs[index], instance); 1.727 + } 1.728 + *aResult = void_t(); 1.729 + *aSuccess = false; 1.730 + return true; 1.731 + } 1.732 + } 1.733 + 1.734 + PluginIdentifierParent* id = static_cast<PluginIdentifierParent*>(aId); 1.735 + NPVariant result; 1.736 + bool success = npn->invoke(instance->GetNPP(), mObject, id->ToNPIdentifier(), 1.737 + convertedArgs.Elements(), argCount, &result); 1.738 + 1.739 + for (uint32_t index = 0; index < argCount; index++) { 1.740 + ReleaseVariant(convertedArgs[index], instance); 1.741 + } 1.742 + 1.743 + if (!success) { 1.744 + *aResult = void_t(); 1.745 + *aSuccess = false; 1.746 + return true; 1.747 + } 1.748 + 1.749 + Variant convertedResult; 1.750 + success = ConvertToRemoteVariant(result, convertedResult, GetInstance()); 1.751 + 1.752 + DeferNPVariantLastRelease(npn, &result); 1.753 + 1.754 + if (!success) { 1.755 + *aResult = void_t(); 1.756 + *aSuccess = false; 1.757 + return true; 1.758 + } 1.759 + 1.760 + *aResult = convertedResult; 1.761 + *aSuccess = true; 1.762 + return true; 1.763 +} 1.764 + 1.765 +bool 1.766 +PluginScriptableObjectParent::AnswerInvokeDefault(const InfallibleTArray<Variant>& aArgs, 1.767 + Variant* aResult, 1.768 + bool* aSuccess) 1.769 +{ 1.770 + if (!mObject) { 1.771 + NS_WARNING("Calling AnswerInvoke with an invalidated object!"); 1.772 + *aResult = void_t(); 1.773 + *aSuccess = false; 1.774 + return true; 1.775 + } 1.776 + 1.777 + NS_ASSERTION(mObject->_class != GetClass(), "Bad object type!"); 1.778 + NS_ASSERTION(mType == LocalObject, "Bad type!"); 1.779 + 1.780 + PluginInstanceParent* instance = GetInstance(); 1.781 + if (!instance) { 1.782 + NS_ERROR("No instance?!"); 1.783 + *aResult = void_t(); 1.784 + *aSuccess = false; 1.785 + return true; 1.786 + } 1.787 + 1.788 + const NPNetscapeFuncs* npn = GetNetscapeFuncs(instance); 1.789 + if (!npn) { 1.790 + NS_ERROR("No netscape funcs?!"); 1.791 + *aResult = void_t(); 1.792 + *aSuccess = false; 1.793 + return true; 1.794 + } 1.795 + 1.796 + AutoFallibleTArray<NPVariant, 10> convertedArgs; 1.797 + uint32_t argCount = aArgs.Length(); 1.798 + 1.799 + if (!convertedArgs.SetLength(argCount)) { 1.800 + *aResult = void_t(); 1.801 + *aSuccess = false; 1.802 + return true; 1.803 + } 1.804 + 1.805 + for (uint32_t index = 0; index < argCount; index++) { 1.806 + if (!ConvertToVariant(aArgs[index], convertedArgs[index], instance)) { 1.807 + // Don't leak things we've already converted! 1.808 + while (index-- > 0) { 1.809 + ReleaseVariant(convertedArgs[index], instance); 1.810 + } 1.811 + *aResult = void_t(); 1.812 + *aSuccess = false; 1.813 + return true; 1.814 + } 1.815 + } 1.816 + 1.817 + NPVariant result; 1.818 + bool success = npn->invokeDefault(instance->GetNPP(), mObject, 1.819 + convertedArgs.Elements(), argCount, 1.820 + &result); 1.821 + 1.822 + for (uint32_t index = 0; index < argCount; index++) { 1.823 + ReleaseVariant(convertedArgs[index], instance); 1.824 + } 1.825 + 1.826 + if (!success) { 1.827 + *aResult = void_t(); 1.828 + *aSuccess = false; 1.829 + return true; 1.830 + } 1.831 + 1.832 + Variant convertedResult; 1.833 + success = ConvertToRemoteVariant(result, convertedResult, GetInstance()); 1.834 + 1.835 + DeferNPVariantLastRelease(npn, &result); 1.836 + 1.837 + if (!success) { 1.838 + *aResult = void_t(); 1.839 + *aSuccess = false; 1.840 + return true; 1.841 + } 1.842 + 1.843 + *aResult = convertedResult; 1.844 + *aSuccess = true; 1.845 + return true; 1.846 +} 1.847 + 1.848 +bool 1.849 +PluginScriptableObjectParent::AnswerHasProperty(PPluginIdentifierParent* aId, 1.850 + bool* aHasProperty) 1.851 +{ 1.852 + if (!mObject) { 1.853 + NS_WARNING("Calling AnswerHasProperty with an invalidated object!"); 1.854 + *aHasProperty = false; 1.855 + return true; 1.856 + } 1.857 + 1.858 + NS_ASSERTION(mObject->_class != GetClass(), "Bad object type!"); 1.859 + NS_ASSERTION(mType == LocalObject, "Bad type!"); 1.860 + 1.861 + PluginInstanceParent* instance = GetInstance(); 1.862 + if (!instance) { 1.863 + NS_ERROR("No instance?!"); 1.864 + *aHasProperty = false; 1.865 + return true; 1.866 + } 1.867 + 1.868 + const NPNetscapeFuncs* npn = GetNetscapeFuncs(instance); 1.869 + if (!npn) { 1.870 + NS_ERROR("No netscape funcs?!"); 1.871 + *aHasProperty = false; 1.872 + return true; 1.873 + } 1.874 + 1.875 + PluginIdentifierParent* id = static_cast<PluginIdentifierParent*>(aId); 1.876 + *aHasProperty = npn->hasproperty(instance->GetNPP(), mObject, 1.877 + id->ToNPIdentifier()); 1.878 + return true; 1.879 +} 1.880 + 1.881 +bool 1.882 +PluginScriptableObjectParent::AnswerGetParentProperty( 1.883 + PPluginIdentifierParent* aId, 1.884 + Variant* aResult, 1.885 + bool* aSuccess) 1.886 +{ 1.887 + if (!mObject) { 1.888 + NS_WARNING("Calling AnswerGetProperty with an invalidated object!"); 1.889 + *aResult = void_t(); 1.890 + *aSuccess = false; 1.891 + return true; 1.892 + } 1.893 + 1.894 + NS_ASSERTION(mObject->_class != GetClass(), "Bad object type!"); 1.895 + NS_ASSERTION(mType == LocalObject, "Bad type!"); 1.896 + 1.897 + PluginInstanceParent* instance = GetInstance(); 1.898 + if (!instance) { 1.899 + NS_ERROR("No instance?!"); 1.900 + *aResult = void_t(); 1.901 + *aSuccess = false; 1.902 + return true; 1.903 + } 1.904 + 1.905 + const NPNetscapeFuncs* npn = GetNetscapeFuncs(instance); 1.906 + if (!npn) { 1.907 + NS_ERROR("No netscape funcs?!"); 1.908 + *aResult = void_t(); 1.909 + *aSuccess = false; 1.910 + return true; 1.911 + } 1.912 + 1.913 + PluginIdentifierParent* id = static_cast<PluginIdentifierParent*>(aId); 1.914 + NPVariant result; 1.915 + if (!npn->getproperty(instance->GetNPP(), mObject, id->ToNPIdentifier(), 1.916 + &result)) { 1.917 + *aResult = void_t(); 1.918 + *aSuccess = false; 1.919 + return true; 1.920 + } 1.921 + 1.922 + Variant converted; 1.923 + if ((*aSuccess = ConvertToRemoteVariant(result, converted, instance))) { 1.924 + DeferNPVariantLastRelease(npn, &result); 1.925 + *aResult = converted; 1.926 + } 1.927 + else { 1.928 + *aResult = void_t(); 1.929 + } 1.930 + 1.931 + return true; 1.932 +} 1.933 + 1.934 +bool 1.935 +PluginScriptableObjectParent::AnswerSetProperty(PPluginIdentifierParent* aId, 1.936 + const Variant& aValue, 1.937 + bool* aSuccess) 1.938 +{ 1.939 + if (!mObject) { 1.940 + NS_WARNING("Calling AnswerSetProperty with an invalidated object!"); 1.941 + *aSuccess = false; 1.942 + return true; 1.943 + } 1.944 + 1.945 + NS_ASSERTION(mObject->_class != GetClass(), "Bad object type!"); 1.946 + NS_ASSERTION(mType == LocalObject, "Bad type!"); 1.947 + 1.948 + PluginInstanceParent* instance = GetInstance(); 1.949 + if (!instance) { 1.950 + NS_ERROR("No instance?!"); 1.951 + *aSuccess = false; 1.952 + return true; 1.953 + } 1.954 + 1.955 + const NPNetscapeFuncs* npn = GetNetscapeFuncs(instance); 1.956 + if (!npn) { 1.957 + NS_ERROR("No netscape funcs?!"); 1.958 + *aSuccess = false; 1.959 + return true; 1.960 + } 1.961 + 1.962 + NPVariant converted; 1.963 + if (!ConvertToVariant(aValue, converted, instance)) { 1.964 + *aSuccess = false; 1.965 + return true; 1.966 + } 1.967 + 1.968 + PluginIdentifierParent* id = static_cast<PluginIdentifierParent*>(aId); 1.969 + if ((*aSuccess = npn->setproperty(instance->GetNPP(), mObject, 1.970 + id->ToNPIdentifier(), &converted))) { 1.971 + ReleaseVariant(converted, instance); 1.972 + } 1.973 + return true; 1.974 +} 1.975 + 1.976 +bool 1.977 +PluginScriptableObjectParent::AnswerRemoveProperty(PPluginIdentifierParent* aId, 1.978 + bool* aSuccess) 1.979 +{ 1.980 + if (!mObject) { 1.981 + NS_WARNING("Calling AnswerRemoveProperty with an invalidated object!"); 1.982 + *aSuccess = false; 1.983 + return true; 1.984 + } 1.985 + 1.986 + NS_ASSERTION(mObject->_class != GetClass(), "Bad object type!"); 1.987 + NS_ASSERTION(mType == LocalObject, "Bad type!"); 1.988 + 1.989 + PluginInstanceParent* instance = GetInstance(); 1.990 + if (!instance) { 1.991 + NS_ERROR("No instance?!"); 1.992 + *aSuccess = false; 1.993 + return true; 1.994 + } 1.995 + 1.996 + const NPNetscapeFuncs* npn = GetNetscapeFuncs(instance); 1.997 + if (!npn) { 1.998 + NS_ERROR("No netscape funcs?!"); 1.999 + *aSuccess = false; 1.1000 + return true; 1.1001 + } 1.1002 + 1.1003 + PluginIdentifierParent* id = static_cast<PluginIdentifierParent*>(aId); 1.1004 + *aSuccess = npn->removeproperty(instance->GetNPP(), mObject, 1.1005 + id->ToNPIdentifier()); 1.1006 + return true; 1.1007 +} 1.1008 + 1.1009 +bool 1.1010 +PluginScriptableObjectParent::AnswerEnumerate(InfallibleTArray<PPluginIdentifierParent*>* aProperties, 1.1011 + bool* aSuccess) 1.1012 +{ 1.1013 + if (!mObject) { 1.1014 + NS_WARNING("Calling AnswerEnumerate with an invalidated object!"); 1.1015 + *aSuccess = false; 1.1016 + return true; 1.1017 + } 1.1018 + 1.1019 + NS_ASSERTION(mObject->_class != GetClass(), "Bad object type!"); 1.1020 + NS_ASSERTION(mType == LocalObject, "Bad type!"); 1.1021 + 1.1022 + PluginInstanceParent* instance = GetInstance(); 1.1023 + if (!instance) { 1.1024 + NS_ERROR("No instance?!"); 1.1025 + *aSuccess = false; 1.1026 + return true; 1.1027 + } 1.1028 + 1.1029 + const NPNetscapeFuncs* npn = GetNetscapeFuncs(instance); 1.1030 + if (!npn) { 1.1031 + NS_WARNING("No netscape funcs?!"); 1.1032 + *aSuccess = false; 1.1033 + return true; 1.1034 + } 1.1035 + 1.1036 + NPIdentifier* ids; 1.1037 + uint32_t idCount; 1.1038 + if (!npn->enumerate(instance->GetNPP(), mObject, &ids, &idCount)) { 1.1039 + *aSuccess = false; 1.1040 + return true; 1.1041 + } 1.1042 + 1.1043 + aProperties->SetCapacity(idCount); 1.1044 + 1.1045 + mozilla::AutoSafeJSContext cx; 1.1046 + for (uint32_t index = 0; index < idCount; index++) { 1.1047 + // Because of GC hazards, all identifiers returned from enumerate 1.1048 + // must be made permanent. 1.1049 + if (_identifierisstring(ids[index])) { 1.1050 + JS::Rooted<JSString*> str(cx, NPIdentifierToString(ids[index])); 1.1051 + if (!JS_StringHasBeenInterned(cx, str)) { 1.1052 + DebugOnly<JSString*> str2 = JS_InternJSString(cx, str); 1.1053 + NS_ASSERTION(str2 == str, "Interning a JS string which is currently an ID should return itself."); 1.1054 + } 1.1055 + } 1.1056 + PluginIdentifierParent* id = 1.1057 + instance->Module()->GetIdentifierForNPIdentifier(instance->GetNPP(), ids[index]); 1.1058 + aProperties->AppendElement(id); 1.1059 + NS_ASSERTION(!id->IsTemporary(), "Should only have permanent identifiers!"); 1.1060 + } 1.1061 + 1.1062 + npn->memfree(ids); 1.1063 + *aSuccess = true; 1.1064 + return true; 1.1065 +} 1.1066 + 1.1067 +bool 1.1068 +PluginScriptableObjectParent::AnswerConstruct(const InfallibleTArray<Variant>& aArgs, 1.1069 + Variant* aResult, 1.1070 + bool* aSuccess) 1.1071 +{ 1.1072 + if (!mObject) { 1.1073 + NS_WARNING("Calling AnswerConstruct with an invalidated object!"); 1.1074 + *aResult = void_t(); 1.1075 + *aSuccess = false; 1.1076 + return true; 1.1077 + } 1.1078 + 1.1079 + NS_ASSERTION(mObject->_class != GetClass(), "Bad object type!"); 1.1080 + NS_ASSERTION(mType == LocalObject, "Bad type!"); 1.1081 + 1.1082 + PluginInstanceParent* instance = GetInstance(); 1.1083 + if (!instance) { 1.1084 + NS_ERROR("No instance?!"); 1.1085 + *aResult = void_t(); 1.1086 + *aSuccess = false; 1.1087 + return true; 1.1088 + } 1.1089 + 1.1090 + const NPNetscapeFuncs* npn = GetNetscapeFuncs(instance); 1.1091 + if (!npn) { 1.1092 + NS_ERROR("No netscape funcs?!"); 1.1093 + *aResult = void_t(); 1.1094 + *aSuccess = false; 1.1095 + return true; 1.1096 + } 1.1097 + 1.1098 + AutoFallibleTArray<NPVariant, 10> convertedArgs; 1.1099 + uint32_t argCount = aArgs.Length(); 1.1100 + 1.1101 + if (!convertedArgs.SetLength(argCount)) { 1.1102 + *aResult = void_t(); 1.1103 + *aSuccess = false; 1.1104 + return true; 1.1105 + } 1.1106 + 1.1107 + for (uint32_t index = 0; index < argCount; index++) { 1.1108 + if (!ConvertToVariant(aArgs[index], convertedArgs[index], instance)) { 1.1109 + // Don't leak things we've already converted! 1.1110 + while (index-- > 0) { 1.1111 + ReleaseVariant(convertedArgs[index], instance); 1.1112 + } 1.1113 + *aResult = void_t(); 1.1114 + *aSuccess = false; 1.1115 + return true; 1.1116 + } 1.1117 + } 1.1118 + 1.1119 + NPVariant result; 1.1120 + bool success = npn->construct(instance->GetNPP(), mObject, 1.1121 + convertedArgs.Elements(), argCount, &result); 1.1122 + 1.1123 + for (uint32_t index = 0; index < argCount; index++) { 1.1124 + ReleaseVariant(convertedArgs[index], instance); 1.1125 + } 1.1126 + 1.1127 + if (!success) { 1.1128 + *aResult = void_t(); 1.1129 + *aSuccess = false; 1.1130 + return true; 1.1131 + } 1.1132 + 1.1133 + Variant convertedResult; 1.1134 + success = ConvertToRemoteVariant(result, convertedResult, instance); 1.1135 + 1.1136 + DeferNPVariantLastRelease(npn, &result); 1.1137 + 1.1138 + if (!success) { 1.1139 + *aResult = void_t(); 1.1140 + *aSuccess = false; 1.1141 + return true; 1.1142 + } 1.1143 + 1.1144 + *aSuccess = true; 1.1145 + *aResult = convertedResult; 1.1146 + return true; 1.1147 +} 1.1148 + 1.1149 +bool 1.1150 +PluginScriptableObjectParent::RecvProtect() 1.1151 +{ 1.1152 + NS_ASSERTION(mObject->_class != GetClass(), "Bad object type!"); 1.1153 + NS_ASSERTION(mType == LocalObject, "Bad type!"); 1.1154 + 1.1155 + Protect(); 1.1156 + return true; 1.1157 +} 1.1158 + 1.1159 +bool 1.1160 +PluginScriptableObjectParent::RecvUnprotect() 1.1161 +{ 1.1162 + NS_ASSERTION(mObject->_class != GetClass(), "Bad object type!"); 1.1163 + NS_ASSERTION(mType == LocalObject, "Bad type!"); 1.1164 + 1.1165 + Unprotect(); 1.1166 + return true; 1.1167 +} 1.1168 + 1.1169 +bool 1.1170 +PluginScriptableObjectParent::AnswerNPN_Evaluate(const nsCString& aScript, 1.1171 + Variant* aResult, 1.1172 + bool* aSuccess) 1.1173 +{ 1.1174 + PluginInstanceParent* instance = GetInstance(); 1.1175 + if (!instance) { 1.1176 + NS_ERROR("No instance?!"); 1.1177 + *aResult = void_t(); 1.1178 + *aSuccess = false; 1.1179 + return true; 1.1180 + } 1.1181 + 1.1182 + const NPNetscapeFuncs* npn = GetNetscapeFuncs(instance); 1.1183 + if (!npn) { 1.1184 + NS_ERROR("No netscape funcs?!"); 1.1185 + *aResult = void_t(); 1.1186 + *aSuccess = false; 1.1187 + return true; 1.1188 + } 1.1189 + 1.1190 + NPString script = { aScript.get(), aScript.Length() }; 1.1191 + 1.1192 + NPVariant result; 1.1193 + bool success = npn->evaluate(instance->GetNPP(), mObject, &script, &result); 1.1194 + if (!success) { 1.1195 + *aResult = void_t(); 1.1196 + *aSuccess = false; 1.1197 + return true; 1.1198 + } 1.1199 + 1.1200 + Variant convertedResult; 1.1201 + success = ConvertToRemoteVariant(result, convertedResult, instance); 1.1202 + 1.1203 + DeferNPVariantLastRelease(npn, &result); 1.1204 + 1.1205 + if (!success) { 1.1206 + *aResult = void_t(); 1.1207 + *aSuccess = false; 1.1208 + return true; 1.1209 + } 1.1210 + 1.1211 + *aSuccess = true; 1.1212 + *aResult = convertedResult; 1.1213 + return true; 1.1214 +} 1.1215 + 1.1216 +bool 1.1217 +PluginScriptableObjectParent::GetPropertyHelper(NPIdentifier aName, 1.1218 + bool* aHasProperty, 1.1219 + bool* aHasMethod, 1.1220 + NPVariant* aResult) 1.1221 +{ 1.1222 + NS_ASSERTION(Type() == Proxy, "Bad type!"); 1.1223 + 1.1224 + ParentNPObject* object = static_cast<ParentNPObject*>(mObject); 1.1225 + if (object->invalidated) { 1.1226 + NS_WARNING("Calling method on an invalidated object!"); 1.1227 + return false; 1.1228 + } 1.1229 + 1.1230 + PluginIdentifierParent::StackIdentifier identifier(GetInstance(), aName); 1.1231 + if (!identifier) { 1.1232 + return false; 1.1233 + } 1.1234 + 1.1235 + bool hasProperty, hasMethod, success; 1.1236 + Variant result; 1.1237 + if (!CallGetChildProperty(identifier, &hasProperty, &hasMethod, &result, 1.1238 + &success)) { 1.1239 + return false; 1.1240 + } 1.1241 + 1.1242 + if (!success) { 1.1243 + return false; 1.1244 + } 1.1245 + 1.1246 + if (!ConvertToVariant(result, *aResult, GetInstance())) { 1.1247 + NS_WARNING("Failed to convert result!"); 1.1248 + return false; 1.1249 + } 1.1250 + 1.1251 + *aHasProperty = hasProperty; 1.1252 + *aHasMethod = hasMethod; 1.1253 + return true; 1.1254 +}