Skip to content

Commit

Permalink
github issue: The user can create infinite loops #6. Fix: add a maxim…
Browse files Browse the repository at this point in the history
…um loop limitation and report 'infinite loop'.
  • Loading branch information
maoling committed Mar 15, 2021
1 parent 525fec3 commit 5236963
Show file tree
Hide file tree
Showing 10 changed files with 109 additions and 1 deletion.
18 changes: 18 additions & 0 deletions Source/Script/CodeDB/CSharp/CSharpInterpreter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -83,12 +83,24 @@ public override void Stop()
}
}

public override void Error(string msg)
{
if (mRunningProcess != null)
{
mRunner.StopProcess(mRunningProcess);
mRunningProcess = null;
CSharp.Interpreter.FireUpdate(new InterpreterUpdateState(InterpreterUpdateState.Error, msg));
}
}

/// <summary>
/// coroutine run code for workspace
/// todo: execute topblocks in order or synchronously
/// </summary>
IEnumerator RunWorkspace(Workspace workspace)
{
yield return null;

//traverse all blocks in the workspace and run code for the blocks
List<Block> blocks = workspace.GetTopBlocks(true);
foreach (Block block in blocks)
Expand All @@ -109,6 +121,12 @@ IEnumerator RunWorkspace(Workspace workspace)
/// </summary>
IEnumerator RunBlock(Block block)
{
//check if stopped
if (mRunningProcess == null)
{
yield break;
}

//check flow
if (ControlCmdtor.SkipRunByControlFlow(block))
{
Expand Down
20 changes: 19 additions & 1 deletion Source/Script/CodeDB/CSharp/Interpreters/Loop_CSharp.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ namespace UBlockly
public abstract class ControlCmdtor : EnumeratorCmdtor
{
protected ControlFlowType mFlowState;

public bool NeedBreak
{
get { return mFlowState == ControlFlowType.Break; }
Expand All @@ -48,6 +48,19 @@ public void ResetFlowState()
mFlowState = ControlFlowType.None;
}

private int mLoopCount = 0;

protected bool CheckInfiniteLoop()
{
if (++mLoopCount == Int16.MaxValue)
{
CSharp.Interpreter.Error("Infinite loop!");
mLoopCount = 0;
return true;
}
return false;
}

/// <summary>
/// find the parent loop block of the flow block
/// </summary>
Expand Down Expand Up @@ -99,6 +112,7 @@ protected override IEnumerator Execute(Block block)
//reset flow control
if (NeedBreak) break;
if (NeedContinue) ResetFlowState();
if (CheckInfiniteLoop()) break;
}
}
}
Expand All @@ -124,6 +138,7 @@ protected override IEnumerator Execute(Block block)
//reset flow control
if (NeedBreak) break;
if (NeedContinue) ResetFlowState();
if (CheckInfiniteLoop()) break;
}
}
}
Expand Down Expand Up @@ -157,6 +172,7 @@ protected override IEnumerator Execute(Block block)
//reset flow control
if (NeedBreak) break;
if (NeedContinue) ResetFlowState();
if (CheckInfiniteLoop()) break;
}
}
}
Expand Down Expand Up @@ -190,6 +206,7 @@ protected override IEnumerator Execute(Block block)
//reset flow control
if (NeedBreak) break;
if (NeedContinue) ResetFlowState();
if (CheckInfiniteLoop()) break;
}
}
}
Expand Down Expand Up @@ -226,6 +243,7 @@ protected override IEnumerator Execute(Block block)
//reset flow control
if (NeedBreak) break;
if (NeedContinue) ResetFlowState();
if (CheckInfiniteLoop()) break;
}
}
}
Expand Down
4 changes: 4 additions & 0 deletions Source/Script/Core/Code/CoroutineRunner.cs
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ public bool StopProcess(IEnumerator itorFunc)
CoroutineStruct value;
if (mCoroutineDict.TryGetValue(itorFunc, out value))
{
value.paused = true;
StopCoroutine(value.coroutine);
mCoroutineDict.Remove(itorFunc);

Expand Down Expand Up @@ -144,6 +145,9 @@ public bool ResumeProcess(IEnumerator itorFunc)
/// <returns></returns>
IEnumerator SimulateCoroutine(IEnumerator itorFunc)
{
//wait for one frame to get the coroutine returned, for dictionary check.
yield return null;

Debug.LogFormat("<color=green>[CodeRunner]SimulateCoroutine: begin - time: {0}.</color>", Time.time);

Stack<IEnumerator> stack = new Stack<IEnumerator>();
Expand Down
12 changes: 12 additions & 0 deletions Source/Script/Core/Code/Interpreter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,11 @@ public virtual void Resume() {}
/// stop the current running interpreting process
/// </summary>
public virtual void Stop() {}

/// <summary>
/// process overflows
/// </summary>
public virtual void Error(string msg) {}
}

public class InterpreterUpdateState
Expand All @@ -86,9 +91,11 @@ public class InterpreterUpdateState
public const int Pause = 3;
public const int Resume = 4;
public const int Stop = 5;
public const int Error = 6;

public readonly int Type;
public readonly Block RunningBlock;
public readonly string Msg;

public InterpreterUpdateState(int type)
{
Expand All @@ -99,5 +106,10 @@ public InterpreterUpdateState(int type, Block runBlock) : this(type)
{
RunningBlock = runBlock;
}

public InterpreterUpdateState(int type, string msg) : this(type)
{
Msg = msg;
}
}
}
12 changes: 12 additions & 0 deletions Source/Script/UGUIView/BlockStatusView.cs
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,18 @@ public void UpdateStatus(InterpreterUpdateState args)
mRunBlockView = null;
break;
}
case InterpreterUpdateState.Error:
{
if (!string.IsNullOrEmpty(args.Msg))
{
MsgDialog dialog = DialogFactory.CreateDialog("message") as MsgDialog;
dialog.SetMsg(args.Msg);
}
enabled = false;
mRunningBlocks.Clear();
mRunBlockView = null;
break;
}
}
}

Expand Down
33 changes: 33 additions & 0 deletions Source/Script/UGUIView/Dialogs/MsgDialog.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/****************************************************************************
Copyright 2016 [email protected]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
****************************************************************************/

using UnityEngine;
using UnityEngine.UI;

namespace UBlockly.UGUI
{
public class MsgDialog : BaseDialog
{
[SerializeField] private Text m_MsgText;

public void SetMsg(string msg)
{
m_MsgText.text = msg;
}
}
}
3 changes: 3 additions & 0 deletions Source/Script/UGUIView/Dialogs/MsgDialog.cs.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Binary file added Source/UGUI/Prefabs/Dialogs/Dialog_message.prefab
Binary file not shown.
8 changes: 8 additions & 0 deletions Source/UGUI/Prefabs/Dialogs/Dialog_message.prefab.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Binary file modified UserData/Resources/BlockResSettings.asset
Binary file not shown.

0 comments on commit 5236963

Please sign in to comment.