private static void InternalConvertFromAbstractFunction( TextWriter tw, IExtractContext extractContext, PreparedFunction preparedFunction, string indent) { var functionPrototype = Utilities.GetFunctionPrototypeString( GetFunctionNameByFunctionType(preparedFunction), preparedFunction.ReturnType, preparedFunction.Parameters, extractContext); tw.WriteLine(); tw.WriteLine("///////////////////////////////////////"); tw.WriteLine("// Abstract: {0}", preparedFunction.RawMethodName); tw.WriteLine(); tw.WriteLine(functionPrototype); tw.WriteLine("{"); tw.WriteLine( "{0}// WARNING: Pure virtual function called.", indent); tw.WriteLine( "{0}//TODO: throw : assert(0);", indent); if (preparedFunction.ReturnType.IsVoidType() == false) { tw.WriteLine( "{0}return ({1}){2};", indent, extractContext.GetCLanguageTypeName(preparedFunction.ReturnType), preparedFunction.ReturnType.IsNumericPrimitive() ? "0" : "NULL"); } tw.WriteLine("}"); }
private static void InternalConvertFromPInvokeFunction( TextWriter tw, IExtractContext extractContext, PreparedFunction preparedFunction, PInvokeInfo pinvokeInfo, string indent) { var functionPrototype = Utilities.GetFunctionPrototypeString( GetFunctionNameByFunctionType(preparedFunction), preparedFunction.ReturnType, preparedFunction.Parameters, extractContext); tw.WriteLine(); tw.WriteLine("///////////////////////////////////////"); tw.WriteLine("// P/Invoke: {0}", preparedFunction.RawMethodName); tw.WriteLine(); tw.WriteLine(functionPrototype); tw.WriteLine("{"); var arguments = string.Join( ", ", preparedFunction.Parameters .Select(parameter => parameter.GetMarshaledInExpression())); if (preparedFunction.ReturnType.IsVoidType()) { tw.WriteLine("{0}{1}({2});", indent, pinvokeInfo.EntryPoint, arguments); } else { tw.WriteLine("{0}return {1}({2});", indent, pinvokeInfo.EntryPoint, arguments); } tw.WriteLine("}"); }
private static void InternalConvertFromFunction( TextWriter tw, IExtractContext extractContext, PreparedFunction preparedFunction, string indent, DebugInformationOptions debugInformationOption) { var locals = preparedFunction.LocalVariables; var functionPrototype = Utilities.GetFunctionPrototypeString( GetFunctionNameByFunctionType(preparedFunction), preparedFunction.ReturnType, preparedFunction.Parameters, extractContext); tw.WriteLine(); tw.WriteLine("///////////////////////////////////////"); tw.WriteLine( "// {0}{1}", (preparedFunction.FunctionType == FunctionTypes.Virtual) ? "Virtual: " : string.Empty, preparedFunction.RawMethodName); tw.WriteLine(); tw.WriteLine(functionPrototype); tw.WriteLine("{"); tw.WriteLine("{0}//-------------------", indent); tw.WriteLine("{0}// Local variables:", indent); tw.WriteLine(); // Important NULL assigner (p = NULL): // Because these variables are pointer (of object reference). // So GC will traverse these variables just setup the stack frame. foreach (var local in preparedFunction.LocalVariables) { tw.WriteLine( "{0}{1} {2}{3};", indent, extractContext.GetCLanguageTypeName(local.TargetType), local.SymbolName, local.TargetType.IsValueType ? string.Empty : " = NULL"); } tw.WriteLine(); tw.WriteLine("{0}//-------------------", indent); tw.WriteLine("{0}// Evaluation stacks:", indent); tw.WriteLine(); foreach (var si in preparedFunction.Stacks) { tw.WriteLine( "{0}{1} {2}{3};", indent, extractContext.GetCLanguageTypeName(si.TargetType), si.SymbolName, si.TargetType.IsValueType ? string.Empty : " = NULL"); } var frameEntries = locals .Concat(preparedFunction.Stacks) .Where(local => !local.TargetType.IsValueType && !local.TargetType.IsPointer) .ToArray(); if (frameEntries.Length >= 1) { tw.WriteLine(); tw.WriteLine("{0}//-------------------", indent); tw.WriteLine("{0}// Setup stack frame:", indent); tw.WriteLine(); tw.WriteLine("{0}struct /* IL2C_EXECUTION_FRAME */", indent); tw.WriteLine("{0}{{", indent); tw.WriteLine("{0}{0}IL2C_EXECUTION_FRAME* pNext;", indent); tw.WriteLine("{0}{0}uint8_t targetCount;", indent); foreach (var frameEntry in frameEntries) { tw.WriteLine( "{0}{0}{1}* p{2};", indent, extractContext.GetCLanguageTypeName(frameEntry.TargetType), frameEntry.SymbolName); } tw.WriteLine("{0}}} __executionFrame__;", indent); tw.WriteLine(); tw.WriteLine("{0}__executionFrame__.targetCount = {1};", indent, frameEntries.Length); foreach (var frameEntry in frameEntries) { tw.WriteLine( "{0}__executionFrame__.p{1} = &{1};", indent, frameEntry.SymbolName); } tw.WriteLine("{0}il2c_link_execution_frame(&__executionFrame__);", indent); } tw.WriteLine(); tw.WriteLine("{0}//-------------------", indent); tw.WriteLine("{0}// IL body:", indent); tw.WriteLine(); var canWriteSequencePoint = true; foreach (var ilBody in preparedFunction.PreparedILBodies) { // Write label if available and used. if (preparedFunction.TryGetLabelName( ilBody.Label, out var labelName)) { tw.WriteLine("{0}:", labelName); } // Write the line preprocessor directive if available. if (canWriteSequencePoint && ilBody.SequencePoints.Any()) { var sp = ilBody.SequencePoints.First(); switch (debugInformationOption) { case DebugInformationOptions.Full: tw.WriteLine( "#line {0} \"{1}\"", sp.StartLine, sp.Document.Url.Replace("\\", "\\\\")); break; case DebugInformationOptions.CommentOnly: tw.WriteLine( "/* {0}({1}): */", sp.Document.Url.Replace("\\", "\\\\"), sp.StartLine); break; } canWriteSequencePoint = false; } if (debugInformationOption != DebugInformationOptions.None) { // Write debugging information. tw.WriteLine( "{0}/* {1} */", indent, ilBody); } // Generate source code fragments and write. var sourceCodes = ilBody.Generator(extractContext); foreach (var sourceCode in sourceCodes) { // Dirty hack: // Write unlink execution frame code if cause exiting method. if (sourceCode.StartsWith("return") && (frameEntries.Length >= 1)) { tw.WriteLine( "{0}il2c_unlink_execution_frame(&__executionFrame__);", indent); } tw.WriteLine( "{0}{1};", indent, sourceCode); canWriteSequencePoint = true; } } tw.WriteLine("}"); }
private static string GetFunctionNameByFunctionType(PreparedFunction preparedFunction) { return((preparedFunction.FunctionType == FunctionTypes.Virtual) ? ("__" + preparedFunction.MethodName + "__") : preparedFunction.MethodName); }