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; } }
/// <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(); }
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(); }
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>(); }
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(); }
internal InstructionParser(Reader/*!*/ reader, Method/*!*/ method, int methodIndex, int RVA) : base (reader, method, methodIndex, RVA){ this.ehMap = new TrivialHashtable(); }
public Looker(Scope scope, Cci.ErrorHandler errorHandler, TrivialHashtable scopeFor) : this(scope, errorHandler, scopeFor, null, null){ this.alreadyReported[StandardIds.Var.UniqueIdKey] = true; }
// 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); } }
public SubstituteParameters(TrivialHashtable map, List<Parameter> parameters) { this.map = map; this.parameters = parameters; }
// LJW: added typeSystem parameter internal Looker(Scope scope, Microsoft.Zing.ErrorHandler errorHandler, TrivialHashtable scopeFor, TypeSystem typeSystem) : this(scope, errorHandler, scopeFor, typeSystem, null, null, null) { }
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; }
internal Checker(SpecSharpCompilation ssCompilation, ErrorHandler errorHandler, TypeSystem typeSystem, TrivialHashtable scopeFor, TrivialHashtable ambiguousTypes, TrivialHashtable referencedLabels) : base(errorHandler, typeSystem, scopeFor, ambiguousTypes, referencedLabels) { this.ssCompilation = ssCompilation; }
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; } }
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; }
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); }
//!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; }
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; }
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; }
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; }
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 } }
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; }
internal Scoper(TrivialHashtable scopeFor) : base(scopeFor){ }
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; }
/// <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; }
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; } }
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; }
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); }
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); } } }
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; }