private JSExpression Hoist(JSExpression expression, TypeReference type, List <JSExpression> commaElements)
        {
            if (expression is JSVariable)
            {
                return(null);
            }
            else if (expression is JSLiteral)
            {
                return(null);
            }

            var thisBoe = expression as JSBinaryOperatorExpression;

            if ((thisBoe != null) &&
                (thisBoe.Operator == JSOperator.Assignment) &&
                (thisBoe.Left is JSVariable)
                )
            {
                // If the value is (x = y), insert 'x = y' and then set the value to 'x'
                commaElements.Add(thisBoe);
                return(thisBoe.Left);
            }
            else
            {
                var tempVar = TemporaryVariable.ForFunction(Function, type, FunctionSource);

                commaElements.Add(new JSBinaryOperatorExpression(
                                      JSOperator.Assignment, tempVar, expression, type
                                      ));

                return(tempVar);
            }
        }
Example #2
0
        public void VisitNode(JSBinaryOperatorExpression boe)
        {
            JSPropertyAccess     pa;
            JSAssignmentOperator assignmentOperator;
            JSBinaryOperator     newOperator;

            if (
                IsPropertyAccess(boe, out pa) &&
                ((assignmentOperator = boe.Operator as JSAssignmentOperator) != null) &&
                IntroduceEnumCasts.ReverseCompoundAssignments.TryGetValue(assignmentOperator, out newOperator)
                )
            {
                // FIXME: Terrible hack
                var type         = pa.GetActualType(TypeSystem);
                var tempVariable = TemporaryVariable.ForFunction(
                    Stack.Last() as JSFunctionExpression, type
                    );
                var replacement = new JSCommaExpression(
                    new JSBinaryOperatorExpression(
                        JSOperator.Assignment, tempVariable,
                        new JSBinaryOperatorExpression(
                            newOperator,
                            new JSPropertyAccess(
                                pa.ThisReference, pa.Property, false,
                                pa.TypeQualified,
                                pa.OriginalType, pa.OriginalMethod,
                                pa.IsVirtualCall
                                ),
                            boe.Right, boe.GetActualType(TypeSystem)
                            ), type
                        ),
                    new JSBinaryOperatorExpression(
                        JSOperator.Assignment,
                        new JSPropertyAccess(
                            pa.ThisReference, pa.Property, true,
                            pa.TypeQualified,
                            pa.OriginalType, pa.OriginalMethod,
                            pa.IsVirtualCall
                            ), tempVariable, type
                        ),
                    tempVariable
                    );

                ParentNode.ReplaceChild(boe, replacement);
                VisitReplacement(replacement);
            }
            else
            {
                VisitChildren(boe);
            }
        }
        public void VisitNode(JSUnaryOperatorExpression uoe)
        {
            JSUnaryMutationOperator op;
            JSExpression            target;
            TypeReference           type;

            if (UnpackUnaryMutation(uoe, out op, out target, out type))
            {
                var tempVar = TemporaryVariable.ForFunction(
                    Stack.Last() as JSFunctionExpression, type
                    );
                var store = new JSBinaryOperatorExpression(
                    JSOperator.Assignment, tempVar, target, type
                    );

                var delta = (
                    (op == JSOperator.PostIncrement) ||
                    (op == JSOperator.PreIncrement)
                    )
                    ? 1
                    : -1;

                JSExpression replacement;
                if (
                    (op == JSOperator.PostIncrement) ||
                    (op == JSOperator.PostDecrement)
                    )
                {
                    var mutated = new JSPointerAddExpression(target, JSLiteral.New(delta), false);
                    replacement = new JSCommaExpression(store, mutated, tempVar);
                }
                else
                {
                    replacement = new JSPointerAddExpression(target, JSLiteral.New(delta), true);
                }

                ParentNode.ReplaceChild(uoe, replacement);
                VisitReplacement(replacement);
                return;
            }

            VisitChildren(uoe);
        }
        public void VisitNode(JSUnaryOperatorExpression uoe)
        {
            JSExpression expr;

            if (!JSReferenceExpression.TryDereference(JSIL, uoe.Expression, out expr))
            {
                expr = uoe.Expression;
            }

            var eVar        = expr as JSVariable;
            var eChangeType = expr as JSChangeTypeExpression;

            if (eChangeType != null)
            {
                eVar = eChangeType.Expression as JSVariable;
            }

            var type = uoe.Expression.GetActualType(TypeSystem);

            if (
                (eVar != null) &&
                (eVar.Identifier == Variable.Identifier) &&
                (uoe.Operator is JSUnaryMutationOperator)
                )
            {
                var newValue = DecomposeMutationOperators.DecomposeUnaryMutation(
                    uoe, () => TemporaryVariable.ForFunction(
                        Stack.Last() as JSFunctionExpression, type
                        ), type, TypeSystem
                    );
                var replacement = new JSWriteThroughReferenceExpression(
                    Variable, newValue
                    );
                ParentNode.ReplaceChild(uoe, replacement);
                VisitReplacement(replacement);
            }
            else
            {
                VisitChildren(uoe);
            }
        }
Example #5
0
        public void VisitNode(JSUnaryOperatorExpression uoe)
        {
            var type       = uoe.Expression.GetActualType(TypeSystem);
            var isIntegral = TypeUtil.Is32BitIntegral(type);

            if (isIntegral && (uoe.Operator is JSUnaryMutationOperator))
            {
                var replacement = DecomposeUnaryMutation(
                    uoe,
                    () => TemporaryVariable.ForFunction(
                        Stack.Last() as JSFunctionExpression, type
                        ),
                    type, TypeSystem
                    );

                ParentNode.ReplaceChild(uoe, replacement);
                VisitReplacement(replacement);
                return;
            }

            VisitChildren(uoe);
        }
Example #6
0
        public void VisitNode(JSUnaryOperatorExpression uoe)
        {
            var type       = uoe.Expression.GetActualType(TypeSystem);
            var isIntegral = TypeUtil.Is32BitIntegral(type);

            if (isIntegral && (uoe.Operator is JSUnaryMutationOperator))
            {
                if (
                    (uoe.Operator == JSOperator.PreIncrement) ||
                    (uoe.Operator == JSOperator.PreDecrement)
                    )
                {
                    var assignment = MakeUnaryMutation(
                        uoe.Expression,
                        (uoe.Operator == JSOperator.PreDecrement)
                            ? JSOperator.Subtract
                            : JSOperator.Add,
                        type
                        );

                    ParentNode.ReplaceChild(uoe, assignment);
                    VisitReplacement(assignment);
                    return;
                }
                else if (
                    (uoe.Operator == JSOperator.PostIncrement) ||
                    (uoe.Operator == JSOperator.PostDecrement)
                    )
                {
                    // FIXME: Terrible hack
                    var tempVariable = TemporaryVariable.ForFunction(
                        Stack.Last() as JSFunctionExpression, type
                        );
                    var makeTempCopy = new JSBinaryOperatorExpression(
                        JSOperator.Assignment, tempVariable, uoe.Expression, type
                        );
                    var assignment = MakeUnaryMutation(
                        uoe.Expression,
                        (uoe.Operator == JSOperator.PostDecrement)
                            ? JSOperator.Subtract
                            : JSOperator.Add,
                        type
                        );

                    var comma = new JSCommaExpression(
                        makeTempCopy,
                        assignment,
                        tempVariable
                        );

                    ParentNode.ReplaceChild(uoe, comma);
                    VisitReplacement(comma);
                    return;
                }
                else
                {
                    throw new NotImplementedException("Unary mutation not supported: " + uoe);
                }
            }

            VisitChildren(uoe);
        }
Example #7
0
        public void VisitNode(JSUnaryOperatorExpression uoe)
        {
            var type   = uoe.Expression.GetActualType(TypeSystem);
            var isEnum = IsEnumOrNullableEnum(type);

            if (isEnum)
            {
                var castToInt = JSInvocationExpression.InvokeMethod(
                    JS.valueOf(TypeSystem.Int32), uoe.Expression, null, true
                    );

                if (LogicalOperators.Contains(uoe.Operator))
                {
                    uoe.ReplaceChild(uoe.Expression, castToInt);
                }
                else if (uoe.Operator == JSOperator.Negation)
                {
                    uoe.ReplaceChild(uoe.Expression, castToInt);
                }
                else if (uoe.Operator is JSUnaryMutationOperator)
                {
                    if (
                        (uoe.Operator == JSOperator.PreIncrement) ||
                        (uoe.Operator == JSOperator.PreDecrement)
                        )
                    {
                        var assignment = MakeUnaryMutation(
                            uoe.Expression,
                            (uoe.Operator == JSOperator.PreDecrement)
                                ? JSOperator.Subtract
                                : JSOperator.Add,
                            type
                            );

                        ParentNode.ReplaceChild(uoe, assignment);
                        VisitReplacement(assignment);
                        return;
                    }
                    else if (
                        (uoe.Operator == JSOperator.PostIncrement) ||
                        (uoe.Operator == JSOperator.PostDecrement)
                        )
                    {
                        // FIXME: Terrible hack
                        var tempVariable = TemporaryVariable.ForFunction(
                            Stack.Last() as JSFunctionExpression, type
                            );
                        var makeTempCopy = new JSBinaryOperatorExpression(
                            JSOperator.Assignment, tempVariable, uoe.Expression, type
                            );
                        var assignment = MakeUnaryMutation(
                            uoe.Expression,
                            (uoe.Operator == JSOperator.PostDecrement)
                                ? JSOperator.Subtract
                                : JSOperator.Add,
                            type
                            );

                        var comma = new JSCommaExpression(
                            makeTempCopy,
                            assignment,
                            tempVariable
                            );

                        ParentNode.ReplaceChild(uoe, comma);
                        VisitReplacement(comma);
                        return;
                    }
                    else
                    {
                        throw new NotImplementedException("Unary mutation of enum not supported: " + uoe.ToString());
                    }
                }
            }

            VisitChildren(uoe);
        }