예제 #1
0
        public static IEnumerable <DisasmMethodCall> ExtractMethodCalls(Disassembler disassembler, Dictionary <string, int> methodArgumentCountTable)
        {
            var instructions = disassembler.Instructions.ToArray();
            var result       = new List <DisasmMethodCall>();

            int index = 0;
            var regs  = new VMObject[16];
            var stack = new Stack <VMObject>();

            while (index < instructions.Length)
            {
                var instruction = instructions[index];

                switch (instruction.Opcode)
                {
                case Opcode.LOAD:
                {
                    var dst   = (byte)instruction.Args[0];
                    var type  = (VMType)instruction.Args[1];
                    var bytes = (byte[])instruction.Args[2];

                    regs[dst] = new VMObject();
                    regs[dst].SetValue(bytes, type);

                    break;
                }

                case Opcode.PUSH:
                {
                    var src = (byte)instruction.Args[0];
                    var val = regs[src];

                    var temp = new VMObject();
                    temp.Copy(val);
                    stack.Push(temp);
                    break;
                }

                case Opcode.CTX:
                {
                    var src = (byte)instruction.Args[0];
                    var dst = (byte)instruction.Args[1];

                    regs[dst] = new VMObject();
                    regs[dst].Copy(regs[src]);
                    break;
                }

                case Opcode.SWITCH:
                {
                    var src = (byte)instruction.Args[0];
                    var val = regs[src];

                    var contractName = regs[src].AsString();
                    var methodName   = stack.Pop().AsString();
                    var args         = PopArgs(contractName, methodName, stack, methodArgumentCountTable);
                    result.Add(new DisasmMethodCall()
                        {
                            MethodName = methodName, ContractName = contractName, Arguments = args
                        });
                    break;
                }

                case Opcode.EXTCALL:
                {
                    var src        = (byte)instruction.Args[0];
                    var methodName = regs[src].AsString();
                    var args       = PopArgs(null, methodName, stack, methodArgumentCountTable);
                    result.Add(new DisasmMethodCall()
                        {
                            MethodName = methodName, ContractName = "", Arguments = args
                        });
                    break;
                }
                }

                index++;
            }

            return(result);
        }