//===--------- Assembly.cpp - Definition of an assembly -------------------===//
//
//                              N3
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include <vector>

#include "N3Debug.h"
#include "types.h"

#include "Assembly.h"
#include "CLIAccess.h"
#include "LockedMap.h"
#include "MSCorlib.h"
#include "N3.h"
#include "Reader.h"
#include "VMClass.h"
#include "VMObject.h"
#include "VMThread.h"

using namespace n3;


#define DEF_TABLE_MASK(name, nb, ...) \
  static void name(uint32 index, \
                   std::vector<Table*, gc_allocator<Table*> >& tables, \
                   uint32 heapSizes) { \
    Table* table = tables[index]; \
    uint32 rowSize = 0; \
    uint32 bitmask = 0; \
    __VA_ARGS__; \
    table->count = nb; \
    table->sizeMask = bitmask; \
    table->rowSize = rowSize; \
  }
  

DEF_TABLE_MASK(METHOD_Module, 5,
  INT16(CONSTANT_MODULE_GENERATION)
  STRING(CONSTANT_MODULE_NAME)
  GUID(CONSTANT_MODULE_MVID)
  GUID(CONSTANT_MODULE_ENCID)
  GUID(CONSTANT_MODULE_ENCBASEID))
  
DEF_TABLE_MASK(METHOD_TypeRef, 3,
  RESOLUTION_SCOPE(CONSTANT_TYPEREF_RESOLUTION_SCOPE)
  STRING(CONSTANT_TYPEREF_NAME)
  STRING(CONSTANT_TYPEREF_NAMESPACE))
  
DEF_TABLE_MASK(METHOD_TypeDef, 6,
  INT32(CONSTANT_TYPEDEF_FLAGS)
  STRING(CONSTANT_TYPEDEF_NAME)
  STRING(CONSTANT_TYPEDEF_NAMESPACE)
  TYPEDEF_OR_REF(CONSTANT_TYPEDEF_EXTENDS)
  TABLE(CONSTANT_Field, CONSTANT_TYPEDEF_FIELDLIST)
  TABLE(CONSTANT_MethodDef, CONSTANT_TYPEDEF_METHODLIST))

DEF_TABLE_MASK(METHOD_MethodDef, 6,
  INT32(CONSTANT_METHODDEF_RVA)
  INT16(CONSTANT_METHODDEF_IMPLFLAGS)
  INT16(CONSTANT_METHODDEF_FLAGS)
  STRING(CONSTANT_METHODDEF_NAME)
  BLOB(CONSTANT_METHODDEF_SIGNATURE)
  TABLE(CONSTANT_Param, CONSTANT_METHODDEF_PARAMLIST))
  
DEF_TABLE_MASK(METHOD_Param, 3,
  INT16(CONSTANT_PARAM_FLAGS)
  INT16(CONSTANT_PARAM_SEQUENCE)
  STRING(CONSTANT_PARAM_NAME))
  
DEF_TABLE_MASK(METHOD_MemberRef, 3,
  MEMBER_REF_PARENT(CONSTANT_MEMBERREF_CLASS)
  STRING(CONSTANT_MEMBERREF_NAME)
  BLOB(CONSTANT_MEMBERREF_SIGNATURE))
  
DEF_TABLE_MASK(METHOD_CustomAttribute, 3,
  HAS_CUSTOM_ATTRIBUTE(CONSTANT_CUSTOM_ATTRIBUTE_PARENT)
  CUSTOM_ATTRIBUTE_TYPE(CONSTANT_CUSTOM_ATTRIBUTE_TYPE)
  BLOB(CONSTANT_CUSTOM_ATTRIBUTE_VALUE))
  
DEF_TABLE_MASK(METHOD_StandaloneSig, 1,
  BLOB(CONSTANT_STANDALONE_SIG_SIGNATURE))
  
DEF_TABLE_MASK(METHOD_TypeSpec, 1,
  BLOB(CONSTANT_TYPESPEC_SIGNATURE))
  
DEF_TABLE_MASK(METHOD_Assembly, 9,
  INT32(CONSTANT_ASSEMBLY_HASH_ALG_ID)
  INT16(CONSTANT_ASSEMBLY_MAJOR)
  INT16(CONSTANT_ASSEMBLY_MINOR)
  INT16(CONSTANT_ASSEMBLY_BUILD)
  INT16(CONSTANT_ASSEMBLY_REVISION)
  INT32(CONSTANT_ASSEMBLY_FLAGS)
  BLOB(CONSTANT_ASSEMBLY_PUBLIC_KEY)
  STRING(CONSTANT_ASSEMBLY_NAME)
  STRING(CONSTANT_ASSEMBLY_CULTURE))
  
DEF_TABLE_MASK(METHOD_AssemblyRef, 9,
  INT16(CONSTANT_ASSEMBLY_REF_MAJOR)
  INT16(CONSTANT_ASSEMBLY_REF_MINOR)
  INT16(CONSTANT_ASSEMBLY_REF_BUILD)
  INT16(CONSTANT_ASSEMBLY_REF_REVISION)
  INT32(CONSTANT_ASSEMBLY_REF_FLAGS)
  BLOB(CONSTANT_ASSEMBLY_REF_PUBLIC_KEY)
  STRING(CONSTANT_ASSEMBLY_REF_NAME)
  STRING(CONSTANT_ASSEMBLY_REF_CULTURE)
  BLOB(CONSTANT_ASSEMBLY_REF_HASH_VALUE))
  
DEF_TABLE_MASK(METHOD_Field, 3,
  INT16(CONSTANT_FIELD_FLAGS)
  STRING(CONSTANT_FIELD_NAME)
  BLOB(CONSTANT_FIELD_SIGNATURE))
  
DEF_TABLE_MASK(METHOD_InterfaceImpl, 2,
  TABLE(CONSTANT_TypeDef, CONSTANT_INTERFACE_IMPL_CLASS)
  TYPEDEF_OR_REF(CONSTANT_INTERFACE_IMPL_INTERFACE))
  
DEF_TABLE_MASK(METHOD_NestedClass, 2,
  TABLE(CONSTANT_TypeDef, CONSTANT_NESTED_CLASS_NESTED_CLASS)
  TABLE(CONSTANT_TypeDef, CONSTANT_NESTED_CLASS_ENCLOSING_CLASS))

DEF_TABLE_MASK(METHOD_MethodSpec, 2,
  METHODDEF_OR_REF(CONSTANT_METHOD_SPEC_METHOD)
  BLOB(CONSTANT_METHOD_SPEC_INSTANTIATION))

DEF_TABLE_MASK(METHOD_GenericParamConstraint, 2,
  TABLE(CONSTANT_GenericParam, CONSTANT_GENERIC_PARAM_CONSTRAINT_OWNER)
  TYPEDEF_OR_REF(CONSTANT_GENERIC_PARAM_CONSTRAINT_CONSTRAINT))
  
DEF_TABLE_MASK(METHOD_Constant, 3,
  INT16(CONSTANT_CONSTANT_TYPE)
  HAS_CONSTANT(CONSTANT_CONSTANT_PARENT)
  BLOB(CONSTANT_CONSTANT_VALUE))
  
DEF_TABLE_MASK(METHOD_FieldMarshal, 2,
  HAS_FIELD_MARSHAL(CONSTANT_FIELD_MARSHAL_PARENT)
  BLOB(CONSTANT_FIELD_MARSHAL_NATIVE_TYPE))
  
DEF_TABLE_MASK(METHOD_DeclSecurity, 3,
  INT16(CONSTANT_DECL_SECURITY_ACTION)
  HAS_DECL_SECURITY(CONSTANT_DECL_SECURITY_PARENT)
  BLOB(CONSTANT_DECL_SECURITY_PERMISSION_SET))

DEF_TABLE_MASK(METHOD_ClassLayout, 3,
  INT16(CONSTANT_CLASS_LAYOUT_PACKING_SIZE)
  INT32(CONSTANT_CLASS_LAYOUT_CLASS_SIZE)
  TABLE(CONSTANT_TypeDef, CONSTANT_CLASS_LAYOUT_PARENT))
  
DEF_TABLE_MASK(METHOD_FieldLayout, 2,
  INT32(CONSTANT_FIELD_LAYOUT_OFFSET)
  TABLE(CONSTANT_Field, CONSTANT_FIELD_LAYOUT_FIELD))

DEF_TABLE_MASK(METHOD_EventMap, 2,
  TABLE(CONSTANT_TypeDef, CONSTANT_EVENT_MAP_PARENT)
  TABLE(CONSTANT_Event, CONSTANT_EVEN_MAP_EVENT_LIST))

DEF_TABLE_MASK(METHOD_Event, 3,
  INT16(CONSTANT_EVENT_EVENT_FLAGS)
  STRING(CONSTANT_EVENT_NAME)
  TYPEDEF_OR_REF(CONSTANT_EVENT_TYPE))
  
DEF_TABLE_MASK(METHOD_PropertyMap, 2,
  TABLE(CONSTANT_TypeDef, CONSTANT_PROPERTY_MAP_PARENT)
  TABLE(CONSTANT_Property, CONSTANT_PROPERTY_MAP_PROPERTY_LIST))
  
DEF_TABLE_MASK(METHOD_Property, 3,
  INT16(CONSTANT_PROPERTY_FLAGS)
  STRING(CONSTANT_PROPERTY_NAME)
  BLOB(CONSTANT_PROPERTY_TYPE))
  
DEF_TABLE_MASK(METHOD_MethodSemantics, 3,
  INT16(CONSTANT_METHOD_SEMANTICS_SEMANTICS)
  TABLE(CONSTANT_MethodDef, CONSTANT_METHOD_SEMANTICS_METHOD)
  HAS_SEMANTICS(CONSTANT_METHOD_SEMANTICS_ASSOCIATION))

DEF_TABLE_MASK(METHOD_MethodImpl, 3,
  TABLE(CONSTANT_TypeDef, CONSTANT_METHOD_IMPL_CLASS)
  METHODDEF_OR_REF(CONSTANT_METHOD_IMPL_METHOD_BODY)
  METHODDEF_OR_REF(CONSTANT_METHOD_IMPL_METHOD_DECLARATION))
  
DEF_TABLE_MASK(METHOD_ModuleRef, 1,
  STRING(CONSTANT_MODULE_REF_NAME))
  
DEF_TABLE_MASK(METHOD_ImplMap, 4,
  INT16(CONSTANT_IMPL_MAP_MAPPING_FLAGS)
  MEMBER_FORWARDED(CONSTANT_IMPL_MAP_MEMBER_FORWARDED)
  STRING(CONSTANT_IMPL_MAP_IMPORT_NAME)
  TABLE(CONSTANT_ModuleRef, CONSTANT_IMPL_MAP_IMPORT_SCOPE))
  
DEF_TABLE_MASK(METHOD_FieldRva, 2,
  INT32(CONSTANT_FIELD_RVA_RVA)
  TABLE(CONSTANT_Field, CONSTANT_FIELD_RVA_FIELD))

DEF_TABLE_MASK(METHOD_ManifestResource, 4,
  INT32(CONSTANT_MANIFEST_RESOURCE_OFFSET)
  INT32(CONSTANT_MANIFEST_RESOURCE_FLAGS)
  STRING(CONSTANT_MANIFEST_RESOURCE_NAME)
  IMPLEMENTATION(CONSTANT_MANIFEST_RESOURCE_IMPLEMENTATION))
  
DEF_TABLE_MASK(METHOD_AssemblyProcessor, 1,
  INT32(CONSTANT_ASSEMBLY_PROCESSOR_PROCESSOR))
  
DEF_TABLE_MASK(METHOD_AssemblyOS, 3,
  INT32(CONSTANT_ASSEMBLY_OS_PLATFORM_ID)
  INT32(CONSTANT_ASSEMBLY_OS_MAJOR_VERSION)
  INT32(CONSTANT_ASSEMBLY_OS_MINOR_VERSION))
  
DEF_TABLE_MASK(METHOD_File, 3,
  INT32(CONSTANT_FILE_FLAGS)
  STRING(CONSTANT_FILE_NAME)
  BLOB(CONSTANT_FILE_HASH_VALUE))

DEF_TABLE_MASK(METHOD_GenericParam, 4,
  INT16(CONSTANT_GENERIC_PARAM_NUMBER)
  INT16(CONSTANT_GENERIC_PARAM_FLAGS)
  TYPE_OR_METHODDEF(CONSTANT_GENERIC_PARAM_OWNER)
  STRING(CONSTANT_GENERIC_PARAM_NAME))

void Header::print(mvm::PrintBuffer* buf) const {
  buf->write("Header<>");
}

void Section::print(mvm::PrintBuffer* buf) const {
  buf->write("Section<>");
}

void Table::print(mvm::PrintBuffer* buf) const {
  buf->write("Table<>");
}

void Stream::print(mvm::PrintBuffer* buf) const {
  buf->write("Table<>");
}

void Assembly::print(mvm::PrintBuffer* buf) const {
  buf->write("Assembly<");
  name->print(buf);
  buf->write(">");
}

static VMCommonClass* arrayDup(ClassNameCmp &cmp, Assembly* ass) {
  VMClassArray* cl = new(ass->allocator, "VMClassArray") VMClassArray();
  cl->initialise(ass->vm, true);
  cl->name = cmp.name;
  cl->nameSpace = cmp.nameSpace;
  cl->super = VMClassArray::SuperArray;
  cl->interfaces = VMClassArray::InterfacesArray;
  cl->virtualMethods = VMClassArray::VirtualMethodsArray;
  cl->staticMethods = VMClassArray::StaticMethodsArray;
  cl->virtualFields = VMClassArray::VirtualFieldsArray;
  cl->staticFields = VMClassArray::StaticFieldsArray;
  cl->depth = 1;
  cl->display.push_back(VMClassArray::SuperArray);
  cl->display.push_back(cl);
  cl->status = loaded;
  cl->assembly = ass;
  return cl; 
}

VMClassArray* Assembly::constructArray(VMCommonClass* base, uint32 dims) {
  if (this != base->assembly) 
    return base->assembly->constructArray(base, dims);

  ClassNameCmp CC(VMClassArray::constructArrayName(base->name, dims),
                  base->nameSpace);
  VMClassArray* cl = (VMClassArray*)(loadedNameClasses->lookupOrCreate(CC, this, arrayDup));
  if (!cl->baseClass) {
    cl->dims = dims;
    if (dims > 1)
      cl->baseClass = constructArray(base, dims - 1);
    else
      cl->baseClass = base;
  }
  return cl;
}

static VMCommonClass* pointerDup(ClassNameCmp &cmp, Assembly* ass) {
  VMClassPointer* cl = new(ass->allocator, "VMClassPointer") VMClassPointer();
  cl->initialise(ass->vm, false);
  cl->isPointer = true;
  cl->name = cmp.name;
  cl->nameSpace = cmp.nameSpace;
  cl->depth = 0;
  cl->display.push_back(cl);
  cl->status = loaded;
  cl->assembly = ass;
  return cl; 
}

VMClassPointer* Assembly::constructPointer(VMCommonClass* base, uint32 dims) {
  if (this != base->assembly) 
    return base->assembly->constructPointer(base, dims);
  
  ClassNameCmp CC(VMClassPointer::constructPointerName(base->name, dims),
                  base->nameSpace);
  VMClassPointer* cl = (VMClassPointer*)(loadedNameClasses->lookupOrCreate(CC, this, pointerDup));
  if (!cl->baseClass) {
    cl->dims = dims;
    cl->baseClass = base;
  }
  return cl;
}

VMClassArray* Assembly::constructArray(const UTF8* name, const UTF8* nameSpace,
                                       uint32 dims) {
  assert(this == ((N3*)VMThread::get()->getVM())->coreAssembly);
  ClassNameCmp CC(VMClassArray::constructArrayName(name, dims),
                  nameSpace);
  VMClassArray* cl = (VMClassArray*)(loadedNameClasses->lookupOrCreate(CC, this, arrayDup));
  cl->dims = dims;
  return cl;
}

static VMCommonClass* classDup(ClassNameCmp &cmp, Assembly* ass) {
  VMClass* cl = new(ass->allocator, "VMClass") VMClass();
  cl->initialise(ass->vm, false);
  cl->name = cmp.name;
  cl->nameSpace = cmp.nameSpace;
  cl->virtualTracer = 0;
  cl->staticInstance = 0;
  cl->virtualInstance = 0;
  cl->virtualType = 0;
  cl->super = 0;
  cl->status = hashed;
  cl->assembly = ass;
  return cl;
}

VMClass* Assembly::constructClass(const UTF8* name,
                                  const UTF8* nameSpace, uint32 token) {
  ClassNameCmp CC(name, nameSpace);
  VMClass* cl = (VMClass*)loadedNameClasses->lookupOrCreate(CC, this, classDup);
  loadedTokenClasses->lookupOrCreate(token, cl);
  cl->token = token;
  return cl;
}

static VMCommonClass* genClassDup(ClassNameCmp &cmp, Assembly* ass) {
  VMClass* cl = new(ass->allocator, "VMGenericClass") VMGenericClass();
  cl->initialise(ass->vm, false);
  cl->name = cmp.name;
  cl->nameSpace = cmp.nameSpace;
  cl->virtualTracer = 0;
  cl->staticInstance = 0;
  cl->virtualInstance = 0;
  cl->virtualType = 0;
  cl->super = 0;
  cl->status = hashed;
  cl->assembly = ass;
  return cl;
}

VMGenericClass* Assembly::constructGenericClass(const UTF8* name,
                                         const UTF8* nameSpace, std::vector<VMCommonClass*> genArgs, uint32 token) {
  uint32 size = name->size + 2;
  sint32 i = 0;
  for (std::vector<VMCommonClass*>::iterator it = genArgs.begin(), e = genArgs.end(); it!= e; ++it) {
    size += (*it)->name->size + 1;
  }
  uint16* buf = (uint16*) alloca(sizeof(uint16) * size);
  for (i = 0; i < name->size; i++) {
    buf[i] = name->elements[i];
  }
  buf[i++] = '<';
  for (std::vector<VMCommonClass*>::iterator it = genArgs.begin(), e = genArgs.end(); it!= e; ++it) {
    for (int j = 0; j < (*it)->name->size; i++, j++) {
      buf[i] = (*it)->name->elements[j];
    }
    buf[i++] = ',';
  }
  buf[i] = '>';
  const UTF8* genName = VMThread::get()->getVM()->bufToUTF8(buf, size);
  //printf("%s\n", mvm::PrintBuffer(genName).cString());
  
  ClassNameCmp CC(genName, nameSpace);
  VMGenericClass* cl = (VMGenericClass*) loadedNameClasses->lookupOrCreate(CC, this, genClassDup);
  
  cl->genericParams = genArgs; // TODO GC safe?
  cl->token = token;
  
  return cl;
}

static VMField* fieldDup(uint32& key, Assembly* ass) {
  VMField* field = new(ass->allocator, "VMField") VMField();
  field->token = key;
  return field;
}

VMField*  Assembly::constructField(VMClass* cl, const UTF8* name,
                                   VMCommonClass* signature,
                                   uint32 token, VMGenericClass* genClass, VMGenericMethod* genMethod) {
  VMField* field; 
  
  if (genClass == 0) {
    // we are not reading a generic class 
    field = loadedTokenFields->lookupOrCreate(token, this, fieldDup);
  } else {
    // we are reading a generic class, don't add a reference
    // to the loadedTokenFields map
    field = fieldDup(token, this);
  }
  
  field->classDef = cl;
  field->signature = signature;
  field->name = name;
  
  return field;
}

static VMMethod* methodDup(uint32& key, Assembly* ass) {
  VMMethod* meth = new(ass->allocator, "VMMethod") VMMethod();
  meth->token = key;
  meth->canBeInlined = false;
  return meth;
}

static VMGenericMethod* genMethodDup(uint32& key, Assembly* ass) {
  VMGenericMethod* meth = new(ass->allocator, "VMGenericMethod") VMGenericMethod();
  meth->token = key;
  meth->canBeInlined = false;
  return meth;
}

VMMethod* Assembly::constructMethod(VMClass* cl, const UTF8* name, 
                                    uint32 token, bool generic,
                                    std::vector<VMCommonClass*>* genMethodInstantiation, VMGenericClass* genClass) {
  VMMethod* meth;
  
  if (genClass == 0 && generic == false) {
    // we are not reading a generic class 
    meth = loadedTokenMethods->lookupOrCreate(token, this, methodDup);
  } else {
    // we are reading a generic class or a generic method, don't add a reference
    // to the loadedTokenMethods map
    meth = methodDup(token, this);
    
    if (generic) {
      // we are reading a generic method
      if (genMethodInstantiation == NULL) {
        cl->genericMethods.push_back(meth);
      } else {
        VMGenericMethod* genMethod = genMethodDup(token, this);
        genMethod->genericParams = *genMethodInstantiation;
        meth = genMethod;
        if (isStatic(meth->flags)) {
          cl->staticMethods.push_back(meth);
        } else {
          cl->virtualMethods.push_back(meth);
        }
      }
    }
  }
  
  meth->classDef = cl;
  meth->_signature = 0;
  meth->name = name;
  
  return meth;
}

Assembly::Assembly(mvm::BumpPtrAllocator &allocator, N3 *vm, const UTF8 *name) : allocator(allocator) {
	this->lockVar = new mvm::LockRecursive();
  this->loadedNameClasses =  new(allocator, "ClassNameMap")   ClassNameMap();
  this->loadedTokenClasses = new(allocator, "ClassTokenMap")  ClassTokenMap();
  this->loadedTokenMethods = new(allocator, "MethodTokenMap") MethodTokenMap();
  this->loadedTokenFields =  new(allocator, "FieldTokenMap")  FieldTokenMap();

  this->assemblyRefs = 0;
  this->isRead = false;
	this->vm = vm;
  this->name = name;
}

static void unimplemented(uint32 index,
                          std::vector<Table*, gc_allocator<Table*> >& tables,
                          uint32 heapSizes) {
  VMThread::get()->getVM()->error("Unknown table %x", index);
}

maskVector_t Assembly::maskVector[64] = {
  METHOD_Module,                // 0x00
  METHOD_TypeRef,               // 0x01
  METHOD_TypeDef,               // 0x02
  unimplemented,                // 0x03
  METHOD_Field,                 // 0x04
  unimplemented,                // 0x05
  METHOD_MethodDef,             // 0x06
  unimplemented,                // 0x07
  METHOD_Param,                 // 0x08
  METHOD_InterfaceImpl,         // 0x09
  METHOD_MemberRef,             // 0x0A
  METHOD_Constant,              // 0x0B
  METHOD_CustomAttribute,       // 0x0C
  METHOD_FieldMarshal,          // 0x0D
  METHOD_DeclSecurity,          // 0x0E
  METHOD_ClassLayout,           // 0x1F
  METHOD_FieldLayout,           // 0x10
  METHOD_StandaloneSig,         // 0x11
  METHOD_EventMap,              // 0x12
  unimplemented,                // 0x13
  METHOD_Event,                 // 0x14
  METHOD_PropertyMap,           // 0x15
  unimplemented,                // 0x16
  METHOD_Property,              // 0x17
  METHOD_MethodSemantics,       // 0x18
  METHOD_MethodImpl,            // 0x19
  METHOD_ModuleRef,             // 0x1A
  METHOD_TypeSpec,              // 0x1B
  METHOD_ImplMap,               // 0x1C
  METHOD_FieldRva,              // 0x1D
  unimplemented,                // 0x1E
  unimplemented,                // 0x1F
  METHOD_Assembly,              // 0x20
  METHOD_AssemblyProcessor,     // 0x21
  METHOD_AssemblyOS,            // 0x22
  METHOD_AssemblyRef,           // 0x23
  unimplemented,                // 0x24
  unimplemented,                // 0x25
  METHOD_File,                  // 0x26
  unimplemented,                // 0x27
  METHOD_ManifestResource,      // 0x28
  METHOD_NestedClass,           // 0x29
  METHOD_GenericParam,          // 0x2A
  METHOD_MethodSpec,            // 0x2B
  METHOD_GenericParamConstraint,// 0x2C
  unimplemented,
  unimplemented,
  unimplemented,
  unimplemented, 
  unimplemented,
  unimplemented,
  unimplemented,
  unimplemented,
  unimplemented,
  unimplemented,
  unimplemented,
  unimplemented,
  unimplemented,
  unimplemented,
  unimplemented,
  unimplemented,
  unimplemented,
  unimplemented,
  unimplemented
};

const char* Assembly::maskVectorName[64] = {
  "METHOD_Module",                // 0x00
  "METHOD_TypeRef",               // 0x01
  "METHOD_TypeDef",               // 0x02
  "unimplemented",                // 0x03
  "METHOD_Field",                 // 0x04
  "unimplemented",                // 0x05
  "METHOD_MethodDef",             // 0x06
  "unimplemented",                // 0x07
  "METHOD_Param",                 // 0x08
  "METHOD_InterfaceImpl",         // 0x09
  "METHOD_MemberRef",             // 0x0A
  "METHOD_Constant",              // 0x0B
  "METHOD_CustomAttribute",       // 0x0C
  "METHOD_FieldMarshal",          // 0x0D
  "METHOD_DeclSecurity",          // 0x0E
  "METHOD_ClassLayout",           // 0x1F
  "METHOD_FieldLayout",           // 0x10
  "METHOD_StandaloneSig",         // 0x11
  "METHOD_EventMap",              // 0x12
  "unimplemented",                // 0x13
  "METHOD_Event",                 // 0x14
  "METHOD_PropertyMap",           // 0x15
  "unimplemented",                // 0x16
  "METHOD_Property",              // 0x17
  "METHOD_MethodSemantics",       // 0x18
  "METHOD_MethodImpl",            // 0x19
  "METHOD_ModuleRef",             // 0x1A
  "METHOD_TypeSpec",              // 0x1B
  "METHOD_ImplMap",               // 0x1C
  "METHOD_FieldRva",              // 0x1D
  "unimplemented",                // 0x1E
  "unimplemented",                // 0x1F
  "METHOD_Assembly",              // 0x20
  "METHOD_AssemblyProcessor",     // 0x21
  "METHOD_AssemblyOS",            // 0x22
  "METHOD_AssemblyRef",           // 0x23
  "unimplemented",                // 0x24
  "unimplemented",                // 0x25
  "METHOD_File",                  // 0x26
  "unimplemented",                // 0x27
  "METHOD_ManifestResource",      // 0x28
  "METHOD_NestedClass",           // 0x29
  "METHOD_GenericParam",          // 0x2A
  "METHOD_MethodSpec",            // 0x2B
  "METHOD_GenericParamConstraint", // 0x2C
  "unimplemented",
  "unimplemented",
  "unimplemented",
  "unimplemented", 
  "unimplemented",
  "unimplemented",
  "unimplemented",
  "unimplemented",
  "unimplemented",
  "unimplemented",
  "unimplemented",
  "unimplemented",
  "unimplemented",
  "unimplemented",
  "unimplemented",
  "unimplemented",
  "unimplemented",
  "unimplemented",
  "unimplemented"
};

#define EXTRACT_SIZE(bitmask, index) \
  (1 + (3 & (bitmask >> (index << 1))))

void Table::readRow(uint32* result, uint32 row, ByteCode* array) {
  uint32 rowOffset = offset + ((row - 1) * rowSize);
  for (uint32 i = 0; i < count; ++i) {
    uint32 size = EXTRACT_SIZE(sizeMask, i);
    switch(size) {
      case 1: VMThread::get()->getVM()->error("implement me"); break;
      case 2: result[i] = READ_U2(array, rowOffset); break;
      case 4: result[i] = READ_U4(array, rowOffset); break;
      default: VMThread::get()->getVM()->error("unknown size %d", size); break;
    }
  }
}

uint32 Table::readIndexInRow(uint32 row, uint32 index, ByteCode* array) {
  uint32 indexOffset = offset + ((row - 1) * rowSize);
  for (uint32 i = 0; i < index; ++i) {
    indexOffset += EXTRACT_SIZE(sizeMask, i);
  }

  uint32 size = EXTRACT_SIZE(sizeMask, index);

  switch(size) {
    case 1: VMThread::get()->getVM()->error("implement me"); break;
    case 2: return READ_U2(array, indexOffset);
    case 4: return READ_U4(array, indexOffset);
    default: VMThread::get()->getVM()->error("unknown size %d", size); break;
  }

  // unreachable
  return 0;
}

void Section::read(Reader* reader, N3* vm) {
  name = (char*) malloc(SECTION_NAME_LENGTH);
  memcpy(name, &(reader->bytes->elements[reader->cursor]),
             SECTION_NAME_LENGTH);
  reader->cursor += SECTION_NAME_LENGTH;

  virtualSize       = reader->readU4();
  virtualAddress    = reader->readU4();
  rawSize           = reader->readU4();
  rawAddress        = reader->readU4();
  relocAddress      = reader->readU4();
  lineNumbers       = reader->readU4();
  relocationsNumber = reader->readU2();
  lineNumbersNumber = reader->readU2();
  characteristics   = reader->readU4();
}

void Header::read(mvm::BumpPtrAllocator &allocator, Reader* reader, N3* vm) {
  uint32 start = reader->cursor;
  signature = reader->readU4();
  major = reader->readU2();
  minor = reader->readU2();
  reserved = reader->readU4();
  versionLength = reader->readU4();
  versionName = Assembly::readUTF8(vm, versionLength, reader);
  flags = reader->readU2();
  nbStreams = reader->readU2();

  for (uint32 i = 0; i < nbStreams; ++i) {
    uint32 offset = reader->readU4();
    uint32 size = reader->readU4();
    uint32 len = 
      strlen((char*)(&(reader->bytes->elements[reader->cursor])));

    Stream* stream = new(allocator, "Stream") Stream();
    char* str = (char*)malloc(len + 1);
    memcpy(str, &(reader->bytes->elements[reader->cursor]), len + 1);
    reader->cursor += (len + (4 - (len % 4)));

    stream->realOffset = start + offset;
    stream->size = size;
    stream->name = str;

    if (!(strcmp(str, "#~"))) tildStream = stream;
    else if (!(strcmp(str, "#Strings"))) stringStream = stream;
    else if (!(strcmp(str, "#US"))) usStream = stream;
    else if (!(strcmp(str, "#Blob"))) blobStream = stream;
    else if (!(strcmp(str, "#GUID"))) guidStream = stream;
    else VMThread::get()->getVM()->error("invalid stream %s", str);
  }
}

const ArrayChar* Assembly::readUTF16(N3* vm, uint32 len, 
                                Reader* reader) {
	declare_gcroot(const ArrayChar*, res) = readUTF16(vm, len, reader->bytes, reader->cursor);
  return res;
}

const ArrayChar* Assembly::readUTF16(N3* vm, uint32 len, 
																			 ByteCode* bytes, uint32 &offset) {
  uint32 realLen = len >> 1;
  uint16* buf = (uint16*)alloca(len);
  uint32 i = 0;
  while (i < realLen) {
    uint16 cur = READ_U2(bytes, offset);
    buf[i] = cur;
    ++i;
  }
	declare_gcroot(ArrayChar*, res) = vm->bufToArray(buf, realLen); 
	return res;
}

const UTF8* Assembly::readUTF8(N3* vm, uint32 len, Reader* reader) {
  return readUTF8(vm, len, reader->bytes, reader->cursor);
}

const UTF8* Assembly::readUTF8(N3* vm, uint32 len,
                               ByteCode* bytes, uint32 &offset) {
  uint16* buf = (uint16*)alloca(len * sizeof(uint16));
  uint32 n = 0;
  uint32 i = 0;
  
  while (i < len) {
    uint32 cur = READ_U1(bytes, offset);
    if (cur & 0x80) {
      uint32 y = READ_U1(bytes, offset);
      if (cur & 0x20) {
        uint32 z = READ_U1(bytes, offset);
        cur = ((cur & 0x0F) << 12) +
              ((y & 0x3F) << 6) +
              (z & 0x3F);
        i += 3;
      } else {
        cur = ((cur & 0x1F) << 6) +
              (y & 0x3F);
        i += 2;
      }
    } else {
      ++i;
    }
    buf[n] = ((uint16)cur);
    ++n;
  }

  const UTF8* utf8 = vm->bufToUTF8(buf, n);

  return utf8;
}

const UTF8* Assembly::readString(N3* vm, uint32 offset) {
  uint32 end = offset;
  uint32 cur = 0;
  while ((cur = READ_U1(bytes, end)) != 0) {}
  return readUTF8(vm, (end - 1 - offset), bytes, offset);
}

void Assembly::readTables(Reader* reader) {
  //uint32 reserved1 = 
  reader->readU4();
  //uint8 major = 
  reader->readU1();
  //uint8 minor = 
  reader->readU1();
  uint8 heapSizes = reader->readU1();
  //uint8 reserved2 = 
  reader->readU1();
  uint32 validLow = reader->readU4();
  uint32 validHigh = reader->readU4();
  //uint32 sortedLow = 
  reader->readU4();
  //uint32 sortedHigh = 
  reader->readU4();
  uint32 tableNumber = 0;
  uint32 offset = 0;

  for (uint32 i = 0; i < 32; ++i) {
    Table* table = new(allocator, "Table") Table();
    if ((1 << i) & validLow) {
      table->rowsNumber = reader->readU4();
      ++tableNumber;
    } else {
      table->rowsNumber = 0;
    }
    CLIHeader->tables.push_back(table);
  }

  for (uint32 i = 0; i < 32; ++i) {
    Table* table = new(allocator, "Table") Table();
    if ((1 << i) & validHigh) {
      table->rowsNumber = reader->readU4();
      ++tableNumber;
    } else {
      table->rowsNumber = 0;
    }
    CLIHeader->tables.push_back(table);
  }

  offset = reader->cursor;
  
  uint32 index = 0;
  for (std::vector<Table*, gc_allocator<Table*> >::iterator i = 
           CLIHeader->tables.begin(),
       e = CLIHeader->tables.end(); i != e; ++i, ++index) {
    Table* table = (*i);
    if (table->rowsNumber) {
      maskVector[index](index, CLIHeader->tables, heapSizes);
      table->offset = offset;
      offset += (table->rowsNumber * table->rowSize);
    }
  }
}

Reader *Assembly::newReader(ByteCode* array, uint32 start, uint32 end) { 
	return new(allocator, "Reader") Reader(array, start, end); 
}

int Assembly::resolve(int doResolve, const char *ext) {
	if(!bytes)
		open(ext);

	if(bytes && doResolve && !isRead) {
		lockVar->lock();
		if(!isRead) {
			Reader* reader = newReader(bytes);
			PRINT_DEBUG(N3_LOAD, 1, LIGHT_GREEN, "Reading %s::%s", mvm::PrintBuffer(vm).cString(),
									mvm::PrintBuffer(this).cString());

			textSection =  new(allocator, "Section") Section();
			rsrcSection =  new(allocator, "Section") Section();
			relocSection = new(allocator, "Section") Section();

			reader->seek(TEXT_SECTION_HEADER, Reader::SeekSet);
			textSection->read(reader, vm);
			rsrcSection->read(reader, vm);
			relocSection->read(reader, vm);

			reader->seek(CLI_HEADER, Reader::SeekSet);
			CLIHeaderLocation = reader->readU4();
			reader->seek(textSection->rawAddress + 
									 (CLIHeaderLocation - textSection->virtualAddress),
									 Reader::SeekSet);

			cb          = reader->readU4();
			major       = reader->readU2();
			minor       = reader->readU2();
			mdRva       = reader->readU4();
			mdSize      = reader->readU4();
			flags       = reader->readU4();
			entryPoint  = reader->readU4();
			resRva      = reader->readU4();
			resSize     = reader->readU4();
  
			reader->seek(textSection->rawAddress + (mdRva - textSection->virtualAddress),
									 Reader::SeekSet);

			CLIHeader = new (allocator, "Header") Header();
			CLIHeader->read(allocator, reader, vm);

			reader->seek(CLIHeader->tildStream->realOffset, Reader::SeekSet);

			readTables(reader);

			isRead = 1;
		}
		lockVar->unlock();
	}

	return bytes ? (doResolve ? isRead : 1) : 0;
}

int Assembly::open(const char *ext) {
	lockVar->lock();
	mvm::PrintBuffer _asciiz = mvm::PrintBuffer(name);
	const char* asciiz = _asciiz.cString();
	uint32 alen = strlen(asciiz);

	uint32 idx = 0;

	while ((bytes == 0) && (idx < vm->assemblyPath.size())) {
		const char* cur = vm->assemblyPath[idx];
		uint32 strLen = strlen(cur);
		char* buf = (char*)alloca(strLen + alen + 16);

		if (ext != 0) {
			sprintf(buf, "%s%s.%s", cur, asciiz, ext);
		} else {
			sprintf(buf, "%s%s", cur, asciiz);
		}
			
		bytes = Reader::openFile(allocator, buf);
		++idx;
	}
	lockVar->unlock();

	return bytes ? 1 : 0;
}

uint32 Assembly::getTypeDefTokenFromMethod(uint32 token) {
  uint32 index = token & 0xffff;
  Table* typeTable = CLIHeader->tables[CONSTANT_TypeDef];
  uint32 nbRows = typeTable->rowsNumber;
  bool found = false;
  uint32 i = 0;
  
  while (!found && (i < nbRows - 1)) {
    
    uint32 myId = typeTable->readIndexInRow(i + 1, CONSTANT_TYPEDEF_METHODLIST,
                                            bytes);
    uint32 nextId = typeTable->readIndexInRow(i + 2, CONSTANT_TYPEDEF_METHODLIST,
                                              bytes);

    if (index < nextId && index >= myId) {
      found = true;
    } else {
      ++i;
    }
  }
  
  return i + 1 + (CONSTANT_TypeDef << 24);
}

VMCommonClass* Assembly::readTypeSpec(N3* vm, uint32 index, VMGenericClass* genClass, VMGenericMethod* genMethod) {
  uint32 blobOffset = CLIHeader->blobStream->realOffset;
  Table* typeTable  = CLIHeader->tables[CONSTANT_TypeSpec];
  uint32* typeArray = (uint32*)alloca(sizeof(uint32) * typeTable->rowSize);
  typeTable->readRow(typeArray, index, bytes);
  
  uint32 signOffset = typeArray[CONSTANT_TYPESPEC_SIGNATURE];
  
  uint32 offset = blobOffset + signOffset;
  return extractTypeInSignature(offset, genClass, genMethod);
  
}

VMCommonClass* Assembly::lookupClassFromName(const UTF8* name,
                                             const UTF8* nameSpace) {
  ClassNameCmp CC(name, nameSpace);
  return loadedNameClasses->lookup(CC);
}

VMCommonClass* Assembly::lookupClassFromToken(uint32 token) {
  return loadedTokenClasses->lookup(token);
}

VMMethod* Assembly::lookupMethodFromToken(uint32 token) {
  return loadedTokenMethods->lookup(token);
}
VMField* Assembly::lookupFieldFromToken(uint32 token) {
  return loadedTokenFields->lookup(token);
}



VMCommonClass* Assembly::getClassFromName(N3* vm, const UTF8* name,
                                          const UTF8* nameSpace) {
  VMCommonClass* type = lookupClassFromName(name, nameSpace);

  if (type == 0) {
    Table* typeTable  = CLIHeader->tables[CONSTANT_TypeDef];
    uint32 nb = typeTable->rowsNumber;
    uint32 stringOffset = CLIHeader->stringStream->realOffset;

    for (uint32 i = 0; i < nb; ++i) {
      uint32 value = typeTable->readIndexInRow(i + 1, CONSTANT_TYPEDEF_NAME, bytes);
      const UTF8* curName = readString(vm, stringOffset + value);
      if (name == curName) {
        uint32 value = typeTable->readIndexInRow(i + 1,
                                                 CONSTANT_TYPEDEF_NAMESPACE,
                                                 bytes);
        const UTF8* curNameSpace = readString(vm, stringOffset + value);
        if (curNameSpace == nameSpace) {
          return readTypeDef(vm, i + 1);
        }
      }
    }
  }

  return type;
}

Assembly* Assembly::readAssemblyRef(N3* vm, uint32 index) {
  if (assemblyRefs == 0) {
    uint32 size = sizeof(Assembly*)*
                      CLIHeader->tables[CONSTANT_AssemblyRef]->rowsNumber;
    assemblyRefs = (Assembly**)malloc(size);
    memset(assemblyRefs, 0, size);
  }
  Assembly* ref = assemblyRefs[index - 1];
  if (ref == 0) {
    uint32 stringOffset = CLIHeader->stringStream->realOffset;
    Table* assTable = CLIHeader->tables[CONSTANT_AssemblyRef];
    uint32* assArray = (uint32*)alloca(sizeof(uint32) * assTable->rowSize);
    assTable->readRow(assArray, index, bytes);
    const UTF8* name = 
      readString(vm, stringOffset + assArray[CONSTANT_ASSEMBLY_REF_NAME]);
    
    ref = vm->constructAssembly(name);

    if(!ref->resolve(1, "dll"))
			 VMThread::get()->getVM()->error("implement me");

    assemblyRefs[index - 1] = ref;
  }
  return ref;
}

VMCommonClass* Assembly::readTypeRef(N3* vm, uint32 index) {
  uint32 stringOffset = CLIHeader->stringStream->realOffset;
  
  Table* typeTable  = CLIHeader->tables[CONSTANT_TypeRef];
  uint32* typeArray = (uint32*)alloca(sizeof(uint32) * typeTable->rowSize);
  
  typeTable->readRow(typeArray, index, bytes);

  uint32 resScope   = typeArray[CONSTANT_TYPEREF_RESOLUTION_SCOPE];
  uint32 name       = typeArray[CONSTANT_TYPEREF_NAME];
  uint32 nameSpace  = typeArray[CONSTANT_TYPEREF_NAMESPACE];
  

  uint32 val = resScope & 3;
  uint32 entry = resScope >> 2;
  VMCommonClass* type = 0;
  
  switch (val) {
    case 0: VMThread::get()->getVM()->error("implement me %d %d", val, entry); break;
    case 1: VMThread::get()->getVM()->error("implement me %d, %d", val, entry); break;
    case 2: {
      Assembly* refAssembly = readAssemblyRef(vm, entry);
      type = refAssembly->getClassFromName(vm, readString(vm, stringOffset + name), 
                                           readString(vm, stringOffset + nameSpace));
      break;
    }
    case 3: VMThread::get()->getVM()->error("implement me %d %d",val, entry); break;
    default: 
      VMThread::get()->getVM()->error("unkknown resolution scope %x", val);
      break;
  }
  return type;
}

VMClass* Assembly::readTypeDef(N3* vm, uint32 index) {
  return readTypeDef(vm, index, (std::vector<VMCommonClass*>) 0);
}

VMClass* Assembly::readTypeDef(N3* vm, uint32 index, std::vector<VMCommonClass*> genArgs) {
  uint32 token = (CONSTANT_TypeDef << 24) + index;
  uint32 stringOffset = CLIHeader->stringStream->realOffset;

  Table* typeTable  = CLIHeader->tables[CONSTANT_TypeDef];
  uint32* typeArray = (uint32*)alloca(sizeof(uint32) * typeTable->rowSize);
  
  typeTable->readRow(typeArray, index, bytes);

  uint32 flags      = typeArray[CONSTANT_TYPEDEF_FLAGS];
  uint32 name       = typeArray[CONSTANT_TYPEDEF_NAME];
  uint32 nameSpace  = typeArray[CONSTANT_TYPEDEF_NAMESPACE];
  uint32 extends    = typeArray[CONSTANT_TYPEDEF_EXTENDS];
  //uint32 fieldList  = typeArray[CONSTANT_TYPEDEF_FIELDLIST];
  //uint32 methodList = typeArray[CONSTANT_TYPEDEF_METHODLIST];

  //Table* fieldTable   = CLIHeader->tables[CONSTANT_Field];
  //uint32 fieldSize    = fieldTable->rowsNumber;
  //Table* methodTable  = CLIHeader->tables[CONSTANT_MethodDef];
  //uint32 methodSize   = methodTable->rowsNumber;

  VMClass* type;
  
  if (genArgs == (std::vector<VMCommonClass*>) 0) {
    type = constructClass(readString(vm, name + stringOffset),
                          readString(vm, nameSpace + stringOffset),
                          token);
  } else {
	// generic type
	type = constructGenericClass(readString(vm, name + stringOffset),
                                 readString(vm, nameSpace + stringOffset),
                                 genArgs, token);
  }

  type->vm = vm;

  uint32 val = 3 & extends;
  uint32 entry = extends >> 2;

  switch (val) {
    case 0: {
      type->superToken = entry + (CONSTANT_TypeDef << 24);
      break;
    }
    case 1: {
      type->superToken = entry + (CONSTANT_TypeRef << 24);
      break;
    }
    case 2: {
      VMThread::get()->getVM()->error("implement me");
      break;
    }
    default: {
      VMThread::get()->getVM()->error("implement me");
      break;
    }
  }

  getInterfacesFromTokenType(type->interfacesToken, token);
  type->flags = flags;

  return type;
}

void Assembly::getInterfacesFromTokenType(std::vector<uint32>& tokens,
                                          uint32 token) {
  uint32 index = token & 0xffff;
  Table* interfacesTable = CLIHeader->tables[CONSTANT_InterfaceImpl];
  uint32 nbRows = interfacesTable->rowsNumber;

  for (uint32 i = 0; i < nbRows; ++i) {
    uint32 interfaceId = 
      interfacesTable->readIndexInRow(i + 1, CONSTANT_INTERFACE_IMPL_CLASS,
                                      bytes);
    if (interfaceId == index) {
      uint32 cl = interfacesTable->readIndexInRow(i + 1,
                                        CONSTANT_INTERFACE_IMPL_INTERFACE,
                                        bytes);
      uint32 table = cl & 3;
      uint32 interfaceToken = cl >> 2;

      switch (table) {
        case 0: interfaceToken += (CONSTANT_TypeDef << 24); break;
        case 1: interfaceToken += (CONSTANT_TypeRef << 24); break;
        case 2: interfaceToken += (CONSTANT_TypeSpec << 24); break;
        default: VMThread::get()->getVM()->error("unknown table %x", table); break;
      }
      tokens.push_back(interfaceToken);
    }
  }
}

VMCommonClass* Assembly::loadType(N3* vm, uint32 token, bool resolve,
                            bool resolveStatic, bool clinit, bool dothrow, VMGenericClass* genClass, VMGenericMethod* genMethod) {
	return loadType(vm, token, resolve, resolveStatic, clinit, dothrow, (std::vector<VMCommonClass*>) 0, genClass, genMethod);
}


VMCommonClass* Assembly::loadType(N3* vm, uint32 token, bool resolve,
                            bool resolveStatic, bool clinit, bool dothrow,
                            std::vector<VMCommonClass*> genArgs, VMGenericClass* genClass, VMGenericMethod* genMethod) {
  
  VMCommonClass* type = lookupClassFromToken(token);
  if (!type || type->status == hashed) {
    uint32 table = token >> 24;
    uint32 index = token & 0xffff;

    if (table == CONSTANT_TypeDef) {
      type = readTypeDef(vm, index, genArgs);
    } else if (table == CONSTANT_TypeRef) {
      type = readTypeRef(vm, index);
    } else if (table == CONSTANT_TypeSpec) {
      type = readTypeSpec(vm, index, genClass, genMethod);
    } else {
      VMThread::get()->getVM()->error("implement me %x", token);
    }
  }

  if (type == 0) VMThread::get()->getVM()->error("implement me");
  if (type->status == hashed) {
    type->aquire();
    if (type->status == hashed) {
      type->status = loaded;
    }
    type->release();
  }

  if (resolve) type->resolveType(resolveStatic, clinit, genMethod);

  return type;
}

void Assembly::readClass(VMCommonClass* cl, VMGenericMethod* genMethod) {
  uint32 index = cl->token & 0xffff;
  Table* typeTable = CLIHeader->tables[CONSTANT_TypeDef];
  uint32 typeSize = typeTable->rowsNumber;
  uint32* typeArray = (uint32*)alloca(sizeof(uint32) * typeTable->rowSize);
  typeTable->readRow(typeArray, index, bytes);
  
  uint32 fieldList  = typeArray[CONSTANT_TYPEDEF_FIELDLIST];
  uint32 methodList = typeArray[CONSTANT_TYPEDEF_METHODLIST];

  Table* fieldTable   = CLIHeader->tables[CONSTANT_Field];
  uint32 fieldSize    = fieldTable->rowsNumber;
  Table* methodTable  = CLIHeader->tables[CONSTANT_MethodDef];
  uint32 methodSize   = methodTable->rowsNumber;
  
  getProperties(cl, static_cast<VMGenericClass*>(cl), genMethod);

  if (methodList && methodTable != 0 && methodList <= methodSize) {
    uint32 endMethod = (index == typeSize) ? 
        methodSize + 1 : 
        typeTable->readIndexInRow(index + 1, CONSTANT_TYPEDEF_METHODLIST,
                                  bytes);

    uint32 nbMethods = endMethod - methodList;

    for (uint32 i = 0; i < nbMethods; ++i) {
      VMMethod* meth = readMethodDef(i + methodList, cl, NULL, static_cast<VMGenericClass*>(cl));
      
      if (meth != NULL) {
        if (isStatic(meth->flags)) {
          cl->staticMethods.push_back(meth);
        } else {
          cl->virtualMethods.push_back(meth);
        }
      }
    }
  }
  
  if (fieldList && fieldTable != 0 && fieldList <= fieldSize) {
    uint32 endField = (index == typeSize) ? 
        fieldSize + 1 : 
        typeTable->readIndexInRow(index + 1, CONSTANT_TYPEDEF_FIELDLIST, bytes);

    uint32 nbFields = endField - fieldList;

    for (uint32 i = 0; i < nbFields; ++i) {
      VMField* field = readField(i + fieldList, cl, static_cast<VMGenericClass*>(cl), genMethod);
      if (isStatic(field->flags)) {
        cl->staticFields.push_back(field);
      } else {
        cl->virtualFields.push_back(field);
      }
    }
  }
}

void Assembly::readCustomAttributes(uint32 offset, std::vector<llvm::GenericValue>& args, VMMethod* meth) {
  uncompressSignature(offset);
  uint16 prolog = READ_U2(bytes, offset);

  if (prolog != 0x1) VMThread::get()->getVM()->error("unknown prolog");

  uint32 start = meth->virt ? 1 : 0;

  for (uint32 i = start + 1; i < meth->parameters.size(); ++i) {
    if (meth->parameters[i] == MSCorlib::pSInt32) {
      llvm::GenericValue gv;
      gv.IntVal = llvm::APInt(32, READ_U4(bytes, offset));
      args.push_back(gv);
    } else {
      VMThread::get()->getVM()->error("implement me");
    }
  }

}

ArrayObject* Assembly::getCustomAttributes(uint32 token, VMCommonClass* cl) {
  Table* attrTable = CLIHeader->tables[CONSTANT_CustomAttribute];
  uint32 attrSize = attrTable->rowsNumber;
  uint32* attrArray = (uint32*)alloca(sizeof(uint32) * attrTable->rowSize);
  std::vector<VMObject*> vec;

  for (uint32 i = 0; i < attrSize; ++i) {
    attrTable->readRow(attrArray, i + 1, bytes);
    uint32 meth = attrArray[CONSTANT_CUSTOM_ATTRIBUTE_TYPE];
    uint32 table = meth & 7;
    uint32 index = meth >> 3;
    VMMethod* cons = 0;

    switch(table) {
      default: 
        VMThread::get()->getVM()->error("implement me"); 
        break;
      case 2: 
        cons = getMethodFromToken(index + (CONSTANT_MethodDef << 24), NULL, NULL);
        break;
      case 3:
        cons = getMethodFromToken(index + (CONSTANT_MemberRef << 24), NULL, NULL);
        break;
    }

    if (cl == cons->classDef) {
      uint32 blobOffset = CLIHeader->blobStream->realOffset;
      std::vector<llvm::GenericValue> args;
      declare_gcroot(VMObject*, obj) = cons->classDef->doNew();
      args.push_back(llvm::GenericValue(obj));
      readCustomAttributes(blobOffset + attrArray[CONSTANT_CUSTOM_ATTRIBUTE_VALUE], args, cons);

      cons->compileToNative()->invokeGeneric(args);
      vec.push_back(obj);
    }
  }

  declare_gcroot(ArrayObject*, res) = (ArrayObject*)MSCorlib::arrayObject->doNew(vec.size());
  for (uint32 i = 0; i < vec.size(); ++i)
    res->elements[i] = vec[i];
  
  return res;
}

void Assembly::getProperties(VMCommonClass* cl, VMGenericClass* genClass, VMGenericMethod *genMethod) {
  uint32 index = cl->token & 0xffff;
  Table* mapTable = CLIHeader->tables[CONSTANT_PropertyMap];
  uint32 mapSize = mapTable->rowsNumber;
  
  Table* propertyTable = CLIHeader->tables[CONSTANT_Property];
  uint32 propertySize = propertyTable->rowsNumber;
  
  uint32 propertyList = 0;
  uint32 i = 0;

  while (!propertyList && i != mapSize) {
    uint32 parent = mapTable->readIndexInRow(i + 1,
                                        CONSTANT_PROPERTY_MAP_PARENT, bytes);
    if (parent == index) {
      propertyList = mapTable->readIndexInRow(i + 1,
                                  CONSTANT_PROPERTY_MAP_PROPERTY_LIST, bytes);
    } else {
      ++i;
    }
  }

  if (propertyList && propertyTable != 0 && propertyList <= propertySize) {
    uint32 endProperty = (i + 1 == mapSize) ? 
        propertySize + 1 : 
        mapTable->readIndexInRow(i + 2, CONSTANT_PROPERTY_MAP_PROPERTY_LIST,
                                 bytes);
    uint32 nbProperties = endProperty - propertyList;

    for (uint32 j = 0; j < nbProperties; ++j) {
      cl->properties.push_back(readProperty(j + propertyList, cl, genClass, genMethod));
    }

  } 
}

Property* Assembly::readProperty(uint32 index, VMCommonClass* cl, VMGenericClass* genClass, VMGenericMethod* genMethod) {
  uint32 stringOffset = CLIHeader->stringStream->realOffset;
  uint32 blobOffset = CLIHeader->blobStream->realOffset;
  
  Table* propTable  = CLIHeader->tables[CONSTANT_Property];
  uint32* propArray = (uint32*)alloca(sizeof(uint32) * propTable->rowSize);
  
  propTable->readRow(propArray, index, bytes);

  uint32 flags      = propArray[CONSTANT_PROPERTY_FLAGS];
  uint32 nameIndex  = propArray[CONSTANT_PROPERTY_NAME];
  uint32 type       = propArray[CONSTANT_PROPERTY_TYPE];

  Property* prop = new(allocator, "Property") Property();
  prop->name = readString(VMThread::get()->getVM(), stringOffset + nameIndex);
  prop->flags = flags;
  prop->type = cl;
  uint32 offset = blobOffset + type;
  prop->virt = extractMethodSignature(offset, cl, prop->parameters, genClass, genMethod);
  return prop;
}

VMMethod* Assembly::readMethodDef(uint32 index, VMCommonClass* cl,
       std::vector<VMCommonClass*>* genMethodInstantiation, VMGenericClass* genClass) {
  uint32 token = index + (CONSTANT_MethodDef << 24);
  uint32 stringOffset = CLIHeader->stringStream->realOffset;
  uint32 blobOffset = CLIHeader->blobStream->realOffset;
  
  Table* paramTable  = CLIHeader->tables[CONSTANT_Param];
  uint32 paramSize    = paramTable->rowsNumber;
  
  Table* methTable  = CLIHeader->tables[CONSTANT_MethodDef];
  uint32 methodSize    = methTable->rowsNumber;
  uint32* methArray = (uint32*)alloca(sizeof(uint32) * methTable->rowSize);
  
  methTable->readRow(methArray, index, bytes);

  uint32 rva        = methArray[CONSTANT_METHODDEF_RVA];
  uint32 implFlags  = methArray[CONSTANT_METHODDEF_IMPLFLAGS];
  uint32 flags      = methArray[CONSTANT_METHODDEF_FLAGS];
  uint32 name       = methArray[CONSTANT_METHODDEF_NAME];
  uint32 signature  = methArray[CONSTANT_METHODDEF_SIGNATURE];
  uint32 paramList  = methArray[CONSTANT_METHODDEF_PARAMLIST];
  
  uint32 offset = blobOffset + signature;

  VMMethod* meth = 
    constructMethod((VMClass*)cl, readString(cl->vm, (name + stringOffset)),
                    token, isGenericMethod(offset), genMethodInstantiation, genClass);
  
  offset = blobOffset + signature;
  
  meth->virt = extractMethodSignature(offset, cl, meth->parameters, genClass, 
      static_cast<VMGenericMethod*> (meth));
  
  meth->flags = flags;
  meth->implFlags = implFlags;

  if (rva) {
    meth->offsetInTextSection = textSection->rawAddress + 
			(rva - textSection->virtualAddress);
  } else {
    meth->offsetInTextSection = 0;
  }

  if (paramList && paramTable != 0 && paramList <= paramSize) {
    uint32 endParam = (index == methodSize) ? 
        paramSize + 1 : 
        methTable->readIndexInRow(index + 1, CONSTANT_METHODDEF_PARAMLIST,
                                bytes);

    uint32 nbParams = endParam - paramList;

    for (uint32 j = 0; j < nbParams; ++j) {
      meth->params.push_back(readParam(j + paramList, meth));
    }
  }

  return meth;
}

VMField* Assembly::readField(uint32 index, VMCommonClass* cl, VMGenericClass* genClass, VMGenericMethod* genMethod) {
  uint32 token = index + (CONSTANT_Field << 24);
  uint32 stringOffset = CLIHeader->stringStream->realOffset;
  uint32 blobOffset = CLIHeader->blobStream->realOffset;
  
  Table* fieldTable  = CLIHeader->tables[CONSTANT_Field];
  uint32* fieldArray = (uint32*)alloca(sizeof(uint32) * fieldTable->rowSize);
  
  fieldTable->readRow(fieldArray, index, bytes);

  uint32 flags      = fieldArray[CONSTANT_FIELD_FLAGS];
  uint32 name       = fieldArray[CONSTANT_FIELD_NAME];
  uint32 signature  = fieldArray[CONSTANT_FIELD_SIGNATURE];
  
  uint32 offset = blobOffset + signature;
  VMField* field = constructField((VMClass*) cl, readString(cl->vm, (name
      + stringOffset)), extractFieldSignature(offset, genClass, genMethod),
      token, genClass, genMethod);
  field->flags = flags;
  
  return field;
}

Param* Assembly::readParam(uint32 index, VMMethod* meth) {
  uint32 stringOffset = CLIHeader->stringStream->realOffset;
  
  Table* paramTable  = CLIHeader->tables[CONSTANT_Param];
  uint32* paramArray = (uint32*)alloca(sizeof(uint32) * paramTable->rowSize);
  
  paramTable->readRow(paramArray, index, bytes);

  uint32 flags      = paramArray[CONSTANT_PARAM_FLAGS];
  uint32 name       = paramArray[CONSTANT_PARAM_NAME];
  uint32 sequence   = paramArray[CONSTANT_PARAM_SEQUENCE];
  
  Param* param = new(allocator, "Param") Param();
  param->flags = flags;
  param->sequence = sequence;
  param->name = readString(meth->classDef->vm, stringOffset + name);
  param->method = meth;
  
  return param;
}

VMCommonClass* Assembly::loadTypeFromName(const UTF8* name, 
                                          const UTF8* nameSpace, 
                                          bool resolve, bool unify,
                                          bool clinit, bool dothrow) {
  VMCommonClass* cl = lookupClassFromName(name, nameSpace);
  if (cl == 0 || cl->status == hashed) {
    cl = getClassFromName(((N3*)VMThread::get()->getVM()), name, nameSpace);
    
    if (cl == 0) VMThread::get()->getVM()->error("implement me");

    if (cl->status == hashed) {
      cl->aquire();
      if (cl->status == hashed) {
        cl->status = loaded;
      }
      cl->release();
    }
  }

  if (resolve) cl->resolveType(unify, clinit, NULL);

  return cl;
}

void Assembly::readSignature(uint32 localVarSig, 
                             std::vector<VMCommonClass*>& locals, VMGenericClass* genClass, VMGenericMethod* genMethod) {
  uint32 table = localVarSig >> 24;
  uint32 index = localVarSig & 0xffff;
  if (table != CONSTANT_StandaloneSig) {
    VMThread::get()->getVM()->error("locals do not point to a StandAloneSig table");
  }
  Table* signatures = CLIHeader->tables[CONSTANT_StandaloneSig];
  uint32* array = (uint32*)alloca(sizeof(uint32) * signatures->rowSize);
  signatures->readRow(array, index, bytes);

  uint32 blobOffset = CLIHeader->blobStream->realOffset;
  uint32 blobEntry = blobOffset + array[CONSTANT_STANDALONE_SIG_SIGNATURE];
  

  localVarSignature(blobEntry, locals, genClass, genMethod);
}

VMField* Assembly::getFieldFromToken(uint32 token, bool stat, VMGenericClass* genClass, VMGenericMethod* genMethod) {
  VMField* field = lookupFieldFromToken(token);
  if (!field) {
    uint32 table = token >> 24;
    switch (table) {
      case CONSTANT_Field : {
        uint32 typeToken = getTypedefTokenFromField(token);
        uint32 newTable = typeToken >> 24;
        switch (newTable) {
          case CONSTANT_TypeDef : {
            loadType((N3*)(VMThread::get()->getVM()), typeToken, true, true, false,
                     true, genClass, genMethod);
            field = lookupFieldFromToken(token);
            if (!field) {
              VMThread::get()->getVM()->error("implement me");
            }
            break;
          }
          default : {
            VMThread::get()->getVM()->error("implement me");
          }
        }
        break;
      }

      case CONSTANT_MemberRef : {
        field = readMemberRefAsField(token, stat, genClass, genMethod);
        break;
      }

      default : {
        VMThread::get()->getVM()->error("implement me");
      }
    }
  }
  field->classDef->resolveType(stat, false, genMethod);
  return field;
}

uint32 Assembly::getTypedefTokenFromField(uint32 token) {
  uint32 index = token & 0xffff;
  Table* typeTable = CLIHeader->tables[CONSTANT_TypeDef];
  uint32 nbRows = typeTable->rowsNumber;

  bool found = false;
  uint32 i = 0;

  while (!found && i < nbRows - 1) {
    uint32 myId = typeTable->readIndexInRow(i + 1, CONSTANT_TYPEDEF_FIELDLIST, bytes);
    uint32 nextId = typeTable->readIndexInRow(i + 2, CONSTANT_TYPEDEF_FIELDLIST, bytes);

    if ((index < nextId) && (index >= myId)) {
      found = true;
    } else {
      ++i;
    }
  }

  return i + 1 + (CONSTANT_TypeDef << 24);
}

uint32 Assembly::getExplicitLayout(uint32 token) {
  uint32 index = token & 0xffff;
  Table* layoutTable = CLIHeader->tables[CONSTANT_ClassLayout];
  uint32 tableSize = layoutTable->rowsNumber;

  bool found = false;
  uint32 i = 0;
  uint32 size = 0;

  while (!found && i != tableSize) {
    uint32 parent = layoutTable->readIndexInRow(i + 1,
                                        CONSTANT_CLASS_LAYOUT_PARENT, bytes);
    if (parent == index) {
      found = true;
      size = layoutTable->readIndexInRow(i + 1,
                                  CONSTANT_CLASS_LAYOUT_CLASS_SIZE, bytes);
    }
    ++i;
  }

  if (!found)
    VMThread::get()->getVM()->error("implement me");

  return size;
}

VMField* Assembly::readMemberRefAsField(uint32 token, bool stat, VMGenericClass* genClass, VMGenericMethod* genMethod) {
  uint32 index = token & 0xffff;
  Table* memberTable = CLIHeader->tables[CONSTANT_MemberRef];
  uint32* memberArray = (uint32*)alloca(sizeof(uint32) * memberTable->rowSize);
  
  memberTable->readRow(memberArray, index, bytes);

  uint32 stringOffset = CLIHeader->stringStream->realOffset;
  uint32 blobOffset   = CLIHeader->blobStream->realOffset;
  
  const UTF8* name = readString((N3*)(VMThread::get()->getVM()), stringOffset + 
                                          memberArray[CONSTANT_MEMBERREF_NAME]);
  

  uint32 value = memberArray[CONSTANT_MEMBERREF_CLASS];
  uint32 table = value & 7;
  index = value >> 3;

  VMCommonClass* type = NULL;
  
  switch (table) {
    case 0 : {
      uint32 typeToken = index + (CONSTANT_TypeDef << 24);
      type = loadType(((N3*)VMThread::get()->getVM()), typeToken,
                                     true, false, false, true, genClass, genMethod);
	  break;
    }

    case 1 : {
      uint32 typeToken = index + (CONSTANT_TypeRef << 24);
      type = loadType(((N3*)VMThread::get()->getVM()), typeToken,
                                     true, false, false, true, genClass, genMethod);
      break;
    }

    case 2:
    case 3: VMThread::get()->getVM()->error("implement me"); break;
    case 4: {
      uint32 typeToken = index + (CONSTANT_TypeSpec << 24);
      type = loadType(((N3*)VMThread::get()->getVM()), typeToken,
                                       true, false, false, true, genClass, genMethod);
      break;
    }
    default:
      VMThread::get()->getVM()->error("unknown MemberRefParent tag %d", table);
      
  }

  uint32 offset = blobOffset + memberArray[CONSTANT_MEMBERREF_SIGNATURE];

  VMGenericClass* genericClass = static_cast<VMGenericClass*> (type);

  if (genericClass) {
    VMCommonClass* signature = extractFieldSignature(offset, genericClass,
        genMethod);
    VMField* field = type->lookupField(name, signature, stat, true);
    return field;
  } else {
    VMCommonClass* signature = extractFieldSignature(offset, genClass, genMethod);
    VMField* field = type->lookupField(name, signature, stat, true);
    return field;
  }
  
}


VMMethod* Assembly::getMethodFromToken(uint32 token, VMGenericClass* genClass, VMGenericMethod* genMethod) {
  VMMethod* meth = lookupMethodFromToken(token);
  
  if (!meth) {
    uint32 table = token >> 24;
    switch (table) {
      case CONSTANT_MethodDef : {
        uint32 typeToken = getTypedefTokenFromMethod(token);
        uint32 newTable = typeToken >> 24;
        switch (newTable) {
          case CONSTANT_TypeDef : {
            loadType((N3*)(VMThread::get()->getVM()), typeToken, true, true, false,
                     true, genClass, genMethod);
            meth = lookupMethodFromToken(token);
            if (!meth) {
              VMThread::get()->getVM()->error("implement me");
            }
            break;
          }
          default : {
            VMThread::get()->getVM()->error("implement me");
          }
        }
        break;
      }

      case CONSTANT_MemberRef : {
        meth = readMemberRefAsMethod(token, NULL, genClass, genMethod);
        break;
      }
      
      case CONSTANT_MethodSpec : {
        meth = readMethodSpec(token, genClass, genMethod); 
        break;
      }

      default : {
        VMThread::get()->getVM()->error("implement me");
      }
    }
  }
  
  meth->getSignature(genMethod);
  
  return meth;
}

uint32 Assembly::getTypedefTokenFromMethod(uint32 token) {
  uint32 index = token & 0xffff;
  Table* typeTable = CLIHeader->tables[CONSTANT_TypeDef];
  uint32 nbRows = typeTable->rowsNumber;

  bool found = false;
  uint32 i = 0;

  while (!found && i < nbRows - 1) {
    uint32 myId = typeTable->readIndexInRow(i + 1, CONSTANT_TYPEDEF_METHODLIST, bytes);
    uint32 nextId = typeTable->readIndexInRow(i + 2, CONSTANT_TYPEDEF_METHODLIST, bytes);

    if ((index < nextId) && (index >= myId)) {
      found = true;
    } else {
      ++i;
    }
  }

  return i + 1 + (CONSTANT_TypeDef << 24);
}

VMMethod *Assembly::instantiateGenericMethod(
    std::vector<VMCommonClass*> *genArgs, VMCommonClass *type,
    const UTF8 *& name, std::vector<VMCommonClass*> & args, uint32 token,
    bool virt, VMGenericClass* genClass) {
  VMMethod *meth = NULL;
  
  if (genArgs != NULL) {
    VMClass* cl = static_cast<VMClass*> (type);

    if (cl == NULL) {
      VMThread::get()->getVM()->error(
          "Only instances of generic classes are allowed.");
    }

    // search for matching signature
    for (uint i = 0; i < cl->genericMethods.size(); ++i) {
      VMMethod* genMethod = cl->genericMethods.at(i);

      if ((name != genMethod->name) || !genMethod->signatureEqualsGeneric(
          args)) {
        continue;
      }

      // use found token to create instance of generic method
      meth = readMethodDef(genMethod->token & 0xFFFFFF, type, genArgs, genClass);
      meth->token = token;
    }
  } else {
    meth = type->lookupMethod(name, args, !virt, true);
  }
  
  return meth;
}

VMMethod* Assembly::readMemberRefAsMethod(uint32 token, std::vector<VMCommonClass*>* genArgs, VMGenericClass* genClass, VMGenericMethod* genMethod) {
  uint32 index = token & 0xffff;
  Table* memberTable = CLIHeader->tables[CONSTANT_MemberRef];
  uint32* memberArray = (uint32*)alloca(sizeof(uint32) * memberTable->rowSize);
  
  memberTable->readRow(memberArray, index, bytes);

  uint32 stringOffset = CLIHeader->stringStream->realOffset;
  uint32 blobOffset   = CLIHeader->blobStream->realOffset;
  
  const UTF8* name = readString((N3*)(VMThread::get()->getVM()), stringOffset + 
                                          memberArray[CONSTANT_MEMBERREF_NAME]);
  
  uint32 offset = blobOffset + memberArray[CONSTANT_MEMBERREF_SIGNATURE];
  std::vector<VMCommonClass*> args;
                                    

  uint32 value = memberArray[CONSTANT_MEMBERREF_CLASS];
  uint32 table = value & 7;
  index = value >> 3;

  switch (table) {
    case 0 : {
      uint32 typeToken = index + (CONSTANT_TypeDef << 24);
      VMCommonClass* type = loadType(((N3*)(VMThread::get()->getVM())), typeToken, true, false, false, true, genClass, genMethod);
      bool virt = extractMethodSignature(offset, type, args, genClass, genMethod);
      VMMethod *meth = instantiateGenericMethod(genArgs, type, name, args, token, virt, genClass);
      return meth;
    }

    case 1 : {
      uint32 typeToken = index + (CONSTANT_TypeRef << 24);
      VMCommonClass* type = loadType(((N3*)VMThread::get()->getVM()), typeToken,
                                     true, false, false, true, genClass, genMethod);
      bool virt = extractMethodSignature(offset, type, args, genClass, genMethod);
      VMMethod *meth = instantiateGenericMethod(genArgs, type, name, args, token, virt, genClass);
      return meth;
    }

    case 2:
    case 3: VMThread::get()->getVM()->error("implement me %d", table); break;
    case 4: {
      VMClass* type = (VMClass*) readTypeSpec(vm, index, genClass, genMethod);
        
      VMGenericClass* genClass = static_cast<VMGenericClass*> (type);
  
      if (genClass) {
        type->resolveType(false, false, genMethod);
        
        bool virt = extractMethodSignature(offset, type, args, genClass, genMethod);
        VMMethod* meth = instantiateGenericMethod(genArgs, type, name, args,
            token, virt, genClass);
        
        return meth;
      } else {
        type->resolveType(false, false, genMethod);
        
        VMMethod* meth = new(allocator, "VMMethod") VMMethod() ;
        bool virt = extractMethodSignature(offset, type, args, genClass, genMethod);
        bool structReturn = false;
        const llvm::FunctionType* signature = VMMethod::resolveSignature(args,
            virt, structReturn, genMethod);
        meth->_signature = signature;
        meth->classDef = type;
        meth->name = name;
        meth->virt = virt;
        meth->structReturn = structReturn;
        meth->parameters = args; // TODO check whether this fix is correct
        return meth;
      }
    }
    default:
      VMThread::get()->getVM()->error("unknown MemberRefParent tag %d", table);
      
  }

  return 0;
}

VMMethod* Assembly::readMethodSpec(uint32 token, VMGenericClass* genClass, VMGenericMethod* genMethod) {
  uint32 index = token & 0xffff;
  uint32 blobOffset = CLIHeader->blobStream->realOffset;
  
  Table* methodTable = CLIHeader->tables[CONSTANT_MethodSpec];
  uint32* methodArray = (uint32*) alloca(sizeof(uint32) * methodTable->rowSize);
  
  methodTable->readRow(methodArray, index, bytes);
  
  uint32 method = methodArray[CONSTANT_METHOD_SPEC_METHOD];
  uint32 instantiation = methodArray[CONSTANT_METHOD_SPEC_INSTANTIATION];
  
  uint32 offset = blobOffset + instantiation;
  
  std::vector<VMCommonClass*> genArgs;
  methodSpecSignature(offset, genArgs, genClass, genMethod);
  
  uint32 table = method & 1;
  index = method >> 1;
  
  uint32 methodToken;
  
  switch (table) {
    case 0 : {
      methodToken = index + (CONSTANT_MethodDef << 24);
      VMThread::get()->getVM()->error("implement me");
      break;
    }
    case 1 : {
      methodToken = index + (CONSTANT_MemberRef << 24);
      return readMemberRefAsMethod(methodToken, &genArgs, genClass, genMethod);
    }
    default:
      VMThread::get()->getVM()->error("Invalid MethodSpec!");
  }
  
  return NULL;
}

const ArrayChar* Assembly::readUserString(uint32 token) {
  uint32 offset = CLIHeader->usStream->realOffset + token;

  uint8 size = READ_U1(bytes, offset);
  if (size >> 7) {
    if ((size >> 6) == 3) {
      uint32 size1 = READ_U1(bytes, offset);
      uint32 size2 = READ_U1(bytes, offset);
      uint32 size3 = READ_U1(bytes, offset);
      size = ((size ^ 0xc0) << 24) + (size1 << 16) + (size2 << 8) + size3;
    } else {
      size = ((size ^ 0x80) << 8) + READ_U1(bytes, offset);
    }
  }

	declare_gcroot(const ArrayChar*, res) = readUTF16((N3*)(VMThread::get()->getVM()), size, bytes, offset);
  return res;
}

uint32 Assembly::getRVAFromField(uint32 token) {
  
  uint32 index = token & 0xffff;
  Table* rvaTable = CLIHeader->tables[CONSTANT_FieldRVA];
  uint32 rvaSize = rvaTable->rowsNumber;
  
  uint32 i = 0;
  bool found = false;

  while (!found && i != rvaSize) {
    uint32 fieldId = rvaTable->readIndexInRow(i + 1, CONSTANT_FIELD_RVA_FIELD,
                                              bytes);
    if (fieldId == index) {
      found = true;
    } else {
      ++i;
    }
  }
  if (!found) {
    return 0;
  } else {
    return rvaTable->readIndexInRow(i + 1, CONSTANT_FIELD_RVA_RVA, bytes);
  }
}

