blob: 07c620d1b585d3e270179ec66fbc579e4eadcd06 [file] [log] [blame]
#include "runtime.h"
#include <stdlib.h>
#include <string.h>
jint llvm_java_is_primitive_class(struct llvm_java_class_record* cr)
{
return cr->typeinfo.elementSize == -2;
}
jint llvm_java_is_interface_class(struct llvm_java_class_record* cr)
{
return cr->typeinfo.elementSize == -1;
}
jint llvm_java_is_array_class(struct llvm_java_class_record* cr)
{
return cr->typeinfo.elementSize > 0;
}
struct llvm_java_class_record* llvm_java_get_class_record(jobject obj) {
return obj->classRecord;
}
void llvm_java_set_class_record(jobject obj,
struct llvm_java_class_record* cr) {
obj->classRecord = cr;
}
struct llvm_java_class_record*
llvm_java_get_superclass_record(struct llvm_java_class_record* cr) {
/* If this is an interface or java/lang/Object return NULL. */
if (llvm_java_is_interface_class(cr) || cr->typeinfo.depth == 0)
return NULL;
return cr->typeinfo.superclasses[cr->typeinfo.depth - 1];
}
jboolean llvm_java_is_assignable_from(struct llvm_java_class_record* cr,
struct llvm_java_class_record* from) {
/* trivial case: class records are the same */
if (cr == from)
return JNI_TRUE;
/* if from is a primitive class then they must be of the same class */
if (llvm_java_is_primitive_class(from))
return cr == from;
/* if from is an interface class then the current class must
* implement that interface */
if (llvm_java_is_interface_class(from)) {
int index = from->typeinfo.interfaceIndex;
return (cr->typeinfo.interfaceIndex >= index &&
cr->typeinfo.interfaces[index]);
}
/* if from is an array class then the component types of must be
* assignable from */
if (llvm_java_is_array_class(from))
return (cr->typeinfo.component &&
llvm_java_is_assignable_from(cr->typeinfo.component,
from->typeinfo.component));
/* otherwise this is a class, check if from is a superclass of this
* class */
if (cr->typeinfo.depth > from->typeinfo.depth) {
int index = from->typeinfo.depth;
return cr->typeinfo.superclasses[index] == from;
}
return JNI_FALSE;
}
jboolean llvm_java_is_instance_of(jobject obj,
struct llvm_java_class_record* cr) {
/* trivial case: a null object can be cast to any type */
if (!obj)
return JNI_TRUE;
return llvm_java_is_assignable_from(obj->classRecord, cr);
}
jint llvm_java_throw(jthrowable obj) {
abort();
}
extern struct llvm_java_class_record* llvm_java_class_records;
struct llvm_java_class_record*
llvm_java_find_class_record(const char* name) {
struct llvm_java_class_record** cr = &llvm_java_class_records;
for (; *cr; ++cr)
if (strcmp((*cr)->typeinfo.name, name) == 0)
return *cr;
return NULL;
}
void Java_java_lang_VMSystem_arraycopy(JNIEnv *env, jobject clazz,
jobject srcObj, jint srcStart,
jobject dstObj, jint dstStart,
jint length) {
struct llvm_java_bytearray* srcArray = (struct llvm_java_bytearray*) srcObj;
struct llvm_java_bytearray* dstArray = (struct llvm_java_bytearray*) dstObj;
unsigned nbytes = length * srcObj->classRecord->typeinfo.elementSize;
jbyte* src = srcArray->data;
jbyte* dst = dstArray->data;
// FIXME: Need to perform a proper type check here.
if (srcObj->classRecord->typeinfo.elementSize !=
dstObj->classRecord->typeinfo.elementSize)
llvm_java_throw(NULL);
src += srcStart * srcObj->classRecord->typeinfo.elementSize;
dst += dstStart * dstObj->classRecord->typeinfo.elementSize;
memmove(dst, src, nbytes);
}
void Java_gnu_classpath_VMSystemProperties_preInit(JNIEnv *env, jobject clazz,
jobject properties) {
}
typedef void (*ClassInitializerFunction)(void);
extern const ClassInitializerFunction llvm_java_class_initializers;
extern void llvm_java_main(int, char**);
int main(int argc, char** argv) {
const ClassInitializerFunction* classInit = &llvm_java_class_initializers;
for (; *classInit; ++classInit)
(*classInit)();
llvm_java_main(argc, argv);
return 0;
}