public CIL_callvirt(string label, CILMethod theMethod) : base(label) { this.theMethod = theMethod; }
public CIL_ldftn(string label, CILMethod theMethod) : base(label) { this.theMethod = theMethod; }
CILMethod ParseMethod(CILClass parentclass, string str) { // TODO: Need cleanup and reparse using Scanner List<string> argNames = new List<string>(); // count how much deep we are in a try block so that we // dont confuse } of the try-s as } of the method int try_counter = 0; int catch_counter; bool isStatic = false; CILScanner scanner = new CILScanner(fin, str); string st; string methodName = null; while(methodName == null) { st = scanner.NextToken(); if(st == "static") isStatic = true; if((st == "int32") || (st == "int64") || (st == "void") || (st == "float64") || (st == "bool")) methodName = scanner.NextToken(); else if(st == "class") { st = scanner.NextToken(); methodName = scanner.NextToken(); } } // skips "(" st = scanner.NextToken(); string methodSig = "("; int paramCount = 0; while(true) { st = scanner.NextToken(); if(st == ")") break; if(st != ",") { if(st == "class") { paramCount++; if(paramCount > 1) methodSig += ","; methodSig += scanner.NextToken(); } else { paramCount++; if(paramCount > 1) methodSig += ","; methodSig += st; } argNames.Add(scanner.NextToken()); } } methodSig += ")"; CILMethod themethod = parentclass.GetMethod(methodName, methodSig); themethod.SetArgumentNames(argNames); themethod.IsStatic = isStatic; currentMethod = themethod; // parse the method body bool done = false; str = GetNextLine(); // skips "{" while(done == false) { str = GetNextLine(); string[] ss = str.Split(' '); switch(ss[0]) { case ".maxstack": // TODO // can optimize stack allocation break; case ".try": // ignore exception handling // increase the try counter so that we know next } // is not end of the method try_counter++; GetNextLine(); // skip the { of the try block break; case "finally": try_counter++; GetNextLine(); // skip the { of the finally block break; case "catch": // ignore the whole catch block, find } to stop // first ignore the {, then count to find the end GetNextLine(); catch_counter = 1; while(true) { string sc = GetNextLine(); sc = sc.TrimStart(); if(sc.Length > 1) { if(sc[0] == '{') catch_counter++; else if(sc[0] == '}') catch_counter--; } if(catch_counter == 0) break; } break; case ".locals": bool endlocals = false; while(endlocals == false) { if(str.IndexOf("(") >= 0) str = str.Substring(str.IndexOf("(") + 1); string s2; if(str.IndexOf(",") >= 0) s2 = str.Substring(0, str.IndexOf(",")); else if(str.IndexOf(")") >= 0) { s2 = str.Substring(0, str.IndexOf(")")); endlocals = true; } else { Console.WriteLine("Unknown local variable declaration {0}", str); throw new Exception("Unknown local variable declaration"); } themethod.AddLocalVariable(ParseLocalVariable(s2)); if(endlocals == false) str = GetNextLine(); } break; case "}": if(try_counter == 0) done = true; else try_counter--; break; case ".entrypoint": program.EntryPoint = themethod; break; default: string label = str.Substring(0, str.IndexOf(":")); CILInstruction inst = ParseInstruction(label, str.Substring(10, str.Length - 10)); if(inst != null) themethod.AddInstruction(inst); break; } } return themethod; }
public CILMethod GetMethod(string methodName, string methodSig) { // TODO // now methods are identified by name only // must change to method signature soon foreach(CILMethod method in methods) if((method.Name == methodName) && (method.Sig == methodSig)) return method; CILMethod ret = new CILMethod(this, methodName, methodSig); methods.Add(ret); return ret; }