瀏覽代碼

Use StackHelper for very long if/else chains

Brian Fiete 1 年之前
父節點
當前提交
084566cdc6

+ 22 - 2
IDEHelper/Backend/BeModule.cpp

@@ -2,6 +2,7 @@
 #include "../Beef/BfCommon.h"
 #include "../Compiler/BfUtil.h"
 #include "BeefySysLib/util/BeefPerf.h"
+#include "BeefySysLib/util/StackHelper.h"
 #include "../Compiler/BfIRCodeGen.h"
 
 #include "BeefySysLib/util/AllocDebug.h"
@@ -1031,8 +1032,27 @@ void BeDbgEnumType::SetMembers(SizedArrayImpl<BeMDNode*>& members)
 
 //////////////////////////////////////////////////////////////////////////
 
-void BeDumpContext::ToString(StringImpl& str, BeValue* value, bool showType, bool mdDrillDown)
+void BeDumpContext::ToString(StringImpl& str, BeValue* value, bool showType, bool mdDrillDown, bool checkStack)
 {
+	if (checkStack)
+	{
+		BP_ZONE("CreateValueFromExpression:CheckStack");
+
+		StackHelper stackHelper;
+		if (!stackHelper.CanStackExpand(64 * 1024))
+		{
+			if (!stackHelper.Execute([&]()
+				{
+					ToString(str, value, showType, mdDrillDown, false);
+				}))
+			{
+				//Fail("Expression too complex to compile", expr);
+				str += "!!!FAILED!!!";
+			}
+			return;
+		}
+	}
+
 	if (value == NULL)
 	{
 		str += "<null>";
@@ -1105,7 +1125,7 @@ void BeDumpContext::ToString(StringImpl& str, BeValue* value, bool showType, boo
 			str += StrFormat("%d@", lexBlock->mId);
 			ToString(str, lexBlock->mFile);
 			str += ":";
-			ToString(str, lexBlock->mScope);
+			ToString(str, lexBlock->mScope, true, false, true);
 			return;
 		}
 

+ 1 - 1
IDEHelper/Backend/BeModule.h

@@ -1554,7 +1554,7 @@ public:
 	Dictionary<BeValue*, String> mValueNameMap;
 	Dictionary<String, int> mSeenNames;
 
-	void ToString(StringImpl& str, BeValue* value, bool showType = true, bool mdDrillDown = false);
+	void ToString(StringImpl& str, BeValue* value, bool showType = true, bool mdDrillDown = false, bool checkStack = false);
 	void ToString(StringImpl& str, BeType* type);
 	void ToString(StringImpl& str, BeDbgFunction* dbgFunction, bool showScope);
 	static void ToString(StringImpl& str, int val);

+ 1 - 1
IDEHelper/Compiler/BfModule.cpp

@@ -9043,7 +9043,7 @@ BfTypedValue BfModule::CreateValueFromExpression(BfExprEvaluator& exprEvaluator,
 		BP_ZONE("CreateValueFromExpression:CheckStack");
 
 		StackHelper stackHelper;
-		if (!stackHelper.CanStackExpand(64 * 1024))
+		if (!stackHelper.CanStackExpand(128 * 1024))
 		{
 			BfTypedValue result;
 			if (!stackHelper.Execute([&]()

+ 2 - 1
IDEHelper/Compiler/BfModule.h

@@ -148,7 +148,8 @@ enum BfEmbeddedStatementFlags : int8
 	BfEmbeddedStatementFlags_None = 0,
 	BfEmbeddedStatementFlags_IsConditional = 1,
 	BfEmbeddedStatementFlags_IsDeferredBlock = 2,
-	BfEmbeddedStatementFlags_Unscoped = 4
+	BfEmbeddedStatementFlags_Unscoped = 4,
+	BfEmbeddedStatementFlags_CheckStack = 8
 };
 
 enum BfLocalVarAssignKind : int8

+ 20 - 1
IDEHelper/Compiler/BfReducer.cpp

@@ -3989,7 +3989,7 @@ BfAstNode* BfReducer::DoCreateStatement(BfAstNode* node, CreateStmtFlags createS
 			{
 				MEMBER_SET(ifStmt, mElseToken, tokenNode);
 				mVisitorPos.MoveNext();
-				auto falseStmt = CreateStatementAfter(ifStmt, subCreateStmtFlags);
+				auto falseStmt = CreateStatementAfter(ifStmt, (CreateStmtFlags)(subCreateStmtFlags | CreateStmtFlags_CheckStack));
 				MEMBER_SET_CHECKED(ifStmt, mFalseStatement, falseStmt);
 			}
 
@@ -4656,6 +4656,25 @@ BfAstNode* BfReducer::CreateStatement(BfAstNode* node, CreateStmtFlags createStm
 {
 	AssertCurrentNode(node);
 
+	if ((createStmtFlags & CreateStmtFlags_CheckStack) != 0)
+	{
+		BP_ZONE("CreateStatement.CheckStack");
+
+		StackHelper stackHelper;
+		if (!stackHelper.CanStackExpand(64 * 1024))
+		{
+			BfAstNode* result = NULL;
+			if (!stackHelper.Execute([&]()
+				{
+					result = CreateStatement(node, createStmtFlags);
+				}))
+			{
+				Fail("Statement too complex to parse", node);
+			}
+				return result;
+		}
+	}
+
 	if ((createStmtFlags & CreateStmtFlags_AllowUnterminatedExpression) != 0)
 	{
 		if (IsTerminatingExpression(node))

+ 1 - 0
IDEHelper/Compiler/BfReducer.h

@@ -39,6 +39,7 @@ public:
 		CreateStmtFlags_AllowUnterminatedExpression = 4,
 		CreateStmtFlags_AllowLocalFunction = 8,
 		CreateStmtFlags_ForceVariableDecl = 0x10,
+		CreateStmtFlags_CheckStack = 0x20,
 
 		CreateStmtFlags_To_CreateExprFlags_Mask = 1
 	};

+ 21 - 1
IDEHelper/Compiler/BfStmtEvaluator.cpp

@@ -8,6 +8,7 @@
 #include "BfMangler.h"
 #include "BeefySysLib/util/PerfTimer.h"
 #include "BeefySysLib/util/BeefPerf.h"
+#include "BeefySysLib/util/StackHelper.h"
 #include "BfSourceClassifier.h"
 #include "BfAutoComplete.h"
 #include "BfDemangler.h"
@@ -3285,6 +3286,25 @@ void BfModule::AddBasicBlock(BfIRBlock bb, bool activate)
 
 void BfModule::VisitEmbeddedStatement(BfAstNode* stmt, BfExprEvaluator* exprEvaluator, BfEmbeddedStatementFlags flags)
 {
+	if ((flags & BfEmbeddedStatementFlags_CheckStack) != 0)
+	{
+		BP_ZONE("BfModule.VisitEmbeddedStatement");
+
+		StackHelper stackHelper;
+		if (!stackHelper.CanStackExpand(64 * 1024))
+		{
+
+			if (!stackHelper.Execute([&]()
+				{
+					VisitEmbeddedStatement(stmt, exprEvaluator, flags);
+				}))
+			{
+				Fail("Statement too complex to parse", stmt);
+			}
+			return;
+		}
+	}
+
 	auto block = BfNodeDynCast<BfBlock>(stmt);
 	BfLabelNode* labelNode = NULL;
 	if (block == NULL)
@@ -3948,7 +3968,7 @@ void BfModule::DoIfStatement(BfIfStatement* ifStmt, bool includeTrueStmt, bool i
 			falseDeferredLocalAssignData.ExtendFrom(mCurMethodState->mDeferredLocalAssignData);
 			SetAndRestoreValue<BfDeferredLocalAssignData*> prevDLA(mCurMethodState->mDeferredLocalAssignData, &falseDeferredLocalAssignData);
 			if (includeFalseStmt)
-				VisitEmbeddedStatement(ifStmt->mFalseStatement, NULL, BfEmbeddedStatementFlags_IsConditional);
+				VisitEmbeddedStatement(ifStmt->mFalseStatement, NULL, (BfEmbeddedStatementFlags)(BfEmbeddedStatementFlags_IsConditional | BfEmbeddedStatementFlags_CheckStack));
 		}
 		if ((!mCurMethodState->mLeftBlockUncond) && (!ignoredLastBlock))
 		{