Ejemplo n.º 1
0
 CIL_newarr ParseNewarr(string label, string str)
 {
     CILScanner scanner = new CILScanner(fin, str);
     if(scanner.NextToken() != "newarr")
         throw new Exception("Unknown exception");
     string elementType = scanner.NextToken();
     switch(elementType)
     {
         case "[mscorlib]System.Int32":
             return new CIL_newarr(label, new CILVar_int32(""));
         case "[mscorlib]System.Int64":
             return new CIL_newarr(label, new CILVar_int64(""));
         case "[mscorlib]System.Double":
             return new CIL_newarr(label, new CILVar_double(""));
         default:
             throw new Exception("Unknown array type");
     }
 }
Ejemplo n.º 2
0
 CIL_ldfld ParseLdfld(string label, string str)
 {
     CILScanner scanner = new CILScanner(fin, str);
     if(scanner.NextToken() != "ldfld")
         throw new Exception("parse error: ldfld expected");
     string fieldtype = scanner.NextToken();
     if(fieldtype == "class")
         fieldtype = "class " + scanner.NextToken();
     string classname = scanner.NextToken();
     if(classname == "modreq")
     {
         scanner.NextToken(); // skip "["
         scanner.NextToken(); // skip "mscorlib...IsVolatile"
         scanner.NextToken(); // skip "]"
         classname = scanner.NextToken();
     }
     scanner.NextToken(); // skip "::";
     string fieldname = scanner.NextToken();
     if(nextAccessIsVolatile)
     {
         nextAccessIsVolatile = false;
         return new CIL_ldfld(label, fieldtype, classname, fieldname, true);
     }
     else
         return new CIL_ldfld(label, fieldtype, classname, fieldname, false);
 }
Ejemplo n.º 3
0
        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;
        }
Ejemplo n.º 4
0
        CIL_callvirt ParseCallvirt(string label, string str)
        {
            // TODO: Need cleanup and reparse using Scanner
            CILScanner scanner = new CILScanner(fin, str);
            string st = scanner.NextToken();
            if(st != "callvirt")
                throw new Exception("unrecognized call");

            string className = null;
            string methodName = null;
            while(className == null)
            {
                st = scanner.NextToken();
                if((st == "int32") || (st == "int64") || (st == "void") || (st == "class"))
                {
                    if(st == "class")
                        scanner.NextToken();
                    className = scanner.NextToken();
                    scanner.NextToken();
                    methodName = scanner.NextToken();
                }
            }

            string methodSig = "(";
            scanner.NextToken(); // skips "(";
            int paramCount = 0;
            while(true)
            {
                st = scanner.NextToken();
                if(st == ")")
                    break;
                if(st != ",")
                {
                    if(st == "class")
                    {
                        paramCount++;
                        if(paramCount == 2)
                            methodSig += ",";
                        methodSig += scanner.NextToken();
                    }
                    else
                        methodSig += st;
                }
            }
            methodSig += ")";

            CILClass theclass = program.GetClass(className);
            CILMethod themethod = theclass.GetMethod(methodName, methodSig);

            return new CIL_callvirt(label, themethod);
        }