bool _NPN_Evaluate(NPP, NPObject* o, NPString* s, NPVariant* variant) { if (o->_class == NPScriptObjectClass) { JavaScriptObject* obj = reinterpret_cast<JavaScriptObject*>(o); RootObject* rootObject = obj->rootObject; if (!rootObject || !rootObject->isValid()) return false; ExecState* exec = rootObject->globalObject()->globalExec(); JSLock lock(SilenceAssertionsOnly); String scriptString = convertNPStringToUTF16(s); ProtectedPtr<JSGlobalObject> globalObject = rootObject->globalObject(); globalObject->globalData()->timeoutChecker.start(); Completion completion = JSC::evaluate(globalObject->globalExec(), globalObject->globalScopeChain(), makeSource(scriptString), JSC::JSValue()); globalObject->globalData()->timeoutChecker.stop(); ComplType type = completion.complType(); JSValue result; if (type == Normal) { result = completion.value(); if (!result) result = jsUndefined(); } else result = jsUndefined(); convertValueToNPVariant(exec, result, variant); exec->clearException(); return true; } VOID_TO_NPVARIANT(*variant); return false; }
bool _NPN_HasProperty(NPP, NPObject* o, NPIdentifier propertyName) { if (o->_class == NPScriptObjectClass) { JavaScriptObject* obj = reinterpret_cast<JavaScriptObject*>(o); RootObject* rootObject = obj->rootObject; if (!rootObject || !rootObject->isValid()) return false; ExecState* exec = rootObject->globalObject()->globalExec(); PrivateIdentifier* i = static_cast<PrivateIdentifier*>(propertyName); JSLock lock(false); if (i->isString) { bool result = obj->imp->hasProperty(exec, identifierFromNPIdentifier(i->value.string)); exec->clearException(); return result; } bool result = obj->imp->hasProperty(exec, i->value.number); exec->clearException(); return result; } if (o->_class->hasProperty) return o->_class->hasProperty(o, propertyName); return false; }
jvalue JavaField::dispatchValueFromInstance(ExecState* exec, const JavaInstance* instance, const char* name, const char* sig, JNIType returnType) const { jobject jinstance = instance->javaInstance(); jobject fieldJInstance = m_field->m_instance; JNIEnv* env = getJNIEnv(); jvalue result; memset(&result, 0, sizeof(jvalue)); jclass cls = env->GetObjectClass(fieldJInstance); if (cls) { jmethodID mid = env->GetMethodID(cls, name, sig); if (mid) { RootObject* rootObject = instance->rootObject(); if (rootObject && rootObject->nativeHandle()) { JSValue exceptionDescription; jvalue args[1]; args[0].l = jinstance; dispatchJNICall(exec, rootObject->nativeHandle(), fieldJInstance, false, returnType, mid, args, result, 0, exceptionDescription); if (exceptionDescription) throwError(exec, GeneralError, exceptionDescription.toString(exec)); } } } return result; }
bool _NPN_SetProperty(NPP, NPObject* o, NPIdentifier propertyName, const NPVariant* variant) { if (o->_class == NPScriptObjectClass) { JavaScriptObject* obj = reinterpret_cast<JavaScriptObject*>(o); RootObject* rootObject = obj->rootObject; if (!rootObject || !rootObject->isValid()) return false; ExecState* exec = rootObject->globalObject()->globalExec(); JSLockHolder lock(exec); IdentifierRep* i = static_cast<IdentifierRep*>(propertyName); if (i->isString()) { PutPropertySlot slot(obj->imp); obj->imp->methodTable()->put(obj->imp, exec, identifierFromNPIdentifier(exec, i->string()), convertNPVariantToValue(exec, variant, rootObject), slot); } else obj->imp->methodTable()->putByIndex(obj->imp, exec, i->number(), convertNPVariantToValue(exec, variant, rootObject), false); exec->clearException(); return true; } if (o->_class->setProperty) return o->_class->setProperty(o, propertyName, variant); return false; }
bool _NPN_RemoveProperty(NPP, NPObject* o, NPIdentifier propertyName) { if (o->_class == NPScriptObjectClass) { JavaScriptObject* obj = reinterpret_cast<JavaScriptObject*>(o); RootObject* rootObject = obj->rootObject; if (!rootObject || !rootObject->isValid()) return false; ExecState* exec = rootObject->globalObject()->globalExec(); IdentifierRep* i = static_cast<IdentifierRep*>(propertyName); if (i->isString()) { if (!obj->imp->hasProperty(exec, identifierFromNPIdentifier(exec, i->string()))) { exec->clearException(); return false; } } else { if (!obj->imp->hasProperty(exec, i->number())) { exec->clearException(); return false; } } JSLockHolder lock(exec); if (i->isString()) obj->imp->methodTable()->deleteProperty(obj->imp, exec, identifierFromNPIdentifier(exec, i->string())); else obj->imp->methodTable()->deletePropertyByIndex(obj->imp, exec, i->number()); exec->clearException(); return true; } return false; }
bool _NPN_Evaluate(NPP instance, NPObject* o, NPString* s, NPVariant* variant) { if (o->_class == NPScriptObjectClass) { JavaScriptObject* obj = reinterpret_cast<JavaScriptObject*>(o); RootObject* rootObject = obj->rootObject; if (!rootObject || !rootObject->isValid()) return false; // There is a crash in Flash when evaluating a script that destroys the // PluginView, so we destroy it asynchronously. PluginView::keepAlive(instance); ExecState* exec = rootObject->globalObject()->globalExec(); JSLockHolder lock(exec); String scriptString = convertNPStringToUTF16(s); JSValue returnValue = JSC::evaluate(rootObject->globalObject()->globalExec(), makeSource(scriptString), JSC::JSValue()); convertValueToNPVariant(exec, returnValue, variant); exec->clearException(); return true; } VOID_TO_NPVARIANT(*variant); return false; }
bool _NPN_GetProperty(NPP, NPObject* o, NPIdentifier propertyName, NPVariant* variant) { if (o->_class == NPScriptObjectClass) { JavaScriptObject* obj = reinterpret_cast<JavaScriptObject*>(o); RootObject* rootObject = obj->rootObject; if (!rootObject || !rootObject->isValid()) return false; ExecState* exec = rootObject->globalObject()->globalExec(); PrivateIdentifier* i = static_cast<PrivateIdentifier*>(propertyName); JSLock lock(false); JSValue* result; if (i->isString) result = obj->imp->get(exec, identifierFromNPIdentifier(i->value.string)); else result = obj->imp->get(exec, i->value.number); convertValueToNPVariant(exec, result, variant); exec->clearException(); return true; } if (o->_class->hasProperty && o->_class->getProperty) { if (o->_class->hasProperty(o, propertyName)) return o->_class->getProperty(o, propertyName, variant); return false; } VOID_TO_NPVARIANT(*variant); return false; }
bool _NPN_RemoveProperty(NPP, NPObject* o, NPIdentifier propertyName) { if (o->_class == NPScriptObjectClass) { JavaScriptObject* obj = (JavaScriptObject*)o; if (!_isSafeScript(obj)) return false; RootObject* rootObject = obj->rootObject; if (!rootObject || !rootObject->isValid()) return false; ExecState* exec = rootObject->interpreter()->globalExec(); PrivateIdentifier* i = (PrivateIdentifier*)propertyName; if (i->isString) { if (!obj->imp->hasProperty(exec, identifierFromNPIdentifier(i->value.string))) return false; } else { if (!obj->imp->hasProperty(exec, i->value.number)) return false; } JSLock lock; if (i->isString) obj->imp->deleteProperty(exec, identifierFromNPIdentifier(i->value.string)); else obj->imp->deleteProperty(exec, i->value.number); return true; } return false; }
bool _NPN_SetProperty(NPP, NPObject* o, NPIdentifier propertyName, const NPVariant* variant) { if (o->_class == NPScriptObjectClass) { JavaScriptObject* obj = (JavaScriptObject*)o; if (!_isSafeScript(obj)) return false; RootObject* rootObject = obj->rootObject; if (!rootObject || !rootObject->isValid()) return false; ExecState* exec = rootObject->interpreter()->globalExec(); JSLock lock; PrivateIdentifier* i = (PrivateIdentifier*)propertyName; if (i->isString) obj->imp->put(exec, identifierFromNPIdentifier(i->value.string), convertNPVariantToValue(exec, variant)); else obj->imp->put(exec, i->value.number, convertNPVariantToValue(exec, variant)); return true; } if (o->_class->setProperty) return o->_class->setProperty(o, propertyName, variant); return false; }
bool _NPN_HasMethod(NPP, NPObject* o, NPIdentifier methodName) { if (o->_class == NPScriptObjectClass) { JavaScriptObject* obj = reinterpret_cast<JavaScriptObject*>(o); PrivateIdentifier* i = static_cast<PrivateIdentifier*>(methodName); if (!i->isString) return false; RootObject* rootObject = obj->rootObject; if (!rootObject || !rootObject->isValid()) return false; ExecState* exec = rootObject->globalObject()->globalExec(); JSLock lock(false); JSValue* func = obj->imp->get(exec, identifierFromNPIdentifier(i->value.string)); exec->clearException(); return !func->isUndefined(); } if (o->_class->hasMethod) return o->_class->hasMethod(o, methodName); return false; }
bool _NPN_Enumerate(NPP, NPObject* o, NPIdentifier** identifier, uint32_t* count) { if (o->_class == NPScriptObjectClass) { JavaScriptObject* obj = reinterpret_cast<JavaScriptObject*>(o); RootObject* rootObject = obj->rootObject; if (!rootObject || !rootObject->isValid()) return false; ExecState* exec = rootObject->globalObject()->globalExec(); JSLock lock(false); PropertyNameArray propertyNames(exec); obj->imp->getPropertyNames(exec, propertyNames); unsigned size = static_cast<unsigned>(propertyNames.size()); // FIXME: This should really call NPN_MemAlloc but that's in WebKit NPIdentifier* identifiers = static_cast<NPIdentifier*>(malloc(sizeof(NPIdentifier) * size)); for (unsigned i = 0; i < size; ++i) identifiers[i] = _NPN_GetStringIdentifier(propertyNames[i].ustring().UTF8String().c_str()); *identifier = identifiers; *count = size; exec->clearException(); return true; } if (NP_CLASS_STRUCT_VERSION_HAS_ENUM(o->_class) && o->_class->enumerate) return o->_class->enumerate(o, identifier, count); return false; }
bool _NPN_HasMethod(NPP, NPObject* o, NPIdentifier methodName) { if (o->_class == NPScriptObjectClass) { JavaScriptObject* obj = (JavaScriptObject*)o; if (!_isSafeScript(obj)) return false; PrivateIdentifier* i = (PrivateIdentifier*)methodName; if (!i->isString) return false; RootObject* rootObject = obj->rootObject; if (!rootObject || !rootObject->isValid()) return false; ExecState* exec = rootObject->interpreter()->globalExec(); JSLock lock; JSValue* func = obj->imp->get(exec, identifierFromNPIdentifier(i->value.string)); return !func->isUndefined(); } if (o->_class->hasMethod) return o->_class->hasMethod(o, methodName); return false; }
bool _NPN_SetProperty(NPP, NPObject* o, NPIdentifier propertyName, const NPVariant* variant) { if (o->_class == NPScriptObjectClass) { JavaScriptObject* obj = reinterpret_cast<JavaScriptObject*>(o); RootObject* rootObject = obj->rootObject; if (!rootObject || !rootObject->isValid()) return false; ExecState* exec = rootObject->globalObject()->globalExec(); JSLock lock(false); PrivateIdentifier* i = static_cast<PrivateIdentifier*>(propertyName); if (i->isString) { PutPropertySlot slot; obj->imp->put(exec, identifierFromNPIdentifier(i->value.string), convertNPVariantToValue(exec, variant, rootObject), slot); } else obj->imp->put(exec, i->value.number, convertNPVariantToValue(exec, variant, rootObject)); exec->clearException(); return true; } if (o->_class->setProperty) return o->_class->setProperty(o, propertyName, variant); return false; }
void JavaField::dispatchSetValueToInstance(ExecState* exec, const JavaInstance* instance, jvalue javaValue, const char* name, const char* sig) const { jobject jinstance = instance->javaInstance(); jobject fieldJInstance = m_field->m_instance; JNIEnv* env = getJNIEnv(); jclass cls = env->GetObjectClass(fieldJInstance); if (cls) { jmethodID mid = env->GetMethodID(cls, name, sig); if (mid) { RootObject* rootObject = instance->rootObject(); if (rootObject && rootObject->nativeHandle()) { JSValue exceptionDescription; jvalue args[2]; jvalue result; args[0].l = jinstance; args[1] = javaValue; dispatchJNICall(exec, rootObject->nativeHandle(), fieldJInstance, false, void_type, mid, args, result, 0, exceptionDescription); if (exceptionDescription) throwError(exec, GeneralError, exceptionDescription.toString(exec)); } } } }
bool _NPN_Invoke(NPP npp, NPObject* o, NPIdentifier methodName, const NPVariant* args, uint32_t argCount, NPVariant* result) { if (o->_class == NPScriptObjectClass) { JavaScriptObject* obj = (JavaScriptObject*)o; if (!_isSafeScript(obj)) return false; PrivateIdentifier* i = (PrivateIdentifier*)methodName; if (!i->isString) return false; // Special case the "eval" method. if (methodName == _NPN_GetStringIdentifier("eval")) { if (argCount != 1) return false; if (args[0].type != NPVariantType_String) return false; return _NPN_Evaluate(npp, o, (NPString *)&args[0].value.stringValue, result); } // Lookup the function object. RootObject* rootObject = obj->rootObject; if (!rootObject || !rootObject->isValid()) return false; ExecState* exec = rootObject->interpreter()->globalExec(); JSLock lock; JSValue* func = obj->imp->get(exec, identifierFromNPIdentifier(i->value.string)); if (func->isNull()) { NULL_TO_NPVARIANT(*result); return false; } if (func->isUndefined()) { VOID_TO_NPVARIANT(*result); return false; } // Call the function object. JSObject *funcImp = static_cast<JSObject*>(func); JSObject *thisObj = const_cast<JSObject*>(obj->imp); List argList = listFromVariantArgs(exec, args, argCount, rootObject); rootObject->interpreter()->startTimeoutCheck(); JSValue *resultV = funcImp->call (exec, thisObj, argList); rootObject->interpreter()->stopTimeoutCheck(); // Convert and return the result of the function call. convertValueToNPVariant(exec, resultV, result); return true; } if (o->_class->invoke) return o->_class->invoke(o, methodName, args, argCount, result); VOID_TO_NPVARIANT(*result); return true; }
int DeclarationExp::inlineCost3(InlineCostState *ics) { int cost = 0; VarDeclaration *vd; //printf("DeclarationExp::inlineCost3()\n"); vd = declaration->isVarDeclaration(); if (vd) { TupleDeclaration *td = vd->toAlias()->isTupleDeclaration(); if (td) { #if 1 return COST_MAX; // finish DeclarationExp::doInline #else for (size_t i = 0; i < td->objects->dim; i++) { RootObject *o = (*td->objects)[i]; if (o->dyncast() != DYNCAST_EXPRESSION) return COST_MAX; Expression *eo = (Expression *)o; if (eo->op != TOKdsymbol) return COST_MAX; } return td->objects->dim; #endif } if (!ics->hdrscan && vd->isDataseg()) return COST_MAX; cost += 1; if (vd->edtor) // if destructor required return COST_MAX; // needs work to make this work // Scan initializer (vd->init) if (vd->init) { ExpInitializer *ie = vd->init->isExpInitializer(); if (ie) { cost += expressionInlineCost(ie->exp, ics); } } } // These can contain functions, which when copied, get output twice. if (declaration->isStructDeclaration() || declaration->isClassDeclaration() || declaration->isFuncDeclaration() || declaration->isTypedefDeclaration() || declaration->isAttribDeclaration() || declaration->isTemplateMixin()) return COST_MAX; //printf("DeclarationExp::inlineCost3('%s')\n", toChars()); return cost; }
int #if _WIN32 __cdecl #endif Array_sort_compare(const void *x, const void *y) { RootObject *ox = *(RootObject **)x; RootObject *oy = *(RootObject **)y; return ox->compare(oy); }
void TypeQualified::toJson(JsonOut *json) // ident.ident.ident.etc { json->propertyStart("idents"); json->arrayStart(); for (size_t i = 0; i < idents.dim; i++) { RootObject *ident = idents[i]; json->item(ident->toChars()); } json->arrayEnd(); }
void _NPN_SetException(NPObject* o, const NPUTF8* message) { if (o->_class == NPScriptObjectClass) { JavaScriptObject* obj = (JavaScriptObject*)o; RootObject* rootObject = obj->rootObject; if (!rootObject || !rootObject->isValid()) return; ExecState* exec = rootObject->interpreter()->globalExec(); JSLock lock; throwError(exec, GeneralError, message); } }
bool _NPN_Invoke(NPP npp, NPObject* o, NPIdentifier methodName, const NPVariant* args, uint32_t argCount, NPVariant* result) { if (o->_class == NPScriptObjectClass) { JavaScriptObject* obj = reinterpret_cast<JavaScriptObject*>(o); IdentifierRep* i = static_cast<IdentifierRep*>(methodName); if (!i->isString()) return false; // Special case the "eval" method. if (methodName == _NPN_GetStringIdentifier("eval")) { if (argCount != 1) return false; if (args[0].type != NPVariantType_String) return false; return _NPN_Evaluate(npp, o, const_cast<NPString*>(&args[0].value.stringValue), result); } // Look up the function object. RootObject* rootObject = obj->rootObject; if (!rootObject || !rootObject->isValid()) return false; ExecState* exec = rootObject->globalObject()->globalExec(); JSLock lock(SilenceAssertionsOnly); JSValue function = obj->imp->get(exec, identifierFromNPIdentifier(i->string())); CallData callData; CallType callType = function.getCallData(callData); if (callType == CallTypeNone) return false; // Call the function object. MarkedArgumentBuffer argList; getListFromVariantArgs(exec, args, argCount, rootObject, argList); ProtectedPtr<JSGlobalObject> globalObject = rootObject->globalObject(); globalObject->globalData()->timeoutChecker.start(); JSValue resultV = JSC::call(exec, function, callType, callData, obj->imp, argList); globalObject->globalData()->timeoutChecker.stop(); // Convert and return the result of the function call. convertValueToNPVariant(exec, resultV, result); exec->clearException(); return true; } if (o->_class->invoke) return o->_class->invoke(o, methodName, args, argCount, result); VOID_TO_NPVARIANT(*result); return true; }
void WebMediaPlayerProxy::invokeMethod(const String& methodName) { Frame* frame = element()->document()->frame(); RootObject *root = frame->script()->bindingRootObject(); if (!root) return; ExecState *exec = root->globalObject()->globalExec(); Instance* instance = pluginInstance().get(); if (!instance) return; instance->begin(); Class *aClass = instance->getClass(); Identifier iden(exec, methodName); MethodList methodList = aClass->methodsNamed(iden, instance); ArgList args; instance->invokeMethod(exec, methodList , args); instance->end(); }
bool _NPN_GetProperty(NPP, NPObject* o, NPIdentifier propertyName, NPVariant* variant) { if (o->_class == NPScriptObjectClass) { JavaScriptObject* obj = (JavaScriptObject*)o; if (!_isSafeScript(obj)) return false; RootObject* rootObject = obj->rootObject; if (!rootObject || !rootObject->isValid()) return false; ExecState* exec = rootObject->interpreter()->globalExec(); PrivateIdentifier* i = (PrivateIdentifier*)propertyName; JSLock lock; JSValue *result; if (i->isString) result = obj->imp->get(exec, identifierFromNPIdentifier(i->value.string)); else result = obj->imp->get(exec, i->value.number); if (result->isNull()) { NULL_TO_NPVARIANT(*variant); return false; } if (result->isUndefined()) { VOID_TO_NPVARIANT(*variant); return false; } convertValueToNPVariant(exec, result, variant); return true; } if (o->_class->hasProperty && o->_class->getProperty) { if (o->_class->hasProperty(o, propertyName)) return o->_class->getProperty(o, propertyName, variant); return false; } VOID_TO_NPVARIANT(*variant); return false; }
bool _NPN_Evaluate(NPP, NPObject* o, NPString* s, NPVariant* variant) { if (o->_class == NPScriptObjectClass) { JavaScriptObject* obj = reinterpret_cast<JavaScriptObject*>(o); RootObject* rootObject = obj->rootObject; if (!rootObject || !rootObject->isValid()) return false; ExecState* exec = rootObject->globalObject()->globalExec(); JSLock lock(false); String scriptString = convertNPStringToUTF16(s); rootObject->globalObject()->startTimeoutCheck(); Completion completion = Interpreter::evaluate(rootObject->globalObject()->globalExec(), rootObject->globalObject()->globalScopeChain(), UString(), 1, scriptString); rootObject->globalObject()->stopTimeoutCheck(); ComplType type = completion.complType(); JSValue* result; if (type == Normal) { result = completion.value(); if (!result) result = jsUndefined(); } else result = jsUndefined(); convertValueToNPVariant(exec, result, variant); exec->clearException(); return true; } VOID_TO_NPVARIANT(*variant); return false; }
bool _NPN_InvokeDefault(NPP, NPObject* o, const NPVariant* args, uint32_t argCount, NPVariant* result) { if (o->_class == NPScriptObjectClass) { JavaScriptObject* obj = reinterpret_cast<JavaScriptObject*>(o); VOID_TO_NPVARIANT(*result); // Lookup the function object. RootObject* rootObject = obj->rootObject; if (!rootObject || !rootObject->isValid()) return false; ExecState* exec = rootObject->globalObject()->globalExec(); JSLock lock(SilenceAssertionsOnly); // Call the function object. JSValue function = obj->imp; CallData callData; CallType callType = function.getCallData(callData); if (callType == CallTypeNone) return false; MarkedArgumentBuffer argList; getListFromVariantArgs(exec, args, argCount, rootObject, argList); ProtectedPtr<JSGlobalObject> globalObject = rootObject->globalObject(); globalObject->globalData()->timeoutChecker.start(); JSValue resultV = JSC::call(exec, function, callType, callData, function, argList); globalObject->globalData()->timeoutChecker.stop(); // Convert and return the result of the function call. convertValueToNPVariant(exec, resultV, result); exec->clearException(); return true; } if (o->_class->invokeDefault) return o->_class->invokeDefault(o, args, argCount, result); VOID_TO_NPVARIANT(*result); return true; }
bool _NPN_Construct(NPP, NPObject* o, const NPVariant* args, uint32_t argCount, NPVariant* result) { if (o->_class == NPScriptObjectClass) { JavaScriptObject* obj = reinterpret_cast<JavaScriptObject*>(o); VOID_TO_NPVARIANT(*result); // Lookup the constructor object. RootObject* rootObject = obj->rootObject; if (!rootObject || !rootObject->isValid()) return false; ExecState* exec = rootObject->globalObject()->globalExec(); JSLock lock(SilenceAssertionsOnly); // Call the constructor object. JSValue constructor = obj->imp; ConstructData constructData; ConstructType constructType = constructor.getConstructData(constructData); if (constructType == ConstructTypeNone) return false; MarkedArgumentBuffer argList; getListFromVariantArgs(exec, args, argCount, rootObject, argList); ProtectedPtr<JSGlobalObject> globalObject = rootObject->globalObject(); globalObject->globalData()->timeoutChecker.start(); JSValue resultV = JSC::construct(exec, constructor, constructType, constructData, argList); globalObject->globalData()->timeoutChecker.stop(); // Convert and return the result. convertValueToNPVariant(exec, resultV, result); exec->clearException(); return true; } if (NP_CLASS_STRUCT_VERSION_HAS_CTOR(o->_class) && o->_class->construct) return o->_class->construct(o, args, argCount, result); return false; }
bool _NPN_Evaluate(NPP, NPObject* o, NPString* s, NPVariant* variant) { if (o->_class == NPScriptObjectClass) { JavaScriptObject* obj = (JavaScriptObject*)o; if (!_isSafeScript(obj)) return false; RootObject* rootObject = obj->rootObject; if (!rootObject || !rootObject->isValid()) return false; ExecState* exec = rootObject->interpreter()->globalExec(); JSLock lock; NPUTF16* scriptString; unsigned int UTF16Length; convertNPStringToUTF16(s, &scriptString, &UTF16Length); // requires free() of returned memory Completion completion = rootObject->interpreter()->evaluate(UString(), 0, UString((const UChar*)scriptString,UTF16Length)); ComplType type = completion.complType(); JSValue* result; if (type == Normal) { result = completion.value(); if (!result) result = jsUndefined(); } else result = jsUndefined(); free(scriptString); convertValueToNPVariant(exec, result, variant); return true; } VOID_TO_NPVARIANT(*variant); return false; }
bool _NPN_InvokeDefault(NPP, NPObject* o, const NPVariant* args, uint32_t argCount, NPVariant* result) { if (o->_class == NPScriptObjectClass) { JavaScriptObject* obj = (JavaScriptObject*)o; if (!_isSafeScript(obj)) return false; VOID_TO_NPVARIANT(*result); // Lookup the function object. RootObject* rootObject = obj->rootObject; if (!rootObject || !rootObject->isValid()) return false; ExecState* exec = rootObject->interpreter()->globalExec(); JSLock lock; // Call the function object. JSObject *funcImp = static_cast<JSObject*>(obj->imp); if (!funcImp->implementsCall()) return false; List argList = listFromVariantArgs(exec, args, argCount, rootObject); rootObject->interpreter()->startTimeoutCheck(); JSValue *resultV = funcImp->call (exec, funcImp, argList); rootObject->interpreter()->stopTimeoutCheck(); // Convert and return the result of the function call. convertValueToNPVariant(exec, resultV, result); return true; } if (o->_class->invokeDefault) return o->_class->invokeDefault(o, args, argCount, result); VOID_TO_NPVARIANT(*result); return true; }
void visit(ClassDeclaration *cd) { //printf("ClassDeclaration::toObjFile('%s')\n", cd->toChars()); if (cd->type->ty == Terror) { cd->error("had semantic errors when compiling"); return; } if (!cd->members) return; if (multiobj && !cd->hasStaticCtorOrDtor()) { obj_append(cd); return; } if (global.params.symdebug) toDebug(cd); assert(!cd->scope); // semantic() should have been run to completion enum_SC scclass = SCglobal; if (cd->isInstantiated()) scclass = SCcomdat; // Put out the members for (size_t i = 0; i < cd->members->dim; i++) { Dsymbol *member = (*cd->members)[i]; /* There might be static ctors in the members, and they cannot * be put in separate obj files. */ member->accept(this); } // Generate C symbols toSymbol(cd); toVtblSymbol(cd); Symbol *sinit = toInitializer(cd); ////////////////////////////////////////////// // Generate static initializer sinit->Sclass = scclass; sinit->Sfl = FLdata; ClassDeclaration_toDt(cd, &sinit->Sdt); out_readonly(sinit); outdata(sinit); ////////////////////////////////////////////// // Put out the TypeInfo genTypeInfo(cd->type, NULL); //toObjFile(cd->type->vtinfo, multiobj); ////////////////////////////////////////////// // Put out the ClassInfo cd->csym->Sclass = scclass; cd->csym->Sfl = FLdata; /* The layout is: { void **vptr; monitor_t monitor; byte[] initializer; // static initialization data char[] name; // class name void *[] vtbl; Interface[] interfaces; ClassInfo *base; // base class void *destructor; void *invariant; // class invariant ClassFlags flags; void *deallocator; OffsetTypeInfo[] offTi; void *defaultConstructor; //const(MemberInfo[]) function(string) xgetMembers; // module getMembers() function void *xgetRTInfo; //TypeInfo typeinfo; } */ dt_t *dt = NULL; unsigned offset = Target::classinfosize; // must be ClassInfo.size if (Type::typeinfoclass) { if (Type::typeinfoclass->structsize != Target::classinfosize) { #ifdef DEBUG printf("Target::classinfosize = x%x, Type::typeinfoclass->structsize = x%x\n", offset, Type::typeinfoclass->structsize); #endif cd->error("mismatch between dmd and object.d or object.di found. Check installation and import paths with -v compiler switch."); fatal(); } } if (Type::typeinfoclass) dtxoff(&dt, toVtblSymbol(Type::typeinfoclass), 0, TYnptr); // vtbl for ClassInfo else dtsize_t(&dt, 0); // BUG: should be an assert() dtsize_t(&dt, 0); // monitor // initializer[] assert(cd->structsize >= 8 || (cd->cpp && cd->structsize >= 4)); dtsize_t(&dt, cd->structsize); // size dtxoff(&dt, sinit, 0, TYnptr); // initializer // name[] const char *name = cd->ident->toChars(); size_t namelen = strlen(name); if (!(namelen > 9 && memcmp(name, "TypeInfo_", 9) == 0)) { name = cd->toPrettyChars(); namelen = strlen(name); } dtsize_t(&dt, namelen); dtabytes(&dt, TYnptr, 0, namelen + 1, name); // vtbl[] dtsize_t(&dt, cd->vtbl.dim); dtxoff(&dt, cd->vtblsym, 0, TYnptr); // interfaces[] dtsize_t(&dt, cd->vtblInterfaces->dim); if (cd->vtblInterfaces->dim) dtxoff(&dt, cd->csym, offset, TYnptr); // (*) else dtsize_t(&dt, 0); // base if (cd->baseClass) dtxoff(&dt, toSymbol(cd->baseClass), 0, TYnptr); else dtsize_t(&dt, 0); // destructor if (cd->dtor) dtxoff(&dt, toSymbol(cd->dtor), 0, TYnptr); else dtsize_t(&dt, 0); // invariant if (cd->inv) dtxoff(&dt, toSymbol(cd->inv), 0, TYnptr); else dtsize_t(&dt, 0); // flags ClassFlags::Type flags = ClassFlags::hasOffTi; if (cd->isCOMclass()) flags |= ClassFlags::isCOMclass; if (cd->isCPPclass()) flags |= ClassFlags::isCPPclass; flags |= ClassFlags::hasGetMembers; flags |= ClassFlags::hasTypeInfo; if (cd->ctor) flags |= ClassFlags::hasCtor; for (ClassDeclaration *pc = cd; pc; pc = pc->baseClass) { if (pc->dtor) { flags |= ClassFlags::hasDtor; break; } } if (cd->isabstract) flags |= ClassFlags::isAbstract; for (ClassDeclaration *pc = cd; pc; pc = pc->baseClass) { if (pc->members) { for (size_t i = 0; i < pc->members->dim; i++) { Dsymbol *sm = (*pc->members)[i]; //printf("sm = %s %s\n", sm->kind(), sm->toChars()); if (sm->hasPointers()) goto L2; } } } flags |= ClassFlags::noPointers; L2: dtsize_t(&dt, flags); // deallocator if (cd->aggDelete) dtxoff(&dt, toSymbol(cd->aggDelete), 0, TYnptr); else dtsize_t(&dt, 0); // offTi[] dtsize_t(&dt, 0); dtsize_t(&dt, 0); // null for now, fix later // defaultConstructor if (cd->defaultCtor && !(cd->defaultCtor->storage_class & STCdisable)) dtxoff(&dt, toSymbol(cd->defaultCtor), 0, TYnptr); else dtsize_t(&dt, 0); // xgetRTInfo if (cd->getRTInfo) Expression_toDt(cd->getRTInfo, &dt); else if (flags & ClassFlags::noPointers) dtsize_t(&dt, 0); else dtsize_t(&dt, 1); //dtxoff(&dt, toSymbol(type->vtinfo), 0, TYnptr); // typeinfo ////////////////////////////////////////////// // Put out (*vtblInterfaces)[]. Must immediately follow csym, because // of the fixup (*) offset += cd->vtblInterfaces->dim * (4 * Target::ptrsize); for (size_t i = 0; i < cd->vtblInterfaces->dim; i++) { BaseClass *b = (*cd->vtblInterfaces)[i]; ClassDeclaration *id = b->sym; /* The layout is: * struct Interface * { * ClassInfo *interface; * void *[] vtbl; * size_t offset; * } */ // Fill in vtbl[] b->fillVtbl(cd, &b->vtbl, 1); dtxoff(&dt, toSymbol(id), 0, TYnptr); // ClassInfo // vtbl[] dtsize_t(&dt, id->vtbl.dim); dtxoff(&dt, cd->csym, offset, TYnptr); dtsize_t(&dt, b->offset); // this offset offset += id->vtbl.dim * Target::ptrsize; } // Put out the (*vtblInterfaces)[].vtbl[] // This must be mirrored with ClassDeclaration::baseVtblOffset() //printf("putting out %d interface vtbl[]s for '%s'\n", vtblInterfaces->dim, toChars()); for (size_t i = 0; i < cd->vtblInterfaces->dim; i++) { BaseClass *b = (*cd->vtblInterfaces)[i]; ClassDeclaration *id = b->sym; //printf(" interface[%d] is '%s'\n", i, id->toChars()); size_t j = 0; if (id->vtblOffset()) { // First entry is ClassInfo reference //dtxoff(&dt, toSymbol(id), 0, TYnptr); // First entry is struct Interface reference dtxoff(&dt, cd->csym, Target::classinfosize + i * (4 * Target::ptrsize), TYnptr); j = 1; } assert(id->vtbl.dim == b->vtbl.dim); for (; j < id->vtbl.dim; j++) { assert(j < b->vtbl.dim); #if 0 RootObject *o = b->vtbl[j]; if (o) { printf("o = %p\n", o); assert(o->dyncast() == DYNCAST_DSYMBOL); Dsymbol *s = (Dsymbol *)o; printf("s->kind() = '%s'\n", s->kind()); } #endif FuncDeclaration *fd = b->vtbl[j]; if (fd) dtxoff(&dt, toThunkSymbol(fd, b->offset), 0, TYnptr); else dtsize_t(&dt, 0); } } // Put out the overriding interface vtbl[]s. // This must be mirrored with ClassDeclaration::baseVtblOffset() //printf("putting out overriding interface vtbl[]s for '%s' at offset x%x\n", toChars(), offset); ClassDeclaration *pc; for (pc = cd->baseClass; pc; pc = pc->baseClass) { for (size_t k = 0; k < pc->vtblInterfaces->dim; k++) { BaseClass *bs = (*pc->vtblInterfaces)[k]; FuncDeclarations bvtbl; if (bs->fillVtbl(cd, &bvtbl, 0)) { //printf("\toverriding vtbl[] for %s\n", bs->sym->toChars()); ClassDeclaration *id = bs->sym; size_t j = 0; if (id->vtblOffset()) { // First entry is ClassInfo reference //dtxoff(&dt, toSymbol(id), 0, TYnptr); // First entry is struct Interface reference dtxoff(&dt, toSymbol(pc), Target::classinfosize + k * (4 * Target::ptrsize), TYnptr); j = 1; } for (; j < id->vtbl.dim; j++) { assert(j < bvtbl.dim); FuncDeclaration *fd = bvtbl[j]; if (fd) dtxoff(&dt, toThunkSymbol(fd, bs->offset), 0, TYnptr); else dtsize_t(&dt, 0); } } } } cd->csym->Sdt = dt; // ClassInfo cannot be const data, because we use the monitor on it outdata(cd->csym); if (cd->isExport()) objmod->export_symbol(cd->csym, 0); ////////////////////////////////////////////// // Put out the vtbl[] //printf("putting out %s.vtbl[]\n", toChars()); dt = NULL; if (cd->vtblOffset()) dtxoff(&dt, cd->csym, 0, TYnptr); // first entry is ClassInfo reference for (size_t i = cd->vtblOffset(); i < cd->vtbl.dim; i++) { FuncDeclaration *fd = cd->vtbl[i]->isFuncDeclaration(); //printf("\tvtbl[%d] = %p\n", i, fd); if (fd && (fd->fbody || !cd->isAbstract())) { // Ensure function has a return value (Bugzilla 4869) fd->functionSemantic(); Symbol *s = toSymbol(fd); if (cd->isFuncHidden(fd)) { /* fd is hidden from the view of this class. * If fd overlaps with any function in the vtbl[], then * issue 'hidden' error. */ for (size_t j = 1; j < cd->vtbl.dim; j++) { if (j == i) continue; FuncDeclaration *fd2 = cd->vtbl[j]->isFuncDeclaration(); if (!fd2->ident->equals(fd->ident)) continue; if (fd->leastAsSpecialized(fd2) || fd2->leastAsSpecialized(fd)) { TypeFunction *tf = (TypeFunction *)fd->type; if (tf->ty == Tfunction) cd->error("use of %s%s is hidden by %s; use 'alias %s = %s.%s;' to introduce base class overload set", fd->toPrettyChars(), parametersTypeToChars(tf->parameters, tf->varargs), cd->toChars(), fd->toChars(), fd->parent->toChars(), fd->toChars()); else cd->error("use of %s is hidden by %s", fd->toPrettyChars(), cd->toChars()); break; } } } dtxoff(&dt, s, 0, TYnptr); } else dtsize_t(&dt, 0); } cd->vtblsym->Sdt = dt; cd->vtblsym->Sclass = scclass; cd->vtblsym->Sfl = FLdata; out_readonly(cd->vtblsym); outdata(cd->vtblsym); if (cd->isExport()) objmod->export_symbol(cd->vtblsym,0); }
JSValue JavaInstance::invokeMethod(ExecState* exec, RuntimeMethod* runtimeMethod, const ArgList &args) { if (!asObject(runtimeMethod)->inherits(&JavaRuntimeMethod::s_info)) return throwError(exec, TypeError, "Attempt to invoke non-Java method on Java object."); const MethodList& methodList = *runtimeMethod->methods(); int i; int count = args.size(); JSValue resultValue; Method* method = 0; size_t numMethods = methodList.size(); // Try to find a good match for the overloaded method. The // fundamental problem is that JavaScript doesn't have the // notion of method overloading and Java does. We could // get a bit more sophisticated and attempt to does some // type checking as we as checking the number of parameters. for (size_t methodIndex = 0; methodIndex < numMethods; methodIndex++) { Method* aMethod = methodList[methodIndex]; if (aMethod->numParameters() == count) { method = aMethod; break; } } if (!method) { LOG(LiveConnect, "JavaInstance::invokeMethod unable to find an appropiate method"); return jsUndefined(); } const JavaMethod* jMethod = static_cast<const JavaMethod*>(method); LOG(LiveConnect, "JavaInstance::invokeMethod call %s %s on %p", UString(jMethod->name()).UTF8String().data(), jMethod->signature(), m_instance->m_instance); Vector<jvalue> jArgs(count); for (i = 0; i < count; i++) { JavaParameter* aParameter = jMethod->parameterAt(i); jArgs[i] = convertValueToJValue(exec, m_rootObject.get(), args.at(i), aParameter->getJNIType(), aParameter->type()); LOG(LiveConnect, "JavaInstance::invokeMethod arg[%d] = %s", i, args.at(i).toString(exec).ascii()); } jvalue result; // Try to use the JNI abstraction first, otherwise fall back to // normal JNI. The JNI dispatch abstraction allows the Java plugin // to dispatch the call on the appropriate internal VM thread. RootObject* rootObject = this->rootObject(); if (!rootObject) return jsUndefined(); bool handled = false; if (rootObject->nativeHandle()) { jobject obj = m_instance->m_instance; JSValue exceptionDescription; const char *callingURL = 0; // FIXME, need to propagate calling URL to Java handled = dispatchJNICall(exec, rootObject->nativeHandle(), obj, jMethod->isStatic(), jMethod->JNIReturnType(), jMethod->methodID(obj), jArgs.data(), result, callingURL, exceptionDescription); if (exceptionDescription) { throwError(exec, GeneralError, exceptionDescription.toString(exec)); return jsUndefined(); } } #ifdef BUILDING_ON_TIGER if (!handled) { jobject obj = m_instance->m_instance; switch (jMethod->JNIReturnType()) { case void_type: callJNIMethodIDA<void>(obj, jMethod->methodID(obj), jArgs.data()); break; case object_type: result.l = callJNIMethodIDA<jobject>(obj, jMethod->methodID(obj), jArgs.data()); break; case boolean_type: result.z = callJNIMethodIDA<jboolean>(obj, jMethod->methodID(obj), jArgs.data()); break; case byte_type: result.b = callJNIMethodIDA<jbyte>(obj, jMethod->methodID(obj), jArgs.data()); break; case char_type: result.c = callJNIMethodIDA<jchar>(obj, jMethod->methodID(obj), jArgs.data()); break; case short_type: result.s = callJNIMethodIDA<jshort>(obj, jMethod->methodID(obj), jArgs.data()); break; case int_type: result.i = callJNIMethodIDA<jint>(obj, jMethod->methodID(obj), jArgs.data()); break; case long_type: result.j = callJNIMethodIDA<jlong>(obj, jMethod->methodID(obj), jArgs.data()); break; case float_type: result.f = callJNIMethodIDA<jfloat>(obj, jMethod->methodID(obj), jArgs.data()); break; case double_type: result.d = callJNIMethodIDA<jdouble>(obj, jMethod->methodID(obj), jArgs.data()); break; case array_type: case invalid_type: break; } } #endif switch (jMethod->JNIReturnType()) { case void_type: { resultValue = jsUndefined(); } break; case object_type: { if (result.l) { // FIXME: array_type return type is handled below, can we actually get an array here? const char* arrayType = jMethod->returnType(); if (arrayType[0] == '[') resultValue = JavaArray::convertJObjectToArray(exec, result.l, arrayType, rootObject); else { jobject classOfInstance = callJNIMethod<jobject>(result.l, "getClass", "()Ljava/lang/Class;"); jstring className = static_cast<jstring>(callJNIMethod<jobject>(classOfInstance, "getName", "()Ljava/lang/String;")); if (!strcmp(JavaString(className).UTF8String(), "sun.plugin.javascript.webkit.JSObject")) { // Pull the nativeJSObject value from the Java instance. This is a pointer to the JSObject. JNIEnv* env = getJNIEnv(); jfieldID fieldID = env->GetFieldID(static_cast<jclass>(classOfInstance), "nativeJSObject", "J"); jlong nativeHandle = env->GetLongField(result.l, fieldID); // FIXME: Handling of undefined values differs between functions in JNIUtilityPrivate.cpp and those in those in jni_jsobject.mm, // and so it does between different versions of LiveConnect spec. There should not be multiple code paths to do the same work. if (nativeHandle == 1 /* UndefinedHandle */) return jsUndefined(); return static_cast<JSObject*>(jlong_to_ptr(nativeHandle)); } else return JavaInstance::create(result.l, rootObject)->createRuntimeObject(exec); } } else return jsUndefined(); } break; case boolean_type: { resultValue = jsBoolean(result.z); } break; case byte_type: { resultValue = jsNumber(exec, result.b); } break; case char_type: { resultValue = jsNumber(exec, result.c); } break; case short_type: { resultValue = jsNumber(exec, result.s); } break; case int_type: { resultValue = jsNumber(exec, result.i); } break; case long_type: { resultValue = jsNumber(exec, result.j); } break; case float_type: { resultValue = jsNumber(exec, result.f); } break; case double_type: { resultValue = jsNumber(exec, result.d); } break; case array_type: { const char* arrayType = jMethod->returnType(); ASSERT(arrayType[0] == '['); resultValue = JavaArray::convertJObjectToArray(exec, result.l, arrayType, rootObject); } break; case invalid_type: { resultValue = jsUndefined(); } break; } return resultValue; }
JSValue *JavaInstance::invokeMethod (ExecState *exec, const MethodList &methodList, const ArgList &args) { int i, count = args.size(); jvalue *jArgs; JSValue *resultValue; Method *method = 0; size_t numMethods = methodList.size(); // Try to find a good match for the overloaded method. The // fundamental problem is that JavaScript doesn have the // notion of method overloading and Java does. We could // get a bit more sophisticated and attempt to does some // type checking as we as checking the number of parameters. Method *aMethod; for (size_t methodIndex = 0; methodIndex < numMethods; methodIndex++) { aMethod = methodList[methodIndex]; if (aMethod->numParameters() == count) { method = aMethod; break; } } if (method == 0) { JS_LOG ("unable to find an appropiate method\n"); return jsUndefined(); } const JavaMethod *jMethod = static_cast<const JavaMethod*>(method); JS_LOG ("call %s %s on %p\n", method->name(), jMethod->signature(), _instance->_instance); if (count > 0) { jArgs = (jvalue *)malloc (count * sizeof(jvalue)); } else jArgs = 0; for (i = 0; i < count; i++) { JavaParameter* aParameter = jMethod->parameterAt(i); jArgs[i] = convertValueToJValue (exec, args.at(i), aParameter->getJNIType(), aParameter->type()); JS_LOG("arg[%d] = %s\n", i, args.at(i)->toString(exec).ascii()); } jvalue result; // Try to use the JNI abstraction first, otherwise fall back to // nornmal JNI. The JNI dispatch abstraction allows the Java plugin // to dispatch the call on the appropriate internal VM thread. RootObject* rootObject = this->rootObject(); if (!rootObject) return jsUndefined(); bool handled = false; if (rootObject->nativeHandle()) { jobject obj = _instance->_instance; JSValue *exceptionDescription = NULL; const char *callingURL = 0; // FIXME, need to propagate calling URL to Java handled = dispatchJNICall(exec, rootObject->nativeHandle(), obj, jMethod->isStatic(), jMethod->JNIReturnType(), jMethod->methodID(obj), jArgs, result, callingURL, exceptionDescription); if (exceptionDescription) { throwError(exec, GeneralError, exceptionDescription->toString(exec)); free (jArgs); return jsUndefined(); } } // The following code can be conditionally removed once we have a Tiger update that // contains the new Java plugin. It is needed for builds prior to Tiger. if (!handled) { jobject obj = _instance->_instance; switch (jMethod->JNIReturnType()){ case void_type: callJNIMethodIDA<void>(obj, jMethod->methodID(obj), jArgs); break; case object_type: result.l = callJNIMethodIDA<jobject>(obj, jMethod->methodID(obj), jArgs); break; case boolean_type: result.z = callJNIMethodIDA<jboolean>(obj, jMethod->methodID(obj), jArgs); break; case byte_type: result.b = callJNIMethodIDA<jbyte>(obj, jMethod->methodID(obj), jArgs); break; case char_type: result.c = callJNIMethodIDA<jchar>(obj, jMethod->methodID(obj), jArgs); break; case short_type: result.s = callJNIMethodIDA<jshort>(obj, jMethod->methodID(obj), jArgs); break; case int_type: result.i = callJNIMethodIDA<jint>(obj, jMethod->methodID(obj), jArgs); break; case long_type: result.j = callJNIMethodIDA<jlong>(obj, jMethod->methodID(obj), jArgs); break; case float_type: result.f = callJNIMethodIDA<jfloat>(obj, jMethod->methodID(obj), jArgs); break; case double_type: result.d = callJNIMethodIDA<jdouble>(obj, jMethod->methodID(obj), jArgs); break; case invalid_type: default: break; } } switch (jMethod->JNIReturnType()){ case void_type: { resultValue = jsUndefined(); } break; case object_type: { if (result.l != 0) { const char *arrayType = jMethod->returnType(); if (arrayType[0] == '[') { resultValue = JavaArray::convertJObjectToArray(exec, result.l, arrayType, rootObject); } else { resultValue = Instance::createRuntimeObject(exec, JavaInstance::create(result.l, rootObject)); } } else { resultValue = jsUndefined(); } } break; case boolean_type: { resultValue = jsBoolean(result.z); } break; case byte_type: { resultValue = jsNumber(exec, result.b); } break; case char_type: { resultValue = jsNumber(exec, result.c); } break; case short_type: { resultValue = jsNumber(exec, result.s); } break; case int_type: { resultValue = jsNumber(exec, result.i); } break; case long_type: { resultValue = jsNumber(exec, result.j); } break; case float_type: { resultValue = jsNumber(exec, result.f); } break; case double_type: { resultValue = jsNumber(exec, result.d); } break; case invalid_type: default: { resultValue = jsUndefined(); } break; } free (jArgs); return resultValue; }