//===----- PNetMSCorlib.cpp - The Pnet MSCorlib implementation ------------===//
//
//                              N3
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//


#include "mvm/JIT.h"

#include "Assembly.h"
#include "MSCorlib.h"
#include "N3.h"
#include "VMClass.h"
#include "VMObject.h"
#include "VMThread.h"

using namespace n3;

void MSCorlib::loadStringClass(N3* vm) {
  VMClass* type = (VMClass*)vm->coreAssembly->loadTypeFromName(
                                           vm->asciizToUTF8("String"),
                                           vm->asciizToUTF8("System"),
                                           false, false, false, true);
  MSCorlib::pString = type;
  MSCorlib::pObject->resolveType(true, false, NULL);
  MSCorlib::pObject->resolveVT();
  type->resolveType(true, false, NULL);
  type->resolveVT();

  uint64 size = mvm::MvmModule::getTypeSize(type->virtualType->getContainedType(0)) + sizeof(const UTF8*) + sizeof(llvm::GlobalVariable*);
  type->virtualInstance = 
    (VMObject*)gc::operator new(size, VMObject::getN3VirtualTable(type->virtualInstance));
	VMObject::initialise(type->virtualInstance, type);
}


void MSCorlib::initialise(N3* vm) {
  #define INIT(var, nameSpace, name, type, prim) {\
  var = (VMClass*)vm->coreAssembly->loadTypeFromName( \
                                           vm->asciizToUTF8(name),     \
                                           vm->asciizToUTF8(nameSpace),\
                                           false, false, false, true); \
  var->isPrimitive = prim; \
  if (type) { \
    var->naturalType = type;  \
    var->virtualType = type;  \
  }}

  INIT(MSCorlib::clrType,   "System.Reflection", "ClrType", 0, false);
  INIT(MSCorlib::assemblyReflection,   "System.Reflection", "Assembly", 0, false);
  INIT(MSCorlib::typedReference,   "System", "TypedReference", 0, false);
  INIT(MSCorlib::propertyType,   "System.Reflection", "ClrProperty", 0, false);
  INIT(MSCorlib::methodType,   "System.Reflection", "ClrMethod", 0, false);
  INIT(MSCorlib::resourceStreamType,   "System.Reflection", "ClrResourceStream", 0, false);

#undef INIT
  
  {
  MSCorlib::clrType->resolveType(false, false, NULL);
  std::vector<VMCommonClass*> args;
  args.push_back(MSCorlib::pVoid);
  args.push_back(MSCorlib::clrType);
  MSCorlib::ctorClrType = MSCorlib::clrType->lookupMethod(vm->asciizToUTF8(".ctor"), args, false, false);
  MSCorlib::typeClrType = MSCorlib::clrType->lookupField(vm->asciizToUTF8("privateData"), MSCorlib::pIntPtr, false, false);
  }

  {
  MSCorlib::assemblyReflection->resolveType(false, false, NULL);
  std::vector<VMCommonClass*> args;
  args.push_back(MSCorlib::pVoid);
  args.push_back(MSCorlib::assemblyReflection);
  MSCorlib::ctorAssemblyReflection = MSCorlib::assemblyReflection->lookupMethod(vm->asciizToUTF8(".ctor"), args, false, false);
  MSCorlib::assemblyAssemblyReflection = MSCorlib::assemblyReflection->lookupField(vm->asciizToUTF8("privateData"), MSCorlib::pIntPtr, false, false);
  }
  
  {
  MSCorlib::propertyType->resolveType(false, false, NULL);
  std::vector<VMCommonClass*> args;
  args.push_back(MSCorlib::pVoid);
  args.push_back(MSCorlib::propertyType);
  MSCorlib::ctorPropertyType = MSCorlib::propertyType->lookupMethod(vm->asciizToUTF8(".ctor"), args, false, false);
  MSCorlib::propertyPropertyType = MSCorlib::propertyType->lookupField(vm->asciizToUTF8("privateData"), MSCorlib::pIntPtr, false, false);
  }
  
  {
  MSCorlib::methodType->resolveType(false, false, NULL);
  std::vector<VMCommonClass*> args;
  args.push_back(MSCorlib::pVoid);
  args.push_back(MSCorlib::methodType);
  MSCorlib::ctorMethodType = MSCorlib::methodType->lookupMethod(vm->asciizToUTF8(".ctor"), args, false, false);
  MSCorlib::methodMethodType = MSCorlib::methodType->lookupField(vm->asciizToUTF8("privateData"), MSCorlib::pIntPtr, false, false);
  }
  
  {
  MSCorlib::resourceStreamType->resolveType(false, false, NULL);
  std::vector<VMCommonClass*> args;
  args.push_back(MSCorlib::pVoid);
  args.push_back(MSCorlib::resourceStreamType);
  args.push_back(MSCorlib::pIntPtr);
  args.push_back(MSCorlib::pSInt64);
  args.push_back(MSCorlib::pSInt64);
  MSCorlib::ctorResourceStreamType = MSCorlib::resourceStreamType->lookupMethod(vm->asciizToUTF8(".ctor"), args, false, false);
  }
  
  VMCommonClass* voidPtr = vm->coreAssembly->constructPointer(MSCorlib::pVoid, 1);
#define INIT(var, cl, type) {\
    cl->resolveType(false, false, NULL); \
    var = cl->lookupField(vm->asciizToUTF8("value_"), type, false, false); \
  }
  
  INIT(MSCorlib::ctorBoolean,  MSCorlib::pBoolean, MSCorlib::pBoolean);
  INIT(MSCorlib::ctorUInt8, MSCorlib::pUInt8, MSCorlib::pUInt8);
  INIT(MSCorlib::ctorSInt8, MSCorlib::pSInt8, MSCorlib::pSInt8);
  INIT(MSCorlib::ctorChar,  MSCorlib::pChar, MSCorlib::pChar);
  INIT(MSCorlib::ctorSInt16, MSCorlib::pSInt16, MSCorlib::pSInt16);
  INIT(MSCorlib::ctorUInt16, MSCorlib::pUInt16, MSCorlib::pUInt16);
  INIT(MSCorlib::ctorSInt32, MSCorlib::pSInt32, MSCorlib::pSInt32);
  INIT(MSCorlib::ctorUInt32, MSCorlib::pUInt32, MSCorlib::pUInt32);
  INIT(MSCorlib::ctorSInt64, MSCorlib::pSInt64, MSCorlib::pSInt64);
  INIT(MSCorlib::ctorUInt64, MSCorlib::pUInt64, MSCorlib::pUInt64);
  INIT(MSCorlib::ctorIntPtr, MSCorlib::pIntPtr, voidPtr);
  INIT(MSCorlib::ctorUIntPtr, MSCorlib::pUIntPtr, voidPtr);
  INIT(MSCorlib::ctorDouble, MSCorlib::pDouble, MSCorlib::pDouble);
  INIT(MSCorlib::ctorFloat, MSCorlib::pFloat, MSCorlib::pFloat);

#undef INIT


}

VMObject* Property::getPropertyDelegatee() {
	declare_gcroot(VMObject*, delegatee) = ooo_delegatee;

  if (!delegatee) {
    ooo_delegatee = delegatee = MSCorlib::propertyType->doNew();
    MSCorlib::ctorPropertyType->compileToNative()->invokeVoid(delegatee);
    MSCorlib::propertyPropertyType->setIntPtr(delegatee, (int*)this);
  }

  return delegatee;
}

VMObject* VMMethod::getMethodDelegatee() {
	declare_gcroot(VMObject*, delegatee) = ooo_delegatee;

  if (!delegatee) {
    ooo_delegatee = delegatee = MSCorlib::methodType->doNew();
    MSCorlib::ctorMethodType->compileToNative()->invokeVoid(delegatee);
    MSCorlib::methodMethodType->setIntPtr(delegatee, (int*)this);
  }

  return delegatee;
}

VMObject* VMCommonClass::getClassDelegatee() {
	declare_gcroot(VMObject*, delegatee) = ooo_delegatee;

  if (!delegatee) {
    ooo_delegatee = delegatee = MSCorlib::clrType->doNew();
    MSCorlib::ctorClrType->compileToNative()->invokeVoid(delegatee);
    MSCorlib::typeClrType->setIntPtr(delegatee, (int*)this);
  }

  return delegatee;
}

VMObject* Assembly::getAssemblyDelegatee() {
	declare_gcroot(VMObject*, delegatee) = ooo_delegatee;

  if (!delegatee) {
    ooo_delegatee = delegatee = MSCorlib::assemblyReflection->doNew();
    MSCorlib::ctorAssemblyReflection->compileToNative()->invokeVoid(delegatee);
    MSCorlib::assemblyAssemblyReflection->setIntPtr(delegatee, (int*)this);
  }

  return delegatee;
}

static void mapInitialThread(N3* vm) {
  VMClass* cl = (VMClass*)vm->coreAssembly->loadTypeFromName(
                                        vm->asciizToUTF8("Thread"),
                                        vm->asciizToUTF8("System.Threading"),
                                        true, true, true, true);
	declare_gcroot(VMObject*, appThread) = cl->doNew();

  std::vector<VMCommonClass*> args;
  args.push_back(MSCorlib::pVoid);
  args.push_back(cl);
  args.push_back(MSCorlib::pIntPtr);
  VMMethod* ctor = cl->lookupMethod(vm->asciizToUTF8(".ctor"), args, 
                                    false, false);
  VMThread* myth = VMThread::get();
  ctor->compileToNative()->invokeVoid(appThread, myth);
  myth->ooo_appThread = appThread;
}

void MSCorlib::loadBootstrap(N3* vm) {
  mapInitialThread(vm);
}
