JSValue JSNPObject::propertyGetter(ExecState* exec, JSValue slotBase, PropertyName propertyName) { JSNPObject* thisObj = static_cast<JSNPObject*>(asObject(slotBase)); ASSERT_GC_OBJECT_INHERITS(thisObj, &s_info); if (!thisObj->m_npObject) return throwInvalidAccessError(exec); if (!thisObj->m_npObject->_class->getProperty) return jsUndefined(); NPVariant result; VOID_TO_NPVARIANT(result); // Calling NPClass::getProperty will call into plug-in code, and there's no telling what the plug-in can do. // (including destroying the plug-in). Because of this, we make sure to keep the plug-in alive until // the call has finished. NPRuntimeObjectMap::PluginProtector protector(thisObj->m_objectMap); bool returnValue; { JSLock::DropAllLocks dropAllLocks(SilenceAssertionsOnly); NPIdentifier npIdentifier = npIdentifierFromIdentifier(propertyName); returnValue = thisObj->m_npObject->_class->getProperty(thisObj->m_npObject, npIdentifier, &result); NPRuntimeObjectMap::moveGlobalExceptionToExecState(exec); } if (!returnValue) return jsUndefined(); JSValue propertyValue = thisObj->m_objectMap->convertNPVariantToJSValue(exec, thisObj->globalObject(), result); releaseNPVariantValue(&result); return propertyValue; }
void NPRuntimeObjectMap::invalidate() { Vector<NPJSObject*> npJSObjects; copyValuesToVector(m_npJSObjects, npJSObjects); // Deallocate all the object wrappers so we won't leak any JavaScript objects. for (size_t i = 0; i < npJSObjects.size(); ++i) deallocateNPObject(npJSObjects[i]); // We shouldn't have any NPJSObjects left now. ASSERT(m_npJSObjects.isEmpty()); Vector<NPObject*> objects; for (HashMap<NPObject*, JSC::Weak<JSNPObject>>::iterator ptr = m_jsNPObjects.begin(), end = m_jsNPObjects.end(); ptr != end; ++ptr) { JSNPObject* jsNPObject = ptr->value.get(); if (!jsNPObject) // Skip zombies. continue; objects.append(jsNPObject->leakNPObject()); } m_jsNPObjects.clear(); for (size_t i = 0; i < objects.size(); ++i) releaseNPObject(objects[i]); // Deal with any objects that were scheduled for delayed destruction if (m_npObjectsToFinalize.isEmpty()) return; ASSERT(m_finalizationTimer.isActive()); m_finalizationTimer.stop(); invalidateQueuedObjects(); }
JSValue JSNPObject::methodGetter(ExecState* exec, JSValue slotBase, const Identifier& methodName) { JSNPObject* thisObj = static_cast<JSNPObject*>(asObject(slotBase)); if (!thisObj->m_npObject) return throwInvalidAccessError(exec); NPIdentifier npIdentifier = npIdentifierFromIdentifier(methodName); return new (exec) JSNPMethod(exec, thisObj->globalObject(), methodName, npIdentifier); }
JSValue JSNPObject::methodGetter(ExecState* exec, JSValue slotBase, PropertyName methodName) { JSNPObject* thisObj = static_cast<JSNPObject*>(asObject(slotBase)); ASSERT_GC_OBJECT_INHERITS(thisObj, &s_info); if (!thisObj->m_npObject) return throwInvalidAccessError(exec); NPIdentifier npIdentifier = npIdentifierFromIdentifier(methodName); return JSNPMethod::create(exec, thisObj->globalObject(), methodName.ustring(), npIdentifier); }
EncodedJSValue JSNPObject::methodGetter(ExecState* exec, EncodedJSValue slotBase, EncodedJSValue, PropertyName propertyName) { JSNPObject* thisObj = jsCast<JSNPObject*>(JSValue::decode(slotBase)); ASSERT_GC_OBJECT_INHERITS(thisObj, info()); if (!thisObj->m_npObject) return JSValue::encode(throwInvalidAccessError(exec)); NPIdentifier npIdentifier = npIdentifierFromIdentifier(propertyName); return JSValue::encode(JSNPMethod::create(exec, thisObj->globalObject(), propertyName.publicName(), npIdentifier)); }
NPObject* NPRuntimeObjectMap::getOrCreateNPObject(JSGlobalData& globalData, JSObject* jsObject) { // If this is a JSNPObject, we can just get its underlying NPObject. if (jsObject->classInfo() == &JSNPObject::s_info) { JSNPObject* jsNPObject = static_cast<JSNPObject*>(jsObject); NPObject* npObject = jsNPObject->npObject(); retainNPObject(npObject); return npObject; } // First, check if we already know about this object. if (NPJSObject* npJSObject = m_npJSObjects.get(jsObject)) { retainNPObject(npJSObject); return npJSObject; } NPJSObject* npJSObject = NPJSObject::create(globalData, this, jsObject); m_npJSObjects.set(jsObject, npJSObject); return npJSObject; }
NPObject* NPRuntimeObjectMap::getOrCreateNPObject(VM& vm, JSObject* jsObject) { // If this is a JSNPObject, we can just get its underlying NPObject. if (jsObject->classInfo() == JSNPObject::info()) { JSNPObject* jsNPObject = jsCast<JSNPObject*>(jsObject); NPObject* npObject = jsNPObject->npObject(); retainNPObject(npObject); return npObject; } // First, check if we already know about this object. if (NPJSObject* npJSObject = m_npJSObjects.get(jsObject)) { retainNPObject(npJSObject); return npJSObject; } NPJSObject* npJSObject = NPJSObject::create(vm, this, jsObject); m_npJSObjects.set(jsObject, npJSObject); return npJSObject; }
static EncodedJSValue JSC_HOST_CALL callMethod(ExecState* exec) { JSNPMethod* jsNPMethod = static_cast<JSNPMethod*>(exec->callee()); JSValue thisValue = exec->hostThisValue(); // Check if we're calling a method on the plug-in script object. if (thisValue.inherits(&JSHTMLElement::s_info)) { JSHTMLElement* element = static_cast<JSHTMLElement*>(asObject(thisValue)); // Try to get the script object from the element if (JSObject* scriptObject = pluginScriptObject(exec, element)) thisValue = scriptObject; } if (thisValue.inherits(&JSNPObject::s_info)) { JSNPObject* jsNPObject = static_cast<JSNPObject*>(asObject(thisValue)); return JSValue::encode(jsNPObject->callMethod(exec, jsNPMethod->npIdentifier())); } return throwVMTypeError(exec); }
void NPRuntimeObjectMap::finalize(JSC::Handle<JSC::Unknown> handle, void* context) { JSNPObject* object = jsCast<JSNPObject*>(handle.get().asCell()); weakRemove(m_jsNPObjects, static_cast<NPObject*>(context), object); addToInvalidationQueue(object->leakNPObject()); }