Value RuntimeObjectImp::get(ExecState *exec, const Identifier &propertyName) const
{
    Value result = Undefined();

    instance->begin();
    
    Class *aClass = instance->getClass();
    
    if (aClass) {
        
        // See if the instance have a field with the specified name.
        Field *aField = aClass->fieldNamed(propertyName.ascii(), instance);
        if (aField) {
            result = instance->getValueOfField (exec, aField); 
        }
        else {
            // Now check if a method with specified name exists, if so return a function object for
            // that method.
            MethodList methodList = aClass->methodsNamed(propertyName.ascii(), instance);
            if (methodList.length() > 0) {
                result = Object (new RuntimeMethodImp(exec, propertyName, methodList));
            }
        }
	
        if (result.type() == UndefinedType) {
            // Try a fallback object.
            result = aClass->fallbackObject (exec, instance, propertyName);
        }
    }
        
    instance->end();

    
    return result;
}
Beispiel #2
0
MethodList BalClass::methodsNamed(const Identifier& identifier, Instance* instance) const
{
    MethodList methodList;

    Method* method = m_methods.get(identifier.ustring().rep());
    if (method) {
        methodList.append(method);
        return methodList;
    }

    const char *ident = identifier.ascii();
    const BalInstance* inst = static_cast<const BalInstance*>(instance);
    BalObject* obj = inst->getObject();
    if( obj->hasMethod( ident ) )
    {
        Method* aMethod = new BalMethod(ident); // deleted in the CClass destructor
        {
            JSLock lock(false);
            m_methods.set(identifier.ustring().rep(), aMethod);
        }
        methodList.append(aMethod);
    }

    return methodList;
}
Beispiel #3
0
MethodList EAClass::methodsNamed(const Identifier& identifier, Instance* instance) const
{
    MethodList methodList;

    // Check to see if the method has been cached first.
    Method* method = mMethods.get(identifier.impl());
    if (method) 
    {
        methodList.append(method);
        return methodList;
    }

    // Method hasn't been called before, see if the object supports it.
    // Rather than doing identifier.ascii().data(), we need to create CString separately otherwise it goes out of scope.
	CString identStr = identifier.ascii();
	const char *ident = identStr.data(); 

    const EAInstance *inst = static_cast<const EAInstance*>(instance);
    EA::WebKit::IJSBoundObject *obj = inst->getObject();
    if (obj->hasMethod(ident)) 
    {
        // The object says it has this method, cache it so that the string
        // lookup can be avoided in the future.
        EAMethod* aMethod = new EAMethod(ident);
        {
            JSLock lock(SilenceAssertionsOnly);
            mMethods.set(identifier.impl(), aMethod);
        }
        methodList.append(aMethod);
    }

    return methodList;
}
Beispiel #4
0
MethodList BalClass::methodsNamed(const Identifier& identifier, Instance* instance) const
{
    MethodList methodList;

    Method* method = m_methods.get(identifier.ustring().rep());
    if (method) {
        methodList.append(method);
        return methodList;
    }

	const UChar* ident16 = identifier.ustring().data();
	char ident[256];
	sprintf(ident,"%S",ident16);
	ident[identifier.ustring().size()] = '\0';

    const BalInstance* inst = static_cast<const BalInstance*>(instance);
    BalObject* obj = inst->getObject();
    if( obj->hasMethod( ident ) )
    {
        BalMethod *aMethod= new BalMethod(obj, 0, ident, 0);
        m_methods.set(identifier.ustring().rep(), aMethod);
        methodList.append(aMethod);
    }

    return methodList;
}
JavaClass::JavaClass(jobject anInstance)
{
    jobject aClass = callJNIMethod<jobject>(anInstance, "getClass", "()Ljava/lang/Class;");

    if (!aClass) {
        LOG_ERROR("Unable to call getClass on instance %p", anInstance);
        m_name = fastStrDup("<Unknown>");
        return;
    }

    if (jstring className = (jstring)callJNIMethod<jobject>(aClass, "getName", "()Ljava/lang/String;")) {
        const char* classNameC = getCharactersFromJString(className);
        m_name = fastStrDup(classNameC);
        releaseCharactersForJString(className, classNameC);
    } else
        m_name = fastStrDup("<Unknown>");

    int i;
    JNIEnv* env = getJNIEnv();

    // Get the fields
    if (jarray fields = (jarray)callJNIMethod<jobject>(aClass, "getFields", "()[Ljava/lang/reflect/Field;")) {
        int numFields = env->GetArrayLength(fields);
        for (i = 0; i < numFields; i++) {
            jobject aJField = env->GetObjectArrayElement((jobjectArray)fields, i);
            JavaField* aField = new JavaField(env, aJField); // deleted in the JavaClass destructor
            {
                JSLock lock(SilenceAssertionsOnly);
                m_fields.set(((UString)aField->name()).rep(), aField);
            }
            env->DeleteLocalRef(aJField);
        }
        env->DeleteLocalRef(fields);
    }

    // Get the methods
    if (jarray methods = (jarray)callJNIMethod<jobject>(aClass, "getMethods", "()[Ljava/lang/reflect/Method;")) {
        int numMethods = env->GetArrayLength(methods);
        for (i = 0; i < numMethods; i++) {
            jobject aJMethod = env->GetObjectArrayElement((jobjectArray)methods, i);
            JavaMethod* aMethod = new JavaMethod(env, aJMethod); // deleted in the JavaClass destructor
            MethodList* methodList;
            {
                JSLock lock(SilenceAssertionsOnly);

                methodList = m_methods.get(((UString)aMethod->name()).rep());
                if (!methodList) {
                    methodList = new MethodList();
                    m_methods.set(((UString)aMethod->name()).rep(), methodList);
                }
            }
            methodList->append(aMethod);
            env->DeleteLocalRef(aJMethod);
        }
        env->DeleteLocalRef(methods);
    }

    env->DeleteLocalRef(aClass);
}
void Package::addMethod(Method *mtd)
{
	assert(mtd && "ERROR!!: Method is NULL\n");
	MethodList *list = (mtds->exists(mtd->subname)) ?
		mtds->get(mtd->subname) : new MethodList();
	list->add(mtd);
	mtds->add(MethodMap::value_type(mtd->subname, list));
}
JavaClassJobject::JavaClassJobject(jobject anInstance, bool requireAnnotation)
    : m_requireAnnotation(requireAnnotation)
#else
JavaClassJobject::JavaClassJobject(jobject anInstance)
#endif
{
    jobject aClass = callJNIMethod<jobject>(anInstance, "getClass", "()Ljava/lang/Class;");

    if (!aClass) {
        LOG_ERROR("unable to call getClass on instance %p", anInstance);
        return;
    }

    JNIEnv* env = getJNIEnv();

    // Get the fields
    jarray fields = static_cast<jarray>(callJNIMethod<jobject>(aClass, "getFields", "()[Ljava/lang/reflect/Field;"));
    int numFields = env->GetArrayLength(fields);
    for (int i = 0; i < numFields; i++) {
        jobject aJField = env->GetObjectArrayElement(static_cast<jobjectArray>(fields), i);
        JavaField* aField = new JavaFieldJobject(env, aJField); // deleted in the JavaClass destructor
        m_fields.set(aField->name(), aField);
        env->DeleteLocalRef(aJField);
    }

    // Get the methods
    jarray methods = static_cast<jarray>(callJNIMethod<jobject>(aClass, "getMethods", "()[Ljava/lang/reflect/Method;"));
    int numMethods = env->GetArrayLength(methods);
#if PLATFORM(ANDROID)
    jmethodID isAnnotationPresentMethodID = getAnnotationMethodID(env);
    if (!isAnnotationPresentMethodID) {
        LOG_ERROR("unable to find method %s on instance %p", kIsAnnotationPresent, anInstance);
        return;
    }
#endif
    for (int i = 0; i < numMethods; i++) {
        jobject aJMethod = env->GetObjectArrayElement(static_cast<jobjectArray>(methods), i);
#if PLATFORM(ANDROID)
        if (jsAccessAllowed(env, isAnnotationPresentMethodID, aJMethod)) {
#endif
            JavaMethod* aMethod = new JavaMethodJobject(env, aJMethod); // deleted in the JavaClass destructor
            MethodList* methodList = m_methods.get(aMethod->name());
            if (!methodList) {
                methodList = new MethodList();
                m_methods.set(aMethod->name(), methodList);
            }
            methodList->append(aMethod);
#if PLATFORM(ANDROID)
        }
#endif
        env->DeleteLocalRef(aJMethod);
    }
    env->DeleteLocalRef(fields);
    env->DeleteLocalRef(methods);
    env->DeleteLocalRef(aClass);
}
MethodList QtPixmapClass::methodsNamed(const Identifier& identifier, Instance*) const
{
    MethodList methods;
    if (identifier == QtPixmapToDataUrlMethod::name())
        methods.append(&qt_pixmap_metaData.toDataUrlMethod);
    else if (identifier == QtPixmapAssignToElementMethod::name())
        methods.append(&qt_pixmap_metaData.assignToElementMethod);
    else if (identifier == QtPixmapToStringMethod::name())
        methods.append(&qt_pixmap_metaData.toStringMethod);
    return methods;
}
Beispiel #9
0
JavaClass::JavaClass(jobject anInstance)
{
    jobject aClass = callJNIMethod<jobject>(anInstance, "getClass", "()Ljava/lang/Class;");
    
    if (!aClass) {
        fprintf(stderr, "%s:  unable to call getClass on instance %p\n", __PRETTY_FUNCTION__, anInstance);
        return;
    }
    
    jstring className = (jstring)callJNIMethod<jobject>(aClass, "getName", "()Ljava/lang/String;");
    const char *classNameC = getCharactersFromJString(className);
    _name = strdup(classNameC);
    releaseCharactersForJString(className, classNameC);

    int i;
    JNIEnv *env = getJNIEnv();

    JSGlobalData* globalData = WebCore::JSDOMWindow::commonJSGlobalData();
    
    // Get the fields
    jarray fields = (jarray)callJNIMethod<jobject>(aClass, "getFields", "()[Ljava/lang/reflect/Field;");
    int numFields = env->GetArrayLength(fields);    
    for (i = 0; i < numFields; i++) {
        jobject aJField = env->GetObjectArrayElement((jobjectArray)fields, i);
        Field *aField = new JavaField(env, aJField); // deleted in the JavaClass destructor
        {
            JSLock lock(false);
            _fields.set(Identifier(globalData, UString(aField->name())).ustring().rep(), aField);
        }
        env->DeleteLocalRef(aJField);
    }

    // Get the methods
    jarray methods = (jarray)callJNIMethod<jobject>(aClass, "getMethods", "()[Ljava/lang/reflect/Method;");
    int numMethods = env->GetArrayLength(methods);
    for (i = 0; i < numMethods; i++) {
        jobject aJMethod = env->GetObjectArrayElement((jobjectArray)methods, i);
        Method *aMethod = new JavaMethod(env, aJMethod); // deleted in the JavaClass destructor
        MethodList* methodList;
        {
            JSLock lock(false);

            methodList = _methods.get(Identifier(globalData, UString(aMethod->name())).ustring().rep());
            if (!methodList) {
                methodList = new MethodList();
                _methods.set(Identifier(globalData, UString(aMethod->name())).ustring().rep(), methodList);
            }
        }
        methodList->append(aMethod);
        env->DeleteLocalRef(aJMethod);
    }    
}
Beispiel #10
0
Method *Package::getMethod(const char *mtd_name)
{
	if (!mtds->size()) return NULL;
	MethodList *list = mtds->get(mtd_name);
	MethodList::reverse_iterator it = list->rbegin();
	Method *mtd = NULL;
	while (it != list->rend()) {
		mtd = *it;
		if (!mtd->ret) return mtd;
		it++;
	}
	return mtd;
}
Beispiel #11
0
MethodList QtPixmapClass::methodsNamed(PropertyName identifier, Instance*) const
{
    MethodList methods;
    UString ustring(identifier.publicName());
    if (ustring == QtPixmapToDataUrlMethod::name())
        methods.append(&qt_pixmap_metaData.toDataUrlMethod);
    else if (ustring == QtPixmapToImageDataMethod::name())
        methods.append(&qt_pixmap_metaData.toImageDataMethod);
    else if (ustring == QtPixmapAssignToElementMethod::name())
        methods.append(&qt_pixmap_metaData.assignToElementMethod);
    else if (ustring == QtPixmapToStringMethod::name())
        methods.append(&qt_pixmap_metaData.toStringMethod);
    return methods;
}
Beispiel #12
0
bool RuntimeObject::getOwnPropertyDescriptor(JSObject* object, ExecState *exec, PropertyName propertyName, PropertyDescriptor& descriptor)
{
    RuntimeObject* thisObject = jsCast<RuntimeObject*>(object);
    if (!thisObject->m_instance) {
        throwInvalidAccessError(exec);
        return false;
    }
    
    RefPtr<Instance> instance = thisObject->m_instance;
    instance->begin();
    
    Class *aClass = instance->getClass();
    
    if (aClass) {
        // See if the instance has a field with the specified name.
        Field *aField = aClass->fieldNamed(propertyName, instance.get());
        if (aField) {
            PropertySlot slot;
            slot.setCustom(thisObject, fieldGetter);
            instance->end();
            descriptor.setDescriptor(slot.getValue(exec, propertyName), DontDelete);
            return true;
        } else {
            // Now check if a method with specified name exists, if so return a function object for
            // that method.
            MethodList methodList = aClass->methodsNamed(propertyName, instance.get());
            if (methodList.size() > 0) {
                PropertySlot slot;
                slot.setCustom(thisObject, methodGetter);
                instance->end();
                descriptor.setDescriptor(slot.getValue(exec, propertyName), DontDelete | ReadOnly);
                return true;
            }
        }
        
        // Try a fallback object.
        if (!aClass->fallbackObject(exec, instance.get(), propertyName).isUndefined()) {
            PropertySlot slot;
            slot.setCustom(thisObject, fallbackObjectGetter);
            instance->end();
            descriptor.setDescriptor(slot.getValue(exec, propertyName), DontDelete | ReadOnly | DontEnum);
            return true;
        }
    }
    
    instance->end();
    
    return instance->getOwnPropertyDescriptor(thisObject, exec, propertyName, descriptor);
}
Beispiel #13
0
bool JavaNPObjectInvoke(NPObject* obj, NPIdentifier identifier, const NPVariant* args, uint32_t argCount, NPVariant* result)
{
    JavaInstance* instance = ExtractJavaInstance(obj);
    if (!instance)
        return false;
    NPUTF8* name = _NPN_UTF8FromIdentifier(identifier);
    if (!name)
        return false;
		
    instance->begin();

    MethodList methodList = instance->getClass()->methodsNamed(name);
    // TODO: use NPN_MemFree
    free(name);

    // 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 do some
    // type checking as well as checking the number of parameters.
    size_t numMethods = methodList.size();
    JavaMethod* aMethod;
    JavaMethod* jMethod = 0;
    for (size_t methodIndex = 0; methodIndex < numMethods; methodIndex++) {
        aMethod = methodList[methodIndex];
        if (aMethod->numParameters() == static_cast<int>(argCount)) {
            jMethod = aMethod;
            break;
        }
    }
    if (!jMethod) {
        instance->end();
        return false;
    }

    JavaValue* jArgs = new JavaValue[argCount];
    for (unsigned int i = 0; i < argCount; i++)
        jArgs[i] = convertNPVariantToJavaValue(args[i], jMethod->parameterAt(i));

    JavaValue jResult = instance->invokeMethod(jMethod, jArgs);
    instance->end();
    delete[] jArgs;

    VOID_TO_NPVARIANT(*result);
    convertJavaValueToNPVariant(jResult, result);
    return true;
}
void JavaClass::_commonInit (jobject aClass)
{
    long i;

    JNIEnv *env = getJNIEnv();
    
    // Get the fields
    jarray fields = (jarray)callJNIObjectMethod (aClass, "getFields", "()[Ljava/lang/reflect/Field;");
    long numFields = env->GetArrayLength (fields);    
    _fields = CFDictionaryCreateMutable(NULL, numFields, &kCFTypeDictionaryKeyCallBacks, NULL);
    for (i = 0; i < numFields; i++) {
        jobject aJField = env->GetObjectArrayElement ((jobjectArray)fields, i);
        Field *aField = new JavaField (env, aJField);
        CFStringRef fieldName = CFStringCreateWithCString(NULL, aField->name(), kCFStringEncodingASCII);
        CFDictionaryAddValue ((CFMutableDictionaryRef)_fields, fieldName, aField);
        CFRelease (fieldName);
        env->DeleteLocalRef (aJField);
    }
    
    // Get the methods
    jarray methods = (jarray)callJNIObjectMethod (aClass, "getMethods", "()[Ljava/lang/reflect/Method;");
    long numMethods = env->GetArrayLength (methods);    
    _methods = CFDictionaryCreateMutable(NULL, numMethods, &kCFTypeDictionaryKeyCallBacks, NULL);
    for (i = 0; i < numMethods; i++) {
        jobject aJMethod = env->GetObjectArrayElement ((jobjectArray)methods, i);
        Method *aMethod = new JavaMethod (env, aJMethod);
        CFStringRef methodName = CFStringCreateWithCString(NULL, aMethod->name(), kCFStringEncodingASCII);
        MethodList *methodList = (MethodList *)CFDictionaryGetValue ((CFMutableDictionaryRef)_methods, methodName);
        if (!methodList) {
            methodList = new MethodList();
            CFDictionaryAddValue ((CFMutableDictionaryRef)_methods, methodName, methodList);
        }
        methodList->addMethod (aMethod);
        CFRelease (methodName);
        env->DeleteLocalRef (aJMethod);
    }

    // Get the constructors
    jarray constructors = (jarray)callJNIObjectMethod (aClass, "getConstructors", "()[Ljava/lang/reflect/Constructor;");
    _numConstructors = env->GetArrayLength (constructors);    
    _constructors = new JavaConstructor[_numConstructors];
    for (i = 0; i < _numConstructors; i++) {
        jobject aConstructor = env->GetObjectArrayElement ((jobjectArray)constructors, i);
        _constructors[i] = JavaConstructor (env, aConstructor);
        env->DeleteLocalRef (aConstructor);
    }
}
Beispiel #15
0
bool RuntimeObject::getOwnPropertySlot(JSCell* cell, ExecState *exec, const Identifier& propertyName, PropertySlot& slot)
{
    RuntimeObject* thisObject = static_cast<RuntimeObject*>(cell);
    if (!thisObject->m_instance) {
        throwInvalidAccessError(exec);
        return false;
    }
    
    RefPtr<Instance> instance = thisObject->m_instance;

    instance->begin();
    
    Class *aClass = instance->getClass();
    
    if (aClass) {
        // See if the instance has a field with the specified name.
        Field *aField = aClass->fieldNamed(propertyName, instance.get());
        if (aField) {
            slot.setCustom(thisObject, thisObject->fieldGetter);
            instance->end();
            return true;
        } else {
            // Now check if a method with specified name exists, if so return a function object for
            // that method.
            MethodList methodList = aClass->methodsNamed(propertyName, instance.get());
            if (methodList.size() > 0) {
                slot.setCustom(thisObject, thisObject->methodGetter);
                
                instance->end();
                return true;
            }
        }

        // Try a fallback object.
        if (!aClass->fallbackObject(exec, instance.get(), propertyName).isUndefined()) {
            slot.setCustom(thisObject, thisObject->fallbackObjectGetter);
            instance->end();
            return true;
        }
    }
        
    instance->end();
    
    return instance->getOwnPropertySlot(thisObject, exec, propertyName, slot);
}
Beispiel #16
0
bool RuntimeObjectImp::getOwnPropertySlot(ExecState *exec, const Identifier& propertyName, PropertySlot& slot)
{
    if (!instance) {
        throwInvalidAccessError(exec);
        return false;
    }
    
    instance->begin();
    
    Class *aClass = instance->getClass();
    
    if (aClass) {
        // See if the instance has a field with the specified name.
        Field *aField = aClass->fieldNamed(propertyName, instance.get());
        if (aField) {
            slot.setCustom(this, fieldGetter);
            instance->end();
            return true;
        } else {
            // Now check if a method with specified name exists, if so return a function object for
            // that method.
            MethodList methodList = aClass->methodsNamed(propertyName, instance.get());
            if (methodList.size() > 0) {
                slot.setCustom(this, methodGetter);
                
                instance->end();
                return true;
            }
        }

        // Try a fallback object.
        if (!aClass->fallbackObject(exec, instance.get(), propertyName)->isUndefined()) {
            slot.setCustom(this, fallbackObjectGetter);
            instance->end();
            return true;
        }
    }
        
    instance->end();

    // don't call superclass, because runtime objects can't have custom properties or a prototype
    return false;
}
LuaExportTypeDescriptor::~LuaExportTypeDescriptor()
{
    //释放类方法
    for (MethodMap::iterator it = _classMethods.begin(); it != _classMethods.end(); it++)
    {
        MethodList methodList = it -> second;
        for (MethodList::iterator mit = methodList.begin(); mit != methodList.end(); mit++)
        {
            (*mit) -> release();
        }
    }
    
    //释放实例方法
    for (MethodMap::iterator it = _instanceMethods.begin(); it != _instanceMethods.end(); it++)
    {
        MethodList methodList = it -> second;
        for (MethodList::iterator mit = methodList.begin(); mit != methodList.end(); mit++)
        {
            (*mit) -> release();
        }
    }
    
    //释放属性
    for (PropertyMap::iterator it = _properties.begin(); it != _properties.end(); it++)
    {
        it -> second -> release();
    }
}
bool RuntimeObjectImp::hasProperty(ExecState *exec,
                            const Identifier &propertyName) const
{
    bool result = false;
    
    instance->begin();

    Field *aField = instance->getClass()->fieldNamed(propertyName.ascii(), instance);
    if (aField) {
        instance->end();
        return true;
    }
        
    MethodList methodList = instance->getClass()->methodsNamed(propertyName.ascii(), instance);

    instance->end();

    if (methodList.length() > 0)
        return true;

    return result;
}
JSValuePtr JavaInstance::invokeMethod (ExecState *exec, const MethodList &methodList, const ArgList &args)
{
    int i, count = args.size();
    jvalue *jArgs;
    JSValuePtr 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", UString(jMethod->name()).UTF8String().c_str(), 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(exec, i), aParameter->getJNIType(), aParameter->type());
        JS_LOG("arg[%d] = %s\n", i, args.at(exec, 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;
        JSValuePtr exceptionDescription = noValue();
        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 = JavaInstance::create(result.l, rootObject)->createRuntimeObject(exec);
                }
            }
            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;
}
Beispiel #20
0
bool JavaInstance::invokeMethod(const char* methodName, const NPVariant* args, uint32_t count, NPVariant* resultValue)
{
    int i;
    jvalue *jArgs;
    JavaMethod *method = 0;

    VOID_TO_NPVARIANT(*resultValue);

    MethodList methodList = getClass()->methodsNamed(methodName);

    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.
    JavaMethod *aMethod;
    for (size_t methodIndex = 0; methodIndex < numMethods; methodIndex++) {
        aMethod = methodList[methodIndex];
        if (aMethod->numParameters() == count) {
            method = aMethod;
            break;
        }
    }
    if (method == 0) {
        LOGW("unable to find an appropiate method\n");
        return false;
    }
    
    const JavaMethod *jMethod = static_cast<const JavaMethod*>(method);
    
    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] = convertNPVariantToJValue(args[i], aParameter->getJNIType(), aParameter->type());
    }
        
    jvalue result;

    // 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.
    {    
        jobject obj = getLocalRef();
        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;
        }
        getJNIEnv()->DeleteLocalRef(obj);
    }
    
    convertJValueToNPVariant(result, jMethod->JNIReturnType(), jMethod->returnType(), resultValue);
    free (jArgs);

    return true;
}
LuaExportMethodDescriptor* LuaExportTypeDescriptor::filterMethod(std::string const& methodName, LuaArgumentList arguments, bool isStatic)
{
    MethodList methodList;
    if (isStatic)
    {
        MethodMap::iterator mapIt = _classMethods.find(methodName);
        if (mapIt != _classMethods.end())
        {
            methodList = mapIt -> second;
        }
    }
    else
    {
        MethodMap::iterator mapIt = _instanceMethods.find(methodName);
        if (mapIt != _instanceMethods.end())
        {
            methodList = mapIt -> second;
        }
    }

    if (methodList.size() > 1)
    {
        LuaExportMethodDescriptor *targetMethod = NULL;
        
        int startIndex = isStatic ? 0 : 1;
        if (arguments.size() > startIndex)
        {
            //带参数
            std::deque<std::string> signList;
            std::string signListStr;
            std::string signStrRegexp;
            
            for (LuaArgumentList::iterator it = arguments.begin() + startIndex; it != arguments.end(); it++)
            {
                LuaValue *value = *it;
                switch (value -> getType())
                {
                    case LuaValueTypeNumber:
                        signList.push_back("N");
                        signListStr += "N";
                        signStrRegexp += "[fdcislqCISLQB@]";
                        break;
                    case LuaValueTypeBoolean:
                        signList.push_back("B");
                        signListStr += "B";
                        signStrRegexp += "[BcislqCISLQfd@]";
                        break;
                    case LuaValueTypeInteger:
                        signList.push_back("I");
                        signListStr += "I";
                        signStrRegexp += "[cislqCISLQfdB@]";
                        break;
                    default:
                        signList.push_back("O");
                        signListStr += "O";
                        signStrRegexp += "@";
                        break;
                }
            }
            
            std::string luaMethodSignStr = methodName  + "_" + signListStr;
            MappingMethodMap::iterator methodIt = _methodsMapping.find(luaMethodSignStr);
            
            if (methodIt == _methodsMapping.end())
            {
                //映射表无该方法,查找匹配方法
                MethodList matchMethods;
                std::regex regExp(signStrRegexp);
                
                for (MethodList::iterator methodIt = methodList.begin(); methodIt != methodList.end(); methodIt ++)
                {
                    LuaExportMethodDescriptor *methodDesc = *methodIt;
                    if (std::regex_match(methodDesc -> methodSignature(), regExp))
                    {
                        matchMethods.push_back(methodDesc);
                    }
                }
                
                if (matchMethods.size() > 0)
                {
                    //选择最匹配的方法
                    //备选方法,如果没有最匹配的情况下使用
                    LuaExportMethodDescriptor *alternateMethod = NULL;
                    for (MethodList::iterator methodIt = matchMethods.begin(); methodIt != matchMethods.end(); methodIt ++)
                    {
                        LuaExportMethodDescriptor *methodDesc = *methodIt;
                        bool hasMatch = true;
                        bool hasAlternate = false;
                        for (int i = 0; i < methodDesc -> methodSignature().length(); i++)
                        {
                            if (i < signList.size())
                            {
                                std::string luaSign = signList[i];
                                char nativeSign = methodDesc -> methodSignature()[i];
                                if (luaSign == "N" && nativeSign != 'f' && nativeSign != 'd')
                                {
                                    hasAlternate = true;
                                    luaSign = "I";
                                }
                                
                                if (luaSign == "B" && nativeSign != 'B')
                                {
                                    hasMatch = false;
                                    break;
                                }
                                
                                if (luaSign == "I" && nativeSign != 'c' && nativeSign != 'i' && nativeSign != 's' && nativeSign != 'l' && nativeSign != 'q'
                                    && nativeSign != 'C' && nativeSign != 'I' && nativeSign != 'S' && nativeSign != 'L' && nativeSign != 'Q')
                                {
                                    hasMatch = false;
                                    break;
                                }
                                
                                if (luaSign == "O" && nativeSign != '@')
                                {
                                    hasMatch = false;
                                    break;
                                }
                            }
                        }
                        
                        if (hasMatch)
                        {
                            if (hasAlternate)
                            {
                                //记录备选方法
                                alternateMethod = methodDesc;
                            }
                            else
                            {
                                //设置匹配方法
                                targetMethod = methodDesc;
                                break;
                            }
                        }
                    }
                    
                    if (targetMethod == NULL)
                    {
                        if (alternateMethod != NULL)
                        {
                            //使用备选方法
                            targetMethod = alternateMethod;
                        }
                        else
                        {
                            //没有最匹配则使用第一个方法
                            targetMethod = *(matchMethods.begin());
                        }
                    }
                    
                    //设置方法映射
                    _methodsMapping[luaMethodSignStr] = targetMethod;
                }
            }
            else
            {
                targetMethod = methodIt -> second;
            }
        }
        else
        {
            //不带参数
            for (MethodList::iterator it = methodList.begin(); it != methodList.end(); it++)
            {
                LuaExportMethodDescriptor *methodDesc = *it;
                if (methodDesc -> methodSignature() == "")
                {
                    targetMethod = methodDesc;
                    break;
                }
            }
        }
        
        return targetMethod;
    }
    else if (methodList.size() == 1)
    {
        return *(methodList.begin());
    }
    
    return NULL;
}