Beispiel #1
0
        public void WriteCodeToOutput(CodeOutput bodySb, MethodInterpreter interpreter)
        {
            bodySb.Append("\n");

            if (Returning == null)
            {
                bodySb.Append("return;");
            }
            else
            {
                //Need to expand this for more cases
                if (Returning is ConstValue)
                {
                    var retType = interpreter.Method.GetReturnType();
                    if (retType == typeof(string))
                    {
                        bodySb.AppendFormat("return {0};", Returning.ComputedValue());
                    }
                    else
                    {
                        bodySb.AppendFormat("return {0};", Returning.Name);
                    }
                }
                else
                {
                    bodySb.AppendFormat("return {0};", Returning.Name);
                }
            }
        }
Beispiel #2
0
        public static string WritePlatformInvokeMethod(this PlatformInvokeMethod platformInvoke,
                                                       ClosureEntities crRuntime)
        {
            var methodId = Import(platformInvoke.LibraryName,
                                  platformInvoke.MethodName,
                                  platformInvoke.CallingConvention,
                                  platformInvoke.EntryPoint);

            var codeOutput = new CodeOutput();

            codeOutput.AppendFormat(platformInvoke.WritePInvokeDefinition(methodId));
            codeOutput.BlankLine();
            codeOutput.Append(platformInvoke.Method.WriteHeaderMethod(crRuntime, false));

            // write PInvoke implementation
            codeOutput.BracketOpen();

            var argumentsCall = platformInvoke.Method.GetParameters()
                                .Select(CallMarshallerFactory.CreateMarshaller)
                                .Each(marshaller => { codeOutput.Append(marshaller.GetTransformationCode()); })
                                .Once(marshallers => { codeOutput.BlankLine(); })
                                .Select(p => p.GetParameterString())
                                .Join(", ");

            if (!platformInvoke.Method.GetReturnType().IsVoid())
            {
                codeOutput.Append("return ");
            }
            codeOutput.AppendFormat("{0}({1});", methodId, argumentsCall);
            codeOutput.BracketClose();

            return(codeOutput.ToString());
        }
        static void WriteClosureBodies(List <MethodInterpreter> closure, CodeOutput sb,
                                       TypeDescriptionTable typeTable, ClosureEntities closureEntities)
        {
            sb.Append("///--- PInvoke code ---\n");
            foreach (var interpreter in closure)
            {
                if (interpreter.Kind != MethodKind.PlatformInvoke)
                {
                    continue;
                }
                sb.Append(MethodInterpreterCodeWriter.WritePInvokeMethodCode((PlatformInvokeMethod)interpreter,
                                                                             closureEntities));
            }

            sb.Append("///---Begin closure code ---\n");
            foreach (var interpreter in closure)
            {
                if (interpreter.Kind != MethodKind.CilInstructions)
                {
                    continue;
                }

                if (interpreter.Method.IsAbstract)
                {
                    continue;
                }
                sb.Append(MethodInterpreterCodeWriter.WriteMethodCode((CilMethodInterpreter)interpreter, typeTable,
                                                                      closureEntities));
            }
            sb.Append("///---End closure code ---\n");
        }
        static void WriteStructWithFields(CodeOutput codeOutput, ClosureEntities crRuntime, Type type)
        {
            if (DelegateManager.IsTypeDelegate(type))
                return;

            var mappedType = type.GetMappedType(crRuntime);
            type = mappedType.GetReversedMappedType(crRuntime);

            if (!type.IsValueType && type.BaseType != null)
            {
                //Not Necessary
                // codeOutput.AppendFormat("struct {0} : public {1} {2} {{", type.ToCppMangling(), type.BaseType.ToCppMangling(),type.GetInterfaces().Any()? " ,"+type.GetInterfaces().Select(j=>j.ToCppMangling()).Aggregate((a,b)=>a + " , " + b):"");
                codeOutput.AppendFormat(
                    "struct {0} : public {1}",
                    type.ToCppMangling(),
                    type.BaseType.ToCppMangling())
                    .BracketOpen();
            }
            else if (!type.IsValueType && type.IsInterface)
            {
                codeOutput.AppendFormat("struct {0} : public {1}",
                    type.ToCppMangling(),
                    typeof(object).ToCppMangling())
                    .BracketOpen();
            }
            else
            {
                codeOutput.AppendFormat("struct {0}", type.ToCppMangling())
                    .BracketOpen();
            }

            if (type == typeof(object))
            {
                codeOutput.Append("int _typeId;\n");
            }

            //String Support
            if (type == typeof(string))
            {
                crRuntime.AddType(typeof(string));
                var usedTypes = crRuntime.MappedTypes.Values.ToList();
                var typeTable = new TypeDescriptionTable(usedTypes, crRuntime);

                codeOutput.Append("System_String()")
                    .BracketOpen()
                    .AppendFormat("_typeId = {0};\n", typeTable.GetTypeId(typeof(string)))
                    .BracketClose()
                    .BlankLine();
            }

            WriteClassFieldsBody(codeOutput, mappedType, crRuntime);
            codeOutput.BracketClose(true)
                .Append(";\n")
                .BlankLine();

            var typedesc = UsedTypeList.Set(type, crRuntime);
            typedesc.WriteStaticFieldInitialization(codeOutput);
        }
        static void WriteClosureDelegateBodies(List <MethodInterpreter> closure, CodeOutput codeOutput)
        {
            foreach (var interpreter in closure)
            {
                if (interpreter.Kind != MethodKind.Delegate)
                {
                    continue;
                }
                codeOutput.Append(MethodInterpreterCodeWriter.WriteDelegateCallCode(interpreter));
            }

            codeOutput.Append(DelegateManager.Instance.BuildDelegateContent());
        }
Beispiel #6
0
        public static string LoadDllMethods()
        {
            var sb = new CodeOutput();

            sb.BlankLine()
            .Append("System_Void mapLibs()")
            .BracketOpen();

            var pos = 0;

            foreach (var library in LinkingData.Libraries)
            {
                sb.Append("//---------------------------------------------------------\n")
                .AppendFormat("// {0} methods\n", library.DllName)
                .Append("//---------------------------------------------------------\n")
                .AppendFormat("auto lib_{0} = LoadNativeLibrary(L\"{1}\");\n", pos, library.DllName)
                .BlankLine();
                foreach (var method in library.Methods.Values)
                {
                    sb.AppendFormat("{0} = ({0}_type)LoadNativeMethod(lib_{2}, \"{1}\");\n", method.FormattedName(),
                                    method.EntryPoint, pos);
                }
                pos++;
            }

            return(sb.BracketClose()
                   .BlankLine()
                   .ToString());
        }
Beispiel #7
0
        public static void WriteHeaderMethodWithEscaping(this MethodInterpreter interpreter,
                                                         CodeOutput codeOutput,
                                                         ClosureEntities closureEntities,
                                                         bool writeEndColon = true)
        {
            var methodBase = interpreter.Method;

            codeOutput.Append(methodBase.GetReturnType().ToCppName())
            .Append(" ")
            .Append(interpreter.ClangMethodSignature(closureEntities));

            var arguments = interpreter.GetArgumentsAsTextWithEscaping(closureEntities);

            codeOutput.AppendFormat("({0})", arguments);
            if (writeEndColon)
            {
                codeOutput.Append(";");
            }
        }
 static void WriteClosureHeaders(IEnumerable <MethodInterpreter> closure, CodeOutput codeOutput,
                                 ClosureEntities closureEntities)
 {
     closure.Where(interpreter => !interpreter.Method.IsAbstract)
     .Each(interpreter =>
     {
         MethodInterpreterCodeWriter.WriteMethodSignature(codeOutput, interpreter, closureEntities);
         codeOutput.Append("\n");
     });
 }
        public static bool HandleCastRelatedOperations(TypeDescriptionTable typeTable, ClosureEntities crRuntime,
                                                       LocalOperation operation, CodeOutput bodySb, OperationKind opKind)
        {
            switch (opKind)
            {
            case OperationKind.Box:
                if (!Boxing.IsUsed)
                {
                    Boxing.IsUsed = true;
                    bodySb.Append(BoxingTemplate);
                }
                HandleBox((Boxing)operation, bodySb, typeTable, crRuntime);
                break;

            case OperationKind.CastClass:
                HandleCastClass((ClassCasting)operation, bodySb, crRuntime);
                break;

            case OperationKind.Unbox:
                HandleUnbox((Unboxing)operation, bodySb, crRuntime);
                break;

            case OperationKind.IsInstance:
            {
                var declarations = new List <string>
                {
                    "bool IsInstanceOf(int typeSource, int typeImplementation);",
                    "System_Void buildTypesTable();",
                    "std::map<int, std::vector<int> > GlobalMappingType;"
                };

                bodySb.Append(Join(Environment.NewLine, declarations));

                HandleIsInstance((IsInstance)operation, bodySb, crRuntime);
            }
            break;

            default:
                return(false);
            }
            return(true);
        }
        static void WriteMainBody(MethodInterpreter interpreter, CodeOutput sb, ClosureEntities crRuntime)
        {
            sb.Append("System_Void initializeRuntime();\n");
            sb.Append("int main(int argc, char**argv)").BracketOpen();
            sb.Append("auto argsAsList = System_getArgumentsAsList(argc, argv);\n");
            sb.Append("initializeRuntime();\n");


            var entryPoint = interpreter.Method as MethodInfo;

            if (entryPoint.ReturnType != typeof(void))
            {
                sb.Append("return ");
            }
            var parameterInfos = entryPoint.GetParameters();
            var args           = string.Empty;

            if (parameterInfos.Length != 0)
            {
                args = "argsAsList";
            }
            sb.AppendFormat("{0}({1});\n", entryPoint.ClangMethodSignature(crRuntime), args);
            sb.BlankLine();
            sb.Append("return 0;");
            sb.BracketClose();
        }
        public void WriteLayout(CodeOutput codeOutput)
        {
            BaseType?.WriteLayout(codeOutput);

            var noOffsetFields = new List <FieldDescription>();
            var dictionary     = new SortedDictionary <int, List <FieldDescription> >();

            BuildUnionLayouts(noOffsetFields, dictionary);
            foreach (var fieldList in dictionary.Values)
            {
                codeOutput.Append("union")
                .BracketOpen();
                WriteFieldListToLayout(codeOutput, fieldList);
                codeOutput.BracketClose();
            }
            WriteFieldListToLayout(codeOutput, noOffsetFields);
        }
        public static void HandleCallInterface(LocalOperation operation, CodeOutput sbCode,
                                               MidRepresentationVariables vars, MethodInterpreter interpreter, ClosureEntities crRuntime)
        {
            var operationData = (CallMethodStatic)operation;
            var sb            = new StringBuilder();
            var methodInfo    = operationData.Info.GetReversedMethod(crRuntime);
            var isVoidMethod  = methodInfo.GetReturnType().IsVoid();

            if (!isVoidMethod && operationData.Result != null)
            {
                sb.AppendFormat("{0} = ", operationData.Result.Name);
            }

            sb.AppendFormat("{0}_icall", methodInfo.ClangMethodSignature(crRuntime));
            WriteParametersToSb(operationData, sb, interpreter);

            sbCode.Append(sb.ToString());
        }
Beispiel #13
0
        public static string WriteCode(CilMethodInterpreter interpreter, TypeDescriptionTable typeTable,
                                       ClosureEntities crRuntime)
        {
            var operations = interpreter.MidRepresentation.LocalOperations;
            var headerSb   = new CodeOutput();

            CppWriteSignature.WriteSignature(headerSb, interpreter, crRuntime);

            var bodySb      = ComputeBodySb(operations, interpreter.MidRepresentation.Vars, typeTable, interpreter, crRuntime);
            var variablesSb = ComputeVariableSb(interpreter.MidRepresentation, interpreter, crRuntime);
            var finalSb     = new CodeOutput();

            finalSb.Append(headerSb.ToString())
            .BracketOpen()
            .Append(variablesSb.ToString())
            .Append(bodySb.ToString())
            .BracketClose();

            return(finalSb.ToString());
        }
Beispiel #14
0
        public string BuildStringTable()
        {
            var sb = new CodeOutput();

            sb.BlankLine()
            .Append("System_Void buildStringTable()")
            .BracketOpen();

            var stringDataBuilder = new List <string>();

            var jump = 0;

            foreach (var strItem in _table)
            {
                sb.AppendFormat("_AddJumpAndLength({0}, {1});\n", jump, strItem.Length);
                var itemTextData = TextData(strItem);
                AddTextToStringTable(stringDataBuilder, itemTextData, strItem);

                jump += strItem.Length + 1;
            }


            sb.BracketClose(true)
            .Append(" // buildStringTable\n");

            var stringTableContent = string.Join(", " + Environment.NewLine, stringDataBuilder);
            var length             = jump == 0 ? 1 : jump;

            sb.BlankLine()
            .AppendFormat("const System_Char _stringTable[{0}] =", length)
            .BracketOpen();
            sb.Append(jump == 0 ? "0" : stringTableContent);
            sb.BracketClose(true)
            .Append("; // _stringTable\n");

            return(sb.ToString());
        }
Beispiel #15
0
        static CodeOutput ComputeBodySb(List <LocalOperation> operations, MidRepresentationVariables vars,
                                        TypeDescriptionTable typeTable, MethodInterpreter interpreter, ClosureEntities crRuntime)
        {
            var bodySb = new CodeOutput();

            foreach (var operation in operations)
            {
                bodySb.Append("\n");
                if (CppHandleOperators.HandleAssignmentOperations(bodySb, operation, operation.Kind, typeTable,
                                                                  interpreter, crRuntime))
                {
                    continue;
                }
                if (CppCastRelatedOperations.HandleCastRelatedOperations(typeTable, crRuntime, operation, bodySb,
                                                                         operation.Kind))
                {
                    continue;
                }
                if (HandleCallOperations(vars, interpreter, crRuntime, operation, bodySb))
                {
                    continue;
                }

                switch (operation.Kind)
                {
                case OperationKind.Label:
                    WriteLabel(bodySb, ((Label)operation).JumpTo);
                    break;

                case OperationKind.AlwaysBranch:
                    HandleAlwaysBranchOperator(operation, bodySb);
                    break;

                case OperationKind.BranchOperator:
                    CppHandleBranches.HandleBranchOperator(operation, bodySb);
                    break;

                case OperationKind.Return:
                    CppHandleCalls.HandleReturn(operation, bodySb, interpreter);
                    break;

                case OperationKind.CopyArrayInitializer:
                    HandleCopyArrayInitializer(operation, bodySb);
                    break;

                case OperationKind.Switch:
                    HandleSwitch(operation, bodySb);
                    break;

                case OperationKind.Comment:
                    HandleComment(operation.ToString(), bodySb);
                    break;


                default:
                    throw new InvalidOperationException(
                              $"Invalid operation '{operation.Kind}' is introduced in intermediary representation\nValue: {operation}");
                }
            }

            return(bodySb);
        }
        public static void HandleCallVirtual(LocalOperation operation, CodeOutput sbCode, MethodInterpreter interpreter,
                                             ClosureEntities crRuntime)
        {
            var operationData = (CallMethodStatic)operation;
            var sb            = new StringBuilder();
            var methodInfo    = operationData.Info.GetReversedMethod(crRuntime);
            var isVoidMethod  = methodInfo.GetReturnType().IsVoid();

            if (!isVoidMethod && operationData.Result != null)
            {
                sb.AppendFormat("{0} = ", operationData.Result.Name);
            }

            var mappedType = methodInfo.DeclaringType.GetReversedMappedType(crRuntime);

            while ((mappedType.BaseType != typeof(object)))  // Match top level virtual dispatch
            {
                if (mappedType.BaseType == null)
                {
                    break;
                }
                mappedType = mappedType.BaseType;
            }


            sb.AppendFormat("{0}_vcall", methodInfo.ClangMethodSignature(crRuntime, mappedType));


            //TODO: the intermediate representation should remove the testinf of final methods and such
            //the virtual call is always a virtual call
            //Added DevirtualizeFinalMethods

            //Virtual Method Dispatch Table is on base class only
            //Also we need to take care of the call if this is not a virtual call
            // C# compiler seems to use virtual calls when derived class uses new operator on non-virtual base class method
            //Added special case for interface calls

            /*
             * if (methodInfo.IsVirtual)
             * {
             *  var @params = operationData.Parameters.Select(h => h.FixedType.ClrType).Skip(1).ToArray(); // Skip first parameter for virtual dispatch
             *
             *  if ((methodInfo.DeclaringType.GetMethod(methodInfo.Name, @params) != null && methodInfo.DeclaringType.GetMethod(methodInfo.Name, @params).DeclaringType == methodInfo.DeclaringType))
             *  {
             *
             *      sb.AppendFormat("{0}_vcall", methodInfo.ClangMethodSignature(crRuntime, isvirtualmethod: true));
             *
             *  }
             *  else
             *  {
             *      sb.AppendFormat("{0}", methodInfo.DeclaringType.BaseType.GetMethod(methodInfo.Name, operationData.Parameters.Select(h => h.FixedType.ClrType).ToArray()).ClangMethodSignature(crRuntime, isvirtualmethod: false));
             *  }
             * }
             * else
             * {
             *  sb.AppendFormat("{0}", methodInfo.ClangMethodSignature(crRuntime, isvirtualmethod: false));
             * }
             */
            WriteParametersToSb(operationData, sb, interpreter);

            sbCode.Append(sb.ToString());
        }