📄 support.c
字号:
#if defined(TRANSLATOR) call.function = func; /* GCDIAG wipes free memory with 0xf4... */ assert(call.function); assert(*(uint32*)(call.function) != 0xf4f4f4f4); /* Make the call - system dependent */ sysdepCallMethod(&call);#endif#if defined(INTERPRETER) if ((meth->accflags & ACC_NATIVE) == 0) { virtualMachine(meth, (slots*)call.args, (slots*)call.ret, THREAD_DATA()); } else { Hjava_lang_Object* syncobj = 0; VmExceptHandler mjbuf; threadData* thread_data = THREAD_DATA(); if (meth->accflags & ACC_SYNCHRONISED) { if (meth->accflags & ACC_STATIC) { syncobj = &meth->class->head; } else { syncobj = (Hjava_lang_Object*)call.args[0].l; } lockObject(syncobj); } setupExceptionHandling(&mjbuf, meth, syncobj, thread_data); /* Make the call - system dependent */ sysdepCallMethod(&call); if (syncobj != 0) { unlockObject(syncobj); } cleanupExceptionHandling(&mjbuf, thread_data); }#endif if (!promoted && call.retsize == 1) { switch (call.rettype) { case 'Z': ret->z = ret->i; break; case 'S': ret->s = ret->i; break; case 'B': ret->b = ret->i; break; case 'C': ret->c = ret->i; break; } }}/** * Generic routine to call a native or Java method (varargs style). * * @param meth the struct _methods 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) */voidcallMethodV(Method* meth, void* func, void* obj, va_list args, jvalue* ret){ /* const char* sig; FIXME */ int i; int s; int j; /* XXX call.callsize and call.calltype arrays are statically sized and are not checked for running out of bounds */ callMethodInfo call; jvalue in[MAXMARGS]; jvalue tmp; if (ret == 0) { ret = &tmp; } i = 0; s = 0;#if defined(INTERPRETER) meth = (Method*)func; if (meth->accflags & ACC_NATIVE) { if (METHOD_NATIVECODE(meth) == 0) { errorInfo info; if (native(meth, &info) == false) { throwError(&info); } } call.function = METHOD_NATIVECODE(meth); } /* Insert the JNI environment */ if (meth->accflags & ACC_JNI) { call.callsize[i] = PTR_TYPE_SIZE / SIZEOF_INT; call.calltype[i] = 'L'; in[i].l = THREAD_JNIENV(); s += call.callsize[i]; i++; /* If method is static we must insert the class as an * argument */ if (meth->accflags & ACC_STATIC) { call.callsize[i] = PTR_TYPE_SIZE / SIZEOF_INT; s += call.callsize[i]; call.calltype[i] = 'L'; in[i].l = meth->class; i++; } }#endif /* If this method isn't static, we must insert the object as * the first argument and get the function code. */ if ((meth->accflags & ACC_STATIC) == 0) { call.callsize[i] = PTR_TYPE_SIZE / SIZEOF_INT; s += call.callsize[i]; call.calltype[i] = 'L'; in[i].l = obj; i++; } for (j = 0; j < METHOD_NARGS(meth); i++, j++) { call.calltype[i] = *METHOD_ARG_TYPE(meth, j); switch (call.calltype[i]) { case 'I': case 'Z': case 'S': case 'B': case 'C': call.callsize[i] = 1; in[i].PROM_i = va_arg(args, jint); break; case 'F': call.callsize[i] = 1; in[i].PROM_f = (jfloat)va_arg(args, jdouble);#if PROMOTE_jfloat2jdouble call.calltype[i] = 'D';#endif break; case 'D': call.callsize[i] = 2; ENSURE_ALIGN64({}); in[i].d = va_arg(args, jdouble); goto second_word; case 'J': call.callsize[i] = 2; ENSURE_ALIGN64({}); in[i].j = va_arg(args, jlong); second_word:#if ! NO_HOLES s += call.callsize[i]; in[i+1].i = (&in[i].i)[1]; i++; call.callsize[i] = 0;#endif break; case '[': call.calltype[i] = 'L'; /* fall through */ case 'L': call.callsize[i] = PTR_TYPE_SIZE / SIZEOF_INT; in[i].l = va_arg(args, jref); break; default: ABORT(); } s += call.callsize[i]; }#if defined(STACK_LIMIT) call.calltype[i] = 'L'; call.callsize[i] = PTR_TYPE_SIZE / SIZEOF_INT; in[i].l = jthread_stacklimit(); s += PTR_TYPE_SIZE / SIZEOF_INT; i++;#endif /* Return info */ call.rettype = *METHOD_RET_TYPE(meth); switch (call.rettype) { case '[': call.rettype = 'L'; /* fall through */ case 'L': call.retsize = PTR_TYPE_SIZE / SIZEOF_INT; break; case 'V': call.retsize = 0; break; case 'D': case 'J': call.retsize = 2; break; default: call.retsize = 1; break; } /* Call info and arguments */ call.nrargs = i; call.argsize = s; call.args = in; call.ret = ret;#if defined(TRANSLATOR) call.function = func; /* GCDIAG wipes free memory with 0xf4... */ assert(call.function); assert(*(uint32*)(call.function) != 0xf4f4f4f4); /* Make the call - system dependent */ sysdepCallMethod(&call);#endif#if defined(INTERPRETER) if ((meth->accflags & ACC_NATIVE) == 0) { virtualMachine(meth, (slots*)call.args, (slots*)call.ret, THREAD_DATA()); } else { Hjava_lang_Object* syncobj = 0; VmExceptHandler mjbuf; threadData* thread_data = THREAD_DATA(); if (meth->accflags & ACC_SYNCHRONISED) { if (meth->accflags & ACC_STATIC) { syncobj = &meth->class->head; } else { syncobj = (Hjava_lang_Object*)call.args[0].l; } lockObject(syncobj); } setupExceptionHandling(&mjbuf, meth, syncobj, thread_data); /* Make the call - system dependent */ sysdepCallMethod(&call); if (syncobj != 0) { unlockObject(syncobj); } cleanupExceptionHandling(&mjbuf, thread_data); }#endif}/** * Lookup a method given class, name and signature. * * @param cls the class where to start search * @param name name of the method being searched * @param sig signature of the method being searched * @param einfo struct errorInfo * * @throws OutOfMemoryError * * @return struct _methods of the method being searched or 0 in case of an error */Method*lookupClassMethod(Hjava_lang_Class* cls, const char* name, const char* sig, errorInfo *einfo){ Method *meth; Utf8Const *name_utf8, *sig_utf8; assert(cls != 0 && name != 0 && sig != 0); name_utf8 = utf8ConstNew(name, -1); if (!name_utf8) { postOutOfMemory(einfo); return 0; } sig_utf8 = utf8ConstNew(sig, -1); if (!sig_utf8) { utf8ConstRelease(name_utf8); postOutOfMemory(einfo); return 0; } meth = findMethod(cls, name_utf8, sig_utf8, einfo); utf8ConstRelease(name_utf8); utf8ConstRelease(sig_utf8); return(meth);}/** * Lookup a method given object, name and signature. * * @param obj the object where to start search * @param name name of the method being searched * @param sig signature of the method being searched * @param einfo struct errorInfo * * @return struct _methods of the method being searched or 0 in case of an error */Method*lookupObjectMethod(Hjava_lang_Object* obj, const char* name, const char* sig, errorInfo *einfo){ assert(obj != 0 && name != 0 && sig != 0); return (lookupClassMethod(OBJECT_CLASS(obj), name, sig, einfo));}/** * Signal an error by creating the object and throwing the exception. * See also SignalErrorf * * @param cname the name of the class of the exception object to be created * @param str the message to be passed to the constructor of the exception object */voidSignalError(const char* cname, const char* str){ Hjava_lang_Throwable* obj; if (str == NULL || *str == '\0') { obj = (Hjava_lang_Throwable*)execute_java_constructor(cname, 0, 0, ERROR_SIGNATURE0); } else { obj = (Hjava_lang_Throwable*)execute_java_constructor(cname, 0, 0, ERROR_SIGNATURE, checkPtr(stringC2Java(str))); } throwException(obj);}/** * Signal an error by creating the object and throwing the exception. * allows for printf-like msg format with additional parameters. * * @param cname the name of the class of the exception object to be created * @param fmt the printf like format of the message * @param ... the parameters necessary for the message format denoted by fmt */voidSignalErrorf(const char* cname, const char* fmt, ...){ errorInfo info; va_list args; va_start(args, fmt); vpostExceptionMessage(&info, cname, fmt, args); va_end(args); throwError(&info);}static voidreplacechar(const char* from, char* to, char old, char new){ int i; /* Convert any 'old' in name to 'new' */ for (i = 0; from[i] != 0; i++) { if (from[i] == old) { to[i] = new; } else { to[i] = from[i]; } } to[i] = 0;}/** * Convert a class name to a path name. * * @param from points to the class name * @param to points to path name */voidclassname2pathname(const char* from, char* to){ replacechar(from, to, '.', '/');}/** * Convert a path name to a class name. * * @param from points to the path name * @param to points to the class name */voidpathname2classname(const char* from, char* to){ replacechar(from, to, '/', '.');}/** * Return current time in milliseconds. */jlongcurrentTime(void){ jlong tme;#if defined(HAVE_GETTIMEOFDAY) struct timeval tm; gettimeofday(&tm, 0); tme = (((jlong)tm.tv_sec * (jlong)1000) + ((jlong)tm.tv_usec / (jlong)1000));#elif defined(HAVE_FTIME) struct timeb tm; ftime(&tm); tme = (((jlong)tm.time * (jlong)1000) + (jlong)tm.millitm);#elif defined(HAVE__FTIME) struct timeb tm; _ftime(&tm); tme = (((jlong)tm.time * (jlong)1000) + (jlong)tm.millitm);#elif defined(HAVE_TIME) tme = (jlong)1000 * (jlong)time(0);#else tme = 0;#endif return (tme);}/** * Set a property to a value. * * @param properties pointer to the properties object whose contents are to be modified * @param key the key of the property to be set * @param value the value of the property to be set */voidsetProperty(void* properties, char* key, char* value){ Hjava_lang_String* jkey; Hjava_lang_String* jvalue; jkey = checkPtr(stringC2Java(key)); jvalue = checkPtr(stringC2Java(value)); do_execute_java_method(properties, "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", 0, false, jkey, jvalue);}/** * Allocate a new object of the given class name. * * @param classname the name of the class to be instantiated * @param loader the loader to be used to lookup the class * * @return the newly allocated object */Hjava_lang_Object*AllocObject(const char* classname, Hjava_lang_ClassLoader* loader){ Hjava_lang_Class* clazz; errorInfo info; clazz = lookupClass(classname, loader, &info); if (clazz == 0) { throwError(&info); } return (newObject(clazz));}/** * Allocate a new array of a given size and type. * * @param len the size of the array * @param type the type of the elements of the array. * * @return the new allocated array */Hjava_lang_Object*AllocArray(int len, int type){ return (newArray(TYPE_CLASS(type), len));}/** * Allocate a new array of the given size and class name. * * @param sz the size of the array * @param classname name of the class of the elements * @param loader the class loader to be used to lookup the class * * @return the newly allocated array * * @throws NegativeArraySizeException iff the size<0 */Hjava_lang_Object*AllocObjectArray(int sz, const char* classname, Hjava_lang_ClassLoader* loader){ Hjava_lang_Class *elclass; errorInfo info; if (sz < 0) { throwException(NegativeArraySizeException); } elclass = getClassFromSignature(classname, loader, &info); if (elclass == 0) { throwError(&info); } return (newArray(elclass, sz));}/** * Used to generate exception for unimplemented features. * * @param mess the message to be displayed * * @throws an InternalError */voidunimp(const char* mess){ SignalError("java.lang.InternalError", mess);}/** * Print messages. * * @param out the FILE* to write the message to * @param mess the printf like format of the message * @param ... the parameters needed for the format */voidkprintf(FILE* out, const char* mess, ...){ va_list argptr; va_start(argptr, mess); vfprintf(out, mess, argptr); va_end(argptr);}/** * Enter/leave critical region. This interface is exported to * native libraries to protect calls to non-reentrant functions. * It works as a global masterlock for C libraries that are not * thread-safe. */void enterUnsafeRegion(void){ jthread_spinon(0);}void leaveUnsafeRegion(void){ jthread_spinoff(0);}/* XXX Ick */int bitCount(int bits){ int lpc, retval = 0; for( lpc = 0; lpc < (sizeof(int) * 8); lpc++ ) { if( (1L << lpc) & bits ) retval++; } return( retval );}#if defined(NO_SHARED_LIBRARIES)/** * Register an user function statically linked in the binary. */voidaddNativeMethod(const char* name, void* func){ static int funcs_nr = 0; static int funcs_max = 0; /* If we run out of space, reallocate */ if (funcs_nr + 1 >= funcs_max) { funcs_max += NATIVE_FUNC_INCREMENT; if (native_funcs != null_funcs) { native_funcs = KREALLOC(native_funcs, funcs_max * sizeof(nativeFunction)); } else { native_funcs = KMALLOC(NATIVE_FUNC_INCREMENT * sizeof(nativeFunction)); } } native_funcs[funcs_nr].name = KMALLOC(strlen(name) + 1); strcpy(native_funcs[funcs_nr].name, name); native_funcs[funcs_nr].func = func; funcs_nr++; native_funcs[funcs_nr].name = 0; native_funcs[funcs_nr].func = 0;}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -