3 using CodeGeneration.ExceptionManagement;
6 using CodeGeneration.Operations;
7 namespace CodeGeneration {
18 get {
return "IL_" + this.currentLabel++; }
22 #region Index of Local variables
24 private static int localVariableIndex = 0;
31 get {
return localVariableIndex; }
32 set { localVariableIndex = value; }
52 this.ilStamentsCodeGeneration.WriteLine();
53 this.Comment(
"=============== CLASS MEMBERS DECLARATION ===================");
57 #region WriteConstructorHeader()
59 internal override void WriteConstructorHeader(
int indent) {
60 this.ilStamentsCodeGeneration.WriteLine(indent,
".method public specialname rtspecialname instance void .ctor()");
65 #region WriteStaticConstructorHeader()
67 internal override void WriteStaticConstructorHeader(
int indent) {
68 this.ilStamentsCodeGeneration.WriteLine(indent,
".method public specialname rtspecialname static void .cctor()");
74 public override void Comment(
string msg) {
79 this.ilStamentsCodeGeneration.WriteComment(msg);
87 public override void Comment(
int indent,
string msg) {
88 this.ilStamentsCodeGeneration.WriteComment(indent, msg);
93 public override void WriteLabel(
int indentation,
string label) {
98 this.ilStamentsCodeGeneration.WriteLine(indentation, label +
": nop");
110 this.ilStamentsCodeGeneration.WriteType(type);
115 #region WriteHeader()
122 this.ilStamentsCodeGeneration.WriteLNAssemblyDirective(fileName);
123 this.ilStamentsCodeGeneration.WriteModule(fileName);
128 #region WriteNamespaceHeader()
136 this.ilStamentsCodeGeneration.WriteIndentation(indent);
137 this.ilStamentsCodeGeneration.WriteNamespace(name);
138 this.ilStamentsCodeGeneration.WriteLine();
139 this.ilStamentsCodeGeneration.WriteOpenBrace(indent);
144 #region WriteClassName
147 this.ilStamentsCodeGeneration.Write(
"auto ansi {0} ", name);
152 #region WriteClassExtends
155 this.ilStamentsCodeGeneration.Write(
"extends ");
157 this.ilStamentsCodeGeneration.Write(
"[mscorlib]System.Object");
159 this.ilStamentsCodeGeneration.Write(TypeMapping.Instance.GetBCLName(type.BaseClass.FullName,
true).ToString());
163 #region WriteClassImplements
169 this.ilStamentsCodeGeneration.Write(
" implements ");
170 for (
int i = 0; i < type.InterfaceList.Count - 1; i++) {
172 this.ilStamentsCodeGeneration.Write(
"[mscorlib]");
173 this.ilStamentsCodeGeneration.Write(
"{0}, ", type.InterfaceList[i].FullName);
176 this.ilStamentsCodeGeneration.Write(
"[mscorlib]");
177 this.ilStamentsCodeGeneration.Write(
"{0}", type.InterfaceList[type.InterfaceList.Count - 1].FullName);
182 #region WriteLNClassHeader()
191 this.ilStamentsCodeGeneration.WriteClassVisibility(indent, name, type);
192 this.WriteClassName(name);
193 this.WriteClassExtends(type);
194 this.WriteClassImplements(type);
195 this.ilStamentsCodeGeneration.WriteLine();
200 #region WriteEndOfClass()
209 this.ilStamentsCodeGeneration.WriteCloseBrace(indent);
210 this.ilStamentsCodeGeneration.WriteComment(name);
215 #region WriteLNInterfaceHeader()
218 this.ilStamentsCodeGeneration.WriteLNInterfaceHeader(indent, name, type);
222 #region WriteLNEndOfInterface()
231 this.ilStamentsCodeGeneration.WriteCloseBrace(indent);
232 this.ilStamentsCodeGeneration.WriteComment(
"End of interface " + name);
236 #region ProcessField()
239 this.ilStamentsCodeGeneration.WriteLine();
241 this.ilStamentsCodeGeneration.WriteLine();
248 this.ilStamentsCodeGeneration.WriteField(indent, name, type, constantField);
253 #region WriteLNFieldInitialization()
256 this.ilStamentsCodeGeneration.WriteFieldInitialization(type);
261 #region WriteEndOfField()
267 this.ilStamentsCodeGeneration.Write(
")");
272 #region WriteStartBlock()
279 this.ilStamentsCodeGeneration.WriteOpenBrace(indent);
284 #region WriteLNEndOfBlock()
291 this.ilStamentsCodeGeneration.WriteLineCloseBrace(indent); ;
296 #region WriteLNMethodHeader
329 #region WriteLNMethodEndOfHeader
331 this.ilStamentsCodeGeneration.WriteLine(
") cil managed");
336 #region WriteMethodModifiers
338 Modifier mask = type.MemberInfo.ModifierMask;
340 this.ilStamentsCodeGeneration.Write(indent,
".method ");
343 this.ilStamentsCodeGeneration.Write(
"public hidebysig ");
350 this.ilStamentsCodeGeneration.Write(
"private ");
351 if ((mask & (
Modifier.Protected |
Modifier.Internal)) == (Modifier.Protected | Modifier.Internal))
352 this.ilStamentsCodeGeneration.Write(
"famorassem ");
354 if ((mask &
Modifier.Internal) != 0)
356 if ((mask &
Modifier.Protected) != 0)
357 this.ilStamentsCodeGeneration.Write(
"family ");
359 this.ilStamentsCodeGeneration.Write(
"hidebysig ");
363 #region WriteMethodTypeOfAccess
366 Modifier mask = type.MemberInfo.ModifierMask;
367 bool constructorFound = type.MemberInfo.Class.Name.Equals(name);
370 if ((mask &
Modifier.Override) != 0)
371 this.ilStamentsCodeGeneration.Write(
"virtual ");
375 if (constructorFound)
376 this.ilStamentsCodeGeneration.Write(
"specialname rtspecialname ");
378 if ((mask &
Modifier.Static) == 0 && !constructorFound &&
379 type.MemberInfo.Class.InterfaceList.Count > 0) {
380 this.ilStamentsCodeGeneration.Write(
"virtual final ");
386 this.ilStamentsCodeGeneration.Write(
"instance ");
388 if (constructorFound) {
389 this.ilStamentsCodeGeneration.Write(
"void");
393 this.ilStamentsCodeGeneration.Write(
" .ctor(");
398 this.WriteType(type.Return);
399 this.ilStamentsCodeGeneration.Write(
" {0}(", name);
405 #region WriteMethodParameters
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++)
416 #region WriteEndOfMethod()
424 this.ilStamentsCodeGeneration.WriteCloseBrace(indent);
425 this.ilStamentsCodeGeneration.WriteComment(
"End of method " + name);
430 #region WriteParams()
436 this.ilStamentsCodeGeneration.Write(
"(");
437 if (memberType != null)
440 this.ilStamentsCodeGeneration.Write(memberType.GetParameter(0).ILType());
441 for (
int i = 1; i < memberType.ParameterListCount; i++)
443 }
else if (arguments != null && arguments.ExpressionCount != 0) {
444 this.ilStamentsCodeGeneration.Write(arguments.GetExpressionElement(0).ILTypeExpression.ILType());
445 for (
int i = 1; i < arguments.ExpressionCount; i++)
448 this.ilStamentsCodeGeneration.Write(
")");
452 #region AddLocalVariable()
462 this.currentLocalVars.Append(
",");
463 this.currentLocalVars.AppendLine();
464 this.currentLocalVars.AppendFormat(
"\t\t\t[{0}] {1} {2}",
LocalVariableIndex++, type.ILType(), name);
469 #region WriteLocalVariable()
477 this.ilStamentsCodeGeneration.WriteIndentation(indent);
478 this.ilStamentsCodeGeneration.WriteLine(
".locals init({0})", this.currentLocalVars);
479 this.currentLocalVars.Remove(0, this.currentLocalVars.Length);
484 #region WriteAuxiliarLocalVariable()
492 this.ilStamentsCodeGeneration.WriteIndentation(indent);
493 this.ilStamentsCodeGeneration.WriteAuxiliarLocalVariable(id, type);
494 this.ilStamentsCodeGeneration.WriteLine();
499 #region WriteEntryPoint ()
502 this.ilStamentsCodeGeneration.WriteIndentation(indent);
503 this.ilStamentsCodeGeneration.WriteEntryPoint();
504 this.ilStamentsCodeGeneration.WriteLine();
509 #region ThrowDirective ()
512 this.ilStamentsCodeGeneration.WriteIndentation(indent);
513 this.ilStamentsCodeGeneration.WriteLine(
".try");
516 this.ilStamentsCodeGeneration.WriteIndentation(indent);
517 this.ilStamentsCodeGeneration.WriteLine(
"{");
520 this.ilStamentsCodeGeneration.WriteIndentation(indent);
521 this.ilStamentsCodeGeneration.WriteLine(
"} // end .try");
524 this.WriteLNNoArgsCommand(indent,
"rethrow");
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));
536 this.ilStamentsCodeGeneration.WriteIndentation(indent);
537 this.ilStamentsCodeGeneration.WriteLine(
"{");
541 this.ilStamentsCodeGeneration.WriteIndentation(indent);
542 this.ilStamentsCodeGeneration.WriteLine(
"} // end handler");
550 this.ilStamentsCodeGeneration.WriteIndentation(indent);
551 this.ilStamentsCodeGeneration.WriteLine(
"finally");
554 this.ilStamentsCodeGeneration.WriteIndentation(indent);
555 this.ilStamentsCodeGeneration.WriteLine(
"{");
558 this.ilStamentsCodeGeneration.WriteIndentation(indent);
559 this.ilStamentsCodeGeneration.WriteLine(
"} // end .try");
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");
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);
577 WriteLNNoArgsCommand(indent,
"call string [mscorlib]System.String::Format(string,object, object)");
578 WriteThrowException(indent,
"[mscorlib]System.MissingMemberException",
new string[] {
"string" });
582 ldstr(indent, String.Format(
"Class {0} does not accept message {1}().", klass, method));
583 WriteThrowException(indent,
"[mscorlib]System.MissingMemberException",
new string[] {
"string" });
585 #region AddExceptionCode()
595 this.exceptions.Add(typeException.TypeName, typeException);
597 while (baseType != null)
598 if (!this.
exceptions.ContainsKey(baseType.TypeName)) {
599 this.exceptions.Add(baseType.TypeName, baseType);
600 baseType = baseType.BaseException;
607 #region RuntimeUnionTypePromotion()
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)");
661 bool isFieldType1 =
false;
662 bool isFieldType2 =
false;
666 typeExp1 = aux.FieldTypeExpression;
672 typeExp2 = aux.FieldTypeExpression;
676 certainType1 = aux.FieldTypeExpression;
679 certainType2 = aux.FieldTypeExpression;
685 if (certainType1.
IsValueType() && certainType2.IsValueType()) {
690 this.UnboxAny(indent, certainType1);
691 this.convToDouble(indent);
695 if (certainType1 == certainType2 || certainType1.
ILType().Equals(certainType2.ILType()))
699 this.UnboxAny(indent, certainType1);
701 if (!isFieldType1 && isFieldType2) {
703 this.Box(indent, certainType2);
710 this.
UnboxAny(indent, certainType2);
716 if (unidirectionalConversion)
717 this.Box(indent, certainType1);
722 if (!IsUnionOfProperties(
union))
723 certainType2.
AcceptOperation(
new CGRuntimeUnionTypePromotionOperation<ILCodeGenerator>(indent,
this,
union), null);
724 else if(
union.Count > 0)
740 if (unidirectionalConversion) {
741 if (!(typeExp1 is
TypeVariable) && typeExp2 is TypeVariable && makeBoxing)
742 this.Box(indent, certainType2);
751 if (certainType1.
IsValueType() && !certainType2.IsValueType()) {
752 if (unidirectionalConversion) {
755 this.Box(indent, certainType1);
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);
766 this.
CallVirt(indent,
"instance",
"string",
"[mscorlib]System.Object",
"ToString", null);
772 if (!certainType1.
IsValueType() && certainType2.IsValueType()) {
777 certainType2.
AcceptOperation(
new CGRuntimeFreshTEPromotionOperation<ILCodeGenerator>(indent,
this), null);
782 certainType2.
AcceptOperation(
new CGRuntimeUnionTypePromotionOperation<ILCodeGenerator>(indent,
this,
union), null);
790 certainType2.AcceptOperation(
new CGRuntimeFreshTEPromotionOperation<ILCodeGenerator>(indent,
this), null);
794 certainType2.AcceptOperation(
new CGRuntimeFreshTEPromotionOperation<ILCodeGenerator>(indent,
this), null);
798 private bool IsUnionOfProperties(
UnionType ut)
800 foreach (var typeExpression
in ut.
TypeSet)
821 #region WriteCodeOfExceptionsTemplateMethod
827 this.ilStamentsCodeGeneration.WriteLine(d.WriteDynamicExceptionCode());
833 #region RuntimeFreshTypeExpressionPromotion()
968 #region WriteThrowException
976 this.newobj(indent, dynException.TypeName,
new string[] { });
977 this.WriteThrow(indent);
987 this.newobj(indent, ex, msg);
988 this.WriteThrow(indent);
994 #region Addressing Classes and Value Types
1007 this.WriteLNUnaryCommand(indent,
"ldobj", val.ILType());
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);
1040 this.WriteLNNoArgsCommand(indent,
"ldnull");
1061 this.ilStamentsCodeGeneration.Write(indent,
"newobj instance void {0}::{1}", obj.ILType(), member);
1062 this.WriteParams(memberType, null);
1063 this.ilStamentsCodeGeneration.WriteLine();
1075 public void newobj(
int indent,
string klass,
string[] args) {
1076 this.ilStamentsCodeGeneration.Write(indent,
"newobj instance void {0}::.ctor(", klass);
1079 this.ilStamentsCodeGeneration.Write(
"{0}", String.Join(
", ", args));
1080 this.ilStamentsCodeGeneration.WriteLine(
")");
1096 this.WriteLNUnaryCommand(indent,
"castclass", token.ILType());
1110 this.WriteLNNoArgsCommand(indent,
"throw");
1117 #region Argument instructions
1120 public void ldarg(
int indent,
int argNumber) {
1132 this.ilStamentsCodeGeneration.WriteLine(indent,
"ldarg.{0}", argNumber);
1140 public void ldarg(
int indent,
string argName) {
1141 this.WriteLNUnaryCommand(indent,
"ldarg", argName);
1147 public void ldarga(
int indent,
string argName) {
1153 this.WriteLNUnaryCommand(indent,
"ldarga", argName);
1171 public void starg(
int indent,
int argNumber) {
1172 this.ilStamentsCodeGeneration.WriteLine(indent,
"starg.{0}", argNumber);
1180 public void starg(
int indent,
string argNumber) {
1181 this.WriteLNUnaryCommand(indent,
"starg", argNumber);
1196 this.WriteLNNoArgsCommand(indent,
"arglist");
1203 #region Arithmetical Operations
1218 this.WriteLNNoArgsCommand(indent,
"add");
1226 this.WriteLNNoArgsCommand(indent,
"call string [mscorlib]System.String::Concat(object, object)");
1241 this.WriteLNNoArgsCommand(indent,
"mul");
1256 this.WriteLNNoArgsCommand(indent,
"div");
1271 this.WriteLNNoArgsCommand(indent,
"neg");
1285 this.WriteLNNoArgsCommand(indent,
"rem");
1301 this.WriteLNNoArgsCommand(indent,
"sub");
1307 #region Bitwise Operations
1321 this.WriteLNNoArgsCommand(indent,
"and");
1335 public void or(
int indent) {
1336 this.WriteLNNoArgsCommand(indent,
"or");
1351 this.WriteLNNoArgsCommand(indent,
"xor");
1365 this.WriteLNNoArgsCommand(indent,
"not");
1372 #region Box and Unbox
1385 this.WriteLNUnaryCommand(indent,
"box", type.ILType());
1395 this.Box(indent, type);
1408 this.Unbox(indent, type);
1419 this.WriteLNUnaryCommand(indent,
"unbox", type.ILType());
1426 #region Calling Methods
1428 #region call <token>
1430 #region WriteCallArguments()
1440 if (IsInstance(memberType))
1441 this.ilStamentsCodeGeneration.Write(
"instance ");
1443 string returnILType, classILType;
1444 if (memberType != null) {
1446 returnILType =
"object";
1448 returnILType = memberType.Return.ILType();
1449 classILType = klass.ILType();
1451 returnILType =
"object";
1452 classILType =
"[mscorlib]System.Object";
1454 this.ilStamentsCodeGeneration.Write(
"{0} {1}::{2}", returnILType, classILType, member);
1455 this.WriteParams(memberType, arguments);
1466 if (IsInstance(memberType))
1467 this.ilStamentsCodeGeneration.Write(
"instance ");
1469 string memberILType = memberType == null ?
"object" : memberType.PropertyTypeExpression.ILType();
1472 this.ilStamentsCodeGeneration.WriteLine(
"void {0}::set_{1}({2})", obj.ILType(), member, memberILType);
1474 this.ilStamentsCodeGeneration.WriteLine(
"{0} {1}::get_{2}()", memberILType, obj.ILType(), member);
1490 this.ilStamentsCodeGeneration.Write(indent,
"call ");
1491 this.WriteCallArguments(memberType, obj, member, null);
1492 this.ilStamentsCodeGeneration.WriteLine();
1504 this.ilStamentsCodeGeneration.Write(indent,
"call ");
1505 this.WriteCallArguments(memberType, obj, member, setProperty);
1506 this.ilStamentsCodeGeneration.WriteLine();
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);
1522 this.ilStamentsCodeGeneration.Write(String.Join(
", ", args));
1524 this.ilStamentsCodeGeneration.WriteLine(
")");
1529 #region CallVirt <token>
1542 this.ilStamentsCodeGeneration.Write(indent,
"callvirt ");
1543 this.WriteCall(memberType, klass, member, null);
1544 this.ilStamentsCodeGeneration.WriteLine();
1556 this.ilStamentsCodeGeneration.Write(indent,
"callvirt ");
1557 this.WriteCall(memberType, obj, member, setProperty);
1558 this.ilStamentsCodeGeneration.WriteLine();
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);
1575 this.ilStamentsCodeGeneration.Write(String.Join(
", ", args));
1576 this.ilStamentsCodeGeneration.WriteLine(
")");
1590 if (IsInstance(memberType))
1591 this.ilStamentsCodeGeneration.Write(
"instance ");
1593 string returnILType, classILType;
1594 if (memberType != null) {
1596 returnILType =
"object";
1598 returnILType = memberType.Return.ILType();
1599 classILType = klass.ILType();
1601 returnILType =
"object";
1602 classILType =
"[mscorlib]System.Object";
1604 this.ilStamentsCodeGeneration.Write(
"{0} {1}::{2}", returnILType, classILType, member);
1605 this.WriteParams(memberType, arguments);
1615 if (IsInstance(memberType))
1616 this.output.Write(
"instance ");
1618 string memberILType = memberType == null ?
"object" : memberType.PropertyTypeExpression.ILType();
1619 string klass = TypeMapping.Instance.GetBCLName(obj.ILType(),
true);
1621 this.ilStamentsCodeGeneration.Write(
"void {0}::set_{1}({2})", klass, member, memberILType);
1623 this.ilStamentsCodeGeneration.Write(
"{0} {1}::get_{2}()", memberILType, klass, member);
1629 #region Comparative Branching Instructions
1641 public void beq(
int indent,
string label) {
1642 this.WriteLNUnaryCommand(indent,
"beq", label);
1657 public void bne(
int indent,
string label) {
1658 this.WriteLNUnaryCommand(indent,
"bne.un", label);
1673 public void bge(
int indent,
string label) {
1674 this.WriteLNUnaryCommand(indent,
"bge", label);
1689 public void bgt(
int indent,
string label) {
1690 this.WriteLNUnaryCommand(indent,
"bgt", label);
1705 public void ble(
int indent,
string label) {
1706 this.WriteLNUnaryCommand(indent,
"ble", label);
1721 public void blt(
int indent,
string label) {
1722 this.WriteLNUnaryCommand(indent,
"blt", label);
1729 #region Constant Loading
1741 public void ldci4(
int indent,
int val) {
1742 this.WriteLNUnaryCommand(indent,
"ldc.i4", val.ToString()); ;
1747 #region ldc <float64>
1760 public void ldcr8(
int indent,
string val) {
1761 this.WriteLNUnaryCommand(indent,
"ldc.r8", val);
1775 public void ldc(
int indent,
bool val) {
1776 this.WriteLNNoArgsCommand(indent, val ?
"ldc.i4.1" :
"ldc.i4.0");
1781 #region ldtoken <type>
1791 this.WriteLNUnaryCommand(indent,
"ldtoken", ILType);
1799 #region constructorCall
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();
1821 this.ilStamentsCodeGeneration.WriteLine(indent,
"call\tinstance {0} {1}::{2}()", VoidType.Instance.ILType(), obj.
ILType(), member);
1827 #region Conversion Operations
1839 this.WriteLNNoArgsCommand(indent,
"conv.i4");
1855 this.WriteLNNoArgsCommand(indent,
"conv.u2");
1860 #region convToDouble
1870 this.WriteLNNoArgsCommand(indent,
"conv.r8");
1877 #region Field instructions
1895 this.ilStamentsCodeGeneration.WriteIndentation(indent);
1898 type = t.FieldTypeExpression;
1901 this.ilStamentsCodeGeneration.WriteLine(
"ldfld {0} {1}::{2}",
"object", classId, fieldName);
1903 this.ilStamentsCodeGeneration.WriteLine(
"ldfld {0} {1}::{2}", ((ClassTypeProxy)type).RealType.ILType(), classId, fieldName);
1905 this.ilStamentsCodeGeneration.WriteLine(
"ldfld {0} {1}::{2}", type.ILType(), classId, fieldName);
1925 type = t.FieldTypeExpression;
1927 this.ilStamentsCodeGeneration.WriteLine(indent,
"ldsfld {0} {1}::{2}",
"object", classId, fieldName);
1929 this.ilStamentsCodeGeneration.WriteLine(
"ldfld {0} {1}::{2}", ((ClassTypeProxy)type).RealType.ILType(), classId, fieldName);
1931 this.ilStamentsCodeGeneration.WriteLine(indent,
"ldsfld {0} {1}::{2}", type.ILType(), classId, fieldName);
1946 this.ilStamentsCodeGeneration.WriteLine(indent,
"ldflda {0} {1}::{2}", type.ILType(), classId, fieldName);
1954 public void ldflda(
int indent,
string token) {
1955 this.WriteLNUnaryCommand(indent,
"ldflda", token);
1970 this.ilStamentsCodeGeneration.WriteLine(indent,
"ldsflda {0} {1}::{2}", type.ILType(), classId, fieldName);
1979 this.WriteLNUnaryCommand(indent,
"ldsflda", token);
2000 type = t.FieldTypeExpression;
2002 this.ilStamentsCodeGeneration.WriteLine(indent,
"stfld {0} {1}::{2}",
"object", classId, fieldName);
2004 this.ilStamentsCodeGeneration.WriteLine(indent,
"stfld {0} {1}::{2}", ((ClassTypeProxy)type).RealType.ILType(), classId, fieldName);
2006 this.ilStamentsCodeGeneration.WriteLine(indent,
"stfld {0} {1}::{2}", type.ILType(), classId, fieldName);
2026 type = t.FieldTypeExpression;
2028 this.ilStamentsCodeGeneration.WriteLine(indent,
"stsfld {0} {1}::{2}",
"object", classId, fieldName);
2030 this.ilStamentsCodeGeneration.WriteLine(indent,
"stfld {0} {1}::{2}", ((ClassTypeProxy)type).RealType.ILType(), classId, fieldName);
2032 this.ilStamentsCodeGeneration.WriteLine(indent,
"stsfld {0} {1}::{2}", type.ILType(), classId, fieldName);
2039 #region Flow Control Instructions
2051 this.WriteLNNoArgsCommand(indent,
"ret");
2058 #region Local variable instructions
2071 public void ldloc(
int indent,
int locNumber) {
2072 this.WriteLNUnaryCommand(indent,
"ldloc", locNumber.ToString());
2080 public void ldloc(
int indent,
string locVar) {
2081 this.WriteLNUnaryCommand(indent,
"ldloc", locVar);
2097 public void ldloca(
int indent,
int locNumber) {
2098 this.WriteLNUnaryCommand(indent,
"ldloca", locNumber.ToString());
2106 public void ldloca(
int indent,
string locVar) {
2107 this.WriteLNUnaryCommand(indent,
"ldloca", locVar);
2115 this.WriteLNUnaryCommand(indent,
"ldloca.s", tmpVar);
2132 public void stloc(
int indent,
int locNumber) {
2133 this.WriteLNNoArgsCommand(indent,
"stloc." + locNumber.ToString());
2141 public void stloc_s(
int indent,
string variable) {
2142 this.WriteLNUnaryCommand(indent,
"stloc.s", variable);
2151 public void stloc(
int indent,
string locVar) {
2152 this.WriteLNUnaryCommand(indent,
"stloc", locVar);
2160 #region Logical Condition Check Operations
2172 this.WriteLNNoArgsCommand(indent,
"ceq");
2189 this.WriteLNNoArgsCommand(indent,
"cgt");
2204 this.WriteLNNoArgsCommand(indent,
"clt");
2226 this.WriteLNUnaryCommand(indent,
"isinst", TypeMapping.Instance.GetBCLName(token.ILType(),
true));
2233 #region Shift Operations
2250 this.WriteLNNoArgsCommand(indent,
"shl");
2265 this.WriteLNNoArgsCommand(indent,
"shr");
2272 #region Stack manipulation
2285 this.WriteLNNoArgsCommand(indent,
"nop");
2301 this.WriteLNNoArgsCommand(indent,
"dup");
2317 this.WriteLNNoArgsCommand(indent,
"pop");
2325 public void WriteLeave(
int indentation,
string label) {
2331 this.WriteLNUnaryCommand(indentation,
"leave", label);
2351 #region Unconditional and Conditional Branching Instructions
2362 public void br(
int indent,
string label) {
2363 this.WriteLNUnaryCommand(indent,
"br", label);
2379 this.WriteLNUnaryCommand(indent,
"brfalse", label);
2394 public void brtrue(
int indent,
string label) {
2395 this.WriteLNUnaryCommand(indent,
"brtrue", label);
2402 #region VectorInstructions
2416 this.WriteLNUnaryCommand(indent,
"newarr",
"object");
2418 this.WriteLNUnaryCommand(indent,
"newarr", token.ILType());
2425 public virtual void newarr(
int indent,
string type) {
2426 this.WriteLNUnaryCommand(indent,
"newarr", type);
2442 this.WriteLNNoArgsCommand(indent,
"ldlen");
2457 this.WriteLNNoArgsCommand(indent,
"ldelem.i4");
2466 this.WriteLNNoArgsCommand(indent,
"ldelem.u2");
2477 this.WriteLNNoArgsCommand(indent,
"ldelem.r8");
2488 this.WriteLNNoArgsCommand(indent,
"ldelem.ref");
2503 this.WriteLNNoArgsCommand(indent,
"stelem.i4");
2514 this.WriteLNNoArgsCommand(indent,
"stelem.r8");
2525 this.WriteLNNoArgsCommand(indent,
"stelem.ref");
2534 internal void WriteLNNoArgsCommand(
int indentation,
string command) {
2535 ilStamentsCodeGeneration.WriteIndentation(indentation);
2536 this.WriteLNNoArgsCommand(command);
2540 internal void WriteLNNoArgsCommand(
string command) {
2541 this.ilStamentsCodeGeneration.WriteLine(command);
2544 ilStamentsCodeGeneration.WriteIndentation(indentation);
2545 ilStamentsCodeGeneration.WriteLine(msg);
2547 internal void WriteLNUnaryCommand(
int indentation,
string command,
string argument) {
2548 ilStamentsCodeGeneration.WriteLine(indentation,
"{0}\t{1}", command, argument);
2551 private static bool IsInstance(
PropertyType memberType) {
2552 return memberType == null || (memberType.MemberInfo.ModifierMask & Modifier.Static) == 0;
2555 private static bool IsInstance(
MethodType memberType) {
2556 return memberType == null || (memberType.MemberInfo.ModifierMask & Modifier.Static) == 0;
2559 this.ilStamentsCodeGeneration.WriteLine();
bool RequireBoxing(string ilType)
Tells if an IL type requires boxing to convert into an object
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
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 'token' 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
override void WriteParams(MethodType memberType, AST.CompoundExpression arguments)
override void WriteCloseBraceCatch(int indent)
void WriteThrow(int indent)
Writes the throw instruction.
static TypeMapping Instance
Offers the mappings between different representations of types in IL.
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.
void WriteRethrow(int indent)
MethodDeclaration ASTNode
The AST node set by the VisitorTypeDefinition and used in the VisitorTypeInferece for abstract interp...
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.
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.
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
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
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
override void WriteThrowException(int indent, DynamicExceptionManager dynException)
Writes the generation code to throw a specified exception.
TypeExpression Return
Gets type expression method return
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.
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.
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
virtual void WriteCall(MethodType memberType, TypeExpression klass, string member, AST.CompoundExpression arguments)
Writes the 'token' 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 <unsigned int16>=""> Load the argument number <unsigned int16>=""> on the stack. The argument enumeration is zero-based, but it’s important to remember that instance methods have an 'invisible' 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 'invisible' 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.
virtual void WriteLNMethodEndOfHeader()
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.
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.
void starg(int indent, int argNumber)
starg <unsigned int16>=""> Take a value from the stack and store it in argument slot number <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).
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
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.
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)
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
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
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.