Exemplo n.º 1
0
        private static IMethodDefinition CreateStringArrayMarshallingEpilog(IMetadataHost host, ITypeDefinition typeDef, IFieldReference intPtrZero, IMethodReference intPtrOpInequality, IMethodReference freeHGlobal)
        {
            var intPtrArrayType = new VectorTypeReference {
                ElementType = host.PlatformType.SystemIntPtr, Rank = 1
            };

            MethodDefinition methodDefinition = new MethodDefinition
            {
                ContainingTypeDefinition = typeDef,
                IsStatic   = true,
                Visibility = TypeMemberVisibility.Assembly,
                Type       = host.PlatformType.SystemVoid,
                Parameters = new List <IParameterDefinition> {
                    new ParameterDefinition {
                        Index = 0, Type = intPtrArrayType
                    }
                },
                Name = host.NameTable.GetNameFor("StringArrayMarshallingEpilog")
            };

            var size = new LocalDefinition {
                Type = host.PlatformType.SystemInt32
            };
            var index = new LocalDefinition {
                Type = host.PlatformType.SystemInt32
            };

            var locals = new List <ILocalDefinition> {
                size, index
            };

            var ilGenerator  = new ILGenerator(host, methodDefinition);
            var loopStart    = new ILGeneratorLabel();
            var loopBackEdge = new ILGeneratorLabel();
            var exitLabel    = new ILGeneratorLabel();

            ilGenerator.Emit(OperationCode.Ldarg_0);
            ilGenerator.Emit(OperationCode.Ldlen);
            ilGenerator.Emit(OperationCode.Conv_I4);
            ilGenerator.Emit(OperationCode.Stloc_0);
            ilGenerator.Emit(OperationCode.Ldc_I4_0);
            ilGenerator.Emit(OperationCode.Stloc_1);
            ilGenerator.Emit(OperationCode.Br_S, loopBackEdge);
            ilGenerator.MarkLabel(loopStart);
            ilGenerator.Emit(OperationCode.Ldarg_0);
            ilGenerator.Emit(OperationCode.Ldloc_1);
            ilGenerator.Emit(OperationCode.Ldelem_I);
            ilGenerator.Emit(OperationCode.Ldsfld, intPtrZero);
            ilGenerator.Emit(OperationCode.Call, intPtrOpInequality);
            ilGenerator.Emit(OperationCode.Brfalse_S, exitLabel);
            ilGenerator.Emit(OperationCode.Ldarg_0);
            ilGenerator.Emit(OperationCode.Ldloc_1);
            ilGenerator.Emit(OperationCode.Ldelem_I);
            ilGenerator.Emit(OperationCode.Call, freeHGlobal);
            ilGenerator.MarkLabel(exitLabel);
            ilGenerator.Emit(OperationCode.Ldloc_1);
            ilGenerator.Emit(OperationCode.Ldc_I4_1);
            ilGenerator.Emit(OperationCode.Add);
            ilGenerator.Emit(OperationCode.Stloc_1);
            ilGenerator.MarkLabel(loopBackEdge);
            ilGenerator.Emit(OperationCode.Ldloc_1);
            ilGenerator.Emit(OperationCode.Ldloc_0);
            ilGenerator.Emit(OperationCode.Blt_S, loopStart);
            ilGenerator.Emit(OperationCode.Ret);

            methodDefinition.Body = new ILGeneratorMethodBody(ilGenerator, true, 2, methodDefinition, locals, new List <ITypeDefinition>());

            return(methodDefinition);
        }
Exemplo n.º 2
0
        private static IMethodDefinition CreateStringArrayMarshallingProlog(IMetadataHost host, ITypeDefinition typeDef, IMethodReference stringToHGlobal, string methodName)
        {
            var stringArrayType = new VectorTypeReference {
                ElementType = host.PlatformType.SystemString, Rank = 1
            };
            var intPtrArrayType = new VectorTypeReference {
                ElementType = host.PlatformType.SystemIntPtr, Rank = 1
            };

            MethodDefinition methodDefinition = new MethodDefinition
            {
                ContainingTypeDefinition = typeDef,
                IsStatic   = true,
                Visibility = TypeMemberVisibility.Assembly,
                Parameters = new List <IParameterDefinition> {
                    new ParameterDefinition {
                        Index = 0, Type = stringArrayType
                    }, new ParameterDefinition {
                        Index = 1, Type = intPtrArrayType
                    }
                },
                Type = host.PlatformType.SystemVoid,
                Name = host.NameTable.GetNameFor(methodName)
            };

            var size = new LocalDefinition {
                Type = host.PlatformType.SystemInt32
            };
            var index = new LocalDefinition {
                Type = host.PlatformType.SystemInt32
            };

            var locals = new List <ILocalDefinition> {
                size, index
            };

            var ilGenerator  = new ILGenerator(host, methodDefinition);
            var loopStart    = new ILGeneratorLabel();
            var loopBackEdge = new ILGeneratorLabel();

            ilGenerator.Emit(OperationCode.Ldarg_0);
            ilGenerator.Emit(OperationCode.Ldlen);
            ilGenerator.Emit(OperationCode.Conv_I4);
            ilGenerator.Emit(OperationCode.Stloc_0);
            ilGenerator.Emit(OperationCode.Ldc_I4_0);
            ilGenerator.Emit(OperationCode.Stloc_1);
            ilGenerator.Emit(OperationCode.Br_S, loopBackEdge);
            ilGenerator.MarkLabel(loopStart);
            ilGenerator.Emit(OperationCode.Ldarg_1);
            ilGenerator.Emit(OperationCode.Ldloc_1);
            ilGenerator.Emit(OperationCode.Ldarg_0);
            ilGenerator.Emit(OperationCode.Ldloc_1);
            ilGenerator.Emit(OperationCode.Ldelem_Ref);
            ilGenerator.Emit(OperationCode.Call, stringToHGlobal);
            ilGenerator.Emit(OperationCode.Stelem_I);
            ilGenerator.Emit(OperationCode.Ldloc_1);
            ilGenerator.Emit(OperationCode.Ldc_I4_1);
            ilGenerator.Emit(OperationCode.Add);
            ilGenerator.Emit(OperationCode.Stloc_1);
            ilGenerator.MarkLabel(loopBackEdge);
            ilGenerator.Emit(OperationCode.Ldloc_1);
            ilGenerator.Emit(OperationCode.Ldloc_0);
            ilGenerator.Emit(OperationCode.Blt_S, loopStart);
            ilGenerator.Emit(OperationCode.Ret);

            methodDefinition.Body = new ILGeneratorMethodBody(ilGenerator, true, 4, methodDefinition, locals, new List <ITypeDefinition>());

            return(methodDefinition);
        }
Exemplo n.º 3
0
        // this function creates all methods that are needed for the generated graph
        public void createGraphMethods() {

            this.logger.writeLine("Adding graph methods to \"" + this.targetClass.ToString() + "\"");

            // check if the graph is already initialized (needed to create the methods)
            if (this.graph == null) {
                throw new ArgumentException("Graph is not initialized.");
            }

            // if debugging is activated
            // => add field for the basic block trace file
            if (this.debugging
                || this.trace) {

                this.logger.writeLine("Debugging activated: Adding field for a basic block tracer file");

                // add trace writer field
                this.debuggingTraceWriter = new FieldDefinition();
                this.debuggingTraceWriter.IsCompileTimeConstant = false;
                this.debuggingTraceWriter.IsNotSerialized = false;
                this.debuggingTraceWriter.IsReadOnly = false;
                this.debuggingTraceWriter.IsRuntimeSpecial = false;
                this.debuggingTraceWriter.IsSpecialName = false;
                this.debuggingTraceWriter.Type = this.helperClass.systemIOStreamWriter;
                this.debuggingTraceWriter.IsStatic = false;
                this.debuggingTraceWriter.Name = host.NameTable.GetNameFor("DEBUG_traceWriter");
                this.debuggingTraceWriter.Visibility = TypeMemberVisibility.Public;
                this.debuggingTraceWriter.InternFactory = host.InternFactory;
                this.debuggingTraceWriter.ContainingTypeDefinition = this.targetClass;
                this.targetClass.Fields.Add(this.debuggingTraceWriter);

            }

            // create a method that can be called to generate the graph
            this.buildGraphMethod = this.helperClass.createNewMethod("buildGraph", this.targetClass, host.PlatformType.SystemVoid, TypeMemberVisibility.Public, null, CallingConvention.HasThis, false, false, true); // TODO RENAME

            ILGenerator ilGenerator = new ILGenerator(host, this.buildGraphMethod);

            // check if graph was already build
            // => if it was jump to exit
            ILGeneratorLabel buildGraphExitLabel = new ILGeneratorLabel();
            ilGenerator.Emit(OperationCode.Ldarg_0);
            ilGenerator.Emit(OperationCode.Callvirt, this.interfaceStartPointerGet);
            ilGenerator.Emit(OperationCode.Ldnull);
            ilGenerator.Emit(OperationCode.Ceq);
            ilGenerator.Emit(OperationCode.Brfalse, buildGraphExitLabel);
            
            // set initial node (root of the tree)
            ilGenerator.Emit(OperationCode.Ldarg_0);
            ilGenerator.Emit(OperationCode.Ldarg_0); // needed as argument for the constructor
            ilGenerator.Emit(OperationCode.Newobj, this.graph.startingNode.constructorToUse);
            ilGenerator.Emit(OperationCode.Callvirt, this.interfaceStartPointerSet);

            // build rest of graph in a "pseudo recursive" manner
            MethodDefinition newMethodToCall = this.addNodeRecursively(this.graph.startingNode, 1, "addNode_0"); // TODO: method name
            ilGenerator.Emit(OperationCode.Ldarg_0);
            ilGenerator.Emit(OperationCode.Ldarg_0);
            ilGenerator.Emit(OperationCode.Callvirt, this.interfaceStartPointerGet);
            ilGenerator.Emit(OperationCode.Ldc_I4_1);
            ilGenerator.Emit(OperationCode.Callvirt, newMethodToCall);

            // exit
            ilGenerator.MarkLabel(buildGraphExitLabel);
            ilGenerator.Emit(OperationCode.Ret);

            // create body
            IMethodBody body = new ILGeneratorMethodBody(ilGenerator, true, 8, this.buildGraphMethod, Enumerable<ILocalDefinition>.Empty, Enumerable<ITypeDefinition>.Empty);
            this.buildGraphMethod.Body = body;

            // create exchangeNodes method
            List<IParameterDefinition> parameters = new List<IParameterDefinition>();
            // node type parameter
            ParameterDefinition parameter = new ParameterDefinition();
            parameter.IsIn = false;
            parameter.IsOptional = false;
            parameter.IsOut = false;
            parameter.Type = this.nodeInterface;
            parameters.Add(parameter);
            // int array parameter for path to node one
            VectorTypeReference intArrayType = new VectorTypeReference();
            intArrayType.ElementType = this.host.PlatformType.SystemInt32;
            intArrayType.Rank = 1;
            intArrayType.IsFrozen = true;
            intArrayType.IsValueType = false;
            intArrayType.InternFactory = host.InternFactory;
            parameter = new ParameterDefinition();
            parameter.IsIn = false;
            parameter.IsOptional = false;
            parameter.IsOut = false;
            parameter.Type = intArrayType;
            parameters.Add(parameter);
            // int array parameter for path to node two
            parameter = new ParameterDefinition();
            parameter.IsIn = false;
            parameter.IsOptional = false;
            parameter.IsOut = false;
            parameter.Type = intArrayType;
            parameters.Add(parameter);

            this.exchangeNodesMethod = this.helperClass.createNewMethod("exchangeNodes", this.targetClass, host.PlatformType.SystemVoid, TypeMemberVisibility.Public, parameters, CallingConvention.HasThis, false, false, true); // TODO RENAME

            ilGenerator = new ILGenerator(host, this.exchangeNodesMethod);
            List<ILocalDefinition> localVariables = new List<ILocalDefinition>();

            // create local integer variable needed for the loops
            LocalDefinition loopIntLocal = new LocalDefinition();
            loopIntLocal.IsReference = false;
            loopIntLocal.IsPinned = false;
            loopIntLocal.IsModified = false;
            loopIntLocal.Type = this.host.PlatformType.SystemInt32;
            loopIntLocal.MethodDefinition = this.exchangeNodesMethod;
            localVariables.Add(loopIntLocal);

            // create local iNode variable needed for nodeOne
            LocalDefinition nodeOneLocal = new LocalDefinition();
            nodeOneLocal.IsReference = false;
            nodeOneLocal.IsPinned = false;
            nodeOneLocal.IsModified = false;
            nodeOneLocal.Type = this.nodeInterface;
            nodeOneLocal.MethodDefinition = this.exchangeNodesMethod;
            localVariables.Add(nodeOneLocal);

            // create local iNode variable needed for prevNodeOne
            LocalDefinition prevNodeOneLocal = new LocalDefinition();
            prevNodeOneLocal.IsReference = false;
            prevNodeOneLocal.IsPinned = false;
            prevNodeOneLocal.IsModified = false;
            prevNodeOneLocal.Type = this.nodeInterface;
            prevNodeOneLocal.MethodDefinition = this.exchangeNodesMethod;
            localVariables.Add(prevNodeOneLocal);

            // create local integer variable needed for prevNodeOneIdx
            LocalDefinition prevNodeOneIdxLocal = new LocalDefinition();
            prevNodeOneIdxLocal.IsReference = false;
            prevNodeOneIdxLocal.IsPinned = false;
            prevNodeOneIdxLocal.IsModified = false;
            prevNodeOneIdxLocal.Type = this.host.PlatformType.SystemInt32;
            prevNodeOneIdxLocal.MethodDefinition = this.exchangeNodesMethod;
            localVariables.Add(prevNodeOneIdxLocal);

            // create local iNode variable needed for nodeTwo
            LocalDefinition nodeTwoLocal = new LocalDefinition();
            nodeTwoLocal.IsReference = false;
            nodeTwoLocal.IsPinned = false;
            nodeTwoLocal.IsModified = false;
            nodeTwoLocal.Type = this.nodeInterface;
            nodeTwoLocal.MethodDefinition = this.exchangeNodesMethod;
            localVariables.Add(nodeTwoLocal);

            // create local iNode variable needed for prevNodeOne
            LocalDefinition prevNodeTwoLocal = new LocalDefinition();
            prevNodeTwoLocal.IsReference = false;
            prevNodeTwoLocal.IsPinned = false;
            prevNodeTwoLocal.IsModified = false;
            prevNodeTwoLocal.Type = this.nodeInterface;
            prevNodeTwoLocal.MethodDefinition = this.exchangeNodesMethod;
            localVariables.Add(prevNodeTwoLocal);

            // create local integer variable needed for prevNodeOneIdx
            LocalDefinition prevNodeTwoIdxLocal = new LocalDefinition();
            prevNodeTwoIdxLocal.IsReference = false;
            prevNodeTwoIdxLocal.IsPinned = false;
            prevNodeTwoIdxLocal.IsModified = false;
            prevNodeTwoIdxLocal.Type = this.host.PlatformType.SystemInt32;
            prevNodeTwoIdxLocal.MethodDefinition = this.exchangeNodesMethod;
            localVariables.Add(prevNodeTwoIdxLocal);

            // create local iNode variable needed for temp
            LocalDefinition tempNodeLocal = new LocalDefinition();
            tempNodeLocal.IsReference = false;
            tempNodeLocal.IsPinned = false;
            tempNodeLocal.IsModified = false;
            tempNodeLocal.Type = this.nodeInterface;
            tempNodeLocal.MethodDefinition = this.exchangeNodesMethod;
            localVariables.Add(tempNodeLocal);

            // initialize local variables
            /*
            iNode nodeOne = givenStartingNode;
            iNode prevNodeOne = null;
            int prevNodeOneIdx = 0;
            */
            ilGenerator.Emit(OperationCode.Ldarg_1);
            ilGenerator.Emit(OperationCode.Stloc, nodeOneLocal);
            ilGenerator.Emit(OperationCode.Ldnull);
            ilGenerator.Emit(OperationCode.Stloc, prevNodeOneLocal);
            ilGenerator.Emit(OperationCode.Ldc_I4_0);
            ilGenerator.Emit(OperationCode.Stloc, prevNodeOneIdxLocal);

            // initialize loop
            ilGenerator.Emit(OperationCode.Ldc_I4_0);
            ilGenerator.Emit(OperationCode.Stloc, loopIntLocal);
            ILGeneratorLabel loopConditionAndIncBranch = new ILGeneratorLabel();
            ILGeneratorLabel loopConditionBranch = new ILGeneratorLabel();
            ILGeneratorLabel loopStartBranch = new ILGeneratorLabel();
            ilGenerator.Emit(OperationCode.Br, loopConditionBranch);

            // start of the code in the loop
            /*
            if (nodeOne.getNode(pathToNodeOne[i]) != null) {
            */
            ilGenerator.MarkLabel(loopStartBranch);
            ilGenerator.Emit(OperationCode.Ldloc, nodeOneLocal);
            ilGenerator.Emit(OperationCode.Ldarg_2);
            ilGenerator.Emit(OperationCode.Ldloc, loopIntLocal);
            ilGenerator.Emit(OperationCode.Ldelem_I4);
            ilGenerator.Emit(OperationCode.Callvirt, this.interfaceChildNodesGet);
            ilGenerator.Emit(OperationCode.Ldnull);
            ilGenerator.Emit(OperationCode.Ceq);
            ilGenerator.Emit(OperationCode.Brtrue, loopConditionAndIncBranch);

            // get the node of the graph that should be exchanged (nodeOne)
            /*
            prevNodeOne = nodeOne;
            prevNodeOneIdx = pathToNodeOne[i];
            nodeOne = nodeOne.getNode(pathToNodeOne[i]);
            */
            ilGenerator.Emit(OperationCode.Ldloc, nodeOneLocal);
            ilGenerator.Emit(OperationCode.Stloc, prevNodeOneLocal);
            ilGenerator.Emit(OperationCode.Ldarg_2);
            ilGenerator.Emit(OperationCode.Ldloc, loopIntLocal);
            ilGenerator.Emit(OperationCode.Ldelem_I4);
            ilGenerator.Emit(OperationCode.Stloc, prevNodeOneIdxLocal);
            ilGenerator.Emit(OperationCode.Ldloc, nodeOneLocal);
            ilGenerator.Emit(OperationCode.Ldloc, prevNodeOneIdxLocal);
            ilGenerator.Emit(OperationCode.Callvirt, this.interfaceChildNodesGet);
            ilGenerator.Emit(OperationCode.Stloc, nodeOneLocal);

            // increment counter of loop
            ilGenerator.MarkLabel(loopConditionAndIncBranch);
            ilGenerator.Emit(OperationCode.Ldloc, loopIntLocal);
            ilGenerator.Emit(OperationCode.Ldc_I4_1);
            ilGenerator.Emit(OperationCode.Add);
            ilGenerator.Emit(OperationCode.Stloc, loopIntLocal);

            // loop condition
            /*
            for (int i = 0; i < pathToNodeOne.Length; i++) {
            */
            ilGenerator.MarkLabel(loopConditionBranch);
            ilGenerator.Emit(OperationCode.Ldloc, loopIntLocal);
            ilGenerator.Emit(OperationCode.Ldarg_2);
            ilGenerator.Emit(OperationCode.Ldlen);
            ilGenerator.Emit(OperationCode.Conv_I4);
            ilGenerator.Emit(OperationCode.Clt);
            ilGenerator.Emit(OperationCode.Brtrue, loopStartBranch);

            // initialize local variables
            /*
            iNode nodeTwo = givenStartingNode;
            iNode prevNodeTwo = null;
            int prevNodeTwoIdx = 0;
            */
            ilGenerator.Emit(OperationCode.Ldarg_1);
            ilGenerator.Emit(OperationCode.Stloc, nodeTwoLocal);
            ilGenerator.Emit(OperationCode.Ldnull);
            ilGenerator.Emit(OperationCode.Stloc, prevNodeTwoLocal);
            ilGenerator.Emit(OperationCode.Ldc_I4_0);
            ilGenerator.Emit(OperationCode.Stloc, prevNodeTwoIdxLocal);

            // initialize loop
            ilGenerator.Emit(OperationCode.Ldc_I4_0);
            ilGenerator.Emit(OperationCode.Stloc, loopIntLocal);
            loopConditionAndIncBranch = new ILGeneratorLabel();
            loopConditionBranch = new ILGeneratorLabel();
            loopStartBranch = new ILGeneratorLabel();
            ilGenerator.Emit(OperationCode.Br, loopConditionBranch);

            // start of the code in the loop
            /*
            if (nodeTwo.getNode(pathToNodeTwo[i]) != null) {
            */
            ilGenerator.MarkLabel(loopStartBranch);
            ilGenerator.Emit(OperationCode.Ldloc, nodeTwoLocal);
            ilGenerator.Emit(OperationCode.Ldarg_3);
            ilGenerator.Emit(OperationCode.Ldloc, loopIntLocal);
            ilGenerator.Emit(OperationCode.Ldelem_I4);
            ilGenerator.Emit(OperationCode.Callvirt, this.interfaceChildNodesGet);
            ilGenerator.Emit(OperationCode.Ldnull);
            ilGenerator.Emit(OperationCode.Ceq);
            ilGenerator.Emit(OperationCode.Brtrue, loopConditionAndIncBranch);

            // get the node of the graph that should be exchanged (nodeTwo)
            /*
            prevNodeTwo = nodeTwo;
            prevNodeTwoIdx = pathToNodeTwo[i];
            nodeTwo = nodeTwo.getNode(pathToNodeTwo[i]);
            */
            ilGenerator.Emit(OperationCode.Ldloc, nodeTwoLocal);
            ilGenerator.Emit(OperationCode.Stloc, prevNodeTwoLocal);
            ilGenerator.Emit(OperationCode.Ldarg_2);
            ilGenerator.Emit(OperationCode.Ldloc, loopIntLocal);
            ilGenerator.Emit(OperationCode.Ldelem_I4);
            ilGenerator.Emit(OperationCode.Stloc, prevNodeTwoIdxLocal);
            ilGenerator.Emit(OperationCode.Ldloc, nodeTwoLocal);
            ilGenerator.Emit(OperationCode.Ldloc, prevNodeTwoIdxLocal);
            ilGenerator.Emit(OperationCode.Callvirt, this.interfaceChildNodesGet);
            ilGenerator.Emit(OperationCode.Stloc, nodeTwoLocal);

            // increment counter of loop
            ilGenerator.MarkLabel(loopConditionAndIncBranch);
            ilGenerator.Emit(OperationCode.Ldloc, loopIntLocal);
            ilGenerator.Emit(OperationCode.Ldc_I4_1);
            ilGenerator.Emit(OperationCode.Add);
            ilGenerator.Emit(OperationCode.Stloc, loopIntLocal);

            // loop condition
            /*
            for (int i = 0; i < pathToNodeTwo.Length; i++) {
            */
            ilGenerator.MarkLabel(loopConditionBranch);
            ilGenerator.Emit(OperationCode.Ldloc, loopIntLocal);
            ilGenerator.Emit(OperationCode.Ldarg_3);
            ilGenerator.Emit(OperationCode.Ldlen);
            ilGenerator.Emit(OperationCode.Conv_I4);
            ilGenerator.Emit(OperationCode.Clt);
            ilGenerator.Emit(OperationCode.Brtrue, loopStartBranch);

            // initialize loop
            ilGenerator.Emit(OperationCode.Ldc_I4_0);
            ilGenerator.Emit(OperationCode.Stloc, loopIntLocal);
            loopConditionAndIncBranch = new ILGeneratorLabel();
            loopConditionBranch = new ILGeneratorLabel();
            loopStartBranch = new ILGeneratorLabel();
            ilGenerator.Emit(OperationCode.Br, loopConditionBranch);

            // start of the code in the loop
            ilGenerator.MarkLabel(loopStartBranch);

            /*
            if (nodeOne.getNode(i) == nodeTwo) {
            */
            ILGeneratorLabel conditionBranch = new ILGeneratorLabel();
            ilGenerator.Emit(OperationCode.Ldloc, nodeOneLocal);
            ilGenerator.Emit(OperationCode.Ldloc, loopIntLocal);
            ilGenerator.Emit(OperationCode.Callvirt, this.interfaceChildNodesGet);
            ilGenerator.Emit(OperationCode.Ldloc, nodeTwoLocal);
            ilGenerator.Emit(OperationCode.Ceq);
            ilGenerator.Emit(OperationCode.Brfalse, conditionBranch);

            /*
            nodeOne.setNode(nodeTwo.getNode(i), i);
            */
            ilGenerator.Emit(OperationCode.Ldloc, nodeOneLocal);
            ilGenerator.Emit(OperationCode.Ldloc, nodeTwoLocal);
            ilGenerator.Emit(OperationCode.Ldloc, loopIntLocal);
            ilGenerator.Emit(OperationCode.Callvirt, this.interfaceChildNodesGet);
            ilGenerator.Emit(OperationCode.Ldloc, loopIntLocal);
            ilGenerator.Emit(OperationCode.Callvirt, this.interfaceChildNodesSet);

            /*
            nodeTwo.setNode(nodeOne, i);
            */
            ilGenerator.Emit(OperationCode.Ldloc, nodeTwoLocal);
            ilGenerator.Emit(OperationCode.Ldloc, nodeOneLocal);
            ilGenerator.Emit(OperationCode.Ldloc, loopIntLocal);
            ilGenerator.Emit(OperationCode.Callvirt, this.interfaceChildNodesSet);
            ilGenerator.Emit(OperationCode.Br, loopConditionAndIncBranch);

            /*
            else if (nodeTwo.getNode(i) == nodeOne) {
            */
            ilGenerator.MarkLabel(conditionBranch);
            ilGenerator.Emit(OperationCode.Ldloc, nodeTwoLocal);
            ilGenerator.Emit(OperationCode.Ldloc, loopIntLocal);
            ilGenerator.Emit(OperationCode.Callvirt, this.interfaceChildNodesGet);
            ilGenerator.Emit(OperationCode.Ldloc, nodeOneLocal);
            ilGenerator.Emit(OperationCode.Ceq);
            conditionBranch = new ILGeneratorLabel();
            ilGenerator.Emit(OperationCode.Brfalse, conditionBranch);

            /*
            nodeTwo.setNode(nodeOne.getNode(i), i);
            */
            ilGenerator.Emit(OperationCode.Ldloc, nodeTwoLocal);
            ilGenerator.Emit(OperationCode.Ldloc, nodeOneLocal);
            ilGenerator.Emit(OperationCode.Ldloc, loopIntLocal);
            ilGenerator.Emit(OperationCode.Callvirt, this.interfaceChildNodesGet);
            ilGenerator.Emit(OperationCode.Ldloc, loopIntLocal);
            ilGenerator.Emit(OperationCode.Callvirt, this.interfaceChildNodesSet);

            /*
            nodeOne.setNode(nodeTwo, i);
            */
            ilGenerator.Emit(OperationCode.Ldloc, nodeOneLocal);
            ilGenerator.Emit(OperationCode.Ldloc, nodeTwoLocal);
            ilGenerator.Emit(OperationCode.Ldloc, loopIntLocal);
            ilGenerator.Emit(OperationCode.Callvirt, this.interfaceChildNodesSet);
            ilGenerator.Emit(OperationCode.Br, loopConditionAndIncBranch);

            /*
            else {
            */
            ilGenerator.MarkLabel(conditionBranch);

            /*
            temp = nodeOne.getNode(i);
            */
            ilGenerator.Emit(OperationCode.Ldloc, nodeOneLocal);
            ilGenerator.Emit(OperationCode.Ldloc, loopIntLocal);
            ilGenerator.Emit(OperationCode.Callvirt, this.interfaceChildNodesGet);
            ilGenerator.Emit(OperationCode.Stloc, tempNodeLocal);

            /*
            nodeOne.setNode(nodeTwo.getNode(i), i);
            */
            ilGenerator.Emit(OperationCode.Ldloc, nodeOneLocal);
            ilGenerator.Emit(OperationCode.Ldloc, nodeTwoLocal);
            ilGenerator.Emit(OperationCode.Ldloc, loopIntLocal);
            ilGenerator.Emit(OperationCode.Callvirt, this.interfaceChildNodesGet);
            ilGenerator.Emit(OperationCode.Ldloc, loopIntLocal);
            ilGenerator.Emit(OperationCode.Callvirt, this.interfaceChildNodesSet);

            /*
            nodeTwo.setNode(temp, i);
            */
            ilGenerator.Emit(OperationCode.Ldloc, nodeTwoLocal);
            ilGenerator.Emit(OperationCode.Ldloc, tempNodeLocal);
            ilGenerator.Emit(OperationCode.Ldloc, loopIntLocal);
            ilGenerator.Emit(OperationCode.Callvirt, this.interfaceChildNodesSet);

            // increment counter of loop
            ilGenerator.MarkLabel(loopConditionAndIncBranch);
            ilGenerator.Emit(OperationCode.Ldloc, loopIntLocal);
            ilGenerator.Emit(OperationCode.Ldc_I4_1);
            ilGenerator.Emit(OperationCode.Add);
            ilGenerator.Emit(OperationCode.Stloc, loopIntLocal);

            // loop condition
            /*
            for (int i = 0; i < GRAPH_DIMENSION; i++) {
            */
            ilGenerator.MarkLabel(loopConditionBranch);
            ilGenerator.Emit(OperationCode.Ldloc, loopIntLocal);
            ilGenerator.Emit(OperationCode.Ldc_I4, this.graphDimension);
            ilGenerator.Emit(OperationCode.Clt);
            ilGenerator.Emit(OperationCode.Brtrue, loopStartBranch);

            /*
            if (prevNodeOne != null) {
            */
            conditionBranch = new ILGeneratorLabel();
            ilGenerator.Emit(OperationCode.Ldloc, prevNodeOneLocal);
            ilGenerator.Emit(OperationCode.Ldnull);
            ilGenerator.Emit(OperationCode.Ceq);
            ilGenerator.Emit(OperationCode.Brtrue, conditionBranch);

            /*
            if (prevNodeOne != nodeTwo) {
            */
            ILGeneratorLabel exitConditionBranch = new ILGeneratorLabel();
            ilGenerator.Emit(OperationCode.Ldloc, prevNodeOneLocal);
            ilGenerator.Emit(OperationCode.Ldloc, nodeTwoLocal);
            ilGenerator.Emit(OperationCode.Ceq);
            ilGenerator.Emit(OperationCode.Brtrue, exitConditionBranch);

            /*
            prevNodeOne.setNode(nodeTwo, prevNodeOneIdx);
            */
            ilGenerator.Emit(OperationCode.Ldloc, prevNodeOneLocal);
            ilGenerator.Emit(OperationCode.Ldloc, nodeTwoLocal);
            ilGenerator.Emit(OperationCode.Ldloc, prevNodeOneIdxLocal);
            ilGenerator.Emit(OperationCode.Callvirt, this.interfaceChildNodesSet);
            ilGenerator.Emit(OperationCode.Br, exitConditionBranch);

            /*
            else {
            */
            ilGenerator.MarkLabel(conditionBranch);

            /*
            this.graphStartNode = nodeTwo;
            */
            ilGenerator.Emit(OperationCode.Ldarg_0);
            ilGenerator.Emit(OperationCode.Ldloc, nodeTwoLocal);
            ilGenerator.Emit(OperationCode.Callvirt, this.interfaceStartPointerSet);

            ilGenerator.MarkLabel(exitConditionBranch);

            /*
            if (prevNodeTwo != null) {
            */
            conditionBranch = new ILGeneratorLabel();
            ilGenerator.Emit(OperationCode.Ldloc, prevNodeTwoLocal);
            ilGenerator.Emit(OperationCode.Ldnull);
            ilGenerator.Emit(OperationCode.Ceq);
            ilGenerator.Emit(OperationCode.Brtrue, conditionBranch);

            /*
            if (prevNodeTwo != nodeOne) {
            */
            exitConditionBranch = new ILGeneratorLabel();
            ilGenerator.Emit(OperationCode.Ldloc, prevNodeTwoLocal);
            ilGenerator.Emit(OperationCode.Ldloc, nodeOneLocal);
            ilGenerator.Emit(OperationCode.Ceq);
            ilGenerator.Emit(OperationCode.Brtrue, exitConditionBranch);

            /*
            prevNodeTwo.setNode(nodeOne, prevNodeTwoIdx);
            */
            ilGenerator.Emit(OperationCode.Ldloc, prevNodeTwoLocal);
            ilGenerator.Emit(OperationCode.Ldloc, nodeOneLocal);
            ilGenerator.Emit(OperationCode.Ldloc, prevNodeTwoIdxLocal);
            ilGenerator.Emit(OperationCode.Callvirt, this.interfaceChildNodesSet);
            ilGenerator.Emit(OperationCode.Br, exitConditionBranch);

            /*
            else {
            */
            ilGenerator.MarkLabel(conditionBranch);

            /*
            this.graphStartNode = nodeOne;
            */
            ilGenerator.Emit(OperationCode.Ldarg_0);
            ilGenerator.Emit(OperationCode.Ldloc, nodeOneLocal);
            ilGenerator.Emit(OperationCode.Callvirt, this.interfaceStartPointerSet);

            ilGenerator.MarkLabel(exitConditionBranch);
            ilGenerator.Emit(OperationCode.Ret);

            // create body
            body = new ILGeneratorMethodBody(ilGenerator, true, 8, this.exchangeNodesMethod, localVariables, Enumerable<ITypeDefinition>.Empty);
            this.exchangeNodesMethod.Body = body;

            // check if debugging is activated
            // => add function to dump graph as .dot file
            if (this.debugging) {

                this.logger.writeLine("Debugging activated: Adding code to dump graph as .dot file");

                // create dumpGraph method
                parameters = new List<IParameterDefinition>();
                // string parameter
                parameter = new ParameterDefinition();
                parameter.IsIn = false;
                parameter.IsOptional = false;
                parameter.IsOut = false;
                parameter.Type = this.host.PlatformType.SystemString;
                parameter.Index = 0;
                parameters.Add(parameter);
                // node type parameter (current pointer of debug method)
                parameter = new ParameterDefinition();
                parameter.IsIn = false;
                parameter.IsOptional = false;
                parameter.IsOut = false;
                parameter.Type = this.nodeInterface;
                parameter.Index = 1;
                parameters.Add(parameter);
                // node type parameter (current pointer of caller)
                parameter = new ParameterDefinition();
                parameter.IsIn = false;
                parameter.IsOptional = false;
                parameter.IsOut = false;
                parameter.Type = this.nodeInterface;
                parameter.Index = 2;
                parameters.Add(parameter);

                this.debuggingDumpGraphMethod = this.helperClass.createNewMethod("DEBUG_dumpGraph", this.targetClass, host.PlatformType.SystemVoid, TypeMemberVisibility.Public, parameters, CallingConvention.HasThis, false, false, true);

                // create dumpGraphRec method
                parameters = new List<IParameterDefinition>();
                // stream writer parameter
                parameter = new ParameterDefinition();
                parameter.IsIn = false;
                parameter.IsOptional = false;
                parameter.IsOut = false;
                parameter.Type = this.helperClass.systemIOStreamWriter;
                parameter.Index = 0;
                parameters.Add(parameter);
                // string parameter
                parameter = new ParameterDefinition();
                parameter.IsIn = false;
                parameter.IsOptional = false;
                parameter.IsOut = false;
                parameter.Type = this.host.PlatformType.SystemString;
                parameter.Index = 1;
                parameters.Add(parameter);
                // node type parameter (current pointer of debug method)
                parameter = new ParameterDefinition();
                parameter.IsIn = false;
                parameter.IsOptional = false;
                parameter.IsOut = false;
                parameter.Type = this.nodeInterface;
                parameter.Index = 2;
                parameters.Add(parameter);
                // node type parameter (current pointer of caller)
                ParameterDefinition currentNodeCallerParameter = new ParameterDefinition();
                currentNodeCallerParameter.IsIn = false;
                currentNodeCallerParameter.IsOptional = false;
                currentNodeCallerParameter.IsOut = false;
                currentNodeCallerParameter.Type = this.nodeInterface;
                currentNodeCallerParameter.Index = 3;
                parameters.Add(currentNodeCallerParameter);

                MethodDefinition dumpGraphRecMethod = this.helperClass.createNewMethod("DEBUG_dumpGraphRec", this.targetClass, host.PlatformType.SystemVoid, TypeMemberVisibility.Public, parameters, CallingConvention.HasThis, false, false, true);
                currentNodeCallerParameter.ContainingSignature = dumpGraphRecMethod; // is needed when parameter is accessed via Ldarg

                // create body for dumpGraph method
                ilGenerator = new ILGenerator(host, this.debuggingDumpGraphMethod);
                localVariables = new List<ILocalDefinition>();

                // create local string variable needed for debugging code
                LocalDefinition nodeNameLocal = new LocalDefinition();
                nodeNameLocal.IsReference = false;
                nodeNameLocal.IsPinned = false;
                nodeNameLocal.IsModified = false;
                nodeNameLocal.Type = this.host.PlatformType.SystemString;
                nodeNameLocal.MethodDefinition = this.debuggingDumpGraphMethod;
                localVariables.Add(nodeNameLocal);

                // create local stream writer variable needed for debugging code
                LocalDefinition streamWriterLocal = new LocalDefinition();
                streamWriterLocal.IsReference = false;
                streamWriterLocal.IsPinned = false;
                streamWriterLocal.IsModified = false;
                streamWriterLocal.Type = this.helperClass.systemIOStreamWriter;
                streamWriterLocal.MethodDefinition = this.debuggingDumpGraphMethod;
                localVariables.Add(streamWriterLocal);

                // create local integer variable for the for loop needed for debugging code
                LocalDefinition forIntegerLocal = new LocalDefinition();
                forIntegerLocal.IsReference = false;
                forIntegerLocal.IsPinned = false;
                forIntegerLocal.IsModified = false;
                forIntegerLocal.Type = this.host.PlatformType.SystemInt32;
                forIntegerLocal.MethodDefinition = this.debuggingDumpGraphMethod;
                localVariables.Add(forIntegerLocal);

                // generate dump file location string
                ilGenerator.Emit(OperationCode.Ldstr, this.debuggingDumpLocation + this.debuggingDumpFilePrefix);
                ilGenerator.Emit(OperationCode.Ldarg_1);
                ilGenerator.Emit(OperationCode.Ldstr, ".dot");
                ilGenerator.Emit(OperationCode.Call, this.helperClass.stringConcatThree);

                // initialize io stream writer
                ilGenerator.Emit(OperationCode.Newobj, this.helperClass.streamWriterCtor);
                ilGenerator.Emit(OperationCode.Stloc, streamWriterLocal);

                // initialize .dot file
                ilGenerator.Emit(OperationCode.Ldloc, streamWriterLocal);
                ilGenerator.Emit(OperationCode.Ldstr, "digraph G {");
                ilGenerator.Emit(OperationCode.Callvirt, this.helperClass.textWriterWriteLine);

                // check if the node to dump is the same as the current node of the class
                // if it is => color the current dumped node
                ilGenerator.Emit(OperationCode.Ldarg_3);
                ilGenerator.Emit(OperationCode.Ldarg_2);
                ilGenerator.Emit(OperationCode.Ceq);
                ILGeneratorLabel currentNodeEqualDumpedNodeBranch = new ILGeneratorLabel();
                ilGenerator.Emit(OperationCode.Brtrue, currentNodeEqualDumpedNodeBranch);

                // case: current dumped node is not the current node of the class
                // create name for the nodes
                ilGenerator.Emit(OperationCode.Ldstr, "node_0");
                ilGenerator.Emit(OperationCode.Stloc, nodeNameLocal);

                // write current node to .dot file
                ilGenerator.Emit(OperationCode.Ldloc, streamWriterLocal);
                ilGenerator.Emit(OperationCode.Ldloc, nodeNameLocal);
                ilGenerator.Emit(OperationCode.Ldstr, " [shape=record]");
                ilGenerator.Emit(OperationCode.Call, this.helperClass.stringConcatTwo);
                ilGenerator.Emit(OperationCode.Callvirt, this.helperClass.textWriterWriteLine);

                // jump to the end of this case
                ILGeneratorLabel currentNodeDumpedBranch = new ILGeneratorLabel();
                ilGenerator.Emit(OperationCode.Br, currentNodeDumpedBranch);

                // case: current dumped node is the current node of the class
                ilGenerator.MarkLabel(currentNodeEqualDumpedNodeBranch);

                // create name for the nodes
                ilGenerator.Emit(OperationCode.Ldstr, "node_0");
                ilGenerator.Emit(OperationCode.Stloc, nodeNameLocal);

                // write current node to .dot file
                ilGenerator.Emit(OperationCode.Ldloc, streamWriterLocal);
                ilGenerator.Emit(OperationCode.Ldloc, nodeNameLocal);
                ilGenerator.Emit(OperationCode.Ldstr, " [shape=record, color=blue]");
                ilGenerator.Emit(OperationCode.Call, this.helperClass.stringConcatTwo);
                ilGenerator.Emit(OperationCode.Callvirt, this.helperClass.textWriterWriteLine);

                // end of the case
                ilGenerator.MarkLabel(currentNodeDumpedBranch);

                // write start of label of the current node to .dot file
                ilGenerator.Emit(OperationCode.Ldloc, streamWriterLocal);
                ilGenerator.Emit(OperationCode.Ldloc, nodeNameLocal);
                ilGenerator.Emit(OperationCode.Ldstr, " [label=\"{");
                ilGenerator.Emit(OperationCode.Call, this.helperClass.stringConcatTwo);
                ilGenerator.Emit(OperationCode.Callvirt, this.helperClass.textWriterWrite);

                // write current node name to .dot file
                ilGenerator.Emit(OperationCode.Ldloc, streamWriterLocal);
                ilGenerator.Emit(OperationCode.Ldstr, "Node: ");
                ilGenerator.Emit(OperationCode.Ldloc, nodeNameLocal);
                ilGenerator.Emit(OperationCode.Ldstr, "|");
                ilGenerator.Emit(OperationCode.Call, this.helperClass.stringConcatThree);
                ilGenerator.Emit(OperationCode.Callvirt, this.helperClass.textWriterWrite);

                // write current node id to .dot file
                ilGenerator.Emit(OperationCode.Ldloc, streamWriterLocal);
                ilGenerator.Emit(OperationCode.Ldstr, "Id: ");
                ilGenerator.Emit(OperationCode.Ldarg_2);
                ilGenerator.Emit(OperationCode.Callvirt, this.debuggingInterfaceIdGet);
                ilGenerator.Emit(OperationCode.Call, this.helperClass.stringConcatTwo);
                ilGenerator.Emit(OperationCode.Callvirt, this.helperClass.textWriterWrite);

                // write end of label of the current node to .dot file
                ilGenerator.Emit(OperationCode.Ldloc, streamWriterLocal);
                ilGenerator.Emit(OperationCode.Ldstr, "}\"]");
                ilGenerator.Emit(OperationCode.Callvirt, this.helperClass.textWriterWriteLine);

                // initialize counter of for loop
                ilGenerator.Emit(OperationCode.Ldc_I4_0);
                ilGenerator.Emit(OperationCode.Stloc, forIntegerLocal);

                // jump to loop condition
                loopConditionBranch = new ILGeneratorLabel();
                loopStartBranch = new ILGeneratorLabel();
                ilGenerator.Emit(OperationCode.Br, loopConditionBranch);

                // start of loop
                ilGenerator.MarkLabel(loopStartBranch);

                // check if childNodes[i] == startNode
                ilGenerator.Emit(OperationCode.Ldarg_2);
                ilGenerator.Emit(OperationCode.Ldloc, forIntegerLocal);
                ilGenerator.Emit(OperationCode.Callvirt, this.interfaceChildNodesGet);
                ilGenerator.Emit(OperationCode.Ldarg_0);
                ilGenerator.Emit(OperationCode.Callvirt, this.interfaceStartPointerGet);
                ilGenerator.Emit(OperationCode.Ceq);
                loopConditionAndIncBranch = new ILGeneratorLabel();
                ilGenerator.Emit(OperationCode.Brtrue, loopConditionAndIncBranch);

                // write connection of current node to next node to .dot file
                ilGenerator.Emit(OperationCode.Ldloc, streamWriterLocal);

                // generate first part of the string
                ilGenerator.Emit(OperationCode.Ldloc, nodeNameLocal);
                ilGenerator.Emit(OperationCode.Ldstr, " -> ");
                ilGenerator.Emit(OperationCode.Ldloc, nodeNameLocal);
                ilGenerator.Emit(OperationCode.Call, this.helperClass.stringConcatThree);

                // generate second part of string and concat to first part
                ilGenerator.Emit(OperationCode.Ldstr, "_");
                ilGenerator.Emit(OperationCode.Ldloca, forIntegerLocal);
                ilGenerator.Emit(OperationCode.Call, this.helperClass.int32ToString);
                ilGenerator.Emit(OperationCode.Call, this.helperClass.stringConcatThree);

                // write to .dot file
                ilGenerator.Emit(OperationCode.Callvirt, this.helperClass.textWriterWriteLine);

                // call method that dumps graph recursively ( this.dumpGraphRec(streamWriter, String name, nextNode) )
                ilGenerator.Emit(OperationCode.Ldarg_0);

                // push stream writer parameter
                ilGenerator.Emit(OperationCode.Ldloc, streamWriterLocal);

                // push string parameter
                ilGenerator.Emit(OperationCode.Ldloc, nodeNameLocal);
                ilGenerator.Emit(OperationCode.Ldstr, "_");
                ilGenerator.Emit(OperationCode.Ldloca, forIntegerLocal);
                ilGenerator.Emit(OperationCode.Call, this.helperClass.int32ToString);
                ilGenerator.Emit(OperationCode.Call, this.helperClass.stringConcatThree);

                // push node parameter (current pointer of debug method)
                ilGenerator.Emit(OperationCode.Ldarg_2);
                ilGenerator.Emit(OperationCode.Ldloc, forIntegerLocal);
                ilGenerator.Emit(OperationCode.Callvirt, this.interfaceChildNodesGet);

                // push node parameter (current pointer of the caller)
                ilGenerator.Emit(OperationCode.Ldarg_3);

                ilGenerator.Emit(OperationCode.Callvirt, dumpGraphRecMethod);

                // increment loop counter
                ilGenerator.MarkLabel(loopConditionAndIncBranch);
                ilGenerator.Emit(OperationCode.Ldloc, forIntegerLocal);
                ilGenerator.Emit(OperationCode.Ldc_I4_1);
                ilGenerator.Emit(OperationCode.Add);
                ilGenerator.Emit(OperationCode.Stloc, forIntegerLocal);

                // loop condition
                ilGenerator.MarkLabel(loopConditionBranch);
                ilGenerator.Emit(OperationCode.Ldloc, forIntegerLocal);
                ilGenerator.Emit(OperationCode.Ldc_I4, this.graphDimension);
                ilGenerator.Emit(OperationCode.Clt);
                ilGenerator.Emit(OperationCode.Brtrue, loopStartBranch);

                // end .dot file
                ilGenerator.Emit(OperationCode.Ldloc, streamWriterLocal);
                ilGenerator.Emit(OperationCode.Ldstr, "}");
                ilGenerator.Emit(OperationCode.Callvirt, this.helperClass.textWriterWriteLine);

                // close io stream writer                
                ilGenerator.Emit(OperationCode.Ldloc, streamWriterLocal);
                ilGenerator.Emit(OperationCode.Callvirt, this.helperClass.textWriterClose);

                ilGenerator.Emit(OperationCode.Ret);

                // create body
                body = new ILGeneratorMethodBody(ilGenerator, true, 8, this.debuggingDumpGraphMethod, localVariables, Enumerable<ITypeDefinition>.Empty);
                this.debuggingDumpGraphMethod.Body = body;

                // create body for dumpGraphRec method
                localVariables = new List<ILocalDefinition>();
                ilGenerator = new ILGenerator(host, dumpGraphRecMethod);

                // create local integer variable for the for loop needed for debugging code
                forIntegerLocal = new LocalDefinition();
                forIntegerLocal.IsReference = false;
                forIntegerLocal.IsPinned = false;
                forIntegerLocal.IsModified = false;
                forIntegerLocal.Type = this.host.PlatformType.SystemInt32;
                forIntegerLocal.MethodDefinition = dumpGraphRecMethod;
                localVariables.Add(forIntegerLocal);

                // check if the node to dump is the same as the current node of the class
                // if it is => color the current dumped node
                ilGenerator.Emit(OperationCode.Ldarg, currentNodeCallerParameter);
                ilGenerator.Emit(OperationCode.Ldarg_3);
                ilGenerator.Emit(OperationCode.Ceq);
                currentNodeEqualDumpedNodeBranch = new ILGeneratorLabel();
                ilGenerator.Emit(OperationCode.Brtrue, currentNodeEqualDumpedNodeBranch);

                // case: current dumped node is not the current node of the class
                // write current node to .dot file
                ilGenerator.Emit(OperationCode.Ldarg_1);
                ilGenerator.Emit(OperationCode.Ldarg_2);
                ilGenerator.Emit(OperationCode.Ldstr, " [shape=record]");
                ilGenerator.Emit(OperationCode.Call, this.helperClass.stringConcatTwo);
                ilGenerator.Emit(OperationCode.Callvirt, this.helperClass.textWriterWriteLine);

                // jump to the end of this case
                currentNodeDumpedBranch = new ILGeneratorLabel();
                ilGenerator.Emit(OperationCode.Br, currentNodeDumpedBranch);

                // case: current dumped node is the current node of the class
                ilGenerator.MarkLabel(currentNodeEqualDumpedNodeBranch);

                // write current node to .dot file
                ilGenerator.Emit(OperationCode.Ldarg_1);
                ilGenerator.Emit(OperationCode.Ldarg_2);
                ilGenerator.Emit(OperationCode.Ldstr, " [shape=record, color=blue]");
                ilGenerator.Emit(OperationCode.Call, this.helperClass.stringConcatTwo);
                ilGenerator.Emit(OperationCode.Callvirt, this.helperClass.textWriterWriteLine);

                // end of the case
                ilGenerator.MarkLabel(currentNodeDumpedBranch);

                // write start of label of the current node to .dot file
                ilGenerator.Emit(OperationCode.Ldarg_1);
                ilGenerator.Emit(OperationCode.Ldarg_2);
                ilGenerator.Emit(OperationCode.Ldstr, " [label=\"{");
                ilGenerator.Emit(OperationCode.Call, this.helperClass.stringConcatTwo);
                ilGenerator.Emit(OperationCode.Callvirt, this.helperClass.textWriterWrite);

                // write current node name to .dot file
                ilGenerator.Emit(OperationCode.Ldarg_1);
                ilGenerator.Emit(OperationCode.Ldstr, "Node: ");
                ilGenerator.Emit(OperationCode.Ldarg_2);
                ilGenerator.Emit(OperationCode.Ldstr, "|");
                ilGenerator.Emit(OperationCode.Call, this.helperClass.stringConcatThree);
                ilGenerator.Emit(OperationCode.Callvirt, this.helperClass.textWriterWrite);

                // write current node id to .dot file
                ilGenerator.Emit(OperationCode.Ldarg_1);
                ilGenerator.Emit(OperationCode.Ldstr, "Id: ");
                ilGenerator.Emit(OperationCode.Ldarg_3);
                ilGenerator.Emit(OperationCode.Callvirt, this.debuggingInterfaceIdGet);
                ilGenerator.Emit(OperationCode.Call, this.helperClass.stringConcatTwo);
                ilGenerator.Emit(OperationCode.Callvirt, this.helperClass.textWriterWrite);

                // write end of label of the current node to .dot file
                ilGenerator.Emit(OperationCode.Ldarg_1);
                ilGenerator.Emit(OperationCode.Ldstr, "}\"]");
                ilGenerator.Emit(OperationCode.Callvirt, this.helperClass.textWriterWriteLine);

                // initialize counter of for loop
                ilGenerator.Emit(OperationCode.Ldc_I4_0);
                ilGenerator.Emit(OperationCode.Stloc, forIntegerLocal);

                // jump to loop condition
                loopConditionBranch = new ILGeneratorLabel();
                loopStartBranch = new ILGeneratorLabel();
                ilGenerator.Emit(OperationCode.Br, loopConditionBranch);

                // start of loop
                ilGenerator.MarkLabel(loopStartBranch);

                // check if childNodes[i] == startNode
                ilGenerator.Emit(OperationCode.Ldarg_3);
                ilGenerator.Emit(OperationCode.Ldloc, forIntegerLocal);
                ilGenerator.Emit(OperationCode.Callvirt, this.interfaceChildNodesGet);
                ilGenerator.Emit(OperationCode.Ldarg_0);
                ilGenerator.Emit(OperationCode.Callvirt, this.interfaceStartPointerGet);
                ilGenerator.Emit(OperationCode.Ceq);
                loopConditionAndIncBranch = new ILGeneratorLabel();
                ilGenerator.Emit(OperationCode.Brtrue, loopConditionAndIncBranch);

                // write connection of current node to next node to .dot file
                ilGenerator.Emit(OperationCode.Ldarg_1);

                // generate first part of the string
                ilGenerator.Emit(OperationCode.Ldarg_2);
                ilGenerator.Emit(OperationCode.Ldstr, " -> ");
                ilGenerator.Emit(OperationCode.Ldarg_2);
                ilGenerator.Emit(OperationCode.Call, this.helperClass.stringConcatThree);

                // generate second part of string and concat to first part
                ilGenerator.Emit(OperationCode.Ldstr, "_");
                ilGenerator.Emit(OperationCode.Ldloca, forIntegerLocal);
                ilGenerator.Emit(OperationCode.Call, this.helperClass.int32ToString);
                ilGenerator.Emit(OperationCode.Call, this.helperClass.stringConcatThree);

                // write to .dot file
                ilGenerator.Emit(OperationCode.Callvirt, this.helperClass.textWriterWriteLine);

                // call method that dumps graph recursively ( this.dumpGraphRec(streamWriter, String name, nextNode) )
                ilGenerator.Emit(OperationCode.Ldarg_0);

                // push stream writer parameter
                ilGenerator.Emit(OperationCode.Ldarg_1);

                // push string parameter
                ilGenerator.Emit(OperationCode.Ldarg_2);
                ilGenerator.Emit(OperationCode.Ldstr, "_");
                ilGenerator.Emit(OperationCode.Ldloca, forIntegerLocal);
                ilGenerator.Emit(OperationCode.Call, this.helperClass.int32ToString);
                ilGenerator.Emit(OperationCode.Call, this.helperClass.stringConcatThree);

                // push node parameter (current pointer of debug method)
                ilGenerator.Emit(OperationCode.Ldarg_3);
                ilGenerator.Emit(OperationCode.Ldloc, forIntegerLocal);
                ilGenerator.Emit(OperationCode.Callvirt, this.interfaceChildNodesGet);

                // push node parameter (current pointer of the caller)
                ilGenerator.Emit(OperationCode.Ldarg, currentNodeCallerParameter);

                ilGenerator.Emit(OperationCode.Callvirt, dumpGraphRecMethod);

                // increment loop counter
                ilGenerator.MarkLabel(loopConditionAndIncBranch);
                ilGenerator.Emit(OperationCode.Ldloc, forIntegerLocal);
                ilGenerator.Emit(OperationCode.Ldc_I4_1);
                ilGenerator.Emit(OperationCode.Add);
                ilGenerator.Emit(OperationCode.Stloc, forIntegerLocal);

                // loop condition
                ilGenerator.MarkLabel(loopConditionBranch);
                ilGenerator.Emit(OperationCode.Ldloc, forIntegerLocal);
                ilGenerator.Emit(OperationCode.Ldc_I4, this.graphDimension);
                ilGenerator.Emit(OperationCode.Clt);
                ilGenerator.Emit(OperationCode.Brtrue, loopStartBranch);

                ilGenerator.Emit(OperationCode.Ret);

                // create body
                body = new ILGeneratorMethodBody(ilGenerator, true, 8, dumpGraphRecMethod, localVariables, Enumerable<ITypeDefinition>.Empty);
                dumpGraphRecMethod.Body = body;

            }

            // inject code to build the graph to all constructors (except the artificial added ctor for a graph node)
            foreach (MethodDefinition ctorMethod in this.targetClass.Methods) {

                // only process constructors
                if (!ctorMethod.IsConstructor) {
                    continue;
                }

                // skip the artificial added ctor with the node interface as parameter
                bool skip = false;
                if (ctorMethod.Parameters != null) {
                    foreach (IParameterDefinition ctorParameter in ctorMethod.Parameters) {
                        if (ctorParameter.Type == this.nodeInterface) {
                            skip = true;
                            break;
                        }
                    }
                }
                if (skip) {
                    continue;
                }

                this.logger.writeLine("Injecting code to build graph to \"" + this.logger.makeFuncSigString(ctorMethod) + "\"");

                MethodCfg ctorMethodCfg = this.cfgBuilder.buildCfgForMethod(ctorMethod);

                // create new basic block that builds the graph
                // (will be the new starting basic block of the method)
                BasicBlock startBasicBlock = new BasicBlock();
                startBasicBlock.startIdx = 0;
                startBasicBlock.endIdx = 0;

                startBasicBlock.operations.Add(this.helperClass.createNewOperation(OperationCode.Ldarg_0));
                startBasicBlock.operations.Add(this.helperClass.createNewOperation(OperationCode.Callvirt, this.buildGraphMethod));

                if (this.debugging) {

                    // dump generated graph
                    startBasicBlock.operations.Add(this.helperClass.createNewOperation(OperationCode.Ldarg_0));
                    startBasicBlock.operations.Add(this.helperClass.createNewOperation(OperationCode.Ldstr, this.debuggingNumber.ToString().PadLeft(3, '0') + "_obfu_" + this.logger.makeFuncSigString(ctorMethodCfg.method)));
                    startBasicBlock.operations.Add(this.helperClass.createNewOperation(OperationCode.Ldarg_0));
                    startBasicBlock.operations.Add(this.helperClass.createNewOperation(OperationCode.Callvirt, this.interfaceStartPointerGet));
                    startBasicBlock.operations.Add(this.helperClass.createNewOperation(OperationCode.Ldarg_0));
                    startBasicBlock.operations.Add(this.helperClass.createNewOperation(OperationCode.Callvirt, this.interfaceStartPointerGet));
                    startBasicBlock.operations.Add(this.helperClass.createNewOperation(OperationCode.Callvirt, this.debuggingDumpGraphMethod));

                }

                // create exit branch for the new start basic block
                NoBranchTarget startExitBranch = new NoBranchTarget();
                startExitBranch.sourceBasicBlock = startBasicBlock;
                startBasicBlock.exitBranch = startExitBranch;

                // set the original start basic block as the target of the exit branch
                startExitBranch.takenTarget = ctorMethodCfg.startBasicBlock;
                ctorMethodCfg.startBasicBlock.entryBranches.Add(startExitBranch);

                // set new start basic block as start basic block of the method cfg
                ctorMethodCfg.startBasicBlock = startBasicBlock;
                ctorMethodCfg.basicBlocks.Add(startBasicBlock);

                this.cfgBuilder.createMethodFromCfg(ctorMethodCfg);

            }

        }
Exemplo n.º 4
0
        private static IMethodDefinition CreateStringToAnsi(IMetadataHost host, ITypeDefinition typeDef, IMethodReference getLength, IMethodReference getChars)
        {
            var byteType      = host.PlatformType.SystemUInt8;
            var byteArrayType = new VectorTypeReference {
                ElementType = byteType, Rank = 1
            };

            MethodDefinition methodDefinition = new MethodDefinition
            {
                ContainingTypeDefinition = typeDef,
                IsStatic   = true,
                Visibility = TypeMemberVisibility.Assembly,
                Type       = byteArrayType.ResolvedArrayType,
                Parameters = new List <IParameterDefinition> {
                    new ParameterDefinition {
                        Type = host.PlatformType.SystemString
                    }
                },
                Name = host.NameTable.GetNameFor("StringToAnsiByteArray")
            };

            var length = new LocalDefinition {
                Type = host.PlatformType.SystemInt32
            };
            var byteArray = new LocalDefinition {
                Type = byteArrayType.ResolvedArrayType
            };
            var loopIndex = new LocalDefinition {
                Type = host.PlatformType.SystemInt32
            };

            var locals = new List <ILocalDefinition> {
                length, byteArray, loopIndex
            };

            var ilGenerator   = new ILGenerator(host, methodDefinition);
            var nullCaseLabel = new ILGeneratorLabel();
            var loopStart     = new ILGeneratorLabel();
            var loopBackEdge  = new ILGeneratorLabel();

            ilGenerator.Emit(OperationCode.Ldarg_0);
            ilGenerator.Emit(OperationCode.Brtrue_S, nullCaseLabel);
            ilGenerator.Emit(OperationCode.Ldnull);
            ilGenerator.Emit(OperationCode.Ret);
            ilGenerator.MarkLabel(nullCaseLabel);
            ilGenerator.Emit(OperationCode.Ldarg_0);
            ilGenerator.Emit(OperationCode.Call, getLength);
            ilGenerator.Emit(OperationCode.Stloc_0);
            ilGenerator.Emit(OperationCode.Ldloc_0);
            ilGenerator.Emit(OperationCode.Ldc_I4_1);
            ilGenerator.Emit(OperationCode.Add);
            ilGenerator.Emit(OperationCode.Newarr, byteArrayType);
            ilGenerator.Emit(OperationCode.Stloc_1);
            ilGenerator.Emit(OperationCode.Ldc_I4_0);
            ilGenerator.Emit(OperationCode.Stloc_2);
            ilGenerator.Emit(OperationCode.Br_S, loopStart);
            ilGenerator.MarkLabel(loopBackEdge);
            ilGenerator.Emit(OperationCode.Ldloc_1);
            ilGenerator.Emit(OperationCode.Ldloc_2);
            ilGenerator.Emit(OperationCode.Ldarg_0);
            ilGenerator.Emit(OperationCode.Ldloc_2);
            ilGenerator.Emit(OperationCode.Call, getChars);
            ilGenerator.Emit(OperationCode.Conv_U1);
            ilGenerator.Emit(OperationCode.Stelem_I1);
            ilGenerator.Emit(OperationCode.Ldloc_2);
            ilGenerator.Emit(OperationCode.Ldc_I4_1);
            ilGenerator.Emit(OperationCode.Add);
            ilGenerator.Emit(OperationCode.Stloc_2);
            ilGenerator.MarkLabel(loopStart);
            ilGenerator.Emit(OperationCode.Ldloc_2);
            ilGenerator.Emit(OperationCode.Ldloc_0);
            ilGenerator.Emit(OperationCode.Blt_S, loopBackEdge);
            ilGenerator.Emit(OperationCode.Ldloc_1);
            ilGenerator.Emit(OperationCode.Ldloc_0);
            ilGenerator.Emit(OperationCode.Ldc_I4_0);
            ilGenerator.Emit(OperationCode.Stelem_I1);
            ilGenerator.Emit(OperationCode.Ldloc_1);
            ilGenerator.Emit(OperationCode.Ret);

            methodDefinition.Body = new ILGeneratorMethodBody(ilGenerator, true, 8, methodDefinition, locals, new List <ITypeDefinition>());

            return(methodDefinition);
        }
Exemplo n.º 5
0
        // this function adds the created iNode interface to the class and also implements all neded functions
        public void addNodeInterfaceToTargetClass(NamespaceTypeDefinition givenClass) {

            this.logger.writeLine("");
            this.logger.writeLine("Add node interface \"" + this.nodeInterface.ToString() + "\" to class \"" + givenClass.ToString() + "\"");

            // check if generated interface was already added to target class
            if (givenClass.Interfaces != null
                && givenClass.Interfaces.Contains(this.nodeInterface)) {
                this.logger.writeLine("Class \"" + givenClass.ToString() + "\" already contains node interface \"" + this.nodeInterface.ToString() + "\"");
                return;
            }

            // add nodes interface to class
            if (givenClass.Interfaces != null) {
                givenClass.Interfaces.Add(this.nodeInterface);
            }
            else {
                givenClass.Interfaces = new List<ITypeReference>();
                givenClass.Interfaces.Add(this.nodeInterface);
            }

            // add start pointer field
            FieldDefinition startPointerField = new FieldDefinition();
            startPointerField.IsCompileTimeConstant = false;
            startPointerField.IsNotSerialized = false;
            startPointerField.IsReadOnly = false;
            startPointerField.IsRuntimeSpecial = false;
            startPointerField.IsSpecialName = false;
            startPointerField.Type = this.nodeInterface;
            startPointerField.IsStatic = false;
            startPointerField.Visibility = TypeMemberVisibility.Public;
            startPointerField.Name = host.NameTable.GetNameFor("startPointer");
            startPointerField.InternFactory = host.InternFactory;
            startPointerField.ContainingTypeDefinition = givenClass;
            if (givenClass.Fields != null) {
                givenClass.Fields.Add(startPointerField);
            }
            else {
                givenClass.Fields = new List<IFieldDefinition>();
                givenClass.Fields.Add(startPointerField);
            }

            // create getter for the startPointer variable
            MethodDefinition startPointerGetMethod = this.helperClass.createNewMethod("startPointer_get", givenClass, this.nodeInterface, TypeMemberVisibility.Public, null, CallingConvention.HasThis, false, false, true); // TODO: method name

            // create a body for the getter method
            ILGenerator ilGenerator = new ILGenerator(host, startPointerGetMethod);
            ilGenerator.Emit(OperationCode.Ldarg_0);
            ilGenerator.Emit(OperationCode.Ldfld, startPointerField);
            ilGenerator.Emit(OperationCode.Ret);
            IMethodBody body = new ILGeneratorMethodBody(ilGenerator, true, 1, startPointerGetMethod, Enumerable<ILocalDefinition>.Empty, Enumerable<ITypeDefinition>.Empty);
            startPointerGetMethod.Body = body;

            // create setter for the startPointer variable
            List<IParameterDefinition> parameters = new List<IParameterDefinition>();
            ParameterDefinition parameter = new ParameterDefinition();
            parameter.IsIn = false;
            parameter.IsOptional = false;
            parameter.IsOut = false;
            parameter.Name = host.NameTable.GetNameFor("value");
            parameter.Type = this.nodeInterface;
            parameters.Add(parameter);
            MethodDefinition startPointerSetMethod = this.helperClass.createNewMethod("startPointer_set", givenClass, host.PlatformType.SystemVoid, TypeMemberVisibility.Public, parameters, CallingConvention.HasThis, false, false, true); // TODO: method name

            // create a body for the setter method
            ilGenerator = new ILGenerator(host, startPointerSetMethod);
            ilGenerator.Emit(OperationCode.Ldarg_0);
            ilGenerator.Emit(OperationCode.Ldarg_1);
            ilGenerator.Emit(OperationCode.Stfld, startPointerField);
            ilGenerator.Emit(OperationCode.Ret);
            body = new ILGeneratorMethodBody(ilGenerator, true, 1, startPointerSetMethod, Enumerable<ILocalDefinition>.Empty, Enumerable<ITypeDefinition>.Empty);
            startPointerSetMethod.Body = body;

            // add childNodes array field
            FieldDefinition childNodesField = new FieldDefinition();
            childNodesField.IsCompileTimeConstant = false;
            childNodesField.IsNotSerialized = false;
            childNodesField.IsReadOnly = false;
            childNodesField.IsRuntimeSpecial = false;
            childNodesField.IsSpecialName = false;
            // create array of node interface type
            VectorTypeReference nodeInterfaceArrayType = new VectorTypeReference();
            nodeInterfaceArrayType.ElementType = this.nodeInterface;
            nodeInterfaceArrayType.Rank = 1;
            nodeInterfaceArrayType.IsFrozen = true;
            nodeInterfaceArrayType.IsValueType = false;
            nodeInterfaceArrayType.InternFactory = host.InternFactory;
            childNodesField.Type = nodeInterfaceArrayType;

            childNodesField.IsStatic = false;
            childNodesField.Visibility = TypeMemberVisibility.Public;
            childNodesField.Name = host.NameTable.GetNameFor("childNodes");
            childNodesField.InternFactory = host.InternFactory;
            childNodesField.ContainingTypeDefinition = givenClass;
            givenClass.Fields.Add(childNodesField);

            // create getter for the childNodes variable
            parameters = new List<IParameterDefinition>();
            // int parameter
            parameter = new ParameterDefinition();
            parameter.IsIn = false;
            parameter.IsOptional = false;
            parameter.IsOut = false;
            parameter.Type = this.host.PlatformType.SystemInt32;
            parameters.Add(parameter);
            MethodDefinition childNodesGetMethod = this.helperClass.createNewMethod("childNodes_get", givenClass, this.nodeInterface, TypeMemberVisibility.Public, parameters, CallingConvention.HasThis, false, false, true); // TODO: method name

            // create a body for the getter method
            ilGenerator = new ILGenerator(host, childNodesGetMethod);
            ilGenerator.Emit(OperationCode.Ldarg_0);
            ilGenerator.Emit(OperationCode.Ldfld, childNodesField);
            ilGenerator.Emit(OperationCode.Ldarg_1);
            ilGenerator.Emit(OperationCode.Ldelem_Ref);
            ilGenerator.Emit(OperationCode.Ret);
            body = new ILGeneratorMethodBody(ilGenerator, true, 1, childNodesGetMethod, Enumerable<ILocalDefinition>.Empty, Enumerable<ITypeDefinition>.Empty);
            childNodesGetMethod.Body = body;

            // create setter for the childNodes variable
            parameters = new List<IParameterDefinition>();
            // iNode parameter
            parameter = new ParameterDefinition();
            parameter.IsIn = false;
            parameter.IsOptional = false;
            parameter.IsOut = false;
            parameter.Type = this.nodeInterface;
            parameters.Add(parameter);
            // int parameter
            parameter = new ParameterDefinition();
            parameter.IsIn = false;
            parameter.IsOptional = false;
            parameter.IsOut = false;
            parameter.Type = this.host.PlatformType.SystemInt32;
            parameters.Add(parameter);
            MethodDefinition childNodesSetMethod = this.helperClass.createNewMethod("childNodes_set", givenClass, host.PlatformType.SystemVoid, TypeMemberVisibility.Public, parameters, CallingConvention.HasThis, false, false, true); // TODO: method name

            // create a body for the setter method
            ilGenerator = new ILGenerator(host, childNodesSetMethod);
            ilGenerator.Emit(OperationCode.Ldarg_0);
            ilGenerator.Emit(OperationCode.Ldfld, childNodesField);
            ilGenerator.Emit(OperationCode.Ldarg_2);
            ilGenerator.Emit(OperationCode.Ldarg_1);
            ilGenerator.Emit(OperationCode.Stelem_Ref);
            ilGenerator.Emit(OperationCode.Ret);
            body = new ILGeneratorMethodBody(ilGenerator, true, 1, childNodesSetMethod, Enumerable<ILocalDefinition>.Empty, Enumerable<ITypeDefinition>.Empty);
            childNodesSetMethod.Body = body;

            // add current node field
            FieldDefinition currentNodeField = new FieldDefinition();
            currentNodeField.IsCompileTimeConstant = false;
            currentNodeField.IsNotSerialized = false;
            currentNodeField.IsReadOnly = false;
            currentNodeField.IsRuntimeSpecial = false;
            currentNodeField.IsSpecialName = false;
            currentNodeField.Type = this.nodeInterface;
            currentNodeField.IsStatic = false;
            currentNodeField.Visibility = TypeMemberVisibility.Public;
            currentNodeField.Name = host.NameTable.GetNameFor("currentNode");
            currentNodeField.InternFactory = host.InternFactory;
            currentNodeField.ContainingTypeDefinition = givenClass;
            givenClass.Fields.Add(currentNodeField);

            // create getter for the currentNode variable
            MethodDefinition currentNodeGetMethod = this.helperClass.createNewMethod("currentNode_get", givenClass, this.nodeInterface, TypeMemberVisibility.Public, null, CallingConvention.HasThis, false, false, true); // TODO: method name

            // create a body for the getter method
            ilGenerator = new ILGenerator(host, currentNodeGetMethod);
            ilGenerator.Emit(OperationCode.Ldarg_0);
            ilGenerator.Emit(OperationCode.Ldfld, currentNodeField);
            ilGenerator.Emit(OperationCode.Ret);
            body = new ILGeneratorMethodBody(ilGenerator, true, 1, currentNodeGetMethod, Enumerable<ILocalDefinition>.Empty, Enumerable<ITypeDefinition>.Empty);
            currentNodeGetMethod.Body = body;

            // create setter for the currentNode variable
            parameters = new List<IParameterDefinition>();
            parameter = new ParameterDefinition();
            parameter.IsIn = false;
            parameter.IsOptional = false;
            parameter.IsOut = false;
            parameter.Name = host.NameTable.GetNameFor("value");
            parameter.Type = this.nodeInterface;
            parameters.Add(parameter);
            MethodDefinition currentNodeSetMethod = this.helperClass.createNewMethod("currentNode_set", givenClass, host.PlatformType.SystemVoid, TypeMemberVisibility.Public, parameters, CallingConvention.HasThis, false, false, true); // TODO: method name

            // create a body for the setter method
            ilGenerator = new ILGenerator(host, currentNodeSetMethod);
            ilGenerator.Emit(OperationCode.Ldarg_0);
            ilGenerator.Emit(OperationCode.Ldarg_1);
            ilGenerator.Emit(OperationCode.Stfld, currentNodeField);
            ilGenerator.Emit(OperationCode.Ret);
            body = new ILGeneratorMethodBody(ilGenerator, true, 1, currentNodeSetMethod, Enumerable<ILocalDefinition>.Empty, Enumerable<ITypeDefinition>.Empty);
            currentNodeSetMethod.Body = body;

            // check if debugging is activated
            // => add graph debugging attributes and methods
            MethodDefinition objectIdGetMethod = null;
            FieldDefinition objectIdField = null;
            if (this.debugging) {

                this.logger.writeLine("Debugging activated: Adding field for unique object id and getter method");

                // add objectId field
                objectIdField = new FieldDefinition();
                objectIdField.IsCompileTimeConstant = false;
                objectIdField.IsNotSerialized = false;
                objectIdField.IsReadOnly = false;
                objectIdField.IsRuntimeSpecial = false;
                objectIdField.IsSpecialName = false;
                objectIdField.Type = this.host.PlatformType.SystemString;
                objectIdField.IsStatic = false;
                objectIdField.Name = host.NameTable.GetNameFor("DEBUG_objectId");
                objectIdField.Visibility = TypeMemberVisibility.Public;
                objectIdField.InternFactory = host.InternFactory;
                objectIdField.ContainingTypeDefinition = givenClass;
                givenClass.Fields.Add(objectIdField);

                // create getter for the objectId variable
                objectIdGetMethod = this.helperClass.createNewMethod("DEBUG_objectId_get", givenClass, this.host.PlatformType.SystemString, TypeMemberVisibility.Public, null, CallingConvention.HasThis, false, false, true); // TODO: method name

                // create a body for the getter method
                ilGenerator = new ILGenerator(host, objectIdGetMethod);
                ilGenerator.Emit(OperationCode.Ldarg_0);
                ilGenerator.Emit(OperationCode.Ldfld, objectIdField);
                ilGenerator.Emit(OperationCode.Ret);
                body = new ILGeneratorMethodBody(ilGenerator, true, 1, objectIdGetMethod, Enumerable<ILocalDefinition>.Empty, Enumerable<ITypeDefinition>.Empty);
                objectIdGetMethod.Body = body;

            }

            // add .ctor(iNode) to target class
            parameters = new List<IParameterDefinition>();
            parameter = new ParameterDefinition();
            parameter.IsIn = false;
            parameter.IsOptional = false;
            parameter.IsOut = false;
            parameter.Type = this.nodeInterface;
            parameters.Add(parameter);

            MethodDefinition nodeConstructor = this.helperClass.createNewMethod(".ctor", givenClass, host.PlatformType.SystemVoid, TypeMemberVisibility.Public, parameters, CallingConvention.HasThis, false, false, false);
            nodeConstructor.IsSpecialName = true;
            nodeConstructor.IsHiddenBySignature = true;
            nodeConstructor.IsRuntimeSpecial = true;

            // generate node constructor body
            ilGenerator = new ILGenerator(host, currentNodeSetMethod);

            // create local variable list
            List<ILocalDefinition> localVariables = new List<ILocalDefinition>();

            // call system.object constructor
            ilGenerator.Emit(OperationCode.Ldarg_0);
            ilGenerator.Emit(OperationCode.Call, this.helperClass.objectCtor);

            // initialize childNodes array
            ilGenerator.Emit(OperationCode.Ldarg_0);
            ilGenerator.Emit(OperationCode.Ldc_I4, this.graphDimension);
            ilGenerator.Emit(OperationCode.Newarr, nodeInterfaceArrayType);
            ilGenerator.Emit(OperationCode.Stfld, childNodesField);

            // check if debugging is activated
            // => add code to constructor that generates a unique id for this object
            if (this.debugging) {

                this.logger.writeLine("Debugging activated: Adding code to generate unique id to node constructor");

                // create local integer variable needed for debugging code
                LocalDefinition intLocal = new LocalDefinition();
                intLocal.IsReference = false;
                intLocal.IsPinned = false;
                intLocal.IsModified = false;
                intLocal.Type = this.host.PlatformType.SystemInt32;
                intLocal.MethodDefinition = nodeConstructor;
                localVariables.Add(intLocal);

                // use the hash code of this instance as unique object id
                ilGenerator.Emit(OperationCode.Ldarg_0);
                ilGenerator.Emit(OperationCode.Ldarg_0);
                ilGenerator.Emit(OperationCode.Callvirt, this.helperClass.objectGetHashCode);
                ilGenerator.Emit(OperationCode.Stloc, intLocal);

                // cast random integer to string and store in object id
                ilGenerator.Emit(OperationCode.Ldloca, intLocal);
                ilGenerator.Emit(OperationCode.Call, this.helperClass.int32ToString);
                ilGenerator.Emit(OperationCode.Stfld, objectIdField);

            }

            ilGenerator.Emit(OperationCode.Ret);
            body = new ILGeneratorMethodBody(ilGenerator, true, 8, nodeConstructor, localVariables, Enumerable<ITypeDefinition>.Empty);
            nodeConstructor.Body = body;


            // add class to the list of possible nodes for the graph
            PossibleNode tempStruct = new PossibleNode();
            tempStruct.nodeConstructor = nodeConstructor;
            tempStruct.givenClass = givenClass;

            // for each interface the class implements add it to the according list
            foreach (ITypeReference interfaceRef in givenClass.Interfaces) {

                this.logger.writeLine("Add class \"" + givenClass.ToString() + "\" to graph interface list \"" + interfaceRef.ToString() + "\"");

                // check if a list with this interface already exists
                // => if it does just add current class to list
                if (this.graphInterfaces.ContainsKey(interfaceRef)) {
                    List<PossibleNode> tempList = (List<PossibleNode>)this.graphInterfaces[interfaceRef];
                    tempList.Add(tempStruct);
                }
                // if not => add new list for this interface
                else {
                    List<PossibleNode> tempList = new List<PossibleNode>();
                    tempList.Add(tempStruct);
                    this.graphInterfaces.Add(interfaceRef, tempList);
                }
            }

            this.logger.writeLine("");

        }