Browse Source

More const eval progress

Brian Fiete 4 years ago
parent
commit
9b80c26d0a

+ 9 - 0
BeefLibs/corlib/src/Compiler.bf

@@ -23,7 +23,16 @@ namespace System
 		[LinkName("#CallerExpression")]
 		public static extern String[Int32.MaxValue] CallerExpression;
 
+		[LinkName("#ProjectName")]
+		public static extern String ProjectName;
+
+		[LinkName("#ModuleName")]
+		public static extern String ModuleName;
+
 		[LinkName("#TimeLocal")]
 		public static extern String TimeLocal;
+
+		[LinkName("#IsConstEval")]
+		public static extern bool IsConstEval;
 	}
 }

+ 6 - 18
BeefLibs/corlib/src/Event.bf

@@ -35,10 +35,8 @@ namespace System
 				if (data == null)
 					return true;
 
-				var type = data.GetType();
-				if (type == typeof(List<T>))
+				if (var list = data as List<T>)
 				{
-					var list = (List<T>)data;
 					return list.Count == 0;
 				}
 				return false;
@@ -54,10 +52,8 @@ namespace System
 				if (data == null)
 					return 0;
 
-				var type = data.GetType();
-				if (type == typeof(List<T>))
+				if (var list = data as List<T>)
 				{
-					var list = (List<T>)data;
 					return list.Count;
 				}
 				return 1;
@@ -105,11 +101,8 @@ namespace System
 				return;
 			}
 
-			var type = data.GetType();
-			
-			if (type == typeof(List<T>))
+			if (var list = data as List<T>)
 			{
-				var list = (List<T>)data;
 				list.Add(ownDelegate);
 			}
 			else
@@ -125,10 +118,8 @@ namespace System
 		{
 			Object data = Target;
 
-			var type = data.GetType();
-			if (type == typeof(List<T>))
+			if (var list = data as List<T>)
 			{
-				var list = (List<T>)data;
 				int32 idx = -1;
 				for (int32 i = 0; i < list.Count; i++)
 					if (Delegate.Equals(list[i], compareDelegate))
@@ -193,9 +184,8 @@ namespace System
 			if (mData == 0)
 				return;
 			var data = Target;
-			if (data.GetType() == typeof(List<T>))
+			if (var list = data as List<T>)
 			{
-				var list = (List<T>)data;
 				for (var dlg in list)
 					delete dlg;
 			}
@@ -282,10 +272,8 @@ namespace System
 				if (data == null)
 					return false;
 
-				var type = data.GetType();
-				if (type == typeof(List<T>))
+				if (var list = data as List<T>)
 				{
-					var list = (List<T>)data;
 					repeat
 					{
 						mIdx++;

+ 2 - 0
BeefLibs/corlib/src/Globalization/CultureInfo.bf

@@ -83,6 +83,8 @@ namespace System.Globalization
 		{
 		    get
 			{
+				if (Compiler.IsConstEval)
+					return InitUserDefaultCulture();
 				if (tlCurrentCulture == null)
 					tlCurrentCulture = CultureInfo.DefaultThreadCurrentCulture ?? CultureInfo.UserDefaultCulture;
 		        return tlCurrentCulture;

+ 2 - 0
BeefLibs/corlib/src/Internal.bf

@@ -127,6 +127,8 @@ namespace System
 		public static T* AllocRawArrayUnmarked<T>(int size)
 		{
 #if BF_ENABLE_REALTIME_LEAK_CHECK
+			if (Compiler.IsConstEval)
+				return new T[size]*(?);
 			// We don't want to use the default mark function because the GC will mark the entire array,
 			//  whereas we have a custom marking routine because we only want to mark up to mSize
 			return (T*)Internal.Dbg_RawAlloc(size * strideof(T), &DbgRawAllocData.Unmarked<T>.sRawAllocData);

+ 13 - 14
BeefLibs/corlib/src/NumberFormatter.bf

@@ -109,7 +109,7 @@ namespace System
 			1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
 		};*/
 
-		private static uint64[2048] MantissaBitsTable = .(
+		private const uint64[2048] MantissaBitsTable = .(
 			4556951262222748432UL, 9113902524445496865UL, 1822780504889099373UL, 
 			3645561009778198746UL, 7291122019556397492UL, 14582244039112794984UL, 
 			2916448807822558996UL, 5832897615645117993UL, 11665795231290235987UL, 
@@ -794,7 +794,7 @@ namespace System
 			4602094425247528723UL, 9204188850495057447UL, 1840837770099011489UL, 
 			3681675540198022979UL, 7363351080396045958UL);
 
-		private static int32[2048] TensExponentTable = .(
+		private const int32[2048] TensExponentTable = .(
 			-323, -323, -322, -322, -322, -322, -321, -321, -321, -320, -320, -320, 
 			-319, -319, -319, -319, -318, -318, -318, -317, -317, -317, -316, -316, 
 			-316, -316, -315, -315, -315, -314, -314, -314, -313, -313, -313, -313, 
@@ -966,9 +966,9 @@ namespace System
 			284, 284, 284, 285, 285, 285, 286, 286, 286, 286, 287, 287, 
 			287, 288, 288, 288, 289, 289, 289, 289, 290, 290, 290, 291, 
 			291, 291, 292, 292, 292, 293, 293, 293 );
-		private static char8[16] DigitLowerTable = .('0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f');
-		private static char8[16] DigitUpperTable = .('0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F');
-		private static int64[19] TenPowersList = .(
+		private const char8[16] DigitLowerTable = .('0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f');
+		private const char8[16] DigitUpperTable = .('0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F');
+		private const int64[19] TenPowersList = .(
 			1L,
 			10L,
 			100L,
@@ -991,7 +991,7 @@ namespace System
 
 		// DecHexDigits s a translation table from a decimal number to its
 		// digits hexadecimal representation (e.g. DecHexDigits [34] = 0x34).
-		private static int32[100] DecHexDigits = .(
+		private const int32[100] DecHexDigits = .(
 			0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 
 			0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 
 			0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 
@@ -1235,8 +1235,10 @@ namespace System
 		//   _isCustomFormat, _specifierIsUpper, _specifier & _precision.
 		this(CultureInfo cultureInfo)
 		{
-			//_cbuf = EmptyArray<char>.Value;
-			_cbuf = sEmtpyBuf;
+			if (Compiler.IsConstEval)
+				_cbuf = new char8[0];
+			else
+				_cbuf = sEmtpyBuf;
 			if (cultureInfo != null)
 				CurrentCulture = cultureInfo;
 		}
@@ -2032,13 +2034,12 @@ namespace System
 		private void FormatHexadecimal (int32 precision, String outString)
 		{
 			int32 size = Math.Max (precision, _decPointPos);
-			char8* digits = _specifierIsUpper ? &DigitUpperTable : &DigitLowerTable;
-
+			
 			ResetCharBuf (size);
 			_ind = size;
 			uint64 val = _val1 | ((uint64)_val2 << 32);
 			while (size > 0) {
-				_cbuf [--size] = digits [val & 0xf];
+				_cbuf [--size] = _specifierIsUpper ? DigitUpperTable[val & 0xf] : DigitLowerTable[val & 0xf];
 				val >>= 4;
 			}
 			outString.Append(_cbuf, 0, _ind);
@@ -2046,8 +2047,6 @@ namespace System
 
 		private void FormatAddress(String outString)
 		{
-			char8* digits = _specifierIsUpper ? &DigitUpperTable : &DigitLowerTable;
-
 			const int bufLen = 18;
 			char8* strChars = scope:: char8[bufLen]* (?);	
 			int32 curLen = 0;	
@@ -2056,7 +2055,7 @@ namespace System
 			{	
 				if (curLen == 8)	
 					strChars[bufLen - curLen++ - 1] = '\'';	
-			    strChars[bufLen - curLen++ - 1] = digits[(int)(valLeft & 0xF)];	
+			    strChars[bufLen - curLen++ - 1] = _specifierIsUpper ? DigitUpperTable[(int)(valLeft & 0xF)] : DigitLowerTable[(int)(valLeft & 0xF)];
 			    valLeft >>= 4;	
 			}	
 

+ 7 - 0
BeefLibs/corlib/src/Object.bf

@@ -40,9 +40,13 @@ namespace System
             return false;
         }
 #endif
+		extern Type ConstEval_GetType();
 
         public Type GetType()
         {
+			if (Compiler.IsConstEval)
+				return ConstEval_GetType();
+
             Type type;
 #if BF_ENABLE_OBJECT_DEBUG_FLAGS
             ClassVData* maskedVData = (ClassVData*)(void*)(mClassVData & ~(int)0xFF);
@@ -61,6 +65,9 @@ namespace System
 		[NoShow]
         Type RawGetType()
         {
+			if (Compiler.IsConstEval)
+				return ConstEval_GetType();
+
             Type type;
 #if BF_ENABLE_OBJECT_DEBUG_FLAGS
             ClassVData* maskedVData = (ClassVData*)(void*)(mClassVData & ~(int)0xFF);

+ 8 - 6
BeefLibs/corlib/src/Text/UTF8.bf

@@ -1,9 +1,10 @@
+using System.Diagnostics;
 namespace System.Text
 {
 	class UTF8
 	{
-		public static int8* sTrailingBytesForUTF8 = new int8[]*
-		(
+		public const int8[256] sTrailingBytesForUTF8 =
+		.(
 		    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
 		    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
 		    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
@@ -12,13 +13,13 @@ namespace System.Text
 		    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
 		    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
 		    2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 3,3,3,3,3,3,3,3,4,4,4,4,5,5,5,5
-		) ~ delete _;
+		);
 
-		public static uint32* sOffsetsFromUTF8 = new uint32[]*
-		(
+		public const uint32[6] sOffsetsFromUTF8 =
+		.(
 			0x00000000, 0x00003080, 0x000E2080,
 		    0x03C82080, 0xFA082080, 0x82082080
-		) ~ delete _;
+		);
 
 		public static int GetEncodedLength(char32 c)
 		{
@@ -58,6 +59,7 @@ namespace System.Text
 			case 2: c <<= 6; c += (int32)buf[bufIdx++]; fallthrough;
 			case 1: c <<= 6; c += (int32)buf[bufIdx++]; fallthrough;
 			}
+
 			c -= (int32)UTF8.sOffsetsFromUTF8[trailingBytes];
 			return (c, trailingBytes + 1);
 		}

+ 13 - 1
BeefySysLib/util/Hash.h

@@ -146,4 +146,16 @@ public:
 	uint64 Finish64();	
 };
 
-NS_BF_END
+NS_BF_END
+
+namespace std
+{
+	template<>
+	struct hash<Beefy::Val128>
+	{
+		size_t operator()(const Beefy::Val128& val) const
+		{
+			return val.mLow;
+		}
+	};
+}

+ 2 - 0
BeefySysLib/util/Heap.cpp

@@ -151,6 +151,8 @@ void ContiguousHeap::Clear(int maxAllocSize)
 		while (block != NULL)
 		{
 			block->mKind = ChBlockKind_Bad;
+			if (block->mNext == -1)
+				break;
 			block = CH_REL_TO_ABS(block->mNext);
 		}
 	}	

+ 5 - 0
IDEHelper/Backend/BeContext.cpp

@@ -70,6 +70,11 @@ BeType* BeContext::GetPrimitiveType(BeTypeCode typeCode)
 	return primType;
 }
 
+BeType* BeContext::GetVoidPtrType()
+{
+	return GetPointerTo(GetPrimitiveType(BeTypeCode_None));
+}
+
 BeStructType* BeContext::CreateStruct(const StringImpl& name)
 {
 	BeStructType* structType = mTypes.Alloc<BeStructType>();

+ 1 - 0
IDEHelper/Backend/BeContext.h

@@ -275,6 +275,7 @@ public:
 public:
 	BeContext();	
 	BeType* GetPrimitiveType(BeTypeCode typeCode);	
+	BeType* GetVoidPtrType();
 	BeStructType* CreateStruct(const StringImpl& name);
 	BeStructType* CreateStruct(const SizedArrayImpl<BeType*>& types);
 	BePointerType* GetPointerTo(BeType* beType);

+ 29 - 2
IDEHelper/Backend/BeIRCodeGen.cpp

@@ -765,6 +765,22 @@ void BeIRCodeGen::Read(BeValue*& beValue)
 			BE_MEM_END("ParamType_Const_PtrToInt");
 			return;
 		}
+		else if (constType == BfConstType_IntToPtr)
+		{
+			CMD_PARAM(BeConstant*, target);
+			CMD_PARAM(BeType*, toType);
+
+			auto castedVal = mBeModule->mAlloc.Alloc<BeCastConstant>();
+			castedVal->mInt64 = target->mInt64;
+			castedVal->mType = toType;
+			castedVal->mTarget = target;
+			BF_ASSERT(target->GetType() != NULL);
+			BF_ASSERT(!target->GetType()->IsComposite());
+			BF_ASSERT(toType->IsPointer());
+			beValue = castedVal;
+			BE_MEM_END("ParamType_Const_IntToPtr");
+			return;
+		}
 		else if (constType == BfConstType_AggZero)
 		{
 			CMD_PARAM(BeType*, type);
@@ -2545,6 +2561,17 @@ void BeIRCodeGen::HandleNextCmd()
 			SetResult(curId, inst);
 		}
 		break;
+	case BfIRCmd_ConstEval_GetReflectType:
+		{
+			CMD_PARAM(int32, typeId);
+			CMD_PARAM(BeType*, resultType);
+
+			auto inst = mBeModule->AllocInst<BeConstEvalGetReflectType>();
+			inst->mTypeId = typeId;
+			inst->mResultType = resultType;
+			SetResult(curId, inst);
+		}
+		break;
 	case BfIRCmd_ConstEval_DynamicCastCheck:
 		{
 			CMD_PARAM(BeValue*, value);
@@ -2575,13 +2602,13 @@ void BeIRCodeGen::HandleNextCmd()
 		{
 			CMD_PARAM(BeValue*, value);
 			CMD_PARAM(int32, ifaceTypeId);
-			CMD_PARAM(int32, virtualTableIdx);
+			CMD_PARAM(int32, methodIdx);
 			CMD_PARAM(BeType*, resultType);
 
 			auto inst = mBeModule->AllocInst<BeConstEvalGetInterfaceFunc>();
 			inst->mValue = value;
 			inst->mIFaceTypeId = ifaceTypeId;
-			inst->mVirtualTableIdx = virtualTableIdx;
+			inst->mMethodIdx = methodIdx;
 			inst->mResultType = resultType;
 			SetResult(curId, inst);
 		}

+ 3 - 2
IDEHelper/Backend/BeModule.cpp

@@ -1282,7 +1282,7 @@ void BeDumpContext::ToString(StringImpl& str, BeValue* value, bool showType, boo
 		str += StrFormat(" %d %d", constantGEP->mIdx0, constantGEP->mIdx1);
 		return;
 	}
-
+	
 	if (auto constantExtract = BeValueDynCast<BeExtractValueConstant>(value))
 	{
 		str += "ConstExtract ";
@@ -2450,9 +2450,10 @@ String BeModule::ToString(BeFunction* wantFunc)
 					}
 					break;
 				DISPLAY_INST1(BeConstEvalGetType, "ConstEvalGetType", mTypeId);
+				DISPLAY_INST1(BeConstEvalGetReflectType, "ConstEvalGetReflectType", mTypeId);
 				DISPLAY_INST2(BeConstEvalDynamicCastCheck, "ConstEvalDynamicCastCheck", mValue, mTypeId);
 				DISPLAY_INST2(BeConstEvalGetVirtualFunc, "ConstEvalGetVirtualFunc", mValue, mVirtualTableIdx);
-				DISPLAY_INST3(BeConstEvalGetInterfaceFunc, "ConstEvalGetInterfaceFunc", mValue, mIFaceTypeId, mVirtualTableIdx);
+				DISPLAY_INST3(BeConstEvalGetInterfaceFunc, "ConstEvalGetInterfaceFunc", mValue, mIFaceTypeId, mMethodIdx);
 				default:
 					BF_FATAL("Notimpl");
 					str += "<UNKNOWN INST>";

+ 24 - 2
IDEHelper/Backend/BeModule.h

@@ -1361,6 +1361,28 @@ public:
 	}
 };
 
+class BeConstEvalGetReflectType : public BeInst
+{
+public:
+	BE_VALUE_TYPE(BeConstEvalGetReflectType, BeInst);
+
+public:
+	int mTypeId;
+	BeType* mResultType;
+
+public:
+	virtual BeType* GetType() override
+	{
+		return mResultType;
+	}
+
+	virtual void HashInst(BeHashContext& hashCtx) override
+	{
+		hashCtx.Mixin(TypeId);
+		hashCtx.Mixin(mTypeId);
+	}
+};
+
 class BeConstEvalDynamicCastCheck : public BeInst
 {
 public:
@@ -1417,7 +1439,7 @@ public:
 public:
 	BeValue* mValue;
 	int mIFaceTypeId;
-	int mVirtualTableIdx;
+	int mMethodIdx;
 	BeType* mResultType;
 
 public:
@@ -1431,7 +1453,7 @@ public:
 		hashCtx.Mixin(TypeId);
 		mValue->HashReference(hashCtx);
 		hashCtx.Mixin(mIFaceTypeId);
-		hashCtx.Mixin(mVirtualTableIdx);
+		hashCtx.Mixin(mMethodIdx);
 	}
 };
 

+ 51 - 25
IDEHelper/Compiler/BfCompiler.cpp

@@ -371,14 +371,15 @@ BfCompiler::BfCompiler(BfSystem* bfSystem, bool isResolveOnly)
 	mHotState = NULL;	
 	mHotResolveData = NULL;
 		
+	mBfObjectTypeDef = NULL;
+	mChar32TypeDef = NULL;
 	mArray1TypeDef = NULL;
 	mArray2TypeDef = NULL;
 	mArray3TypeDef = NULL;
 	mArray4TypeDef = NULL;
 	mSpanTypeDef = NULL;
 	mAttributeTypeDef = NULL;
-	mAttributeUsageAttributeTypeDef = NULL;
-	mBfObjectTypeDef = NULL;
+	mAttributeUsageAttributeTypeDef = NULL;	
 	mClassVDataTypeDef = NULL;
 	mCLinkAttributeTypeDef = NULL;
 	mImportAttributeTypeDef = NULL;
@@ -1043,26 +1044,28 @@ void BfCompiler::CreateVData(BfVDataModule* bfModule)
 
 	//////////////////////////////////////////////////////////////////////////
 
-	// Create types we'll need for vdata, so we won't change the vdata hash afterward
-	bfModule->CreatePointerType(bfModule->GetPrimitiveType(BfTypeCode_NullPtr));
-
-	///
-	
-	auto typeDefType = bfModule->ResolveTypeDef(mTypeTypeDef)->ToTypeInstance();
-	if (!typeDefType)
-		return;
-	BF_ASSERT(typeDefType != NULL);
-	vdataContext->mBfTypeType = typeDefType->ToTypeInstance();
+	mContext->ReflectInit();
 
-	auto typeInstanceDefType = bfModule->ResolveTypeDef(mReflectTypeInstanceTypeDef);
-	if (!typeInstanceDefType)
-		return;
-	auto typeInstanceDefTypeInstance = typeInstanceDefType->ToTypeInstance();
-
-	auto typeDef = mSystem->FindTypeDef("System.ClassVData");
-	BF_ASSERT(typeDef != NULL);
-	auto bfClassVDataType = bfModule->ResolveTypeDef(typeDef)->ToTypeInstance();	
-	vdataContext->mBfClassVDataPtrType = bfModule->CreatePointerType(bfClassVDataType);
+	// Create types we'll need for vdata, so we won't change the vdata hash afterward
+// 	bfModule->CreatePointerType(bfModule->GetPrimitiveType(BfTypeCode_NullPtr));
+// 
+// 	///
+// 	
+// 	auto typeDefType = bfModule->ResolveTypeDef(mTypeTypeDef)->ToTypeInstance();
+// 	if (!typeDefType)
+// 		return;
+// 	BF_ASSERT(typeDefType != NULL);
+// 	vdataContext->mBfTypeType = typeDefType->ToTypeInstance();
+// 
+// 	auto typeInstanceDefType = bfModule->ResolveTypeDef(mReflectTypeInstanceTypeDef);
+// 	if (!typeInstanceDefType)
+// 		return;
+// 	auto typeInstanceDefTypeInstance = typeInstanceDefType->ToTypeInstance();
+// 
+// 	auto typeDef = mSystem->FindTypeDef("System.ClassVData");
+// 	BF_ASSERT(typeDef != NULL);
+// 	auto bfClassVDataType = bfModule->ResolveTypeDef(typeDef)->ToTypeInstance();	
+// 	vdataContext->mBfClassVDataPtrType = bfModule->CreatePointerType(bfClassVDataType);
 
 	//////////////////////////////////////////////////////////////////////////
 
@@ -1278,6 +1281,7 @@ void BfCompiler::CreateVData(BfVDataModule* bfModule)
 
 	bool madeBfTypeData = false;
 	
+	auto typeDefType = mContext->mBfTypeType;
 	bool needsTypeList = bfModule->IsMethodImplementedAndReified(typeDefType, "GetType");
 	bool needsObjectTypeData = needsTypeList || bfModule->IsMethodImplementedAndReified(vdataContext->mBfObjectType, "RawGetType") || bfModule->IsMethodImplementedAndReified(vdataContext->mBfObjectType, "GetType");	
 	bool needsTypeNames = bfModule->IsMethodImplementedAndReified(typeDefType, "GetName") || bfModule->IsMethodImplementedAndReified(typeDefType, "GetFullName");
@@ -1801,7 +1805,7 @@ void BfCompiler::CreateVData(BfVDataModule* bfModule)
 			bool hadRet = false;
 
 			String entryClassName = project->mStartupObject;
-			typeDef = mSystem->FindTypeDef(entryClassName, 0, bfModule->mProject, {}, NULL, BfFindTypeDefFlag_AllowGlobal);
+			auto typeDef = mSystem->FindTypeDef(entryClassName, 0, bfModule->mProject, {}, NULL, BfFindTypeDefFlag_AllowGlobal);
 
 			if (typeDef != NULL)
 			{
@@ -6546,14 +6550,33 @@ bool BfCompiler::DoCompile(const StringImpl& outputDirectory)
 		return typeDef;
 	};
 
+
+	_GetRequiredType("System.Void");
+	_GetRequiredType("System.Boolean");	
+	_GetRequiredType("System.Int");
+	_GetRequiredType("System.Int8");
+	_GetRequiredType("System.Int16");
+	_GetRequiredType("System.Int32");
+	_GetRequiredType("System.Int64");
+	_GetRequiredType("System.UInt");
+	_GetRequiredType("System.UInt8");
+	_GetRequiredType("System.UInt16");
+	_GetRequiredType("System.UInt32");
+	_GetRequiredType("System.UInt64");
+	_GetRequiredType("System.Float");
+	_GetRequiredType("System.Double");
+	_GetRequiredType("System.Char8");
+	_GetRequiredType("System.Char16");
+	mChar32TypeDef = _GetRequiredType("System.Char32");
+
+	mBfObjectTypeDef = _GetRequiredType("System.Object");	 
 	mArray1TypeDef = _GetRequiredType("System.Array1", 1);
 	mArray2TypeDef = _GetRequiredType("System.Array2", 1);
 	mArray3TypeDef = _GetRequiredType("System.Array3", 1);
 	mArray4TypeDef = _GetRequiredType("System.Array4", 1);
-	mSpanTypeDef = _GetRequiredType("System.Span", 1);
+	mSpanTypeDef = _GetRequiredType("System.Span", 1);	
 	mAttributeTypeDef = _GetRequiredType("System.Attribute");
-	mAttributeUsageAttributeTypeDef = _GetRequiredType("System.AttributeUsageAttribute");
-	mBfObjectTypeDef = _GetRequiredType("System.Object");
+	mAttributeUsageAttributeTypeDef = _GetRequiredType("System.AttributeUsageAttribute");	
 	mClassVDataTypeDef = _GetRequiredType("System.ClassVData");
 	mCLinkAttributeTypeDef = _GetRequiredType("System.CLinkAttribute");
 	mImportAttributeTypeDef = _GetRequiredType("System.ImportAttribute");
@@ -6623,6 +6646,9 @@ bool BfCompiler::DoCompile(const StringImpl& outputDirectory)
 	for (int i = 0; i < BfTypeCode_Length; i++)
 		mContext->mPrimitiveStructTypes[i] = NULL;
 
+	mContext->mBfTypeType = NULL;
+	mContext->mBfClassVDataPtrType = NULL;
+
 	if (!hasRequiredTypes)
 	{
 		// Force rebuilding

+ 6 - 3
IDEHelper/Compiler/BfCompiler.h

@@ -331,13 +331,16 @@ public:
 	CompileState mCompileState;
 
 	Array<BfVDataModule*> mVDataModules;	
+		
+	BfTypeDef* mChar32TypeDef;
+	BfTypeDef* mBfObjectTypeDef;
+
 	BfTypeDef* mArray1TypeDef;
 	BfTypeDef* mArray2TypeDef;
 	BfTypeDef* mArray3TypeDef;
 	BfTypeDef* mArray4TypeDef;
-	BfTypeDef* mSpanTypeDef;
-	
-	BfTypeDef* mBfObjectTypeDef;
+	BfTypeDef* mSpanTypeDef;	
+		
 	BfTypeDef* mClassVDataTypeDef;	
 	
 	BfTypeDef* mDbgRawAllocDataTypeDef;

+ 29 - 14
IDEHelper/Compiler/BfContext.cpp

@@ -631,20 +631,10 @@ bool BfContext::ProcessWorkList(bool onlyReifiedTypes, bool onlyReifiedMethods)
 
 			BfLogSysM("Module %p inlining method %p into func:%p\n", module, methodInstance, workItem.mFunc);
 
-			BfMethodInstance dupMethodInstance = *methodInstance;
-			if (dupMethodInstance.mMethodInfoEx != NULL)
-			{
-				dupMethodInstance.mMethodInfoEx = new BfMethodInfoEx();
-				*dupMethodInstance.mMethodInfoEx = *(methodInstance->mMethodInfoEx);
-				for (auto genericParam : dupMethodInstance.mMethodInfoEx->mGenericParams)
-					genericParam->AddRef();				
-				dupMethodInstance.mMethodInfoEx->mMethodCustomAttributes = NULL;
-			}
-			dupMethodInstance.mHasBeenProcessed = false;			
-			dupMethodInstance.mIRFunction = workItem.mFunc;
-			dupMethodInstance.mMethodProcessRequest = NULL;
-			dupMethodInstance.mIsReified = true;			
-			dupMethodInstance.mHotMethod = NULL;
+			BfMethodInstance dupMethodInstance;
+			dupMethodInstance.CopyFrom(methodInstance);						
+			dupMethodInstance.mIRFunction = workItem.mFunc;			
+			dupMethodInstance.mIsReified = true;
 			dupMethodInstance.mInCEMachine = false; // Only have the original one
 			BF_ASSERT(module->mIsReified); // We should only bother inlining in reified modules
 
@@ -1437,6 +1427,31 @@ BfHotTypeData* BfContext::GetHotTypeData(int typeId)
 	return NULL;
 }
 
+void BfContext::ReflectInit()
+{
+	auto bfModule = mScratchModule;
+
+	bfModule->CreatePointerType(bfModule->GetPrimitiveType(BfTypeCode_NullPtr));
+
+	///
+
+	auto typeDefType = bfModule->ResolveTypeDef(mCompiler->mTypeTypeDef)->ToTypeInstance();
+	if (!typeDefType)
+		return;
+	BF_ASSERT(typeDefType != NULL);
+	mBfTypeType = typeDefType->ToTypeInstance();
+
+	auto typeInstanceDefType = bfModule->ResolveTypeDef(mCompiler->mReflectTypeInstanceTypeDef);
+	if (!typeInstanceDefType)
+		return;
+	auto typeInstanceDefTypeInstance = typeInstanceDefType->ToTypeInstance();
+
+	auto typeDef = mSystem->FindTypeDef("System.ClassVData");
+	BF_ASSERT(typeDef != NULL);
+	auto bfClassVDataType = bfModule->ResolveTypeDef(typeDef)->ToTypeInstance();
+	mBfClassVDataPtrType = bfModule->CreatePointerType(bfClassVDataType);
+}
+
 void BfContext::DeleteType(BfType* type, bool deferDepRebuilds)
 {
 	if (type == mBfObjectType)

+ 1 - 0
IDEHelper/Compiler/BfContext.h

@@ -412,6 +412,7 @@ public:
 	BfType* FindType(const StringImpl& typeName);
 	String TypeIdToString(int typeId);
 	BfHotTypeData* GetHotTypeData(int typeId);	
+	void ReflectInit();
 
 public:
 	BfContext(BfCompiler* compiler);

+ 38 - 2
IDEHelper/Compiler/BfIRBuilder.cpp

@@ -1280,6 +1280,12 @@ String BfIRBuilder::ToString(BfIRValue irValue)
 			BfIRValue targetConst(BfIRValueFlags_Const, ptrToIntConst->mTarget);
 			return ToString(targetConst) + StrFormat(" PtrToInt TypeCode:%d", ptrToIntConst->mToTypeCode);			
 		}
+		else if (constant->mConstType == BfConstType_IntToPtr)
+		{
+			auto bitcast = (BfConstantIntToPtr*)constant;
+			BfIRValue targetConst(BfIRValueFlags_Const, bitcast->mTarget);
+			return ToString(targetConst) + " IntToPtr " + ToString(bitcast->mToType);
+		}
 		else if (constant->mConstType == BfConstType_Array)
 		{
 			auto constArray = (BfConstantArray*)constant;
@@ -1896,6 +1902,14 @@ void BfIRBuilder::Write(const BfIRValue& irValue)
 				Write(ptrToIntConst->mToTypeCode);
 			}
 			break;
+		case (int)BfConstType_IntToPtr:			
+			{
+				auto intToPtrConst = (BfConstantIntToPtr*)constant;
+				BfIRValue targetConst(BfIRValueFlags_Const, intToPtrConst->mTarget);
+				Write(targetConst);
+				Write(intToPtrConst->mToType);
+			}
+			break;
 		case (int)BfConstType_AggZero:
 			{
 				Write(constant->mIRType);
@@ -4074,6 +4088,20 @@ BfIRValue BfIRBuilder::CreatePtrToInt(BfIRValue val, BfTypeCode typeCode)
 
 BfIRValue BfIRBuilder::CreateIntToPtr(BfIRValue val, BfIRType type)
 {
+	if (val.IsConst())
+	{
+		auto ptrToInt = mTempAlloc.Alloc<BfConstantIntToPtr>();
+		ptrToInt->mConstType = BfConstType_IntToPtr;
+		ptrToInt->mTarget = val.mId;
+		ptrToInt->mToType = type;
+
+		BfIRValue castedVal(BfIRValueFlags_Const, mTempAlloc.GetChunkedId(ptrToInt));
+#ifdef CHECK_CONSTHOLDER
+		castedVal.mHolder = this;
+#endif
+		return castedVal;
+	}
+
 	BfIRValue retVal = WriteCmd(BfIRCmd_IntToPtr, val, type);
 	NEW_CMD_INSERTED_IRVALUE;
 	return retVal;
@@ -4806,6 +4834,13 @@ BfIRValue BfIRBuilder::ConstEval_GetBfType(int typeId, BfIRType resultType)
 	return retVal;
 }
 
+BfIRValue BfIRBuilder::ConstEval_GetReflectType(int typeId, BfIRType resultType)
+{
+	BfIRValue retVal = WriteCmd(BfIRCmd_ConstEval_GetReflectType, typeId, resultType);
+	NEW_CMD_INSERTED;
+	return retVal;
+}
+
 BfIRValue BfIRBuilder::ConstEval_DynamicCastCheck(BfIRValue value, int typeId, BfIRType resultType)
 {
 	BfIRValue retVal = WriteCmd(BfIRCmd_ConstEval_DynamicCastCheck, value, typeId, resultType);
@@ -4820,9 +4855,9 @@ BfIRValue BfIRBuilder::ConstEval_GetVirtualFunc(BfIRValue value, int virtualTabl
 	return retVal;
 }
 
-BfIRValue BfIRBuilder::ConstEval_GetInterfaceFunc(BfIRValue value, int typeId, int virtualTableId, BfIRType resultType)
+BfIRValue BfIRBuilder::ConstEval_GetInterfaceFunc(BfIRValue value, int typeId, int methodIdx, BfIRType resultType)
 {
-	BfIRValue retVal = WriteCmd(BfIRCmd_ConstEval_GetInterfaceFunc, value, typeId, virtualTableId, resultType);
+	BfIRValue retVal = WriteCmd(BfIRCmd_ConstEval_GetInterfaceFunc, value, typeId, methodIdx, resultType);
 	NEW_CMD_INSERTED;
 	return retVal;
 }
@@ -4920,6 +4955,7 @@ void BfIRBuilder::CreateObjectAccessCheck(BfIRValue value, bool useAsm)
 	NEW_CMD_INSERTED_IRBLOCK;
 	if (!mIgnoreWrites)
 	{
+		BF_ASSERT(!value.IsConst());
 		BF_ASSERT(!retBlock.IsFake());
 		mActualInsertBlock = retBlock;
 	}

+ 11 - 1
IDEHelper/Compiler/BfIRBuilder.h

@@ -118,6 +118,7 @@ enum BfConstType
 	BfConstType_GEP32_2,
 	BfConstType_ExtractValue,
 	BfConstType_PtrToInt,
+	BfConstType_IntToPtr,
 	BfConstType_TypeOf,
 	BfConstType_AggZero,
 	BfConstType_Array,
@@ -282,6 +283,7 @@ enum BfIRCmd : uint8
 	BfIRCmd_Func_SetLinkage,
 
 	BfIRCmd_ConstEval_GetBfType,
+	BfIRCmd_ConstEval_GetReflectType,
 	BfIRCmd_ConstEval_DynamicCastCheck,
 	BfIRCmd_ConstEval_GetVirtualFunc,
 	BfIRCmd_ConstEval_GetInterfaceFunc,
@@ -831,6 +833,13 @@ struct BfConstantPtrToInt
 	BfTypeCode mToTypeCode;
 };
 
+struct BfConstantIntToPtr
+{
+	BfConstType mConstType;
+	int mTarget;
+	BfIRType mToType;
+};
+
 struct BfConstantGEP32_2
 {
 	BfConstType mConstType;
@@ -1230,9 +1239,10 @@ public:
 	void Func_SetLinkage(BfIRFunction func, BfIRLinkageType linkage);
 	
 	BfIRValue ConstEval_GetBfType(int typeId, BfIRType resultType);
+	BfIRValue ConstEval_GetReflectType(int typeId, BfIRType resultType);
 	BfIRValue ConstEval_DynamicCastCheck(BfIRValue value, int typeId, BfIRType resultType);
 	BfIRValue ConstEval_GetVirtualFunc(BfIRValue value, int virtualTableId, BfIRType resultType);
-	BfIRValue ConstEval_GetInterfaceFunc(BfIRValue value, int typeId, int virtualTableId, BfIRType resultType);
+	BfIRValue ConstEval_GetInterfaceFunc(BfIRValue value, int typeId, int methodIdx, BfIRType resultType);
 
 	void SaveDebugLocation();
 	void RestoreDebugLocation();

+ 80 - 39
IDEHelper/Compiler/BfModule.cpp

@@ -1338,13 +1338,15 @@ void BfModule::StartExtension()
 
 void BfModule::GetConstClassValueParam(BfIRValue classVData, SizedArrayImpl<BfIRValue>& typeValueParams)
 {
+	auto hasObjectDebugFlags = mContext->mBfObjectType->mFieldInstances[0].mResolvedType->IsInteger();
+
 	BfIRValue vDataValue;
-	if (mCompiler->mOptions.mObjectHasDebugFlags)
+	if (hasObjectDebugFlags)
 		vDataValue = mBfIRBuilder->CreatePtrToInt(classVData, BfTypeCode_IntPtr);
 	else
 		vDataValue = mBfIRBuilder->CreateBitCast(classVData, mBfIRBuilder->MapType(mContext->mBfClassVDataPtrType));	
 	typeValueParams.push_back(vDataValue);
-	if (mCompiler->mOptions.mObjectHasDebugFlags)
+	if (hasObjectDebugFlags)
 	{
 		auto primType = GetPrimitiveType(BfTypeCode_IntPtr);
 		typeValueParams.push_back(GetDefaultValue(primType));		
@@ -4640,6 +4642,12 @@ BfIRValue BfModule::CreateClassVDataGlobal(BfTypeInstance* typeInstance, int* ou
 	PopulateType(typeInstance, BfPopulateType_DataAndMethods);
 
 	BfType* classVDataType = ResolveTypeDef(mCompiler->mClassVDataTypeDef);
+
+	if (mIsConstModule)
+	{
+		auto idVal = mBfIRBuilder->CreateConst(BfTypeCode_IntPtr, typeInstance->mTypeId);
+		return mBfIRBuilder->CreateIntToPtr(idVal, mBfIRBuilder->MapType(CreatePointerType(classVDataType)));
+	}	
 		
 	BfIRValue* globalVariablePtr = NULL;
 	mClassVDataRefs.TryGetValue(typeInstance, &globalVariablePtr);
@@ -4828,6 +4836,13 @@ BfIRValue BfModule::CreateTypeDataRef(BfType* type)
 	{
 		return mBfIRBuilder->CreateTypeOf(type);
 	}
+
+	if (mIsConstModule)
+	{
+		auto typeTypeDef = ResolveTypeDef(mCompiler->mTypeTypeDef);
+		auto typeTypeInst = typeTypeDef->ToTypeInstance();
+		return mBfIRBuilder->ConstEval_GetReflectType(type->mTypeId, mBfIRBuilder->MapType(typeTypeInst));
+	}
 	
 	BfIRValue globalVariable;
 	
@@ -4883,6 +4898,11 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary<int, int>& usedStrin
 		return BfIRValue();
 	}
 	
+	if (mContext->mBfTypeType == NULL)
+	{
+
+	}
+
 	BfIRValue typeTypeData;
 	int typeFlags = 0;	
 	if (needsTypeData)
@@ -5141,29 +5161,32 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary<int, int>& usedStrin
 	StringT<128> mangledName;
 	BfMangler::Mangle(mangledName, mCompiler->GetMangleKind(), typeInstance, typeInstance->mModule);
 	
-	for (int methodIdx = 0; methodIdx < (int)typeDef->mMethods.size(); methodIdx++)
+	if (!mIsConstModule)
 	{
-		auto methodDef = typeDef->mMethods[methodIdx];
-		auto methodInstance = typeInstance->mMethodInstanceGroups[methodIdx].mDefault;
-		if (methodInstance == NULL)
-			continue;
-		if (typeInstance->IsUnspecializedType())
-			continue;
-		if (!typeInstance->IsTypeMemberAccessible(methodDef->mDeclaringType, mProject))
+		for (int methodIdx = 0; methodIdx < (int)typeDef->mMethods.size(); methodIdx++)
 		{
-			if (methodInstance->mChainType == BfMethodChainType_ChainMember)
+			auto methodDef = typeDef->mMethods[methodIdx];
+			auto methodInstance = typeInstance->mMethodInstanceGroups[methodIdx].mDefault;
+			if (methodInstance == NULL)
+				continue;
+			if (typeInstance->IsUnspecializedType())
+				continue;
+			if (!typeInstance->IsTypeMemberAccessible(methodDef->mDeclaringType, mProject))
 			{
-				BF_ASSERT(!methodInstance->GetOwner()->IsUnspecializedType());
+				if (methodInstance->mChainType == BfMethodChainType_ChainMember)
+				{
+					BF_ASSERT(!methodInstance->GetOwner()->IsUnspecializedType());
 
-				// We need to create an empty thunk for this chained method
-				BfIRFunction func = CreateFunctionFrom(methodInstance, false, methodInstance->mAlwaysInline);
-				mBfIRBuilder->SetActiveFunction(func);
-				auto block = mBfIRBuilder->CreateBlock("entry", true);
-				mBfIRBuilder->SetInsertPoint(block);
-				mBfIRBuilder->CreateRetVoid();
-				mBfIRBuilder->SetActiveFunction(BfIRFunction());
+					// We need to create an empty thunk for this chained method
+					BfIRFunction func = CreateFunctionFrom(methodInstance, false, methodInstance->mAlwaysInline);
+					mBfIRBuilder->SetActiveFunction(func);
+					auto block = mBfIRBuilder->CreateBlock("entry", true);
+					mBfIRBuilder->SetInsertPoint(block);
+					mBfIRBuilder->CreateRetVoid();
+					mBfIRBuilder->SetActiveFunction(BfIRFunction());
+				}
 			}
-		}		
+		}
 	}
 	
 	SizedArray<BfIRValue, 32> vData;
@@ -5292,7 +5315,7 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary<int, int>& usedStrin
 			{
 				highestIFaceVirtIdx = BF_MAX(highestIFaceVirtIdx, interfaceEntry.mStartVirtualIdx + interfaceEntry.mInterfaceType->mVirtualMethodTableSize);
 
-				if (!typeInstance->IsTypeMemberAccessible(interfaceEntry.mDeclaringType, mProject))
+				if ((!mIsConstModule) && (!typeInstance->IsTypeMemberAccessible(interfaceEntry.mDeclaringType, mProject)))
 					continue;
 
 				_InterfaceMatchEntry* matchEntry = NULL;
@@ -5391,13 +5414,14 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary<int, int>& usedStrin
 					if (entry.mDeclaringMethod.mMethodNum == -1)
 						continue;
 					BfMethodInstance* methodInstance = (BfMethodInstance*)entry.mImplementingMethod;
-					if ((methodInstance == NULL) || (!typeInstance->IsTypeMemberAccessible(methodInstance->mMethodDef->mDeclaringType, mProject)))
+					if ((methodInstance == NULL) || 
+						((!mIsConstModule) && (!typeInstance->IsTypeMemberAccessible(methodInstance->mMethodDef->mDeclaringType, mProject))))
 					{
 						if (origVTable.empty())
 							origVTable = typeInstance->mVirtualMethodTable;
 
 						BfMethodInstance* declMethodInstance = entry.mDeclaringMethod;
-						if (typeInstance->IsTypeMemberAccessible(declMethodInstance->mMethodDef->mDeclaringType, mProject))
+						if ((mIsConstModule) || (typeInstance->IsTypeMemberAccessible(declMethodInstance->mMethodDef->mDeclaringType, mProject)))
 						{
 							// Prepare to reslot...
 							entry.mImplementingMethod = entry.mDeclaringMethod;
@@ -5429,7 +5453,7 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary<int, int>& usedStrin
 						if (!reslotNames.Contains(methodInstance->mMethodDef->mName))
 							continue;
 
-						if (!typeInstance->IsTypeMemberAccessible(methodInstance->mMethodDef->mDeclaringType, mProject))
+						if ((!mIsConstModule) && (!typeInstance->IsTypeMemberAccessible(methodInstance->mMethodDef->mDeclaringType, mProject)))
 							continue;
 						if ((methodInstance->mChainType != BfMethodChainType_None) && (methodInstance->mChainType != BfMethodChainType_ChainHead))
 							continue;
@@ -5465,7 +5489,7 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary<int, int>& usedStrin
 						BfMethodInstance* methodInstance = (BfMethodInstance*)entry.mImplementingMethod;
 						if ((methodInstance != NULL) && (!methodInstance->mMethodDef->mIsAbstract))
 						{
-							BF_ASSERT(typeInstance->IsTypeMemberAccessible(methodInstance->mMethodDef->mDeclaringType, mProject));
+							BF_ASSERT((mIsConstModule) || typeInstance->IsTypeMemberAccessible(methodInstance->mMethodDef->mDeclaringType, mProject));
 							moduleMethodInst = GetMethodInstanceAtIdx(methodInstance->mMethodInstanceGroup->mOwner, methodInstance->mMethodInstanceGroup->mMethodIdx, NULL, BfGetMethodInstanceFlag_NoInline);
 							auto funcPtr = mBfIRBuilder->CreateBitCast(moduleMethodInst.mFunc, voidPtrIRType);
 							vValue = funcPtr;
@@ -5531,7 +5555,7 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary<int, int>& usedStrin
 			auto interfaceEntry = interfacePair.mValue.mEntry;
 
 			bool makeEmpty = false;
-			if (!typeInstance->IsTypeMemberAccessible(interfaceEntry->mDeclaringType, mProject))
+			if ((!mIsConstModule) && (!typeInstance->IsTypeMemberAccessible(interfaceEntry->mDeclaringType, mProject)))
 				makeEmpty = true;
 			
 			int endVirtualIdx = interfaceEntry->mStartVirtualIdx + interfaceEntry->mInterfaceType->mVirtualMethodTableSize;
@@ -5627,10 +5651,10 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary<int, int>& usedStrin
 			}
 		}
 				
-		if ((needsVData) && (!typeInstance->mTypeDef->mIsStatic))
+		if ((needsVData) && (!typeInstance->mTypeDef->mIsStatic) && (!mIsConstModule))
 		{
 			BfIRValue ifaceMethodExtVar;
-			if (!ifaceMethodExtData.IsEmpty())
+			if ((!ifaceMethodExtData.IsEmpty()) && (!mIsConstModule))
 			{
 				StringT<128> classVDataName;
 				BfMangler::MangleStaticFieldName(classVDataName, mCompiler->GetMangleKind(), typeInstance, "bf_hs_replace_IFaceExt");
@@ -6228,6 +6252,10 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary<int, int>& usedStrin
 		if (!needsTypeData)
 			break;
 
+		// Disable const method reflection info for now
+		if (mIsConstModule)
+			break;
+
 		auto methodInstanceGroup = &typeInstance->mMethodInstanceGroups[methodIdx];
 		if (!methodInstanceGroup->IsImplemented())
 			continue;		
@@ -6270,9 +6298,8 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary<int, int>& usedStrin
 			}
 		}
 		
-		if (!typeInstance->IsTypeMemberAccessible(methodDef->mDeclaringType, mProject))
+		if ((!mIsConstModule) && (!typeInstance->IsTypeMemberAccessible(methodDef->mDeclaringType, mProject)))
 			continue;
-
 		
 		//
 		{
@@ -6709,7 +6736,7 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary<int, int>& usedStrin
 
 	mTypeDataRefs[typeInstance] = typeDataVar;
 
-	if (classVDataVar)
+	if ((!mIsConstModule) && (classVDataVar))
 	{	
 		BF_ASSERT(!classVDataName.IsEmpty());
 
@@ -6751,6 +6778,8 @@ void BfModule::CheckStaticAccess(BfTypeInstance* typeInstance)
 	// Note: this is not just for perf, it fixes a field var-type resolution issue
 	if (mBfIRBuilder->mIgnoreWrites)
 		return;
+	if (mIsConstModule)
+		return;
 
 	PopulateType(typeInstance, BfPopulateType_DataAndMethods);
 
@@ -6891,7 +6920,7 @@ BfIRFunction BfModule::GetBuiltInFunc(BfBuiltInFuncType funcTypeId)
 			break;
 		case BfBuiltInFuncType_Malloc:			
 			{
-				if (mCompiler->mOptions.mDebugAlloc)
+				if ((mCompiler->mOptions.mDebugAlloc) && (!mIsConstModule))
 				{
 					func = GetInternalMethod("Dbg_RawAlloc", 1).mFunc;
 				}
@@ -6914,7 +6943,7 @@ BfIRFunction BfModule::GetBuiltInFunc(BfBuiltInFuncType funcTypeId)
 			break;
 		case BfBuiltInFuncType_Free:			
 		{				
-				if (mCompiler->mOptions.mDebugAlloc)	 
+				if ((mCompiler->mOptions.mDebugAlloc) && (!mIsConstModule))
 				{
 					func = GetInternalMethod("Dbg_RawFree").mFunc;
 				}
@@ -8142,7 +8171,7 @@ BfIRValue BfModule::AllocBytes(BfAstNode* refNode, const BfAllocTarget& allocTar
 	if ((allocFlags & BfAllocFlags_NoDefaultToMalloc) != 0)
 		return result;
 	
-	if (mCompiler->mOptions.mDebugAlloc)
+	if ((mCompiler->mOptions.mDebugAlloc) && (!mIsConstModule))
 	{
 		BfIRValue allocData = GetDbgRawAllocData(type);
 		BfModuleMethodInstance allocMethod = GetInternalMethod("Dbg_RawAlloc", 2);
@@ -8838,13 +8867,14 @@ BfIRValue BfModule::AllocFromType(BfType* type, const BfAllocTarget& allocTarget
 		}		
 		else
 		{	
-			if ((mBfIRBuilder->mIgnoreWrites) || (mCompiler->mIsResolveOnly))
+			if ((mBfIRBuilder->mIgnoreWrites) || 
+				((mCompiler->mIsResolveOnly) && (!mIsConstModule)))
 				return GetDefaultValue(typeInstance);
 
 			auto classVDataType = ResolveTypeDef(mCompiler->mClassVDataTypeDef);			
 			auto vData = mBfIRBuilder->CreateBitCast(vDataRef, mBfIRBuilder->MapTypeInstPtr(classVDataType->ToTypeInstance()));			
 
-			if ((mCompiler->mOptions.mObjectHasDebugFlags) && (!mIsConstModule))
+			if (mCompiler->mOptions.mObjectHasDebugFlags)
 			{
 				SizedArray<BfIRValue, 4> llvmArgs;
 				llvmArgs.push_back(vData);
@@ -8870,6 +8900,12 @@ BfIRValue BfModule::AllocFromType(BfType* type, const BfAllocTarget& allocTarget
 				BfIRValue objectVal = mBfIRBuilder->CreateCall(irFunc, llvmArgs);
 				auto objResult = mBfIRBuilder->CreateBitCast(objectVal, mBfIRBuilder->MapType(mContext->mBfObjectType, BfIRPopulateType_Full));
 				auto vdataPtr = mBfIRBuilder->CreateInBoundsGEP(objResult, 0, 0);
+
+				if (mIsConstModule)
+				{					
+					vdataPtr = mBfIRBuilder->CreateBitCast(vdataPtr, mBfIRBuilder->GetPointerTo(mBfIRBuilder->MapTypeInstPtr(classVDataType->ToTypeInstance())));
+				}
+
 				mBfIRBuilder->CreateStore(vData, vdataPtr);
 				result = mBfIRBuilder->CreateBitCast(objectVal, mBfIRBuilder->MapType(typeInstance));				
 			}
@@ -9136,7 +9172,7 @@ bool BfModule::WantsLifetimes()
 
 bool BfModule::HasCompiledOutput()
 {
-	return (!mSystem->mIsResolveOnly) && (mIsReified);
+	return (!mSystem->mIsResolveOnly) && (mIsReified) && (!mIsConstModule);
 }
 
 // We will skip the object access check for any occurances of this value
@@ -13114,6 +13150,11 @@ BfTypedValue BfModule::ReferenceStaticField(BfFieldInstance* fieldInstance)
 			typeType = typeType->GetUnderlyingType();
 		}
 
+		if (mIsConstModule)
+		{			
+			mCompiler->mCEMachine->QueueStaticField(fieldInstance, staticVarName);
+		}
+
 		PopulateType(typeType);
 		if ((typeType != NULL) && (!typeType->IsValuelessType()))
 		{
@@ -17487,7 +17528,7 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup)
 	}
 
 	int dependentGenericStartIdx = 0;
-	if (methodDef->mIsLocalMethod) // See DoMethodDeclaration for an explaination of dependentGenericStartIdx
+	if ((methodDef->mIsLocalMethod) && (mCurMethodState != NULL)) // See DoMethodDeclaration for an explaination of dependentGenericStartIdx
 		dependentGenericStartIdx = (int)mCurMethodState->GetRootMethodState()->mMethodInstance->GetNumGenericArguments();
 
 	SetAndRestoreValue<BfMethodInstance*> prevMethodInstance(mCurMethodInstance, methodInstance);	
@@ -17495,7 +17536,7 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup)
 	SetAndRestoreValue<BfFilePosition> prevFilePos(mCurFilePosition);	
 	SetAndRestoreValue<bool> prevHadBuildError(mHadBuildError, false);
 	SetAndRestoreValue<bool> prevHadWarning(mHadBuildWarning, false);
-	SetAndRestoreValue<bool> prevIgnoreWarnings(mIgnoreWarnings, false);
+	SetAndRestoreValue<bool> prevIgnoreWarnings(mIgnoreWarnings, mIsConstModule);
 
 	if ((methodInstance->mIsReified) &&
 		((methodDef->mMethodType == BfMethodType_Ctor) || (methodDef->mMethodType == BfMethodType_CtorNoBody)))

+ 23 - 0
IDEHelper/Compiler/BfResolvedTypeUtils.cpp

@@ -567,6 +567,29 @@ BfMethodInstance::~BfMethodInstance()
 	delete mMethodInfoEx;	
 }
 
+void BfMethodInstance::CopyFrom(BfMethodInstance* methodInstance)
+{
+	*this = *methodInstance;
+	if (mMethodInfoEx != NULL)
+	{
+		mMethodInfoEx = new BfMethodInfoEx();
+		*mMethodInfoEx = *(methodInstance->mMethodInfoEx);
+		for (auto genericParam : mMethodInfoEx->mGenericParams)
+			genericParam->AddRef();
+		mMethodInfoEx->mMethodCustomAttributes = NULL;
+		
+		if (mMethodInfoEx->mClosureInstanceInfo != NULL)
+		{
+			mMethodInfoEx->mClosureInstanceInfo = new BfClosureInstanceInfo();
+			*mMethodInfoEx->mClosureInstanceInfo = *methodInstance->mMethodInfoEx->mClosureInstanceInfo;
+		}
+	}
+	mHasBeenProcessed = false;
+	mIRFunction = BfIRValue();
+	mMethodProcessRequest = NULL;
+	mHotMethod = NULL;
+}
+
 BfImportKind BfMethodInstance::GetImportKind()
 {
 	if (mMethodDef->mImportKind != BfImportKind_Import_Unknown)

+ 9 - 7
IDEHelper/Compiler/BfResolvedTypeUtils.h

@@ -771,7 +771,7 @@ public:
 	BfTypeVector mMethodGenericArguments;
 	Dictionary<int64, BfType*> mGenericTypeBindings;
 	BfMethodCustomAttributes* mMethodCustomAttributes;
-	int mMinDependDepth;
+	int mMinDependDepth;	
 
 	BfMethodInfoEx()
 	{
@@ -779,10 +779,10 @@ public:
 		mForeignType = NULL;
 		mClosureInstanceInfo = NULL;
 		mMethodCustomAttributes = NULL;
-		mMinDependDepth = -1;
+		mMinDependDepth = -1;		
 	}
-
-	~BfMethodInfoEx();
+	
+	~BfMethodInfoEx();	
 };
 
 enum BfImportCallKind
@@ -872,6 +872,8 @@ public:
 
 	~BfMethodInstance();
 
+	void CopyFrom(BfMethodInstance* methodInstance);
+
 	bool IsMixin()
 	{
 		return mMethodDef->mMethodType == BfMethodType_Mixin;
@@ -923,7 +925,7 @@ public:
 	int GetIRFunctionParamCount(BfModule* module);
 
 	bool IsExactMatch(BfMethodInstance* other, bool ignoreImplicitParams = false, bool checkThis = false);	
-	bool IsReifiedAndImplemented();
+	bool IsReifiedAndImplemented();	
 
 	BfMethodInfoEx* GetMethodInfoEx();
 	BfCustomAttributes* GetCustomAttributes()
@@ -1292,7 +1294,7 @@ public:
 	bool mFieldIncluded;
 	bool mIsEnumPayloadCase;
 	bool mIsThreadLocal;
-	bool mIsInferredType;
+	bool mIsInferredType;	
 	int mLastRevisionReferenced;
 
 public:
@@ -1314,7 +1316,7 @@ public:
 		mFieldIncluded = copyFrom.mFieldIncluded;		
 		mIsEnumPayloadCase = copyFrom.mIsEnumPayloadCase;
 		mIsThreadLocal = copyFrom.mIsThreadLocal;
-		mIsInferredType = copyFrom.mIsInferredType;
+		mIsInferredType = copyFrom.mIsInferredType;		
 		mLastRevisionReferenced = copyFrom.mLastRevisionReferenced;		
 	}
 

+ 5 - 5
IDEHelper/Compiler/BfStmtEvaluator.cpp

@@ -3933,7 +3933,7 @@ void BfModule::Visit(BfDeleteStatement* deleteStmt)
 			allowPrivate = false;
 		}			
 
-		if (mCompiler->mOptions.mObjectHasDebugFlags)
+		if ((mCompiler->mOptions.mObjectHasDebugFlags) && (!mIsConstModule))
 		{			
 			auto preDelete = GetInternalMethod((deleteStmt->mTargetTypeToken != NULL) ? "Dbg_ObjectPreCustomDelete" : "Dbg_ObjectPreDelete");
 			SizedArray<BfIRValue, 4> llvmArgs;
@@ -3990,7 +3990,7 @@ void BfModule::Visit(BfDeleteStatement* deleteStmt)
 		}
 		else
 		{
-			if (mCompiler->mOptions.mEnableRealtimeLeakCheck)
+			if ((mCompiler->mOptions.mEnableRealtimeLeakCheck) && (!mIsConstModule))
 			{				
 				SizedArray<BfIRValue, 4> llvmArgs;
 				llvmArgs.push_back(mBfIRBuilder->CreateBitCast(val.mValue, mBfIRBuilder->MapType(objectType)));
@@ -6784,7 +6784,7 @@ void BfModule::Visit(BfDeferStatement* deferStmt)
 
 			if (!customAllocator)
 			{
-				if (mCompiler->mOptions.mEnableRealtimeLeakCheck)
+				if ((mCompiler->mOptions.mEnableRealtimeLeakCheck) && (!mIsConstModule))
 				{
 					auto moduleMethodInstance = GetInternalMethod("Dbg_MarkObjectDeleted");
 					AddDeferredCall(moduleMethodInstance, llvmArgs, scope, deleteStmt, false, true);
@@ -6801,7 +6801,7 @@ void BfModule::Visit(BfDeferStatement* deferStmt)
 			auto moduleMethodInstance = GetMethodInstance(objectType, methodInstance->mMethodDef, BfTypeVector());
 			AddDeferredCall(moduleMethodInstance, llvmArgs, scope, deleteStmt, false, true);
 
-			if (mCompiler->mOptions.mObjectHasDebugFlags)
+			if ((mCompiler->mOptions.mObjectHasDebugFlags) && (!mIsConstModule))
 			{
 				auto moduleMethodInstance = GetMethodByName(internalType->ToTypeInstance(), (deleteStmt->mTargetTypeToken != NULL) ? "Dbg_ObjectPreCustomDelete" : "Dbg_ObjectPreDelete");
 				AddDeferredCall(moduleMethodInstance, llvmArgs, scope, deleteStmt, false, true);
@@ -6813,7 +6813,7 @@ void BfModule::Visit(BfDeferStatement* deferStmt)
 			{
 				val = LoadValue(val);
 				BfModuleMethodInstance moduleMethodInstance;
-				if (mCompiler->mOptions.mEnableRealtimeLeakCheck)
+				if ((mCompiler->mOptions.mDebugAlloc) && (!mIsConstModule))
 					moduleMethodInstance = GetMethodByName(internalType->ToTypeInstance(), "Dbg_RawFree");
 				else
 					moduleMethodInstance = GetMethodByName(internalType->ToTypeInstance(), "Free");

File diff suppressed because it is too large
+ 732 - 180
IDEHelper/Compiler/CeMachine.cpp


+ 114 - 12
IDEHelper/Compiler/CeMachine.h

@@ -13,11 +13,13 @@ class BeContext;
 class BeDbgLoc;
 class BeType;
 class BeValue;
+class BeConstant;
 class BeInst;
 class BeDbgFile;
 class BePhiInst;
 class BeFunction;
 class BeSwitchInst;
+class BeGlobalVariable;
 class CeMachine;
 class CeFunction;
 
@@ -68,6 +70,7 @@ enum CeOp : int16
 
 	CeOp_Error,	
 	CeOp_DynamicCastCheck,
+	CeOp_GetReflectType,
 	CeOp_GetString,
 	CeOp_Malloc,
 	CeOp_Free,
@@ -78,7 +81,9 @@ enum CeOp : int16
 	
 	CeOp_FrameAddr_32,
 	CeOp_FrameAddr_64,
+	CeOp_FrameAddrOfs_32,
 
+	CeOp_ConstDataRef,
 	CeOp_Zero,
 	CEOP_SIZED(Const),
 	CEOP_SIZED(Load),
@@ -92,9 +97,12 @@ enum CeOp : int16
 	CeOp_AdjustSPConst,
 	CeOp_GetSP,
 	CeOp_SetSP,
+	CeOp_GetStaticField,
+	CeOp_GetMethod,
+	CeOp_GetMethod_Inner,
+	CeOp_GetMethod_Virt,
+	CeOp_GetMethod_IFace,
 	CeOp_Call,
-	CeOp_Call_Virt,
-	CeOp_Call_IFace,
 	
 	CeOp_Conv_I8_I16,
 	CeOp_Conv_I8_I32,
@@ -231,16 +239,71 @@ enum CeFunctionKind
 	CeFunctionKind_Normal,
 	CeFunctionKind_Extern,
 	CeFunctionKind_OOB,
+	CeFunctionKind_Malloc,
+	CeFunctionKind_Free,
 	CeFunctionKind_FatalError,
 	CeFunctionKind_DebugWrite,
 	CeFunctionKind_DebugWrite_Int,
+	CeFunctionKind_GetReflectType,
+	CeFunctionKind_Char32_ToLower,
+	CeFunctionKind_Char32_ToUpper,
+	CeFunctionKind_Char32_IsLower,
+	CeFunctionKind_Char32_IsUpper,
+	CeFunctionKind_Char32_IsWhiteSpace_EX,
+	CeFunctionKind_Char32_IsLetterOrDigit,
+	CeFunctionKind_Char32_IsLetter,
+	CeFunctionKind_Char32_IsNumber,
+};
+
+class CeConstStructData
+{
+public:
+	Val128 mHash;
+	Array<uint8> mData;
+	addr_ce mAddr;
+	int mBindExecuteId;
+
+public:
+	CeConstStructData()
+	{
+		mBindExecuteId = -1;
+		mAddr = 0;
+	}
+};
+
+class CeInnerFunctionInfo
+{
+public:
+	String mName;
+	BeFunction* mBeFunction;
+	CeFunction* mOwner;
+};
+
+class CeStaticFieldEntry
+{
+public:
+	String mName;
+	int mTypeId;
+	int mSize;
+	addr_ce mAddr;
+	int mBindExecuteId;
+
+public:
+	CeStaticFieldEntry()
+	{
+		mTypeId = -1;
+		mSize = 0;
+		mAddr = 0;		
+		mBindExecuteId = -1;		
+	}
 };
 
 class CeFunction
 {
 public:
 	CeFunctionInfo* mCeFunctionInfo;
-	BfMethodInstance* mMethodInstance;
+	CeInnerFunctionInfo* mCeInnerFunctionInfo;
+	BfMethodInstance* mMethodInstance;	
 	CeFunctionKind mFunctionKind;
 	bool mInitialized;
 	bool mFailed;		
@@ -249,7 +312,10 @@ public:
 	Array<CeEmitEntry> mEmitTable;
 	Array<CeCallEntry> mCallTable;
 	Array<CeStringEntry> mStringTable;
+	Array<CeConstStructData> mConstStructTable;
+	Array<CeStaticFieldEntry> mStaticFieldTable;
 	Array<BfType*> mTypeTable;
+	Array<CeFunction*> mInnerFunctions;
 	String mGenError;
 	int mFrameSize;	
 
@@ -257,6 +323,7 @@ public:
 	CeFunction()
 	{
 		mCeFunctionInfo = NULL;
+		mCeInnerFunctionInfo = NULL;
 		mFunctionKind = CeFunctionKind_Normal;
 		mInitialized = false;
 		mMethodInstance = NULL;
@@ -278,7 +345,9 @@ enum CeOperandKind
 	CeOperandKind_FrameOfs,
 	CeOperandKind_AllocaAddr,
 	CeOperandKind_Block,
-	CeOperandKind_Immediate
+	CeOperandKind_Immediate,
+	CeOperandKind_ConstAgg,	
+	CeOperandKind_CallTableIdx
 };
 
 class CeOperand
@@ -290,6 +359,8 @@ public:
 		int mFrameOfs;
 		int mBlockIdx;
 		int mImmediate;
+		int mCallTableIdx;
+		BeConstant* mConstant;
 	};
 	BeType* mType;
 
@@ -312,8 +383,10 @@ public:
 	}
 };
 
-#define BF_CE_STACK_SIZE 1024*1024
+#define BF_CE_STACK_SIZE 4*1024*1024
 #define BF_CE_MAX_MEMORY 128*1024*1024
+#define BF_CE_MAX_CARRYOVER_MEMORY BF_CE_STACK_SIZE + 1024*1024
+#define BF_CE_MAX_CARRYOVER_HEAP 1024*1024
 
 enum CeOperandInfoKind
 {
@@ -385,6 +458,7 @@ public:
 class CeBuilder
 {
 public:	
+	CeBuilder* mParentBuilder;
 	CeMachine* mCeMachine;	
 	CeFunction* mCeFunction;
 	BeFunction* mBeFunction;	
@@ -401,10 +475,14 @@ public:
 	Dictionary<BeDbgFile*, int> mDbgFileMap;
 	Dictionary<BeFunction*, int> mFunctionMap;
 	Dictionary<int, int> mStringMap;
+	Dictionary<BeConstant*, int> mConstDataMap;
+	Dictionary<BeFunction*, int> mInnerFunctionMap;
+	Dictionary<BeGlobalVariable*, int> mStaticFieldMap;
 	
 public:
 	CeBuilder()
 	{
+		mParentBuilder = NULL;
 		mPtrSize = 0;
 		mCeFunction = NULL;
 		mBeFunction = NULL;
@@ -417,6 +495,7 @@ public:
 
 	CeOperand FrameAlloc(BeType* type);
 	CeOperand EmitConst(int64 val, int size);
+	CeErrorKind EmitConst(Array<uint8>& arr, BeConstant* constant);
 	CeOperand GetOperand(BeValue* value, bool allowAlloca = false, bool allowImmediate = false);
 	CeSizeClass GetSizeClass(int size);
 	int GetCodePos();
@@ -430,6 +509,7 @@ public:
 	void Emit(int64 val);
 	void Emit(bool val);
 	void Emit(void* ptr, int size);
+	void EmitZeroes(int size);
 	void EmitJump(CeOp op, const CeOperand& block);
 	void EmitBinarySwitchSection(BeSwitchInst* switchInst, int startIdx, int endIdx);	
 
@@ -454,15 +534,24 @@ public:
 	CeFrame()
 	{
 		mFunction = NULL;
-		mStackAddr = NULL;
-		mFrameAddr = NULL;
+		mStackAddr = 0;
+		mFrameAddr = 0;
 		mInstPtr = NULL;
 	}
 };
 
-class CeFunctionRef
+class CeStaticFieldInfo
 {
-	//CeFunction* ;
+public:
+	BfFieldInstance* mFieldInstance;	
+	addr_ce mAddr;
+
+public:
+	CeStaticFieldInfo()
+	{
+		mFieldInstance = NULL;		
+		mAddr = 0;
+	}
 };
 
 class CeMachine
@@ -470,15 +559,22 @@ class CeMachine
 public:
 	Dictionary<BfMethodInstance*, CeFunctionInfo*> mFunctions;
 	Dictionary<String, CeFunctionInfo*> mNamedFunctionMap;
+		
 	BfCompiler* mCompiler;
 	BfModule* mCeModule;
 	int mRevision;
 	int mExecuteId;
 
+	// These are only valid for the current execution
 	ContiguousHeap* mHeap;
 	Array<CeFrame> mCallStack;
 	Array<uint8> mMemory;
 	Dictionary<int, addr_ce> mStringMap;
+	int mStringCharsOffset;
+	Dictionary<int, addr_ce> mReflectMap;
+	Dictionary<Val128, addr_ce> mConstDataMap;	
+	Dictionary<String, CeStaticFieldInfo> mStaticFieldMap;
+	HashSet<int> mStaticCtorExecSet;
 	
 	BfAstNode* mCurTargetSrc;
 	BfModule* mCurModule;	
@@ -492,24 +588,30 @@ public:
 	void Init();	
 	uint8* CeMalloc(int size);
 	bool CeFree(addr_ce addr);
+	addr_ce GetReflectType(int typeId);
+	addr_ce GetString(int stringId);
+	addr_ce GetConstantData(BeConstant* constant);
+	BfType* GetBfType(int typeId);	
 
 	BeContext* GetBeContext();
 	BeModule* GetBeModule();
 	void DerefMethodInfo(CeFunctionInfo* ceFunctionInfo);
-	void RemoveMethod(BfMethodInstance* methodInstance);
+	void RemoveMethod(BfMethodInstance* methodInstance);	
 	int GetConstantSize(BfConstant* constant);
+	CeErrorKind WriteConstant(Array<uint8>& arr, BeConstant* constVal);
 	void WriteConstant(uint8* ptr, BfConstant* constant);
 	void CreateFunction(BfMethodInstance* methodInstance, CeFunction* ceFunction);		
 	bool Execute(CeFunction* startFunction, uint8* startStackPtr, uint8* startFramePtr);
 
-	void PrepareFunction(CeFunction* methodInstance);	
+	void PrepareFunction(CeFunction* methodInstance, CeBuilder* parentBuilder);	
 	CeFunction* GetFunction(BfMethodInstance* methodInstance, BfIRValue func, bool& added);
 	CeFunction* GetPreparedFunction(BfMethodInstance* methodInstance);
-
+	
 public:
 	void CompileStarted();
 	void QueueMethod(BfMethodInstance* methodInstance, BfIRValue func);
 	void QueueMethod(BfModuleMethodInstance moduleMethodInstance);
+	void QueueStaticField(BfFieldInstance* fieldInstance, const StringImpl& mangledFieldName);
 	BfTypedValue Call(BfAstNode* targetSrc, BfModule* module, BfMethodInstance* methodInstance, const BfSizedArray<BfIRValue>& args, CeEvalFlags flags);
 };
 

Some files were not shown because too many files changed in this diff