Ejemplo n.º 1
0
        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);
        }
Ejemplo n.º 2
0
        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);
        }