private (CfgNode, CfgNode) CreateBranchConditionNodes(ProgramState state, Expression trueNodeCondition, Expression falseNodeCondition) { var truePruneNode = new PruneNode(state.CurrentLocation, true, PruneNode.PruneNodeKind.MethodBody, Prune.IfKind.Ik_if, state.ProcDesc); var falsePruneNode = new PruneNode(state.CurrentLocation, false, PruneNode.PruneNodeKind.MethodBody, Prune.IfKind.Ik_if, state.ProcDesc); truePruneNode.Instructions.Add(new Prune(trueNodeCondition, true, Prune.IfKind.Ik_if, state.CurrentLocation)); falsePruneNode.Instructions.Add(new Prune(falseNodeCondition, false, Prune.IfKind.Ik_if, state.CurrentLocation)); if (HasLoops(state.CurrentInstruction)) { var joinNode = new JoinNode(state.CurrentLocation, state.ProcDesc); RegisterNode(state, joinNode); state.PreviousNode = joinNode; } return(truePruneNode, falsePruneNode); }
protected static (CfgNode, CfgNode) CreateExceptionTypeCheckBranchNodes( ProgramState state, ExceptionHandler handler, Identifier exceptionIdentifier) { var handlerStartLocation = GetHandlerStartLocation(state, handler); var exceptionExpression = new VarExpression(exceptionIdentifier); var isInstIdentifier = state.GetIdentifier(Identifier.IdentKind.Normal); var isInstArgs = new List <Call.CallArg> { new Call.CallArg(exceptionExpression, Typ.FromTypeReference(handler.CatchType)), new Call.CallArg( new SizeofExpression( Typ.FromTypeReferenceNoPointer(handler.CatchType), SizeofExpression.SizeofExpressionKind.exact), new Tvoid()) }; // We don't mark the function output as an isinst output, as there is no load or store // of it. var isInstCall = new Call(isInstIdentifier, new Tint(Tint.IntKind.IBool), new ConstExpression(ProcedureName.BuiltIn__instanceof), isInstArgs, new Call.CallFlags(), handlerStartLocation); var isInstOutputExpression = new VarExpression(isInstIdentifier); var pruneTrueInstruction = new Prune(isInstOutputExpression, true, Prune.IfKind.Ik_switch, handlerStartLocation); var pruneFalseInstruction = new Prune(new UnopExpression(UnopExpression.UnopKind.LNot, isInstOutputExpression, null), false, Prune.IfKind.Ik_switch, handlerStartLocation); var setCatchVarInstruction = new Store(GetHandlerCatchVar(state, handler), exceptionExpression, Typ.FromTypeReference(state.Method.ReturnType), handlerStartLocation); var pruneTrueNode = new PruneNode(handlerStartLocation, true, PruneNode.PruneNodeKind.ExceptionHandler, Prune.IfKind.Ik_switch, state.ProcDesc); var pruneFalseNode = new PruneNode(handlerStartLocation, false, PruneNode.PruneNodeKind.ExceptionHandler, Prune.IfKind.Ik_switch, state.ProcDesc); pruneTrueNode.Instructions.AddRange(new List <SilInstruction> { isInstCall, pruneTrueInstruction, setCatchVarInstruction }); pruneFalseNode.Instructions.AddRange(new List <SilInstruction> { isInstCall, pruneFalseInstruction }); pruneTrueNode.BlockEndOffset = state.MethodExceptionHandlers .GetBlockEndOffsetFromOffset( state.CurrentInstruction.Offset); pruneFalseNode.BlockEndOffset = state.MethodExceptionHandlers .GetBlockEndOffsetFromOffset( state.CurrentInstruction.Offset); state.Cfg.RegisterNode(pruneTrueNode); state.Cfg.RegisterNode(pruneFalseNode); return(pruneTrueNode, pruneFalseNode); }