예제 #1
0
        public void VisitNode (JSBlockStatement bs) {
            RemoveNullStatements(bs);

            if ((bs.Statements.Count == 0) && (bs.Label == null)) {
                var newNull = new JSNullStatement();
                ParentNode.ReplaceChild(bs, newNull);
                VisitReplacement(newNull);
                return;
            }

            VisitChildren(bs);

            // Some of the children may have replaced themselves with nulls
            RemoveNullStatements(bs);
        }
예제 #2
0
        public void VisitNode (JSLabelGroupStatement lgs) {
            var nonNull = (from kvp in lgs.Labels where !kvp.Value.IsNull select kvp.Value).ToArray();

            if (nonNull.Length == 0) {
                var theNull = new JSNullStatement();
                ParentNode.ReplaceChild(lgs, theNull);
                VisitReplacement(theNull);
            } else if (
                (nonNull.Length == 1) && 
                !nonNull[0].AllChildrenRecursive.OfType<JSGotoExpression>().Any(
                    (g) => g.TargetLabel == nonNull[0].Label
                )
            ) {
                var onlyLabel = nonNull[0];
                var labelGroupExit = onlyLabel.AllChildrenRecursive.OfType<JSExitLabelGroupExpression>().FirstOrDefault();

                if (labelGroupExit != null) {
                    /* FIXME: This doesn't work
                    var enclosingFunction = Stack.OfType<JSFunctionExpression>().First();
                    var loops = enclosingFunction.AllChildrenRecursive.OfType<JSLoopStatement>();

                    int nextLoopIndex = 0;
                    if (loops.Any((l) => true))
                        nextLoopIndex = loops.Max((l) => l.Index.GetValueOrDefault(0)) + 1;

                    var replacement = new JSDoLoop(
                        JSLiteral.New(false),
                        onlyLabel
                    );
                    replacement.Index = nextLoopIndex;

                    var newBreak = new JSBreakExpression();
                    newBreak.TargetLoop = nextLoopIndex;

                    onlyLabel.ReplaceChildRecursive(labelGroupExit, newBreak);

                    ParentNode.ReplaceChild(lgs, replacement);
                    VisitReplacement(replacement);
                     */
                    VisitChildren(lgs);
                } else {
                    ParentNode.ReplaceChild(lgs, onlyLabel);
                    VisitReplacement(onlyLabel);
                }
            } else {
                VisitChildren(lgs);
            }
        }
예제 #3
0
        public void VisitNode(JSLabelGroupStatement lgs)
        {
            var nonNull = (from kvp in lgs.Labels where !kvp.Value.IsNull select kvp.Value).ToArray();

            if (nonNull.Length == 0) {
                var theNull = new JSNullStatement();
                ParentNode.ReplaceChild(lgs, theNull);
                VisitReplacement(theNull);
            } else if (
                (nonNull.Length == 1) &&
                !nonNull[0].AllChildrenRecursive.OfType<JSGotoExpression>().Any(
                    (g) => g.TargetLabel == nonNull[0].Label
                )
            ) {
                ParentNode.ReplaceChild(lgs, nonNull[0]);
                VisitReplacement(nonNull[0]);
            } else {
                VisitChildren(lgs);
            }
        }
예제 #4
0
        protected bool TranslateCallSiteConstruction(ILCondition condition, out JSStatement result)
        {
            var cond = condition.Condition;
            if (
                (cond.Code == ILCode.LogicNot) &&
                (cond.Arguments.Count > 0) &&
                (cond.Arguments[0].Code == ILCode.GetCallSite) &&
                (condition.TrueBlock != null) &&
                (condition.TrueBlock.Body.Count == 1) &&
                (condition.TrueBlock.Body[0] is ILExpression)
            ) {
                var callSiteExpression = (ILExpression)condition.TrueBlock.Body[0];
                var callSiteType = callSiteExpression.Arguments[0].ExpectedType;
                var binderExpression = callSiteExpression.Arguments[0].Arguments[0];
                var binderMethod = (MethodReference)binderExpression.Operand;
                var arguments = Translate(binderExpression.Arguments);
                var targetType = ((IGenericInstance)callSiteType).GenericArguments[0];

                DynamicCallSites.InitializeCallSite(
                    (FieldReference)cond.Arguments[0].Operand,
                    binderMethod.Name,
                    targetType,
                    arguments
                );

                result = new JSNullStatement();
                return true;
            }

            result = null;
            return false;
        }