Example #1
0
        public static void Translate(
            TextWriter logw,
            CodeTextStorage storage,
            bool readSymbols,
            bool enableBundler,
            TargetPlatforms targetPlatform,
            DebugInformationOptions debugInformationOptions,
            string assemblyPath)
        {
            logw.Write("IL2C: Preparing assembly: \"{0}\" ...", Path.GetFullPath(assemblyPath));

            var translateContext  = new TranslateContext(assemblyPath, readSymbols, targetPlatform);
            var preparedFunctions = AssemblyPreparer.Prepare(translateContext);

            logw.WriteLine(" done.");

            using (var _ = storage.EnterScope("include"))
            {
                AssemblyWriter.WriteHeader(
                    storage,
                    translateContext,
                    preparedFunctions);
            }

            using (var _ = storage.EnterScope("src"))
            {
                AssemblyWriter.WriteSourceCode(
                    storage,
                    translateContext,
                    preparedFunctions,
                    enableBundler,
                    debugInformationOptions);
            }
        }
Example #2
0
        public static void CallStaticMethodTest()
        {
            var mainMethod = testType.GetMethod("CallTestMethod");

            var translateContext = new TranslateContext(testTypeAssembly.Location);
            var tw = new StringWriter();

            var prepared = AssemblyPreparer.Prepare(
                translateContext, method => method.MemberEquals(mainMethod));

            AssemblyWriter.InternalConvertFromMethod(tw, translateContext, prepared, mainMethod, "  ");

            var sourceCode = tw.ToString();

            var expected = new StringWriter();

            expected.WriteLine(@"int32_t IL2C_TestTargetClass_CallTestMethod(void)");
            expected.WriteLine(@"{");
            expected.WriteLine(@"  int32_t local0;");
            expected.WriteLine(@"");
            expected.WriteLine(@"  int32_t __stack0_int32_t;");
            expected.WriteLine(@"  int32_t __stack1_int32_t;");
            expected.WriteLine(@"");
            expected.WriteLine(@"  __stack0_int32_t = 1;");
            expected.WriteLine(@"  __stack1_int32_t = 2;");
            expected.WriteLine(@"  __stack0_int32_t = IL2C_TestTargetClass_CallStaticMethodTestType_Test(__stack0_int32_t, (int16_t)__stack1_int32_t);");
            expected.WriteLine(@"  local0 = __stack0_int32_t;");
            expected.WriteLine(@"  goto L_0000;");
            expected.WriteLine(@"L_0000:");
            expected.WriteLine(@"  __stack0_int32_t = local0;");
            expected.WriteLine(@"  return __stack0_int32_t;");
            expected.WriteLine(@"}");

            Assert.AreEqual(expected.ToString(), sourceCode);
        }
Example #3
0
        public static void ConditionalBranchTest()
        {
            var mainMethod = testType.GetMethod("ConditionalBranchMainBody");

            var translateContext = new TranslateContext(testTypeAssembly.Location);
            var tw = new StringWriter();

            var prepared = AssemblyPreparer.Prepare(
                translateContext, method => method.MemberEquals(mainMethod));

            AssemblyWriter.InternalConvertFromMethod(tw, translateContext, prepared, mainMethod, "  ");

            var sourceCode = tw.ToString();

            var expected = new StringWriter();

            expected.WriteLine(@"int32_t IL2C_TestTargetClass_ConditionalBranchMainBody(int32_t a)");
            expected.WriteLine(@"{");
            expected.WriteLine(@"  bool local0;");
            expected.WriteLine(@"  int32_t local1;");
            expected.WriteLine();
            expected.WriteLine(@"  int32_t __stack0_int32_t;");
            expected.WriteLine(@"  int32_t __stack1_int32_t;");
            expected.WriteLine();
            expected.WriteLine(@"  __stack0_int32_t = a;");
            expected.WriteLine(@"  __stack1_int32_t = 0;");
            expected.WriteLine(@"  __stack0_int32_t = (__stack0_int32_t > __stack1_int32_t) ? 1 : 0;");
            expected.WriteLine(@"  local0 = __stack0_int32_t ? true : false;");
            expected.WriteLine(@"  __stack0_int32_t = local0 ? 1 : 0;");
            expected.WriteLine(@"  if (__stack0_int32_t == 0) goto L_0000;");
            expected.WriteLine(@"  __stack0_int32_t = a;");
            expected.WriteLine(@"  __stack1_int32_t = 1;");
            expected.WriteLine(@"  __stack0_int32_t = __stack0_int32_t + __stack1_int32_t;");
            expected.WriteLine(@"  local1 = __stack0_int32_t;");
            expected.WriteLine(@"  goto L_0001;");
            expected.WriteLine(@"L_0000:");
            expected.WriteLine(@"  __stack0_int32_t = a;");
            expected.WriteLine(@"  __stack1_int32_t = 2;");
            expected.WriteLine(@"  __stack0_int32_t = __stack0_int32_t + __stack1_int32_t;");
            expected.WriteLine(@"  local1 = __stack0_int32_t;");
            expected.WriteLine(@"  goto L_0001;");
            expected.WriteLine(@"L_0001:");
            expected.WriteLine(@"  __stack0_int32_t = local1;");
            expected.WriteLine(@"  return __stack0_int32_t;");
            expected.WriteLine(@"}");

            Assert.AreEqual(expected.ToString(), sourceCode);
        }
Example #4
0
        public static void SimpleOverallByInt64SummationTest()
        {
            var mainMethod = testType.GetMethod("Int64MainBody");

            var translateContext = new TranslateContext(testTypeAssembly.Location);
            var tw = new StringWriter();

            var prepared = AssemblyPreparer.Prepare(
                translateContext, method => method.MemberEquals(mainMethod));

            AssemblyWriter.InternalConvertFromMethod(tw, translateContext, prepared, mainMethod, "  ");

            var sourceCode = tw.ToString();

            var expected = new StringWriter();

            expected.WriteLine(@"int64_t IL2C_TestTargetClass_Int64MainBody(void)");
            expected.WriteLine(@"{");
            expected.WriteLine(@"  int64_t local0;");
            expected.WriteLine(@"  int64_t local1;");
            expected.WriteLine(@"  int64_t local2;");
            expected.WriteLine(@"  int64_t local3;");
            expected.WriteLine();
            expected.WriteLine(@"  int32_t __stack0_int32_t;");
            expected.WriteLine(@"  int64_t __stack0_int64_t;");
            expected.WriteLine(@"  int64_t __stack1_int64_t;");
            expected.WriteLine();
            expected.WriteLine(@"  __stack0_int32_t = 1;");
            expected.WriteLine(@"  __stack0_int64_t = __stack0_int32_t;");
            expected.WriteLine(@"  local0 = __stack0_int64_t;");
            expected.WriteLine(@"  __stack0_int32_t = 2;");
            expected.WriteLine(@"  __stack0_int64_t = __stack0_int32_t;");
            expected.WriteLine(@"  local1 = __stack0_int64_t;");
            expected.WriteLine(@"  __stack0_int64_t = local0;");
            expected.WriteLine(@"  __stack1_int64_t = local1;");
            expected.WriteLine(@"  __stack0_int64_t = __stack0_int64_t + __stack1_int64_t;");
            expected.WriteLine(@"  local2 = __stack0_int64_t;");
            expected.WriteLine(@"  __stack0_int64_t = local2;");
            expected.WriteLine(@"  local3 = __stack0_int64_t;");
            expected.WriteLine(@"  goto L_0000;");
            expected.WriteLine(@"L_0000:");
            expected.WriteLine(@"  __stack0_int64_t = local3;");
            expected.WriteLine(@"  return __stack0_int64_t;");
            expected.WriteLine(@"}");

            Assert.AreEqual(expected.ToString(), sourceCode);
        }
Example #5
0
        public static void AccessValueTypeFieldTest()
        {
            Assert.Fail("TODO:");

            var mainMethod = testType.GetMethod("AccessValueTypeFieldMethod");

            var translateContext = new TranslateContext(testTypeAssembly.Location);
            var tw = new StringWriter();

            var targetType = typeof(TestTargetClass.AccessValueTypeFieldTestType);

            var prepared = AssemblyPreparer.Prepare(
                translateContext, method => method.MemberEquals(mainMethod));

            AssemblyWriter.InternalConvertFromMethod(tw, translateContext, prepared, mainMethod, "  ");

            var sourceCode = tw.ToString();

            var expected = new StringWriter();

            expected.WriteLine(@"");

            Assert.AreEqual(expected.ToString(), sourceCode);
        }
Example #6
0
        public static async Task ExecuteTestAsync(TestCaseInformation caseInfo)
        {
            Assert.IsTrue(caseInfo.Method.IsPublic && caseInfo.Method.IsStatic);

            // Split current thread context.
            await Task.Yield();

            ///////////////////////////////////////////////

            // Step 1-1: Create translation context.
            var translateContext = new TranslateContext(caseInfo.Method.DeclaringType.Assembly.Location, false);

            // Step 1-2: Prepare target methods.
            var targetTypes = new HashSet <string>(
                new[] { caseInfo.Method }.
                Concat(caseInfo.AdditionalMethods).
                Select(method => method.DeclaringType).
                Concat(caseInfo.AdditionalTypes).
                Select(type => type.FullName).
                Distinct());
            var targetMethods = new[] { caseInfo.Method }.
                Concat(caseInfo.AdditionalMethods).
            GroupBy(method => method.Name).
            ToDictionary(g => g.Key, g => g.ToArray());

            var prepared = AssemblyPreparer.Prepare(
                translateContext,
                t => targetTypes.Contains(t.FriendlyName),
                m => targetMethods.ContainsKey(m.Name));

            // Step 1-3: Extract prepared target type/caseInfo.Method informations.
            var targetType =
                translateContext.Assembly.Modules
                .First().Types
                .First(t => t.FriendlyName == caseInfo.Method.DeclaringType.FullName);
            var targetMethod =
                targetType.DeclaredMethods
                .First(m => m.Name == caseInfo.Method.Name);
            var targetAdditionalMethods =
                targetType.DeclaredMethods
                .Where(m => (caseInfo.AdditionalMethods.FirstOrDefault(am => m.Name == am.Name) != null))
                .ToArray();

            // Step 1-4: Translate caseInfo.Method bodies.
            var header = CodeTextWriter.Create(new StringWriter(), "    ");

            AssemblyWriter.InternalWriteHeader(
                header, translateContext, prepared, false);
            header.Flush();

            var body = CodeTextWriter.Create(new StringWriter(), "    ");

            AssemblyWriter.InternalWriteSourceCode(
                body, translateContext, prepared, DebugInformationOptions.Full, false);
            body.Flush();

            // Step 1-5: Write Visual C++ project file and Visual Studio Code launch config from template.
            //     Note: It's only debugging purpose. The test doesn't use.
            var translatedPath = Path.GetFullPath(
                Path.Combine(
                    Path.GetDirectoryName(caseInfo.Method.DeclaringType.Assembly.Location),
                    caseInfo.CategoryName,
                    caseInfo.Id,
                    caseInfo.Name));

            var vcxprojTemplatePath = Path.Combine(translatedPath, "test.vcxproj");
            await TestUtilities.CopyResourceToTextFileAsync(vcxprojTemplatePath, "test.vcxproj");

            var launchTemplatePath = Path.Combine(translatedPath, ".vscode", "launch.json");
            await TestUtilities.CopyResourceToTextFileAsync(launchTemplatePath, "launch.json");

            // Step 1-6: Write source code into a file from template.
            var expectedType = targetMethod.ReturnType;

            var sourceCodeStream = new MemoryStream();
            await TestUtilities.CopyResourceToStreamAsync(
                sourceCodeStream,
                // If the target caseInfo.Method result is void-type, we have to use void-type tolerant template.
                (expectedType.IsVoidType || (caseInfo.Assert == TestCaseAsserts.CauseBreak))? "test_void.c" : "test.c");

            sourceCodeStream.Position = 0;
            var sourceCode = new StreamReader(sourceCodeStream);

            var constants = caseInfo.Arguments.
                            Zip(targetMethod.Parameters, (arg, p) => new Constant(
                                    p.ParameterName,
                                    p.TargetType,
                                    arg?.GetType(),
                                    Utilities.GetCLanguageExpression(arg))
                                ).
                            ToArray();
            var argumentList = constants.
                               Select(constant => new Constant(
                                          "_" + constant.SymbolName,
                                          constant.TargetType,
                                          null,
                                          GetCLangaugeSafeConversionExpression(constant.TargetType, constant.ExpressionType, constant.SymbolName))).
                               ToArray();

            var arguments = argumentList;
            var locals    = argumentList.
                            Select(argument =>
                                   new Constant(
                                       argument.SymbolName,
                                       argument.TargetType,
                                       argument.ExpressionType,
                                       Utilities.GetCLanguageExpression(expectedType.InternalStaticEmptyValue))).
                            ToArray();

            if (!(expectedType.IsVoidType || (caseInfo.Assert == TestCaseAsserts.CauseBreak)))
            {
                // VERY DIRTY:
                constants = constants.Concat(new Constant[]
                {
                    new Constant(
                        "expected",
                        expectedType,
                        caseInfo.Expected?.GetType(),
                        Utilities.GetCLanguageExpression(caseInfo.Expected)),
                }).
                            ToArray();
                arguments = constants.
                            Select(constant => new Constant(
                                       "_" + constant.SymbolName,
                                       constant.TargetType,
                                       null,
                                       GetCLangaugeSafeConversionExpression(constant.TargetType, constant.ExpressionType, constant.SymbolName))).
                            ToArray();
                locals = arguments.
                         Select(argument =>
                                new Constant(
                                    argument.SymbolName,
                                    argument.TargetType,
                                    argument.ExpressionType,
                                    Utilities.GetCLanguageExpression(argument.TargetType.InternalStaticEmptyValue))).
                         Concat(new Constant[]
                {
                    new Constant(
                        "_actual",
                        expectedType,
                        caseInfo.Expected?.GetType(),
                        Utilities.GetCLanguageExpression(expectedType.InternalStaticEmptyValue)),
                }).
                         ToArray();
            }

            // Construct test definitions.
            var expectedSymbolName = locals.
                                     Any(entry => (entry.SymbolName == "_expected") && entry.TargetType.IsReferenceType) ?
                                     "frame__._expected" :
                                     "_expected";
            var actualSymbolName = locals.
                                   Any(entry => (entry.SymbolName == "_actual") && entry.TargetType.IsReferenceType) ?
                                   "frame__._actual" :
                                   "_actual";
            var replaceValues = new Dictionary <string, object>
            {
                { "testName", targetMethod.FriendlyName },
                { "type", targetMethod.ReturnType.CLanguageTypeName },
                { "body", body.Parent.ToString() },
                { "constants", string.Join(" ", constants.
                                           Select(entry => string.Format("{0} {1} = {2};",
                                                                         (entry.ExpressionType != null) ? Utilities.GetCLanguageTypeName(entry.ExpressionType) : entry.TargetType.CLanguageTypeName,
                                                                         entry.SymbolName,
                                                                         entry.Expression))) },
                { "locals", string.Join(" ", locals.
                                        Where(entry => !entry.TargetType.IsReferenceType).
                                        Select(entry => string.Format("{0} {1} = {2};",
                                                                      entry.TargetType.CLanguageTypeName,
                                                                      entry.SymbolName,
                                                                      entry.Expression))) },
                { "frames", string.Join(" ", locals.
                                        Where(entry => entry.TargetType.IsReferenceType).
                                        Select(entry => string.Format("{0} {1};",
                                                                      entry.TargetType.CLanguageTypeName,
                                                                      entry.SymbolName))) },
                { "frameCount", locals.
                  Where(entry => entry.TargetType.IsClass).Count() },
                { "arguments", string.Join(" ", arguments.
                                           Select(entry => string.Format("{0}{1} = {2};",
                                                                         entry.TargetType.IsReferenceType ? "frame__." : string.Empty,
                                                                         entry.SymbolName,
                                                                         entry.Expression))) },
                { "actual", actualSymbolName },
                { "function", targetMethod.CLanguageFunctionName },
                { "argumentList", string.Join(", ", argumentList.
                                              Select(arg => string.Format(
                                                         "{0}{1}",
                                                         arg.TargetType.IsReferenceType ? "frame__." : string.Empty,
                                                         arg.SymbolName))) },
                { "equality", GetCLanguageCompareExpression(expectedType, expectedSymbolName, actualSymbolName) },
                { "format", GetCLanguagePrintFormatFromType(targetMethod.ReturnType) },
                { "expectedExpression", GetCLanguagePrintArgumentExpression(expectedType, expectedSymbolName) },
                { "actualExpression", GetCLanguagePrintArgumentExpression(expectedType, actualSymbolName) },
            };

            var sourcePath = Path.Combine(translatedPath, "test.c");
            var headerPath = Path.Combine(translatedPath, "test.h");

            await Task.WhenAll(
                TestUtilities.WriteTextFileAsync(sourcePath, sourceCode, replaceValues),
                TestUtilities.WriteTextFileAsync(headerPath, header.Parent.ToString()));

            ///////////////////////////////////////////////
            // Step 2: Test and verify result by real IL code at this runtime.

            object rawResult;

            switch (caseInfo.Assert)
            {
            case TestCaseAsserts.IgnoreValidateInvokeResult:
                try
                {
                    rawResult = caseInfo.Method.Invoke(null, caseInfo.Arguments);
                }
                catch
                {
                    // ignore.
                    rawResult = null;
                }
                break;

            case TestCaseAsserts.CauseBreak:
                rawResult = null;
                break;

            default:
                rawResult = caseInfo.Method.Invoke(null, caseInfo.Arguments);
                Assert.AreEqual(caseInfo.Expected, rawResult);
                break;
            }

            ///////////////////////////////////////////////
            // Step 3: Test compiled C source code and execute.

            string sanitized = null;

            try
            {
                var il2cRuntimeSourcePaths = new[] {
                    // Use combined runtime source. 5 times faster!
                    Path.Combine(il2cRuntimePath, "il2c_combined.c")
                };

#if DEBUG
                var executedResult = await GccDriver.CompileAndRunAsync(false, sourcePath, il2cRuntimePath);
#else
                var executedResult = await GccDriver.CompileAndRunAsync(true, sourcePath, il2cRuntimePath);
#endif

                sanitized = executedResult.Trim(' ', '\r', '\n');
            }
            catch (Exception ex)
            {
                if ((caseInfo.Assert == TestCaseAsserts.CauseBreak) && ex.Message.Contains("ExitCode=-2147483645"))
                {
                    return;
                }
                throw;
            }

            Assert.IsFalse(caseInfo.Assert == TestCaseAsserts.CauseBreak, "Code didn't break.");

            ///////////////////////////////////////////////
            // Step 4: Verify result.

            Assert.AreEqual("Success", sanitized);
        }
Example #7
0
        public static async Task ExecuteTestAsync(TestCaseInformation caseInfo)
        {
            Assert.IsTrue(caseInfo.Method.IsPublic && caseInfo.Method.IsStatic);

            // Split current thread context.
            await Task.Delay(1);

#if DEBUG
            const string configuration = "Debug";
#else
            const string configuration = "Release";
#endif

            ///////////////////////////////////////////////

            // Step 1-1: Create translation context.
            var translateContext = new TranslateContext(
                caseInfo.Method.DeclaringType.Assembly.Location,
                true,
                TargetPlatforms.Generic);

            // Step 1-2: Prepare target methods.
            var targetTypes = new HashSet <string>(
                new[] { caseInfo.Method }.
                Concat(caseInfo.AdditionalMethods).
                Select(method => method.DeclaringType).
                Concat(caseInfo.AdditionalTypes).
                Select(type => type.FullName).
                Distinct());
            var targetMethods = new[] { caseInfo.Method }.
                Concat(caseInfo.AdditionalMethods).
            GroupBy(method => method.Name).
            ToDictionary(g => g.Key, g => g.ToArray());

            var prepared = AssemblyPreparer.Prepare(
                translateContext,
                t => targetTypes.Contains(t.FriendlyName),
                m => targetMethods.ContainsKey(m.Name));

            // Step 1-3: Extract prepared target type/caseInfo.Method informations.
            var targetType =
                translateContext.Assembly.Modules
                .First().Types
                .First(t => t.FriendlyName == caseInfo.Method.DeclaringType.FullName);
            var targetMethod =
                targetType.DeclaredMethods
                .First(m => m.Name == caseInfo.Method.Name);
            var targetAdditionalMethods =
                targetType.DeclaredMethods
                .Where(m => (caseInfo.AdditionalMethods.FirstOrDefault(am => m.Name == am.Name) != null))
                .ToArray();

            // Step 1-4: Create storing director for test artifacts
            //   HACK: It's reliability for Windows MAX_PATH limitation.
            var basePath =
                Path.GetFullPath(
                    Path.Combine(
                        Path.GetDirectoryName(caseInfo.Method.DeclaringType.Assembly.Location),
                        "..", "..", "..", "..", "..",
                        "test-artifacts", configuration));
            while (true)
            {
                try
                {
                    if (!Directory.Exists(basePath))
                    {
                        Directory.CreateDirectory(basePath);
                    }
                    break;
                }
                catch
                {
                }
            }

            // Step 1-4: Translate caseInfo.Method bodies.
            var translatedPath =
                Path.Combine(
                    basePath,
                    caseInfo.CategoryName,
                    caseInfo.Id,
                    caseInfo.UniqueName);

            var logw    = new StringWriter();
            var storage = new CodeTextStorage(logw, translatedPath, false, "    ");

            AssemblyWriter.WriteHeader(
                storage,
                translateContext,
                prepared);
            var sourceFiles = AssemblyWriter.WriteSourceCode(
                storage,
                translateContext,
                prepared,
                true,
                DebugInformationOptions.CommentOnly);

            // Step 1-5: Write source code into a file from template.
            var expectedType = targetMethod.ReturnType;

            var sourceCodeStream = new MemoryStream();
            await TestUtilities.CopyResourceToStreamAsync(
                sourceCodeStream,
                // If the target caseInfo.Method result is void-type, we have to use void-type tolerant template.
                (expectedType.IsVoidType || (caseInfo.Assert == TestCaseAsserts.CauseBreak))? "test_void.c" : "test.c");

            sourceCodeStream.Position = 0;
            var sourceCode = new StreamReader(sourceCodeStream);

            var constants = caseInfo.Arguments.
                            Zip(targetMethod.Parameters, (arg, p) => new Constant(
                                    p.ParameterName,
                                    p.TargetType,
                                    arg?.GetType(),
                                    Utilities.GetCLanguageExpression(arg))
                                ).
                            ToArray();
            var argumentList = constants.
                               Select(constant => new Constant(
                                          "_" + constant.SymbolName,
                                          constant.TargetType,
                                          null,
                                          GetCLangaugeSafeConversionExpression(constant.TargetType, constant.ExpressionType, constant.SymbolName))).
                               ToArray();

            var arguments = argumentList;
            var locals    = argumentList.
                            Select(argument =>
                                   new Constant(
                                       argument.SymbolName,
                                       argument.TargetType,
                                       argument.ExpressionType,
                                       Utilities.GetCLanguageExpression(expectedType.InternalStaticEmptyValue))).
                            ToArray();

            if (!(expectedType.IsVoidType || (caseInfo.Assert == TestCaseAsserts.CauseBreak)))
            {
                // VERY DIRTY:
                constants = constants.Concat(new Constant[]
                {
                    new Constant(
                        "expected",
                        expectedType,
                        caseInfo.Expected?.GetType(),
                        Utilities.GetCLanguageExpression(caseInfo.Expected)),
                }).
                            ToArray();
                arguments = constants.
                            Select(constant => new Constant(
                                       "_" + constant.SymbolName,
                                       constant.TargetType,
                                       null,
                                       GetCLangaugeSafeConversionExpression(constant.TargetType, constant.ExpressionType, constant.SymbolName))).
                            ToArray();
                locals = arguments.
                         Select(argument =>
                                new Constant(
                                    argument.SymbolName,
                                    argument.TargetType,
                                    argument.ExpressionType,
                                    Utilities.GetCLanguageExpression(argument.TargetType.InternalStaticEmptyValue))).
                         Concat(new Constant[]
                {
                    new Constant(
                        "_actual",
                        expectedType,
                        caseInfo.Expected?.GetType(),
                        Utilities.GetCLanguageExpression(expectedType.InternalStaticEmptyValue)),
                }).
                         ToArray();
            }

            // Construct test definitions.
            var expectedSymbolName = locals.
                                     Any(entry => (entry.SymbolName == "_expected") && entry.TargetType.IsReferenceType) ?
                                     "frame__._expected" :
                                     "_expected";
            var actualSymbolName = locals.
                                   Any(entry => (entry.SymbolName == "_actual") && entry.TargetType.IsReferenceType) ?
                                   "frame__._actual" :
                                   "_actual";
            var replaceValues = new Dictionary <string, object>
            {
                { "assemblyName", targetMethod.DeclaringType.DeclaringModule.DeclaringAssembly.Name },
                { "testName", targetMethod.FriendlyName },
                { "type", targetMethod.ReturnType.CLanguageTypeName },
                { "constants", string.Join(" ", constants.
                                           Select(entry => string.Format("{0} {1} = {2};",
                                                                         (entry.ExpressionType != null) ? Utilities.GetCLanguageTypeName(entry.ExpressionType) : entry.TargetType.CLanguageTypeName,
                                                                         entry.SymbolName,
                                                                         entry.Expression))) },
                { "locals", string.Join(" ", locals.
                                        Where(entry => !entry.TargetType.IsReferenceType).
                                        Select(entry => string.Format("{0} {1} = {2};",
                                                                      entry.TargetType.CLanguageTypeName,
                                                                      entry.SymbolName,
                                                                      entry.Expression))) },
                { "frames", string.Join(" ", locals.
                                        Where(entry => entry.TargetType.IsReferenceType).
                                        Select(entry => string.Format("{0} {1};",
                                                                      entry.TargetType.CLanguageTypeName,
                                                                      entry.SymbolName))) },
                { "frameCount", locals.
                  Where(entry => entry.TargetType.IsClass).Count() },
                { "arguments", string.Join(" ", arguments.
                                           Select(entry => string.Format("{0}{1} = {2};",
                                                                         entry.TargetType.IsReferenceType ? "frame__." : string.Empty,
                                                                         entry.SymbolName,
                                                                         entry.Expression))) },
                { "actual", actualSymbolName },
                { "function", targetMethod.CLanguageFunctionFullName },
                { "argumentList", string.Join(", ", argumentList.
                                              Select(arg => string.Format(
                                                         "{0}{1}",
                                                         arg.TargetType.IsReferenceType ? "frame__." : string.Empty,
                                                         arg.SymbolName))) },
                { "equality", GetCLanguageCompareExpression(expectedType, expectedSymbolName, actualSymbolName) },
                { "format", GetCLanguagePrintFormatFromType(targetMethod.ReturnType) },
                { "expectedExpression", GetCLanguagePrintArgumentExpression(expectedType, expectedSymbolName) },
                { "actualExpression", GetCLanguagePrintArgumentExpression(expectedType, actualSymbolName) },
                { "sourcePath", translateContext.Assembly.Name + "_bundle.c" }
            };

            // Step 1-6: Write Visual C++ project file and Visual Studio Code launch config from template.
            //     Note: It's only debugging purpose. The test doesn't use.
            var vcxprojTemplatePath = Path.Combine(translatedPath, "test.vcxproj");
            await TestUtilities.CopyResourceToTextFileAsync(vcxprojTemplatePath, "test.vcxproj", replaceValues);

            TestContext.AddTestAttachment(vcxprojTemplatePath, "Generated VC++ project");

            var launchTemplatePath = Path.Combine(translatedPath, ".vscode", "launch.json");
            await TestUtilities.CopyResourceToTextFileAsync(launchTemplatePath, "launch.json", replaceValues);

            var sourcePath = Path.Combine(translatedPath, "test.c");
            await TestUtilities.WriteTextFileAsync(sourcePath, sourceCode, replaceValues);

            ///////////////////////////////////////////////
            // Step 2: Test and verify result by real IL code at this runtime.

            object rawResult;
            switch (caseInfo.Assert)
            {
            case TestCaseAsserts.IgnoreValidateInvokeResult:
                break;

            case TestCaseAsserts.CauseBreak:
                rawResult = null;
                break;

            default:
                CultureInfo.CurrentCulture   = CultureInfo.InvariantCulture;
                CultureInfo.CurrentUICulture = CultureInfo.InvariantCulture;
                rawResult = caseInfo.Method.Invoke(null, caseInfo.Arguments);
                Assert.AreEqual(caseInfo.Expected, rawResult);
                break;
            }

            ///////////////////////////////////////////////
            // Step 3: Test compiled C source code and execute.

            string sanitized = null;
            try
            {
                var executedResult = await CMakeDriver.BuildDirectlyAsync(
                    binPath,
                    configuration,
                    sourcePath,
                    il2cRuntimePath);

                sanitized = executedResult.Trim(' ', '\r', '\n');
            }
            catch (Exception ex)
            {
                if ((caseInfo.Assert == TestCaseAsserts.CauseBreak) && ex.Message.Contains("ExitCode=-2147483645"))
                {
                    return;
                }
                throw;
            }

            Assert.IsFalse(caseInfo.Assert == TestCaseAsserts.CauseBreak, "Code didn't break.");

            ///////////////////////////////////////////////
            // Step 4: Verify result.

            Assert.AreEqual("Success", sanitized);
        }
Example #8
0
        public static void Translate(
            TextWriter tw,
            string assemblyPath,
            string outputPath,
            bool readSymbols,
            bool enableCpp,
            DebugInformationOptions debugInformationOptions)
        {
            tw.Write("IL2C: Preparing assembly: \"{0}\" ...", Path.GetFullPath(assemblyPath));

            if (Directory.Exists(outputPath) == false)
            {
                try
                {
                    Directory.CreateDirectory(outputPath);
                }
                catch
                {
                }
            }

            var translateContext  = new TranslateContext(assemblyPath, readSymbols);
            var preparedFunctions = AssemblyPreparer.Prepare(translateContext);

            tw.WriteLine(" done.");

            var assemblyName   = Path.GetFileNameWithoutExtension(assemblyPath);
            var filePath       = Path.Combine(outputPath, assemblyName);
            var sourceFilePath = filePath + (enableCpp ? ".cpp" : ".c");

            tw.Write("IL2C: Writing source code: \"{0}\" ...", Path.GetFullPath(sourceFilePath));

            using (var fsSource = new FileStream(
                       sourceFilePath,
                       FileMode.Create,
                       FileAccess.ReadWrite,
                       FileShare.None))
            {
                var twSource = CodeTextWriter.Create(fsSource, "    ");
                AssemblyWriter.WriteSourceCode(
                    twSource, translateContext, preparedFunctions, debugInformationOptions);
                twSource.Flush();
            }

            tw.WriteLine(" done.");

            var headerFilePath = filePath + ".h";

            tw.Write("IL2C: Writing header: \"{0}\" ...", Path.GetFullPath(headerFilePath));

            using (var fsHeader = new FileStream(
                       headerFilePath,
                       FileMode.Create,
                       FileAccess.ReadWrite,
                       FileShare.None))
            {
                var twHeader = CodeTextWriter.Create(fsHeader, "    ");
                AssemblyWriter.WriteHeader(twHeader, translateContext, preparedFunctions);
                twHeader.Flush();
            }

            tw.WriteLine(" done.");
        }