示例#1
0
        protected override void TraverseLoop(Loop loop)
        {
            Func<Type, Type> safeType = t => t.IsRectMdArray() ? typeof(Object) : t;
            loop.Locals.ForEach(l => locals.Add(l, il.DeclareLocal(safeType(l.Type.AssertNotNull()))));

            var test = il.DefineLabel();
            var @continue = il.DefineLabel();
            var body = il.DefineLabel();
            var @break = il.DefineLabel();
            continues.Add(loop, @continue);
            breaks.Add(loop, @break);

            Traverse(loop.Init);
            if (loop.IsDoWhile) il.br(body);
            il.label(test);
            Traverse(loop.Test);
            il.brfalse(@break);
            il.label(body);
            Traverse(loop.Body);
            il.label(@continue);
            Traverse(loop.Iter);
            il.br(test);
            il.label(@break);
        }
 protected internal virtual void TraverseLoop(Loop loop) { loop.Unsupported(); }
示例#3
0
        private void Expand(Node node)
        {
            if (node is Expression)
            {
                var expr = (Expression)node;
                var inlined = expr.Expand(Ctx);
                inlined.Stmts.ForEach(Stmts.Add);
                if (inlined.Result != null) Stmts.Add(inlined.Result);
            }
            else if (node is Block)
            {
                var block = (Block)node;
                Stmts.Add(block.Expand(Ctx.SpinOff()));
            }
            else if (node is Break)
            {
                Stmts.Add(node);
            }
            else if (node is Continue)
            {
                Stmts.Add(node);
            }
            else if (node is Goto)
            {
                Stmts.Add(node);
            }
            else if (node is Label)
            {
                Stmts.Add(node);
            }
            else if (node is If)
            {
                var @if = (If)node;

                var test = @if.Test.Expand(Ctx);
                test.Stmts.ForEach(Stmts.Add);
                test.Result.AssertNotNull();

                var if_true = @if.IfTrue.Expand(Ctx.SpinOff());
                var if_false = @if.IfFalse.Expand(Ctx.SpinOff());
                var expanded = new If(test.Result, if_true, if_false);
                Stmts.Add(expanded);
            }
            else if (node is Loop)
            {
                var loop = (Loop)node;

                var test = loop.Test.Expand(Ctx);
                test.Result.AssertNotNull();
                var init = loop.Init.Expand(Ctx.SpinOff());
                var iter = loop.Iter.Expand(Ctx.SpinOff());
                var body = loop.Body.Expand(Ctx.SpinOff());

                var prepend_test = loop.IsWhileDo && test.Stmts.IsNotEmpty();
                if (init.IsNotEmpty() && prepend_test) { Stmts.Add(init); init = new Block(); }
                if (prepend_test) test.Stmts.ForEach(Stmts.Add);
                test.Stmts.ForEach(iter.Add);

                var xloop = new Loop(test.Result, body, loop.IsWhileDo){Init = init, Iter = iter};
                var cloned_locals = loop.Locals.Select(l => l.DeepClone());
                cloned_locals.ForEach(local => xloop.Locals.Add(local));

                Stmts.Add(xloop);
            }
            else if (node is Return)
            {
                var ret = (Return)node;
                (ret.Value == null).AssertEquiv(Ret == null);
                if (ret.Value != null) Expand(new Assign(Ret, ret.Value));
                Stmts.Add(new Goto(RetLabel));
            }
            else if (node is Try || node is Clause || node is Throw ||
                node is Using || node is Iter)
            {
                // todo. implement support for non-linear control flow
                // this is only possible when we fully implement decompilation of tries
                // until now I leave this marked as "to be implemented"
                throw AssertionHelper.Fail();
            }
            else
            {
                throw AssertionHelper.Fail();
            }
        }
 protected internal override void TraverseLoop(Loop loop)
 {
     Dispatch(loop);
 }
 protected internal override Node TransformLoop(Loop loop)
 {
     return Dispatch(loop);
 }
 protected internal override void TraverseLoop(Loop loop)
 {
     Traverse(loop.Init);
     Traverse(loop.Test);
     Traverse(loop.Body);
     Traverse(loop.Iter);
     Types.Add(loop, null);
 }
示例#7
0
        protected override void TraverseLoop(Loop loop)
        {
            var loop_id = Guid.NewGuid().ToString().Slice(0, 4);
            var test = _ptx.def_label("$loop_test_" + loop_id);
            var @continue = _ptx.def_label("$loop_continue_" + loop_id);
            var body = _ptx.def_label("$loop_body_" + loop_id);
            var @break = _ptx.def_label("$loop_break_" + loop_id);
            _continues.Add(loop, @continue);
            _breaks.Add(loop, @break);

            _ptx.emit(loop.Init);
            if (loop.IsDoWhile) _ptx.bra(body);

            _ptx.label(test)
                .comment(Environment.NewLine)
                .comment(loop.Test.ToDebugString_WithoutParentInfo())
                .bra(Operator.Not(loop.Test), @break)
                .label(body)
                .emit(loop.Body)
                .label(@continue)
                .emit(loop.Iter)
                .bra(test)
                .label(@break);
        }
        protected internal override void TraverseLoop(Loop loop)
        {
            Action dumpHeader = () =>
            {
                var initIsNotEmpty = loop.Init.IsNeitherNullNorEmpty();
                var iterIsNotEmpty = loop.Iter.IsNeitherNullNorEmpty(); ;
                if (initIsNotEmpty || iterIsNotEmpty) _writer.Write("for (");
                else _writer.Write("while (");

                if (initIsNotEmpty || iterIsNotEmpty)
                {
                    (loop.Init ?? new Block()).ForEach((c, i) =>
                    {
                        var ass = c as Assign;
                        var lhs = ass == null ? null : ass.Lhs as Ref;
                        if (lhs != null && loop.Locals.Contains(lhs.Sym as Local)) _writer.Write("var ");

                        Traverse(c.AssertCast<Expression>());
                        if (i != loop.Init.Count() - 1) _writer.Write(", ");
                    });

                    _writer.Write(";");
                    if (initIsNotEmpty) _writer.Write(" ");
                }

                Traverse(loop.Test);

                if (initIsNotEmpty || iterIsNotEmpty)
                {
                    _writer.Write(";");

                    if (iterIsNotEmpty) _writer.Write(" ");
                    (loop.Iter ?? new Block()).ForEach((c, i) =>
                    {
                        Traverse(c.AssertCast<Expression>());
                        if (i != loop.Iter.Count() - 1) _writer.Write(", ");
                    });
                }

                _writer.WriteLine(")");
            };

            if (loop.IsWhileDo)
            {
                dumpHeader();
                Traverse(loop.Body);
            }
            else
            {
                _writer.WriteLine("do");
                Traverse(loop.Body);
                dumpHeader();
            }
        }
示例#9
0
        // todo. verify that init and iter can live outside the thread loop (when insideThreadLoop is false)
        private void TransformLoop(Loop loop, Block xregion, bool insideThreadLoop)
        {
            var x_init = new Block(); TransformBlock(loop.Init, x_init, true);
            var x_test = TransformExpression(loop.Test, insideThreadLoop);
            var x_body = new Block(); TransformBlock(loop.Body, x_body, insideThreadLoop);
            var x_iter = new Block(); TransformBlock(loop.Iter, x_iter, true);

            var x_loop = new Loop(x_test, x_body);
            x_loop.Locals.SetElements(loop.Locals);
            x_loop.Init = new Block(x_init.Children);
            x_loop.Iter = new Block(x_iter.Children);
            xregion.Add(x_loop);
        }
 protected internal virtual Node TransformLoop(Loop loop) { return loop.AcceptTransformer(this, true); }