/// <summary> /// Get the first expression to be excecuted if the instruction pointer is at the end of the given node /// </summary> ILNode Exit(ILNode node, HashSet <ILNode> visitedNodes) { if (node == null) { throw new ArgumentNullException(); } ILNode nodeParent = parent[node]; if (nodeParent == null) { return(null); // Exited main body } if (nodeParent is ILBlock) { ILNode nextNode = nextSibling[node]; if (nextNode != null) { return(Enter(nextNode, visitedNodes)); } else { return(Exit(nodeParent, visitedNodes)); } } if (nodeParent is ILCondition) { return(Exit(nodeParent, visitedNodes)); } if (nodeParent is ILSwitch) { return(null); // Implicit exit from switch is not allowed } if (nodeParent is ILWhileLoop) { return(Enter(nodeParent, visitedNodes)); } throw new NotSupportedException(nodeParent.GetType().ToString()); }
/// <summary> /// Get the first expression to be excecuted if the instruction pointer is at the start of the given node. /// Try blocks may not be entered in any way. If possible, the try block is returned as the node to be executed. /// </summary> ILNode Enter(ILNode node, HashSet<ILNode> visitedNodes) { if (node == null) throw new ArgumentNullException(); if (!visitedNodes.Add(node)) return null; // Infinite loop ILLabel label = node as ILLabel; if (label != null) { return Exit(label, visitedNodes); } ILExpression expr = node as ILExpression; if (expr != null) { if (expr.Code == ILCode.Br || expr.Code == ILCode.Leave) { ILLabel target = (ILLabel)expr.Operand; // Early exit - same try-block if (GetParents(expr).OfType<ILTryCatchBlock>().FirstOrDefault() == GetParents(target).OfType<ILTryCatchBlock>().FirstOrDefault()) return Enter(target, visitedNodes); // Make sure we are not entering any try-block var srcTryBlocks = GetParents(expr).OfType<ILTryCatchBlock>().Reverse().ToList(); var dstTryBlocks = GetParents(target).OfType<ILTryCatchBlock>().Reverse().ToList(); // Skip blocks that we are already in int i = 0; while(i < srcTryBlocks.Count && i < dstTryBlocks.Count && srcTryBlocks[i] == dstTryBlocks[i]) i++; if (i == dstTryBlocks.Count) { return Enter(target, visitedNodes); } else { ILTryCatchBlock dstTryBlock = dstTryBlocks[i]; // Check that the goto points to the start ILTryCatchBlock current = dstTryBlock; while(current != null) { foreach(ILNode n in current.TryBlock.Body) { if (n is ILLabel) { if (n == target) return dstTryBlock; } else if (!n.Match(ILCode.Nop)) { current = n as ILTryCatchBlock; break; } } } return null; } } else if (expr.Code == ILCode.Nop) { return Exit(expr, visitedNodes); } else if (expr.Code == ILCode.LoopOrSwitchBreak) { ILNode breakBlock = GetParents(expr).First(n => n is ILWhileLoop || n is ILSwitch); return Exit(breakBlock, new HashSet<ILNode>() { expr }); } else if (expr.Code == ILCode.LoopContinue) { ILNode continueBlock = GetParents(expr).First(n => n is ILWhileLoop); return Enter(continueBlock, new HashSet<ILNode>() { expr }); } else { return expr; } } ILBlock block = node as ILBlock; if (block != null) { if (block.EntryGoto != null) { return Enter(block.EntryGoto, visitedNodes); } else if (block.Body.Count > 0) { return Enter(block.Body[0], visitedNodes); } else { return Exit(block, visitedNodes); } } ILCondition cond = node as ILCondition; if (cond != null) { return cond.Condition; } ILWhileLoop loop = node as ILWhileLoop; if (loop != null) { if (loop.Condition != null) { return loop.Condition; } else { return Enter(loop.BodyBlock, visitedNodes); } } ILTryCatchBlock tryCatch = node as ILTryCatchBlock; if (tryCatch != null) { return tryCatch; } ILSwitch ilSwitch = node as ILSwitch; if (ilSwitch != null) { return ilSwitch.Condition; } throw new NotSupportedException(node.GetType().ToString()); }
public JSNode TranslateNode(ILNode node) { Console.Error.WriteLine("Node NYI: {0}", node.GetType().Name); return new JSUntranslatableStatement(node.GetType().Name); }
/// <summary> /// Get the first expression to be excecuted if the instruction pointer is at the start of the given node. /// Try blocks may not be entered in any way. If possible, the try block is returned as the node to be executed. /// </summary> ILNode Enter(ILNode node, HashSet <ILNode> visitedNodes) { if (node == null) { throw new ArgumentNullException(); } if (!visitedNodes.Add(node)) { return(null); // Infinite loop } ILLabel label = node as ILLabel; if (label != null) { return(Exit(label, visitedNodes)); } ILExpression expr = node as ILExpression; if (expr != null) { if (expr.Code == GMCode.B) { ILLabel target = (ILLabel)expr.Operand; return(Enter(target, visitedNodes)); } else if (expr.Code == GMCode.BadOp || expr.Code == GMCode.Constant || expr.Code == GMCode.Var) { return(Exit(expr, visitedNodes)); } else if (expr.Code == GMCode.LoopOrSwitchBreak) { ILNode breakBlock = GetParents(expr).First(n => n is ILWhileLoop || n is ILSwitch || n is ILWithStatement); return(Exit(breakBlock, new HashSet <ILNode>() { expr })); } else if (expr.Code == GMCode.LoopContinue) { ILNode continueBlock = GetParents(expr).First(n => n is ILWhileLoop || n is ILWithStatement); return(Enter(continueBlock, new HashSet <ILNode>() { expr })); } else { return(expr); } } ILBlock block = node as ILBlock; if (block != null) { if (block.EntryGoto != null) { return(Enter(block.EntryGoto, visitedNodes)); } else if (block.Body.Count > 0) { return(Enter(block.Body[0], visitedNodes)); } else { return(Exit(block, visitedNodes)); } } ILCondition cond = node as ILCondition; if (cond != null) { return(cond.Condition); } ILWhileLoop loop = node as ILWhileLoop; if (loop != null) { if (loop.Condition != null) { return(loop.Condition); } else { return(Enter(loop.Body, visitedNodes)); } } ILSwitch ilSwitch = node as ILSwitch; if (ilSwitch != null) { return(ilSwitch.Condition); } throw new NotSupportedException(node.GetType().ToString()); }
public JSNode TranslateNode(ILNode node) { Translator.WarningFormat("Node NYI: {0}", node.GetType().Name); return new JSUntranslatableStatement(node.GetType().Name); }
/// <summary> /// Get the first expression to be excecuted if the instruction pointer is at the start of the given node. /// Try blocks may not be entered in any way. If possible, the try block is returned as the node to be executed. /// </summary> ILNode Enter(ILNode node, HashSet<ILNode> visitedNodes) { if (node == null) throw new ArgumentNullException(); if (!visitedNodes.Add(node)) return null; // Infinite loop ILLabel label = node as ILLabel; if (label != null) { return Exit(label, visitedNodes); } ILExpression expr = node as ILExpression; if (expr != null) { if (expr.Code == GMCode.B) { ILLabel target = (ILLabel)expr.Operand; return Enter(target, visitedNodes); } else if (expr.Code == GMCode.BadOp || expr.Code == GMCode.Constant || expr.Code == GMCode.Var) { return Exit(expr, visitedNodes); } else if (expr.Code == GMCode.LoopOrSwitchBreak) { ILNode breakBlock = GetParents(expr).First(n => n is ILWhileLoop || n is ILSwitch || n is ILWithStatement); return Exit(breakBlock, new HashSet<ILNode>() { expr }); } else if (expr.Code == GMCode.LoopContinue) { ILNode continueBlock = GetParents(expr).First(n => n is ILWhileLoop || n is ILWithStatement); return Enter(continueBlock, new HashSet<ILNode>() { expr }); } else { return expr; } } ILBlock block = node as ILBlock; if (block != null) { if (block.EntryGoto != null) { return Enter(block.EntryGoto, visitedNodes); } else if (block.Body.Count > 0) { return Enter(block.Body[0], visitedNodes); } else { return Exit(block, visitedNodes); } } ILCondition cond = node as ILCondition; if (cond != null) { return cond.Condition; } ILWhileLoop loop = node as ILWhileLoop; if (loop != null) { if (loop.Condition != null) { return loop.Condition; } else { return Enter(loop.Body, visitedNodes); } } ILSwitch ilSwitch = node as ILSwitch; if (ilSwitch != null) { return ilSwitch.Condition; } throw new NotSupportedException(node.GetType().ToString()); }
/// <summary> /// Get the first expression to be excecuted if the instruction pointer is at the start of the given node /// </summary> ILExpression Enter(ILNode node, HashSet<ILNode> visitedNodes) { if (node == null) throw new ArgumentNullException(); if (!visitedNodes.Add(node)) return null; // Infinite loop ILLabel label = node as ILLabel; if (label != null) { return Exit(label, visitedNodes); } ILExpression expr = node as ILExpression; if (expr != null) { if (expr.Code == ILCode.Br || expr.Code == ILCode.Leave) { return Enter((ILLabel)expr.Operand, visitedNodes); } else if (expr.Code == ILCode.Nop) { return Exit(expr, visitedNodes); } else { return expr; } } ILBlock block = node as ILBlock; if (block != null) { if (block.EntryGoto != null) { return Enter(block.EntryGoto, visitedNodes); } else if (block.Body.Count > 0) { return Enter(block.Body[0], visitedNodes); } else { return Exit(block, visitedNodes); } } ILCondition cond = node as ILCondition; if (cond != null) { return cond.Condition; } ILWhileLoop loop = node as ILWhileLoop; if (loop != null) { if (loop.Condition != null) { return loop.Condition; } else { return Enter(loop.BodyBlock, visitedNodes); } } ILTryCatchBlock tryCatch = node as ILTryCatchBlock; if (tryCatch != null) { return Enter(tryCatch.TryBlock, visitedNodes); } ILSwitch ilSwitch = node as ILSwitch; if (ilSwitch != null) { return ilSwitch.Condition; } throw new NotSupportedException(node.GetType().ToString()); }