Beispiel #1
0
        public static Method MethodFactory <T> (Identifier methodName, params TypeNode[] methodParameters)
        {
            ArgumentUtility.CheckNotNull("methodName", methodName);
            ArgumentUtility.CheckNotNull("methodParameters", methodParameters);

            TypeNode ct = TypeNodeFactory <T>();

            return(ct.GetMethod(methodName, methodParameters));
        }
Beispiel #2
0
        public static Method MethodFactory(TypeNode targetTypeNode, string methodName, params TypeNode[] methodParameters)
        {
            ArgumentUtility.CheckNotNull("methodName", methodName);
            ArgumentUtility.CheckNotNull("methodParameters", methodParameters);
            ArgumentUtility.CheckNotNull("targetTypeNode", targetTypeNode);

            Identifier methodIdentifier = Identifier.For(methodName);
            Method     targetMethod     = targetTypeNode.GetMethod(methodIdentifier, methodParameters);

            return(targetMethod);
        }
Beispiel #3
0
        private Method GetMethod(TypeNode type, string name, params TypeNode[] argTypes)
        {
            var res = type.GetMethod(Identifier.For(name), argTypes);

            if (res == null)
            {
                Log(new InvalidInteropMessage(null, "can't load required method: " + name));
                throw new ExitException();
            }
            return(res);
        }
 private Method GetMethod(TypeNode type, string name, params TypeNode[] argTypes)
 {
     var res = type.GetMethod(Identifier.For(name), argTypes);
     if (res == null)
     {
         Log(new InvalidInteropMessage(null, "can't load required method: " + name));
         throw new ExitException();
     }
     return res;
 }
Beispiel #5
0
    public virtual Expression ImplicitCoercion(Expression source, TypeNode targetType, TypeViewer typeViewer){
      TypeNode originalTargetType = targetType;
      if (targetType == null || targetType.Name == Looker.NotFound) return source;
      if (source == null) return null;
      //HS D
      if (source is Hole)
          {
              source.Type = targetType;
              return source;
          }
      //HS D
      if (source is LambdaHole)
          {
              if (targetType == SystemTypes.Boolean)
                  source = new LambdaHole(source, new Literal(0), NodeType.Ge, source.SourceContext);                      
              source.Type = targetType;
              return source;
          }
      Literal sourceLit = source as Literal;
      if (sourceLit != null && sourceLit.Value is TypeNode){
        this.HandleError(source, Error.TypeInVariableContext, this.GetTypeName((TypeNode)sourceLit.Value), "class", "variable");
        return null;
      }
      //Ignore parentheses
      if (source.NodeType == NodeType.Parentheses){
        UnaryExpression uex = (UnaryExpression)source;
        uex.Operand = this.ImplicitCoercion(uex.Operand, targetType, typeViewer);
        if (uex.Operand == null) return null;
        uex.Type = uex.Operand.Type;
        return uex;
      }
      bool targetIsNonNullType = this.IsNonNullType(targetType);
      targetType = TypeNode.StripModifier(targetType, SystemTypes.NonNullType);
      targetType = TypeNode.StripModifier(targetType, SystemTypes.NullableType);
      //TODO: handle SkipCheck and EnforceCheck
      //Special case for closure expressions
      if (source.NodeType == NodeType.AnonymousNestedFunction)
        return this.CoerceAnonymousNestedFunction((AnonymousNestedFunction)source, targetType, false, typeViewer);
      TypeNode sourceType = source.Type;
      if (sourceType == null) sourceType = SystemTypes.Object;
      bool sourceIsNonNullType = this.IsNonNullType(source.Type);
      sourceType = TypeNode.StripModifier(sourceType, SystemTypes.NonNullType);
      sourceType = TypeNode.StripModifier(sourceType, SystemTypes.NullableType);
      if (sourceType == SystemTypes.String && !sourceIsNonNullType && source is Literal)
        sourceIsNonNullType = ((Literal)source).Value != null;
      if (this.currentParameter != null && targetType is Reference){
        UnaryExpression uex = source as UnaryExpression;
        if (uex != null){
          if (sourceIsNonNullType && !targetIsNonNullType){
            string ttypeName = this.GetTypeName(targetType);
            string stypeName = this.GetTypeName(source.Type);
            this.HandleError(source, Error.NoImplicitCoercion, stypeName, ttypeName);
            return null;
          }
          if (!sourceIsNonNullType && targetIsNonNullType){
            string ttypeName = this.GetTypeName(targetType);
            string stypeName = this.GetTypeName(source.Type);
            this.HandleError(source, Error.NoImplicitCoercion, stypeName, ttypeName);
            return null;
          }
          if (uex.NodeType == NodeType.OutAddress){
            if ((this.currentParameter.Flags & ParameterFlags.Out) == 0){
              this.currentParameter.Flags |= ParameterFlags.Out;
              string stypeName = this.GetTypeName(sourceType);
              this.currentParameter.Flags &= ~ParameterFlags.Out;
              this.HandleError(source, Error.NoImplicitCoercion, stypeName, this.GetTypeName(targetType));
              return null;
            }
          }else if (uex.NodeType == NodeType.RefAddress){
            if ((this.currentParameter.Flags & ParameterFlags.Out) != 0){
              this.currentParameter.Flags &= ~ParameterFlags.Out;
              string stypeName = this.GetTypeName(sourceType);
              this.currentParameter.Flags |= ParameterFlags.Out;
              this.HandleError(source, Error.NoImplicitCoercion, stypeName, this.GetTypeName(targetType));
              return null;
            }
          }
        }
      }
      Expression result = this.StandardImplicitCoercion(source, sourceIsNonNullType, sourceType, targetIsNonNullType, targetType, originalTargetType, typeViewer);
      if (result != null) return result;
      Method coercion = this.UserDefinedImplicitCoercionMethod(source, sourceType, targetType, true, typeViewer);
      if (coercion != null){
        if (this.IsNullableType(targetType) && this.IsNullableType(sourceType) && !this.IsNullableType(coercion.Parameters[0].Type))
          return this.CoerceWithLiftedCoercion(source, sourceType, targetType, coercion, false, typeViewer);
        ExpressionList args = new ExpressionList(1);
        args.Add(this.ImplicitCoercion(source, coercion.Parameters[0].Type, typeViewer));
        return this.ImplicitCoercion(new MethodCall(new MemberBinding(null, coercion), args, NodeType.Call, coercion.ReturnType, source.SourceContext), targetType, typeViewer);
      }
      if (sourceType == SystemTypes.Type && source is Literal)
        this.HandleError(source, Error.TypeInVariableContext, this.GetTypeName((TypeNode)((Literal)source).Value), "class", "variable");
      else if (this.IsNullableType(sourceType) && this.IsNullableType(targetType) && this.ImplicitCoercionFromTo(this.RemoveNullableWrapper(sourceType), this.RemoveNullableWrapper(targetType))) {
        TypeNode usType = this.RemoveNullableWrapper(sourceType);
        TypeNode utType = this.RemoveNullableWrapper(targetType);

        Local tempSrc = new Local(sourceType);
        Local tempTar = new Local(targetType);
        StatementList statements = new StatementList();
        BlockExpression result1 = new BlockExpression(new Block(statements));
        statements.Add(new AssignmentStatement(tempSrc, source));

        Method hasValue = sourceType.GetMethod(StandardIds.getHasValue);
        Method getValueOrDefault = sourceType.GetMethod(StandardIds.GetValueOrDefault);
        Method ctor = targetType.GetMethod(StandardIds.Ctor, utType);
        Block pushValue = new Block();
        Block done = new Block();

        Expression tempHasValue = new MethodCall(new MemberBinding(new UnaryExpression(tempSrc, NodeType.AddressOf), hasValue), null);
        tempHasValue.Type = SystemTypes.Boolean;
        statements.Add(new Branch(tempHasValue, pushValue));
        statements.Add(new AssignmentStatement(new AddressDereference(new UnaryExpression(tempTar, NodeType.AddressOf), targetType), new Literal(null, CoreSystemTypes.Object)));
        statements.Add(new Branch(null, done));
        statements.Add(pushValue);
        Expression value = new MethodCall(new MemberBinding(new UnaryExpression(tempSrc, NodeType.AddressOf), getValueOrDefault), null);
        value.Type = usType;
        value = this.ImplicitCoercion(value, utType);
        Construct cons = new Construct(new MemberBinding(null, ctor), new ExpressionList(value));
        result1.Type = ctor.DeclaringType;
        statements.Add(new AssignmentStatement(tempTar, cons));
        statements.Add(done);

        statements.Add(new ExpressionStatement(tempTar));
        return result1;
      }else
        this.HandleError(source, Error.NoImplicitCoercion, this.GetTypeName(sourceType), this.GetTypeName(originalTargetType));
      return null;
    }
        public override Expression VisitOldExpression(OldExpression oldExpression)
        {
            if (this.topLevelClosureClass != null)
            {
                // In Closure ==> Create a field

                // Since we're within a closure, we can't create a local to hold the value of the old expression
                // but instead have to create a field for it. That field can be a member of the top-level
                // closure class since nothing mentioned in the old expression (except possibly for the
                // bound variables of enclosing quantifications) should be anything captured from
                // an inner anonymous delegate.

                // BUT, first we have to know if the old expression depends on any of the bound
                // variables of the closures in which it is located. If not, then we can implement
                // it as a scalar and just generate the assignment "closure_class.field := e" for
                // "Old(e)" to take a snapshot of e's value in the prestate. If it does depend on
                // any of the bound variables, then we need to generate a set of for-loops that
                // compute the indices and values of e for each tuple of indices so it can be retrieved
                // (given the indices) in the post-state.
                CollectBoundVariables cbv = new CollectBoundVariables(this.stackOfBoundVariables);
                cbv.VisitExpression(oldExpression.expression);

                SubstituteClosureClassWithinOldExpressions subst = new SubstituteClosureClassWithinOldExpressions(this.closureLocals);
                Expression e = subst.VisitExpression(oldExpression.expression);
                if (cbv.FoundVariables.Count == 0)
                {
                    // Use a scalar for the old variable

                    Local closureLocal;
                    if (!this.closureLocals.TryGetValue(this.topLevelClosureClass, out closureLocal))
                    {
                        Contract.Assume(false, "can't find closure local!");
                    }

                    // Define a scalar

                    var   clTemplate = HelperMethods.Unspecialize(this.topLevelClosureClass);
                    Field f          = new Field(clTemplate,
                                                 null,
                                                 FieldFlags.CompilerControlled | FieldFlags.Public,
                                                 Identifier.For("_old" + oldExpression.expression.UniqueKey.ToString()),
                                                 // unique name for this old expr.
                                                 oldExpression.Type,
                                                 null);

                    clTemplate.Members.Add(f);

                    // now produce properly instantiated field
                    f = (Field)Rewriter.GetMemberInstanceReference(f, this.topLevelClosureClass);

                    // Generate code to store value in prestate

                    this.prestateValuesOfOldExpressions.Statements.Add(
                        new AssignmentStatement(new MemberBinding(closureLocal, f), e));

                    // Return expression to be used in poststate

                    // Return an expression that will evaluate in the poststate to the value of the old
                    // expression in the prestate. This will be this.up.f where "up" is the field C#
                    // generated to point to the instance of the top-level closure class.
                    if (this.PointerToTopLevelClosureClass == null)
                    {
                        // then the old expression occurs in the top-level closure class. Just return "this.f"
                        // where "this" refers to the top-level closure class.
                        return(new MemberBinding(new This(this.currentClosureClass), f));
                    }
                    else
                    {
                        return(new MemberBinding(
                                   new MemberBinding(new This(this.currentClosureClass), this.PointerToTopLevelClosureClass),
                                   f));
                    }
                }
                else
                {
                    // the Old expression *does* depend upon at least one of the bound variable
                    // in a ForAll or Exists expression

                    // Use an indexed variable for the old variable

                    TypeNode oldVariableTypeDomain;

                    // Decide if domain is one-dimensional or not

                    bool oneDimensional = cbv.FoundVariables.Count == 1 && cbv.FoundVariables[0].Type.IsValueType;
                    if (oneDimensional)
                    {
                        // a one-dimensional old-expression can use the index variable directly
                        oldVariableTypeDomain = cbv.FoundVariables[0].Type;
                    }
                    else
                    {
                        oldVariableTypeDomain = SystemTypes.GenericList.GetTemplateInstance(this.module,
                                                                                            SystemTypes.Int32);
                    }

                    TypeNode oldVariableTypeRange = oldExpression.Type;
                    TypeNode oldVariableType      = SystemTypes.GenericDictionary.GetTemplateInstance(this.module,
                                                                                                      oldVariableTypeDomain, oldVariableTypeRange);

                    Local closureLocal;
                    if (!this.closureLocals.TryGetValue(this.topLevelClosureClass, out closureLocal))
                    {
                        Contract.Assume(false, "can't find closure local");
                    }

                    // Define an indexed variable

                    var clTemplate = HelperMethods.Unspecialize(this.topLevelClosureClass);

                    Field f = new Field(clTemplate,
                                        null,
                                        FieldFlags.CompilerControlled | FieldFlags.Assembly,
                                        // can't be private or protected because it needs to be accessed from inner (closure) classes that don't inherit from the class this field is added to.
                                        Identifier.For("_old" + oldExpression.expression.UniqueKey.ToString()),
                                        // unique name for this old expr.
                                        oldVariableType,
                                        null);

                    clTemplate.Members.Add(f);

                    // instantiate f
                    f = (Field)Rewriter.GetMemberInstanceReference(f, closureLocal.Type);

                    // Generate code to initialize the indexed variable

                    Statement init = new AssignmentStatement(
                        new MemberBinding(closureLocal, f),
                        new Construct(new MemberBinding(null, oldVariableType.GetConstructor()), null));

                    this.prestateValuesOfOldExpressions.Statements.Add(init);

                    // Generate code to store values in prestate

                    // Create assignment: this.closure.f[i,j,k,...] = e;

                    Method setItem = oldVariableType.GetMethod(Identifier.For("set_Item"), oldVariableTypeDomain, oldVariableTypeRange);

                    Expression index;
                    if (oneDimensional)
                    {
                        index = cbv.FoundVariables[0];
                    }
                    else
                    {
                        //InstanceInitializer ctor =
                        //  ContractNodes.TupleClass.GetConstructor(SystemTypes.Int32.GetArrayType(1));
                        //Expression index = new Construct(new MemberBinding(null,ctor),new ExpressionList(
                        index = Literal.Null;
                    }

                    MethodCall mc = new MethodCall(new MemberBinding(new MemberBinding(closureLocal, f), setItem),
                                                   new ExpressionList(index, e));

                    Statement stat = new ExpressionStatement(mc);

                    List <Local>     locals   = new List <Local>(this.stackOfBoundVariables.Count);
                    TrivialHashtable paramMap = new TrivialHashtable();

                    // Generate a local for each bound variable to use in for-loop

                    foreach (Variable v in this.stackOfBoundVariables)
                    {
                        Local l = new Local(Identifier.Empty, v.Type);
                        paramMap[v.UniqueKey] = l;
                        locals.Add(l);
                    }

                    // Substitute locals for bound variables in old expression *AND* in inner loop bounds

                    SubstituteParameters sps = new SubstituteParameters(paramMap, this.stackOfBoundVariables);
                    sps.Visit(stat);

                    // Create nested for-loops around assignment

                    // keep track of when the first variable is used (from innermost to outermost)
                    // as soon as the first one is needed because the old expression depends on it,
                    // then keep all enclosing loops. It would be possible to keep only those where
                    // the necessary loops have loop bounds that depend on an enclosing loop, but I
                    // haven't calculated that, so just keep them all. For instance, if the old expression
                    // depends on j and the loops are "for i,0,n" and inside that "for j,0,i", then need
                    // both loops. If the inner loop bounds were 0 and n, then wouldn't need the outer
                    // loop.
                    bool usedAVariable = false;

                    for (int i = this.stackOfBoundVariables.Count - 1; 0 <= i; i--)
                    {
                        if (!usedAVariable &&
                            !cbv.FoundVariables.Contains(this.stackOfBoundVariables[i]))
                        {
                            continue;
                        }
                        usedAVariable = true;
                        Expression lowerBound = new Duplicator(this.module, this.currentClosureClass).VisitExpression(
                            this.stackOfMethods[i].Operands[0]);

                        lowerBound = subst.VisitExpression(lowerBound);
                        lowerBound = sps.VisitExpression(lowerBound);

                        Expression upperBound = new Duplicator(this.module, this.currentClosureClass).VisitExpression(
                            this.stackOfMethods[i].Operands[1]);

                        upperBound = subst.VisitExpression(upperBound);
                        upperBound = sps.VisitExpression(upperBound);

                        stat = RewriteHelper.GenerateForLoop(locals[i], lowerBound, upperBound, stat);
                    }

                    this.prestateValuesOfOldExpressions.Statements.Add(stat);

                    // Return expression to be used in poststate

                    Method getItem = oldVariableType.GetMethod(Identifier.For("get_Item"), oldVariableTypeDomain);
                    if (oneDimensional)
                    {
                        index = cbv.FoundReferences[0];
                    }
                    else
                    {
                        //InstanceInitializer ctor =
                        //  ContractNodes.TupleClass.GetConstructor(SystemTypes.Int32.GetArrayType(1));
                        //Expression index = new Construct(new MemberBinding(null,ctor),new ExpressionList(
                        index = Literal.Null;
                    }

                    // Return an expression that will evaluate in the poststate to the value of the old
                    // expression in the prestate. This will be this.up.f[i,j,k,...] where "up" is the field C#
                    // generated to point to the instance of the top-level closure class.
                    MemberBinding thisDotF;

                    if (this.PointerToTopLevelClosureClass == null)
                    {
                        // then the old expression occurs in the top-level closure class. Just return "this.f"
                        // where "this" refers to the top-level closure class.
                        Contract.Assume(f != null);

                        thisDotF = new MemberBinding(new This(clTemplate), HelperMethods.Unspecialize(f));
                    }
                    else
                    {
                        thisDotF = new MemberBinding(
                            new MemberBinding(new This(clTemplate), this.PointerToTopLevelClosureClass),
                            f);
                    }

                    return(new MethodCall(new MemberBinding(thisDotF, getItem), new ExpressionList(index)));
                }
            }
            else
            {
                // Not in closure ==> Create a local variable

                Local l = GetLocalForOldExpression(oldExpression);

                // Make sure local can be seen in the debugger (for the entire method, unfortunately)

                if (currentMethod.LocalList == null)
                {
                    currentMethod.LocalList = new LocalList();
                }

                currentMethod.LocalList.Add(l);
                currentMethod.Body.HasLocals = true;

                this.prestateValuesOfOldExpressions.Statements.Add(new AssignmentStatement(l, oldExpression.expression));

                // Return an expression that will evaluate in the poststate to the value of the old
                // expression in the prestate. When we're not in a closure, this is just the local
                // itself.
                return(l);
            }
        }
Beispiel #7
0
 public static Expression BindPseudoMember(Expression qualifier, Identifier identifier)
 {
     if (qualifier != null)
     {
         SourceContext fullSourceContext = identifier.SourceContext;
         if (qualifier.SourceContext.Document != null)
         {
             fullSourceContext.StartPos = qualifier.SourceContext.StartPos;
         }
         TypeNode qualifierType = qualifier.Type;
         if (identifier.UniqueIdKey == Cci.Runtime.IsConsistentId.UniqueIdKey)
         {
             if (qualifier is Base)
             {
                 if (qualifierType != null)
                 {
                     qualifierType = TypeNode.StripModifiers(qualifierType);
                     return(new MethodCall(new MemberBinding(null, SystemTypes.Guard.GetMethod(Identifier.For("FrameIsExposable"), SystemTypes.Object, SystemTypes.Type)),
                                           new ExpressionList(qualifier, new UnaryExpression(new Literal(qualifierType, SystemTypes.Type), NodeType.Typeof, OptionalModifier.For(SystemTypes.NonNullType, SystemTypes.Type))), NodeType.Call, SystemTypes.Boolean, fullSourceContext));
                 }
             }
             else
             {
                 return(new MethodCall(
                            new MemberBinding(null, SystemTypes.Guard.GetMethod(Cci.Runtime.IsConsistentId,
                                                                                OptionalModifier.For(SystemTypes.NonNullType, SystemTypes.Object))),
                            new ExpressionList(qualifier), NodeType.Call, SystemTypes.Boolean, fullSourceContext));
             }
         }
         if (identifier.UniqueIdKey == Cci.Runtime.IsPeerConsistentId.UniqueIdKey)
         {
             return(new MethodCall(
                        new MemberBinding(null, SystemTypes.Guard.GetMethod(Cci.Runtime.IsPeerConsistentId,
                                                                            OptionalModifier.For(SystemTypes.NonNullType, SystemTypes.Object))),
                        new ExpressionList(qualifier), NodeType.Call, SystemTypes.Boolean, fullSourceContext));
         }
         if (qualifierType != null)
         {
             qualifierType = TypeNode.StripModifiers(qualifierType);
             if (identifier.UniqueIdKey == Cci.Runtime.IsVirtualConsistentId.UniqueIdKey)
             {
                 if (qualifier is This || qualifier is ImplicitThis)
                 {
                     SourceContext sc = identifier.SourceContext;
                     identifier = Cci.Runtime.IsExposableId;
                     identifier.SourceContext = sc;
                 }
             }
             TypeNode guard = SystemTypes.Guard;
             if (guard != null)
             {
                 Property property = guard.GetProperty(identifier);
                 if (property != null && property.IsPublic && !property.IsStatic)
                 {
                     Method method = guard.GetMethod(Identifier.For("Frame" + identifier.Name), SystemTypes.Object, SystemTypes.Type);
                     if (method != null && method.IsPublic && method.IsStatic)
                     {
                         return
                             (new MethodCall(
                                  new MemberBinding(null, method),
                                  new ExpressionList(qualifier, new UnaryExpression(new Literal(qualifierType, SystemTypes.Type), NodeType.Typeof, OptionalModifier.For(SystemTypes.NonNullType, SystemTypes.Type))),
                                  NodeType.Call,
                                  method.ReturnType,
                                  fullSourceContext));
                     }
                 }
             }
         }
         {
             Method method = SystemTypes.Guard.GetMethod(identifier, SystemTypes.Object);
             if (method != null && method.IsPublic && method.IsStatic && method.ReturnType != SystemTypes.Void)
             {
                 return(new MethodCall(new MemberBinding(null, method), new ExpressionList(qualifier), NodeType.Call, method.ReturnType, fullSourceContext));
             }
         }
     }
     return(null);
 }
Beispiel #8
0
        public static void Initialize()
        {
            TypeNode RuntimeHelpers = SystemTypes.SystemAssembly.GetType(Identifier.For("System.Runtime.CompilerServices"), Identifier.For("RuntimeHelpers"));

            if (RuntimeHelpers != null)
            {
                Runtime.GetOffsetToStringData = RuntimeHelpers.GetMethod(Identifier.For("get_OffsetToStringData"));
            }
            Runtime.Combine               = SystemTypes.Delegate.GetMethod(StandardIds.Combine, SystemTypes.Delegate, SystemTypes.Delegate);
            Runtime.CreateInstance        = SystemTypes.Activator.GetMethod(StandardIds.CreateInstance, SystemTypes.Type);
            Runtime.GenericCreateInstance = SystemTypes.Activator.GetMethod(StandardIds.CreateInstance);
            Runtime.GetCurrent            = SystemTypes.IEnumerator.GetMethod(StandardIds.getCurrent);
            Runtime.GetEnumerator         = SystemTypes.IEnumerable.GetMethod(StandardIds.GetEnumerator);
            Runtime.GetType               = SystemTypes.Object.GetMethod(Identifier.For("GetType"));
            Runtime.GetTypeFromHandle     = SystemTypes.Type.GetMethod(Identifier.For("GetTypeFromHandle"), SystemTypes.RuntimeTypeHandle);
            Runtime.IDisposableDispose    = SystemTypes.IDisposable.GetMethod(StandardIds.Dispose);
            Runtime.IsInterned            = SystemTypes.String.GetMethod(StandardIds.IsInterned, SystemTypes.String);
            Runtime.MemberwiseClone       = SystemTypes.Object.GetMethod(StandardIds.MemberwiseClone);
            Runtime.MonitorEnter          = SystemTypes.Monitor.GetMethod(StandardIds.Enter, SystemTypes.Object);
            Runtime.MonitorExit           = SystemTypes.Monitor.GetMethod(StandardIds.Exit, SystemTypes.Object);
            Runtime.MoveNext              = SystemTypes.IEnumerator.GetMethod(StandardIds.MoveNext);
            Runtime.ObjectToString        = SystemTypes.Object.GetMethod(StandardIds.ToString);
            Runtime.Reset  = SystemTypes.IEnumerator.GetMethod(StandardIds.Reset);
            Runtime.Remove = SystemTypes.Delegate.GetMethod(StandardIds.Remove, SystemTypes.Delegate, SystemTypes.Delegate);
            Runtime.StringConcatObjects = SystemTypes.String.GetMethod(StandardIds.Concat, SystemTypes.Object, SystemTypes.Object);
            Runtime.StringConcatStrings = SystemTypes.String.GetMethod(StandardIds.Concat, SystemTypes.String, SystemTypes.String);
            Runtime.StringEquals        = SystemTypes.String.GetMethod(StandardIds.Equals, SystemTypes.String, SystemTypes.String);
            InstanceInitializer dbgConstr = null;

            if (SystemTypes.DebuggableAttribute != null)
            {
                if (SystemTypes.DebuggingModes != null)
                {
                    dbgConstr = SystemTypes.DebuggableAttribute.GetConstructor(SystemTypes.DebuggingModes);
                }
                else
                {
                    dbgConstr = SystemTypes.DebuggableAttribute.GetConstructor(SystemTypes.Boolean, SystemTypes.Boolean);
                }
            }
            MemberBinding debuggableAttributeCtor = null;

            if (dbgConstr != null)
            {
                debuggableAttributeCtor = new MemberBinding(null, dbgConstr);
            }
            if (debuggableAttributeCtor != null)
            {
                Literal trueLit  = new Literal(true, SystemTypes.Boolean);
                Literal falseLit = new Literal(false, SystemTypes.Boolean);
                Runtime.Debuggable             = new AttributeNode();
                Runtime.Debuggable.Constructor = debuggableAttributeCtor; //TODO: will need to fix this up in the case where the type is compiled from source
                Runtime.Debuggable.Expressions = new ExpressionList(2);
                if (SystemTypes.DebuggingModes != null)
                {
                    Runtime.Debuggable.Expressions.Add(new Literal(0x107, SystemTypes.DebuggingModes));
                }
                else
                {
                    Runtime.Debuggable.Expressions.Add(trueLit);
                    Runtime.Debuggable.Expressions.Add(trueLit);
                }
                Runtime.OptimizedButDebuggable             = new AttributeNode();
                Runtime.OptimizedButDebuggable.Constructor = debuggableAttributeCtor;
                Runtime.OptimizedButDebuggable.Expressions = new ExpressionList(2);
                if (SystemTypes.DebuggingModes != null)
                {
                    Runtime.OptimizedButDebuggable.Expressions.Add(new Literal(0x007, SystemTypes.DebuggingModes));
                }
                else
                {
                    Runtime.OptimizedButDebuggable.Expressions.Add(trueLit);
                    Runtime.OptimizedButDebuggable.Expressions.Add(falseLit);
                }
                Runtime.OptimizedWithPDBOnly             = new AttributeNode();
                Runtime.OptimizedWithPDBOnly.Constructor = debuggableAttributeCtor;
                Runtime.OptimizedWithPDBOnly.Expressions = new ExpressionList(2);
                if (SystemTypes.DebuggingModes != null)
                {
                    Runtime.OptimizedWithPDBOnly.Expressions.Add(new Literal(0x006, SystemTypes.DebuggingModes));
                }
                else
                {
                    Runtime.OptimizedWithPDBOnly.Expressions.Add(falseLit);
                    Runtime.OptimizedWithPDBOnly.Expressions.Add(falseLit);
                }
            }
        }