Esempio n. 1
0
        private IReadOnlyList <IlMethod> LinkMethods(int startAddress, CallTree callTree)
        {
            var result  = new List <IlMethod>();
            var methods = callTree.Flatten().Select(m => m.Method).OrderBy(m => m.Order).ToList();

            GetMethodAddressLookup(_methodTableBuilder, startAddress, methods);

            foreach (var method in methods)
            {
                var address           = _methodTableBuilder.Targets[method.Name];
                var methdoBodyAddress = address.Value + InstructionFacts.SizeOfMethodHeader;
                var ilObjects         = LinkNodes(methdoBodyAddress, method.Nodes);
                var ilMethod          = new IlMethod(address, method.Args, ilObjects);

                if (method.IsEntryPoint)
                {
                    _entryPoint = ilMethod.Address;
                }

                result.Add(ilMethod);
            }

            return(result);
Esempio n. 2
0
        private IlProgram GetProgram(ReadOnlySpan <byte> program)
        {
            var pointer     = 0;
            var ilMethods   = new List <IlMethod>();
            var methodNames = new Dictionary <IlAddress, string>();

            var entryPointValue = BinaryConvert.GetInt32(ref pointer, program);

            var callTargets = new Stack <int>();

            callTargets.Push(entryPointValue);
            var visitedTargets = new HashSet <int> {
                entryPointValue
            };

            while (callTargets.Count > 0)
            {
                var ilObjects = new List <IlObject>();

                pointer = callTargets.Pop();
                var argCount = program[pointer];

                var method = new IlMethod(pointer, argCount, ilObjects);
                ilMethods.Add(method);
                methodNames.Add(method.Address, $"m{ilMethods.Count}");

                pointer += InstructionFacts.SizeOfMethodHeader;

                while (pointer < program.Length)
                {
                    var instructionAddress = pointer;
                    var instruction        = GetInstruction(program, ref pointer);
                    ilObjects.Add(new IlObject(instructionAddress, 0, instruction));

                    var arg = ReadArguments(instruction, program, ref pointer);

                    if (instruction == InstructionCode.Ret)
                    {
                        break;
                    }

                    if (arg is null)
                    {
                        continue;
                    }

                    ilObjects.Add(arg);

                    if (instruction != InstructionCode.Call)
                    {
                        continue;
                    }

                    var callTarget = (int)arg.Obj;

                    if (!visitedTargets.Add(callTarget))
                    {
                        continue;
                    }

                    callTargets.Push(callTarget);
                }
            }

            return(new IlProgram(entryPointValue, ilMethods.OrderBy(m => m.Address).ToArray(), methodNames, _labelTargets));
        }