Explorar o código

Fixed comptime geps with non-ptrsize indices

Brian Fiete %!s(int64=2) %!d(string=hai) anos
pai
achega
dd22fa056f

+ 2 - 0
IDEHelper/Compiler/BfExprEvaluator.cpp

@@ -21183,6 +21183,8 @@ void BfExprEvaluator::Visit(BfTupleExpression* tupleExpr)
 		if (isExactConst)
 		{
 			mModule->PopulateType(tupleType);
+			if (tupleType->IsDataIncomplete())
+				return;
 
 			Array<BfIRValue> irValues;
 			irValues.Resize(typedValues.mSize + 1);

+ 15 - 0
IDEHelper/Compiler/CeDebugger.cpp

@@ -1108,6 +1108,21 @@ String CeDebugger::Evaluate(const StringImpl& expr, CeFormatInfo formatInfo, int
 	auto terminatedExpr = expr;
 	terminatedExpr.Trim();
 
+	if (terminatedExpr.StartsWith("!"))
+	{
+		if (terminatedExpr == "!info")
+		{
+			auto ceFrame = GetFrame(callStackIdx);
+			if (ceFrame != NULL)
+			{
+				if (ceFrame->mFunction->mCeFunctionInfo->mMethodInstance != NULL)
+					OutputMessage(StrFormat("Module: %s\n", ceFrame->mFunction->mCeFunctionInfo->mMethodInstance->GetOwner()->mModule->mModuleName.c_str()));
+				OutputMessage(StrFormat("Link Name: %s\n", ceFrame->mFunction->mCeFunctionInfo->mName.c_str()));
+			}
+			return "";
+		}
+	}
+
 	if (terminatedExpr.EndsWith(">"))
 		parseAsType = true;
 	else if ((terminatedExpr.StartsWith("comptype(")) && (!terminatedExpr.Contains('.')))

+ 401 - 252
IDEHelper/Compiler/CeMachine.cpp

@@ -250,9 +250,29 @@ static_assert(BF_ARRAY_COUNT(gOpInfo) == (int)CeOp_COUNT, "gOpName incorrect siz
 
 //////////////////////////////////////////////////////////////////////////
 
-static int FloatToString(float d, char* outStr)
+static int ToString(float d, char* outStr, bool roundTrip)
 {
-	sprintf(outStr, "%1.9g", d);
+	if (!roundTrip)
+	{
+		int digits;
+		if (d > 100000)
+			digits = 1;
+		else if (d > 10000)
+			digits = 2;
+		else if (d > 1000)
+			digits = 3;
+		else if (d > 100)
+			digits = 4;
+		else if (d > 10)
+			digits = 5;
+		else
+			digits = 6;
+
+		sprintf(outStr, "%1.*f", digits, d);
+	}
+	else
+		sprintf(outStr, "%1.9g", d);
+
 	int len = (int)strlen(outStr);
 	for (int i = 0; outStr[i] != 0; i++)
 	{
@@ -266,6 +286,10 @@ static int FloatToString(float d, char* outStr)
 				{
 					return checkC;
 				}
+				else if (c == 'e')
+				{
+					return len;
+				}
 				else if (c != '0')
 				{
 					for (int j = i + 1; j <= checkC; j++)
@@ -277,12 +301,97 @@ static int FloatToString(float d, char* outStr)
 			}
 		}
 	}
+	if ((len == 3) && (outStr[0] == 'i'))
+	{
+		strcpy(outStr, "Infinity");
+		return 8;
+	}
+	if ((len == 4) && (outStr[0] == '-') && (outStr[1] == 'i'))
+	{
+		strcpy(outStr, "-Infinity");
+		return 9;
+	}
+	if ((len == 9) && (outStr[0] == '-') && (outStr[1] == 'n')) //-nan(xxx)
+	{
+		strcpy(outStr, "NaN");
+		return 3;
+	}
 	return len;
 }
 
-static int DoubleToString(double d, char* outStr)
+static int ToString(double d, char* outStr, bool roundTrip)
 {
-	sprintf(outStr, "%1.17g", d);
+	if (!roundTrip)
+	{
+		int digits;
+		if (d < 0)
+		{
+			if (d < -10000000000)
+			{
+				sprintf(outStr, "%g", d);
+			}
+			else
+			{
+				if (d < -1000000000)
+					digits = 1;
+				else if (d < -100000000)
+					digits = 2;
+				else if (d < -10000000)
+					digits = 3;
+				else if (d < -1000000)
+					digits = 4;
+				else if (d < -100000)
+					digits = 5;
+				else if (d < -10000)
+					digits = 6;
+				else if (d < -1000)
+					digits = 7;
+				else if (d < -100)
+					digits = 8;
+				else if (d < -10)
+					digits = 9;
+				else
+					digits = 10;
+
+				sprintf(outStr, "%1.*f", digits, d);
+			}
+		}
+		else
+		{
+			if (d > 10000000000)
+			{
+				sprintf(outStr, "%g", d);
+			}
+			else
+			{
+				if (d > 1000000000)
+					digits = 1;
+				else if (d > 100000000)
+					digits = 2;
+				else if (d > 10000000)
+					digits = 3;
+				else if (d > 1000000)
+					digits = 4;
+				else if (d > 100000)
+					digits = 5;
+				else if (d > 10000)
+					digits = 6;
+				else if (d > 1000)
+					digits = 7;
+				else if (d > 100)
+					digits = 8;
+				else if (d > 10)
+					digits = 9;
+				else
+					digits = 10;
+
+				sprintf(outStr, "%1.*f", digits, d);
+			}
+		}
+	}
+	else
+		sprintf(outStr, "%1.17g", d);
+
 	int len = (int)strlen(outStr);
 	for (int i = 0; outStr[i] != 0; i++)
 	{
@@ -311,9 +420,34 @@ static int DoubleToString(double d, char* outStr)
 			}
 		}
 	}
+	if ((len == 3) && (outStr[0] == 'i'))
+	{
+		strcpy(outStr, "Infinity");
+		return 8;
+	}
+	if ((len == 4) && (outStr[0] == '-') && (outStr[1] == 'i'))
+	{
+		strcpy(outStr, "-Infinity");
+		return 9;
+	}
+	if ((len == 9) && (outStr[0] == '-') && (outStr[1] == 'n')) //-nan(xxx)
+	{
+		strcpy(outStr, "NaN");
+		return 3;
+	}
 	return len;
 }
 
+static int FloatToString(float d, char* outStr)
+{
+	return ::ToString(d, outStr, false);
+}
+
+static int DoubleToString(double d, char* outStr)
+{
+	return ::ToString(d, outStr, false);
+}
+
 //////////////////////////////////////////////////////////////////////////
 
 String CeDbgMethodRef::ToString()
@@ -871,6 +1005,261 @@ void CeBuilder::EmitBinaryOp(CeOp iOp, CeOp fOp, const CeOperand& lhs, const CeO
 	EmitFrameOffset(rhs);
 }
 
+CeOperand CeBuilder::EmitNumericCast(const CeOperand& ceValue, BeType* toType, bool valSigned, bool toSigned)
+{
+	CeOperand result;
+	auto fromType = ceValue.mType;
+
+	if (fromType == toType)
+	{
+		// If it's just a sign change then leave it alone
+		result = ceValue;
+	}
+	else
+	{
+		if ((toType->IsIntable()) && (fromType->IsIntable()) && (toType->mSize <= fromType->mSize))
+		{
+			// For truncating values, no actual instructions are needed
+			// Note that a copy is not needed because of SSA rules
+			result = ceValue;
+			result.mType = toType;
+		}
+		else
+		{
+			result = FrameAlloc(toType);
+
+			CeOp op = CeOp_InvalidOp;
+
+			BeTypeCode fromTypeCode = fromType->mTypeCode;
+			BeTypeCode toTypeCode = toType->mTypeCode;
+
+			if ((valSigned) && (toSigned))
+			{
+				switch (fromTypeCode)
+				{
+				case BeTypeCode_Int8:
+					switch (toTypeCode)
+					{
+					case BeTypeCode_Int16:
+						op = CeOp_Conv_I8_I16;
+						break;
+					case BeTypeCode_Int32:
+						op = CeOp_Conv_I8_I32;
+						break;
+					case BeTypeCode_Int64:
+						op = CeOp_Conv_I8_I64;
+						break;
+					case BeTypeCode_Float:
+						op = CeOp_Conv_I8_F32;
+						break;
+					case BeTypeCode_Double:
+						op = CeOp_Conv_I8_F64;
+						break;
+					}
+					break;
+				case BeTypeCode_Int16:
+					switch (toTypeCode)
+					{
+					case BeTypeCode_Int32:
+						op = CeOp_Conv_I16_I32;
+						break;
+					case BeTypeCode_Int64:
+						op = CeOp_Conv_I16_I64;
+						break;
+					case BeTypeCode_Float:
+						op = CeOp_Conv_I16_F32;
+						break;
+					case BeTypeCode_Double:
+						op = CeOp_Conv_I16_F64;
+						break;
+					}
+					break;
+				case BeTypeCode_Int32:
+					switch (toTypeCode)
+					{
+					case BeTypeCode_Int64:
+						op = CeOp_Conv_I32_I64;
+						break;
+					case BeTypeCode_Float:
+						op = CeOp_Conv_I32_F32;
+						break;
+					case BeTypeCode_Double:
+						op = CeOp_Conv_I32_F64;
+						break;
+					}
+					break;
+				case BeTypeCode_Int64:
+					switch (toTypeCode)
+					{
+					case BeTypeCode_Float:
+						op = CeOp_Conv_I64_F32;
+						break;
+					case BeTypeCode_Double:
+						op = CeOp_Conv_I64_F64;
+						break;
+					}
+					break;
+				case BeTypeCode_Float:
+					switch (toTypeCode)
+					{
+					case BeTypeCode_Int8:
+						op = CeOp_Conv_F32_I8;
+						break;
+					case BeTypeCode_Int16:
+						op = CeOp_Conv_F32_I16;
+						break;
+					case BeTypeCode_Int32:
+						op = CeOp_Conv_F32_I32;
+						break;
+					case BeTypeCode_Int64:
+						op = CeOp_Conv_F32_I64;
+						break;
+					case BeTypeCode_Double:
+						op = CeOp_Conv_F32_F64;
+						break;
+					}
+					break;
+				case BeTypeCode_Double:
+					switch (toTypeCode)
+					{
+					case BeTypeCode_Int8:
+						op = CeOp_Conv_F64_I8;
+						break;
+					case BeTypeCode_Int16:
+						op = CeOp_Conv_F64_I16;
+						break;
+					case BeTypeCode_Int32:
+						op = CeOp_Conv_F64_I32;
+						break;
+					case BeTypeCode_Int64:
+						op = CeOp_Conv_F64_I64;
+						break;
+					case BeTypeCode_Float:
+						op = CeOp_Conv_F64_F32;
+						break;
+					}
+					break;
+				}
+			}
+			else
+			{
+				switch (fromTypeCode)
+				{
+				case BeTypeCode_Int8:
+					switch (toTypeCode)
+					{
+					case BeTypeCode_Int16:
+						op = CeOp_Conv_U8_U16;
+						break;
+					case BeTypeCode_Int32:
+						op = CeOp_Conv_U8_U32;
+						break;
+					case BeTypeCode_Int64:
+						op = CeOp_Conv_U8_U64;
+						break;
+					case BeTypeCode_Float:
+						op = CeOp_Conv_I8_F32;
+						break;
+					case BeTypeCode_Double:
+						op = CeOp_Conv_I8_F64;
+						break;
+					}
+					break;
+				case BeTypeCode_Int16:
+					switch (toTypeCode)
+					{
+					case BeTypeCode_Int32:
+						op = CeOp_Conv_U16_U32;
+						break;
+					case BeTypeCode_Int64:
+						op = CeOp_Conv_U16_U64;
+						break;
+					case BeTypeCode_Float:
+						op = CeOp_Conv_U16_F32;
+						break;
+					case BeTypeCode_Double:
+						op = CeOp_Conv_U16_F64;
+						break;
+					}
+					break;
+				case BeTypeCode_Int32:
+					switch (toTypeCode)
+					{
+					case BeTypeCode_Int64:
+						op = CeOp_Conv_U32_U64;
+						break;
+					case BeTypeCode_Float:
+						op = CeOp_Conv_U32_F32;
+						break;
+					case BeTypeCode_Double:
+						op = CeOp_Conv_U32_F64;
+						break;
+					}
+					break;
+				case BeTypeCode_Int64:
+					switch (toTypeCode)
+					{
+					case BeTypeCode_Float:
+						op = CeOp_Conv_I64_F32;
+						break;
+					case BeTypeCode_Double:
+						op = CeOp_Conv_I64_F64;
+						break;
+					}
+					break;
+				case BeTypeCode_Float:
+					switch (toTypeCode)
+					{
+					case BeTypeCode_Int8:
+						op = CeOp_Conv_F32_U8;
+						break;
+					case BeTypeCode_Int16:
+						op = CeOp_Conv_F32_U16;
+						break;
+					case BeTypeCode_Int32:
+						op = CeOp_Conv_F32_U32;
+						break;
+					case BeTypeCode_Int64:
+						op = CeOp_Conv_F32_U64;
+						break;
+					}
+					break;
+				case BeTypeCode_Double:
+					switch (toTypeCode)
+					{
+					case BeTypeCode_Int8:
+						op = CeOp_Conv_F64_U8;
+						break;
+					case BeTypeCode_Int16:
+						op = CeOp_Conv_F64_U16;
+						break;
+					case BeTypeCode_Int32:
+						op = CeOp_Conv_F64_U32;
+						break;
+					case BeTypeCode_Int64:
+						op = CeOp_Conv_F64_U64;
+						break;
+					}
+					break;
+				}
+			}
+
+			if (op == CeOp_InvalidOp)
+			{
+				Fail("Invalid conversion op");
+			}
+			else
+			{
+				Emit(op);
+				EmitFrameOffset(result);
+				EmitFrameOffset(ceValue);
+			}
+		}
+	}
+
+	return result;
+}
+
 void CeBuilder::EmitUnaryOp(CeOp iOp, CeOp fOp, const CeOperand& val, CeOperand& result)
 {
 	CeOp op = iOp;
@@ -2089,254 +2478,7 @@ void CeBuilder::Build()
 				{
 					auto castedInst = (BeNumericCastInst*)inst;
 					auto ceValue = GetOperand(castedInst->mValue);
-					auto fromType = ceValue.mType;
-					if (fromType == castedInst->mToType)
-					{
-						// If it's just a sign change then leave it alone
-						result = ceValue;
-					}
-					else
-					{
-						auto toType = castedInst->mToType;
-						if ((toType->IsIntable()) && (fromType->IsIntable()) && (toType->mSize <= fromType->mSize))
-						{
-							// For truncating values, no actual instructions are needed
-							// Note that a copy is not needed because of SSA rules
-							result = ceValue;
-							result.mType = toType;
-						}
-						else
-						{
-							result = FrameAlloc(toType);
-
-							CeOp op = CeOp_InvalidOp;
-
-							BeTypeCode fromTypeCode = fromType->mTypeCode;
-							BeTypeCode toTypeCode = toType->mTypeCode;
-
-							if ((castedInst->mValSigned) && (castedInst->mToSigned))
-							{
-								switch (fromTypeCode)
-								{
-								case BeTypeCode_Int8:
-									switch (toTypeCode)
-									{
-									case BeTypeCode_Int16:
-										op = CeOp_Conv_I8_I16;
-										break;
-									case BeTypeCode_Int32:
-										op = CeOp_Conv_I8_I32;
-										break;
-									case BeTypeCode_Int64:
-										op = CeOp_Conv_I8_I64;
-										break;
-									case BeTypeCode_Float:
-										op = CeOp_Conv_I8_F32;
-										break;
-									case BeTypeCode_Double:
-										op = CeOp_Conv_I8_F64;
-										break;
-									}
-									break;
-								case BeTypeCode_Int16:
-									switch (toTypeCode)
-									{
-									case BeTypeCode_Int32:
-										op = CeOp_Conv_I16_I32;
-										break;
-									case BeTypeCode_Int64:
-										op = CeOp_Conv_I16_I64;
-										break;
-									case BeTypeCode_Float:
-										op = CeOp_Conv_I16_F32;
-										break;
-									case BeTypeCode_Double:
-										op = CeOp_Conv_I16_F64;
-										break;
-									}
-									break;
-								case BeTypeCode_Int32:
-									switch (toTypeCode)
-									{
-									case BeTypeCode_Int64:
-										op = CeOp_Conv_I32_I64;
-										break;
-									case BeTypeCode_Float:
-										op = CeOp_Conv_I32_F32;
-										break;
-									case BeTypeCode_Double:
-										op = CeOp_Conv_I32_F64;
-										break;
-									}
-									break;
-								case BeTypeCode_Int64:
-									switch (toTypeCode)
-									{
-									case BeTypeCode_Float:
-										op = CeOp_Conv_I64_F32;
-										break;
-									case BeTypeCode_Double:
-										op = CeOp_Conv_I64_F64;
-										break;
-									}
-									break;
-								case BeTypeCode_Float:
-									switch (toTypeCode)
-									{
-									case BeTypeCode_Int8:
-										op = CeOp_Conv_F32_I8;
-										break;
-									case BeTypeCode_Int16:
-										op = CeOp_Conv_F32_I16;
-										break;
-									case BeTypeCode_Int32:
-										op = CeOp_Conv_F32_I32;
-										break;
-									case BeTypeCode_Int64:
-										op = CeOp_Conv_F32_I64;
-										break;
-									case BeTypeCode_Double:
-										op = CeOp_Conv_F32_F64;
-										break;
-									}
-									break;
-								case BeTypeCode_Double:
-									switch (toTypeCode)
-									{
-									case BeTypeCode_Int8:
-										op = CeOp_Conv_F64_I8;
-										break;
-									case BeTypeCode_Int16:
-										op = CeOp_Conv_F64_I16;
-										break;
-									case BeTypeCode_Int32:
-										op = CeOp_Conv_F64_I32;
-										break;
-									case BeTypeCode_Int64:
-										op = CeOp_Conv_F64_I64;
-										break;
-									case BeTypeCode_Float:
-										op = CeOp_Conv_F64_F32;
-										break;
-									}
-									break;
-								}
-							}
-							else
-							{
-								switch (fromTypeCode)
-								{
-								case BeTypeCode_Int8:
-									switch (toTypeCode)
-									{
-									case BeTypeCode_Int16:
-										op = CeOp_Conv_U8_U16;
-										break;
-									case BeTypeCode_Int32:
-										op = CeOp_Conv_U8_U32;
-										break;
-									case BeTypeCode_Int64:
-										op = CeOp_Conv_U8_U64;
-										break;
-									case BeTypeCode_Float:
-										op = CeOp_Conv_I8_F32;
-										break;
-									case BeTypeCode_Double:
-										op = CeOp_Conv_I8_F64;
-										break;
-									}
-									break;
-								case BeTypeCode_Int16:
-									switch (toTypeCode)
-									{
-									case BeTypeCode_Int32:
-										op = CeOp_Conv_U16_U32;
-										break;
-									case BeTypeCode_Int64:
-										op = CeOp_Conv_U16_U64;
-										break;
-									case BeTypeCode_Float:
-										op = CeOp_Conv_U16_F32;
-										break;
-									case BeTypeCode_Double:
-										op = CeOp_Conv_U16_F64;
-										break;
-									}
-									break;
-								case BeTypeCode_Int32:
-									switch (toTypeCode)
-									{
-									case BeTypeCode_Int64:
-										op = CeOp_Conv_U32_U64;
-										break;
-									case BeTypeCode_Float:
-										op = CeOp_Conv_U32_F32;
-										break;
-									case BeTypeCode_Double:
-										op = CeOp_Conv_U32_F64;
-										break;
-									}
-									break;
-								case BeTypeCode_Int64:
-									switch (toTypeCode)
-									{
-									case BeTypeCode_Float:
-										op = CeOp_Conv_I64_F32;
-										break;
-									case BeTypeCode_Double:
-										op = CeOp_Conv_I64_F64;
-										break;
-									}
-									break;
-								case BeTypeCode_Float:
-									switch (toTypeCode)
-									{
-									case BeTypeCode_Int8:
-										op = CeOp_Conv_F32_U8;
-										break;
-									case BeTypeCode_Int16:
-										op = CeOp_Conv_F32_U16;
-										break;
-									case BeTypeCode_Int32:
-										op = CeOp_Conv_F32_U32;
-										break;
-									case BeTypeCode_Int64:
-										op = CeOp_Conv_F32_U64;
-										break;
-									}
-									break;
-								case BeTypeCode_Double:
-									switch (toTypeCode)
-									{
-									case BeTypeCode_Int8:
-										op = CeOp_Conv_F64_U8;
-										break;
-									case BeTypeCode_Int16:
-										op = CeOp_Conv_F64_U16;
-										break;
-									case BeTypeCode_Int32:
-										op = CeOp_Conv_F64_U32;
-										break;
-									case BeTypeCode_Int64:
-										op = CeOp_Conv_F64_U64;
-										break;
-									}
-									break;
-								}
-							}
-
-							if (op == CeOp_InvalidOp)
-							{
-								Fail("Invalid conversion op");
-							}
-							else
-							{
-								Emit(op);
-								EmitFrameOffset(result);
-								EmitFrameOffset(ceValue);
-							}
-						}
-					}
+					result = EmitNumericCast(ceValue, castedInst->mToType, castedInst->mValSigned, castedInst->mToSigned);
 				}
 				break;
 			case BeStoreInst::TypeId:
@@ -2463,6 +2605,9 @@ void CeBuilder::Build()
 					auto ceVal = GetOperand(castedInst->mPtr);
 					auto ceIdx0 = GetOperand(castedInst->mIdx0, false, true);
 
+					if ((ceIdx0.mType != NULL) && (ceIdx0.mType->mSize < mPtrSize))
+						ceIdx0 = EmitNumericCast(ceIdx0, mIntPtrType, true, true);
+
 					BePointerType* ptrType = (BePointerType*)ceVal.mType;
 					BF_ASSERT(ptrType->mTypeCode == BeTypeCode_Pointer);
 
@@ -2473,6 +2618,10 @@ void CeBuilder::Build()
 						BF_ASSERT(castedInst->mIdx0);
 
 						auto ceIdx1 = GetOperand(castedInst->mIdx1, false, true);
+
+						if ((ceIdx1.mType != NULL) && (ceIdx1.mType->mSize < mPtrSize))
+							ceIdx1 = EmitNumericCast(ceIdx1, mIntPtrType, true, true);
+
 						if (!ceIdx1.IsImmediate())
 						{
 							// This path is used when we have a const array that gets indexed by a non-const index value

+ 1 - 0
IDEHelper/Compiler/CeMachine.h

@@ -883,6 +883,7 @@ public:
 	void EmitZeroes(int size);
 	void EmitJump(CeOp op, const CeOperand& block);
 	void EmitBinarySwitchSection(BeSwitchInst* switchInst, int startIdx, int endIdx);
+	CeOperand EmitNumericCast(const CeOperand& ceValue, BeType* toType, bool valSigned, bool toSigned);
 
 	void EmitFrameOffset(const CeOperand& val);
 	void FlushPhi(CeBlock* ceBlock, int targetBlockIdx);