blob: f39a909f04f9f94dce25a627badd14c628cd8c4a [file] [log] [blame]
//===----------- N3Initialise.cpp - Initialization of N3 ------------------===//
//
// N3
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include <vector>
#include "mvm/JIT.h"
#include "mvm/Threads/Locks.h"
#include "Assembly.h"
#include "CLIString.h"
#include "CLIJit.h"
#include "LockedMap.h"
#include "NativeUtil.h"
#include "N3.h"
#include "N3ModuleProvider.h"
#include "Reader.h"
#include "VirtualMachine.h"
#include "VMArray.h"
#include "VMCache.h"
#include "VMClass.h"
#include "VMObject.h"
#include "VMThread.h"
using namespace n3;
N3* N3::bootstrapVM = 0;
mvm::Lock* VMObject::globalLock = 0;
mvm::Key<VMThread>* VMThread::threadKey = 0;
VMCommonClass* VMClassArray::SuperArray = 0;
std::vector<VMClass*> VMClassArray::InterfacesArray;
std::vector<VMMethod*> VMClassArray::VirtualMethodsArray;
std::vector<VMMethod*> VMClassArray::StaticMethodsArray;
std::vector<VMField*> VMClassArray::VirtualFieldsArray;
std::vector<VMField*> VMClassArray::StaticFieldsArray;
VMClass* N3::pVoid = 0;
VMClass* N3::pBoolean= 0;
VMClass* N3::pChar = 0;
VMClass* N3::pSInt8 = 0;
VMClass* N3::pUInt8 = 0;
VMClass* N3::pSInt16 = 0;
VMClass* N3::pUInt16 = 0;
VMClass* N3::pSInt32 = 0;
VMClass* N3::pUInt32 = 0;
VMClass* N3::pSInt64 = 0;
VMClass* N3::pUInt64 = 0;
VMClass* N3::pFloat = 0;
VMClass* N3::pDouble = 0;
VMClass* N3::pIntPtr = 0;
VMClass* N3::pUIntPtr = 0;
VMClass* N3::pObject = 0;
VMClass* N3::pString = 0;
VMClass* N3::pValue = 0;
VMClass* N3::pEnum = 0;
VMClass* N3::pArray = 0;
VMClass* N3::pDelegate = 0;
VMClass* N3::pException = 0;
VMClassArray* N3::arrayChar = 0;
VMClassArray* N3::arrayString = 0;
VMClassArray* N3::arrayObject = 0;
VMClassArray* N3::arrayByte = 0;
VMMethod* N3::ctorPropertyType;
VMMethod* N3::ctorMethodType;
VMMethod* N3::ctorClrType;
VMClass* N3::clrType;
VMField* N3::typeClrType;
VMField* N3::propertyPropertyType;
VMField* N3::methodMethodType;
VMMethod* N3::ctorAssemblyReflection;
VMClass* N3::assemblyReflection;
VMClass* N3::typedReference;
VMField* N3::assemblyAssemblyReflection;
VMClass* N3::propertyType;
VMClass* N3::methodType;
VMClass* N3::resourceStreamType;
VMMethod* N3::ctorResourceStreamType;
VMField* N3::ctorBoolean;
VMField* N3::ctorUInt8;
VMField* N3::ctorSInt8;
VMField* N3::ctorChar;
VMField* N3::ctorSInt16;
VMField* N3::ctorUInt16;
VMField* N3::ctorSInt32;
VMField* N3::ctorUInt32;
VMField* N3::ctorSInt64;
VMField* N3::ctorUInt64;
VMField* N3::ctorIntPtr;
VMField* N3::ctorUIntPtr;
VMField* N3::ctorDouble;
VMField* N3::ctorFloat;
const UTF8* N3::clinitName = 0;
const UTF8* N3::ctorName = 0;
const UTF8* N3::invokeName = 0;
const UTF8* N3::math = 0;
const UTF8* N3::system = 0;
const UTF8* N3::sqrt = 0;
const UTF8* N3::sin = 0;
const UTF8* N3::cos = 0;
const UTF8* N3::exp = 0;
const UTF8* N3::log = 0;
const UTF8* N3::floor = 0;
const UTF8* N3::log10 = 0;
const UTF8* N3::isNan = 0;
const UTF8* N3::pow = 0;
const UTF8* N3::floatName = 0;
const UTF8* N3::doubleName = 0;
const UTF8* N3::testInfinity = 0;
const llvm::Type* VMArray::llvmType;
const llvm::Type* VMObject::llvmType;
const llvm::Type* Enveloppe::llvmType;
const llvm::Type* CacheNode::llvmType;
llvm::Function* CLIJit::printExecutionLLVM;
llvm::Function* CLIJit::indexOutOfBoundsExceptionLLVM;
llvm::Function* CLIJit::nullPointerExceptionLLVM;
llvm::Function* CLIJit::classCastExceptionLLVM;
llvm::Function* CLIJit::clearExceptionLLVM;
llvm::Function* CLIJit::compareExceptionLLVM;
llvm::Function* CLIJit::arrayLengthLLVM;
llvm::Function* CLIJit::markAndTraceLLVM;
const llvm::FunctionType* CLIJit::markAndTraceLLVMType;
llvm::Function* CLIJit::vmObjectTracerLLVM;
llvm::Function* CLIJit::initialiseClassLLVM;
llvm::Function* CLIJit::virtualLookupLLVM;
llvm::Function* CLIJit::arrayConsLLVM;
llvm::Function* CLIJit::arrayMultiConsLLVM;
llvm::Function* CLIJit::objConsLLVM;
llvm::Function* CLIJit::objInitLLVM;
llvm::Function* CLIJit::throwExceptionLLVM;
llvm::Function* CLIJit::instanceOfLLVM;
llvm::Function* CLIJit::isInCodeLLVM;
llvm::Function* CLIJit::getCLIExceptionLLVM;
llvm::Function* CLIJit::getCppExceptionLLVM;
llvm::Function* CLIJit::newStringLLVM;
const llvm::Type* ArrayUInt8::llvmType = 0;
const llvm::Type* ArraySInt8::llvmType = 0;
const llvm::Type* ArrayUInt16::llvmType = 0;
const llvm::Type* ArraySInt16::llvmType = 0;
const llvm::Type* ArrayUInt32::llvmType = 0;
const llvm::Type* ArraySInt32::llvmType = 0;
const llvm::Type* ArrayFloat::llvmType = 0;
const llvm::Type* ArrayDouble::llvmType = 0;
const llvm::Type* ArrayLong::llvmType = 0;
const llvm::Type* ArrayObject::llvmType = 0;
const llvm::Type* UTF8::llvmType = 0;
static void initialiseVT() {
# define INIT(X) { \
X fake; \
X::VT = ((void**)(void*)(&fake))[0]; }
INIT(Assembly);
INIT(Header);
INIT(Property);
INIT(Param);
INIT(Section);
INIT(Table);
INIT(VMArray);
INIT(ArrayUInt8);
INIT(ArraySInt8);
INIT(ArrayUInt16);
INIT(ArraySInt16);
INIT(ArrayUInt32);
INIT(ArraySInt32);
INIT(ArrayLong);
INIT(ArrayFloat);
INIT(ArrayDouble);
INIT(ArrayObject);
INIT(UTF8);
INIT(VMCommonClass);
INIT(VMClass);
INIT(VMClassArray);
INIT(VMMethod);
INIT(VMField);
INIT(VMCond);
INIT(LockObj);
INIT(VMObject);
INIT(VMThread);
//mvm::Key<VMThread>::VT = mvm::ThreadKey::VT;
INIT(ThreadSystem);
INIT(N3);
INIT(Reader);
INIT(UTF8Map);
INIT(ClassNameMap);
INIT(ClassTokenMap);
INIT(FieldTokenMap);
INIT(MethodTokenMap);
INIT(StringMap);
INIT(FunctionMap);
INIT(VirtualMachine);
INIT(CLIString);
INIT(CLIJit);
INIT(CacheNode);
INIT(Enveloppe);
INIT(Opinfo);
INIT(Exception);
#undef INIT
}
static void loadStringClass(N3* vm) {
VMClass* type = (VMClass*)vm->coreAssembly->loadTypeFromName(
vm->asciizConstructUTF8("String"),
vm->asciizConstructUTF8("System"),
false, false, false, true);
N3::pString = type;
type->resolveType(false, false);
uint64 size = mvm::jit::getTypeSize(type->virtualType->getContainedType(0)) + sizeof(const UTF8*) + sizeof(llvm::GlobalVariable*);
type->virtualInstance =
(VMObject*)mvm::Object::gcmalloc(size, type->virtualInstance->getVirtualTable());
type->virtualInstance->initialise(type);
}
static void initialiseStatics() {
NativeUtil::initialise();
CLIJit::initialise();
VMObject::globalLock = mvm::Lock::allocNormal();
//mvm::Object::pushRoot((mvm::Object*)VMObject::globalLock);
VMThread::threadKey = new mvm::Key<VMThread>();
//mvm::Object::pushRoot((mvm::Object*)VMThread::threadKey);
N3* vm = N3::bootstrapVM = N3::allocateBootstrap();
mvm::Object::pushRoot((mvm::Object*)N3::bootstrapVM);
char* assemblyName = getenv("MSCORLIB");
if (assemblyName == 0)
VMThread::get()->vm->error("can not find mscorlib.dll. Abort");
vm->assemblyPath.push_back("");
vm->assemblyPath.push_back(assemblyName);
const UTF8* mscorlib = vm->asciizConstructUTF8("mscorlib");
Assembly* ass = vm->loadAssembly(mscorlib, "dll");
if (ass == 0)
VMThread::get()->vm->error("can not find mscorlib.dll. Abort");
vm->coreAssembly = ass;
// Array initialization
const UTF8* System = vm->asciizConstructUTF8("System");
const UTF8* utf8OfChar = vm->asciizConstructUTF8("Char");
N3::arrayChar = ass->constructArray(utf8OfChar, System, 1);
((UTF8*)System)->classOf = N3::arrayChar;
((UTF8*)utf8OfChar)->classOf = N3::arrayChar;
((UTF8*)mscorlib)->classOf = N3::arrayChar;
#define INIT(var, nameSpace, name, type, prim) {\
var = (VMClass*)vm->coreAssembly->loadTypeFromName( \
vm->asciizConstructUTF8(name), \
vm->asciizConstructUTF8(nameSpace),\
false, false, false, true); \
var->isPrimitive = prim; \
if (type) { \
var->naturalType = type; \
var->virtualType = type; \
}}
INIT(N3::pObject, "System", "Object", VMObject::llvmType, false);
INIT(N3::pValue, "System", "ValueType", 0, false);
INIT(N3::pVoid, "System", "Void", llvm::Type::VoidTy, true);
INIT(N3::pBoolean, "System", "Boolean", llvm::Type::Int1Ty, true);
INIT(N3::pUInt8, "System", "Byte", llvm::Type::Int8Ty, true);
INIT(N3::pSInt8, "System", "SByte", llvm::Type::Int8Ty, true);
INIT(N3::pChar, "System", "Char", llvm::Type::Int16Ty, true);
INIT(N3::pSInt16, "System", "Int16", llvm::Type::Int16Ty, true);
INIT(N3::pUInt16, "System", "UInt16", llvm::Type::Int16Ty, true);
INIT(N3::pSInt32, "System", "Int32", llvm::Type::Int32Ty, true);
INIT(N3::pUInt32, "System", "UInt32", llvm::Type::Int32Ty, true);
INIT(N3::pSInt64, "System", "Int64", llvm::Type::Int64Ty, true);
INIT(N3::pUInt64, "System", "UInt64", llvm::Type::Int64Ty, true);
INIT(N3::pIntPtr, "System", "IntPtr", llvm::PointerType::getUnqual(llvm::Type::Int8Ty), true);
INIT(N3::pUIntPtr, "System", "UIntPtr", llvm::PointerType::getUnqual(llvm::Type::Int8Ty), true);
INIT(N3::pDouble, "System", "Double", llvm::Type::DoubleTy, true);
INIT(N3::pFloat, "System", "Single", llvm::Type::FloatTy, true);
INIT(N3::pEnum, "System", "Enum", llvm::Type::Int32Ty, true);
INIT(N3::pArray, "System", "Array", 0, true);
INIT(N3::pException,"System", "Exception", 0, false);
INIT(N3::pDelegate, "System", "Delegate", 0, false);
INIT(N3::clrType, "System.Reflection", "ClrType", 0, false);
INIT(N3::assemblyReflection, "System.Reflection", "Assembly", 0, false);
INIT(N3::typedReference, "System", "TypedReference", 0, false);
INIT(N3::propertyType, "System.Reflection", "ClrProperty", 0, false);
INIT(N3::methodType, "System.Reflection", "ClrMethod", 0, false);
INIT(N3::resourceStreamType, "System.Reflection", "ClrResourceStream", 0, false);
#undef INIT
N3::arrayChar->baseClass = N3::pChar;
VMClassArray::SuperArray = N3::pArray;
N3::arrayChar->super = N3::pArray;
loadStringClass(vm);
N3::arrayString = ass->constructArray(vm->asciizConstructUTF8("String"),
System, 1);
N3::arrayString->baseClass = N3::pString;
N3::arrayByte = ass->constructArray(vm->asciizConstructUTF8("Byte"),
System, 1);
N3::arrayByte->baseClass = N3::pUInt8;
N3::arrayObject = ass->constructArray(vm->asciizConstructUTF8("Object"),
System, 1);
N3::arrayObject->baseClass = N3::pObject;
N3::clinitName = vm->asciizConstructUTF8(".cctor");
N3::ctorName = vm->asciizConstructUTF8(".ctor");
N3::invokeName = vm->asciizConstructUTF8("Invoke");
N3::math = vm->asciizConstructUTF8("Math");
N3::system = vm->asciizConstructUTF8("System");
N3::sqrt = vm->asciizConstructUTF8("Sqrt");
N3::sin = vm->asciizConstructUTF8("Sin");
N3::cos = vm->asciizConstructUTF8("Cos");
N3::exp = vm->asciizConstructUTF8("Exp");
N3::log = vm->asciizConstructUTF8("Log");
N3::floor = vm->asciizConstructUTF8("Floor");
N3::log10 = vm->asciizConstructUTF8("Log10");
N3::isNan = vm->asciizConstructUTF8("IsNaN");
N3::pow = vm->asciizConstructUTF8("Pow");
N3::floatName = vm->asciizConstructUTF8("Float");
N3::doubleName = vm->asciizConstructUTF8("Double");
N3::testInfinity = vm->asciizConstructUTF8("TestInfinity");
{
N3::clrType->resolveType(false, false);
std::vector<VMCommonClass*> args;
args.push_back(N3::pVoid);
args.push_back(N3::clrType);
N3::ctorClrType = N3::clrType->lookupMethod(vm->asciizConstructUTF8(".ctor"), args, false, false);
N3::typeClrType = N3::clrType->lookupField(vm->asciizConstructUTF8("privateData"), N3::pIntPtr, false, false);
}
{
N3::assemblyReflection->resolveType(false, false);
std::vector<VMCommonClass*> args;
args.push_back(N3::pVoid);
args.push_back(N3::assemblyReflection);
N3::ctorAssemblyReflection = N3::assemblyReflection->lookupMethod(vm->asciizConstructUTF8(".ctor"), args, false, false);
N3::assemblyAssemblyReflection = N3::assemblyReflection->lookupField(vm->asciizConstructUTF8("privateData"), N3::pIntPtr, false, false);
}
{
N3::propertyType->resolveType(false, false);
std::vector<VMCommonClass*> args;
args.push_back(N3::pVoid);
args.push_back(N3::propertyType);
N3::ctorPropertyType = N3::propertyType->lookupMethod(vm->asciizConstructUTF8(".ctor"), args, false, false);
N3::propertyPropertyType = N3::propertyType->lookupField(vm->asciizConstructUTF8("privateData"), N3::pIntPtr, false, false);
}
{
N3::methodType->resolveType(false, false);
std::vector<VMCommonClass*> args;
args.push_back(N3::pVoid);
args.push_back(N3::methodType);
N3::ctorMethodType = N3::methodType->lookupMethod(vm->asciizConstructUTF8(".ctor"), args, false, false);
N3::methodMethodType = N3::methodType->lookupField(vm->asciizConstructUTF8("privateData"), N3::pIntPtr, false, false);
}
{
N3::resourceStreamType->resolveType(false, false);
std::vector<VMCommonClass*> args;
args.push_back(N3::pVoid);
args.push_back(N3::resourceStreamType);
args.push_back(N3::pIntPtr);
args.push_back(N3::pSInt64);
args.push_back(N3::pSInt64);
N3::ctorResourceStreamType = N3::resourceStreamType->lookupMethod(vm->asciizConstructUTF8(".ctor"), args, false, false);
}
VMCommonClass* voidPtr = vm->coreAssembly->constructPointer(N3::pVoid, 1);
#define INIT(var, cl, type) {\
cl->resolveType(false, false); \
var = cl->lookupField(vm->asciizConstructUTF8("value_"), type, false, false); \
}
INIT(N3::ctorBoolean, N3::pBoolean, N3::pBoolean);
INIT(N3::ctorUInt8, N3::pUInt8, N3::pUInt8);
INIT(N3::ctorSInt8, N3::pSInt8, N3::pSInt8);
INIT(N3::ctorChar, N3::pChar, N3::pChar);
INIT(N3::ctorSInt16, N3::pSInt16, N3::pSInt16);
INIT(N3::ctorUInt16, N3::pUInt16, N3::pUInt16);
INIT(N3::ctorSInt32, N3::pSInt32, N3::pSInt32);
INIT(N3::ctorUInt32, N3::pUInt32, N3::pUInt32);
INIT(N3::ctorSInt64, N3::pSInt64, N3::pSInt64);
INIT(N3::ctorUInt64, N3::pUInt64, N3::pUInt64);
INIT(N3::ctorIntPtr, N3::pIntPtr, voidPtr);
INIT(N3::ctorUIntPtr, N3::pUIntPtr, voidPtr);
INIT(N3::ctorDouble, N3::pDouble, N3::pDouble);
INIT(N3::ctorFloat, N3::pFloat, N3::pFloat);
#undef INIT
}
extern "C" int boot(int argc, char **argv, char **envp) {
initialiseVT();
initialiseStatics();
return 0;
}
extern "C" int start_app(int argc, char** argv) {
N3* vm = N3::allocate("", N3::bootstrapVM);
vm->runMain(argc, argv);
return 0;
}