The StaDyn Programming Language
Source code documentation of StaDyn, a hybrid static and dynamic typing language.
ILCodeGenerator.cs
Go to the documentation of this file.
1 using TypeSystem;
2 using System.IO;
3 using CodeGeneration.ExceptionManagement;
4 using System;
5 using AST;
6 using CodeGeneration.Operations;
7 namespace CodeGeneration {
8  abstract public class ILCodeGenerator : CodeGenerator {
9 
10  #region Fields
12 
13  #endregion
14 
15  #region NewLabel
16  //TODO: Revisar si se mueve a ilStamentsCodeGeneration
17  public override string NewLabel {
18  get { return "IL_" + this.currentLabel++; }
19  }
20  #endregion
21 
22  #region Index of Local variables
23 
24  private static int localVariableIndex = 0;
25 
26  #endregion
27 
28  #region Properties
29 
30  public int LocalVariableIndex {
31  get { return localVariableIndex; }
32  set { localVariableIndex = value; }
33  }
34 
35  #endregion
36 
37  #region Constructors
38 
39  public ILCodeGenerator(TextWriter output)
40  : base(output) {
41  // EL único que accede al fichero
42  this.ilStamentsCodeGeneration = new ILStatementsCodeGeneration(output);
43  }
44 
45  #endregion
46 
47  #region InitialComent
48  public override void InitialComment() {
52  this.ilStamentsCodeGeneration.WriteLine();
53  this.Comment("=============== CLASS MEMBERS DECLARATION ===================");
54  }
55  #endregion
56 
57  #region WriteConstructorHeader()
58 
59  internal override void WriteConstructorHeader(int indent) {
60  this.ilStamentsCodeGeneration.WriteLine(indent, ".method public specialname rtspecialname instance void .ctor()");
61  }
62 
63  #endregion
64 
65  #region WriteStaticConstructorHeader()
66 
67  internal override void WriteStaticConstructorHeader(int indent) {
68  this.ilStamentsCodeGeneration.WriteLine(indent, ".method public specialname rtspecialname static void .cctor()");
69  }
70 
71  #endregion
72 
73  #region WriteComment
74  public override void Comment(string msg) {
79  this.ilStamentsCodeGeneration.WriteComment(msg);
80  }
81 
87  public override void Comment(int indent, string msg) {
88  this.ilStamentsCodeGeneration.WriteComment(indent, msg);
89  }
90  #endregion
91 
92  #region WriteLabel
93  public override void WriteLabel(int indentation, string label) {
98  this.ilStamentsCodeGeneration.WriteLine(indentation, label + ": nop");
99  }
100 
101  #endregion
102 
103  #region WriteType()
104 
109  public override void WriteType(TypeExpression type) {
110  this.ilStamentsCodeGeneration.WriteType(type);
111  }
112 
113  #endregion
114 
115  #region WriteHeader()
116 
121  public override void WriteHeader(string fileName) {
122  this.ilStamentsCodeGeneration.WriteLNAssemblyDirective(fileName);
123  this.ilStamentsCodeGeneration.WriteModule(fileName);
124  }
125 
126  #endregion
127 
128  #region WriteNamespaceHeader()
129  // .namespace <name>
135  public override void WriteNamespaceHeader(int indent, string name) {
136  this.ilStamentsCodeGeneration.WriteIndentation(indent);
137  this.ilStamentsCodeGeneration.WriteNamespace(name);
138  this.ilStamentsCodeGeneration.WriteLine();
139  this.ilStamentsCodeGeneration.WriteOpenBrace(indent);
140  }
141 
142  #endregion
143 
144  #region WriteClassName
145 
146  public virtual void WriteClassName(string name) {
147  this.ilStamentsCodeGeneration.Write("auto ansi {0} ", name);
148  }
149 
150  #endregion
151 
152  #region WriteClassExtends
153 
154  public virtual void WriteClassExtends(ClassType type) {
155  this.ilStamentsCodeGeneration.Write("extends ");
156  if (type.BaseClass == null)
157  this.ilStamentsCodeGeneration.Write("[mscorlib]System.Object");
158  else
159  this.ilStamentsCodeGeneration.Write(TypeMapping.Instance.GetBCLName(type.BaseClass.FullName, true).ToString());
160  }
161  #endregion
162 
163  #region WriteClassImplements
164 
165  public virtual void WriteClassImplements(ClassType type) {
166  if (type.InterfaceList.Count == 0) // {P} type.InterfaceList.Count != 0)
167  return;
168 
169  this.ilStamentsCodeGeneration.Write(" implements ");
170  for (int i = 0; i < type.InterfaceList.Count - 1; i++) {
171  if (type.InterfaceList[i] is BCLInterfaceType)
172  this.ilStamentsCodeGeneration.Write("[mscorlib]");
173  this.ilStamentsCodeGeneration.Write("{0}, ", type.InterfaceList[i].FullName);
174  }
175  if (type.InterfaceList[type.InterfaceList.Count - 1] is BCLInterfaceType)
176  this.ilStamentsCodeGeneration.Write("[mscorlib]");
177  this.ilStamentsCodeGeneration.Write("{0}", type.InterfaceList[type.InterfaceList.Count - 1].FullName);
178  }
179 
180  #endregion
181 
182  #region WriteLNClassHeader()
183 
190  public override void WriteLNClassHeader(int indent, string name, ClassType type) {
191  this.ilStamentsCodeGeneration.WriteClassVisibility(indent, name, type);
192  this.WriteClassName(name);
193  this.WriteClassExtends(type);
194  this.WriteClassImplements(type);
195  this.ilStamentsCodeGeneration.WriteLine();
196  }
197 
198  #endregion
199 
200  #region WriteEndOfClass()
201 
207  public override void WriteEndOfClass(int indent, string name) {
208  //this.ilStamentsCodeGeneration.WriteIndentation(indent);
209  this.ilStamentsCodeGeneration.WriteCloseBrace(indent);
210  this.ilStamentsCodeGeneration.WriteComment(name);
211  }
212 
213  #endregion
214 
215  #region WriteLNInterfaceHeader()
216 
217  public override void WriteInterfaceHeader(int indent, string name, InterfaceType type) {
218  this.ilStamentsCodeGeneration.WriteLNInterfaceHeader(indent, name, type);
219  }
220  #endregion
221 
222  #region WriteLNEndOfInterface()
223 
229  public override void WriteEndOfInterface(int indent, string name) {
230  //this.ilStamentsCodeGeneration.WriteIndentation(indent);
231  this.ilStamentsCodeGeneration.WriteCloseBrace(indent);
232  this.ilStamentsCodeGeneration.WriteComment("End of interface " + name);
233  }
234  #endregion
235 
236  #region ProcessField()
237 
238  virtual public void ProcessField(int indent, FieldDeclaration node, Object obj, bool constantField) {
239  this.ilStamentsCodeGeneration.WriteLine(); //*
240  this.WriteField(indent, ((FieldType)node.TypeExpr).MemberInfo.MemberIdentifier, (FieldType)node.TypeExpr, constantField);
241  this.ilStamentsCodeGeneration.WriteLine(); //*
242  }
243  #endregion
244 
245  #region WriteField()
246 
247  public override void WriteField(int indent, string name, FieldType type, bool constantField) {
248  this.ilStamentsCodeGeneration.WriteField(indent, name, type, constantField);
249  }
250 
251  #endregion
252 
253  #region WriteLNFieldInitialization()
254 
255  public override void WriteLNFieldInitialization(TypeExpression type) {
256  this.ilStamentsCodeGeneration.WriteFieldInitialization(type);
257  }
258 
259  #endregion
260 
261  #region WriteEndOfField()
262 
266  public override void WriteEndOfField() {
267  this.ilStamentsCodeGeneration.Write(")");
268  }
269 
270  #endregion
271 
272  #region WriteStartBlock()
273 
278  public override void WriteStartBlock(int indent) {
279  this.ilStamentsCodeGeneration.WriteOpenBrace(indent);
280  }
281 
282  #endregion
283 
284  #region WriteLNEndOfBlock()
285 
290  public override void WriteEndOfBlock(int indent) {
291  this.ilStamentsCodeGeneration.WriteLineCloseBrace(indent); ;
292  }
293 
294  #endregion
295 
296  #region WriteLNMethodHeader
297 
298  // .method <flags> <call_conv> <ret_type> <name>(<arg_list>) <impl> { <method_body> }
299  // <flags> := public (public)
300  // | private (private)
301  // | assembly (internal)
302  // | family (protected)
303  // | famorassem (protected internal)
304  // | static (static)
305  // | newslot virtual (virtual)
306  // | virtual (override)
307  // | newslot abstract virtual (abstract)
308  //
309  // Method modifiers: new, public, protected, internal, private, static, virtual, sealed,
310  // override, abstract, extern
311  // Method cannot be both virtual and static
312  //
313  // Sealed and extern modifier currently does not apply because it is commented in grammar file.
314 
321  public override void WriteLNMethodHeader(int indent, string name, MethodType type) {
322  WriteMethodModifiers(indent, type);
323  WriteMethodTypeOfAccess(name, type);
324  WriteMethodParameters(type);
326  }
327  #endregion
328 
329  #region WriteLNMethodEndOfHeader
330  protected virtual void WriteLNMethodEndOfHeader() {
331  this.ilStamentsCodeGeneration.WriteLine(") cil managed");
332  }
333  #endregion
334  // Este métodoo y el siguiente se dejan aquí por si puede aprovecharse para Rotor y CLR de no poder se delegaria
335  // en ilStamentesCodeGeneration
336  #region WriteMethodModifiers
337  protected virtual void WriteMethodModifiers(int indent, MethodType type) {
338  Modifier mask = type.MemberInfo.ModifierMask;
339 
340  this.ilStamentsCodeGeneration.Write(indent, ".method ");
341 
342  if (type.MemberInfo.Class is InterfaceType) {
343  this.ilStamentsCodeGeneration.Write("public hidebysig ");
344  return;
345  }
346 
347  if ((mask & Modifier.Public) != 0)
348  this.ilStamentsCodeGeneration.Write("public ");
349  if ((mask & Modifier.Private) != 0)
350  this.ilStamentsCodeGeneration.Write("private ");
351  if ((mask & (Modifier.Protected | Modifier.Internal)) == (Modifier.Protected | Modifier.Internal))
352  this.ilStamentsCodeGeneration.Write("famorassem ");
353  else {
354  if ((mask & Modifier.Internal) != 0)
355  this.ilStamentsCodeGeneration.Write("assembly ");
356  if ((mask & Modifier.Protected) != 0)
357  this.ilStamentsCodeGeneration.Write("family ");
358  }
359  this.ilStamentsCodeGeneration.Write("hidebysig ");
360  }
361  #endregion
362 
363  #region WriteMethodTypeOfAccess
364 
365  public virtual void WriteMethodTypeOfAccess(string name, MethodType type) {
366  Modifier mask = type.MemberInfo.ModifierMask;
367  bool constructorFound = type.MemberInfo.Class.Name.Equals(name);
368  if ((mask & Modifier.Virtual) != 0)
369  this.ilStamentsCodeGeneration.Write("newslot virtual ");
370  if ((mask & Modifier.Override) != 0)
371  this.ilStamentsCodeGeneration.Write("virtual ");
372  if ((mask & Modifier.Abstract) != 0 || type.MemberInfo.Class is InterfaceType)
373  this.ilStamentsCodeGeneration.Write("newslot abstract virtual ");
374 
375  if (constructorFound)
376  this.ilStamentsCodeGeneration.Write("specialname rtspecialname ");
377 
378  if ((mask & Modifier.Static) == 0 && !constructorFound &&
379  type.MemberInfo.Class.InterfaceList.Count > 0) {
380  this.ilStamentsCodeGeneration.Write("virtual final ");
381  }
382 
383  if ((mask & Modifier.Static) != 0)
384  this.ilStamentsCodeGeneration.Write("static ");
385  else
386  this.ilStamentsCodeGeneration.Write("instance ");
387 
388  if (constructorFound) {
389  this.ilStamentsCodeGeneration.Write("void");
390  if ((mask & Modifier.Static) != 0)
391  this.ilStamentsCodeGeneration.Write(" .cctor(");
392  else
393  this.ilStamentsCodeGeneration.Write(" .ctor(");
394  } else {
395  if (type.Return is FieldType && ((FieldType)type.Return).FieldTypeExpression is TypeVariable)
397  else
398  this.WriteType(type.Return);
399  this.ilStamentsCodeGeneration.Write(" {0}(", name);
400  }
401  }
402 
403  #endregion
404 
405  #region WriteMethodParameters
406  public virtual void WriteMethodParameters(MethodType type) {
407  if (type.ParameterListCount == 0) // {P} type.ParameterListCount>0
408  return;
409  this.WriteType(type.GetParameter(0));
410  this.ilStamentsCodeGeneration.Write(" {0}", type.ASTNode.ParametersInfo[0].ILName);
411  for (int i = 1; i < type.ParameterListCount; i++)
412  this.ilStamentsCodeGeneration.Write(", {0} {1}", type.GetParameter(i).ILType(), type.ASTNode.ParametersInfo[i].ILName);
413  }
414  #endregion
415 
416  #region WriteEndOfMethod()
417 
423  public override void WriteEndOfMethod(int indent, string name) {
424  this.ilStamentsCodeGeneration.WriteCloseBrace(indent);
425  this.ilStamentsCodeGeneration.WriteComment("End of method " + name);
426  }
427 
428  #endregion
429 
430  #region WriteParams()
431  public override void WriteParams(MethodType memberType, AST.CompoundExpression arguments) {
436  this.ilStamentsCodeGeneration.Write("("); // start of signature
437  if (memberType != null)
438  // * When a method is known (not free type variable) we use the formal parameters
439  if (memberType.ParameterListCount != 0) {
440  this.ilStamentsCodeGeneration.Write(memberType.GetParameter(0).ILType());
441  for (int i = 1; i < memberType.ParameterListCount; i++)
442  this.ilStamentsCodeGeneration.Write(", {0}", memberType.GetParameter(i).ILType());
443  } else if (arguments != null && arguments.ExpressionCount != 0) { // * When a method is not known (free type variable) we use the actual parameters (arguments)
444  this.ilStamentsCodeGeneration.Write(arguments.GetExpressionElement(0).ILTypeExpression.ILType());
445  for (int i = 1; i < arguments.ExpressionCount; i++)
446  this.ilStamentsCodeGeneration.Write(", {0}", arguments.GetExpressionElement(i).ILTypeExpression.ILType());
447  }
448  this.ilStamentsCodeGeneration.Write(")"); // end of signature
449  }
450  #endregion
451 
452  #region AddLocalVariable()
453  public override void AddLocalVariable(string name, TypeExpression type) {
459  if (this.currentLocalVars.Length == 0)
460  LocalVariableIndex = 0;
461  else
462  this.currentLocalVars.Append(",");
463  this.currentLocalVars.AppendLine();
464  this.currentLocalVars.AppendFormat("\t\t\t[{0}] {1} {2}", LocalVariableIndex++, type.ILType(), name);
465  }
466 
467  #endregion
468 
469  #region WriteLocalVariable()
470  public override void WriteLocalVariable(int indent) {
475  if (this.currentLocalVars.Length == 0) // {p} this.currentLocalVars.Length != 0
476  return;
477  this.ilStamentsCodeGeneration.WriteIndentation(indent);
478  this.ilStamentsCodeGeneration.WriteLine(".locals init({0})", this.currentLocalVars);
479  this.currentLocalVars.Remove(0, this.currentLocalVars.Length);
480  }
481 
482  #endregion
483 
484  #region WriteAuxiliarLocalVariable()
485  public override void WriteAuxiliarLocalVariable(int indent, string id, string type) {
492  this.ilStamentsCodeGeneration.WriteIndentation(indent);
493  this.ilStamentsCodeGeneration.WriteAuxiliarLocalVariable(id, type);
494  this.ilStamentsCodeGeneration.WriteLine();
495  }
496 
497  #endregion
498 
499  #region WriteEntryPoint ()
500 
501  public override void WriteEntryPoint(int indent) {
502  this.ilStamentsCodeGeneration.WriteIndentation(indent);
503  this.ilStamentsCodeGeneration.WriteEntryPoint();
504  this.ilStamentsCodeGeneration.WriteLine();
505  }
506 
507  #endregion
508 
509  #region ThrowDirective ()
510 
511  public override void WriteTryDirective(int indent) {
512  this.ilStamentsCodeGeneration.WriteIndentation(indent);
513  this.ilStamentsCodeGeneration.WriteLine(".try");
514  }
515  public override void WriteOpenBraceTry(int indent) {
516  this.ilStamentsCodeGeneration.WriteIndentation(indent);
517  this.ilStamentsCodeGeneration.WriteLine("{");
518  }
519  public override void WriteCloseBraceTry(int indent) {
520  this.ilStamentsCodeGeneration.WriteIndentation(indent);
521  this.ilStamentsCodeGeneration.WriteLine("} // end .try");
522  }
523  public void WriteRethrow(int indent) {
524  this.WriteLNNoArgsCommand(indent, "rethrow");
525  }
526 
527  #endregion
528 
529  #region Catch()
530 
531  public override void WriteCatch(int indent, String type, String var) {
532  this.ilStamentsCodeGeneration.WriteIndentation(indent);
533  this.ilStamentsCodeGeneration.WriteLine("catch " + (var == null ? String.Empty : var));
534  }
535  public override void WriteOpenBraceCatch(int indent) {
536  this.ilStamentsCodeGeneration.WriteIndentation(indent);
537  this.ilStamentsCodeGeneration.WriteLine("{");
538 
539  }
540  public override void WriteCloseBraceCatch(int indent) {
541  this.ilStamentsCodeGeneration.WriteIndentation(indent);
542  this.ilStamentsCodeGeneration.WriteLine("} // end handler");
543  }
544 
545  #endregion
546 
547  #region Finally()
548 
549  public override void WriteFinally(int indent) {
550  this.ilStamentsCodeGeneration.WriteIndentation(indent);
551  this.ilStamentsCodeGeneration.WriteLine("finally");
552  }
553  public override void WriteOpenBraceFinally(int indent) {
554  this.ilStamentsCodeGeneration.WriteIndentation(indent);
555  this.ilStamentsCodeGeneration.WriteLine("{");
556  }
557  public override void WriteCloseBraceFinally(int indent) {
558  this.ilStamentsCodeGeneration.WriteIndentation(indent);
559  this.ilStamentsCodeGeneration.WriteLine("} // end .try");
560  }
561 
562  #endregion
563 
564  public virtual void WriteThrowMissingMethodException(int indent, string method)
565  {
566  WriteAuxiliarLocalVariable(indent, "_temp_top_stack_str_", "string");
567  WriteLNNoArgsCommand(indent, "callvirt instance class [mscorlib]System.Type [mscorlib]System.Object::GetType()");
568  WriteLNNoArgsCommand(indent, "callvirt instance string [mscorlib]System.Reflection.MemberInfo::get_Name()");
569  Comment(indent, "//in the top of the stack there is the name of the class");
570 
571  // swappingt he top of the stack with the string inmediately bellow
572  stloc(indent, "_temp_top_stack_str_");
573  ldstr(indent, "Class {0} does not accept message {1}().");
574  ldloc(indent, "_temp_top_stack_str_");
575  ldstr(indent, method);
576 
577  WriteLNNoArgsCommand(indent, "call string [mscorlib]System.String::Format(string,object, object)");
578  WriteThrowException(indent, "[mscorlib]System.MissingMemberException", new string[] { "string" });
579  }
580 
581  public virtual void WriteThrowNonSuitableObjectException(int indent, string klass, string method) {
582  ldstr(indent, String.Format("Class {0} does not accept message {1}().", klass, method));
583  WriteThrowException(indent, "[mscorlib]System.MissingMemberException", new string[] { "string" });
584  }
585  #region AddExceptionCode()
586 
591  public void AddExceptionCode(DynamicExceptionManager typeException) {
592  if (this.exceptions.ContainsKey(typeException.TypeName)) // {P} the exception isn't included yet
593  return;
594 
595  this.exceptions.Add(typeException.TypeName, typeException);
596  DynamicExceptionManager baseType = typeException.BaseException;
597  while (baseType != null)
598  if (!this.exceptions.ContainsKey(baseType.TypeName)) {
599  this.exceptions.Add(baseType.TypeName, baseType);
600  baseType = baseType.BaseException;
601  } else
602  break; //baseType = null;
603  }
604 
605  #endregion
606 
607  #region RuntimeUnionTypePromotion()
608 
619 
638  #endregion
639 
640 #region Exit(int)
641  public virtual void Exit(int indent, int res) {
647  this.ldci4(indent, res);
648  this.WriteLNNoArgsCommand(indent, "call void [mscorlib]System.Environment::Exit(int32)");
649 
650  }
651 #endregion
652  #region Promotion()
653 
659  public void Promotion(int indent, TypeExpression typeExp1, TypeExpression certainType1, TypeExpression typeExp2, TypeExpression certainType2, bool unidirectionalConversion, bool makeBoxing) {
660  FieldType aux;
661  bool isFieldType1 = false;
662  bool isFieldType2 = false;
663  UnionType union = null;
664 
665  if ((aux = TypeExpression.As<FieldType>(typeExp1)) != null) {
666  typeExp1 = aux.FieldTypeExpression;
667  isFieldType1 = true;
668  }
669 
670 
671  if ((aux = TypeExpression.As<FieldType>(typeExp2)) != null) {
672  typeExp2 = aux.FieldTypeExpression;
673  isFieldType2 = true;
674  }
675  if ((aux = TypeExpression.As<FieldType>(certainType1)) != null)
676  certainType1 = aux.FieldTypeExpression;
677 
678  if ((aux = TypeExpression.As<FieldType>(certainType2)) != null)
679  certainType2 = aux.FieldTypeExpression;
680 
681 
682  if (!certainType1.IsFreshVariable() && !TypeExpression.Is<UnionType>(certainType1))
683  {
684  // * If both values are built-in, check promotion of int to double
685  if (certainType1.IsValueType() && certainType2.IsValueType()) {
686  // Only converts integer to double. If certain type1==Double laconversión es necesaria
687  if (TypeExpression.Is<DoubleType>(certainType2) &&
688  (TypeExpression.Is<CharType>(certainType1) || TypeExpression.Is<IntType>(certainType1))) {
689  if (typeExp1 is TypeVariable && makeBoxing)
690  this.UnboxAny(indent, certainType1);
691  this.convToDouble(indent);
692  } else {
693  if (!(TypeExpression.Is<IntType>(certainType2) && TypeExpression.Is<CharType>(certainType1))) {
694  // if certainType1 and certainType2 are the same value type, and one of this is a field variable type, then make boxing.
695  if (certainType1 == certainType2 || certainType1.ILType().Equals(certainType2.ILType()))
696  {
697  if (isFieldType1) {
698  if (typeExp1 is TypeVariable)
699  this.UnboxAny(indent, certainType1);
700  } else {
701  if (!isFieldType1 && isFieldType2) {
702  if (typeExp2 is TypeVariable)
703  this.Box(indent, certainType2);
704  }
705  }
706  } else {
707  if (typeExp1 is TypeVariable && makeBoxing)
708  {
709  if (!TypeExpression.Is<UnionType>(certainType2))
710  this.UnboxAny(indent, certainType2);
711  }
712  else
713  {
714  if (!TypeExpression.Is<UnionType>(certainType1) && TypeExpression.Is<UnionType>(certainType2))
715  {
716  if (unidirectionalConversion)
717  this.Box(indent, certainType1);
718  }
719 
720  if ((union = TypeExpression.As<UnionType>(certainType1)) != null && !TypeExpression.Is<UnionType>(certainType2))
721  {
722  if (!IsUnionOfProperties(union))
723  certainType2.AcceptOperation(new CGRuntimeUnionTypePromotionOperation<ILCodeGenerator>(indent, this, union), null);
724  else if(union.Count > 0)
725  {
726  PropertyType propertyType = TypeExpression.As<PropertyType>(union.TypeSet[0]);
727  Promotion(indent, propertyType.PropertyTypeExpression, propertyType.PropertyTypeExpression, typeExp2, certainType2, unidirectionalConversion, makeBoxing);
728  }
729  }
730 
731  }
732 
733  // ValueType to TypeVariable
734  // - This code is only execute if the conversion is unidirectional (e.g. argument to parameter)
735  // - The conversion can be bidirectional (e.g a != b; type(a) to type(b) or type(b) to type(a)
736  // In this case, the correct conversion is to make an Unbox on TypeVariable and not to make a Box on ValueType.
737  // Note: Relational expressions are different of the rest of binary expression.
738  // e.g. a + b; 'a' or 'b' are going to promote to the type of arithmetical node. But, in relational expression,
739  // the type of this expression is always bool, but it is possible that 'a' has to promote to 'b' or viceversa.
740  if (unidirectionalConversion) {
741  if (!(typeExp1 is TypeVariable) && typeExp2 is TypeVariable && makeBoxing)
742  this.Box(indent, certainType2);
743  }
744  }
745  }
746  }
747  return;
748  }
749 
750  // * If the built-in must promote to an object, boxing is required
751  if (certainType1.IsValueType() && !certainType2.IsValueType()) {
752  if (unidirectionalConversion) {
753  if ((!(typeExp1 is TypeVariable)) || (TypeExpression.Is<UnionType>(certainType2)))
754  //if (!(typeExp1 is TypeVariable)) //If TypeExp1 is a TypeVariable boxing is no needed
755  this.Box(indent, certainType1);
756  else if(!makeBoxing && !(TypeExpression.Is<UnionType>(certainType1)) && certainType2.FullName.Equals(typeof(Object).FullName))
757  this.Box(indent, certainType1);
758  else if (certainType2 is TypeVariable && ((TypeVariable)certainType2).Substitution == null && !isFieldType1)
759  this.Box(indent, certainType1);
760  else if (certainType2 is TypeVariable && ((TypeVariable)certainType2).Substitution == null && ((TypeVariable)certainType2).EquivalenceClass != null)
761  this.Box(indent, certainType1);
762  }
763 
764  // * If the expected type is an String, we must call its ToString method
765  if (TypeExpression.Is<StringType>(certainType2))
766  this.CallVirt(indent, "instance", "string", "[mscorlib]System.Object", "ToString", null);
767 
768  return;
769  }
770 
771  // If the object must promote to an built-in, unboxing is required
772  if (!certainType1.IsValueType() && certainType2.IsValueType()) {
773  if (TypeExpression.Is<UnionType>(certainType1))
777  certainType2.AcceptOperation(new CGRuntimeFreshTEPromotionOperation<ILCodeGenerator>(indent, this), null);
778  return;
779  }
780 
781  if ((union = TypeExpression.As<UnionType>(certainType1)) != null && !TypeExpression.Is<UnionType>(certainType2) && (certainType2.IsValueType() || TypeExpression.Is<StringType>(certainType2)))
782  certainType2.AcceptOperation(new CGRuntimeUnionTypePromotionOperation<ILCodeGenerator>(indent, this, union), null);
783  }
784  else if (certainType1.IsFreshVariable())
785  {
786  // * We require a runtime check to know if a promotion is needed
790  certainType2.AcceptOperation(new CGRuntimeFreshTEPromotionOperation<ILCodeGenerator>(indent, this), null);
791  }
792  else if (TypeExpression.Is<UnionType>(certainType1) && IsValueType(certainType2))
793  {
794  certainType2.AcceptOperation(new CGRuntimeFreshTEPromotionOperation<ILCodeGenerator>(indent, this), null);
795  }
796  }
797 
798  private bool IsUnionOfProperties(UnionType ut)
799  {
800  foreach (var typeExpression in ut.TypeSet)
801  if (!(typeExpression is PropertyType))
802  return false;
803  return true;
804  }
805 
806  protected bool IsValueType(TypeExpression exp)
807  {
808  if (exp is BoolType)
809  return true;
810  if (exp is CharType)
811  return true;
812  if (exp is IntType)
813  return true;
814  if (exp is DoubleType)
815  return true;
816  return false;
817  }
818 
819  #endregion
820 
821  #region WriteCodeOfExceptionsTemplateMethod
827  this.ilStamentsCodeGeneration.WriteLine(d.WriteDynamicExceptionCode());
828 
829  }
830 
831  #endregion
832 
833  #region RuntimeFreshTypeExpressionPromotion()
834  // <summary>
839  // public override void RuntimeFreshTypeExpressionPromotion(int indent, TypeExpression typeExpression) {
841  //if (!typeExpression.IsValueType())
842  // return;
843 
845  //if (TypeExpression.Is<IntType>(typeExpression)) {
846  // // * char to int
847  // // * If we must promote to an integer, a Char could be on the stack
848  // this.dup(indent);
849  // this.isinst(indent, CharType.Instance);
850  // string notACharLabel = this.NewLabel;
851  // this.brfalse(indent, notACharLabel);
852  // this.UnboxAny(indent, CharType.Instance);
853  // string endLabel = this.NewLabel;
854  // this.br(indent, endLabel);
855 
856  // this.WriteLabel(notACharLabel);
857  // this.UnboxAny(indent, IntType.Instance);
858 
859  // this.WriteLabel(endLabel);
860 
861  // return;
862  //}
863  //if (TypeExpression.Is<DoubleType>(typeExpression)) {
864  // // * char to double or int to double
865  // // * If we must promote to an double, a Char or a Int32 could be on the stack
866  // this.dup(indent);
867  // this.isinst(indent, CharType.Instance);
868  // string notACharLabel = this.NewLabel;
869  // this.brfalse(indent, notACharLabel);
870  // this.UnboxAny(indent, CharType.Instance);
871  // this.convToDouble(indent);
872  // string endLabel = this.NewLabel;
873  // this.br(indent, endLabel);
874 
875  // this.WriteLabel(notACharLabel);
876  // this.dup(indent);
877  // this.isinst(indent, IntType.Instance);
878  // string notAInt32Label = this.NewLabel;
879  // this.brfalse(indent, notAInt32Label);
880  // this.UnboxAny(indent, IntType.Instance);
881  // this.convToDouble(indent);
882  // this.br(indent, endLabel);
883 
884  // this.WriteLabel(notAInt32Label);
885  // this.UnboxAny(indent, DoubleType.Instance);
886 
887  // this.WriteLabel(endLabel);
888 
889  // return;
890  //}
891 
893  //this.UnboxAny(indent, typeExpression);
894  //return;
895  // }
896 
897  #endregion
898 
900 
911 
919 
927 
933 
941 
949 
955 
958 
965 
967 
968  #region WriteThrowException
969 
975  public override void WriteThrowException(int indent, DynamicExceptionManager dynException) {
976  this.newobj(indent, dynException.TypeName, new string[] { });
977  this.WriteThrow(indent);
978  }
979 
986  public override void WriteThrowException(int indent, string ex, string[] msg) {
987  this.newobj(indent, ex, msg);
988  this.WriteThrow(indent);
989  }
990 
991 #endregion
992  // IL Instructions
993 
994  #region Addressing Classes and Value Types
995 
996  #region ldobj
997 
998  // ldobj <token>
999  // Load an instance value type specified by <token> on the stack.
1000 
1006  public void ldobj(int indent, TypeExpression val) {
1007  this.WriteLNUnaryCommand(indent, "ldobj", val.ILType());
1008  }
1009 
1010  #endregion
1011 
1012  #region ldstr
1013 
1014  // ldstr <token>
1015  // Load a string reference on the stack.
1016 
1022  public void ldstr(int indent, string val) {
1023  if (val[0] != '\"' || val[val.Length - 1] != '\"')
1024  val = "\"" + val + "\"";
1025  this.WriteLNUnaryCommand(indent, "ldstr", val);
1026  }
1027 
1028  #endregion
1029 
1030  #region ldnull
1031 
1032  // ldnull
1033  // Load a null object reference on the stack.
1034 
1039  public void ldnull(int indent) {
1040  this.WriteLNNoArgsCommand(indent, "ldnull");
1041  }
1042 
1043  #endregion
1044 
1045  #region newobj
1046 
1047  #region newobj
1048 
1049  // newobj
1050  // Allocate memory for a new instance of a class—not a value type—and call
1051  // the instance constructor method specified by <token>.
1052 
1060  public void newobj(int indent, MethodType memberType, TypeExpression obj, string member) {
1061  this.ilStamentsCodeGeneration.Write(indent, "newobj instance void {0}::{1}", obj.ILType(), member);
1062  this.WriteParams(memberType, null);
1063  this.ilStamentsCodeGeneration.WriteLine();
1064  }
1065 
1066  #endregion
1067 
1068 
1075  public void newobj(int indent, string klass, string[] args) {
1076  this.ilStamentsCodeGeneration.Write(indent, "newobj instance void {0}::.ctor(", klass);
1077 
1078  if (args != null)
1079  this.ilStamentsCodeGeneration.Write("{0}", String.Join(", ", args));
1080  this.ilStamentsCodeGeneration.WriteLine(")");
1081  }
1082 
1083  #endregion
1084 
1085  #region castclass
1086 
1087  // castclass <token>
1088  // Cast a class instance to the class specified by <token>.
1089 
1095  public void castclass(int indent, TypeExpression token) {
1096  this.WriteLNUnaryCommand(indent, "castclass", token.ILType());
1097  }
1098 
1099  #endregion
1100 
1101  #region throw
1102 
1103  // throw
1104  // Pop the object reference from the stack and throw it as a managed exception.
1109  public void WriteThrow(int indent) {
1110  this.WriteLNNoArgsCommand(indent, "throw");
1111  }
1112 
1113  #endregion
1114 
1115  #endregion
1116 
1117  #region Argument instructions
1118 
1119  #region ldarg()
1120  public void ldarg(int indent, int argNumber) {
1132  this.ilStamentsCodeGeneration.WriteLine(indent, "ldarg.{0}", argNumber);
1133  }
1134 
1140  public void ldarg(int indent, string argName) {
1141  this.WriteLNUnaryCommand(indent, "ldarg", argName);
1142  }
1143 
1144  #endregion
1145 
1146  #region ldarga()
1147  public void ldarga(int indent, string argName) {
1153  this.WriteLNUnaryCommand(indent, "ldarga", argName);
1154  }
1155  #endregion
1156 
1157  #region starg()
1158 
1171  public void starg(int indent, int argNumber) {
1172  this.ilStamentsCodeGeneration.WriteLine(indent, "starg.{0}", argNumber);
1173  }
1174 
1180  public void starg(int indent, string argNumber) {
1181  this.WriteLNUnaryCommand(indent, "starg", argNumber);
1182  }
1183 
1184  #endregion
1185 
1186  #region arglist()
1187 
1188  // arglist
1189  // Get the argument list handle.
1190 
1195  public void arglist(int indent) {
1196  this.WriteLNNoArgsCommand(indent, "arglist");
1197  }
1198 
1199  #endregion
1200 
1201  #endregion
1202 
1203  #region Arithmetical Operations
1204 
1205  // All arithmetical operations except the negation operation take two
1206  // operands from the stack and put the result on the stack.
1207 
1208  #region add
1209 
1210  // add
1211  // Addition.
1212 
1217  public void add(int indent) {
1218  this.WriteLNNoArgsCommand(indent, "add");
1219  }
1220 
1225  public void concat(int indent) {
1226  this.WriteLNNoArgsCommand(indent, "call string [mscorlib]System.String::Concat(object, object)");
1227  }
1228 
1229  #endregion
1230 
1231  #region mul
1232 
1233  // mul
1234  // Multiplication.
1235 
1240  public void mul(int indent) {
1241  this.WriteLNNoArgsCommand(indent, "mul");
1242  }
1243 
1244  #endregion
1245 
1246  #region div
1247 
1248  // div
1249  // Division.
1250 
1255  public void div(int indent) {
1256  this.WriteLNNoArgsCommand(indent, "div");
1257  }
1258 
1259  #endregion
1260 
1261  #region neg
1262 
1263  // neg
1264  // Negate—that is, invert the sign.
1265 
1270  public void neg(int indent) {
1271  this.WriteLNNoArgsCommand(indent, "neg");
1272  }
1273  #endregion
1274 
1275  #region rem
1276 
1277  // rem
1278  // Remainder, modulo.
1279 
1284  public void rem(int indent) {
1285  this.WriteLNNoArgsCommand(indent, "rem");
1286  }
1287 
1288 
1289  #endregion
1290 
1291  #region sub
1292 
1293  // sub
1294  // Subtraction.
1295 
1300  public void sub(int indent) {
1301  this.WriteLNNoArgsCommand(indent, "sub");
1302  }
1303  #endregion
1304 
1305  #endregion
1306 
1307  #region Bitwise Operations
1308 
1309  // Bitwise operations have no parameters and are defined for integer types only
1310 
1311  #region and
1312 
1313  // and
1314  // Bitwise AND (binary).
1315 
1320  public void and(int indent) {
1321  this.WriteLNNoArgsCommand(indent, "and");
1322  }
1323 
1324  #endregion
1325 
1326  #region or
1327 
1328  // or
1329  // Bitwise OR (binary).
1330 
1335  public void or(int indent) {
1336  this.WriteLNNoArgsCommand(indent, "or");
1337  }
1338 
1339  #endregion
1340 
1341  #region xor
1342 
1343  // xor
1344  // Bitwise exclusive OR (binary).
1345 
1350  public void xor(int indent) {
1351  this.WriteLNNoArgsCommand(indent, "xor");
1352  }
1353 
1354  #endregion
1355 
1356  #region not
1357 
1364  public void not(int indent) {
1365  this.WriteLNNoArgsCommand(indent, "not");
1366  }
1367 
1368  #endregion
1369 
1370  #endregion
1371 
1372  #region Box and Unbox
1373 
1374  #region Box
1375  // Box <token>
1376  // Convert a value type instance to an object reference. <token> specifies the value type being converted and must be a valid TypeDef or TypeRef token.
1377  // This instruction pops the value type instance from the stack, creates a new instance of the type as an object, and pushes the object reference to this instance on the stack.
1378 
1384  public override void Box(int indent, TypeExpression type) {
1385  this.WriteLNUnaryCommand(indent, "box", type.ILType());
1386  }
1387 
1393  public override void BoxIfNeeded(int indent, TypeExpression type) {
1395  this.Box(indent, type);
1396  }
1397 
1398  #endregion
1399 
1400  #region Unbox
1401 
1406  public virtual void UnBoxIfNeeded(int indent, TypeExpression type) {
1407  if ( TypeMapping.Instance.RequireBoxing(type.ILType()) )
1408  this.Unbox(indent, type);
1409  } // Unbox <token>
1410  // Revert a boxed value type instance from the object form to its value type form. <token> specifies the value type being converted and must be a valid TypeDef or TypeRef token.
1411  // This instruction takes an object reference from the stack and puts a managed pointer to the value type instance on the stack.
1412 
1418  public override void Unbox(int indent, TypeExpression type) {
1419  this.WriteLNUnaryCommand(indent, "unbox", type.ILType());
1420  }
1421 
1422  #endregion
1423 
1424  #endregion
1425 
1426  #region Calling Methods
1427 
1428  #region call <token>
1429 
1430  #region WriteCallArguments()
1431  // Esta seguramente no sé podrá mover pues puede que se use en el dlR
1439  virtual protected void WriteCallArguments(MethodType memberType, TypeExpression klass, string member, AST.CompoundExpression arguments) {
1440  if (IsInstance(memberType))
1441  this.ilStamentsCodeGeneration.Write("instance ");
1442 
1443  string returnILType, classILType;
1444  if (memberType != null) {
1445  if (memberType.Return is FieldType && ((FieldType)memberType.Return).FieldTypeExpression is TypeVariable)
1446  returnILType = "object"; // * Fresh type variables
1447  else
1448  returnILType = memberType.Return.ILType();
1449  classILType = klass.ILType();
1450  } else {
1451  returnILType = "object"; // * Fresh type variables
1452  classILType = "[mscorlib]System.Object";
1453  }
1454  this.ilStamentsCodeGeneration.Write("{0} {1}::{2}", returnILType, classILType, member);
1455  this.WriteParams(memberType, arguments);
1456  }
1457 
1465  private void WriteCallArguments(PropertyType memberType, TypeExpression obj, string member, bool setProperty) {
1466  if (IsInstance(memberType))
1467  this.ilStamentsCodeGeneration.Write("instance ");
1468 
1469  string memberILType = memberType == null ? "object" : memberType.PropertyTypeExpression.ILType();
1470 
1471  if (setProperty)
1472  this.ilStamentsCodeGeneration.WriteLine("void {0}::set_{1}({2})", obj.ILType(), member, memberILType);
1473  else
1474  this.ilStamentsCodeGeneration.WriteLine("{0} {1}::get_{2}()", memberILType, obj.ILType(), member);
1475  }
1476  #endregion
1477 
1478 
1479  // call <token>
1480  // Call a nonvirtual method.
1481 
1489  public override void Call(int indent, MethodType memberType, TypeExpression obj, string member) {
1490  this.ilStamentsCodeGeneration.Write(indent, "call ");
1491  this.WriteCallArguments(memberType, obj, member, null);
1492  this.ilStamentsCodeGeneration.WriteLine();
1493  }
1494 
1503  public override void Call(int indent, PropertyType memberType, TypeExpression obj, string member, bool setProperty) {
1504  this.ilStamentsCodeGeneration.Write(indent, "call ");
1505  this.WriteCallArguments(memberType, obj, member, setProperty);
1506  this.ilStamentsCodeGeneration.WriteLine();
1507  }
1508  //OJO: igual está mal el orden de los parámetros de este call, sólo es llamado desde el VisitorCLRCOdeGeneration
1509 
1519  public override void Call(int indent, string methodType, string result, string klass, string memberName, string[] args) {
1520  this.ilStamentsCodeGeneration.Write(indent, "call {0} {1} {2}::{3}(", methodType, result, klass, memberName);
1521  if (args != null) {
1522  this.ilStamentsCodeGeneration.Write(String.Join(", ", args));
1523  }
1524  this.ilStamentsCodeGeneration.WriteLine(")");
1525  }
1526 
1527  #endregion
1528 
1529  #region CallVirt <token>
1530  // CallVirt <token>
1531  // Call the virtual method specified by <token>.
1532 
1541  public override void CallVirt(int indent, MethodType memberType, TypeExpression klass, string member, AST.CompoundExpression arguments) {
1542  this.ilStamentsCodeGeneration.Write(indent, "callvirt ");
1543  this.WriteCall(memberType, klass, member, null);
1544  this.ilStamentsCodeGeneration.WriteLine();
1545  }
1546 
1555  public override void CallVirt(int indent, PropertyType memberType, TypeExpression obj, string member, bool setProperty) {
1556  this.ilStamentsCodeGeneration.Write(indent, "callvirt ");
1557  this.WriteCall(memberType, obj, member, setProperty);
1558  this.ilStamentsCodeGeneration.WriteLine();
1559  }
1560 
1561 
1571  public override void CallVirt(int indent, string methodType, string result, string klass, string memberName, string[] args) {
1572  this.ilStamentsCodeGeneration.Write(indent, "callvirt {0} {1} {2}::{3}(", methodType, result, klass, memberName);
1573 
1574  if (args != null)
1575  this.ilStamentsCodeGeneration.Write(String.Join(", ", args));
1576  this.ilStamentsCodeGeneration.WriteLine(")");
1577  }
1578  #endregion
1579 
1580  #region WriteCall()
1581 
1589  virtual protected void WriteCall(MethodType memberType, TypeExpression klass, string member, AST.CompoundExpression arguments) {
1590  if (IsInstance(memberType))
1591  this.ilStamentsCodeGeneration.Write("instance ");
1592 
1593  string returnILType, classILType;
1594  if (memberType != null) {
1595  if (memberType.Return is FieldType && ((FieldType)memberType.Return).FieldTypeExpression is TypeVariable)
1596  returnILType = "object"; // * Fresh type variables
1597  else
1598  returnILType = memberType.Return.ILType();
1599  classILType = klass.ILType();
1600  } else {
1601  returnILType = "object"; // * Fresh type variables
1602  classILType = "[mscorlib]System.Object";
1603  }
1604  this.ilStamentsCodeGeneration.Write("{0} {1}::{2}", returnILType, classILType, member);
1605  this.WriteParams(memberType, arguments);
1606  }
1614  private void WriteCall(PropertyType memberType, TypeExpression obj, string member, bool setProperty) {
1615  if (IsInstance(memberType))
1616  this.output.Write("instance ");
1617 
1618  string memberILType = memberType == null ? "object" : memberType.PropertyTypeExpression.ILType();
1619  string klass = TypeMapping.Instance.GetBCLName(obj.ILType(), true);
1620  if (setProperty)
1621  this.ilStamentsCodeGeneration.Write("void {0}::set_{1}({2})", klass, member, memberILType);
1622  else
1623  this.ilStamentsCodeGeneration.Write("{0} {1}::get_{2}()", memberILType, klass, member);
1624  }
1625  #endregion
1626 
1627  #endregion
1628 
1629  #region Comparative Branching Instructions
1630 
1631  #region beq
1632 
1633  // beq <int32>
1634  // Branch if <value1> is equal to <value2>.
1635 
1641  public void beq(int indent, string label) {
1642  this.WriteLNUnaryCommand(indent, "beq", label);
1643  }
1644 
1645  #endregion
1646 
1647  #region bne.un
1648 
1649  // bne.un <int32>
1650  // Branch if the two values are not equal. Integer values are interpreted as unsigned.
1651 
1657  public void bne(int indent, string label) {
1658  this.WriteLNUnaryCommand(indent, "bne.un", label);
1659  }
1660 
1661  #endregion
1662 
1663  #region bge
1664 
1665  // bge <int32>
1666  // Branch if greater or equal.
1667 
1673  public void bge(int indent, string label) {
1674  this.WriteLNUnaryCommand(indent, "bge", label);
1675  }
1676 
1677  #endregion
1678 
1679  #region bgt
1680 
1681  // bgt <int32>
1682  // Branch if greater.
1683 
1689  public void bgt(int indent, string label) {
1690  this.WriteLNUnaryCommand(indent, "bgt", label);
1691  }
1692 
1693  #endregion
1694 
1695  #region ble
1696 
1697  // ble <int32>
1698  // Branch if less or equal.
1699 
1705  public void ble(int indent, string label) {
1706  this.WriteLNUnaryCommand(indent, "ble", label);
1707  }
1708 
1709  #endregion
1710 
1711  #region blt
1712 
1713  // blt <int32>
1714  // Branch if less.
1715 
1721  public void blt(int indent, string label) {
1722  this.WriteLNUnaryCommand(indent, "blt", label);
1723  }
1724 
1725  #endregion
1726 
1727  #endregion
1728 
1729  #region Constant Loading
1730 
1731  #region ldc <int32>
1732 
1733  // ldc.i4 <int32>
1734  // Load <int32> on the stack.
1735 
1741  public void ldci4(int indent, int val) {
1742  this.WriteLNUnaryCommand(indent, "ldc.i4", val.ToString()); ;
1743  }
1744 
1745  #endregion
1746 
1747  #region ldc <float64>
1748 
1749  // ldc.r8 <float64>
1750  // Load <float64> (double-precision) on the stack. ILAsm permits the use
1751  // of integer parameters in both the ldc.r4 and ldc.r8 instructions; in
1752  // such cases, the integers are interpreted as binary images of the
1753  // floating-point numbers.
1754 
1760  public void ldcr8(int indent, string val) {
1761  this.WriteLNUnaryCommand(indent, "ldc.r8", val);
1762  }
1763 
1764  #endregion
1765 
1766  #region ldc <int32>
1767  // ldc.i4 <int32>
1768  // Load <int32> on the stack.
1769 
1775  public void ldc(int indent, bool val) {
1776  this.WriteLNNoArgsCommand(indent, val ? "ldc.i4.1" : "ldc.i4.0");
1777  }
1778 
1779  #endregion
1780 
1781  #region ldtoken <type>
1782  // ldtoken <type>
1783  // Load <type> on the stack.
1784 
1790  public void ldtoken(int indent, string ILType) {
1791  this.WriteLNUnaryCommand(indent, "ldtoken", ILType);
1792  }
1793 
1794  #endregion
1795 
1796  #endregion
1797 
1798 
1799  #region constructorCall
1800 
1808  public void constructorCall(int indent, MethodType memberType, TypeExpression obj, string member) {
1809  this.ilStamentsCodeGeneration.Write(indent, "call instance {0} {1}::{2}", VoidType.Instance.ILType(), obj.ILType(), member);
1810  this.WriteParams(memberType, null);
1811  this.ilStamentsCodeGeneration.WriteLine();
1812  }
1813 
1820  public void constructorCall(int indent, TypeExpression obj, string member) {
1821  this.ilStamentsCodeGeneration.WriteLine(indent, "call\tinstance {0} {1}::{2}()", VoidType.Instance.ILType(), obj.ILType(), member);
1822  }
1823 
1824  #endregion
1825 
1826 
1827  #region Conversion Operations
1828 
1829  #region convToInt
1830 
1831  // conv.i4
1832  // Convert the value to int32.
1833 
1838  public void convToInt(int indent) {
1839  this.WriteLNNoArgsCommand(indent, "conv.i4");
1840  }
1841 
1842  #endregion
1843 
1844  #region convToChar
1845 
1846  // conv.u2
1847  // Convert the value to char.
1848 
1853  public void convToChar(int indent)
1854  {
1855  this.WriteLNNoArgsCommand(indent, "conv.u2");
1856  }
1857 
1858  #endregion
1859 
1860  #region convToDouble
1861 
1862  // conv.r8
1863  // Convert the value to float64.
1864 
1869  public void convToDouble(int indent) {
1870  this.WriteLNNoArgsCommand(indent, "conv.r8");
1871  }
1872 
1873  #endregion
1874 
1875  #endregion
1876 
1877  #region Field instructions
1878 
1879  #region ldfld()
1880 
1881  // ldfld <token>
1882  // Pop the instance pointer from the stack and load the value of an
1883  // instance field on the stack. <token> must be a valid FieldDef or
1884  // MemberRef token, uncompressed and uncoded.
1885 
1894  public void ldfld(int indent, TypeExpression type, string classId, string fieldName) {
1895  this.ilStamentsCodeGeneration.WriteIndentation(indent);
1896  FieldType t = type as FieldType;
1897  if (t != null)
1898  type = t.FieldTypeExpression;
1899 
1900  if (type is TypeVariable)
1901  this.ilStamentsCodeGeneration.WriteLine("ldfld {0} {1}::{2}", "object", classId, fieldName);
1902  else if (type is ClassTypeProxy)
1903  this.ilStamentsCodeGeneration.WriteLine("ldfld {0} {1}::{2}", ((ClassTypeProxy)type).RealType.ILType(), classId, fieldName);
1904  else
1905  this.ilStamentsCodeGeneration.WriteLine("ldfld {0} {1}::{2}", type.ILType(), classId, fieldName);
1906  }
1907 
1908  #endregion
1909 
1910  #region ldsfld()
1911 
1912  // ldsfld <token>
1913  // Load the value of a static field on the stack.
1914 
1922  public void ldsfld(int indent, TypeExpression type, string classId, string fieldName) {
1923  FieldType t = type as FieldType;
1924  if (t != null)
1925  type = t.FieldTypeExpression;
1926  if (type is TypeVariable)
1927  this.ilStamentsCodeGeneration.WriteLine(indent, "ldsfld {0} {1}::{2}", "object", classId, fieldName);
1928  else if (type is ClassTypeProxy)
1929  this.ilStamentsCodeGeneration.WriteLine("ldfld {0} {1}::{2}", ((ClassTypeProxy)type).RealType.ILType(), classId, fieldName);
1930  else
1931  this.ilStamentsCodeGeneration.WriteLine(indent, "ldsfld {0} {1}::{2}", type.ILType(), classId, fieldName);
1932  }
1933 
1934  #endregion
1935 
1936  #region ldflda()
1937 
1945  public void ldflda(int indent, TypeExpression type, string classId, string fieldName) {
1946  this.ilStamentsCodeGeneration.WriteLine(indent, "ldflda {0} {1}::{2}", type.ILType(), classId, fieldName);
1947  }
1948 
1954  public void ldflda(int indent, string token) {
1955  this.WriteLNUnaryCommand(indent, "ldflda", token);
1956  }
1957 
1958  #endregion
1959 
1960  #region ldsflda()
1961 
1969  public void ldsflda(int indent, TypeExpression type, string classId, string fieldName) {
1970  this.ilStamentsCodeGeneration.WriteLine(indent, "ldsflda {0} {1}::{2}", type.ILType(), classId, fieldName);
1971  }
1972 
1978  public void ldsflda(int indent, string token) {
1979  this.WriteLNUnaryCommand(indent, "ldsflda", token);
1980  }
1981 
1982  #endregion
1983 
1984  #region stfld()
1985 
1986  // stfld <token>
1987  // Pop the value from the stack, pop the instance pointer from the stack,
1988  // and store the value in the instance field.
1989 
1997  public void stfld(int indent, TypeExpression type, string classId, string fieldName) {
1998  FieldType t = type as FieldType;
1999  if (t != null)
2000  type = t.FieldTypeExpression;
2001  if (type is TypeVariable)
2002  this.ilStamentsCodeGeneration.WriteLine(indent, "stfld {0} {1}::{2}", "object", classId, fieldName);
2003  else if(type is ClassTypeProxy)
2004  this.ilStamentsCodeGeneration.WriteLine(indent, "stfld {0} {1}::{2}", ((ClassTypeProxy)type).RealType.ILType(), classId, fieldName);
2005  else
2006  this.ilStamentsCodeGeneration.WriteLine(indent, "stfld {0} {1}::{2}", type.ILType(), classId, fieldName);
2007  }
2008 
2009  #endregion
2010 
2011  #region stsfld()
2012 
2013  // stsfld <token>
2014  // Store the value from the stack in the static field.
2015 
2023  public void stsfld(int indent, TypeExpression type, string classId, string fieldName) {
2024  FieldType t = type as FieldType;
2025  if (t != null)
2026  type = t.FieldTypeExpression;
2027  if (type is TypeVariable)
2028  this.ilStamentsCodeGeneration.WriteLine(indent, "stsfld {0} {1}::{2}", "object", classId, fieldName);
2029  else if (type is ClassTypeProxy)
2030  this.ilStamentsCodeGeneration.WriteLine(indent, "stfld {0} {1}::{2}", ((ClassTypeProxy)type).RealType.ILType(), classId, fieldName);
2031  else
2032  this.ilStamentsCodeGeneration.WriteLine(indent, "stsfld {0} {1}::{2}", type.ILType(), classId, fieldName);
2033  }
2034 
2035  #endregion
2036 
2037  #endregion
2038 
2039  #region Flow Control Instructions
2040 
2041  #region ret()
2042 
2043  // ret
2044  // Return from a method.
2045 
2050  public void ret(int indent) {
2051  this.WriteLNNoArgsCommand(indent, "ret");
2052  }
2053 
2054  #endregion
2055 
2056  #endregion
2057 
2058  #region Local variable instructions
2059 
2060  #region ldloc()
2061 
2062  // ldloc <unsigned int16>
2063  // Load the value of local variable number <unsigned int16> on the stack.
2064  // Local variable numbers can range from 0 to 0xFFFE.
2065 
2071  public void ldloc(int indent, int locNumber) {
2072  this.WriteLNUnaryCommand(indent, "ldloc", locNumber.ToString());
2073  }
2074 
2080  public void ldloc(int indent, string locVar) {
2081  this.WriteLNUnaryCommand(indent, "ldloc", locVar);
2082  }
2083 
2084  #endregion
2085 
2086  #region ldloca()
2087 
2088  // ldloca <unsigned int16>
2089  // Load the address of local variable number <unsigned int16> on the
2090  // stack. The local variable number can vary from 0 to 0xFFFE.
2091 
2097  public void ldloca(int indent, int locNumber) {
2098  this.WriteLNUnaryCommand(indent, "ldloca", locNumber.ToString());
2099  }
2100 
2106  public void ldloca(int indent, string locVar) {
2107  this.WriteLNUnaryCommand(indent, "ldloca", locVar);
2108  }
2109 
2114  public void ldloca_s(int indent, string tmpVar) {
2115  this.WriteLNUnaryCommand(indent, "ldloca.s", tmpVar);
2116  }
2117  #endregion
2118  #region stloc()
2119 
2120  // stloc <unsigned int16>
2121  // Pop the value from the stack and store it in local variable slot
2122  // number <unsigned int16>. The value on the stack must be of the same
2123  // type as the argument slot or must be convertible to the type of the
2124  // argument slot. The convertibility rules and effects are the same as
2125  // those for the conversion operations, discussed earlier in this chapter.
2126 
2132  public void stloc(int indent, int locNumber) {
2133  this.WriteLNNoArgsCommand(indent, "stloc." + locNumber.ToString());
2134  }
2135 
2141  public void stloc_s(int indent, string variable) {
2142  this.WriteLNUnaryCommand(indent, "stloc.s", variable);
2143  }
2144 
2145 
2151  public void stloc(int indent, string locVar) {
2152  this.WriteLNUnaryCommand(indent, "stloc", locVar);
2153  }
2154 
2155  #endregion
2156 
2157  #endregion
2158 
2159 
2160  #region Logical Condition Check Operations
2161 
2162  #region ceq
2163 
2164  // ceq
2165  // Check whether the two values on the stack are equal.
2166 
2171  public void ceq(int indent) {
2172  this.WriteLNNoArgsCommand(indent, "ceq");
2173  }
2174 
2175  #endregion
2176 
2177  #region cgt
2178 
2179  // cgt
2180  // Check whether the first value is greater than the second value. It’s
2181  // the stack we are working with, so the “second” value is the one on the
2182  // top of the stack.
2183 
2188  public void cgt(int indent) {
2189  this.WriteLNNoArgsCommand(indent, "cgt");
2190  }
2191 
2192  #endregion
2193 
2194  #region clt
2195 
2196  // clt
2197  // Check whether the first value is less than the second value.
2198 
2203  public void clt(int indent) {
2204  this.WriteLNNoArgsCommand(indent, "clt");
2205  }
2206 
2207  #endregion
2208 
2209  #region isinst
2210  // isinst <token>
2211  // Check to see whether the object reference on the stack is an instance of the class specified by <token>.
2212 
2225  public void isinst(int indent, TypeExpression token) {
2226  this.WriteLNUnaryCommand(indent, "isinst", TypeMapping.Instance.GetBCLName(token.ILType(), true));
2227  }
2228 
2229  #endregion
2230 
2231  #endregion
2232 
2233  #region Shift Operations
2234 
2235  // Shift operations have no parameters and are defined for integer
2236  // operands only. The shift operations are binary: they take from the
2237  // stack the shift count and the value being shifted, in that order, and
2238  // put the shifted value on the stack.
2239 
2240  #region shl
2241 
2242  // shl
2243  // Shift left.
2244 
2249  public void shl(int indent) {
2250  this.WriteLNNoArgsCommand(indent, "shl");
2251  }
2252 
2253  #endregion
2254 
2255  #region shr
2256 
2257  // shr
2258  // Shift right.
2259 
2264  public void shr(int indent) {
2265  this.WriteLNNoArgsCommand(indent, "shr");
2266  }
2267 
2268  #endregion
2269 
2270  #endregion
2271 
2272  #region Stack manipulation
2273 
2274  #region nop()
2275 
2276  // nop
2277  // No operation; a placeholder only. The nop instruction is not exactly a
2278  // stack manipulation instruction, since it does not touch the stack.
2279 
2284  public void nop(int indent) {
2285  this.WriteLNNoArgsCommand(indent, "nop");
2286  }
2287 
2288  #endregion
2289 
2290  #region dup()
2291 
2292  // dup
2293  // Duplicate the value on the top of the stack. If the stack is empty,
2294  // the JIT compiler fails because of the stack underflow.
2295 
2300  public void dup(int indent) {
2301  this.WriteLNNoArgsCommand(indent, "dup");
2302  }
2303 
2304  #endregion
2305 
2306  #region pop()
2307 
2308  // pop
2309  // Remove the value from the top of the stack. The value is lost. If the
2310  // stack is empty, the JIT compiler fails.
2311 
2316  public void pop(int indent) {
2317  this.WriteLNNoArgsCommand(indent, "pop");
2318  }
2319 
2320  #endregion
2321 
2322  #endregion
2323 
2324  #region leave
2325  public void WriteLeave(int indentation, string label) {
2331  this.WriteLNUnaryCommand(indentation, "leave", label);
2332  }
2333 
2334  #endregion
2335 
2336  #region UnboxAny
2337 
2338  // Unbox <token>
2339  // Revert a boxed value type instance from the object form to its value type form. <token> specifies the value type being converted and must be a valid TypeDef or TypeRef token.
2340  // This instruction takes an object reference from the stack and puts a managed pointer to the value type instance on the stack.
2341 
2347  public abstract override void UnboxAny(int indent, TypeExpression type);
2348 
2349  #endregion
2350 
2351  #region Unconditional and Conditional Branching Instructions
2352 
2353  #region br
2354 
2355  // br <int32>
2356 
2362  public void br(int indent, string label) {
2363  this.WriteLNUnaryCommand(indent, "br", label);
2364  }
2365 
2366  #endregion
2367 
2368  #region brfalse
2369 
2370  // brfalse (brnull, brzero) <int32>
2371  // Branch if <value> is 0.
2372 
2378  public void brfalse(int indent, string label) {
2379  this.WriteLNUnaryCommand(indent, "brfalse", label);
2380  }
2381 
2382  #endregion
2383 
2384  #region brtrue
2385 
2386  // brtrue <int32>
2387  // Branch if <value> is nonzero.
2388 
2394  public void brtrue(int indent, string label) {
2395  this.WriteLNUnaryCommand(indent, "brtrue", label);
2396  }
2397 
2398  #endregion
2399 
2400  #endregion
2401 
2402  #region VectorInstructions
2403 
2404  #region newarr
2405 
2406  // newarr <token>
2407  // Create a vector. <token> specifies the type of vector elements.
2408 
2414  public virtual void newarr(int indent, TypeExpression token) {
2415  if(token is TypeVariable && ((TypeVariable)token).Substitution != null && ((TypeVariable)token).Substitution.IsValueType() && !(((TypeVariable)token).Substitution is StringType))
2416  this.WriteLNUnaryCommand(indent, "newarr", "object");
2417  else
2418  this.WriteLNUnaryCommand(indent, "newarr", token.ILType());
2419  }
2425  public virtual void newarr(int indent, string type) {
2426  this.WriteLNUnaryCommand(indent, "newarr", type);
2427  }
2428 
2429  #endregion
2430 
2431  #region ldlen
2432 
2433  // ldlen
2434  // Get the element count of a vector.
2435 
2441  public virtual void ldlen(int indent, TypeExpression token) {
2442  this.WriteLNNoArgsCommand(indent, "ldlen");
2443  }
2444 
2445  #endregion
2446 
2447  #region ldelem
2448 
2449  // ldelem.i4
2450  // Load a vector element of type int32.
2451 
2456  public virtual void ldelemInt(int indent) {
2457  this.WriteLNNoArgsCommand(indent, "ldelem.i4");
2458  }
2459 
2464  public virtual void ldelemChar(int indent)
2465  {
2466  this.WriteLNNoArgsCommand(indent, "ldelem.u2");
2467  }
2468 
2469  // ldelem.r8
2470  // Load a vector element of type float64.
2471 
2476  public virtual void ldelemDouble(int indent) {
2477  this.WriteLNNoArgsCommand(indent, "ldelem.r8");
2478  }
2479 
2480  // ldelem.ref
2481  // Load a vector element of object reference type.
2482 
2487  public virtual void ldelemRef(int indent) {
2488  this.WriteLNNoArgsCommand(indent, "ldelem.ref");
2489  }
2490 
2491  #endregion
2492 
2493  #region stelem
2494 
2495  // stelem.i4
2496  // Store a value in a vector element of type int32.
2497 
2502  public virtual void stelemInt(int indent) {
2503  this.WriteLNNoArgsCommand(indent, "stelem.i4");
2504  }
2505 
2506  // stelem.r8
2507  // Store a value in a vector element of type float64.
2508 
2513  public virtual void stelemDouble(int indent) {
2514  this.WriteLNNoArgsCommand(indent, "stelem.r8");
2515  }
2516 
2517  // stelem.ref
2518  // Store a value in a vector element of object reference type.
2519 
2524  public virtual void stelemRef(int indent) {
2525  this.WriteLNNoArgsCommand(indent, "stelem.ref");
2526  }
2527 
2528  #endregion
2529 
2530  #endregion
2531 
2532  //helpers
2533 
2534  internal void WriteLNNoArgsCommand(int indentation, string command) {
2535  ilStamentsCodeGeneration.WriteIndentation(indentation);
2536  this.WriteLNNoArgsCommand(command);
2537  }
2538 
2539 
2540  internal void WriteLNNoArgsCommand(string command) {
2541  this.ilStamentsCodeGeneration.WriteLine(command);
2542  }
2543  public void WriteLine(int indentation, string msg) {
2544  ilStamentsCodeGeneration.WriteIndentation(indentation);
2545  ilStamentsCodeGeneration.WriteLine(msg);
2546  }
2547  internal void WriteLNUnaryCommand(int indentation, string command, string argument) {
2548  ilStamentsCodeGeneration.WriteLine(indentation, "{0}\t{1}", command, argument);
2549  }
2550 
2551  private static bool IsInstance(PropertyType memberType) {
2552  return memberType == null || (memberType.MemberInfo.ModifierMask & Modifier.Static) == 0;
2553  }
2554 
2555  private static bool IsInstance(MethodType memberType) {
2556  return memberType == null || (memberType.MemberInfo.ModifierMask & Modifier.Static) == 0;
2557  }
2558  public void WriteLine() {
2559  this.ilStamentsCodeGeneration.WriteLine();
2560  }
2561  }
2562 }
bool RequireBoxing(string ilType)
Tells if an IL type requires boxing to convert into an object
Definition: TypeMapping.cs:71
override void WriteTryDirective(int indent)
override void WriteEndOfMethod(int indent, string name)
Writes the method termination. It writes also en end of line
void WriteLeave(int indentation, string label)
Write leave.s label
void Write(string format, params Object[] obj)
void constructorCall(int indent, TypeExpression obj, string member)
Writes the call instruction.
void ldsflda(int indent, TypeExpression type, string classId, string fieldName)
Writes the ldsflda instruction.
static TypeVariable NewTypeVariable
Gets a new identify to the variable type
Definition: TypeVariable.cs:67
virtual void Exit(int indent, int res)
Checks if the union type can to promote to the specified type.
virtual void WriteCallArguments(MethodType memberType, TypeExpression klass, string member, AST.CompoundExpression arguments)
Writes the &#39;token&#39; of call instructions.
void neg(int indent)
Writes the neg instruction.
void Promotion(int indent, TypeExpression typeExp1, TypeExpression certainType1, TypeExpression typeExp2, TypeExpression certainType2, bool unidirectionalConversion, bool makeBoxing)
Writes the il code to promote typeExp1 to typeExp2
void ldsfld(int indent, TypeExpression type, string classId, string fieldName)
Writes the ldsfld instruction.
override void WriteType(TypeExpression type)
Writes the current type information
Representa a union type.
Definition: UnionType.cs:36
override void WriteParams(MethodType memberType, AST.CompoundExpression arguments)
override void WriteCloseBraceCatch(int indent)
void WriteThrow(int indent)
Writes the throw instruction.
static TypeMapping Instance
Definition: TypeMapping.cs:28
Offers the mappings between different representations of types in IL.
Definition: TypeMapping.cs:23
void ldc(int indent, bool val)
Writes the ldc instruction.
override bool IsValueType()
True if type expression is a ValueType. Otherwise, false.
void ldloca(int indent, int locNumber)
Writes the ldloca instruction.
void bge(int indent, string label)
Writes the bge instruction.
virtual void ldelemDouble(int indent)
Writes the ldelem.r8 instruction.
MethodDeclaration ASTNode
The AST node set by the VisitorTypeDefinition and used in the VisitorTypeInferece for abstract interp...
Definition: MethodType.cs:139
virtual void ldelemInt(int indent)
Writes the ldelem.i4 instruction.
void newobj(int indent, string klass, string[] args)
Writes the newobj instruction
override void CallVirt(int indent, MethodType memberType, TypeExpression klass, string member, AST.CompoundExpression arguments)
Writes the CallVirt instruction.
override void Unbox(int indent, TypeExpression type)
Writes the Unbox instruction
void stloc(int indent, string locVar)
Writes the ldloc instruction.
override void WriteLabel(int indentation, string label)
Writes a label in il. Format –indentation– LABEL:
override void WriteHeader(string fileName)
Writes the header of the il code file.
Represent a string type.
Definition: StringType.cs:36
override void WriteEndOfField()
Writes the field termination
override void Box(int indent, TypeExpression type)
Writes the Box instruction
virtual void stelemRef(int indent)
Writes the stelem.ref instruction.
override void WriteField(int indent, string name, FieldType type, bool constantField)
Writes the field header.
void AddExceptionCode(DynamicExceptionManager typeException)
Adds the information of specified exception to include in intermediate code file. ...
void shr(int indent)
Writes the shr instruction.
virtual void ldelemRef(int indent)
Writes the ldelem.ref instruction.
override void WriteLNFieldInitialization(TypeExpression type)
Writes the field inicialization.
override void WriteOpenBraceTry(int indent)
override void CallVirt(int indent, PropertyType memberType, TypeExpression obj, string member, bool setProperty)
Writes the CallVirt instruction.
void ldsflda(int indent, string token)
Writes the ldsflda instruction.
void ldloca(int indent, string locVar)
Writes the ldloca instruction.
This class encapsulates the IL code to generate a dynamic exception.
void stsfld(int indent, TypeExpression type, string classId, string fieldName)
Writes the stsfld instruction.
override void Comment(string msg)
Writes the specified message as a comment in il language
void castclass(int indent, TypeExpression token)
Writes the castclass instruction.
Represents a interface type.
void ldobj(int indent, TypeExpression val)
Writes the ldobj instruction.
Represent a character type.
Definition: CharType.cs:38
void or(int indent)
Writes the or instruction.
override void WriteStartBlock(int indent)
Writes the block inicialization
AccessModifier MemberInfo
Gets or sets the attribute information of method type
Definition: MethodType.cs:118
void clt(int indent)
Writes the clt instruction.
Abstract class that represents all different types.
override void Call(int indent, PropertyType memberType, TypeExpression obj, string member, bool setProperty)
Writes the call instruction.
Represents a generic type expression
Definition: TypeVariable.cs:36
Represents a proxy of a class type. It implements the unfold operatations of theoretical type systes...
virtual void WriteMethodTypeOfAccess(string name, MethodType type)
override void WriteFinally(int indent)
void div(int indent)
Writes the div instruction.
void constructorCall(int indent, MethodType memberType, TypeExpression obj, string member)
Writes the call instruction.
This class encapsulates the instruction used to generate the code.
virtual string FullName
Gets the full name of the type Note: WriteType expression is the longest recursive representation of ...
int ParameterListCount
Gets the number of parameters
Definition: MethodType.cs:111
override void WriteThrowException(int indent, DynamicExceptionManager dynException)
Writes the generation code to throw a specified exception.
TypeExpression Return
Gets type expression method return
Definition: MethodType.cs:100
override void WriteCatch(int indent, String type, String var)
void ldnull(int indent)
Writes the ldnull instruction.
void brtrue(int indent, string label)
Writes the brtrue instruction.
override void WriteOpenBraceFinally(int indent)
void bne(int indent, string label)
Writes the bne instruction.
void stfld(int indent, TypeExpression type, string classId, string fieldName)
Writes the stfld instruction.
void blt(int indent, string label)
Writes the blt instruction.
void mul(int indent)
Writes the mul instruction.
override void WriteAuxiliarLocalVariable(int indent, string id, string type)
Writes the information of local variables.
Represent a integer type.
Definition: IntType.cs:37
override void WriteCodeOfExceptionsTemplateMethod(DynamicExceptionManager d)
Implements Template Method
virtual void newarr(int indent, TypeExpression token)
Writes the newarr instruction.
override void WriteEndOfInterface(int indent, string name)
Writes the interface termination
void ceq(int indent)
Writes the ceq instruction.
void bgt(int indent, string label)
Writes the bgt instruction.
virtual bool IsFreshVariable()
To know if it is a type variable with no substitution
override void WriteLNMethodHeader(int indent, string name, MethodType type)
Writes the method header.
List< Parameter > ParametersInfo
Gets the parameters information used to obtain its type
override void WriteCloseBraceTry(int indent)
abstract bool IsValueType()
True if type expression is a ValueType. Otherwise, false.
void ldflda(int indent, string token)
Writes the ldflda instruction.
Represents a double type.
Definition: DoubleType.cs:36
void concat(int indent)
Writes the concat instruction for string types.
abstract override void UnboxAny(int indent, TypeExpression type)
Writes the Unbox instruction
void ldcr8(int indent, string val)
Writes the ldc.i8 instruction.
void stloc_s(int indent, string variable)
Writes the stloc.s instruction.
TextWriter output
Writer to write the intermediate code.
void beq(int indent, string label)
Writes the beq instruction.
void convToInt(int indent)
Writes the conv.i4 instruction.
void brfalse(int indent, string label)
Writes the brfalse instruction.
virtual void ProcessField(int indent, FieldDeclaration node, Object obj, bool constantField)
void not(int indent)
Bitwise inversion (unary). This operation, rather than neg, is recommended for integer sign inversion...
void newobj(int indent, MethodType memberType, TypeExpression obj, string member)
Writes the newobj instruction.
virtual string ILType()
Gets the type name to use in IL code.
override void WriteEndOfBlock(int indent)
Writes the termination token
virtual void UnBoxIfNeeded(int indent, TypeExpression type)
Convert and OBject to a valuetype if is not an reference type ///
override void WriteEntryPoint(int indent)
Writes the entrypoint directive.
List< InterfaceType > InterfaceList
Gets the list of interfaces
Definition: UserType.cs:157
virtual void WriteCall(MethodType memberType, TypeExpression klass, string member, AST.CompoundExpression arguments)
Writes the &#39;token&#39; of call instructions.
void ldflda(int indent, TypeExpression type, string classId, string fieldName)
Writes the ldflda instruction.
virtual void WriteThrowNonSuitableObjectException(int indent, string klass, string method)
void isinst(int indent, TypeExpression token)
Writes the isinst instruction. About the isinst Instruction. It takes two arguments: an object refere...
void pop(int indent)
Writes a pop instruction.
virtual void WriteClassName(string name)
void ret(int indent)
Writes the ret instruction.
void ldloc(int indent, string locVar)
Writes the ldloc instruction.
void xor(int indent)
Writes the xor instruction.
override void WriteNamespaceHeader(int indent, string name)
Writes the namespace header of an IL file.
override void Comment(int indent, string msg)
void ble(int indent, string label)
Writes the ble instruction.
override void BoxIfNeeded(int indent, TypeExpression type)
Makes sure to convert a type to an object
void dup(int indent)
Writes a dup instruction.
void ldci4(int indent, int val)
Writes the ldc.i4 instruction.
override void WriteThrowException(int indent, string ex, string[] msg)
Writes the code to throw an exception derived from Exception without using DynamicExceptionManager ...
void ldarg(int indent, int argNumber)
ldarg &lt;unsigned int16&gt;=&quot;&quot;&gt; Load the argument number &lt;unsigned int16&gt;=&quot;&quot;&gt; on the stack. The argument enumeration is zero-based, but it’s important to remember that instance methods have an &#39;invisible&#39; argument not specified in the method signature: the class instance pointer, this, which is always argument number 0. Because static methods don’t have such an &#39;invisible&#39; argument, for them argument number 0 is the first argument specified in
void shl(int indent)
Writes the shl instruction.
Modifier
Indicates differents modifiers to use in class (only public, internal or static), fields or methods...
override void Call(int indent, string methodType, string result, string klass, string memberName, string[] args)
Writes the call instruction
virtual void newarr(int indent, string type)
Writes the newarr instruction.
void convToChar(int indent)
Writes the conv.u2 instruction.
override void WriteLocalVariable(int indent)
Writes the information of local variables.
void ldstr(int indent, string val)
Writes the ldstr instruction.
Representa a property type.
Definition: PropertyType.cs:34
UserType Class
Gets or sets the class type reference
override void CallVirt(int indent, string methodType, string result, string klass, string memberName, string[] args)
Writes the CallVirt instruction
void WriteLine(int indentation, string msg)
virtual void WriteMethodModifiers(int indent, MethodType type)
Representa a method type.
Definition: MethodType.cs:37
void starg(int indent, int argNumber)
starg &lt;unsigned int16&gt;=&quot;&quot;&gt; Take a value from the stack and store it in argument slot number &lt;unsigned...
virtual void stelemDouble(int indent)
Writes the stelem.r8 instruction.
Encapsulates a declaration of a concrete field.
override void WriteInterfaceHeader(int indent, string name, InterfaceType type)
Writes the interface header
ClassType BaseClass
Gets the base type (null if not exists).
Definition: ClassType.cs:56
Dictionary< string, DynamicExceptionManager > exceptions
List of exceptions that is necessary to include in intermediate code file.
void ldarg(int indent, string argName)
Writes the ldarg instruction. Unsing argument names instead of numbers. See ldar(int, int) above
virtual void WriteClassImplements(ClassType type)
void arglist(int indent)
Writes the arglist instruction.
void ldfld(int indent, TypeExpression type, string classId, string fieldName)
Writes the ldfld instruction.
StringBuilder currentLocalVars
Stores the current information about local variables.
virtual void WriteThrowMissingMethodException(int indent, string method)
void and(int indent)
Writes the and instruction.
IList< TypeExpression > TypeSet
Gets the list of type expressions
Definition: UnionType.cs:57
Represent a bool type.
Definition: BoolType.cs:36
void ldtoken(int indent, string ILType)
Writes the ldtoken instruction.
void ldloca_s(int indent, string tmpVar)
loads the content of variable tmpVar in the top of the stack
override void AddLocalVariable(string name, TypeExpression type)
Stores the information of the local variable.
void stloc(int indent, int locNumber)
Writes the stloc instruction.
override void Call(int indent, MethodType memberType, TypeExpression obj, string member)
Writes the call instruction.
virtual void WriteClassExtends(ClassType type)
TypeExpression PropertyTypeExpression
Gets the property type.
Definition: PropertyType.cs:64
void ldarga(int indent, string argName)
Writes the ldarga instruction, that loads the direction of argument with name argName.
bool IsValueType(TypeExpression exp)
virtual void WriteMethodParameters(MethodType type)
Represents a class type.
Definition: ClassType.cs:35
Representa a field type.
Definition: FieldType.cs:37
void br(int indent, string label)
Writes the br instruction.
override void WriteLNClassHeader(int indent, string name, ClassType type)
Writes the class header in IL code
virtual string TypeName
Gets the type information
virtual void ldlen(int indent, TypeExpression token)
Writes the ldlen instruction.
override void InitialComment()
Displays de comment to show in the first line of il file.
override void WriteOpenBraceCatch(int indent)
void ldloc(int indent, int locNumber)
Writes the ldloc instruction.
ILCodeGenerator(TextWriter output)
TypeExpression GetParameter(int index)
Gets the type expression of the specific parameter
Definition: MethodType.cs:202
void starg(int indent, string argNumber)
Writes the starg instruction.
virtual object AcceptOperation(TypeSystemOperation op, object arg)
void sub(int indent)
Writes the sub instruction.
void rem(int indent)
Writes the rem instruction.
void add(int indent)
Writes the add instruction.
ILStatementsCodeGeneration ilStamentsCodeGeneration
TypeExpression TypeExpr
Gets or sets the type of the declaration
Definition: Declaration.cs:63
virtual void ldelemChar(int indent)
Writes the ldelem.u2 instruction.
override void WriteCloseBraceFinally(int indent)
override void WriteEndOfClass(int indent, string name)
Writes the class termination acoording to IL code
virtual void stelemInt(int indent)
Writes the stelem.i4 instruction.
void cgt(int indent)
Writes the cgt instruction.
void convToDouble(int indent)
Writes the conv.r8 instruction.
void nop(int indent)
Writes a nop instruction.