blob: 63d1ec65ca9bbb206ce95582c02d3d868c5a7d28 [file] [log] [blame]
//===------------- MSCorlib.cpp - mscorlib interface ----------------------===//
//
// N3
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include <math.h>
#include <dlfcn.h>
#include <stdio.h>
#include "mvm/JIT.h"
#include "Assembly.h"
#include "CLIAccess.h"
#include "CLIJit.h"
#include "NativeUtil.h"
#include "MSCorlib.h"
#include "N3.h"
#include "Reader.h"
#include "VMArray.h"
#include "VMClass.h"
#include "VMObject.h"
#include "VMThread.h"
using namespace n3;
extern "C" void System_Runtime_CompilerServices_RuntimeHelpers_InitializeArray(
VMArray* array, VMField* field) {
if (!array || !field) return;
VMClass* type = field->classDef;
VMClassArray* ts = (VMClassArray*)array->classOf;
VMCommonClass* bs = ts->baseClass;
Assembly* ass = type->assembly;
uint32 rva = ass->getRVAFromField(field->token);
Section* inSection = 0;
if (rva >= ass->rsrcSection->virtualAddress && rva < ass->rsrcSection->virtualAddress + ass->rsrcSection->virtualSize)
inSection = ass->rsrcSection;
if (rva >= ass->textSection->virtualAddress && rva < ass->textSection->virtualAddress + ass->textSection->virtualSize)
inSection = ass->textSection;
if (rva >= ass->relocSection->virtualAddress && rva < ass->relocSection->virtualAddress + ass->relocSection->virtualSize)
inSection = ass->relocSection;
uint32 size = array->size;
uint32 offset = inSection->rawAddress + (rva - inSection->virtualAddress);
ByteCode* bytes = ass->bytes;
if (bs == MSCorlib::pChar) {
for (uint32 i = 0; i < size; ++i) {
((ArrayUInt16*)array)->elements[i] = READ_U2(bytes, offset);
}
} else if (bs == MSCorlib::pSInt32) {
for (uint32 i = 0; i < size; ++i) {
((ArraySInt32*)array)->elements[i] = READ_U4(bytes, offset);
}
} else if (bs == MSCorlib::pDouble) {
for (uint32 i = 0; i < size; ++i) {
((ArrayDouble*)array)->elements[i] = READ_U8(bytes, offset);
}
} else {
VMThread::get()->getVM()->error("implement me");
}
}
extern "C" VMObject* System_Type_GetTypeFromHandle(VMCommonClass* cl) {
return cl->getClassDelegatee();
}
extern "C" VMObject* System_Reflection_Assembly_GetCallingAssembly() {
// Call to this function.
void** cur = (void**)__builtin_frame_address(0);
// Stub from CLI to native.
cur = (void**)cur[0];
// The CLI function.
cur = (void**)cur[0];
// The caller of the CLI function;
cur = (void**)cur[0];
N3* vm = VMThread::get()->getVM();
abort();
VMMethod* meth = NULL; //vm->IPToMethod<VMMethod>(FRAME_IP(cur));
assert(meth && "Wrong stack");
return meth->classDef->assembly->getAssemblyDelegatee();
}
extern "C" VMObject* System_Reflection_Assembly_GetExecutingAssembly() {
// Call to this function.
void** cur = (void**)__builtin_frame_address(0);
// Stub from CLI to native.
cur = (void**)cur[0];
// The CLI function.
cur = (void**)cur[0];
N3* vm = VMThread::get()->getVM();
abort();
VMMethod* meth = NULL; //vm->IPToMethod<VMMethod>(FRAME_IP(cur));
assert(meth && "Wrong stack");
return meth->classDef->assembly->getAssemblyDelegatee();
}
extern "C" void System_Reflection_Assembly_LoadFromFile() {
VMThread::get()->getVM()->error("implement me");
}
extern "C" void System_Array_InternalCopy(VMArray* src, sint32 sstart,
VMArray* dst, sint32 dstart,
sint32 len) {
N3* vm = (N3*)(VMThread::get()->getVM());
verifyNull(src);
verifyNull(dst);
if (!(src->classOf->isArray && dst->classOf->isArray)) {
vm->arrayStoreException();
}
VMClassArray* ts = (VMClassArray*)src->classOf;
VMClassArray* td = (VMClassArray*)dst->classOf;
VMCommonClass* dstType = td->baseClass;
VMCommonClass* srcType = ts->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);
}
bool doThrow = false;
if (srcType->super == MSCorlib::pValue && srcType != dstType) {
vm->arrayStoreException();
} else if (srcType->super != MSCorlib::pValue && srcType->super != MSCorlib::pEnum) {
sint32 i = sstart;
while (i < sstart + len && !doThrow) {
VMObject* cur = ((ArrayObject*)src)->elements[i];
if (cur) {
if (!(cur->classOf->isAssignableFrom(dstType))) {
doThrow = true;
len = i;
}
}
++i;
}
}
uint32 size = srcType->naturalType->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();
}
extern "C" sint32 System_Array_GetRank(VMObject* arr) {
verifyNull(arr);
if (arr->classOf->isArray) {
return ((VMClassArray*)(arr->classOf))->dims;
} else {
VMThread::get()->getVM()->error("implement me");
return 0;
}
}
extern "C" sint32 System_Array_GetLength(VMObject* arr) {
verifyNull(arr);
if (arr->classOf->isArray) {
return ((VMArray*)arr)->size;
} else {
VMThread::get()->getVM()->error("implement me");
return 0;
}
}
extern "C" sint32 System_Array_GetLowerBound(VMObject* arr, sint32 dim) {
return 0;
}
extern "C" VMObject* System_Object_GetType(VMObject* obj) {
verifyNull(obj);
return obj->classOf->getClassDelegatee();
}
extern "C" double System_Decimal_ToDouble(void* ptr) {
VMThread::get()->getVM()->error("implement me");
return 0.0;
}
extern "C" double System_Math_Log10(double val) {
return log10(val);
}
extern "C" double System_Math_Floor(double val) {
return floor(val);
}
extern "C" void System_GC_Collect() {
#ifdef MULTIPLE_GC
VMThread::get()->GC->collect();
#else
mvm::Collector::collect();
#endif
}
extern "C" void System_GC_SuppressFinalize(VMObject* obj) {
// TODO: implement me
}