private void CopyMissingMembers()
        {
            Contract.Ensures(this.duplicatedMembers != null);

            this.duplicatedMembers = new TrivialHashtable(this.toBeDuplicatedMembers.Count*2);
            foreach (var missing in this.toBeDuplicatedMembers)
            {
                Contract.Assume(missing.Value != null);
                Contract.Assume(missing.Key != null);

                InstanceInitializer ctor = missing.Key as InstanceInitializer;
                if (ctor != null && ctor.ParameterCount == 0) continue;

                var targetType = missing.Value;

                Trace("COPYOOB: copying {0} to {1}", missing.Key.FullName, targetType.FullName);

                this.Duplicator.TargetType = targetType;

                var dup = (Member) this.Duplicator.Visit(missing.Key);

                targetType.Members.Add(dup);
                duplicatedMembers[missing.Key.UniqueKey] = missing;
            }
        }
示例#2
0
 /// <param name="module">The module into which the duplicate IR will be grafted.</param>
 /// <param name="type">The type into which the duplicate Member will be grafted. Ignored if entire type, or larger unit is duplicated.</param>
 public Duplicator(Module/*!*/ module, TypeNode type)
 {
     this.TargetModule = module;
     this.TargetType = this.OriginalTargetType = type;
     this.DuplicateFor = new TrivialHashtable();
     this.TypesToBeDuplicated = new TrivialHashtable();
     //^ base();
 }
示例#3
0
 internal Checker(ErrorHandler errorHandler, TypeSystem typeSystem, TrivialHashtable scopeFor, // LJW: added scopeFor
     TrivialHashtable ambiguousTypes, TrivialHashtable referencedLabels)
     : base(errorHandler, typeSystem, scopeFor, ambiguousTypes, referencedLabels)
 {
     this.validChooses = new Hashtable();
     this.validMethodCalls = new Hashtable();
     this.validSetOperations = new Hashtable();
     this.validSelfAccess = new Hashtable();
 }
示例#4
0
 internal BBSplitter(Splicer splicer)
 {
     this.splicer = splicer;
     branchTargets = new TrivialHashtable();
     blockList = new List<BasicBlock>();
     continuationStack = new Stack<BasicBlock>();
     scopeStack = new Stack<Scope>();
     handlerBlocks = new Stack<BasicBlock>();
 }
示例#5
0
 public Splicer(CompilerParameters options, TrivialHashtable referencedLabels, Hashtable exceptionNames)
 {
     this.options = options;
     this.referencedLabels = referencedLabels;
     this.exceptionNames = exceptionNames;
     choosableTypes = new Hashtable();
     sourceDocuments = new Hashtable();
     ZingCompilerOptions zOptions = (ZingCompilerOptions)options;
     if (zOptions.DumpLabels)
         labelString = new System.Text.StringBuilder();
 }
        public AbbreviationDuplicator(Method sourceMethod, Method targetMethod, ContractNodes contractNodes,
            Method abbreviation, Expression targetObject, ExpressionList actuals)
            : base(targetMethod.DeclaringType.DeclaringModule, sourceMethod, targetMethod, contractNodes, false)
        {
            this.targetObject = targetObject;
            this.abbreviation = abbreviation;
            this.actuals = actuals;

            this.localsInActuals = new TrivialHashtable();

            PopulateLocalsInActuals();
        }
示例#7
0
 internal InstructionParser(Reader/*!*/ reader, Method/*!*/ method, int methodIndex, int RVA)
   : base (reader, method, methodIndex, RVA){
   this.ehMap = new TrivialHashtable();
 }
示例#8
0
 public Looker(Scope scope, Cci.ErrorHandler errorHandler, TrivialHashtable scopeFor)
   : this(scope, errorHandler, scopeFor, null, null){
   this.alreadyReported[StandardIds.Var.UniqueIdKey] = true;
 }
示例#9
0
        // Ensures:
        //  Preconditions != null
        //  && ForAll{Requires r in Preconditions;
        //              r.Condition is BlockExpression
        //              && r.Condition.Type == Void
        //              && IsClump(r.Condition.Block.Statements)
        //  Postconditions != null
        //  && ForAll{Ensures e in Posconditions;
        //              e.PostCondition is BlockExpression
        //              && e.PostCondition.Type == Void
        //              && IsClump(e.PostCondition.Block.Statements)
        //  (In addition, each Requires is a RequiresPlain when the contract
        //   call is Contract.Requires and is a RequiresOtherwise when the
        //   contract call is Critical.Requires. In the latter case, the
        //   ThrowException is filled in correctly.)
        //       
        /// <summary>
        /// 
        /// </summary>
        /// <param name="method"></param>
        /// <param name="Preconditions"></param>
        /// <param name="Postconditions"></param>
        /// <param name="Validations"></param>
        /// <param name="contractInitializerBlock">used to store extra closure initializations from abbrevs and validators</param>
        public void CheapAndDirty(
            Method method,
            ref RequiresList Preconditions,
            ref EnsuresList Postconditions,
            ref RequiresList Validations,
            ref EnsuresList modelPostConditions,
            Block contractInitializerBlock,
            ref HelperMethods.StackDepthTracker dupStackTracker)
        {
            if (this.verbose)
            {
                Console.WriteLine("Method : " + method.FullName);
            }

            if (method == null || method.Body == null || method.Body.Statements == null ||
                method.Body.Statements.Count <= 0)
            {
                return;
            }

            Block methodBody = method.Body;
            int n = methodBody.Statements.Count;
            int beginning = 0;

            while (beginning < n && methodBody.Statements[beginning] is PreambleBlock)
            {
                beginning++;
            }

            int lastBlockContainingContract;
            int lastStatementContainingContract;

            bool anyContractCall = FindLastBlockWithContracts(methodBody.Statements, beginning,
                out lastBlockContainingContract, out lastStatementContainingContract);

            // Make sure any locals in the contracts are disjoint from the locals in the rest of the body

            // can use the same one throughout
            GatherLocals gatherLocals = new GatherLocals();

            SourceContext lastContractSourceContext = method.SourceContext;
            if (!anyContractCall)
            {
                if (this.verbose)
                {
                    Console.WriteLine("\tNo contracts found");
                }

                // still need to check for bad other contract calls in method body

                goto CheckBody;
            }

            Block lastBlock = methodBody.Statements[lastBlockContainingContract] as Block;
            lastContractSourceContext = lastBlock.SourceContext;

            // probably not a good context, what to do if one can't be found?
            if (lastBlock.Statements != null && 0 <= lastStatementContainingContract &&
                lastStatementContainingContract < lastBlock.Statements.Count)
            {
                lastContractSourceContext = lastBlock.Statements[lastStatementContainingContract].SourceContext;
            }

            // Make sure contract section is not in any try-catch region

            TrivialHashtable<int> block2Index = new TrivialHashtable<int>(methodBody.Statements.Count);
            for (int i = 0, nn = methodBody.Statements.Count; i < nn; i++)
            {
                if (methodBody.Statements[i] == null) continue;
                block2Index[methodBody.Statements[i].UniqueKey] = i;
            }
            // Check each exception handler and see if any overlap with the contract section
            for (int i = 0, nn = method.ExceptionHandlers == null ? 0 : method.ExceptionHandlers.Count; i < nn; i++)
            {
                ExceptionHandler eh = method.ExceptionHandlers[i];
                if (eh == null) continue;

                if (((int) block2Index[eh.BlockAfterTryEnd.UniqueKey]) < beginning ||
                    lastBlockContainingContract < ((int) block2Index[eh.TryStartBlock.UniqueKey]))
                {
                    continue; // can't overlap
                }

                this.HandleError(method, 1024, "Contract section within try block.", lastContractSourceContext);
                return;
            }

            // Extract <beginning,0> to <lastBlockContainingContract,lastStatmentContainingContract>
            StatementList contractClump = HelperMethods.ExtractClump(methodBody.Statements, beginning, 0,
                lastBlockContainingContract, lastStatementContainingContract);

            // Look for bad stuff

            BadStuff(method, contractClump, lastContractSourceContext);

            // Make sure that the entire contract section is closed.
            if (!CheckClump(method, gatherLocals, currentMethodSourceContext, new Block(contractClump)))
            {
                return;
            }

            // Checking that had the side effect of populating the hashtable, but now each contract will be individually visited.
            // That process needs to start with a fresh table.
            gatherLocals.Locals = new TrivialHashtable();

            Preconditions = new RequiresList();
            Postconditions = new EnsuresList();
            Validations = new RequiresList();
            modelPostConditions = new EnsuresList();

            if (!ExtractFromClump(
                contractClump, method, gatherLocals, Preconditions, Postconditions, Validations,
                modelPostConditions, lastContractSourceContext, method, contractInitializerBlock, ref dupStackTracker))
            {
                return;
            }

            CheckBody:

            // Check "real" method body for use of any locals used in contracts

            //      var checkMethodBody = new CheckForBadContractStuffInMethodBody(gatherLocals, this.CallErrorFound, method);
            var checkMethodBody = new CheckLocals(gatherLocals);
            checkMethodBody.Visit(methodBody);

            if (!this.fSharp && checkMethodBody.reUseOfExistingLocal != null)
            {
                SourceContext sc = lastContractSourceContext;

                this.HandleError(method, 1025,
                    "After contract block, found use of local variable '" +
                    checkMethodBody.reUseOfExistingLocal.Name.Name + "' defined in contract block", sc);
            }
        }
示例#10
0
 public SubstituteParameters(TrivialHashtable map, List<Parameter> parameters) {
   this.map = map;
   this.parameters = parameters;
 }
示例#11
0
 // LJW: added typeSystem parameter
 internal Looker(Scope scope, Microsoft.Zing.ErrorHandler errorHandler, TrivialHashtable scopeFor, TypeSystem typeSystem)
     : this(scope, errorHandler, scopeFor, typeSystem, null, null, null)
 {
 }
示例#12
0
 private bool CheckDeterministic(BitSet bitset, NamedNode[] namedTerminals, ValidationState context) {
   TrivialHashtable nodeTable = new TrivialHashtable();
   for (int i = 0; i < namedTerminals.Length; i++) {
     if (bitset[i]) {
       NamedNode node = namedTerminals[i];
       Identifier n = node.Name;
       if (n != Identifier.Empty) {
         if (nodeTable[n.UniqueKey] == null) {
           nodeTable[n.UniqueKey] = n;
         }
         else {
           Node offendingNode = (node.Member is Method) ? node.Name : node.Member.Name;
           context.HandleError(this.RootNode, offendingNode, Error.NonDeterministic, context.Name.ToString(), n.Name.ToString());
           return false;
         }
       }
     }
   }
   return true;
 }
示例#13
0
 internal Checker(SpecSharpCompilation ssCompilation, ErrorHandler errorHandler, TypeSystem typeSystem, TrivialHashtable scopeFor, TrivialHashtable ambiguousTypes, TrivialHashtable referencedLabels)
   : base(errorHandler, typeSystem, scopeFor, ambiguousTypes, referencedLabels) {
   this.ssCompilation = ssCompilation;
 }
示例#14
0
 public virtual Method GetExplicitCoercionFromMethod(TypeNode sourceType)
 {
     if(sourceType == null)
         return null;
     Method result = null;
     if(this.explicitCoercionFromTable != null)
         result = (Method)this.explicitCoercionFromTable[sourceType.UniqueKey];
     if(result == TypeNode.MethodDoesNotExist)
         return null;
     if(result != null)
         return result;
     lock(this)
     {
         if(this.explicitCoercionFromTable != null)
             result = (Method)this.explicitCoercionFromTable[sourceType.UniqueKey];
         if(result == TypeNode.MethodDoesNotExist)
             return null;
         if(result != null)
             return result;
         MemberList coercions = this.ExplicitCoercionMethods;
         for(int i = 0, n = coercions.Count; i < n; i++)
         {
             Method m = (Method)coercions[i];
             if(sourceType == m.Parameters[0].Type) { result = m; break; }
         }
         if(this.explicitCoercionFromTable == null)
             this.explicitCoercionFromTable = new TrivialHashtable();
         if(result == null)
             this.explicitCoercionFromTable[sourceType.UniqueKey] = TypeNode.MethodDoesNotExist;
         else
             this.explicitCoercionFromTable[sourceType.UniqueKey] = result;
         return result;
     }
 }
示例#15
0
 internal TypeNode/*!*/ GetModified(TypeNode/*!*/ modifierType, bool optionalModifier)
 {
     if(this.modifierTable == null)
         this.modifierTable = new TrivialHashtable();
     TypeNode result = (TypeNode)this.modifierTable[modifierType.UniqueKey];
     if(result != null)
         return result;
     result = optionalModifier ? (TypeNode)new OptionalModifier(modifierType, this) : (TypeNode)new RequiredModifier(modifierType, this);
     this.modifierTable[modifierType.UniqueKey] = result;
     return result;
 }
示例#16
0
 public virtual void ResolveSymbolTable(Compilation/*!*/ parsedCompilation, ErrorNodeList/*!*/ errors, out TrivialHashtable scopeFor){
   scopeFor = new TrivialHashtable();
   if (parsedCompilation == null) { Debug.Assert(false); return; }
   if (errors == null){Debug.Assert(false); return;}
   Scoper scoper = new Scoper(scopeFor);
   scoper.currentModule = parsedCompilation.TargetModule;
   scoper.VisitCompilation(parsedCompilation);
   ErrorHandler errorHandler = new ErrorHandler(errors);
   TrivialHashtable ambiguousTypes = new TrivialHashtable();
   TrivialHashtable referencedLabels = new TrivialHashtable();
   Looker looker = new Looker(null, errorHandler, scopeFor, ambiguousTypes, referencedLabels);
   // begin change by drunje
   SpecSharpCompilerOptions options = parsedCompilation.CompilerParameters as SpecSharpCompilerOptions;
   if (options != null)
     looker.AllowPointersToManagedStructures = options.AllowPointersToManagedStructures;
   // end change by drunje
   looker.currentAssembly = (looker.currentModule = parsedCompilation.TargetModule) as AssemblyNode;
   looker.VisitCompilation(parsedCompilation);
 }
示例#17
0
        //!EFW
        /// <summary>
        /// Load target framework settings and assembly details
        /// </summary>
        /// <param name="platformType">The platform type</param>
        /// <param name="version">The framework version</param>
        public static void SetFrameworkInformation(string platformType, string version)
        {
            var fs = Sandcastle.Core.Frameworks.FrameworkDictionary.AllFrameworks.FrameworkMatching(
                platformType, new Version(version), true);

            if(fs == null)
                throw new InvalidOperationException(String.Format("Unable to locate information for the " +
                    "framework version '{0} {1}' or a suitable redirected version on this system",
                    platformType, version));

            var coreLocation = fs.AssemblyLocations.First(l => l.IsCoreLocation);

            if(coreLocation == null)
                throw new InvalidOperationException(String.Format("A core framework location has not been " +
                    "defined for the framework '{0} {1}'", platformType, version));

            TargetPlatform.Platform = fs.Platform;
            TargetPlatform.TargetVersion = fs.Version;
            TargetPlatform.TargetRuntimeVersion = "v" + fs.Version.ToString();
            TargetPlatform.GenericTypeNamesMangleChar = '`';
            TargetPlatform.PlatformAssembliesLocation = coreLocation.Path;

            // Set references to the common core framework assemblies
            var ad = fs.FindAssembly("mscorlib");

            if(ad != null)
                SystemAssemblyLocation.Location = ad.Filename;

            ad = fs.FindAssembly("System.Data");

            if(ad != null)
                SystemDataAssemblyLocation.Location = ad.Filename;

            ad = fs.FindAssembly("System.Xml");

            if(ad != null)
                SystemXmlAssemblyLocation.Location = ad.Filename;

            // Load references to all the other framework assemblies
            var allAssemblies = fs.AllAssemblies.ToList();

            TrivialHashtable assemblyReferenceFor = new TrivialHashtable(allAssemblies.Count);

            // Loading mscorlib causes a reset of the reference cache and other info so we must ignore it.
            foreach(var asm in allAssemblies)
                if(!asm.Name.Equals("mscorlib", StringComparison.OrdinalIgnoreCase) && File.Exists(asm.Filename))
                {
                    AssemblyReference aref = new AssemblyReference(asm.ToString());
                    aref.Location = asm.Filename;
                    assemblyReferenceFor[Identifier.For(asm.Name).UniqueIdKey] = aref;
                }

            TargetPlatform.assemblyReferenceFor = assemblyReferenceFor;
        }
示例#18
0
 public AllElementsContentValidator(Member mixed, int size, bool isEmptiable) : base(mixed == null ? XmlSchemaContentType.ElementOnly : XmlSchemaContentType.Mixed, mixed) {
   elements = new TrivialHashtable(size);
   isRequired = new BitSet(size);
   namedNodes = new ArrayList();
   this.isEmptiable = isEmptiable;
 }
示例#19
0
 internal Looker(Scope scope, ErrorHandler errorHandler, TrivialHashtable scopeFor, TypeSystem typeSystem, TrivialHashtable ambiguousTypes,  // LJW: added typeSystem parameter
     TrivialHashtable referencedLabels, Hashtable exceptionNames)
     : base(scope, errorHandler, scopeFor, typeSystem, ambiguousTypes, referencedLabels)
 {
     this.exceptionNames = exceptionNames;
 }
示例#20
0
 private TypeUnion GetTypeUnionForChoiceTypes(Member mem) {
   TrivialHashtable tuForMember = this.TypeUnionForMember;
   if (tuForMember == null) this.TypeUnionForMember = tuForMember = new TrivialHashtable();
   TypeUnion tu = (TypeUnion)tuForMember[mem.UniqueKey];
   if (tu != null) return tu;
   // why is tu rebuilt when member is not found?
   AttributeList attributes = mem.Attributes;
   int n = attributes == null ? 0 : attributes.Length;
   TypeNodeList types = new TypeNodeList(n);
   for (int i = 0; i < n; i++) {
     AttributeNode attr = attributes[i];
     if (attr == null) continue;
     MemberBinding mb = attr.Constructor as MemberBinding;
     if (mb == null) continue;
     if (mb.BoundMember.DeclaringType == Runtime.XmlElementAttributeClass){
       TypeNode t = SchemaElementDecl.GetAttrType(attr, 1, SchemaElementDecl.TypeId);
       if (t != null) types.Add(t);
     }
   }
   tuForMember[mem.UniqueKey] = tu = TypeUnion.For(types, mem.DeclaringType.DeclaringModule);
   return tu;
 }
示例#21
0
    public override Expression VisitOldExpression(OldExpression oldExpression) {
      if (this.topLevelClosureClass != null) {
        #region 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) {
          #region 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!");
          }
          #region 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);
          #endregion
          #region Generate code to store value in prestate
          this.prestateValuesOfOldExpressions.Statements.Add(new AssignmentStatement(new MemberBinding(closureLocal, f), e));
          #endregion
          #region 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);
          }
          #endregion
          #endregion
        } else {
          // the Old expression *does* depend upon at least one of the bound variable
          // in a ForAll or Exists expression
          #region Use an indexed variable for the old variable
          TypeNode oldVariableTypeDomain;
          #region 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);
          }
          #endregion
          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");
          }
          #region 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);
          #endregion
          #region 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);
          #endregion
          #region Generate code to store values in prestate
          #region 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);
          #endregion
          List<Local> locals = new List<Local>(this.stackOfBoundVariables.Count);
          TrivialHashtable paramMap = new TrivialHashtable();
          #region 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);
          }
          #endregion
          #region Substitute locals for bound variables in old expression *AND* in inner loop bounds
          SubstituteParameters sps = new SubstituteParameters(paramMap, this.stackOfBoundVariables);
          sps.Visit(stat);
          #endregion
          #region 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);
          }
          #endregion
          this.prestateValuesOfOldExpressions.Statements.Add(stat);
          #endregion
          #region 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));
          #endregion
          #endregion
        }
        #endregion
      } else {
        #region Not in closure ==> Create a local variable
        Local l = GetLocalForOldExpression(oldExpression);
        #region 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;
        #endregion
        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;
        #endregion
      }
    }
示例#22
0
    public override void CompileParseTree(Compilation compilation, ErrorNodeList errorNodes){
      if (compilation == null || compilation.CompilationUnits == null || compilation.TargetModule == null){Debug.Assert(false); return;}
      if (compilation.CompilationUnits.Count == 0) return;
      TrivialHashtable ambiguousTypes = new TrivialHashtable();
      TrivialHashtable referencedLabels = new TrivialHashtable();
      TrivialHashtable scopeFor = new TrivialHashtable(64);
      ErrorHandler errorHandler = new ErrorHandler(errorNodes);
      SpecSharpCompilation ssCompilation = new SpecSharpCompilation();
      SpecSharpCompilerOptions options = (SpecSharpCompilerOptions)compilation.CompilerParameters;

      //Attach scopes to namespaces and types so that forward references to base types can be looked up in the appropriate namespace scope
      Scoper scoper = new Scoper(scopeFor);
      scoper.VisitCompilation(compilation);
      scoper = null;

      if (options.NoStandardLibrary && compilation.TargetModule is AssemblyNode) {
        if (compilation.TargetModule.IsValidTypeName(StandardIds.System, StandardIds.CapitalObject)) {
          SystemAssemblyLocation.ParsedAssembly = (AssemblyNode)compilation.TargetModule;
          SystemCompilerRuntimeAssemblyLocation.ParsedAssembly = (AssemblyNode)compilation.TargetModule; //So that mscorlib can have contracts but no reference to another assembly
        } else if (compilation.TargetModule.IsValidTypeName(Identifier.For("System.Compiler"), Identifier.For("ComposerAttribute")))
          SystemCompilerRuntimeAssemblyLocation.ParsedAssembly = (AssemblyNode)compilation.TargetModule;
        else if (compilation.TargetModule.IsValidTypeName(Identifier.For("Microsoft.SpecSharp"), Identifier.For("dummy")))
          RuntimeAssemblyLocation.ParsedAssembly = (AssemblyNode)compilation.TargetModule;
      }
      object ObjectType = SystemTypes.Object;
      if (ObjectType == null) return; //system types did not initialize

      //Walk IR looking up names
      Looker looker = new Looker(compilation.GlobalScope, errorHandler, scopeFor, ambiguousTypes, referencedLabels);
      if (options != null && options.EmitSourceContextsOnly)
      {
        looker.DontInjectDefaultConstructors = true;
      }

      // begin change by drunje
      looker.AllowPointersToManagedStructures = options.AllowPointersToManagedStructures;
      // end change by drunje
      looker.VisitCompilation(compilation);
      looker = null;

      if (options != null && options.EmitSourceContextsOnly) return; // stop after looker to have resolved types

      //Walk IR inferring types and resolving overloads
      TypeSystem typeSystem = new TypeSystem(errorHandler);
      Resolver resolver = new Resolver(errorHandler, typeSystem);
      resolver.VisitCompilation(compilation);
      resolver = null;

      //Walk IR checking for semantic errors and repairing it so that the next walk will work
      Checker checker = new Checker(ssCompilation, errorHandler, typeSystem, scopeFor, ambiguousTypes, referencedLabels);
      checker.VisitCompilation(compilation);
      checker = null;
      scopeFor = null;
      ambiguousTypes = null;
      referencedLabels = null;

      if (!options.IsContractAssembly) {
        if (options.RunProgramVerifier)
          ssCompilation.AddProgramVerifierPlugin(typeSystem, compilation);

        //Allow third party extensions to analyze AST IR for further errors
        ssCompilation.RunPlugins(compilation, errorHandler);
      }

      //Walk IR reducing it to nodes that have predefined mappings to MD+IL
      Normalizer normalizer = new Normalizer(typeSystem);
      normalizer.VisitCompilation(compilation);
      normalizer = null;

      if (options.IsContractAssembly) return;
      //Walk normalized IR instrumenting accesses of fields of guarded classes with checks
      CompilationUnit cu = compilation.CompilationUnits[0];
      if (cu != null && cu.PreprocessorDefinedSymbols != null && cu.PreprocessorDefinedSymbols.ContainsKey("GuardedFieldAccessChecks")){
        if (errorNodes.Count == 0){
          GuardedFieldAccessInstrumenter instrumenter = new GuardedFieldAccessInstrumenter();
          instrumenter.VisitCompilation(compilation);
          instrumenter = null;
        }
      }

      //Walk normalized IR doing code analysis
      Analyzer analyzer = new Analyzer(typeSystem, compilation);
      analyzer.Visit(compilation);

      //Allow third party extensions to analyze normalized IR for further errors
      ssCompilation.analyzer = analyzer; // make the analyzer available to plugins for access to method CFGs
      ssCompilation.RunPlugins(compilation, errorHandler);
      ssCompilation.analyzer = null;
      ssCompilation = null;
      analyzer = null;
      errorHandler = null;

      //Walk IR to optimize code further after analyses were performed, eg. to remove debug only code
      Optimizer optimizer = new Optimizer();
      optimizer.Visit(compilation);
      optimizer = null;
    }
示例#23
0
 internal Scoper(TrivialHashtable scopeFor)
   : base(scopeFor){
 }
示例#24
0
    public override Node CompileParseTree(Node node, Scope scope, Module targetModule, ErrorNodeList errorNodes){
      TrivialHashtable ambiguousTypes = new TrivialHashtable();
      TrivialHashtable referencedLabels = new TrivialHashtable();
      TrivialHashtable scopeFor = new TrivialHashtable();
      ErrorHandler errorHandler = new ErrorHandler(errorNodes);
      SpecSharpCompilation ssCompilation = new SpecSharpCompilation();

      // Setting the state
      TypeNode thisType = null;
      Method   currentMethod = null;
      BlockScope blockScope = scope as BlockScope;
      if (blockScope != null){
        Class baseScope = blockScope;
        MethodScope methodScope = null;
        while (baseScope != null){
          methodScope = baseScope.BaseClass as MethodScope;
          if (methodScope != null) break;
          baseScope = baseScope.BaseClass;
        }
        if (methodScope != null){
          thisType = methodScope.ThisType;
          if (thisType == null && methodScope.BaseClass is TypeScope){
            thisType = ((TypeScope) methodScope.BaseClass).Type;

          }
          currentMethod = methodScope.DeclaringMethod;
        }
      }

      //Attach scope to namespaces and types
      scopeFor[node.UniqueKey] = scope;
      Scoper scoper = new Scoper(scopeFor);
      scoper.currentScope = scope;
      node = scoper.Visit(node);

      //Walk IR looking up names
      Looker looker = new Looker(scope, errorHandler, scopeFor, ambiguousTypes, referencedLabels);
      // begin change by drunje (this is called from debugger only)
      looker.AllowPointersToManagedStructures = true;
      // end change by drunje
      if (blockScope != null)
      {
        looker.currentType = thisType;
        looker.currentMethod = currentMethod;
      }
      looker.currentAssembly = targetModule as AssemblyNode;
      looker.currentModule = targetModule;
      node = looker.Visit(node);
      
      //Walk IR inferring types and resolving overloads
      TypeSystem typeSystem = new TypeSystem(errorHandler);
      Resolver resolver = new Resolver(errorHandler, typeSystem);
      if (blockScope != null){
        resolver.currentType = thisType;
        resolver.currentMethod = currentMethod;
      }
      resolver.currentAssembly = targetModule as AssemblyNode;
      resolver.currentModule = targetModule;
      node = resolver.Visit(node);
      
      //TODO:  Need to set the state of the checker for compiling Expression, STOP using this method when the shift is complete
      //Walk IR checking for semantic errors and repairing it so that the next walk will work
      Checker checker = new Checker(ssCompilation, errorHandler, typeSystem, scopeFor, ambiguousTypes, referencedLabels);
      if (blockScope != null){
        checker.currentType = thisType;
        checker.currentMethod = currentMethod;
      }
      checker.currentAssembly = targetModule as AssemblyNode;
      checker.currentModule = targetModule;
      node = checker.Visit(node);

      //Walk IR reducing it to nodes that have predefined mappings to MD+IL
      Normalizer normalizer = new Normalizer(typeSystem);
      if (blockScope != null){
        normalizer.currentType = thisType;
        normalizer.currentMethod = currentMethod;
        normalizer.WrapToBlockExpression = false;
      }
      normalizer.currentModule = targetModule;
      node = normalizer.Visit(node);

      return node;
    }
示例#25
0
        /// <summary>
        /// requires IsClump(stmts);
        /// </summary>
        /// <param name="stmts">StatementList representing a clump</param>
        /// <returns>true iff stmts is a clump and all branches in stmts are to blocks in stmts</returns>
        internal static bool ClumpIsClosed(StatementList /*?*/ stmts)
        {
            if (stmts == null) return true;

            if (!IsClump(stmts)) return false;
            
            TrivialHashtable blocks = new TrivialHashtable(stmts.Count); // can't be any bigger!
            
            for (int i = 0, n = stmts.Count; i < n; i++)
            {
                if (stmts[i] == null) continue;

                blocks[stmts[i].UniqueKey] = stmts[i];
            }

            for (int i = 0, n = stmts.Count; i < n; i++)
            {
                Block b = stmts[i] as Block;
                
                if (b == null) continue; // tolerate nulls
                if (b.Statements == null || b.Statements.Count == 0) continue;
                
                Branch br = b.Statements[b.Statements.Count - 1] as Branch;
                if (br == null) continue;
                
                Block target = br.Target;
                if (target == null) continue;

                if (blocks[target.UniqueKey] == null)
                {
                    PrintClumpStructure(stmts);
                    return false; // found a branch to a block outside the clump!
                }
            }

            return true;
        }
示例#26
0
 public override void AddStandardLibraries(CompilerOptions coptions, Module module, TrivialHashtable alreadyReferencedAssemblies){
   if (coptions.NoStandardLibrary) return;
   base.AddStandardLibraries(coptions, module, alreadyReferencedAssemblies);
   SpecSharpCompilerOptions ssoptions = coptions as SpecSharpCompilerOptions;
   if (ssoptions != null && ssoptions.Compatibility) return;
   if (Microsoft.SpecSharp.Runtime.RuntimeAssembly != null && alreadyReferencedAssemblies[Microsoft.SpecSharp.Runtime.RuntimeAssembly.UniqueKey] == null){
     AssemblyReference aref = new AssemblyReference(Microsoft.SpecSharp.Runtime.RuntimeAssembly);
     module.AssemblyReferences.Add(aref);
     if (aref.PublicKeyOrToken == null || aref.PublicKeyOrToken.Length == 0)
       this.AssemblyCache[aref.Name] = Microsoft.SpecSharp.Runtime.RuntimeAssembly;
   }
 }
示例#27
0
 public Looker(Scope scope, Cci.ErrorHandler errorHandler, TrivialHashtable scopeFor, TrivialHashtable ambiguousTypes, TrivialHashtable referencedLabels)
   : base(scope, errorHandler, scopeFor, new TypeSystem(new ErrorHandler(errorHandler.Errors)), ambiguousTypes, referencedLabels){
   this.alreadyReported[StandardIds.Var.UniqueIdKey] = true;
 }
示例#28
0
 public override void AddExtendedRuntimeLibrary(CompilerOptions coptions, Module module, TrivialHashtable alreadyReferencedAssemblies){
   SpecSharpCompilerOptions ssoptions = coptions as SpecSharpCompilerOptions;
   if (ssoptions != null && ssoptions.Compatibility) return;
   base.AddExtendedRuntimeLibrary(coptions, module, alreadyReferencedAssemblies);
 }
示例#29
0
 override protected void ParseExceptionHandlerEntry(bool smallSection){
   TrivialHashtable tryMap = new TrivialHashtable();
   int dataSize = this.reader.tables.GetByte();
   int n = (int)(ushort)this.reader.tables.GetInt16();
   if (smallSection)
     n = dataSize / 12;
   else
     n = (dataSize + (n << 8)) / 24;      
   for (int i = 0; i < n; i++){
     Instruction matchingInstruction;
     int flags, tryOffset, tryLength, handlerOffset, handlerLength, tokenOrOffset;
     if (smallSection){
       flags = this.reader.tables.GetInt16();
       tryOffset = this.reader.tables.GetUInt16();
       tryLength = this.reader.tables.GetByte();
       handlerOffset = this.reader.tables.GetUInt16();
       handlerLength = this.reader.tables.GetByte();
     }else{
       flags = this.reader.tables.GetInt32();
       tryOffset = this.reader.tables.GetInt32();
       tryLength = this.reader.tables.GetInt32();
       handlerOffset = this.reader.tables.GetInt32();
       handlerLength = this.reader.tables.GetInt32();
     }
     tokenOrOffset = this.reader.tables.GetInt32();
     if (tryMap[tryOffset+tryLength] == null){
       matchingInstruction = this.AddInstruction(OpCode._Try, tryOffset, 5);
       this.AddInstruction(OpCode._EndTry, tryOffset+tryLength, matchingInstruction, 3);
       tryMap[tryOffset+tryLength] = String.Empty;
     }
     switch(flags){
       case 0x00: 
         int pos = this.reader.tables.GetCurrentPosition();
         TypeNode catchType = (TypeNode)this.reader.GetMemberFromToken(tokenOrOffset);
         this.reader.tables.SetCurrentPosition(pos);
         matchingInstruction = this.AddInstruction(OpCode._Catch, handlerOffset, catchType, 4);
         this.AddInstruction(OpCode._EndHandler, handlerOffset+handlerLength, matchingInstruction, 2);
         break;
       case 0x01:
         matchingInstruction = this.AddInstruction(OpCode._Filter, tokenOrOffset, 3);
         this.AddInstruction(OpCode._EndFilter, handlerOffset, matchingInstruction, 1);
         matchingInstruction = this.AddInstruction(OpCode._Catch, handlerOffset, 4);
         this.AddInstruction(OpCode._EndHandler, handlerOffset+handlerLength, matchingInstruction, 2);
         break;
       case 0x02:
         matchingInstruction = this.AddInstruction(OpCode._Finally, handlerOffset, 4);
         this.AddInstruction(OpCode._EndHandler, handlerOffset+handlerLength, matchingInstruction, 2);
         break;
       case 0x04:
         matchingInstruction = this.AddInstruction(OpCode._Fault, handlerOffset, 4);
         this.AddInstruction(OpCode._EndHandler, handlerOffset+handlerLength, matchingInstruction, 2);
         break;
       default: throw new InvalidMetadataException(ExceptionStrings.BadExceptionHandlerType);
     }
   }
 }
示例#30
0
    public virtual void ConstructSymbolTable(Compilation compilation, ErrorNodeList errors, TrivialHashtable scopeFor){
      if (compilation == null || scopeFor == null){Debug.Assert(false); return;}
      this.CurrentCompilation = compilation;
      Module symbolTable = compilation.TargetModule = this.CreateModule(compilation.CompilerParameters, errors, compilation);
      Scoper scoper = new Scoper(scopeFor);
      scoper.currentModule = symbolTable;
      ErrorHandler errorHandler = new ErrorHandler(errors);
      Looker looker = new Looker(this.GetGlobalScope(symbolTable), errorHandler, scopeFor);
      // begin change by drunje
      SpecSharpCompilerOptions options = compilation.CompilerParameters as SpecSharpCompilerOptions;
      if (options != null)
        looker.AllowPointersToManagedStructures = options.AllowPointersToManagedStructures;
      // end change by drunje
      looker.currentAssembly = (looker.currentModule = symbolTable) as AssemblyNode;
      looker.ignoreMethodBodies = true;
      Scope globalScope = compilation.GlobalScope = this.GetGlobalScope(symbolTable);

      CompilationUnitList sources = compilation.CompilationUnits;
      if (sources == null) return;
      int n = sources.Count;
      for (int i = 0; i < n; i++){
        CompilationUnitSnippet compilationUnitSnippet = sources[i] as CompilationUnitSnippet;
        if (compilationUnitSnippet == null){Debug.Assert(false); continue;}
        compilationUnitSnippet.ChangedMethod = null;
        Document doc = compilationUnitSnippet.SourceContext.Document;
        if (doc == null || doc.Text == null){Debug.Assert(false); continue;}
        IParserFactory factory = compilationUnitSnippet.ParserFactory;
        if (factory == null){Debug.Assert(false); return;}
        IParser p = factory.CreateParser(doc.Name, doc.LineNumber, doc.Text, symbolTable, errors, compilation.CompilerParameters);
        if (p is ResgenCompilerStub) continue;
        if (p == null){Debug.Assert(false); continue;}
        Parser specSharpParser = p as Parser;
        if (specSharpParser == null)
          p.ParseCompilationUnit(compilationUnitSnippet);
        else
          specSharpParser.ParseCompilationUnit(compilationUnitSnippet, true, false);
        //TODO: this following is a good idea only if the files will not be frequently reparsed from source
        //StringSourceText stringSourceText = doc.Text.TextProvider as StringSourceText;
        //if (stringSourceText != null && stringSourceText.IsSameAsFileContents)
        //  doc.Text.TextProvider = new CollectibleSourceText(doc.Name, doc.Text.Length);
        //else if (doc.Text.TextProvider != null)
        //  doc.Text.TextProvider.MakeCollectible();
      }
      CompilationUnitList compilationUnits = new CompilationUnitList();
      for (int i = 0; i < n; i++){
        CompilationUnit cUnit = sources[i];
        compilationUnits.Add(scoper.VisitCompilationUnit(cUnit));
      }
      for (int i = 0; i < n; i++){
        CompilationUnit cUnit = compilationUnits[i];
        if (cUnit == null) continue;
        looker.VisitCompilationUnit(cUnit);
      }
      //Run resolver over symbol table so that custom attributes on member signatures are known and can be used
      //to error check the the given file.
      TypeSystem typeSystem = new TypeSystem(errorHandler);
      Resolver resolver = new Resolver(errorHandler, typeSystem);
      resolver.currentAssembly = (resolver.currentModule = symbolTable) as AssemblyNode;
      for (int i = 0; i < n; i++) {
        CompilationUnit cUnit = compilationUnits[i];
        if (cUnit == null) continue;
        resolver.VisitCompilationUnit(cUnit);
      }
      this.CurrentCompilation = null;
    }