The StaDyn Programming Language
Source code documentation of StaDyn, a hybrid static and dynamic typing language.
VisitorCLRCodeGeneration.cs
Go to the documentation of this file.
1 // --------------------------------------------------------------------------
3 // Project StaDyn
4 // --------------------------------------------------------------------------
5 // File: VisitorCLRCodeGeneration.cs
6 // Author: Francisco Ortin - francisco.ortin@gmail.com
7 // Daniel Zapico - daniel.zapico.rodriguez@gmail.com
8 // Description:
9 // This class walks the AST to obtain the CLR IL code .
10 // Inheritance: VisitorCodeGeneration
11 // Implements Visitor pattern [Concrete Visitor].
12 // Implements Factory method [Concrete Product].
13 // --------------------------------------------------------------------------
14 // Create date: 21-08-2007
15 // Modification date: 21-08-2007
17 
18 using System;
19 using System.Collections.Generic;
20 
21 using AST;
22 using TypeSystem;
23 using CodeGeneration.Operations;
24 
25 namespace CodeGeneration {
34  class VisitorCLRCodeGeneration<T> : VisitorILCodeGeneration<T> where T : CLRCodeGenerator {
35  #region Constructor
36  public VisitorCLRCodeGeneration(string moduleName, T codeGenerator)
43  : base(moduleName, codeGenerator) { }
44  #endregion
45 
46  #region Visit(InvocationExpression node, Object obj)
47 
48  #region Pattern: runtime check union methods
49 
69 
70  #endregion
71  public override Object Visit(InvocationExpression node, Object obj) {
72  InheritedAttributes ia = (InheritedAttributes)obj; //Simple cast to shorten thee expression
73  Object objArgs = obj;
74  //Object o = null;
76  MethodType actualMethodCalled = TypeExpression.As<MethodType>(node.ActualMethodCalled);
77 
78  if ( actualMethodCalled != null )
79  objArgs = new InheritedAttributes(ia.CurrentMethod, ia.Assignment, ia.Reference, ia.ArrayAccessFound, actualMethodCalled, true);
80 
81  return node.Identifier.AcceptOperation(new CGILInvocationExpressionOperation<T>(this.indent, this, this.codeGenerator, node, ia, objInv, objArgs), null);
82  }
83 
84  #endregion
85 
86  internal override void RuntimeCheckArguments(InvocationExpression node, Object objArgs, MethodType actualMethodCalled, List<string> nextMethod) {
87  for (int j = 0; j < node.Arguments.ExpressionCount; j++) {
88  node.Arguments.GetExpressionElement(j).Accept(this, objArgs);
89  actualMethodCalled.GetParameter(j).AcceptOperation(new CGRuntimeCheckArgumentOperation<T>(this.indent, this.codeGenerator, nextMethod), null);
90  //if ((!(actualMethodCalled.GetParameter(j).IsValueType()))
91  // || (actualMethodCalled.GetParameter(j) is BoolType) || (actualMethodCalled.GetParameter(j) is CharType))
92  //{
93  // this.codeGenerator.dup(this.indent);
94  // this.codeGenerator.isinst(this.indent, actualMethodCalled.GetParameter(j));
95  // // if check fail then check nextMethod
96  // nextMethod.Add(this.codeGenerator.NewLabel);
97  // this.codeGenerator.brfalse(this.indent, nextMethod[nextMethod.Count - 1]);
98  // if (actualMethodCalled.GetParameter(j).IsValueType())
99  // this.codeGenerator.UnboxAny(this.indent, actualMethodCalled.GetParameter(j));
100  //}
101  //else
102  //{
103  // // Param is Int. Is the argument an int?
104  // if (actualMethodCalled.GetParameter(j) is IntType)
105  // {
106  // string nextArgument = this.codeGenerator.NewLabel;
107  // CharType.Instance.AcceptOperation(new CGRuntimeCheckTypeExpressionOperation(this.indent, this.codeGenerator, nextArgument, false));
108  // IntType.Instance.AcceptOperation(new CGRuntimeCheckTypeExpressionOperation(this.indent, this.codeGenerator, nextArgument, false));
109 
110  // nextMethod.Add(this.codeGenerator.NewLabel);
111  // this.codeGenerator.br(this.indent, nextMethod[nextMethod.Count - 1]);
112  // this.codeGenerator.WriteLabel(nextArgument);
113  // }
114  // else
115  // {
116  // // Param is Double. Is the argument a double?
117  // if (actualMethodCalled.GetParameter(j) is DoubleType)
118  // {
119  // string nextArgument = this.codeGenerator.NewLabel;
120 
121  // CharType.Instance.AcceptOperation(new CGRuntimeCheckTypeExpressionOperation(this.indent, this.codeGenerator, nextArgument, true));
122  // IntType.Instance.AcceptOperation(new CGRuntimeCheckTypeExpressionOperation(this.indent, this.codeGenerator, nextArgument, true));
123  // DoubleType.Instance.AcceptOperation(new CGRuntimeCheckTypeExpressionOperation(this.indent, this.codeGenerator, nextArgument, true));
124 
125  // nextMethod.Add(this.codeGenerator.NewLabel);
126  // this.codeGenerator.br(this.indent, nextMethod[nextMethod.Count - 1]);
127  // this.codeGenerator.WriteLabel(nextArgument);
128  // }
129  // }
130  //}
131  }
132  }
133 
134  #region runtimeCheckTypeExpression()
135 
142  // private void runtimeCheckTypeExpression(string endLabel, TypeExpression type, bool toDouble)
143  //{
144  // type.AcceptOperation(new CGRuntimeCheckTypeExpressionOperation(this.indent, this.codeGenerator, endLabel, toDouble));
145  //string notThisType = this.codeGenerator.NewLabel;
146 
147  //this.codeGenerator.dup(this.indent);
148  //this.codeGenerator.isinst(this.indent, type);
149  //this.codeGenerator.brfalse(this.indent, notThisType);
150  //this.codeGenerator.UnboxAny(this.indent, type);
151  //if ((toDouble) && (!(type is DoubleType)))
152  // this.codeGenerator.convToDouble(this.indent);
153  //this.codeGenerator.br(this.indent, endLabel);
154  //this.codeGenerator.WriteLabel(notThisType);
155  //}
156 
157  #endregion
158 
159 
160 
161  #region IntrospectiveInvocation()
162  internal void IntrospectiveInvocation(InvocationExpression node, Object obj, Object inheritedAttributes, string memberName) {
167  InheritedAttributes ia = (InheritedAttributes)obj;
168  ia.IsParentNodeAnInvocation = true;
169  Object o = node.Identifier.Accept(this, ia);
170  this.IntrospectiveGetMethod(node, ia, memberName);
171  node.Identifier.Accept(this, ia);
172  this.codeGenerator.ldci4(this.indent, node.Arguments.ExpressionCount);
173  this.codeGenerator.newarr(this.indent, "[mscorlib]System.Object");
174  for (int i = 0; i < node.Arguments.ExpressionCount; i++)
175  IntrospectiveInvocationMakeReadyArgument(node, ia, i);
176  this.codeGenerator.CallVirt(this.indent, "instance", "object", "[mscorlib]System.Reflection.MethodBase", "Invoke", new string[] { "object", "object[]" });
177  }
178 
179  private void IntrospectiveGetMethod(InvocationExpression node, InheritedAttributes ia, String memberName)
180  {
181  String end = this.codeGenerator.NewLabel;
182  this.codeGenerator.CallVirt(this.indent, "instance class", "[mscorlib]System.Type", "[mscorlib]System.Object", "GetType", null);
183  this.codeGenerator.ldstr(this.indent, memberName);
184  this.codeGenerator.ldci4(this.indent, node.Arguments.ExpressionCount);
185  this.codeGenerator.newarr(this.indent, "[mscorlib]System.Type");
186  for (int i = 0; i < node.Arguments.ExpressionCount; i++)
187  {
188  TypeExpression argType = node.Arguments.GetExpressionElement(i).ILTypeExpression;
189  this.IntropectiveInvocationLoadArgument(i, argType);
190  }
191  this.codeGenerator.CallVirt(this.indent, "instance class", "[mscorlib]System.Reflection.MethodInfo", "[mscorlib]System.Type", "GetMethod", new string[] { "string", "class [mscorlib]System.Type[]" });
192  this.codeGenerator.dup(this.indent);
193  this.codeGenerator.brtrue(this.indent,end);
194  this.codeGenerator.pop(this.indent);
195  node.Identifier.Accept(this, ia);
196  this.codeGenerator.CallVirt(this.indent, "instance class", "[mscorlib]System.Type", "[mscorlib]System.Object", "GetType", null);
197  this.codeGenerator.ldstr(this.indent, memberName);
198  this.codeGenerator.CallVirt(this.indent, "instance class", "[mscorlib]System.Reflection.MethodInfo", "[mscorlib]System.Type", "GetMethod", new string[] { "string" });
199  this.codeGenerator.WriteLabel(this.indent, end);
200  }
201 
208  private void IntrospectiveInvocationMakeReadyArgument(InvocationExpression node, Object inheritedAttributes, int i) {
209  TypeExpression argType = node.Arguments.GetExpressionElement(i).ILTypeExpression;
210  this.codeGenerator.dup(this.indent);
211  this.codeGenerator.ldci4(this.indent, i);
212  node.Arguments.GetExpressionElement(i).Accept(this, inheritedAttributes);
213  this.codeGenerator.BoxIfNeeded(this.indent, argType);
214  this.codeGenerator.stelemRef(this.indent);
215  }
221  private void IntropectiveInvocationLoadArgument(int index, TypeExpression argType) {
222  this.codeGenerator.dup(this.indent);
223  this.codeGenerator.ldci4(this.indent, index);
224  this.codeGenerator.ldtoken(this.indent, TypeMapping.Instance.GetBCLName(argType.ILType(), true));
225  this.codeGenerator.Call(this.indent, "class", "[mscorlib]System.Type", "[mscorlib]System.Type", "GetTypeFromHandle", new string[] { "valuetype [mscorlib]System.RuntimeTypeHandle" });
226  this.codeGenerator.stelemRef(this.indent);
227  }
228 
229 
230 
231  #endregion
232  }
233 }
Encapsulates a invocation expression.
MethodType ActualMethodCalled
Gets or sets the type expression of the current invocation expression. If not exists, their value is null.
Abstract class that represents all different types.
bool ArrayAccessFound
Gets or sets true if array access expression found. Otherwise, gets or sets false.
MethodDefinition CurrentMethod
Gets or sets the current method definition node.
This class encapsulates the IL CLR code generator IL.
Expression Reference
Gets or sets the reference of a concrete identifier.
It typechecks the runtime arguments, embeded in a method call, with the parametes of this method...
override Object Visit(InvocationExpression node, Object obj)
This class encapsulates several inherited attributes used in code generation process.
bool Assignment
Gets or sets true if assignment expression found. Otherwise, gets or sets false.
Representa a method type.
Definition: MethodType.cs:37