Example #1
0
        /// <summary>
        /// Generate C class/struct.
        /// </summary>
        /// <param name="type">Class type</param>
        public CClass(Type type)
        {
            Structure = "";
            if (type.IsAbstract)
            {
                return;
            }

            if (type.Name.Contains("<") || type.Name.Contains("`"))
            {
                Console.WriteLine($"Unsupported and/or generic type {type.Name}");
                return;
            }

            Structure += $"typedef struct {type.Name}\n" + "{\n";
            var methods = type.GetMethods().ToList();

            methods.AddRange(type.GetMethods(BindingFlags.NonPublic));

            var methodList = (from method in type.GetMethods()
                              where type.BaseType != null
                              from info in type.BaseType?.GetMethods()
                              where method.GetBaseDefinition() == info
                              select method).ToList();

            /*
             * Collect methods
             */
            foreach (var method in type.GetMethods())
            {
                if (method.GetCustomAttribute <CMethodCoverAttribute>() != null)
                {
                    return;
                }
                if (type.BaseType != null)
                {
                    var none = true;
                    foreach (var info in type.BaseType.GetMethods())
                    {
                        if (method.GetBaseDefinition() == info)
                        {
                            none = false;
                        }
                    }
                    if (none)
                    {
                        methodList.Add(method);
                    }
                }
                else
                {
                    methodList.Add(method);
                }
            }

            foreach (var method in methodList)
            {
                if (method.IsStatic)
                {
                    continue;
                }
                try
                {
                    var parts = method.ReturnType.Name.Split('.');
                    Structure +=
                        $"\t{CType.Deserialize(parts[parts.Length - 1])} (*{method.Name}{Visualizer.Additional(method, type)})(";
                    foreach (var parameter in method.GetParameters())
                    {
                        Structure += $"{CType.Deserialize(parameter.ParameterType)} {parameter.Name}";
                    }

                    if (!method.IsStatic)
                    {
                        if (method.GetParameters().Length > 0)
                        {
                            Structure += ", ";
                        }
                        Structure += $"struct {type.Name}*me";
                    }

                    Structure += ");\n\n";
                }
                catch
                {
                    Console.WriteLine("Failed");
                }
            }

            var fields = type.GetFields().ToList();

            fields.AddRange(type.GetFields(BindingFlags.NonPublic | BindingFlags.Instance));
            foreach (var field in fields)
            {
                if (field.IsStatic)
                {
                    continue;
                }
                try
                {
                    var newName = field.Name.Where(t => t != '<' && t != '>')
                                  .Aggregate("", (current, t) => current + t);
                    Structure += $"\t{CType.Deserialize(field.FieldType.Name)} {newName};\n";
                }
                catch
                {
                    Console.WriteLine("Failed");
                }
            }

            Structure += "}" + $" {type.Name};\n\n";
        }
Example #2
0
        /// <summary>
        /// Generate C function.
        /// </summary>
        public CFunction(MethodInfo function, Type cls, IReadOnlyList <string> genericTypes = null)
        {
            Declaration = "";
            Definition  = "";
            if (function.GetCustomAttribute <CMethodCoverAttribute>() != null ||
                function.DeclaringType.IsAbstract)
            {
                return;
            }

            if (function.GetCustomAttribute <CMethodCoverAttribute>() != null)
            {
                return;
            }

            var pars = function.GetParameters().Select(parameter =>
                                                       $"{CType.Deserialize(parameter.ParameterType)} {parameter.Name}").ToList();

            if (function.IsGenericMethod && genericTypes != null)
            {
                var generics = function.GetGenericArguments();
                for (var i = 0; i < generics.Length; i++)
                {
                    var generic = generics[i];
                    for (var index = 0; index < function.GetParameters().Length; index++)
                    {
                        var parameter = function.GetParameters()[index];
                        if (parameter.ParameterType.Name == generic.Name)
                        {
                            pars[index] = $"{genericTypes[i]} {parameter.Name}";
                        }
                    }
                }
            }

            var parts = function.ReturnType.Name.Split('.');

            /*
             * DEC
             */

            Declaration = $"extern {CType.Deserialize(parts[parts.Length - 1])} " +
                          $"{cls.Name + function.Name}" +
                          $"{Visualizer.Additional(function, cls)} (";

            foreach (var par in pars)
            {
                Declaration += $"{par}";
                if (pars[pars.Count - 1] != par)
                {
                    Declaration += ", ";
                }
            }

            if (!function.IsStatic)
            {
                if (pars.Count > 0)
                {
                    Declaration += ", ";
                }
                Declaration += $"struct {function.DeclaringType?.Name}*me";
            }

            Declaration += ");\n\n";

            /*
             * DEF
             */

            if (function.DeclaringType != null)
            {
                Definition = $"{CType.Deserialize(parts[parts.Length - 1])} " +
                             $"{cls.Name + function.Name}" +
                             $"{Visualizer.Additional(function, cls)} (";

                foreach (var par in pars)
                {
                    Definition += $"{par}";
                    if (pars[pars.Count - 1] != par)
                    {
                        Definition += ", ";
                    }
                }

                if (!function.IsStatic)
                {
                    if (pars.Count > 0)
                    {
                        Definition += ", ";
                    }
                    Definition += $"struct {function.DeclaringType?.Name}*me";
                }

                Definition += ")\n{\n";
            }

            Visualizer.FirstPass = false;
            foreach (var line in Visualizer.BuildBody(function))
            {
                Definition += line;
            }

            Definition += "}\n\n";
        }
Example #3
0
        /// <summary>
        /// Build C code body.
        /// </summary>
        /// <param name="body"></param>
        /// <returns></returns>
        public static IEnumerable <string> BuildBody(MethodBase body)
        {
            /*
             * Get methods from Mono.cil
             */
            var assembly  = AssemblyDefinition.ReadAssembly(body.DeclaringType?.Assembly.Location);
            var toInspect = assembly.MainModule
                            .GetTypes()
                            .SelectMany(t => t.Methods.Select(m => new { t, m }))
                            .Where(x => x.m.HasBody).ToArray();

            if (!toInspect.Any())
            {
                //Failed to find any methods.
                yield return("return 0");

                yield break;
            }

            /*
             * Find the correct method.
             */
            var declared = false;
            var method   = (MethodDefinition)null;

            foreach (var me in toInspect)
            {
                if (body.DeclaringType != null && (me.m.Name != body.Name ||
                                                   body.GetParameters().Length != me.m.Parameters.Count ||
                                                   me.t.FullName != body.DeclaringType.FullName))
                {
                    continue;
                }
                var hold = true;
                for (var index = 0; index < body.GetParameters().Length; index++)
                {
                    var parameter = body.GetParameters()[index];
                    if (parameter.ParameterType.FullName == me.m.Parameters[index].ParameterType.FullName)
                    {
                        continue;
                    }
                    hold = false;
                    break;
                }

                if (!hold)
                {
                    continue;
                }
                declared = true;
                method   = me.m;
            }

            if (!declared)
            {
                yield break;
            }

            for (var index = 0; index < method.Body.Instructions.Count; index++)
            {
                var instruction = method.Body.Instructions[index];
                //For debugging
                Console.WriteLine($"[{instruction.Offset}][{index}] {instruction.OpCode} \"{instruction.Operand}\"");
            }

            /*
             * Collect the method's variables.
             */
            Variables.Clear();
            foreach (var variable in method.Body.Variables)
            {
                yield return($"\t{CType.Deserialize(variable)} var{variable.Index} = 0;\n");

                Variables.Add(new ScopeVariable
                {
                    Type = CType.Deserialize(variable.VariableType.Name), Value = "0"
                });
            }

            /*
             * Build Scope Instructions from Instructors
             */
            var  instr = new List <ScopeInstruction>();
            uint i     = 0;

            foreach (var instruction in method.Body.Instructions)
            {
                var inst = new ScopeInstruction
                {
                    Name                                  = instruction.OpCode.Name,
                    Offset                                = (uint)instruction.Offset,
                    Operand                               = instruction.Operand != null?instruction.Operand.ToString() : "",
                                                 Index    = i,
                                                 Template = instruction
                };
                instr.Add(inst);
                i++;
            }

            //For label naming.
            FuncCount++;

            //Build scope.
            foreach (var str in BuildScope(new List <ScopeVariable>(), instr, body, 1, 0))
            {
                yield return(str);
            }
        }
Example #4
0
        /// <summary>
        /// Generate C constructor.
        /// </summary>
        /// <param name="function">Method</param>
        /// <param name="cls">Class</param>
        public CConstructor(MethodBase function, Type cls)
        {
            Declaration = "";
            Definition  = "";

            var pars = function.GetParameters().Select(parameter =>
                                                       $"{CType.Deserialize(parameter.ParameterType)} {parameter.Name}").ToList();

            if (function.DeclaringType == null)
            {
                return;
            }
            Definition +=
                $"struct {function.DeclaringType.Name}* new{function.DeclaringType.Name}{Visualizer.Additional(function, cls)} (";
            foreach (var par in pars)
            {
                Definition += $"{par}";
                if (pars[pars.Count - 1] != par)
                {
                    Definition += ", ";
                }
            }

            Definition += ")\n{\n\t" + $"{function.DeclaringType.Name}* me = " +
                          $"malloc(sizeof({function.DeclaringType.Name}));";

            if (function.DeclaringType != null)
            {
                foreach (var method in function.DeclaringType.GetMethods())
                {
                    if (method.IsConstructor || method.IsStatic)
                    {
                        continue;
                    }
                    Definition +=
                        $"\n\tme->{method.Name}{Visualizer.Additional(method, cls)} = &{function.DeclaringType.Name + method.Name}{Visualizer.Additional(method, cls)};";
                }

                Definition          += "\n";
                Visualizer.FirstPass = false;
                foreach (var line in Visualizer.BuildBody(function))
                {
                    Definition += line;
                }
            }

            Definition += "\n\treturn me;";
            Definition += "\n}\n\n";

            Declaration +=
                $"struct {function.DeclaringType.Name}* new{function.DeclaringType.Name}{Visualizer.Additional(function, cls)} (";
            foreach (var par in pars)
            {
                Declaration += $"{par}";
                if (pars[pars.Count - 1] != par)
                {
                    Declaration += ", ";
                }
            }

            Declaration += ");\n\n";
        }