📄 support.c
字号:
/* * support.c * Native language support (excluding string routines). * * Copyright (c) 1996, 1997 * Transvirtual Technologies, Inc. All rights reserved. * * Copyright (c) 2002-2005 * Kaffe.org contributors. See ChangeLog for details. All rights reserved. * * See the file "license.terms" for information on usage and redistribution * of this file. */#include "debug.h"#include "config.h"#include "config-std.h"#include "config-mem.h"#include "jni.h"#include <stdarg.h>#include "errors.h"#include "jni_md.h"#include "kaffe/jmalloc.h"#include "gtypes.h"#include "access.h"#include "object.h"#include "constants.h"#include "baseClasses.h"#include "stringSupport.h"#include "lookup.h"#include "exception.h"#include "slots.h"#include "support.h"#include "classMethod.h"#include "machine.h"#include "md.h"#include "itypes.h"#include "external.h"#include "thread.h"#include "jthread.h"#include "locks.h"#include "methodcalls.h"#include "native.h"#include "jni_i.h"#include "soft.h"#if !defined(HAVE_GETTIMEOFDAY)#include <sys/timeb.h>#endif#define MAXEXCEPTIONLEN 200#define ERROR_SIGNATURE0 "()V"#define ERROR_SIGNATURE "(Ljava/lang/String;)V"/* Anchor point for user defined properties */userProperty* userProperties = NULL;/** * This function is an helper for lookupField. It creates a UTF string and invoke lookupField * with it. * * */Field* KNI_lookupFieldC(struct Hjava_lang_Class* clazz, const char* fieldName, bool isStatic, errorInfo* einfo){ Utf8Const *fieldUTF; Field *field; checkPtr(fieldUTF = utf8ConstFromString(fieldName)); field = lookupClassField(clazz, fieldUTF, isStatic, einfo); utf8ConstRelease(fieldUTF); return field;}/** * Call a Java method from native code. * * @param obj the obj or 0 if the method is static * @param method_name the name of the method to be called * @param signature the signature of the method to be called * @param mb pointer to the struct _jmethodID of the method to be called * @param isStaticCall true if the call is static, otherwise false * @param argptr va_list of the arguments to be passed to the method * * @throws NoSuchMethodError method was not found * @throws NullPointerException if obj is 0 but method is not static * * @return the return value of the method to be called */voiddo_execute_java_method_v(jvalue *retval, void* obj, const char* method_name, const char* signature, Method* mb, int isStaticCall, va_list argptr){ errorInfo info; if (obj == 0 && (! isStaticCall || ! mb)) { throwException(NullPointerException); } if (mb == 0) { assert(method_name != NULL); assert(signature != NULL); if (isStaticCall) { mb = lookupClassMethod((Hjava_lang_Class*)obj, method_name, signature, false, &info); } else { mb = lookupObjectMethod((Hjava_lang_Object*)obj, method_name, signature, &info); } } /* No method or wrong type - throw exception */ if (mb == 0) { throwError(&info); } else if (isStaticCall && (mb->accflags & ACC_STATIC) == 0) { throwException(NoSuchMethodError(method_name)); } else if (!isStaticCall && (mb->accflags & ACC_STATIC) != 0) { throwException(NoSuchMethodError(method_name)); } KaffeVM_callMethodV(mb, METHOD_NATIVECODE(mb), obj, argptr, retval);}/** * Call a Java method from native code. * * @param obj the obj or 0 if the method is static * @param method_name the name of the method to be called * @param signature the signature of the method to be called * @param mb pointer to the struct _jmethodID of the method to be called * @param isStaticCall true if the call is static, otherwise false * @param ... the arguments to be passed to the method * * @return the return value of the method to be called */voiddo_execute_java_method(jvalue *retval, void* obj, const char* method_name, const char* signature, Method* mb, int isStaticCall, ...){ va_list argptr; assert(method_name != 0 || mb != 0); va_start(argptr, isStaticCall); do_execute_java_method_v(retval, obj, method_name, signature, mb, isStaticCall, argptr); va_end(argptr);}/** * Call a Java static method on a class from native code. * * @param cname name of the class whose method is to be called * @param loader the class loader that's to be used to lookup the class * @param method_name the name of the method to be called * @param signature the signature of the method to be called * @param argptr the arguments to be passed to the method * * @throws NuSuchMethodError if method cannot be found * * @return the return value of the method */voiddo_execute_java_class_method_v(jvalue *retval, const char* cname, Hjava_lang_ClassLoader* loader, const char* method_name, const char* signature, va_list argptr){ Hjava_lang_Class* clazz; errorInfo info; Method* mb = NULL; char *buf; /* Convert "." to "/" and lookup class */ buf = checkPtr(KMALLOC(strlen(cname) + 1)); classname2pathname(cname, buf); clazz = lookupClass(buf, loader, &info); KFREE(buf); /* Get method */ if (clazz != NULL) { mb = lookupClassMethod(clazz, method_name, signature, false, &info); } if (mb == NULL) { throwError(&info); } /* Method must be static to invoke it here */ if ((mb->accflags & ACC_STATIC) == 0) { throwException(NoSuchMethodError(method_name)); } /* Make the call */ KaffeVM_callMethodV(mb, METHOD_NATIVECODE(mb), NULL, argptr, retval);}/** * Call a Java static method on a class from native code. * * @param cname name of the class whose method is to be called * @param loader the class loader that's to be used to lookup the class * @param method_name the name of the method to be called * @param signature the signature of the method to be called * @param ... the arguments to be passed to the method * * @return the return value of the method */voiddo_execute_java_class_method(jvalue *retval, const char* cname, Hjava_lang_ClassLoader*loader, const char* method_name, const char* signature, ...){ va_list argptr; va_start(argptr, signature); do_execute_java_class_method_v(retval, cname, loader, method_name, signature, argptr); va_end(argptr);}/** * Allocate an object and execute the constructor. * * @param cname the name of the class to be instantiated (may be 0 if cc is != 0) * @param loader the class loader that's to be used to lookup the class * @param cc the class to be instantiated (may be 0 if cname is != 0) * @param signature the signature of the constructor to be executed * @param argptr arguments to be passed to the constructor * * @throws InstantiationException if class is an interface or abstract * @throws NoSuchMethodError if the specified constructor cannot be found * * @return the newly allocated object */Hjava_lang_Object*execute_java_constructor_v(const char* cname, Hjava_lang_ClassLoader* loader, Hjava_lang_Class* cc, const char* signature, va_list argptr){ Hjava_lang_Object* obj; Method* mb; jvalue retval; errorInfo info; Utf8Const* sig; if (cc == 0) { char *buf; /* Convert "." to "/" and lookup class */ buf = checkPtr(KMALLOC(strlen(cname) + 1)); classname2pathname(cname, buf); cc = lookupClass(buf, loader, &info); KFREE(buf); if (!cc) { throwError(&info); } } /* We cannot construct interfaces or abstract classes */ if (CLASS_IS_INTERFACE(cc) || CLASS_IS_ABSTRACT(cc)) { throwException(InstantiationException(cc->name->data)); } if (cc->state < CSTATE_USABLE) { if (processClass(cc, CSTATE_COMPLETE, &info) == false) { throwError(&info); } } sig = checkPtr(utf8ConstFromString(signature)); mb = findMethodLocal(cc, constructor_name, sig); utf8ConstRelease(sig); if (mb == 0) { throwException(NoSuchMethodError(constructor_name->data)); } obj = newObject(cc); assert(obj != 0); /* Make the call */ KaffeVM_callMethodV(mb, METHOD_NATIVECODE(mb), obj, argptr, &retval); return (obj);}/** * Allocate an object and execute the constructor. * * @param cname the name of the class to be instantiated * @param loader the class loader that's to be used to lookup the class * @param cc the class to be instantiated * @param signature the signature of the constructor to be executed * @param ... arguments to be passed to the constructor * * @return the new allocated object */Hjava_lang_Object*execute_java_constructor(const char* cname, Hjava_lang_ClassLoader* loader, Hjava_lang_Class* cc, const char* signature, ...){ va_list argptr; Hjava_lang_Object* obj; va_start(argptr, signature); obj = execute_java_constructor_v(cname, loader, cc, signature, argptr); va_end(argptr); return (obj);}/** * Generic routine to call a native or Java method (array style). This is the exception-safe version of * KaffeVM_callMethodA. Exceptions are not thrown but caught the JNI way. This is useful for internal VM * functions which are not exception-safe. * * @param meth the struct _jmethodID of the method to be executed * @param func the code that's to be executed * @param obj the object whose method is to be called (my be 0 iff method is static) * @param args the arguments to be passed to the method * @param ret buffer for the return value of the method (may be 0 iff return type is void) * @param promoted true iff 64 bit values occupy two entries in args, otherwise false */voidKaffeVM_safeCallMethodA(Method* meth, void* func, void* obj, jvalue* args, jvalue* ret, int promoted){ BEGIN_EXCEPTION_HANDLING_VOID(); KaffeVM_callMethodA(meth, func, obj, args, ret, promoted); END_EXCEPTION_HANDLING();}/** * Generic routine to call a native or Java method (varargs style). This is the exception-safe version of * KaffeVM_callMethodV. Exceptions are not thrown but caught the JNI way. This is useful for internal VM * functions which are not exception-safe. * * @param meth the struct _jmethodID of the method to be executed * @param func the code that's to be executed * @param obj the object whose method is to be called (my be 0 iff method is static) * @param args the arguments to be passed to the method * @param ret buffer for the return value of the method (may be 0 iff return type is void) * @param promoted true iff 64 bit values occupy two entries in args, otherwise false */voidKaffeVM_safeCallMethodV(Method* meth, void* func, void* obj, va_list args, jvalue* ret){
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -