blob: fe2efa71d8a1444694e8da6ca4de5a75e3d8cd88 [file] [log] [blame]
//===-------- Precompiled.cpp - Support for precompiled code --------------===//
//
// The VMKit project
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// for dlopen and dlsym
#include <dlfcn.h>
#include "vmkit/MethodInfo.h"
#include "JavaClass.h"
#include "JavaUpcalls.h"
#include "JnjvmClassLoader.h"
#include "Jnjvm.h"
#include "LockedMap.h"
namespace j3 {
typedef void (*static_init_t)(JnjvmClassLoader*);
void JnjvmClassLoader::insertAllMethodsInVM(Jnjvm* vm) {
UNIMPLEMENTED();
}
void JnjvmClassLoader::loadLibFromJar(Jnjvm* vm, const char* name,
const char* file) {
vmkit::ThreadAllocator threadAllocator;
char* soName = (char*)threadAllocator.Allocate(
strlen(name) + strlen(DYLD_EXTENSION));
const char* ptr = strrchr(name, '/');
sprintf(soName, "%s%s", ptr ? ptr + 1 : name, DYLD_EXTENSION);
void* handle = dlopen(soName, RTLD_LAZY | RTLD_LOCAL);
if (handle) {
Class* cl = (Class*)dlsym(handle, file);
if (cl) {
static_init_t init = (static_init_t)(word_t)cl->classLoader;
assert(init && "Loaded the wrong library");
init(this);
insertAllMethodsInVM(vm);
}
}
}
void JnjvmClassLoader::loadLibFromFile(Jnjvm* vm, const char* name) {
vmkit::ThreadAllocator threadAllocator;
assert(classes->map.size() == 0);
char* soName = (char*)threadAllocator.Allocate(
strlen(name) + strlen(DYLD_EXTENSION));
sprintf(soName, "%s%s", name, DYLD_EXTENSION);
void* handle = dlopen(soName, RTLD_LAZY | RTLD_LOCAL);
if (handle) {
Class* cl = (Class*)dlsym(handle, name);
if (cl) {
static_init_t init = (static_init_t)(word_t)cl->classLoader;
init(this);
insertAllMethodsInVM(vm);
}
}
}
Class* JnjvmClassLoader::loadClassFromSelf(Jnjvm* vm, const char* name) {
assert(classes->map.size() == 0);
Class* cl = (Class*)dlsym(SELF_HANDLE, name);
if (cl) {
static_init_t init = (static_init_t)(word_t)cl->classLoader;
init(this);
insertAllMethodsInVM(vm);
}
return cl;
}
// Extern "C" functions called by the vmjc static intializer.
extern "C" void vmjcAddPreCompiledClass(JnjvmClassLoader* JCL,
CommonClass* cl) {
cl->classLoader = JCL;
}
extern "C" void vmjcAddString(const char* str) {
UNIMPLEMENTED();
}
extern "C" void vmjcGetClassArray(JnjvmClassLoader* JCL, ClassArray** ptr,
const UTF8* name) {
*ptr = JCL->constructArray(name);
}
extern "C" word_t vmjcNativeLoader(JavaMethod* meth) {
bool j3 = false;
const UTF8* jniConsClName = meth->classDef->name;
const UTF8* jniConsName = meth->name;
const UTF8* jniConsType = meth->type;
sint32 clen = jniConsClName->size;
sint32 mnlen = jniConsName->size;
sint32 mtlen = jniConsType->size;
vmkit::ThreadAllocator threadAllocator;
char* buf = (char*)threadAllocator.Allocate(
3 + JNI_NAME_PRE_LEN + 1 + ((mnlen + clen + mtlen) << 3));
word_t res = meth->classDef->classLoader->nativeLookup(meth, j3, buf);
assert(res && "Could not find required native method");
return res;
}
extern "C" void staticCallback() {
fprintf(stderr, "Implement me");
abort();
}
bool Precompiled::Init(JnjvmBootstrapLoader* loader) {
Class* javaLangObject = (Class*)dlsym(SELF_HANDLE, "java_lang_Object");
void* nativeHandle = vmkit::System::GetSelfHandle();
if (javaLangObject == NULL) {
void* handle = dlopen("libvmjc"DYLD_EXTENSION, RTLD_LAZY | RTLD_GLOBAL);
if (handle != NULL) {
nativeHandle = handle;
javaLangObject = (Class*)dlsym(nativeHandle, "java_lang_Object");
}
}
if (javaLangObject == NULL) {
return false;
}
ClassArray::SuperArray = javaLangObject;
// Get the native classes.
Classpath* upcalls = loader->upcalls;
upcalls->OfVoid = (ClassPrimitive*)dlsym(nativeHandle, "void");
upcalls->OfBool = (ClassPrimitive*)dlsym(nativeHandle, "boolean");
upcalls->OfByte = (ClassPrimitive*)dlsym(nativeHandle, "byte");
upcalls->OfChar = (ClassPrimitive*)dlsym(nativeHandle, "char");
upcalls->OfShort = (ClassPrimitive*)dlsym(nativeHandle, "short");
upcalls->OfInt = (ClassPrimitive*)dlsym(nativeHandle, "int");
upcalls->OfFloat = (ClassPrimitive*)dlsym(nativeHandle, "float");
upcalls->OfLong = (ClassPrimitive*)dlsym(nativeHandle, "long");
upcalls->OfDouble = (ClassPrimitive*)dlsym(nativeHandle, "double");
upcalls->OfVoid->classLoader = loader;
upcalls->OfBool->classLoader = loader;
upcalls->OfByte->classLoader = loader;
upcalls->OfChar->classLoader = loader;
upcalls->OfShort->classLoader = loader;
upcalls->OfInt->classLoader = loader;
upcalls->OfFloat->classLoader = loader;
upcalls->OfLong->classLoader = loader;
upcalls->OfDouble->classLoader = loader;
vmkit::VmkitDenseSet<vmkit::UTF8MapKey, const UTF8*>* precompiledUTF8Map =
reinterpret_cast<vmkit::VmkitDenseSet<vmkit::UTF8MapKey, const UTF8*>*>(dlsym(nativeHandle, "UTF8Map"));
loader->hashUTF8 = new (loader->allocator, "UTF8Map") UTF8Map(loader->allocator, precompiledUTF8Map);
vmkit::VmkitDenseMap<const UTF8*, CommonClass*>* precompiledClassMap =
reinterpret_cast<vmkit::VmkitDenseMap<const UTF8*, CommonClass*>*>(dlsym(nativeHandle, "ClassMap"));
loader->classes = new (loader->allocator, "ClassMap") ClassMap(precompiledClassMap);
for (ClassMap::iterator i = loader->getClasses()->map.begin(),
e = loader->getClasses()->map.end(); i != e; i++) {
i->second->classLoader = loader;
}
// Get the base object arrays after the init, because init puts arrays
// in the class loader map.
upcalls->ArrayOfString =
loader->constructArray(loader->asciizConstructUTF8("[Ljava/lang/String;"));
upcalls->ArrayOfObject =
loader->constructArray(loader->asciizConstructUTF8("[Ljava/lang/Object;"));
ClassArray::InterfacesArray = upcalls->ArrayOfObject->interfaces;
return true;
}
}