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); } } }
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()); }
static void HandleReadArrayItem(LocalOperation operation, CodeOutput bodySb, MethodInterpreter interpreter, ClosureEntities closureEntities) { var valueSrc = (GetArrayElement)operation; var parentType = valueSrc.Instance.ComputedType(); var variableData = interpreter.AnalyzeProperties.GetVariableData(valueSrc.AssignedTo); switch (variableData) { case EscapingMode.Smart: bodySb.AppendFormat( (parentType.GetClrType(closureEntities).IsClass || parentType.GetClrType(closureEntities).IsInterface) ? "{0} = (*{1})[{2}];" : "{0} = {1}[{2}];", valueSrc.AssignedTo.Name, valueSrc.Instance.Name, valueSrc.Index.Name); return; case EscapingMode.Pointer: bodySb.AppendFormat( (parentType.GetClrType(closureEntities).IsClass || parentType.GetClrType(closureEntities).IsInterface) ? "{0} = ((*{1})[{2}]).get();" : "{0} = ({1}[{2}]).get();", valueSrc.AssignedTo.Name, valueSrc.Instance.Name, valueSrc.Index.Name); return; } }
static void WriteCppMethods(List <MethodInterpreter> closure, CodeOutput sb, ClosureEntities crRuntime) { var cppMethods = closure .Where(m => m.Kind == MethodKind.RuntimeCppMethod) .ToArray(); var methodInterpreter = cppMethods.FirstOrDefault(); if (methodInterpreter == null) { return; } foreach (var interpreter in cppMethods) { var cppInterpreter = (CppMethodInterpreter)interpreter; var runtimeLibrary = cppInterpreter.CppRepresentation; if (LinkingData.SetInclude(runtimeLibrary.Header)) { sb.AppendFormat("#include \"{0}\"\n", runtimeLibrary.Header); } CppWriteSignature.WriteSignature(sb, interpreter, crRuntime, false); sb.BracketOpen() .Append(runtimeLibrary.Source) .BracketClose(); } }
public static void HandleCallRuntime(LocalOperation operation, CodeOutput sb, ClosureEntities crRuntime) { var operationData = (CallMethodStatic)operation; var methodInfo = operationData.Info; if (methodInfo.IsConstructor) { return; //don't call constructor for now } var isVoidMethod = methodInfo.GetReturnType().IsVoid(); if (isVoidMethod) { sb.AppendFormat("{0}", methodInfo.ClangMethodSignature(crRuntime)); } else { sb.AppendFormat("{1} = {0}", methodInfo.ClangMethodSignature(crRuntime), operationData.Result.Name); } var identifierValues = operationData.Parameters; var argumentsCall = string.Join(", ", identifierValues.Select(p => p.Name)); sb.AppendFormat("({0});", argumentsCall); }
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(); }
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"); }
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 HandleSizeOf(LocalOperation operation, CodeOutput bodySb) { var assign = (SizeOfAssignment)operation; var leftData = (IdentifierValue)assign.AssignedTo; var rightData = assign.Right.ToCppName(); bodySb.AppendFormat("{0} = sizeof({1});", leftData.Name, rightData); }
static void HandleSub(BinaryOperator localVar, CodeOutput sb) { string right, left, local; GetBinaryOperandNames(localVar, out right, out left, out local); sb.AppendFormat("{0} = {1}-{2};", local, left, right); }
static void HandleNot(UnaryOperator localVar, CodeOutput sb) { var local = localVar.AssignedTo.Name; string left; GetUnaryOperandNames(localVar, out left); sb.AppendFormat("{0} = !{1};", local, left); }
static void HandleDerefAssignment(LocalOperation operation, CodeOutput bodySb) { var assign = (DerefAssignment)operation; var leftData = (IdentifierValue)assign.Left; var rightData = (IdentifierValue)assign.Right; bodySb.AppendFormat("{0} = *{1};", leftData.Name, rightData.Name); }
static void HandleLoadArrayRef(BinaryOperator binaryOperator, CodeOutput sb) { string right, left, local; GetBinaryOperandNames(binaryOperator, out right, out left, out local); sb.AppendFormat("{0}={1}[{2}];", local, right, left); }
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 HandleLoadFunction(LocalOperation operation, CodeOutput bodySb, ClosureEntities crRuntime) { var assign = (FunctionPointerStore)operation; var leftData = assign.AssignedTo; var info = assign.FunctionPointer; var methodName = info.ClangMethodSignature(crRuntime); bodySb.AppendFormat("{0}=&({1});", leftData.Name, methodName); }
static void HandleSetStaticField(LocalOperation operation, CodeOutput bodySb) { var assign = (Assignment)operation; var rightData = (StaticFieldSetter)assign.AssignedTo; bodySb.AppendFormat("{1}::{2} = {0};", assign.Right.Name, rightData.DeclaringType.ToCppMangling(), rightData.FieldName.ValidName()); }
static void HandleFieldRefAssignment(LocalOperation operation, CodeOutput bodySb) { var assign = (FieldRefAssignment)operation; var leftData = assign.Left; var rightData = assign.Right; var fieldName = assign.Field.Name; bodySb.AppendFormat("{0} = &({1}->{2});", leftData.Name, rightData.Name, fieldName); }
static void HandleCastClass(ClassCasting casting, CodeOutput bodySb, ClosureEntities closureEntities) { var typeDescription = casting.AssignedTo.ComputedType(); bodySb .AppendFormat("{0} = std::static_pointer_cast<{2}>({1});", casting.AssignedTo.Name, casting.Value.Name, typeDescription.GetClrType(closureEntities).ToDeclaredVariableType(EscapingMode.Stack)); }
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"); }); }
static void HandleLoadStaticField(LocalOperation operation, CodeOutput bodySb, ClosureEntities closureEntities) { var assign = (Assignment)operation; var rightData = (StaticFieldGetter)assign.Right; bodySb.AppendFormat("{0} = {1}::{2};", assign.AssignedTo.Name, rightData.DeclaringType.GetClrType(closureEntities).ToCppMangling(), rightData.FieldName.ValidName()); }
static void HandleUnbox(Unboxing unboxing, CodeOutput bodySb, ClosureEntities closureEntities) { var typeDescription = unboxing.AssignedTo.ComputedType(); bodySb .AppendFormat("{0} = unbox_value<{2}>({1});", unboxing.AssignedTo.Name, unboxing.Right.Name, typeDescription.GetClrType(closureEntities).ToDeclaredVariableType(EscapingMode.Stack)); }
public static void WriteSignature(CodeOutput codeOutput, MethodInterpreter interpreter, ClosureEntities closureEntities, bool writeEndColon = false) { if (interpreter == null) { return; } interpreter.WriteHeaderMethodWithEscaping(codeOutput, closureEntities, writeEndColon); }
public static void WriteMethodSignature(CodeOutput codeOutput, MethodInterpreter interpreter, ClosureEntities closureEntities) { if (interpreter.Method == null) { Console.WriteLine("Should not be null"); return; } CppWriteSignature.WriteSignature(codeOutput, interpreter, closureEntities, true); }
static void HandleBox(Boxing boxing, CodeOutput bodySb, TypeDescriptionTable typeTable, ClosureEntities closureEntities) { var typeDescription = boxing.Right.ComputedType(); bodySb .AppendFormat("{0} = box_value<{2}>({1}, {3});", boxing.AssignedTo.Name, boxing.Right.Name, typeDescription.GetClrType(closureEntities).ToDeclaredVariableType(EscapingMode.Stack), typeTable.GetTypeId(typeDescription.GetClrType(closureEntities))); }
public static void HandleBranchOperator(object operation, CodeOutput sb) { var localBranch = (LocalOperation)operation; var objList = (BranchOperator)localBranch; var operationName = objList.Name; var jumpAddress = objList.JumpTo; var localVar = objList.CompareValue; var secondVar = objList.SecondValue; switch (operationName) { case OpcodeBranchNames.BrTrue: HandleBrTrue(localVar, sb, jumpAddress); break; case OpcodeBranchNames.BrFalse: HandleBrFalse(localVar, sb, jumpAddress); break; case OpcodeBranchNames.Beq: CppHandleCompareBranches.HandleBeq(localVar, secondVar, sb, jumpAddress); break; case OpcodeBranchNames.Bge: CppHandleCompareBranches.HandleBge(localVar, secondVar, sb, jumpAddress); break; case OpcodeBranchNames.Bgt: CppHandleCompareBranches.HandleBgt(localVar, secondVar, sb, jumpAddress); break; case OpcodeBranchNames.Ble: case OpcodeBranchNames.BleUn: //Should we treat unsigned differently ? case OpcodeBranchNames.BleUnS: CppHandleCompareBranches.HandleBle(localVar, secondVar, sb, jumpAddress); break; case OpcodeBranchNames.Blt: case OpcodeBranchNames.BltUn: case OpcodeBranchNames.BltUnS: CppHandleCompareBranches.HandleBlt(localVar, secondVar, sb, jumpAddress); break; case OpcodeBranchNames.Bne: case OpcodeBranchNames.BneUn: CppHandleCompareBranches.HandleBne(localVar, secondVar, sb, jumpAddress); break; default: throw new InvalidOperationException($"Operation '{operationName}' is not handled"); } }
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()); }
static void GenerateForwardTypes(Type[] typeDatas, CodeOutput sb, ClosureEntities crRuntime) { foreach (var typeData in typeDatas) { var mappedType = typeData.GetMappedType(crRuntime); if (ShouldSkipType(typeData)) continue; if (!mappedType.IsGenericType) { sb.AppendFormat("struct {0};\n", mappedType.ToCppMangling()); } } }
static void HandleCopyArrayInitializer(LocalOperation operation, CodeOutput sb) { var assignment = (Assignment)operation; var left = assignment.AssignedTo; var right = (ConstByteArrayValue)assignment.Right; var rightArrayData = (ConstByteArrayData)right.Value; var rightArray = rightArrayData.Data; sb.AppendFormat("{0} = std::make_shared<Array<System::Byte> >(" + "{1}, RuntimeHelpers_GetBytes({2}) ); ", left.Name, rightArray.Length, right.Id); }
static void HandleAdd(BinaryOperator localVar, CodeOutput sb, ClosureEntities closureEntities) { string right, left, local; GetBinaryOperandNames(localVar, out right, out left, out local); if (localVar.Right.ComputedType().GetClrType(closureEntities) == typeof(IntPtr)) { sb.AppendFormat("{0} = {1}+(size_t){2};", local, left, right); return; } sb.AppendFormat("{0} = {1}+{2};", local, left, right); }
public static void HandleUnaryOperator(UnaryOperator operation, CodeOutput sb) { var localVar = operation; var unaryOperator = localVar; var operationName = localVar.Name; switch (operationName) { case OpcodeOperatorNames.Not: HandleNot(localVar, sb); break; case OpcodeOperatorNames.Neg: HandleNeg(localVar, sb); break; case OpcodeOperatorNames.LoadLen: HandleLoadLen(unaryOperator, sb); break; case OpcodeOperatorNames.ConvI: HandleConvI(unaryOperator, sb); break; case OpcodeOperatorNames.ConvU1: HandleConvU1(unaryOperator, sb); break; case OpcodeOperatorNames.ConvI4: HandleConvI4(unaryOperator, sb); break; case OpcodeOperatorNames.ConvI8: HandleConvI8(unaryOperator, sb); break; case OpcodeOperatorNames.ConvR4: HandleConvR4(unaryOperator, sb); break; case OpcodeOperatorNames.ConvR8: HandleConvR8(unaryOperator, sb); break; default: throw new InvalidOperationException($"Operation '{operationName}' is not handled"); } }