Beispiel #1
0
        public override void VisitTryStatement(TryStatementSyntax node)
        {
            if (debug)
            {
                Console.WriteLine(node.ToFullString());
            }
            var nl = OurLine.NewLine(LineKind.Decl, "TryStatement");

            if (node.Finally != null)
            {
                OurLine.AddEssentialInfo(ref nl, "finally:" + node.Finally.ToString());
            }
            if (node.Catches != null)
            {
                OurLine.AddEssentialInfo(ref nl, "catches:" + node.Catches.ToString());
            }
            // we get the details later on.
            nl.Source     = node.ToFullString();
            nl.ParentKind = node.Parent.RawKind;
            nl.RawKind    = node.RawKind;
            LogCommand(nl);

            StartBlock("TryStatement");
            base.VisitTryStatement(node);
            EndBlock("TryStatement");
        }
Beispiel #2
0
        private void TryStatement(TryStatementSyntax statement)
        {
            if (statement.Finally != null)
            {
                throw new NotSupportedException("Finally blocks not supported: " + statement.ToFullString());
            }
            if (statement.Catches == null || statement.Catches.Count == 0)
            {
                throw new NotSupportedException("No catach block after try: " + statement.ToFullString());
            }

            // add special locals
            StartTryBlock(out string jmpBuffLast, out string jmpBuff, out string isJmp);
            ++tryCatchNestingLevel;

            // write try
            writer.WriteLinePrefix("/* try */");
            writer.WriteLinePrefix($"memcpy({jmpBuffLast}, CS2X_ThreadExceptionJmpBuff, sizeof(jmp_buf));");
            writer.WriteLinePrefix($"{isJmp} = setjmp({jmpBuff});");
            writer.WriteLinePrefix($"if ({isJmp} == 0)");
            void WriteTryStart()
            {
                writer.WriteLinePrefix($"memcpy(CS2X_ThreadExceptionJmpBuff, {jmpBuff}, sizeof(jmp_buf));");
            }

            BlockStartCallback = WriteTryStart;
            WriteStatement(statement.Block);

            // write catches
            writer.WriteLinePrefix("else /* end try */");
            writer.WriteLinePrefix('{');
            writer.AddTab();
            writer.WriteLinePrefix($"memcpy(CS2X_ThreadExceptionJmpBuff, {jmpBuffLast}, sizeof(jmp_buf));");
            var first = statement.Catches.FirstOrDefault();

            foreach (var c in statement.Catches)
            {
                if (c.Filter != null)
                {
                    throw new NotSupportedException("Catch blocks do not support filters: " + c.ToFullString());
                }
                if (c.Declaration != null)
                {
                    var type = ResolveType(c.Declaration.Type);
                    writer.WritePrefix();
                    if (c != first)
                    {
                        writer.Write("else ");
                    }
                    writer.WriteLine($"if (CS2X_IsType((({GetTypeFullName(specialTypes.objectType)}*)CS2X_ThreadExceptionObject)->CS2X_RuntimeType, &{GetRuntimeTypeObjFullName(type)})) /* catch */");
                }
                else
                {
                    writer.WriteLinePrefix("/* empty catch */");
                }
                void WriteCatchStart()
                {
                    if (c.Declaration != null)
                    {
                        var type  = ResolveType(c.Declaration.Type);
                        var local = TryAddLocal(c.Declaration.Identifier.ValueText, type);
                        writer.WriteLinePrefix($"{local.name} = CS2X_ThreadExceptionObject;");
                    }
                    writer.WriteLinePrefix("CS2X_ThreadExceptionObject = 0;");
                }

                BlockStartCallback = WriteCatchStart;
                WriteStatement(c.Block);
            }
            writer.WriteLinePrefix("if (CS2X_ThreadExceptionObject != 0) longjmp(CS2X_ThreadExceptionJmpBuff, 1); /* throw unhandled exception */");
            writer.RemoveTab();
            writer.WriteLinePrefix('}');
            writer.WriteLinePrefix($"memcpy(CS2X_ThreadExceptionJmpBuff, {jmpBuffLast}, sizeof(jmp_buf));");
            writer.WriteLinePrefix("/* end catch */");
            --tryCatchNestingLevel;
        }