| //===---- JavaMetaJIT.cpp - Functions for Java internal objects -----------===// |
| // |
| // JnJVM |
| // |
| // This file is distributed under the University of Illinois Open Source |
| // License. See LICENSE.TXT for details. |
| // |
| //===----------------------------------------------------------------------===// |
| |
| #include <stdarg.h> |
| #include <string.h> |
| |
| #include "mvm/JIT.h" |
| #include "mvm/Method.h" |
| |
| #include "debug.h" |
| #include "JavaArray.h" |
| #include "JavaClass.h" |
| #include "JavaJIT.h" |
| #include "JavaObject.h" |
| #include "JavaThread.h" |
| #include "JavaTypes.h" |
| #include "Jnjvm.h" |
| #include "JnjvmModule.h" |
| |
| using namespace jnjvm; |
| |
| void JavaJIT::invokeOnceVoid(Jnjvm* vm, JnjvmClassLoader* loader, |
| char const* className, char const* func, |
| char const* sign, int access, ...) { |
| |
| UserCommonClass* cl = loader->loadName(loader->asciizConstructUTF8(className), |
| true, true); |
| |
| cl->initialiseClass(vm); |
| bool stat = access == ACC_STATIC ? true : false; |
| JavaMethod* method = cl->lookupMethod(loader->asciizConstructUTF8(func), |
| loader->asciizConstructUTF8(sign), stat, |
| true, 0); |
| va_list ap; |
| va_start(ap, access); |
| if (stat) { |
| method->invokeIntStaticAP(vm, (UserClass*)cl, ap); |
| } else { |
| JavaObject* obj = va_arg(ap, JavaObject*); |
| method->invokeIntSpecialAP(vm, (UserClass*)cl, obj, ap); |
| } |
| va_end(ap); |
| } |
| |
| |
| |
| |
| #define readArgs(buf, signature, ap) \ |
| for (std::vector<Typedef*>::iterator i = signature->args.begin(), \ |
| e = signature->args.end(); i!= e; i++) { \ |
| const Typedef* type = *i;\ |
| if (type->isPrimitive()){\ |
| const PrimitiveTypedef* prim = (PrimitiveTypedef*)type;\ |
| if (prim->isLong()){\ |
| ((sint64*)buf)[0] = va_arg(ap, sint64);\ |
| buf += 2;\ |
| } else if (prim->isInt()){ \ |
| ((sint32*)buf)[0] = va_arg(ap, sint32);\ |
| buf++; \ |
| } else if (prim->isChar()){ \ |
| ((uint32*)buf)[0] = va_arg(ap, uint32);\ |
| buf++; \ |
| } else if (prim->isShort()){ \ |
| ((uint32*)buf)[0] = va_arg(ap, uint32);\ |
| buf++; \ |
| } else if (prim->isByte()){ \ |
| ((uint32*)buf)[0] = va_arg(ap, uint32);\ |
| buf++; \ |
| } else if (prim->isBool()){ \ |
| ((uint32*)buf)[0] = va_arg(ap, uint32);\ |
| buf++;\ |
| } else if (prim->isFloat()){\ |
| ((float*)buf)[0] = (float)va_arg(ap, double);\ |
| buf++;\ |
| } else if (prim->isDouble()){\ |
| ((double*)buf)[0] = va_arg(ap, double);\ |
| buf += 2;\ |
| } else{\ |
| fprintf(stderr, "Can't happen");\ |
| abort();\ |
| }\ |
| } else{\ |
| ((JavaObject**)buf)[0] = va_arg(ap, JavaObject*);\ |
| buf++; \ |
| }\ |
| }\ |
| |
| |
| #if 1//defined(__PPC__) && !defined(__MACH__) |
| #define INVOKE(TYPE, TYPE_NAME, FUNC_TYPE_VIRTUAL_AP, FUNC_TYPE_STATIC_AP, FUNC_TYPE_VIRTUAL_BUF, FUNC_TYPE_STATIC_BUF) \ |
| \ |
| TYPE JavaMethod::invoke##TYPE_NAME##VirtualAP(Jnjvm* vm, UserClass* cl, JavaObject* obj, va_list ap) { \ |
| if (!cl->isReady()) { \ |
| cl->classLoader->loadName(cl->getName(), true, true); \ |
| cl->initialiseClass(vm); \ |
| } \ |
| verifyNull(obj); \ |
| Signdef* sign = getSignature(); \ |
| void** buf = (void**)alloca(sign->args.size() * sizeof(uint64)); \ |
| void* _buf = (void*)buf; \ |
| readArgs(buf, sign, ap); \ |
| void* func = (((void***)obj)[0])[offset];\ |
| return ((FUNC_TYPE_VIRTUAL_BUF)sign->getVirtualCallBuf())(vm, cl->getConstantPool(), func, obj, _buf);\ |
| }\ |
| \ |
| TYPE JavaMethod::invoke##TYPE_NAME##SpecialAP(Jnjvm* vm, UserClass* cl, JavaObject* obj, va_list ap) {\ |
| if (!cl->isReady()) { \ |
| cl->classLoader->loadName(cl->getName(), true, true); \ |
| cl->initialiseClass(vm); \ |
| } \ |
| \ |
| verifyNull(obj);\ |
| Signdef* sign = getSignature(); \ |
| void** buf = (void**)alloca(sign->args.size() * sizeof(uint64)); \ |
| void* _buf = (void*)buf; \ |
| readArgs(buf, sign, ap); \ |
| void* func = this->compiledPtr();\ |
| return ((FUNC_TYPE_VIRTUAL_BUF)sign->getVirtualCallBuf())(vm, cl->getConstantPool(), func, obj, _buf);\ |
| }\ |
| \ |
| TYPE JavaMethod::invoke##TYPE_NAME##StaticAP(Jnjvm* vm, UserClass* cl, va_list ap) {\ |
| if (!cl->isReady()) { \ |
| cl->classLoader->loadName(cl->getName(), true, true); \ |
| cl->initialiseClass(vm); \ |
| } \ |
| \ |
| Signdef* sign = getSignature(); \ |
| void** buf = (void**)alloca(sign->args.size() * sizeof(uint64)); \ |
| void* _buf = (void*)buf; \ |
| readArgs(buf, sign, ap); \ |
| void* func = this->compiledPtr();\ |
| return ((FUNC_TYPE_STATIC_BUF)sign->getStaticCallBuf())(vm, cl->getConstantPool(), func, _buf);\ |
| }\ |
| \ |
| TYPE JavaMethod::invoke##TYPE_NAME##VirtualBuf(Jnjvm* vm, UserClass* cl, JavaObject* obj, void* buf) {\ |
| if (!cl->isReady()) { \ |
| cl->classLoader->loadName(cl->getName(), true, true); \ |
| cl->initialiseClass(vm); \ |
| } \ |
| \ |
| verifyNull(obj);\ |
| \ |
| Signdef* sign = getSignature(); \ |
| void* func = (((void***)obj)[0])[offset];\ |
| return ((FUNC_TYPE_VIRTUAL_BUF)sign->getVirtualCallBuf())(vm, cl->getConstantPool(), func, obj, buf);\ |
| }\ |
| \ |
| TYPE JavaMethod::invoke##TYPE_NAME##SpecialBuf(Jnjvm* vm, UserClass* cl, JavaObject* obj, void* buf) {\ |
| if (!cl->isReady()) { \ |
| cl->classLoader->loadName(cl->getName(), true, true); \ |
| cl->initialiseClass(vm); \ |
| } \ |
| \ |
| verifyNull(obj);\ |
| void* func = this->compiledPtr();\ |
| Signdef* sign = getSignature(); \ |
| return ((FUNC_TYPE_VIRTUAL_BUF)sign->getVirtualCallBuf())(vm, cl->getConstantPool(), func, obj, buf);\ |
| }\ |
| \ |
| TYPE JavaMethod::invoke##TYPE_NAME##StaticBuf(Jnjvm* vm, UserClass* cl, void* buf) {\ |
| if (!cl->isReady()) { \ |
| cl->classLoader->loadName(cl->getName(), true, true); \ |
| cl->initialiseClass(vm); \ |
| } \ |
| \ |
| void* func = this->compiledPtr();\ |
| Signdef* sign = getSignature(); \ |
| return ((FUNC_TYPE_STATIC_BUF)sign->getStaticCallBuf())(vm, cl->getConstantPool(), func, buf);\ |
| }\ |
| \ |
| TYPE JavaMethod::invoke##TYPE_NAME##Virtual(Jnjvm* vm, UserClass* cl, JavaObject* obj, ...) { \ |
| va_list ap;\ |
| va_start(ap, obj);\ |
| TYPE res = invoke##TYPE_NAME##VirtualAP(vm, cl, obj, ap);\ |
| va_end(ap); \ |
| return res; \ |
| }\ |
| \ |
| TYPE JavaMethod::invoke##TYPE_NAME##Special(Jnjvm* vm, UserClass* cl, JavaObject* obj, ...) {\ |
| va_list ap;\ |
| va_start(ap, obj);\ |
| TYPE res = invoke##TYPE_NAME##SpecialAP(vm, cl, obj, ap);\ |
| va_end(ap); \ |
| return res; \ |
| }\ |
| \ |
| TYPE JavaMethod::invoke##TYPE_NAME##Static(Jnjvm* vm, UserClass* cl, ...) {\ |
| va_list ap;\ |
| va_start(ap, cl);\ |
| TYPE res = invoke##TYPE_NAME##StaticAP(vm, cl, ap);\ |
| va_end(ap); \ |
| return res; \ |
| }\ |
| |
| #else |
| |
| #define INVOKE(TYPE, TYPE_NAME, FUNC_TYPE_VIRTUAL_AP, FUNC_TYPE_STATIC_AP, FUNC_TYPE_VIRTUAL_BUF, FUNC_TYPE_STATIC_BUF) \ |
| \ |
| TYPE JavaMethod::invoke##TYPE_NAME##VirtualAP(Jnjvm* vm, UserClass* cl, JavaObject* obj, va_list ap) { \ |
| if (!cl->isReady()) { \ |
| cl->classLoader->loadName(cl->getName(), true, true); \ |
| cl->initialiseClass(vm); \ |
| } \ |
| \ |
| verifyNull(obj); \ |
| void* func = (((void***)obj)[0])[offset];\ |
| Signdef* sign = getSignature(); \ |
| return ((FUNC_TYPE_VIRTUAL_AP)sign->getVirtualCallAP())(vm, cl->getConstantPool(), func, obj, ap);\ |
| }\ |
| \ |
| TYPE JavaMethod::invoke##TYPE_NAME##SpecialAP(Jnjvm* vm, UserClass* cl, JavaObject* obj, va_list ap) {\ |
| if (!cl->isReady()) { \ |
| cl->classLoader->loadName(cl->getName(), true, true); \ |
| cl->initialiseClass(vm); \ |
| } \ |
| \ |
| verifyNull(obj);\ |
| void* func = this->compiledPtr();\ |
| Signdef* sign = getSignature(); \ |
| return ((FUNC_TYPE_VIRTUAL_AP)sign->getVirtualCallAP())(vm, cl->getConstantPool(), func, obj, ap);\ |
| }\ |
| \ |
| TYPE JavaMethod::invoke##TYPE_NAME##StaticAP(Jnjvm* vm, UserClass* cl, va_list ap) {\ |
| if (!cl->isReady()) { \ |
| cl->classLoader->loadName(cl->getName(), true, true); \ |
| cl->initialiseClass(vm); \ |
| } \ |
| \ |
| void* func = this->compiledPtr();\ |
| Signdef* sign = getSignature(); \ |
| return ((FUNC_TYPE_STATIC_AP)sign->getStaticCallAP())(vm, cl->getConstantPool(), func, ap);\ |
| }\ |
| \ |
| TYPE JavaMethod::invoke##TYPE_NAME##VirtualBuf(Jnjvm* vm, UserClass* cl, JavaObject* obj, void* buf) {\ |
| if (!cl->isReady()) { \ |
| cl->classLoader->loadName(cl->getName(), true, true); \ |
| cl->initialiseClass(vm); \ |
| } \ |
| \ |
| verifyNull(obj);\ |
| void* func = (((void***)obj)[0])[offset];\ |
| Signdef* sign = getSignature(); \ |
| return ((FUNC_TYPE_VIRTUAL_BUF)sign->getVirtualCallBuf())(vm, cl->getConstantPool(), func, obj, buf);\ |
| }\ |
| \ |
| TYPE JavaMethod::invoke##TYPE_NAME##SpecialBuf(Jnjvm* vm, UserClass* cl, JavaObject* obj, void* buf) {\ |
| if (!cl->isReady()) { \ |
| cl->classLoader->loadName(cl->getName(), true, true); \ |
| cl->initialiseClass(vm); \ |
| } \ |
| \ |
| verifyNull(obj);\ |
| void* func = this->compiledPtr();\ |
| Signdef* sign = getSignature(); \ |
| return ((FUNC_TYPE_VIRTUAL_BUF)sign->getVirtualCallBuf())(vm, cl->getConstantPool(), func, obj, buf);\ |
| }\ |
| \ |
| TYPE JavaMethod::invoke##TYPE_NAME##StaticBuf(Jnjvm* vm, UserClass* cl, void* buf) {\ |
| if (!cl->isReady()) { \ |
| cl->classLoader->loadName(cl->getName(), true, true); \ |
| cl->initialiseClass(vm); \ |
| } \ |
| \ |
| void* func = this->compiledPtr();\ |
| Signdef* sign = getSignature(); \ |
| return ((FUNC_TYPE_STATIC_BUF)sign->getStaticCallBuf())(vm, cl->getConstantPool(), func, buf);\ |
| }\ |
| \ |
| TYPE JavaMethod::invoke##TYPE_NAME##Virtual(Jnjvm* vm, UserClass* cl, JavaObject* obj, ...) { \ |
| va_list ap;\ |
| va_start(ap, obj);\ |
| TYPE res = invoke##TYPE_NAME##VirtualAP(vm, cl, obj, ap);\ |
| va_end(ap); \ |
| return res; \ |
| }\ |
| \ |
| TYPE JavaMethod::invoke##TYPE_NAME##Special(Jnjvm* vm, UserClass* cl, JavaObject* obj, ...) {\ |
| va_list ap;\ |
| va_start(ap, obj);\ |
| TYPE res = invoke##TYPE_NAME##SpecialAP(vm, cl, obj, ap);\ |
| va_end(ap); \ |
| return res; \ |
| }\ |
| \ |
| TYPE JavaMethod::invoke##TYPE_NAME##Static(Jnjvm* vm, UserClass* cl, ...) {\ |
| va_list ap;\ |
| va_start(ap, cl);\ |
| TYPE res = invoke##TYPE_NAME##StaticAP(vm, cl, ap);\ |
| va_end(ap); \ |
| return res; \ |
| }\ |
| |
| #endif |
| |
| typedef uint32 (*uint32_virtual_ap)(Jnjvm*, UserConstantPool*, void*, JavaObject*, va_list); |
| typedef sint64 (*sint64_virtual_ap)(Jnjvm*, UserConstantPool*, void*, JavaObject*, va_list); |
| typedef float (*float_virtual_ap)(Jnjvm*, UserConstantPool*, void*, JavaObject*, va_list); |
| typedef double (*double_virtual_ap)(Jnjvm*, UserConstantPool*, void*, JavaObject*, va_list); |
| typedef JavaObject* (*object_virtual_ap)(Jnjvm*, UserConstantPool*, void*, JavaObject*, va_list); |
| |
| typedef uint32 (*uint32_static_ap)(Jnjvm*, UserConstantPool*, void*, va_list); |
| typedef sint64 (*sint64_static_ap)(Jnjvm*, UserConstantPool*, void*, va_list); |
| typedef float (*float_static_ap)(Jnjvm*, UserConstantPool*, void*, va_list); |
| typedef double (*double_static_ap)(Jnjvm*, UserConstantPool*, void*, va_list); |
| typedef JavaObject* (*object_static_ap)(Jnjvm*, UserConstantPool*, void*, va_list); |
| |
| typedef uint32 (*uint32_virtual_buf)(Jnjvm*, UserConstantPool*, void*, JavaObject*, void*); |
| typedef sint64 (*sint64_virtual_buf)(Jnjvm*, UserConstantPool*, void*, JavaObject*, void*); |
| typedef float (*float_virtual_buf)(Jnjvm*, UserConstantPool*, void*, JavaObject*, void*); |
| typedef double (*double_virtual_buf)(Jnjvm*, UserConstantPool*, void*, JavaObject*, void*); |
| typedef JavaObject* (*object_virtual_buf)(Jnjvm*, UserConstantPool*, void*, JavaObject*, void*); |
| |
| typedef uint32 (*uint32_static_buf)(Jnjvm*, UserConstantPool*, void*, void*); |
| typedef sint64 (*sint64_static_buf)(Jnjvm*, UserConstantPool*, void*, void*); |
| typedef float (*float_static_buf)(Jnjvm*, UserConstantPool*, void*, void*); |
| typedef double (*double_static_buf)(Jnjvm*, UserConstantPool*, void*, void*); |
| typedef JavaObject* (*object_static_buf)(Jnjvm*, UserConstantPool*, void*, void*); |
| |
| INVOKE(uint32, Int, uint32_virtual_ap, uint32_static_ap, uint32_virtual_buf, uint32_static_buf) |
| INVOKE(sint64, Long, sint64_virtual_ap, sint64_static_ap, sint64_virtual_buf, sint64_static_buf) |
| INVOKE(float, Float, float_virtual_ap, float_static_ap, float_virtual_buf, float_static_buf) |
| INVOKE(double, Double, double_virtual_ap, double_static_ap, double_virtual_buf, double_static_buf) |
| INVOKE(JavaObject*, JavaObject, object_virtual_ap, object_static_ap, object_virtual_buf, object_static_buf) |
| |
| #undef INVOKE |