/// <summary> /// Checks for less-than-visible member references in an expression. /// </summary> public override void VisitMemberBinding(MemberBinding binding) { if (binding == null) return; Member mem = binding.BoundMember; if (mem != null) { // Member visiting includes also all attributes for the method. // But from Code Contracts perspective public method can have less visible attributes // because they're not part of the precondition. if (IsAttribute(mem.DeclaringType)) return; Field f = mem as Field; bool specPublic = false; if (f != null) { specPublic = IsSpecPublic(f); } if (!specPublic && !HelperMethods.IsCompilerGenerated(mem)) { // F: It seems there is some type-state like invariant here justifying why this.AsThisMemeber != null Contract.Assume(this.AsThisMember != null); if (!HelperMethods.IsReferenceAsVisibleAs(mem, this.AsThisMember)) { this.memberInErrorFound = mem; return; } } } base.VisitMemberBinding(binding); }
/// <summary> /// Checks for less-than-visible member references in an expression. /// </summary> public override void VisitMemberBinding(MemberBinding binding) { if (binding == null) return; Member mem = binding.BoundMember; if (mem != null) { Field f = mem as Field; bool specPublic = false; if (f != null) { specPublic = IsSpecPublic(f); } if (!specPublic && !HelperMethods.IsCompilerGenerated(mem)) { // F: It seems there is some type-state like invariant here justifying why this.AsThisMemeber != null Contract.Assume(this.AsThisMember != null); if (!HelperMethods.IsReferenceAsVisibleAs(mem, this.AsThisMember)) { this.memberInErrorFound = mem; return; } } } base.VisitMemberBinding(binding); }
public override void VisitMemberBinding(MemberBinding memberBinding) { if (memberBinding.BoundMember != null) { if (HelperMethods.HasAttribute(memberBinding.BoundMember.Attributes, this.attributeToFind)) { this.foundAttribute = true; return; } if (referencingType.Count > 0 && !HelperMethods.IsVisibleFrom(memberBinding.BoundMember, this.referencingType.Peek())) { this.generatedMethodContainsInvisibleMemberReference = true; this.foundAttribute = true; return; } Method referencedMethod = HelperMethods.Unspecialize(memberBinding.BoundMember as Method); if (referencedMethod != null) { if (HasAttribute(referencedMethod)) { this.foundAttribute = true; return; } if (this.skipQuantifiers && (this.contractNodes.IsForallMethod(referencedMethod) || this.contractNodes.IsGenericForallMethod(referencedMethod) || this.contractNodes.IsExistsMethod(referencedMethod) || this.contractNodes.IsGenericExistsMethod(referencedMethod)) ) { this.foundAttribute = true; return; } // check if we deal with a contract method on an interface/abstract method that is annotated var origType = HelperMethods.IsContractTypeForSomeOtherTypeUnspecialized(referencedMethod.DeclaringType, this.contractNodes); if (origType != null) { var origMethod = HelperMethods.FindImplementedMethodSpecialized(origType, referencedMethod); if (HasAttribute(origMethod)) { this.foundAttribute = true; return; } } } } base.VisitMemberBinding(memberBinding); }
public override Expression VisitMemberBinding(MemberBinding memberBinding) { Local closureLocal; if (memberBinding.TargetObject != null && this.closureLocals.TryGetValue(memberBinding.TargetObject.Type, out closureLocal)) { return new MemberBinding(closureLocal, memberBinding.BoundMember); } return base.VisitMemberBinding(memberBinding); }
public override void VisitMemberBinding(MemberBinding memberBinding) { if (memberBinding == null) return; base.VisitMemberBinding(memberBinding); var member = memberBinding.BoundMember; if (member == null) return; Contract.Assume(member.DeclaringType != null, "top-level types should not be memberbound"); var declaringType = HelperMethods.Unspecialize(member.DeclaringType); if (declaringType == contractClass) { // must reroute Method method = member as Method; if (method != null) { if (HelperMethods.IsClosureMethod(this.contractClass, HelperMethods.Unspecialize(method))) return; var template = method.Template; if (method.IsGeneric && template != null) { Method targetTemplate = HelperMethods.FindImplementedMethodSpecialized(this.OriginalType, template); if (targetTemplate != null) { var target = targetTemplate.GetTemplateInstance(this.OriginalType, method.TemplateArguments); memberBinding.BoundMember = target; return; } } else { Method target = HelperMethods.FindImplementedMethodSpecialized(this.OriginalType, method); if (target != null) { memberBinding.BoundMember = target; return; } } // couldn't find target: must issue error parent.HandleError(this.currentMethod, 1075, string.Format( "Contract class '{0}' references member '{1}' which is not part of the abstract class/interface being annotated.", this.contractClass.FullName, member.FullName), currentSourceContext); } } }
public override Expression VisitMemberBinding(MemberBinding memberBinding) { if (memberBinding.TargetObject != null && (memberBinding.TargetObject.NodeType == NodeType.This || memberBinding.TargetObject.NodeType == NodeType.Local)) { // search in list of parameters to see if any have the same name as the bound member foreach (Parameter p in this.parameters) { if (p.Name.UniqueIdKey == memberBinding.BoundMember.Name.UniqueIdKey) { return (Expression) this.map[p.UniqueKey]; } } return base.VisitMemberBinding(memberBinding); } return base.VisitMemberBinding(memberBinding); }
public override void VisitMemberBinding(MemberBinding memberBinding) { if (memberBinding == null) return; if (memberBinding.TargetObject.NodeType == NodeType.This || memberBinding.TargetObject.NodeType == NodeType.Local) { // search in list of parameters to see if any have the same name as the bound member foreach (Parameter p in this.BoundVars) { if (p.Name.UniqueIdKey == memberBinding.BoundMember.Name.UniqueIdKey) { if (!this.FoundVariables.Contains(p)) { this.FoundVariables.Add(p); this.FoundReferences.Add(memberBinding); } } } } base.VisitMemberBinding(memberBinding); }
public override void VisitMemberBinding(MemberBinding memberBinding) { if (memberBinding == null) return; var method = TemplateOrMethod(memberBinding.BoundMember as Method); if (usedToExtract.IsInvariantMethod(method)) { // indicates invariant use inside a method not marked by ObjectInvariantAttribute // F: Added the assumption, is it always true??? Contract.Assume(this.CurrentMethod != null); var containingMethodName = this.CurrentMethod.FullName; this.errorHandler(new Error(1022, string.Format("Bad use of method 'Contract.Invariant' in method body '{0}'", containingMethodName), lastSC)); return; } base.VisitMemberBinding(memberBinding); }
public override Expression VisitMemberBinding(MemberBinding memberBinding) { Expression result = base.VisitMemberBinding(memberBinding); return result; }
MemberBinding GetMemberBinding(Expression source, Member m) { MemberBinding src = new MemberBinding(source, m); src.Type = Checker.GetMemberType(m); return src; }
internal Class CreateSerializerFor(TypeNode type) { // todo: look in the genCache for other serializer assemblies that may have already // created the serializer for this type and make an assembly reference to that // serializer instead of creating a complete duplicate. TypeNode saved = tempChecker.currentType; Class c = (Class)serializers[type]; if (c != null) return c; c = new Class(); c.Flags = TypeFlags.Class | TypeFlags.BeforeFieldInit; // copy the accessibility of the type we are serializing. c.Flags |= (type.Flags & (TypeFlags.Public | TypeFlags.NestedAssembly)); c.Name = Identifier.For(GetSerializerName(type)); c.Namespace = Identifier.For(GetSerializerNamespace(type)); c.DeclaringModule = this.module; c.Members = new MemberList(); c.Attributes = new AttributeList(); c.BaseClass = Runtime.XmlSerializer; tempChecker.currentType = c; InstanceInitializer ii = Runtime.XmlSerializerAttribute.GetConstructor(); MemberBinding mb = new MemberBinding(null, ii); mb.Type = Runtime.XmlSerializerAttribute; c.Attributes.Add(new AttributeNode(mb, null)); if (cunit != null) { cunit.Namespaces[0].Types.Add(c); } this.module.Types.Add(c); Identifier typeId = Identifier.For("type"); // what we are writing to. Identifier rootName = Identifier.For("rootName"); // what we are writing to. Identifier rootNamespace = Identifier.For("rootNamespace"); // what we are writing to. // Constructor Method constructor = new InstanceInitializer(); constructor.Name = StandardIds.Ctor; constructor.DeclaringType = c; constructor.Flags = MethodFlags.Public|MethodFlags.HideBySig|MethodFlags.SpecialName|MethodFlags.RTSpecialName; constructor.Parameters = new ParameterList(); constructor.Parameters.Add(new Parameter(new AttributeList(), ParameterFlags.In, typeId, SystemTypes.Type, null, null)); constructor.Parameters.Add(new Parameter(new AttributeList(), ParameterFlags.In, rootName, SystemTypes.String, null, null)); constructor.Parameters.Add(new Parameter(new AttributeList(), ParameterFlags.In, rootNamespace, SystemTypes.String, null, null)); constructor.ReturnType = SystemTypes.Void; c.Members.Add(constructor); // pass args thru to base XmlSerializer constructor. Block b = constructor.Body = new Block(new StatementList()); b.Statements.Add(new ExpressionStatement(new MethodCall(new QualifiedIdentifier(new Base(), StandardIds.Ctor), new ExpressionList(typeId, rootName, rootNamespace), NodeType.Call))); //AddConsoleWrite(b.Statements, new Literal("Hello!!",SystemTypes.String)); // Serialize(T source, XmlSerializationWriter writer) method Identifier src = Identifier.For("source"); // object being serialized. Identifier writer = Identifier.For("writer"); // what we are writing to. Method serialize = new Method(); serialize.Name = Identifier.For("Serialize"); serialize.DeclaringType = c; serialize.Flags = MethodFlags.Public|MethodFlags.Static|MethodFlags.HideBySig; serialize.Parameters = new ParameterList(); serialize.Parameters.Add(new Parameter(new AttributeList(), ParameterFlags.In, src, type, null, null)); serialize.Parameters.Add(new Parameter(new AttributeList(), ParameterFlags.In, writer, Runtime.XmlSerializationWriter, null, null)); serialize.Parameters.Add(new Parameter(new AttributeList(), ParameterFlags.In, rootName, SystemTypes.String, null, null)); serialize.Parameters.Add(new Parameter(new AttributeList(), ParameterFlags.In, rootNamespace, SystemTypes.String, null, null)); serialize.ReturnType = SystemTypes.Void; c.Members.Add(serialize); // T Deserialize(XmlReader reader, bool required, out bool result) method Identifier reader = Identifier.For("reader"); // what we are reading from. Identifier required = Identifier.For("required"); // whether an object is required or not. Identifier result = Identifier.For("result"); // whether we found anything. Method deserialize = new Method(); deserialize.Name = Identifier.For("Deserialize"); deserialize.DeclaringType = c; deserialize.Flags = MethodFlags.Public|MethodFlags.Static|MethodFlags.HideBySig; deserialize.Parameters = new ParameterList(); deserialize.Parameters.Add(new Parameter(new AttributeList(), ParameterFlags.In, reader, Runtime.XmlSerializationReader, null, null)); deserialize.Parameters.Add(new Parameter(new AttributeList(), ParameterFlags.In, required, SystemTypes.Boolean, null, null)); deserialize.Parameters.Add(new Parameter(new AttributeList(), ParameterFlags.Out, result, SystemTypes.Boolean.GetReferenceType(), null, null)); deserialize.ReturnType = type; c.Members.Add(deserialize); // It is important that we add the serializer to the cache AFTER we create the methods, but // BEFORE we create the method bodies so that we can handle recurrsive calls to AddCallSerializer which // happens in recurrsive structures like "class Foo { public Foo f; }". Otherwise we'd get stuck in an // infinite loop. serializers[type] = c; // Body of serialize method. b = serialize.Body = new Block(new StatementList()); StatementList statements = b.Statements; if (!AddWriteSimpleType(type, statements, c, writer, src, rootName, rootNamespace)) { MethodCall call = new MethodCall(); call.Callee = new QualifiedIdentifier(writer,Identifier.For("WriteStartElement")); call.Operands = new ExpressionList(); call.Operands.Add(rootName); call.Operands.Add(rootNamespace); statements.Add(new If(new BinaryExpression(rootName,Literal.Null,NodeType.Ne), new Block(new StatementList(new ExpressionStatement(call))),null)); Expression source = src; if (type.Template == SystemTypes.GenericBoxed) { statements = AddCheckForNull(statements, Duplicate(src, c), type); type = Checker.GetCollectionElementType(type); source = CastTo(src, type);//unbox it } if (type is TupleType) { AddWriteTuple(type as TupleType, statements, c, source, writer); } else if (type is TypeUnion) { AddWriteChoice(type as TypeUnion, statements, c, source, writer); } else if (IsStream(type)) { AddWriteStream(type, statements, c, source, writer); } else { SchemaElementDecl sd = SchemaElementDecl.Compile(this.module, type, Checker.GetCollectionElementType(type), this.errorHandler, schemaElementDeclCache); SchemaValidator validator = validator = sd.CreateValidator(this.errorHandler); statements = AddCheckForNull(statements, Duplicate(src, c), type); AddWriteAttributes(statements, c, writer, source, validator); AddWriteContent(type, statements, c, writer, source, validator); } call = new MethodCall(); call.Callee = new QualifiedIdentifier(writer,Identifier.For("WriteEndElement")); call.Operands = new ExpressionList(); statements.Add(new If(new BinaryExpression(rootName,Literal.Null,NodeType.Ne), new Block(new StatementList(new ExpressionStatement(call))),null)); } // body of deserialize method. b = deserialize.Body = new Block(new StatementList()); statements = b.Statements; Local target = new Local(Identifier.Empty, type); if (type.Template == SystemTypes.GenericBoxed){ type = Checker.GetCollectionElementType(type); } if (type is TupleType) { AddReadTuple(b, type as TupleType, statements, reader, target, required, result); } else if (type is TypeUnion) { AddReadChoice(b, type as TypeUnion, statements, reader, target, required, result); } else if (IsStream(type)) { AddReadStream(b, type, statements, reader, target, result); } else { if (type is TypeAlias) { type = ((TypeAlias)type).AliasedType; } // Then we are already positioned on the element to be deserialized. statements.Add(new AssignmentStatement(required, Literal.True)); if (!AddReadSimpleType(type, statements, reader, target, result, false)) { if (!type.IsValueType && !type.IsAbstract && type.GetConstructor() != null) { Construct cons = new Construct(new MemberBinding(null, type), new ExpressionList(), type); statements.Add(new AssignmentStatement(target, cons)); } SchemaElementDecl sd = SchemaElementDecl.Compile(this.module, type, Checker.GetCollectionElementType(type), this.errorHandler, schemaElementDeclCache); SchemaValidator validator = validator = sd.CreateValidator(this.errorHandler); AddReadAttributes(type, statements, reader, target, validator); AddReadContent(c, b, type, statements, reader, target, required, result, validator); } } statements.Add(new Return(target)); tempChecker.currentType = saved; return c; }
private bool ParseStatement(Block/*!*/ block) { //parse instructions and put in expression tree until an assignment, void call, branch target, or branch is encountered StatementList statementList = block.Statements; Expression expr = null; Statement statement = null; bool transferStatement = false; int startingAddress = 0; #if !FxCop SourceContext sourceContext = new SourceContext(); sourceContext.StartPos = this.counter; #endif #if !ROTOR if (this.method.contextForOffset != null){ object sctx = this.method.contextForOffset[this.counter+1]; if (sctx != null) sourceContext = (SourceContext)sctx; } #endif while (true){ bool isStatement = false; startingAddress = this.counter+1; //Add one so that it is never zero (the latter means no entry to the TrivialHashtable) #if FxCop || ILOFFSETS this.ilOffset = this.counter; this.opCode = this.GetOpCode(); #else OpCode opCode = this.GetOpCode(); #endif #if FxCop if (this.handlerMap.TryGetValue(this.ilOffset, out expr)){ expr.sourceContext = sourceContext; expr.ILOffset = this.ilOffset; this.operandStack.Push(expr); } #endif switch (opCode){ case OpCode.Nop: statement = new Statement(NodeType.Nop); goto done; case OpCode.Break: statement = new Statement(NodeType.DebugBreak); goto done; case OpCode.Ldarg_0: expr = this.Parameters(0); break; case OpCode.Ldarg_1: expr = this.Parameters(1); break; case OpCode.Ldarg_2: expr = this.Parameters(2); break; case OpCode.Ldarg_3: expr = this.Parameters(3); break; case OpCode.Ldloc_0: expr = this.locals[0]; break; case OpCode.Ldloc_1: expr = this.locals[1]; break; case OpCode.Ldloc_2: expr = this.locals[2]; break; case OpCode.Ldloc_3: expr = this.locals[3]; break; case OpCode.Stloc_0: statement = new AssignmentStatement(this.locals[0], PopOperand()); goto done; case OpCode.Stloc_1: statement = new AssignmentStatement(this.locals[1], PopOperand()); goto done; case OpCode.Stloc_2: statement = new AssignmentStatement(this.locals[2], PopOperand()); goto done; case OpCode.Stloc_3: statement = new AssignmentStatement(this.locals[3], PopOperand()); goto done; case OpCode.Ldarg_S: expr = this.Parameters(this.GetByte()); break; case OpCode.Ldarga_S: expr = SetType(new UnaryExpression(this.Parameters(this.GetByte()), NodeType.AddressOf)); break; case OpCode.Starg_S: statement = new AssignmentStatement(this.Parameters(this.GetByte()), PopOperand()); goto done; case OpCode.Ldloc_S: expr = this.locals[this.GetByte()]; break; case OpCode.Ldloca_S: expr = SetType(new UnaryExpression(this.locals[this.GetByte()], NodeType.AddressOf)); break; case OpCode.Stloc_S: statement = new AssignmentStatement(this.locals[this.GetByte()], PopOperand()); goto done; case OpCode.Ldnull: expr = new Literal(null, CoreSystemTypes.Object); break; case OpCode.Ldc_I4_M1: expr = new Literal(-1, CoreSystemTypes.Int32); break; case OpCode.Ldc_I4_0: expr = new Literal(0, CoreSystemTypes.Int32); break; case OpCode.Ldc_I4_1: expr = new Literal(1, CoreSystemTypes.Int32); break; case OpCode.Ldc_I4_2: expr = new Literal(2, CoreSystemTypes.Int32); break; case OpCode.Ldc_I4_3: expr = new Literal(3, CoreSystemTypes.Int32); break; case OpCode.Ldc_I4_4: expr = new Literal(4, CoreSystemTypes.Int32); break; case OpCode.Ldc_I4_5: expr = new Literal(5, CoreSystemTypes.Int32); break; case OpCode.Ldc_I4_6: expr = new Literal(6, CoreSystemTypes.Int32); break; case OpCode.Ldc_I4_7: expr = new Literal(7, CoreSystemTypes.Int32); break; case OpCode.Ldc_I4_8: expr = new Literal(8, CoreSystemTypes.Int32); break; case OpCode.Ldc_I4_S: expr = new Literal((int)this.GetSByte(), CoreSystemTypes.Int32); break; case OpCode.Ldc_I4: expr = new Literal(this.GetInt32(), CoreSystemTypes.Int32); break; case OpCode.Ldc_I8: expr = new Literal(this.GetInt64(), CoreSystemTypes.Int64); break; case OpCode.Ldc_R4: expr = new Literal(this.GetSingle(), CoreSystemTypes.Single); break; case OpCode.Ldc_R8: expr = new Literal(this.GetDouble(), CoreSystemTypes.Double); break; case OpCode.Dup: statement = new ExpressionStatement(new Expression(NodeType.Dup)); goto done; case OpCode.Pop: statement = new ExpressionStatement(new UnaryExpression(PopOperand(), NodeType.Pop)); goto done; case OpCode.Jmp: expr = this.ParseCall(NodeType.Jmp, out isStatement); if (isStatement) goto done; break; case OpCode.Call: expr = this.ParseCall(NodeType.Call, out isStatement); if (isStatement) goto done; break; case OpCode.Calli: expr = this.ParseCalli(out isStatement); if (isStatement) goto done; break; case OpCode.Ret: Expression retVal = BodyParser.TypeIsVoid(this.method.ReturnType) ? null : PopOperand(); statement = new Return(retVal); transferStatement = true; goto done; case OpCode.Br_S: statement = this.ParseBranch(NodeType.Nop, 0, true, false); transferStatement = true; goto done; case OpCode.Brfalse_S: statement = this.ParseBranch(NodeType.LogicalNot, 1, true, false); transferStatement = true; goto done; case OpCode.Brtrue_S: statement = this.ParseBranch(NodeType.Nop, 1, true, false); transferStatement = true; goto done; case OpCode.Beq_S: statement = this.ParseBranch(NodeType.Eq, 2, true, false); transferStatement = true; goto done; case OpCode.Bge_S: statement = this.ParseBranch(NodeType.Ge, 2, true, false); transferStatement = true; goto done; case OpCode.Bgt_S: statement = this.ParseBranch(NodeType.Gt, 2, true, false); transferStatement = true; goto done; case OpCode.Ble_S: statement = this.ParseBranch(NodeType.Le, 2, true, false); transferStatement = true; goto done; case OpCode.Blt_S: statement = this.ParseBranch(NodeType.Lt, 2, true, false); transferStatement = true; goto done; case OpCode.Bne_Un_S: statement = this.ParseBranch(NodeType.Ne, 2, true, true); transferStatement = true; goto done; case OpCode.Bge_Un_S: statement = this.ParseBranch(NodeType.Ge, 2, true, true); transferStatement = true; goto done; case OpCode.Bgt_Un_S: statement = this.ParseBranch(NodeType.Gt, 2, true, true); transferStatement = true; goto done; case OpCode.Ble_Un_S: statement = this.ParseBranch(NodeType.Le, 2, true, true); transferStatement = true; goto done; case OpCode.Blt_Un_S: statement = this.ParseBranch(NodeType.Lt, 2, true, true); transferStatement = true; goto done; case OpCode.Br: statement = this.ParseBranch(NodeType.Nop, 0, false, false); transferStatement = true; goto done; case OpCode.Brfalse: statement = this.ParseBranch(NodeType.LogicalNot, 1, false, false); transferStatement = true; goto done; case OpCode.Brtrue: statement = this.ParseBranch(NodeType.Nop, 1, false, false); transferStatement = true; goto done; case OpCode.Beq: statement = this.ParseBranch(NodeType.Eq, 2, false, false); transferStatement = true; goto done; case OpCode.Bge: statement = this.ParseBranch(NodeType.Ge, 2, false, false); transferStatement = true; goto done; case OpCode.Bgt: statement = this.ParseBranch(NodeType.Gt, 2, false, false); transferStatement = true; goto done; case OpCode.Ble: statement = this.ParseBranch(NodeType.Le, 2, false, false); transferStatement = true; goto done; case OpCode.Blt: statement = this.ParseBranch(NodeType.Lt, 2, false, false); transferStatement = true; goto done; case OpCode.Bne_Un: statement = this.ParseBranch(NodeType.Ne, 2, false, true); transferStatement = true; goto done; case OpCode.Bge_Un: statement = this.ParseBranch(NodeType.Ge, 2, false, true); transferStatement = true; goto done; case OpCode.Bgt_Un: statement = this.ParseBranch(NodeType.Gt, 2, false, true); transferStatement = true; goto done; case OpCode.Ble_Un: statement = this.ParseBranch(NodeType.Le, 2, false, true); transferStatement = true; goto done; case OpCode.Blt_Un: statement = this.ParseBranch(NodeType.Lt, 2, false, true); transferStatement = true; goto done; case OpCode.Switch: statement = this.ParseSwitchInstruction(); transferStatement = true; goto done; case OpCode.Ldind_I1: expr = new AddressDereference(PopOperand(), CoreSystemTypes.Int8, this.isVolatile, this.alignment); break; case OpCode.Ldind_U1: expr = new AddressDereference(PopOperand(), CoreSystemTypes.UInt8, this.isVolatile, this.alignment); break; case OpCode.Ldind_I2: expr = new AddressDereference(PopOperand(), CoreSystemTypes.Int16, this.isVolatile, this.alignment); break; case OpCode.Ldind_U2: expr = new AddressDereference(PopOperand(), CoreSystemTypes.UInt16, this.isVolatile, this.alignment); break; case OpCode.Ldind_I4: expr = new AddressDereference(PopOperand(), CoreSystemTypes.Int32, this.isVolatile, this.alignment); break; case OpCode.Ldind_U4: expr = new AddressDereference(PopOperand(), CoreSystemTypes.UInt32, this.isVolatile, this.alignment); break; case OpCode.Ldind_I8: expr = new AddressDereference(PopOperand(), CoreSystemTypes.Int64, this.isVolatile, this.alignment); break; case OpCode.Ldind_I: expr = new AddressDereference(PopOperand(), CoreSystemTypes.IntPtr, this.isVolatile, this.alignment); break; case OpCode.Ldind_R4: expr = new AddressDereference(PopOperand(), CoreSystemTypes.Single, this.isVolatile, this.alignment); break; case OpCode.Ldind_R8: expr = new AddressDereference(PopOperand(), CoreSystemTypes.Double, this.isVolatile, this.alignment); break; case OpCode.Ldind_Ref: expr = new AddressDereference(PopOperand(), CoreSystemTypes.Object, this.isVolatile, this.alignment); break; case OpCode.Stind_Ref: statement = this.ParseStoreIndirect(CoreSystemTypes.Object); goto done; case OpCode.Stind_I1: statement = this.ParseStoreIndirect(CoreSystemTypes.Int8); goto done; case OpCode.Stind_I2: statement = this.ParseStoreIndirect(CoreSystemTypes.Int16); goto done; case OpCode.Stind_I4: statement = this.ParseStoreIndirect(CoreSystemTypes.Int32); goto done; case OpCode.Stind_I8: statement = this.ParseStoreIndirect(CoreSystemTypes.Int64); goto done; case OpCode.Stind_R4: statement = this.ParseStoreIndirect(CoreSystemTypes.Single); goto done; case OpCode.Stind_R8: statement = this.ParseStoreIndirect(CoreSystemTypes.Double); goto done; case OpCode.Add: expr = this.ParseBinaryOperation(NodeType.Add); break; case OpCode.Sub: expr = this.ParseBinaryOperation(NodeType.Sub); break; case OpCode.Mul: expr = this.ParseBinaryOperation(NodeType.Mul); break; case OpCode.Div: expr = this.ParseBinaryOperation(NodeType.Div); break; case OpCode.Div_Un: expr = this.ParseBinaryOperation(NodeType.Div_Un); break; case OpCode.Rem: expr = this.ParseBinaryOperation(NodeType.Rem); break; case OpCode.Rem_Un: expr = this.ParseBinaryOperation(NodeType.Rem_Un); break; case OpCode.And: expr = this.ParseBinaryOperation(NodeType.And); break; case OpCode.Or: expr = this.ParseBinaryOperation(NodeType.Or); break; case OpCode.Xor: expr = this.ParseBinaryOperation(NodeType.Xor); break; case OpCode.Shl: expr = this.ParseBinaryOperation(NodeType.Shl); break; case OpCode.Shr: expr = this.ParseBinaryOperation(NodeType.Shr); break; case OpCode.Shr_Un: expr = this.ParseBinaryOperation(NodeType.Shr_Un); break; case OpCode.Neg: expr = this.ParseUnaryOperation(NodeType.Neg); break; case OpCode.Not: expr = this.ParseUnaryOperation(NodeType.Not); break; case OpCode.Conv_I1: expr = new UnaryExpression(PopOperand(), NodeType.Conv_I1, CoreSystemTypes.Int8); break; case OpCode.Conv_I2: expr = new UnaryExpression(PopOperand(), NodeType.Conv_I2, CoreSystemTypes.Int16); break; case OpCode.Conv_I4: expr = new UnaryExpression(PopOperand(), NodeType.Conv_I4, CoreSystemTypes.Int32); break; case OpCode.Conv_I8: expr = new UnaryExpression(PopOperand(), NodeType.Conv_I8, CoreSystemTypes.Int64); break; case OpCode.Conv_R4: expr = new UnaryExpression(PopOperand(), NodeType.Conv_R4, CoreSystemTypes.Single); break; case OpCode.Conv_R8: expr = new UnaryExpression(PopOperand(), NodeType.Conv_R8, CoreSystemTypes.Double); break; case OpCode.Conv_U4: expr = new UnaryExpression(PopOperand(), NodeType.Conv_U4, CoreSystemTypes.UInt32); break; case OpCode.Conv_U8: expr = new UnaryExpression(PopOperand(), NodeType.Conv_U8, CoreSystemTypes.UInt64); break; case OpCode.Callvirt: expr = this.ParseCall(NodeType.Callvirt, out isStatement); if (isStatement) goto done; break; case OpCode.Cpobj: statement = this.ParseCopyObject(); goto done; case OpCode.Ldobj: expr = new AddressDereference(PopOperand(), (TypeNode)this.GetMemberFromToken(), this.isVolatile, this.alignment); break; case OpCode.Ldstr: expr = new Literal(this.GetStringFromToken(), CoreSystemTypes.String); break; case OpCode.Newobj: expr = this.ParseConstruct(); break; case OpCode.Castclass: expr = ParseTypeCheck(PopOperand(), (TypeNode)this.GetMemberFromToken(), NodeType.Castclass); break; case OpCode.Isinst: expr = ParseTypeCheck(PopOperand(), (TypeNode)this.GetMemberFromToken(), NodeType.Isinst); break; case OpCode.Conv_R_Un: expr = new UnaryExpression(PopOperand(), NodeType.Conv_R_Un, CoreSystemTypes.Double); break; case OpCode.Unbox: expr = ParseTypeCheck(PopOperand(), (TypeNode)this.GetMemberFromToken(), NodeType.Unbox); break; case OpCode.Throw: statement = new Throw(PopOperand()); transferStatement = true; goto done; case OpCode.Ldfld: expr = new MemberBinding(PopOperand(), this.GetMemberFromToken(), this.isVolatile, this.alignment); break; case OpCode.Ldflda: expr = SetType(new UnaryExpression(new MemberBinding(PopOperand(), this.GetMemberFromToken(), this.isVolatile, this.alignment), NodeType.AddressOf)); break; case OpCode.Stfld: statement = this.ParseStoreField(); goto done; case OpCode.Ldsfld: expr = new MemberBinding(null, this.GetMemberFromToken(), this.isVolatile, this.alignment); break; case OpCode.Ldsflda: expr = SetType(new UnaryExpression(new MemberBinding(null, this.GetMemberFromToken(), this.isVolatile, this.alignment), NodeType.AddressOf)); break; case OpCode.Stsfld: statement = new AssignmentStatement(new MemberBinding(null, this.GetMemberFromToken(), this.isVolatile, this.alignment), PopOperand()); goto done; case OpCode.Stobj: statement = this.ParseStoreIndirect((TypeNode)this.GetMemberFromToken()); goto done; case OpCode.Conv_Ovf_I1_Un: expr = new UnaryExpression(PopOperand(), NodeType.Conv_Ovf_I1_Un, CoreSystemTypes.Int8); break; case OpCode.Conv_Ovf_I2_Un: expr = new UnaryExpression(PopOperand(), NodeType.Conv_Ovf_I2_Un, CoreSystemTypes.Int16); break; case OpCode.Conv_Ovf_I4_Un: expr = new UnaryExpression(PopOperand(), NodeType.Conv_Ovf_I4_Un, CoreSystemTypes.Int32); break; case OpCode.Conv_Ovf_I8_Un: expr = new UnaryExpression(PopOperand(), NodeType.Conv_Ovf_I8_Un, CoreSystemTypes.Int64); break; case OpCode.Conv_Ovf_U1_Un: expr = new UnaryExpression(PopOperand(), NodeType.Conv_Ovf_U1_Un, CoreSystemTypes.UInt8); break; case OpCode.Conv_Ovf_U2_Un: expr = new UnaryExpression(PopOperand(), NodeType.Conv_Ovf_U2_Un, CoreSystemTypes.UInt16); break; case OpCode.Conv_Ovf_U4_Un: expr = new UnaryExpression(PopOperand(), NodeType.Conv_Ovf_U4_Un, CoreSystemTypes.UInt32); break; case OpCode.Conv_Ovf_U8_Un: expr = new UnaryExpression(PopOperand(), NodeType.Conv_Ovf_U8_Un, CoreSystemTypes.UInt64); break; case OpCode.Conv_Ovf_I_Un: expr = new UnaryExpression(PopOperand(), NodeType.Conv_Ovf_I_Un, CoreSystemTypes.IntPtr); break; case OpCode.Conv_Ovf_U_Un: expr = new UnaryExpression(PopOperand(), NodeType.Conv_Ovf_U_Un, CoreSystemTypes.UIntPtr); break; case OpCode.Box: TypeNode t = (TypeNode)this.GetMemberFromToken(); TypeNode bt = t is EnumNode ? CoreSystemTypes.Enum : CoreSystemTypes.ValueType; expr = new BinaryExpression(PopOperand(), new Literal(t, CoreSystemTypes.Type), NodeType.Box, bt); break; case OpCode.Newarr: expr = this.ParseNewArray(); break; case OpCode.Ldlen: expr = new UnaryExpression(PopOperand(), NodeType.Ldlen, CoreSystemTypes.UIntPtr); break; case OpCode.Ldelema: expr = this.ParseArrayElementLoadAddress(); break; case OpCode.Ldelem_I1: case OpCode.Ldelem_U1: case OpCode.Ldelem_I2: case OpCode.Ldelem_U2: case OpCode.Ldelem_I4: case OpCode.Ldelem_U4: case OpCode.Ldelem_I8: case OpCode.Ldelem_I: case OpCode.Ldelem_R4: case OpCode.Ldelem_R8: case OpCode.Ldelem_Ref: expr = this.ParseArrayElementLoad(opCode, null); break; case OpCode.Stelem_I: case OpCode.Stelem_I1: case OpCode.Stelem_I2: case OpCode.Stelem_I4: case OpCode.Stelem_I8: case OpCode.Stelem_R4: case OpCode.Stelem_R8: case OpCode.Stelem_Ref: statement = this.ParseArrayElementAssignment(opCode); goto done; case OpCode.Ldelem: expr = this.ParseArrayElementLoad(opCode, null); break; case OpCode.Stelem: statement = this.ParseArrayElementAssignment(opCode); goto done; case OpCode.Unbox_Any: expr = ParseTypeCheck(PopOperand(), (TypeNode)this.GetMemberFromToken(), NodeType.UnboxAny); break; case OpCode.Conv_Ovf_I1: expr = new UnaryExpression(PopOperand(), NodeType.Conv_Ovf_I1, CoreSystemTypes.Int8); break; case OpCode.Conv_Ovf_U1: expr = new UnaryExpression(PopOperand(), NodeType.Conv_Ovf_U1, CoreSystemTypes.UInt8); break; case OpCode.Conv_Ovf_I2: expr = new UnaryExpression(PopOperand(), NodeType.Conv_Ovf_I2, CoreSystemTypes.Int16); break; case OpCode.Conv_Ovf_U2: expr = new UnaryExpression(PopOperand(), NodeType.Conv_Ovf_U2, CoreSystemTypes.UInt16); break; case OpCode.Conv_Ovf_I4: expr = new UnaryExpression(PopOperand(), NodeType.Conv_Ovf_I4, CoreSystemTypes.Int32); break; case OpCode.Conv_Ovf_U4: expr = new UnaryExpression(PopOperand(), NodeType.Conv_Ovf_U4, CoreSystemTypes.UInt32); break; case OpCode.Conv_Ovf_I8: expr = new UnaryExpression(PopOperand(), NodeType.Conv_Ovf_I8, CoreSystemTypes.Int64); break; case OpCode.Conv_Ovf_U8: expr = new UnaryExpression(PopOperand(), NodeType.Conv_Ovf_U8, CoreSystemTypes.UInt64); break; case OpCode.Refanyval: expr = new BinaryExpression(PopOperand(), new Literal(this.GetMemberFromToken(), CoreSystemTypes.Type), NodeType.Refanyval, CoreSystemTypes.IntPtr); break; case OpCode.Ckfinite: expr = this.ParseUnaryOperation(NodeType.Ckfinite); break; case OpCode.Mkrefany: expr = new BinaryExpression(PopOperand(), new Literal(this.GetMemberFromToken(), CoreSystemTypes.Type), NodeType.Mkrefany, CoreSystemTypes.DynamicallyTypedReference); break; case OpCode.Ldtoken: expr = ParseLoadRuntimeMetadataToken(); break; case OpCode.Conv_U2: expr = new UnaryExpression(PopOperand(), NodeType.Conv_U2, CoreSystemTypes.UInt16); break; case OpCode.Conv_U1: expr = new UnaryExpression(PopOperand(), NodeType.Conv_U1, CoreSystemTypes.UInt8); break; case OpCode.Conv_I: expr = new UnaryExpression(PopOperand(), NodeType.Conv_I, CoreSystemTypes.IntPtr); break; case OpCode.Conv_Ovf_I: expr = new UnaryExpression(PopOperand(), NodeType.Conv_Ovf_I, CoreSystemTypes.IntPtr); break; case OpCode.Conv_Ovf_U: expr = new UnaryExpression(PopOperand(), NodeType.Conv_Ovf_U, CoreSystemTypes.UIntPtr); break; case OpCode.Add_Ovf: expr = this.ParseBinaryOperation(NodeType.Add_Ovf); break; case OpCode.Add_Ovf_Un: expr = this.ParseBinaryOperation(NodeType.Add_Ovf_Un); break; case OpCode.Mul_Ovf: expr = this.ParseBinaryOperation(NodeType.Mul_Ovf); break; case OpCode.Mul_Ovf_Un: expr = this.ParseBinaryOperation(NodeType.Mul_Ovf_Un); break; case OpCode.Sub_Ovf: expr = this.ParseBinaryOperation(NodeType.Sub_Ovf); break; case OpCode.Sub_Ovf_Un: expr = this.ParseBinaryOperation(NodeType.Sub_Ovf_Un); break; case OpCode.Endfinally: statement = new EndFinally(); transferStatement = true; goto done; case OpCode.Leave: statement = this.ParseBranch(NodeType.Nop, 0, false, false, true); transferStatement = true; goto done; case OpCode.Leave_S: statement = this.ParseBranch(NodeType.Nop, 0, true, false, true); transferStatement = true; goto done; case OpCode.Stind_I: statement = this.ParseStoreIndirect(CoreSystemTypes.IntPtr); goto done; case OpCode.Conv_U: expr = new UnaryExpression(PopOperand(), NodeType.Conv_U, CoreSystemTypes.UIntPtr); break; case OpCode.Arglist: expr = new Expression(NodeType.Arglist, CoreSystemTypes.ArgIterator); break; case OpCode.Ceq: expr = this.ParseBinaryComparison(NodeType.Ceq); break; case OpCode.Cgt: expr = this.ParseBinaryComparison(NodeType.Cgt); break; case OpCode.Cgt_Un: expr = this.ParseBinaryComparison(NodeType.Cgt_Un); break; case OpCode.Clt: expr = this.ParseBinaryComparison(NodeType.Clt); break; case OpCode.Clt_Un: expr = this.ParseBinaryComparison(NodeType.Clt_Un); break; case OpCode.Ldftn: expr = new UnaryExpression(new MemberBinding(null, this.GetMemberFromToken()), NodeType.Ldftn, CoreSystemTypes.IntPtr); break; case OpCode.Ldvirtftn: expr = new BinaryExpression(PopOperand(), new MemberBinding(null, this.GetMemberFromToken()), NodeType.Ldvirtftn, CoreSystemTypes.IntPtr); break; case OpCode.Ldarg: expr = this.Parameters((ushort)this.GetInt16()); break; case OpCode.Ldarga: expr = SetType(new UnaryExpression(this.Parameters((ushort)this.GetInt16()), NodeType.AddressOf)); break; case OpCode.Starg: statement = new AssignmentStatement(this.Parameters((ushort)this.GetInt16()), PopOperand()); goto done; case OpCode.Ldloc: expr = this.locals[(ushort)this.GetInt16()]; break; case OpCode.Ldloca: expr = SetType(new UnaryExpression(this.locals[(ushort)this.GetInt16()], NodeType.AddressOf)); break; case OpCode.Stloc: statement = new AssignmentStatement(this.locals[(ushort)this.GetInt16()], PopOperand()); goto done; case OpCode.Localloc: expr = new UnaryExpression(PopOperand(), NodeType.Localloc, CoreSystemTypes.Void); break; case OpCode.Endfilter: statement = new EndFilter(PopOperand()); transferStatement = true; goto done; case OpCode.Unaligned_: this.alignment = this.GetByte(); continue; case OpCode.Volatile_: this.isVolatile = true; continue; case OpCode.Tail_: this.isTailCall = true; continue; case OpCode.Initobj: statement = this.ParseInitObject(); goto done; case OpCode.Constrained_: this.constraint = this.GetMemberFromToken() as TypeNode; continue; case OpCode.Cpblk: expr = this.ParseTernaryOperation(NodeType.Cpblk); goto done; case OpCode.Initblk: expr = this.ParseTernaryOperation(NodeType.Initblk); goto done; case OpCode.Rethrow: statement = new Throw(null); statement.NodeType = NodeType.Rethrow; transferStatement = true; goto done; case OpCode.Sizeof: expr = new UnaryExpression(new Literal(this.GetMemberFromToken(), CoreSystemTypes.Type), NodeType.Sizeof, CoreSystemTypes.Int32); break; case OpCode.Refanytype: expr = new UnaryExpression(PopOperand(), NodeType.Refanytype, CoreSystemTypes.RuntimeTypeHandle); break; case OpCode.Readonly_: this.isReadOnly = true; continue; default: throw new InvalidMetadataException(ExceptionStrings.UnknownOpCode); } if (this.blockMap[this.counter+1] != null){ transferStatement = true; //Falls through to the next basic block, so implicitly a "transfer" statement goto done; } //^ assume expr != null; #if FxCop expr.sourceContext = sourceContext; #endif #if FxCop || ILOFFSETS expr.ILOffset = this.ilOffset; #endif this.operandStack.Push(expr); this.isReadOnly = false; this.isVolatile = false; this.isTailCall = false; this.alignment = -1; } done: for (int i = 0; i <= this.operandStack.top; i++){ Expression e = this.operandStack.elements[i]; //^ assume e != null; Statement s = new ExpressionStatement(e); #if FxCop s.SourceContext = this.sourceContext; #endif #if FxCop || ILOFFSETS s.ILOffset = this.ilOffset; #endif statementList.Add(s); } this.operandStack.top = -1; if (statement == null) { statement = new ExpressionStatement(expr); #if FxCop expr.sourceContext = this.sourceContext; #endif #if FxCop || ILOFFSETS expr.ILOffset = this.ilOffset; #endif } statement.SourceContext = sourceContext; #if FxCop || ILOFFSETS statement.ILOffset = this.ilOffset; #endif #if ILOFFSETS this.lastSourceContext = sourceContext; #endif statementList.Add(statement); if (transferStatement) return true; return this.blockMap[this.counter+1] != null; }
private MethodCall/*!*/ ParseCalli(out bool isStatement) { FunctionPointer fp = this.reader.GetCalliSignature(this.GetInt32()); if (fp == null) throw new InvalidMetadataException(ExceptionStrings.BaddCalliSignature); isStatement = BodyParser.TypeIsVoid(fp.ReturnType); int n = fp.ParameterTypes.Count; Expression[] args = new Expression[n+1]; ExpressionList arguments = new ExpressionList(n+1); for (int i = n; i >= 0; i--) args[i] = PopOperand(); for (int i = 0; i <= n; i++) arguments.Add(args[i]); Expression thisob = fp.IsStatic ? null : PopOperand(); MemberBinding methBinding = new MemberBinding(thisob, fp); MethodCall result = new MethodCall(methBinding, arguments, NodeType.Calli); result.Type = fp.ReturnType; result.IsTailCall = this.isTailCall; return result; }
public virtual Expression VisitMemberBinding(MemberBinding memberBinding) { if (memberBinding == null) return null; memberBinding.TargetObject = this.VisitExpression(memberBinding.TargetObject); return memberBinding; }
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 Expression VisitMemberBinding(MemberBinding memberBinding) { if (memberBinding == null) return null; Field f = memberBinding.BoundMember as Field; if (f == null || !this.substitution.ContainsKey(f)) return base.VisitMemberBinding(memberBinding); Method m = this.substitution[f]; return new MethodCall( new MemberBinding(memberBinding.TargetObject, m), null, m.IsVirtual ? NodeType.Callvirt : NodeType.Call, f.Type ); }
private MethodCall/*!*/ ParseCall(NodeType typeOfCall, out bool isStatement) { TypeNodeList varArgTypes; Method meth = (Method)this.GetMemberFromToken(out varArgTypes); int numVarArgs = varArgTypes == null ? 0 : varArgTypes.Count; isStatement = BodyParser.TypeIsVoid(meth.ReturnType); int n = meth.Parameters == null ? 0 : meth.Parameters.Count; if (typeOfCall == NodeType.Jmp) n = 0; else n += numVarArgs; Expression[] args = new Expression[n]; ExpressionList arguments = new ExpressionList(n); for (int i = n-1; i >= 0; i--) args[i] = PopOperand(); for (int i = 0; i < n; i++) arguments.Add(args[i]); if (varArgTypes != null) { for (int i = n-1, j = numVarArgs; j > 0; j--, i--) { Expression e = arguments[i]; TypeNode t = varArgTypes[j-1]; if (e != null && t != null) e.Type = t; } } Expression thisob = meth.IsStatic ? null : PopOperand(); MemberBinding methBinding = new MemberBinding(thisob, meth); MethodCall result = new MethodCall(methBinding, arguments, typeOfCall); result.Type = meth.ReturnType; result.IsTailCall = this.isTailCall; if (this.constraint != null){ result.Constraint = this.constraint; this.constraint = null; } return result; }
public override Expression VisitMemberBinding(MemberBinding memberBinding) { Field field = memberBinding.BoundMember as Field; if (field != null) { // Case 1: iterator_closure's this.field should be turned into either a parameter or a local. if (memberBinding.TargetObject is This) { var thisParam = (This) memberBinding.TargetObject; var declType = thisParam.Type; Reference declRef = declType as Reference; if (declRef != null) { declType = declRef.ElementType; } declType = HelperMethods.Unspecialize(declType); if (declType == this.closureUnspec) { // actually a closure field. if (closureParametersMapping.ContainsKey(field.Name.Name)) { return closureParametersMapping[field.Name.Name]; } if (closureLocalsMapping.ContainsKey(field.Name.Name)) { return closureLocalsMapping[field.Name.Name]; } if (field.Name.Name.Contains("__locals" /* csc.exe */) || field.Name.Name.Contains("<>8__") /* roslyn-based csc */|| field.Name.Name.Contains("<>9__") /* roslyn-based cached anonymous method delegates */|| field.Name.Name.Contains("__spill") /* rcsc.exe */|| field.Name.Name.Contains("__CachedAnonymousMethodDelegate") /* junk, revisit */) { Local newLocal = new Local(field.Name, field.Type); closureLocalsMapping.Add(field.Name.Name, newLocal); return newLocal; } throw new NotImplementedException( String.Format("Found field {0} in contract that shouldn't be here", field.Name.Name)); } else { // some other field. Leave it alone. } } } // case 2: assert (memberbinding.targetObject is memberbinding && memberbinding.boundmember is capturing // either a parameter or a local). Then targetObject is hopefully turned into a parameter or a local, with // the boundmember untouched. We simply use base.VisitMemberBinding for this case. return base.VisitMemberBinding(memberBinding); }
private UnaryExpression /*!*/ ParseLoadRuntimeMetadataToken() { Expression expr = null; TypeNode exprType = null; Member member = this.GetMemberFromToken(); TypeNode t = member as TypeNode; if (t == null) { exprType = (member.NodeType == NodeType.Field) ? CoreSystemTypes.RuntimeFieldHandle : CoreSystemTypes.RuntimeMethodHandle; expr = new MemberBinding(null, member); } else { exprType = CoreSystemTypes.RuntimeTypeHandle; expr = new Literal(t, CoreSystemTypes.Type); } return new UnaryExpression(expr, NodeType.Ldtoken, exprType); }
private bool IsAutoPropGetterCall(MemberBinding mb) { if (!(mb.TargetObject is This)) return false; if (mb.BoundMember == autoProp.Getter) return true; return false; }
void AddReadStream(Block block, TypeNode type, StatementList statements, Identifier reader, Expression target, Expression result){ // Read next element and figure out if it matches the stream element type, if so read it and add it to the list // If not, then return (throw an error if there are no items and the list is the non-empty type). // flexArray = new flexarray(); // while (reader.Read() && read.NodeType != XmlNodeType.EndElement) { // if (reader.NodeType == XmlNodeType.Element) { // readchild(flexarray); // } // } // target = flexArray; Local nameLocal = new Local(Identifier.For("name"),SystemTypes.String, block); Local nsLocal = new Local(Identifier.For("ns"),SystemTypes.String, block); Local nodeType = new Local(Identifier.For("nodeType"),Runtime.XmlNodeType, block); Local optional = new Local(Identifier.Empty, SystemTypes.Boolean, block); Local foundChild = new Local(Identifier.Empty, SystemTypes.Boolean, block); statements.Add(new AssignmentStatement(optional, Literal.False)); TypeNode eType = Checker.GetCollectionElementType(type); Local local = new Local(Identifier.Empty, eType, block); Method addMethod = null; Local localArray = null; if (type.Template == SystemTypes.GenericBoxed) { addMethod = null; // only needs one! } else if (Checker.IsGenericList(type)) { //TODO: this call is invalid if the eType is not public TypeNode flexArrayType = SystemTypes.GenericList.GetTemplateInstance(this.module, eType); localArray = new Local(Identifier.For("stream"+streamCount++), flexArrayType, block); statements.Add(new AssignmentStatement(localArray, new Construct(new MemberBinding(null, flexArrayType), new ExpressionList(), flexArrayType))); addMethod = flexArrayType.GetMethod(Identifier.For("Add"), eType); } else { TypeNode arrayType = SystemTypes.ArrayList; localArray = new Local(Identifier.Empty, arrayType, block); statements.Add(new AssignmentStatement(localArray, new Construct(new MemberBinding(null, arrayType), new ExpressionList(), arrayType))); addMethod = arrayType.GetMethod(Identifier.For("Add"), SystemTypes.Object); } Block whileBody = new Block(new StatementList()); MethodCall moveToContent = new MethodCall(new QualifiedIdentifier(reader, Identifier.For("MoveToContent")), new ExpressionList()); BinaryExpression notAtEnd = new BinaryExpression(moveToContent, new QualifiedIdentifier(Identifier.For("XmlNodeType"), Identifier.For("EndElement")), NodeType.Ne); BinaryExpression notEOF = new BinaryExpression( new QualifiedIdentifier(reader, Identifier.For("EOF")), Literal.True, NodeType.Ne); While w = new While(new BinaryExpression(notAtEnd, notEOF, NodeType.And), whileBody); statements.Add(w); whileBody.Statements.Add(new AssignmentStatement(nameLocal, new QualifiedIdentifier(reader, Identifier.For("LocalName")))); whileBody.Statements.Add(new AssignmentStatement(nsLocal, new QualifiedIdentifier(reader, Identifier.For("NamespaceURI")))); whileBody.Statements.Add(new AssignmentStatement(nodeType, new QualifiedIdentifier(reader, Identifier.For("NodeType")))); StatementList trueStatements = whileBody.Statements; if (type.Template == SystemTypes.GenericBoxed){ type = Checker.GetCollectionElementType(type); } trueStatements.Add(new AssignmentStatement(foundChild, Literal.False)); if (eType is TupleType || eType is TypeUnion || IsStream(eType)) { AddCallDeserializer(eType, trueStatements, reader, local, optional, foundChild); } else { AddReadChild(whileBody, trueStatements, Checker.GetDefaultElementName(eType), eType, local, reader, foundChild, true, false); } If ifFound = new If(new BinaryExpression(foundChild, Literal.True, NodeType.Eq), new Block(new StatementList()), new Block(new StatementList())); ifFound.TrueBlock.Statements.Add(new AssignmentStatement(result, Literal.True)); // set our result to true then. ifFound.FalseBlock.Statements.Add(new Exit()); // break out of loop then. trueStatements.Add(ifFound); if (addMethod == null) { trueStatements.Add(new AssignmentStatement(target, CastTo(local, type))); // box the result. trueStatements.Add(new Exit()); // break out of loop we have it! } else { MemberBinding addCall = new MemberBinding(localArray, addMethod); trueStatements.Add(new ExpressionStatement(new MethodCall(addCall, new ExpressionList(new Expression[1] {local})))); } // clear out the local, it is a struct of some sort. if (local.Type.IsValueType && ! local.Type.IsPrimitive) { trueStatements.Add(new AssignmentStatement(local, new Construct(new MemberBinding(null,local.Type), new ExpressionList(), local.Type))); } // end while // assign resulting array to the target object (if we have anything to assign). If ifResult = new If(new BinaryExpression(result, Literal.True, NodeType.Eq), new Block(new StatementList()), null); statements.Add(ifResult); statements = ifResult.TrueBlock.Statements; if (addMethod != null) { if (type is ArrayType) { // target = (type)localArray.ToArray(etype); Method toArray = SystemTypes.ArrayList.GetMethod(Identifier.For("ToArray"), SystemTypes.Type); ExpressionList args = new ExpressionList(); args.Add(new UnaryExpression(new Literal(eType, SystemTypes.Type), NodeType.Typeof, SystemTypes.Type)); statements.Add(new AssignmentStatement(target, CastTo(new MethodCall(new MemberBinding(localArray, toArray), args, NodeType.Callvirt, SystemTypes.Array), type))); } else if (type.Template == SystemTypes.GenericNonEmptyIEnumerable) { // Explicit coercion of IEnumerable to NonEmptyIEnumerable requires constructing // the NonEmptyIEnumerable object passing in the IEnumerable as an argument. TypeNode ienumtype = Checker.GetIEnumerableTypeFromNonEmptyIEnumerableStruct(this.module, type); Debug.Assert(ienumtype!=null); //TODO: this call is invalid if the eType is not public TypeNode nonEmptyIEnum = SystemTypes.GenericNonEmptyIEnumerable.GetTemplateInstance(this.module, eType); InstanceInitializer ii = nonEmptyIEnum.GetConstructor(ienumtype); Construct c = new Construct(new MemberBinding(null, ii), new ExpressionList(localArray), nonEmptyIEnum); statements.Add(new AssignmentStatement(target, c)); } else { statements.Add(new AssignmentStatement(target, localArray)); } } }
private bool IsInvariantCall(MemberBinding mb) { if (mb.TargetObject != null) return false; if (this.parent.contractNodes.IsInvariantMethod(mb.BoundMember as Method)) return true; return false; }
Expression GetConvertFromString(TypeNode targetType, Expression src, bool always) { if (targetType == SystemTypes.String) return src;// nothing to do! if (targetType is EnumNode) { // e.g. return (DayOfWeek)Enum.Parse(typeof(DayOfWeek),"Sunday"); Method method = SystemTypes.Enum.GetMethod(Identifier.For("Parse"), new TypeNode[2]{ SystemTypes.Type, SystemTypes.String}); UnaryExpression typeOfEnum = new UnaryExpression(new MemberBinding(null, targetType), NodeType.Typeof); MethodCall call = new MethodCall(new MemberBinding(new MemberBinding(null, targetType), method), new ExpressionList(new Expression[2]{typeOfEnum, src }), NodeType.Call, SystemTypes.Object); return CastTo(call, targetType); } // See if it has a type converter. Class converterClass = Checker.GetTypeConverter(targetType); if (converterClass != null) { TypeConverter converter = TypeDescriptor.GetConverter(targetType.GetRuntimeType()); if (converter != null) { Type converterType = converter.GetType(); AssemblyNode converterAssembly = AssemblyNode.GetAssembly(converterType.Assembly, cache, false, true); converterClass = converterAssembly.GetType(Identifier.For(converterType.Namespace), Identifier.For(converterType.Name)) as Class; Expression e = tempChecker.GetConverterFromString(converter, converterClass, SystemTypes.String, src, SystemTypes.Object); if (e != null) { //Do I need to add namespace and assembly reference for type converter? return CastTo(e, targetType); } } } if (always) { // e.g. return PointArray.Parse("10,20 30,40 50,60"); Method method = targetType.GetImplicitCoercionFromMethod(SystemTypes.String); if (method == null) { method = targetType.GetMethod(Identifier.For("Parse"), new TypeNode[1]{ SystemTypes.String}); } if (method != null) { MemberBinding typeBinding = new MemberBinding(null, targetType); MethodCall call = new MethodCall(new MemberBinding(typeBinding, method), new ExpressionList(new Expression[1]{ src }), NodeType.Call, targetType ); return call; } } return null; }
public override void VisitMemberBinding(MemberBinding memberBinding) { if (memberBinding == null) return; if (memberBinding.BoundMember != null) { if (memberBinding.BoundMember.Name.Matches(ContractNodes.InvariantName) && memberBinding.BoundMember.DeclaringType.Name.Matches(ContractNodes.ContractClassName)) { // skip } else { this.referencedMembers.Add(memberBinding.BoundMember); } } base.VisitMemberBinding(memberBinding); }
MemberBinding GetMemberBinding(Expression source, Member m, TypeNode t) { MemberBinding src = new MemberBinding(source, m); src.Type = t; return src; }
public override void VisitMemberBinding(MemberBinding memberBinding) { Field f = memberBinding.BoundMember as Field; if (f != null) { this.Found = f; return; } base.VisitMemberBinding(memberBinding); }
public override Expression VisitMemberBinding(MemberBinding memberBinding) { // TODO: Just guessing here for now - need to understand this better. if (memberBinding == null) return null; if (memberBinding.TargetObject != null) this.VisitExpression(memberBinding.TargetObject); else if (memberBinding.BoundMember is TypeExpression) this.VisitExpression(((TypeExpression)memberBinding.BoundMember).Expression); else if (memberBinding.BoundMember is TypeNode) this.VisitTypeReference((TypeNode)memberBinding.BoundMember); else if (memberBinding.BoundMember is InstanceInitializer) this.VisitTypeReference(((InstanceInitializer)memberBinding.BoundMember).DeclaringType); else throw new NotImplementedException("Unexpected scenario in VisitMemberBinding"); return memberBinding; }
public override Expression VisitMemberBinding(MemberBinding binding) { Debug.Assert(false, "Reached a member binding node unexpectedly"); return null; }
public override void VisitMemberBinding(MemberBinding mb) { if (mb == null) return; var m = mb.BoundMember as Method; if (m == null) return; Method invMethod = this.InvariantMethods[m.UniqueKey] as Method; if (invMethod != null) { this.parent.HandleError(new Error(1042, "Explicit use of invariant method '" + invMethod.FullName + "' is not allowed.", this.lastSC)); } }
private Expression VisitMemberBindingExpression(MemberBinding binding) { if (binding.BoundMember.NodeType != NodeType.Field) { Debug.Assert(false, "MemberBinding scenario not yet supported"); return null; } if (binding.BoundMember is ParameterField) { Parameter param = ((ParameterField)binding.BoundMember).Parameter; if ((param.Flags & ParameterFlags.Out) != 0) return new QualifiedIdentifier(refOutputs, param.Name); else return new QualifiedIdentifier(refInputs, param.Name); } Field field = (Field)binding.BoundMember; Expression targetObject = binding.TargetObject; // for output parameters while (targetObject is AddressDereference) targetObject = ((AddressDereference)targetObject).Address; if (field.IsStatic) { // This is a reference to a global variable. Expression globalAccess = Templates.GetExpressionTemplate("GlobalFieldAccess"); Replacer.Replace(globalAccess, "_fieldName", new Identifier(string.Format(CultureInfo.InvariantCulture, "{0}_{1}", field.DeclaringType.Name.Name, field.Name.Name))); return globalAccess; } else if (field.DeclaringType is BlockScope) { return new QualifiedIdentifier(refLocals, field.Name); } else if (targetObject is ImplicitThis || targetObject is This) { Expression thisExpr = Templates.GetExpressionTemplate("ThisFieldAccess"); Replacer.Replace(thisExpr, "_objectType", targetObject.Type.Name); Replacer.Replace(thisExpr, "_fieldName", field.Name); return thisExpr; } else if (targetObject is MemberBinding || targetObject is Indexer) { // Need to distinguish between class field and struct field access. // Structs are not on the heap, so the pointer deref isn't appropriate. if (!field.DeclaringType.IsPrimitive && field.DeclaringType is Struct) { // we're gradually transforming struct // fields into properties so far, we've // done it for globals only, locals will // be added next, then heap objects... string propName = field.Name.Name; bool pFlatten = true; Expression prefix = null; // search for pattern var.struct1...structn.member while (true) { Field vField = null; MemberBinding vBinding = targetObject as MemberBinding; if (vBinding != null) { ParameterField pf = vBinding.BoundMember as ParameterField; if (pf != null) { // param.struct1...structn.member Parameter param = pf.Parameter; propName = param.Name.Name + "_" + propName; if ((param.Flags & ParameterFlags.Out) != 0) prefix = refOutputs; else prefix = refInputs; break; } } else { pFlatten = false; break; } vField = vBinding.BoundMember as Field; if (vField == null) { pFlatten = false; break; } propName = vField.Name.Name + "_" + propName; if (vField.IsStatic) { // global.struct1...structn.member propName = vField.DeclaringType.Name.Name + "_" + propName; prefix = new QualifiedIdentifier(Identifier.For("application"), Identifier.For("globals")); break; } else if (vField.DeclaringType is BlockScope) { // local.struct1...structn.member prefix = refLocals; break; } if (vField.DeclaringType.IsPrimitive || !(vField.DeclaringType is Struct)) { // can't match the pattern. let's bail prefix = null; pFlatten = false; break; } binding = vBinding; targetObject = binding.TargetObject; // for output parameters while (targetObject is AddressDereference) targetObject = ((AddressDereference)targetObject).Address; } if (pFlatten) { Debug.Assert(prefix != null); propName = "__strprops_" + propName; return new QualifiedIdentifier(prefix, Identifier.For(propName)); } else { Expression structRefExpr = Templates.GetExpressionTemplate("StructFieldAccess"); Replacer.Replace(structRefExpr, "_structExpr", this.VisitExpression(targetObject)); Replacer.Replace(structRefExpr, "_fieldName", field.Name); return structRefExpr; } } else { Expression derefExpr = Templates.GetExpressionTemplate("ClassFieldAccess"); Replacer.Replace(derefExpr, "_objectType", field.DeclaringType.Name); Replacer.Replace(derefExpr, "_ptrExpr", this.VisitExpression(targetObject)); Replacer.Replace(derefExpr, "_fieldName", field.Name); return derefExpr; } } else return base.VisitExpression(binding); }