Inheritance: Statement, IReturnStatement
        public override void BuildMethod()
        {
            AddStatement.DeclareInterceptedType(field.ContainingType.ResolvedType);

            Context.Log.WriteTrace("  Adding: var interceptedField = interceptedType.GetField('{0}');", field.Name.Value);
            Context.Block.Statements.Add(
                Declare.Variable<FieldInfo>("interceptedField").As(
                    Call.VirtualMethod("GetField", typeof (string)).ThatReturns<FieldInfo>().WithArguments(
                        Constant.Of(field.Name.Value)).On("interceptedType"))
            );

            AddStatement.DeclareArgumentsList();

            var funcT = SharpMockTypes.Functions[0];
            var funcActualT = new GenericTypeInstanceReference();
            funcActualT.GenericType = funcT;
            funcActualT.GenericArguments.Add(field.Type);

            var accessor = new AnonymousDelegate();
            accessor.Type = funcActualT;
            accessor.ReturnType = field.Type;
            accessor.CallingConvention = CallingConvention.HasThis;

            var accessorBody = new BlockStatement();
            var returnActualField = new ReturnStatement();
            var actualField = new BoundExpression();
            actualField.Type = field.Type;
            actualField.Definition = field;
            returnActualField.Expression = actualField;
            accessorBody.Statements.Add(returnActualField);
            accessor.Body = accessorBody;

            Context.Block.Statements.Add(
                Declare.Variable("local_0", funcActualT).As(accessor)
            );

            AddStatement.DeclareRegistryInterceptor();
            AddStatement.DeclareInvocation();
            AddStatement.SetArgumentsOnInvocation();
            AddStatement.SetOriginalCallOnInvocation();
            AddStatement.SetTargetOnInvocationToNull();

            Context.Block.Statements.Add(
                Do(Call.PropertySetter<MemberInfo>("OriginalCallInfo").WithArguments("interceptedField").On("invocation"))
            );

            AddStatement.CallShouldInterceptOnInterceptor();
            AddStatement.CallInterceptOnInterceptor();

            Context.Block.Statements.Add(
                Declare.Variable("interceptionResult", field.Type).As(
                    ChangeType.Convert(Call.PropertyGetter<object>("Return").On("invocation")).To(field.Type))
            );

            Context.Block.Statements.Add(Return.Variable(Locals["interceptionResult"]));
        }
Esempio n. 2
0
 private bool ReplaceReturnViaGotoInVoidMethods(BlockStatement b) {
   Contract.Requires(b != null);
   if (!this.isVoidMethod) return false;
   if (this.labelOfFinalReturn == null) return false;
   bool replacedPattern = false;
   var statements = b.Statements;
   for (int i = 1; i < b.Statements.Count - 1; i++) {
     var gotoStatement = statements[i] as GotoStatement;
     if (gotoStatement == null) continue;
     if (gotoStatement.TargetStatement.Label != this.labelOfFinalReturn) continue;
     var gotos = this.gotosThatTarget[(uint)gotoStatement.TargetStatement.Label.UniqueKey];
     if (gotos != null) gotos.Remove(gotoStatement);
     statements[i] = new ReturnStatement();
     replacedPattern = true;
   }
   return replacedPattern;
 }
Esempio n. 3
0
 private bool ReplaceReturnViaGoto(BlockStatement b) {
   Contract.Requires(b != null);
   if (this.returnValueTemp == null) return false;
   bool replacedPattern = false;
   var statements = b.Statements;
   for (int i = 1; i < b.Statements.Count-1; i++) {
     var expressionStatement = statements[i] as ExpressionStatement;
     if (expressionStatement == null) continue;
     var assign = expressionStatement.Expression as Assignment;
     if (assign == null) continue;
     if (assign.Target.Definition != this.returnValueTemp) continue;
     var gotoStatement = statements[i+1] as GotoStatement;
     if (gotoStatement == null) continue;
     if (gotoStatement.TargetStatement.Label != this.labelOfFinalReturn) continue;
     var gotos = this.gotosThatTarget[(uint)gotoStatement.TargetStatement.Label.UniqueKey];
     if (gotos != null) gotos.Remove(gotoStatement);
     statements[i] = new ReturnStatement() { Expression = assign.Source };
     this.numberOfAssignmentsToLocal[this.returnValueTemp]--;
     statements.RemoveAt(i+1);
     replacedPattern = true;
   }
   return replacedPattern;
 }
 public FieldAccessorReplacementFactory(FieldReference field, ReturnStatement firstStatement, ReplacementRegistry registry)
 {
     this.field = field;
     this.firstStatement = firstStatement;
     this.registry = registry;
 }
 public override IStatement Visit(ReturnStatement returnStatement)
 {
     if (returnStatement.Expression != null) {
     returnStatement.Expression = this.Visit(returnStatement.Expression);
       }
       if (this.sourceMethodBody.MethodDefinition.Type.TypeCode == PrimitiveTypeCode.Boolean) {
     CompileTimeConstant/*?*/ cc = returnStatement.Expression as CompileTimeConstant;
     if (cc != null) {
       if (ExpressionHelper.IsIntegralZero(cc))
     cc.Value = false;
       else
     cc.Value = true;
       cc.Type = this.containingType.PlatformType.SystemBoolean;
     }
       }
       return returnStatement;
 }
Esempio n. 6
0
 /// <summary>
 /// Rewrites the children of the return statement.
 /// </summary>
 public virtual void RewriteChildren(ReturnStatement returnStatement)
 {
     this.RewriteChildren((Statement)returnStatement);
       if (returnStatement.Expression != null)
     returnStatement.Expression = this.Rewrite(returnStatement.Expression);
 }
Esempio n. 7
0
 /// <summary>
 /// Build the state machine. 
 /// 
 /// We start from state 0. For each yield return, we assign a unique state, which we call continueing state. For a yield return 
 /// assigned with state x, we move the state machine from the previous state to x. Whenever we see a yield break, we transit
 /// the state to -1. 
 /// 
 /// When we return from state x, we jump to a label that is inserted right after the previous yield return (that is assigned with state x). 
 /// </summary>
 private BlockStatement BuildStateMachine(IteratorClosureInformation iteratorClosure, BlockStatement oldBody, Dictionary<int, ILabeledStatement> stateEntries) {
   // Switch on cases. StateEntries, which have been computed previously, map a state number (for initial and continuing states) to a label that has been inserted 
   // right after the associated yield return. 
   BlockStatement result = new BlockStatement();
   var returnFalse = new ReturnStatement() { Expression = new CompileTimeConstant() { Value = false, Type = this.host.PlatformType.SystemBoolean } };
   var returnFalseLabel = new LabeledStatement() { Label = this.host.NameTable.GetNameFor("return false"), Statement = returnFalse };
   List<ISwitchCase> cases = new List<ISwitchCase>();
   foreach (int i in stateEntries.Keys) {
     SwitchCase c = new SwitchCase() {
       Expression = new CompileTimeConstant() { Type = this.host.PlatformType.SystemInt32, Value = i },
       Body = new List<IStatement>(),
     };
     c.Body.Add(new GotoStatement() { TargetStatement = stateEntries[i] });
     cases.Add(c);
   }
   // Default case.
   SwitchCase defaultCase = new SwitchCase();
   defaultCase.Body.Add(new GotoStatement() { TargetStatement = returnFalseLabel });
   cases.Add(defaultCase);
   SwitchStatement switchStatement = new SwitchStatement() {
     Cases = cases,
     Expression = new BoundExpression() { Type = this.host.PlatformType.SystemInt32, Instance = new ThisReference(), Definition = iteratorClosure.StateFieldReference }
   };
   result.Statements.Add(switchStatement);
   result.Statements.Add(oldBody);
   result.Statements.Add(returnFalseLabel);
   return result;
 }
 private Statement ParseReturn() {
   ReturnStatement result = new ReturnStatement();
   if (this.MethodDefinition.Type.TypeCode != PrimitiveTypeCode.Void) {
     result.Expression = TypeInferencer.Convert(this.PopOperandStack(), this.MethodDefinition.Type);
   }
   return result;
 }
Esempio n. 9
0
 /// <summary>
 /// Replace a (yield return exp)with a new block of the form:
 /// {
 ///   Fresh_Label:;
 ///   this.current = exp;
 ///   state = Fresh_state;
 ///   return true;
 /// }
 /// and associate the newly generated Fresh_state with its entry point: Fresh_label.
 /// </summary>
 public override IStatement Rewrite(IYieldReturnStatement yieldReturnStatement) {
   BlockStatement blockStatement = new BlockStatement();
   int state = this.stateNumber++;
   ExpressionStatement thisDotStateEqState = new ExpressionStatement() {
     Expression = new Assignment() {
       Source = new CompileTimeConstant() { Value = state, Type = this.host.PlatformType.SystemInt32 },
       Target = new TargetExpression() { Definition = this.iteratorClosure.StateFieldReference, Instance = new ThisReference(), Type = this.host.PlatformType.SystemInt32 },
       Type = this.host.PlatformType.SystemInt32,
     },
     Locations = IteratorHelper.EnumerableIsEmpty(yieldReturnStatement.Locations) ? null : new List<ILocation>(yieldReturnStatement.Locations)
   };
   blockStatement.Statements.Add(thisDotStateEqState);
   ExpressionStatement thisDotCurrentEqReturnExp = new ExpressionStatement() {
     Expression = new Assignment() {
       Source = yieldReturnStatement.Expression,
       Target = new TargetExpression() { Definition = this.iteratorClosure.CurrentFieldReference, Instance = new ThisReference(), Type = this.iteratorClosure.CurrentFieldReference.Type },
       Type = this.iteratorClosure.CurrentFieldReference.Type
     }
   };
   blockStatement.Statements.Add(thisDotCurrentEqReturnExp);
   ReturnStatement returnTrue = new ReturnStatement() {
     Expression = new CompileTimeConstant() {
       Value = true, Type = this.host.PlatformType.SystemBoolean
     }
   };
   blockStatement.Statements.Add(returnTrue);
   LabeledStatement labeledStatement = new LabeledStatement() {
     Label = this.host.NameTable.GetNameFor("Label"+state), Statement = new EmptyStatement()
   };
   blockStatement.Statements.Add(labeledStatement);
   this.stateEntries.Add(state, labeledStatement);
   return blockStatement;
 }
Esempio n. 10
0
 /// <summary>
 /// Replace a yield break with:
 /// {
 ///   this.state = -2;
 ///   return;
 /// }
 /// </summary>
 /// <param name="yieldBreakStatement"></param>
 /// <returns></returns>
 public override IStatement Rewrite(IYieldBreakStatement yieldBreakStatement) {
   BlockStatement blockStatement = new BlockStatement();
   ExpressionStatement thisDotStateEqMinus2 = new ExpressionStatement() {
     Expression = new Assignment() {
       Source = new CompileTimeConstant() { Value = -2, Type = this.host.PlatformType.SystemInt32 },
       Target = new TargetExpression() { Definition = iteratorClosure.StateFieldReference, Type = this.host.PlatformType.SystemInt32, Instance = new ThisReference() },
       Type = this.host.PlatformType.SystemInt32,
     }
   };
   blockStatement.Statements.Add(thisDotStateEqMinus2);
   ReturnStatement returnFalse = new ReturnStatement() {
     Expression = new CompileTimeConstant() {
       Value = false,
       Type = this.host.PlatformType.SystemBoolean
     }
   };
   blockStatement.Statements.Add(returnFalse);
   return blockStatement;
 }
Esempio n. 11
0
    /// <summary>
    /// Create two properties: object Current and T Current as the closure class implements both the 
    /// generic and non-generic version of ienumerator. 
    /// 
    /// Current Implementation generates getters, but not the property.
    /// </summary>
    /// <param name="iteratorClosure">Information about the closure created when compiling the current iterator method</param>
    private void CreateIteratorClosureProperties(IteratorClosureInformation iteratorClosure) {
      // Non-generic version of the get_Current, which returns the generic version of get_Current. 
      MethodDefinition getterNonGenericCurrent = new MethodDefinition() {
        Attributes = new List<ICustomAttribute>(1),
        InternFactory = this.host.InternFactory,
        Name = this.host.NameTable.GetNameFor("System.Collections.IEnumerator.get_Current")
      };
      CustomAttribute debuggerHiddenAttribute = new CustomAttribute();
      debuggerHiddenAttribute.Constructor = this.DebuggerHiddenCtor;
      getterNonGenericCurrent.Attributes.Add(debuggerHiddenAttribute);
      getterNonGenericCurrent.CallingConvention |= CallingConvention.HasThis;
      getterNonGenericCurrent.Visibility |= TypeMemberVisibility.Public;
      getterNonGenericCurrent.ContainingTypeDefinition = iteratorClosure.ClosureDefinition;
      getterNonGenericCurrent.Type = this.host.PlatformType.SystemObject;
      getterNonGenericCurrent.IsSpecialName = true;
      getterNonGenericCurrent.IsVirtual = true;
      getterNonGenericCurrent.IsNewSlot = true;
      getterNonGenericCurrent.IsHiddenBySignature = true;
      getterNonGenericCurrent.IsSealed = true;
      iteratorClosure.NonGenericGetCurrent = getterNonGenericCurrent;
      IMethodReference originalMethod = Dummy.MethodReference;
      foreach (ITypeMemberReference tref in iteratorClosure.NonGenericIEnumeratorInterface.ResolvedType.GetMembersNamed(this.host.NameTable.GetNameFor("get_Current"), false)) {
        originalMethod = tref as IMethodReference; if (originalMethod != null) break;
      }
      // assert originalMethod != Dummy
      MethodImplementation getterImplementation = new MethodImplementation() {
        ContainingType = iteratorClosure.ClosureDefinition,
        ImplementingMethod = getterNonGenericCurrent,
        ImplementedMethod = originalMethod
      };
      iteratorClosure.ClosureDefinition.ExplicitImplementationOverrides.Add(getterImplementation);

      List<IStatement> statements = new List<IStatement>();
      IFieldReference currentField = iteratorClosure.CurrentFieldReference;
      BoundExpression thisDotCurr = new BoundExpression() {
        Definition = currentField,
        Instance = new ThisReference(),
        Locations = iteratorClosure.ClosureDefinition.Locations,
        Type = currentField.Type
      };
      IExpression returnExpression;
      if (!iteratorClosure.ElementType.IsValueType && TypeHelper.TypesAreAssignmentCompatible(iteratorClosure.ElementType.ResolvedType, this.host.PlatformType.SystemObject.ResolvedType)) {
        returnExpression = thisDotCurr;
      } else {
        Conversion convertion = new Conversion() {
          CheckNumericRange = false,
          Type = this.host.PlatformType.SystemObject,
          TypeAfterConversion = getterNonGenericCurrent.Type,
          ValueToConvert = thisDotCurr
        };
        returnExpression = convertion;
      }
      ReturnStatement returnCurrent = new ReturnStatement() {
        Expression = returnExpression,
        Locations = iteratorClosure.ClosureDefinition.Locations
      };
      statements.Add(returnCurrent);
      BlockStatement block = new BlockStatement() { Statements = statements };
      SourceMethodBody body = new SourceMethodBody(this.host, this.sourceLocationProvider);
      body.IsNormalized = true;
      body.LocalsAreZeroed = true;
      body.Block = block;
      body.MethodDefinition = getterNonGenericCurrent;
      getterNonGenericCurrent.Body = body;

      // Create generic version of get_Current, the body of which is simply returning this.current.
      MethodDefinition getterGenericCurrent = new MethodDefinition() {
        Attributes = new List<ICustomAttribute>(1),
        InternFactory = this.host.InternFactory,
        Name = this.host.NameTable.GetNameFor("System.Collections.Generic.IEnumerator<" + iteratorClosure.ElementType.ToString() +">.get_Current")
      };
      getterGenericCurrent.Attributes.Add(debuggerHiddenAttribute);

      getterGenericCurrent.CallingConvention |= CallingConvention.HasThis;
      getterGenericCurrent.Visibility |= TypeMemberVisibility.Public;
      getterGenericCurrent.ContainingTypeDefinition = iteratorClosure.ClosureDefinition;
      getterGenericCurrent.Type = iteratorClosure.ElementType;
      getterGenericCurrent.IsSpecialName = true;
      getterGenericCurrent.IsVirtual = true;
      getterGenericCurrent.IsNewSlot = true;
      getterGenericCurrent.IsHiddenBySignature = true;
      getterGenericCurrent.IsSealed = true;
      iteratorClosure.GenericGetCurrent = getterGenericCurrent;
      originalMethod = Dummy.MethodReference;
      foreach (ITypeMemberReference tref in iteratorClosure.GenericIEnumeratorInterface.ResolvedType.GetMembersNamed(this.host.NameTable.GetNameFor("get_Current"), false)) {
        originalMethod = tref as IMethodReference; if (originalMethod != null) break;
      }
      MethodImplementation getterImplementation2 = new MethodImplementation() {
        ContainingType = iteratorClosure.ClosureDefinition,
        ImplementingMethod = getterGenericCurrent,
        ImplementedMethod = originalMethod
      };
      iteratorClosure.ClosureDefinition.ExplicitImplementationOverrides.Add(getterImplementation2);

      statements = new List<IStatement>();
      currentField = iteratorClosure.CurrentFieldReference;
      BoundExpression thisDotCurrent = new BoundExpression() {
        Definition = currentField, Instance = new ThisReference(), Locations = iteratorClosure.ClosureDefinition.Locations, Type = currentField.Type
      };
      returnCurrent = new ReturnStatement() {
        Expression = thisDotCurrent,
        Locations = iteratorClosure.ClosureDefinition.Locations
      };
      statements.Add(returnCurrent);
      block = new BlockStatement() { Statements = statements };
      body = new SourceMethodBody(this.host, this.sourceLocationProvider);
      body.LocalsAreZeroed = true;
      body.Block = block;
      body.MethodDefinition = getterGenericCurrent;
      getterGenericCurrent.Body = body;
    }
Esempio n. 12
0
        private IModule CreateNewDll(string assemblyName)
        {
            var host = new PeReader.DefaultHost();
            var core = host.LoadAssembly(host.CoreAssemblySymbolicIdentity);

            var assembly = new Assembly();
            assembly.Name = host.NameTable.GetNameFor(assemblyName);
            assembly.ModuleName = host.NameTable.GetNameFor(assemblyName + ".dll");
            assembly.Kind = ModuleKind.DynamicallyLinkedLibrary;
            assembly.PlatformType = host.PlatformType;
            assembly.TargetRuntimeVersion = core.TargetRuntimeVersion;
            assembly.AssemblyReferences.Add(core);

            foreach (var referencePath in model.ReferencePaths)
            {
                assembly.AssemblyReferences.Add(host.LoadUnitFrom(referencePath) as IAssembly);
            }

            var root = new RootUnitNamespace();
            root.Unit = assembly;
            assembly.UnitNamespaceRoot = root;

            var module = new NamespaceTypeDefinition();
            module.Name = host.NameTable.GetNameFor("<Module>");
            module.IsClass = true;
            module.InternFactory = host.InternFactory;
            module.ContainingUnitNamespace = root;

            assembly.AllTypes.Add(module);

            var rootTypeNamespace = new NestedUnitNamespace();
            rootTypeNamespace.Name = host.NameTable.GetNameFor(assembly.Name.Value);

            root.Members.Add(rootTypeNamespace);

            foreach (var classConfiguration in model.Classes)
            {
                var newClass = new NamespaceTypeDefinition();
                newClass.IsAbstract = classConfiguration.IsAbstract;
                newClass.IsClass = true;
                newClass.BaseClasses = new List<ITypeReference>{ host.PlatformType.SystemObject };
                newClass.IsPublic = true;

                if (classConfiguration.IsStatic)
                {
                    newClass.IsStatic = true;
                    newClass.IsAbstract = true;
                    newClass.IsSealed = true;
                }

                if (!String.IsNullOrEmpty(classConfiguration.Namespace))
                {
                    NestedUnitNamespace classContainer = rootTypeNamespace;
                    var namespaceNames = classConfiguration.Namespace.Split('.');
                    foreach (var namespaceName in namespaceNames)
                    {
                        var existingMembers = classContainer.GetMembersNamed(host.NameTable.GetNameFor(namespaceName), false);
                        var nestedNamespace = new NestedUnitNamespace();
                        foreach (var existing in existingMembers)
                        {
                            if (existing as NestedUnitNamespace != null)
                            {
                                nestedNamespace = existing as NestedUnitNamespace;
                                break;
                            }
                        }

                        nestedNamespace.Name = host.NameTable.GetNameFor(namespaceName);
                        nestedNamespace.ContainingUnitNamespace = classContainer;
                        classContainer.Members.Add(nestedNamespace);
                        classContainer = nestedNamespace;
                    }

                    newClass.ContainingUnitNamespace = classContainer;
                }
                else
                {
                    newClass.ContainingUnitNamespace = rootTypeNamespace;
                }

                newClass.InternFactory = host.InternFactory;
                newClass.Name = host.NameTable.GetNameFor(classConfiguration.Name);
                newClass.Methods = new List<IMethodDefinition>(classConfiguration.Methods.Count);
                newClass.Fields = new List<IFieldDefinition>(classConfiguration.Fields.Count);

                foreach (var methodConfiguration in classConfiguration.Methods)
                {
                    var newMethod = new MethodDefinition();
                    newMethod.Name = host.NameTable.GetNameFor(methodConfiguration.Name);
                    newMethod.IsStatic = methodConfiguration.IsStatic;
                    newMethod.ContainingTypeDefinition = newClass;
                    newMethod.IsCil = true;
                    newMethod.IsHiddenBySignature = true;
                    newMethod.InternFactory = host.InternFactory;
                    newMethod.Visibility = TypeMemberVisibility.Public;
                    newMethod.Type = host.PlatformType.SystemVoid;

                    var newMethodParameters = new List<IParameterDefinition>();
                    foreach (var param in methodConfiguration.Parameters)
                    {
                        var newMethodParameter = new ParameterDefinition();
                        newMethodParameter.ContainingSignature = newMethod;
                        newMethodParameter.Index = (ushort)methodConfiguration.Parameters.IndexOf(param);
                        newMethodParameter.Name = host.NameTable.GetNameFor(param.Key);
                        newMethodParameter.Type = new UnitReflector(host).Get(param.Value);

                        newMethodParameters.Add(newMethodParameter);
                    }

                    newMethod.Parameters = newMethodParameters;

                    var methodBody = new SourceMethodBody(host, null);
                    methodBody.MethodDefinition = newMethod;
                    methodBody.LocalsAreZeroed = true;

                    var block = new BlockStatement();
                    var returnStatement = new ReturnStatement();

                    if (methodConfiguration.ReturnType != null)
                    {
                        newMethod.Type = new UnitReflector(host).Get(methodConfiguration.ReturnType);
                        returnStatement.Expression = new CompileTimeConstant();
                    }

                    if (methodConfiguration.MethodBody != null)
                    {
                        var codeBuilder = new CodeBuilder(host, newMethod.Parameters);
                        methodConfiguration.MethodBody(codeBuilder);

                        foreach (var statement in codeBuilder.Statements)
                        {
                            block.Statements.Add(statement);
                        }
                    }

                    // "Stack must be empty on return from a void method"
                    //returnStatement.Expression = new CompileTimeConstant();
                    //block.Statements.Add(returnStatement);

                    methodBody.Block = block;

                    newMethod.Body = methodBody;

                    newClass.Methods.Add(newMethod);
                }

                foreach (var field in classConfiguration.Fields)
                {
                    var fieldDefinition = new FieldDefinition();
                    fieldDefinition.ContainingTypeDefinition = newClass;
                    fieldDefinition.InternFactory = host.InternFactory;
                    fieldDefinition.IsReadOnly = field.IsReadonly;
                    fieldDefinition.IsStatic = field.IsStatic;
                    fieldDefinition.Name = host.NameTable.GetNameFor(field.Name);
                    fieldDefinition.Type = new UnitReflector(host).Get(field.FieldType);
                    fieldDefinition.Visibility = field.Accessibility.ToTypeMemberVisibility();

                    newClass.Fields.Add(fieldDefinition);
                }

                assembly.AllTypes.Add(newClass);
            }

            using (var dll = File.Create(assemblyName + ".dll"))
            {
                PeWriter.WritePeToStream(assembly, host, dll);
                dll.Close();
            }

            return assembly;
        }
Esempio n. 13
0
 /// <summary>
 /// Visits the specified return statement.
 /// </summary>
 /// <param name="returnStatement">The return statement.</param>
 /// <returns></returns>
 public virtual IStatement Visit(ReturnStatement returnStatement)
 {
     if (returnStatement.Expression != null)
     returnStatement.Expression = Visit(returnStatement.Expression);
       return returnStatement;
 }
Esempio n. 14
0
 /// <summary>
 /// Visits the specified return statement.
 /// </summary>
 /// <param name="returnStatement">The return statement.</param>
 /// <returns></returns>
 protected virtual IStatement DeepCopy(ReturnStatement returnStatement)
 {
     if (returnStatement.Expression != null)
     returnStatement.Expression = this.Substitute(returnStatement.Expression);
       return returnStatement;
 }
Esempio n. 15
0
 /// <summary>
 /// Create the Reset method. Like in CSC, this method contains nothing. 
 /// </summary>
 private void CreateResetMethod(IteratorClosureInformation iteratorClosure) {
   // System.Collections.IEnumerator.Reset: Simply throws an exception
   MethodDefinition reset = new MethodDefinition() {
     Attributes = new List<ICustomAttribute>(1),
     InternFactory = this.host.InternFactory,
     Name = this.host.NameTable.GetNameFor("Reset")
   };
   CustomAttribute debuggerHiddenAttribute = new CustomAttribute() { Constructor = this.DebuggerHiddenCtor };
   reset.Attributes.Add(debuggerHiddenAttribute);
   reset.CallingConvention |= CallingConvention.HasThis;
   reset.Visibility = TypeMemberVisibility.Private;
   reset.ContainingTypeDefinition = iteratorClosure.ClosureDefinition;
   reset.Type = this.host.PlatformType.SystemVoid;
   reset.IsVirtual = true;
   reset.IsNewSlot = true;
   reset.IsHiddenBySignature = true;
   reset.IsSealed = true;
   iteratorClosure.Reset = reset;
   // explicitly state that this reset method implements IEnumerator's reset method. 
   IMethodReference resetImplemented = Dummy.MethodReference;
   foreach (var memref in iteratorClosure.NonGenericIEnumeratorInterface.ResolvedType.GetMembersNamed(this.host.NameTable.GetNameFor("Reset"), false)) {
     IMethodReference mref = memref as IMethodReference;
     if (mref != null) {
       resetImplemented = mref;
       break;
     }
   }
   MethodImplementation resetImp = new MethodImplementation() {
     ContainingType = iteratorClosure.ClosureDefinition,
     ImplementedMethod = resetImplemented,
     ImplementingMethod = reset
   };
   iteratorClosure.ClosureDefinition.ExplicitImplementationOverrides.Add(resetImp);
   List<IStatement> statements = new List<IStatement>();
   ReturnStatement returnCurrent = new ReturnStatement() {
     Expression = null,
     Locations = iteratorClosure.ClosureDefinition.Locations
   };
   statements.Add(returnCurrent);
   BlockStatement block = new BlockStatement() { Statements = statements };
   SourceMethodBody body = new SourceMethodBody(this.host, this.sourceLocationProvider);
   body.LocalsAreZeroed = true;
   body.IsNormalized = true;
   body.Block = block;
   body.MethodDefinition = reset;
   reset.Body = body;
 }
Esempio n. 16
0
 /// <summary>
 /// Visits the specified return statement.
 /// </summary>
 /// <param name="returnStatement">The return statement.</param>
 public override void Visit(IReturnStatement returnStatement)
 {
     ReturnStatement mutableReturnStatement = new ReturnStatement(returnStatement);
     this.resultStatement = this.myCodeCopier.DeepCopy(mutableReturnStatement);
 }
Esempio n. 17
0
    /// <summary>
    /// Create the body of the generic version of GetEnumerator for the iterator closure class.
    /// 
    /// The body's pseudo code. 
    /// {
    ///   if (Thread.CurrentThread.ManagedThreadId == this.l_initialThreadId AND this.state == -2) {
    ///     this.state = 0;
    ///     return this;
    ///   }
    ///   else {
    ///     return a new copy of the iterator instance with state being zero.
    ///   }
    /// }
    /// </summary>
    private BlockStatement GetBodyOfGenericGetEnumerator(IteratorClosureInformation iteratorClosure) {
      var thisDotState = new BoundExpression() {
        Definition = iteratorClosure.StateFieldReference,
        Instance = new ThisReference(),
        Type = this.host.PlatformType.SystemInt32
      };
      var thisDotThreadId = new BoundExpression() {
        Definition = iteratorClosure.InitThreadIdFieldReference,
        Instance = new ThisReference(),
        Type = this.host.PlatformType.SystemInt32
      };
      var currentThreadId = new MethodCall() {
        MethodToCall = ThreadDotManagedThreadId.Getter,
        ThisArgument = ThreadDotCurrentThread,
        Type = this.host.PlatformType.SystemInt32
      };
      var stateEqMinus2 = new Equality() { LeftOperand = thisDotState, RightOperand = new CompileTimeConstant() { Type = this.host.PlatformType.SystemInt32, Value = -2 }, Type = this.host.PlatformType.SystemBoolean };
      var threadIdEqCurrentThreadId = new Equality { LeftOperand = thisDotThreadId, RightOperand = currentThreadId, Type = this.host.PlatformType.SystemBoolean };

      var thisDotStateEq0 = new ExpressionStatement() {
        Expression = new Assignment() {
          Source = new CompileTimeConstant() { Type = this.host.PlatformType.SystemInt32, Value = 0 },
          Target = new TargetExpression() {
            Definition = iteratorClosure.StateFieldReference,
            Instance = new ThisReference(),
            Type = this.host.PlatformType.SystemInt32
          },
          Type = this.host.PlatformType.SystemInt32
        },
      };
      var returnThis = new BlockStatement();
      returnThis.Statements.Add(thisDotStateEq0);
      returnThis.Statements.Add(new ReturnStatement() { Expression = new ThisReference() });
      var returnNew = new BlockStatement();
      var args = new List<IExpression>();
      args.Add(new CompileTimeConstant() { Value = 0, Type = this.host.PlatformType.SystemInt32 });
      var closureInstanceLocalDecl = new LocalDeclarationStatement() {
        LocalVariable = new LocalDefinition() {
          Name = this.host.NameTable.GetNameFor("local0"),
          Type = iteratorClosure.ClosureDefinitionReference
        },
        InitialValue = new CreateObjectInstance() {
          MethodToCall = iteratorClosure.ConstructorReference,
          Arguments = args,
          Type = iteratorClosure.ClosureDefinitionReference
        }
      };
      var returnNewClosureInstance = new ReturnStatement() {
        Expression = new BoundExpression() {
          Instance = null,
          Type = iteratorClosure.ClosureDefinitionReference,
          Definition = closureInstanceLocalDecl.LocalVariable
        }
      };
      returnNew.Statements.Add(closureInstanceLocalDecl);
      if (!method.IsStatic) {
        ExpressionStatement assignThisDotThisToNewClosureDotThis = new ExpressionStatement() {
          Expression = new Assignment() {
            Source = new BoundExpression() {
              Definition = iteratorClosure.ThisFieldReference,
              Instance = new ThisReference(),
              Type = iteratorClosure.ClosureDefinitionReference
            },
            Type = iteratorClosure.ClosureDefinition,
            Target = new TargetExpression() {
              Instance = new BoundExpression() {
                Instance = null,
                Definition = closureInstanceLocalDecl.LocalVariable,
                Type = iteratorClosure.ClosureDefinitionReference
              },
              Definition = iteratorClosure.ThisFieldReference,
              Type = iteratorClosure.ClosureDefinitionReference
            }
          }
        };
        returnNew.Statements.Add(assignThisDotThisToNewClosureDotThis);
      }
      returnNew.Statements.Add(returnNewClosureInstance);

      ConditionalStatement returnThisOrNew = new ConditionalStatement() {
        Condition = new Conditional() {
          Condition = stateEqMinus2,
          ResultIfTrue = threadIdEqCurrentThreadId,
          ResultIfFalse = new CompileTimeConstant() { Type = this.host.PlatformType.SystemBoolean, Value = false },
          Type = this.host.PlatformType.SystemBoolean
        },
        TrueBranch = returnThis,
        FalseBranch = returnNew
      };
      BlockStatement block = new BlockStatement();
      block.Statements.Add(returnThisOrNew);
      return block;
    }
Esempio n. 18
0
 private Statement ParseReturn()
 {
     ReturnStatement result = new ReturnStatement();
       if (this.MethodDefinition.Type.TypeCode != PrimitiveTypeCode.Void)
     result.Expression = this.PopOperandStack();
       return result;
 }
Esempio n. 19
0
 /// <summary>
 /// Visits the specified return statement.
 /// </summary>
 /// <param name="returnStatement">The return statement.</param>
 public override void Visit(IReturnStatement returnStatement)
 {
     ReturnStatement mutableReturnStatement = returnStatement as ReturnStatement;
     if (alwaysMakeACopy || mutableReturnStatement == null) mutableReturnStatement = new ReturnStatement(returnStatement);
     this.resultStatement = this.myCodeMutator.Visit(mutableReturnStatement);
 }