blob: 4f1a644f43abceddd49cec6d2117044137a02e35 [file] [log] [blame]
//===-- ClasspathVMSystem.cpp - GNU classpath java/lang/VMSystem ----------===//
//
// JnJVM
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include <string.h>
#include "llvm/Type.h"
#include "types.h"
#include "JavaArray.h"
#include "JavaClass.h"
#include "JavaObject.h"
#include "JavaTypes.h"
#include "JavaThread.h"
#include "Jnjvm.h"
#include "NativeUtil.h"
using namespace jnjvm;
extern "C" {
JNIEXPORT void JNICALL Java_java_lang_VMSystem_arraycopy(
#ifdef NATIVE_JNI
JNIEnv *env,
jclass _cl,
#endif
jobject _src,
jint sstart,
jobject _dst,
jint dstart,
jint len) {
jnjvm::Jnjvm *vm = JavaThread::get()->isolate;
JavaArray* src = (JavaArray*)_src;
JavaArray* dst = (JavaArray*)_dst;
verifyNull(src);
verifyNull(dst);
if (!(src->classOf->isArray && dst->classOf->isArray)) {
vm->arrayStoreException();
}
ClassArray* ts = (ClassArray*)src->classOf;
ClassArray* td = (ClassArray*)dst->classOf;
AssessorDesc* srcFuncs = ts->funcs();
AssessorDesc* dstFuncs = ts->funcs();
CommonClass* dstType = td->baseClass();
if (len > src->size) {
vm->indexOutOfBounds(src, len);
} else if (len > dst->size) {
vm->indexOutOfBounds(dst, len);
} else if (len + sstart > src->size) {
vm->indexOutOfBounds(src, len + sstart);
} else if (len + dstart > dst->size) {
vm->indexOutOfBounds(dst, len + dstart);
} else if (dstart < 0) {
vm->indexOutOfBounds(dst, dstart);
} else if (sstart < 0) {
vm->indexOutOfBounds(src, sstart);
} else if (len < 0) {
vm->indexOutOfBounds(src, len);
} else if (srcFuncs != dstFuncs) {
vm->arrayStoreException();
}
jint i = sstart;
bool doThrow = false;
if (srcFuncs == AssessorDesc::dTab || srcFuncs == AssessorDesc::dRef) {
while (i < sstart + len && !doThrow) {
JavaObject* cur = ((ArrayObject*)src)->at(i);
if (cur) {
if (!(cur->classOf->isAssignableFrom(dstType))) {
doThrow = true;
len = i;
}
}
++i;
}
}
uint32 size = srcFuncs->llvmType->getPrimitiveSizeInBits() / 8;
if (size == 0) size = sizeof(void*);
void* ptrDst = (void*)((int64_t)(dst->elements) + size * dstart);
void* ptrSrc = (void*)((int64_t)(src->elements) + size * sstart);
memmove(ptrDst, ptrSrc, size * len);
if (doThrow)
vm->arrayStoreException();
}
JNIEXPORT jint JNICALL Java_java_lang_VMSystem_identityHashCode(
#ifdef NATIVE_JNI
JNIEnv *env,
jclass clazz,
#endif
jobject obj) {
return (jint)obj;
}
}