/// <summary> /// Execute an expression /// </summary> /// <param name="expression">The expression to interpret</param> /// <returns>Returns the returned value of the expression</returns> internal object RunExpression(AlgorithmExpression expression) { object result = null; switch (expression.DomType) { case AlgorithmDomType.PrimitiveExpression: result = new PrimitiveValue(DebugMode, this, expression).Execute(); break; case AlgorithmDomType.PropertyReferenceExpression: result = new PropertyReference(DebugMode, this, expression).Execute(); break; case AlgorithmDomType.VariableReferenceExpression: result = new VariableReference(DebugMode, this, expression).Execute(); break; case AlgorithmDomType.ClassReferenceExpression: result = new ClassReference(DebugMode, this, expression).Execute(); break; case AlgorithmDomType.ThisReferenceExpression: result = new ThisReference(DebugMode, this, expression).Execute(); break; case AlgorithmDomType.InstanciateExpression: result = new Instanciate(DebugMode, this, expression).Execute(); break; case AlgorithmDomType.InvokeCoreMethodExpression: result = new InvokeCoreMethod(DebugMode, this, expression).Execute(); break; case AlgorithmDomType.InvokeMethodExpression: result = new InvokeMethod(DebugMode, this, expression).Execute(); break; case AlgorithmDomType.BinaryOperatorExpression: result = new BinaryOperator(DebugMode, this, expression).Execute(); break; case AlgorithmDomType.ArrayIndexerExpression: result = new ArrayIndexerExpression(DebugMode, this, expression).Execute(); break; default: ChangeState(this, new AlgorithmInterpreterStateEventArgs(new Error(new InvalidCastException($"Unable to find an interpreter for this expression : '{expression.GetType().FullName}'"), expression), GetDebugInfo())); break; } return(FailedOrStop ? null : result); }
/// <summary> /// Creates an instance of <see cref="ThisReference"/>. /// </summary> /// <returns>A <see cref="ThisReference"/></returns> protected ThisReference ThisReference() { if (CurrentFunction == null || !CurrentFunction.IsMethod || CurrentFunction.IsStatic) { throw new ParseException(FileName, token, Resources.ThisUsedOutOfMethod); } var thisRef = new ThisReference(); thisRef.CopyLocation(token); Consume(1); return(thisRef); }
private static List <IStatement> InitializeFieldsInConstructor(IMethodDefinition method) { Contract.Ensures(Contract.Result <List <IStatement> >() != null); var inits = new List <IStatement>(); if (method.IsConstructor || method.IsStaticConstructor) { var smb = method.Body as ISourceMethodBody; if (method.IsStaticConstructor || (smb != null && !FindCtorCall.IsDeferringCtor(method, smb.Block))) { var thisExp = new ThisReference() { Type = method.ContainingTypeDefinition, }; foreach (var f in method.ContainingTypeDefinition.Fields) { if (f.IsStatic == method.IsStatic) { var a = new Assignment() { Source = new DefaultValue() { DefaultValueType = f.Type, Type = f.Type, }, Target = new TargetExpression() { Definition = f, Instance = method.IsConstructor ? thisExp : null, Type = f.Type }, Type = f.Type, }; inits.Add(new ExpressionStatement() { Expression = a, }); } } } } return(inits); }
public override void RewriteChildren(ThisReference thisReference) { thisReference.Type = this.closureMethod.ContainingTypeDefinition; }
public void CompileThisReference(ThisReference thisRef) { textWriter.Write("this"); }
public void CompileThisReference(ThisReference thisRef) { currentElement.AppendChild(document.CreateElement("ThisReference")); }
private NamespaceTypeDefinition CreateContractReferenceAssemblyAttribute(IRootUnitNamespace rootNs) { var internFactory = this.host.InternFactory; var nameTable = this.host.NameTable; var contractReferenceAssemblyAttributeName = nameTable.GetNameFor("ContractReferenceAssemblyAttribute"); var contractNamespaceName = nameTable.GetNameFor("System.Diagnostics.Contracts"); #region Define type CustomAttribute compilerGeneratedAttribute = new CustomAttribute() { Constructor = new Microsoft.Cci.MethodReference( this.host, this.compilerGeneratedAttributeType, CallingConvention.HasThis, this.systemVoidType, this.host.NameTable.Ctor, 0) }; var contractsNs = new NestedUnitNamespace() { ContainingUnitNamespace = rootNs, Name = contractNamespaceName, }; NamespaceTypeDefinition result = new NamespaceTypeDefinition() { Name = contractReferenceAssemblyAttributeName, Attributes = new List <ICustomAttribute> { compilerGeneratedAttribute }, BaseClasses = new List <ITypeReference> { this.systemAttributeType }, ContainingUnitNamespace = contractsNs, //unitNamespace, InternFactory = internFactory, IsBeforeFieldInit = true, IsClass = true, IsSealed = true, Methods = new List <IMethodDefinition>(), Layout = LayoutKind.Auto, StringFormat = StringFormatKind.Ansi, }; contractsNs.Members.Add(result); this.allTypes.Add(result); #endregion Define type #region Define the ctor List <IStatement> statements = new List <IStatement>(); SourceMethodBody body = new SourceMethodBody(this.host) { LocalsAreZeroed = true, Block = new BlockStatement() { Statements = statements }, }; MethodDefinition ctor = new MethodDefinition() { Body = body, CallingConvention = CallingConvention.HasThis, ContainingTypeDefinition = result, InternFactory = internFactory, IsRuntimeSpecial = true, IsStatic = false, IsSpecialName = true, Name = nameTable.Ctor, Type = this.systemVoidType, Visibility = TypeMemberVisibility.Public, }; body.MethodDefinition = ctor; var thisRef = new ThisReference() { Type = result, }; // base(); foreach (var baseClass in result.BaseClasses) { var baseCtor = new Microsoft.Cci.MutableCodeModel.MethodReference() { CallingConvention = CallingConvention.HasThis, ContainingType = baseClass, GenericParameterCount = 0, InternFactory = this.host.InternFactory, Name = nameTable.Ctor, Type = this.systemVoidType, }; statements.Add( new ExpressionStatement() { Expression = new MethodCall() { MethodToCall = baseCtor, IsStaticCall = false, // REVIEW: Is this needed in addition to setting the ThisArgument? ThisArgument = new ThisReference() { Type = result, }, Type = this.systemVoidType, // REVIEW: Is this the right way to do this? Arguments = new List <IExpression>(), } } ); break; } // return; statements.Add(new ReturnStatement()); result.Methods.Add(ctor); #endregion Define the ctor return(result); }
private Expression ParsePrimaryExpression(TokenSet followers) //^ ensures followers[this.currentToken] || this.currentToken == Token.EndOfFile; { ISourceLocation sctx = this.scanner.SourceLocationOfLastScannedToken; Expression expression = new DummyExpression(sctx); switch (this.currentToken) { case Token.ArgList: this.GetNextToken(); expression = new RuntimeArgumentHandleExpression(sctx); break; case Token.Delegate: expression = this.ParseAnonymousMethod(followers); break; case Token.New: expression = this.ParseNew(followers|Token.Dot|Token.LeftBracket|Token.Arrow); break; case Token.Identifier: expression = this.ParseSimpleName(followers|Token.Dot|Token.DoubleColon|Token.Lambda|Token.LeftParenthesis); if (this.currentToken == Token.DoubleColon) { if (((SimpleName)expression).Name == this.nameTable.global) expression = new RootNamespaceExpression(expression.SourceLocation); expression = this.ParseQualifiedName(expression, followers|Token.Dot|Token.LessThan|Token.LeftParenthesis|Token.AddOne|Token.SubtractOne); } else if (this.currentToken == Token.Lambda) { expression = this.ParseLambda((SimpleName)expression, followers); } break; case Token.Null: expression = new NullLiteral(sctx); this.GetNextToken(); break; case Token.True: expression = new CompileTimeConstant(true, false, sctx); this.GetNextToken(); break; case Token.False: expression = new CompileTimeConstant(false, false, sctx); this.GetNextToken(); break; case Token.CharLiteral: expression = new CompileTimeConstant(this.scanner.charLiteralValue, false, sctx); this.GetNextToken(); break; case Token.HexLiteral: expression = this.ParseHexLiteral(); break; case Token.IntegerLiteral: expression = this.ParseIntegerLiteral(); break; case Token.RealLiteral: expression = this.ParseRealLiteral(); break; case Token.StringLiteral: expression = new CompileTimeConstant(this.scanner.GetString(), false, sctx); this.GetNextToken(); break; case Token.This: expression = new ThisReference(sctx); this.GetNextToken(); break; case Token.Base: expression = new BaseClassReference(sctx); this.GetNextToken(); break; case Token.Typeof: case Token.Sizeof: case Token.Default: expression = this.ParseTypeofSizeofOrDefault(followers); break; case Token.Stackalloc: return this.ParseStackalloc(followers); case Token.Checked: case Token.MakeRef: case Token.RefType: case Token.Unchecked: expression = this.ParseCheckedOrMakeRefOrRefTypeOrUnchecked(followers); break; case Token.RefValue: expression = this.ParseGetValueOfTypedReference(followers); break; case Token.Bool: case Token.Decimal: case Token.Sbyte: case Token.Byte: case Token.Short: case Token.Ushort: case Token.Int: case Token.Uint: case Token.Long: case Token.Ulong: case Token.Char: case Token.Float: case Token.Double: case Token.Object: case Token.String: expression = this.RootQualifiedNameFor(this.currentToken, sctx); this.GetNextToken(); break; case Token.LeftParenthesis: expression = this.ParseCastExpression(followers|Token.Dot|Token.LeftBracket|Token.Arrow); break; default: if (Parser.IdentifierOrNonReservedKeyword[this.currentToken]) goto case Token.Identifier; if (Parser.InfixOperators[this.currentToken]) { this.HandleError(Error.InvalidExprTerm, this.scanner.GetTokenSource()); //^ assume this.currentToken != Token.EndOfFile; //should not be a member of InfixOperators this.GetNextToken(); } else this.SkipTo(followers|Parser.PrimaryStart, Error.InvalidExprTerm, this.scanner.GetTokenSource()); if (Parser.PrimaryStart[this.currentToken]) return this.ParsePrimaryExpression(followers); goto done; } expression = this.ParseIndexerCallOrSelector(expression, followers|Token.AddOne|Token.SubtractOne); for (; ; ) { switch (this.currentToken) { case Token.AddOne: SourceLocationBuilder slb = new SourceLocationBuilder(expression.SourceLocation); slb.UpdateToSpan(this.scanner.SourceLocationOfLastScannedToken); this.GetNextToken(); expression = new PostfixIncrement(new TargetExpression(expression), slb); break; case Token.SubtractOne: slb = new SourceLocationBuilder(expression.SourceLocation); slb.UpdateToSpan(this.scanner.SourceLocationOfLastScannedToken); this.GetNextToken(); expression = new PostfixDecrement(new TargetExpression(expression), slb); break; case Token.Arrow: case Token.Dot: case Token.LeftBracket: expression = this.ParseIndexerCallOrSelector(expression, followers|Token.AddOne|Token.SubtractOne); break; default: goto done; } } done: this.SkipTo(followers); return expression; }
/// <summary> /// Returns a method whose body is empty, but which can be replaced with the real body when it is /// available. /// </summary> /// <remarks> /// Public because it needs to get called when an anonymous delegate is encountered /// while translating a method body. Just mapping the anonymous delegate doesn't /// provide the information needed. The parameters of a method reference are not /// IParameterDefinitions. /// </remarks> public MethodDefinition TranslateMetadata(IMethodSymbol methodSymbol) { Contract.Requires(methodSymbol != null); Contract.Ensures(Contract.Result <MethodDefinition>() != null); var containingType = (ITypeDefinition)this.typeSymbolCache[methodSymbol.ContainingType]; var isConstructor = methodSymbol.MethodKind == MethodKind.Constructor; List <IParameterDefinition> parameters = new List <IParameterDefinition>(); var m = new MethodDefinition() { CallingConvention = methodSymbol.IsStatic ? CallingConvention.Default : CallingConvention.HasThis, ContainingTypeDefinition = containingType, InternFactory = this.host.InternFactory, IsHiddenBySignature = true, // REVIEW IsNewSlot = containingType.IsInterface, // REVIEW IsRuntimeSpecial = isConstructor, IsSpecialName = isConstructor, IsStatic = methodSymbol.IsStatic, IsVirtual = containingType.IsInterface, // REVIEW: Why doesn't using methodSymbol.Virtual work for interface methods? Locations = Helper.WrapLocations(methodSymbol.Locations), Name = this.nameTable.GetNameFor(methodSymbol.Name), Parameters = parameters, Type = this.Map(methodSymbol.ReturnType), Visibility = this.Map(methodSymbol.DeclaredAccessibility), }; // IMPORTANT: Have to add it to the cache before doing anything else because it may // get looked up if it is generic and a parameter's type involves the generic // method parameter. this.methodSymbolCache.Add(methodSymbol, m); #region Define the generic parameters if (methodSymbol.IsGenericMethod) { var genericParameters = new List <IGenericMethodParameter>(); foreach (var gp in methodSymbol.TypeParameters) { var gp2 = this.CreateTypeDefinition(gp); genericParameters.Add((IGenericMethodParameter)gp2); } m.GenericParameters = genericParameters; } #endregion #region Define the parameters ushort i = 0; foreach (var p in methodSymbol.Parameters) { var p_prime = new ParameterDefinition() { ContainingSignature = m, IsByReference = p.RefKind == RefKind.Ref, IsIn = p.RefKind == RefKind.None, IsOut = p.RefKind == RefKind.Out, Name = nameTable.GetNameFor(p.Name), Type = this.Map(p.Type), Index = i++, }; parameters.Add(p_prime); } #endregion Define the parameters #region Define default ctor, if needed if (/*methodSymbol.IsSynthesized &&*/ isConstructor) // BUGBUG!! { m.IsHiddenBySignature = true; m.IsRuntimeSpecial = true; m.IsSpecialName = true; var statements = new List <IStatement>(); var body = new SourceMethodBody(this.host, null, null) { LocalsAreZeroed = true, Block = new BlockStatement() { Statements = statements }, }; var thisRef = new ThisReference() { Type = containingType, }; // base(); foreach (var baseClass in containingType.BaseClasses) { var baseCtor = new Microsoft.Cci.MutableCodeModel.MethodReference() { CallingConvention = CallingConvention.HasThis, ContainingType = baseClass, GenericParameterCount = 0, InternFactory = this.host.InternFactory, Name = nameTable.Ctor, Type = this.host.PlatformType.SystemVoid, }; statements.Add( new ExpressionStatement() { Expression = new MethodCall() { MethodToCall = baseCtor, IsStaticCall = false, // REVIEW: Is this needed in addition to setting the ThisArgument? ThisArgument = thisRef, Type = this.host.PlatformType.SystemVoid, // REVIEW: Is this the right way to do this? Arguments = new List <IExpression>(), } } ); break; } // return; statements.Add(new ReturnStatement()); body.MethodDefinition = m; m.Body = body; } #endregion return(m); }
private static NamespaceTypeDefinition DefineMethodHashAttributeType(HostEnvironment host, RootUnitNamespace rootUnitNamespace) { Contract.Requires(host != null); var internFactory = host.InternFactory; #region Define the type var methodHashAttributeType = new NamespaceTypeDefinition() { BaseClasses = new List <ITypeReference> { host.PlatformType.SystemAttribute, }, ContainingUnitNamespace = rootUnitNamespace, InternFactory = internFactory, //IsBeforeFieldInit = true, IsClass = true, IsPublic = true, //IsSealed = true, Methods = new List <IMethodDefinition>(1), Name = host.NameTable.GetNameFor("MethodHashAttribute"), //Layout = LayoutKind.Auto, //StringFormat = StringFormatKind.Ansi, }; #endregion #region Define the ctor var systemVoidType = host.PlatformType.SystemVoid; List <IStatement> statements = new List <IStatement>(); SourceMethodBody body = new SourceMethodBody(host) { LocalsAreZeroed = true, Block = new BlockStatement() { Statements = statements }, }; var ctor = new MethodDefinition() { Body = body, CallingConvention = CallingConvention.HasThis, ContainingTypeDefinition = methodHashAttributeType, InternFactory = internFactory, IsRuntimeSpecial = true, IsStatic = false, IsSpecialName = true, Name = host.NameTable.Ctor, Type = systemVoidType, Visibility = TypeMemberVisibility.Public, }; var systemStringType = host.PlatformType.SystemString; var systemIntType = host.PlatformType.SystemInt32; ctor.Parameters = new List <IParameterDefinition>() { new ParameterDefinition() { ContainingSignature = ctor, Name = host.NameTable.GetNameFor("a"), Type = systemStringType, Index = 0, }, new ParameterDefinition() { ContainingSignature = ctor, Name = host.NameTable.GetNameFor("b"), Type = systemIntType, Index = 1, } }; body.MethodDefinition = ctor; var thisRef = new ThisReference() { Type = methodHashAttributeType, }; // base(); foreach (var baseClass in methodHashAttributeType.BaseClasses) { var baseCtor = new Microsoft.Cci.MutableCodeModel.MethodReference() { CallingConvention = CallingConvention.HasThis, ContainingType = baseClass, GenericParameterCount = 0, InternFactory = internFactory, Name = host.NameTable.Ctor, Type = systemVoidType, }; statements.Add( new ExpressionStatement() { Expression = new MethodCall() { MethodToCall = baseCtor, IsStaticCall = false, // REVIEW: Is this needed in addition to setting the ThisArgument? ThisArgument = new ThisReference() { Type = methodHashAttributeType, }, Type = systemVoidType, // REVIEW: Is this the right way to do this? Arguments = new List <IExpression>(), } } ); break; } // return; statements.Add(new ReturnStatement()); methodHashAttributeType.Methods.Add(ctor); #endregion Define the ctor return(methodHashAttributeType); }
public BlockStatement GetMethodBody(IMethodDefinition cciMethod, BaseMethodDeclarationSyntax roslynMethod, bool extractContracts) { Contract.Requires(roslynMethod.Body != null); var expressionVisitor = new ExpressionVisitor(this.host, this.semanticModel, this.mapper, cciMethod); var sv = new StatementVisitor(this.host, this.semanticModel, this.mapper, cciMethod, expressionVisitor); var block = roslynMethod.Body; var statements = new List <IStatement>(); if (roslynMethod.Kind == SyntaxKind.ConstructorDeclaration) { var roslynCtor = roslynMethod as ConstructorDeclarationSyntax; var es = new List <IExpression>(); var ps = new List <IParameterTypeInformation>(); ITypeReference ctorClass = null; if (roslynCtor.Initializer != null) { switch (roslynCtor.Initializer.ThisOrBaseKeyword.Kind) { case SyntaxKind.BaseKeyword: ctorClass = cciMethod.ContainingTypeDefinition.BaseClasses.First(); // safe to assume there is always at least one? what if there are more than one? break; case SyntaxKind.ThisKeyword: ctorClass = cciMethod.ContainingType; break; default: var msg = String.Format("Was unable to convert {0} which was used for a base/this ctor call in {1}", roslynCtor.Initializer.ThisOrBaseKeyword, MemberHelper.GetMethodSignature(cciMethod)); throw new ConverterException(msg); } foreach (var a in roslynCtor.Initializer.ArgumentList.Arguments) { var e = expressionVisitor.Visit(a); es.Add(e); } } else { // Create a call to the nullary base constructor ctorClass = cciMethod.ContainingTypeDefinition.BaseClasses.First(); // safe to assume there is always at least one? what if there are more than one? } var thisRef = new ThisReference() { Type = cciMethod.ContainingType, }; var ctorRef = new Microsoft.Cci.MutableCodeModel.MethodReference() { CallingConvention = CallingConvention.HasThis, ContainingType = ctorClass, GenericParameterCount = 0, InternFactory = this.host.InternFactory, Name = nameTable.Ctor, Parameters = ps, Type = this.host.PlatformType.SystemVoid, }; statements.Add( new ExpressionStatement() { Expression = new MethodCall() { MethodToCall = ctorRef, IsStaticCall = false, ThisArgument = thisRef, Type = this.host.PlatformType.SystemVoid, Arguments = es, } } ); } statements.Add( new EmptyStatement() { Locations = Helper.SourceLocation(this.semanticModel.SyntaxTree, block.OpenBraceToken), } ); foreach (var s in block.Statements) { var s_prime = sv.Visit(s); statements.Add(s_prime); } // REVIEW: need to do this only if debugging info is needed? // (But if it isn't done, then there can be unreachable nops // corresponding to close curlys for blocks because of return // statements within the block. When that happens at the method // level, then peverify is unhappy with the assembly.) //if (false) { // // commented this out because it is needed only if this is being used // // to generate IL that in the end should pass peverify (and run). // statements = CreateUnifiedReturnPoint(statements, cciMethod.Type); //} BlockStatement bs = new BlockStatement() { Statements = statements, }; return(bs); }