private JSBinaryOperatorExpression MakeUnaryMutation (
            JSExpression expressionToMutate, JSBinaryOperator mutationOperator,
            TypeReference type
        ) {
            var newValue = new JSBinaryOperatorExpression(
                mutationOperator, expressionToMutate, JSLiteral.New(1),
                type
            );
            var assignment = new JSBinaryOperatorExpression(
                JSOperator.Assignment,
                MakeLhsForAssignment(expressionToMutate), newValue, type
            );

            return assignment;
        }
예제 #2
0
        public static JSBinaryOperatorExpression MakeUnaryMutation (
            JSExpression expressionToMutate, JSBinaryOperator mutationOperator,
            TypeReference type, TypeSystem typeSystem
        ) {
            var newValue = new JSBinaryOperatorExpression(
                mutationOperator, expressionToMutate, JSLiteral.New(1),
                type
            );
            var assignment = new JSBinaryOperatorExpression(
                JSOperator.Assignment,
                MakeLhsForAssignment(expressionToMutate), newValue, type
            );

            assignment = ConvertReadExpressionToWriteExpression(assignment, typeSystem);

            return assignment;
        }
예제 #3
0
        protected JSExpression Translate_BinaryOp(ILExpression node, JSBinaryOperator op)
        {
            // Detect attempts to perform pointer arithmetic
            if (IsIgnoredType(node.Arguments[0].ExpectedType) ||
                IsIgnoredType(node.Arguments[1].ExpectedType) ||
                IsIgnoredType(node.Arguments[0].InferredType) ||
                IsIgnoredType(node.Arguments[1].InferredType)
            ) {
                return new JSUntranslatableExpression(node);
            }

            // Detect attempts to perform pointer arithmetic on a local variable.
            // (ldloca produces a reference, not a pointer, so the previous check won't catch this.)
            if ((node.Arguments[0].Code == ILCode.Ldloca) &&
                !(op is JSAssignmentOperator))
                return new JSUntranslatableExpression(node);

            var lhs = TranslateNode(node.Arguments[0]);
            var rhs = TranslateNode(node.Arguments[1]);

            var boeLeft = lhs as JSBinaryOperatorExpression;
            if (
                (op is JSAssignmentOperator) &&
                (boeLeft != null) && !(boeLeft.Operator is JSAssignmentOperator)
            )
                return new JSUntranslatableExpression(node);

            return new JSBinaryOperatorExpression(
                op, lhs, rhs, node.ExpectedType ?? node.InferredType
            );
        }
예제 #4
0
        protected JSExpression Translate_ComparisonOperator(ILExpression node, JSBinaryOperator op)
        {
            if (
                (node.Arguments[0].ExpectedType.FullName == "System.Boolean") &&
                (node.Arguments[1].ExpectedType.FullName == "System.Boolean") &&
                (node.Arguments[1].Code.ToString().Contains("Ldc_"))
            ) {
                // Comparison against boolean constant
                bool comparand = Convert.ToInt64(node.Arguments[1].Operand) != 0;
                bool checkEquality = (op == JSOperator.Equal);

                if (comparand != checkEquality)
                    return new JSUnaryOperatorExpression(
                        JSOperator.LogicalNot, TranslateNode(node.Arguments[0])
                    );
                else
                    return TranslateNode(node.Arguments[0]);
            } else if (
                (!node.Arguments[0].ExpectedType.IsValueType) &&
                (!node.Arguments[1].ExpectedType.IsValueType) &&
                (node.Arguments[0].ExpectedType == node.Arguments[1].ExpectedType) &&
                (node.Arguments[0].Code == ILCode.Isinst)
            ) {
                // The C# expression 'x is y' translates into roughly '(x is y) > null' in IL,
                //  because there's no IL opcode for != and the IL isinst opcode returns object, not bool
                var value = TranslateNode(node.Arguments[0].Arguments[0]);
                var nullLiteral = TranslateNode(node.Arguments[1]) as JSNullLiteral;
                var targetType = (TypeReference)node.Arguments[0].Operand;

                var targetInfo = TypeInfo.Get(targetType);
                JSExpression checkTypeResult;

                if ((targetInfo != null) && targetInfo.IsIgnored)
                    checkTypeResult = JSLiteral.New(false);
                else
                    checkTypeResult = JSIL.CheckType(
                        value, targetType
                    );

                if (nullLiteral != null) {
                    if (
                        (op == JSOperator.Equal) ||
                        (op == JSOperator.LessThanOrEqual) ||
                        (op == JSOperator.LessThan)
                    ) {
                        return new JSUnaryOperatorExpression(
                            JSOperator.LogicalNot, checkTypeResult, TypeSystem.Boolean
                        );
                    } else if (
                        (op == JSOperator.GreaterThan)
                    ) {
                        return checkTypeResult;
                    } else {
                        return new JSUntranslatableExpression(node);
                    }
                }
            }

            return Translate_BinaryOp(node, op);
        }
예제 #5
0
        private string GetVerb(JSBinaryOperator op)
        {
            switch (op.Token)
            {
                case "+": return "op_Addition";
                case "-": return "op_Subtraction";
                case "/": return "op_Division";
                case "*": return "op_Multiplication";
                case "%": return "op_Modulus";
                case "|": return "op_BitwiseOr";
                case "^": return "op_ExclusiveOr";
                case "&": return "op_BitwiseAnd";
                case "<<": return "op_LeftShift";
                case ">>":
                case ">>>":
                    return "op_RightShift";

                case "===": return "op_Equality";
                case "!==": return "op_Inequality";
                case "<": return "op_LessThan";
                case "<=": return "op_LessThanOrEqual";
                case ">": return "op_GreaterThan";
                case ">=": return "op_GreaterThanOrEqual";

                default:
                    return null;
            }
        }
예제 #6
0
        private JSBinaryOperatorExpression MakeUnaryMutation(
            JSExpression expressionToMutate, JSBinaryOperator mutationOperator,
            TypeReference type
        )
        {
            var newValue = new JSBinaryOperatorExpression(
                mutationOperator, expressionToMutate, JSLiteral.New(1),
                TypeSystem.Int32
            );
            var assignment = new JSBinaryOperatorExpression(
                JSOperator.Assignment,
                expressionToMutate, JSCastExpression.New(
                    newValue, type, TypeSystem, true
                ), type
            );

            return assignment;
        }