Exemple #1
0
        private JSExpression ComputeAddress(
            JSExpression pointer, JSExpression offsetInElements, JSExpression offsetInBytes,
            out TypeReference elementType
            )
        {
            var pointerType = pointer.GetActualType(TypeSystem);

            elementType = pointerType.GetElementType();
            var elementSize = WasmUtil.SizeOfType(elementType);

            if (
                (offsetInElements != null) &&
                // I'm so helpful :-)))))
                (offsetInBytes == null)
                )
            {
                offsetInBytes = new JSBinaryOperatorExpression(
                    JSOperator.Multiply,
                    offsetInElements,
                    JSLiteral.New(elementSize),
                    pointerType
                    );
            }

            if (offsetInBytes != null)
            {
                var result = new JSPointerAddExpression(pointer, offsetInBytes, false);
                // Console.WriteLine("Constructing pae {0} from {1} {2} {3}", result, pointer, offsetInElements, offsetInBytes);
                return(result);
            }
            else
            {
                return(pointer);
            }
        }
        public void VisitNode(JSBinaryOperatorExpression boe)
        {
            var leftType  = boe.Left.GetActualType(TypeSystem);
            var rightType = boe.Right.GetActualType(TypeSystem);

            JSVariable             leftVar;
            JSPointerAddExpression rightAdd;

            if (
                TypeUtil.IsPointer(leftType) &&
                TypeUtil.IsPointer(rightType) &&
                (boe.Operator is JSAssignmentOperator) &&
                ((leftVar = boe.Left as JSVariable) != null) &&
                ((rightAdd = boe.Right as JSPointerAddExpression) != null) &&
                rightAdd.Pointer.Equals(leftVar) &&
                !rightAdd.MutateInPlace
                )
            {
                var replacement = new JSPointerAddExpression(
                    leftVar, rightAdd.Delta, true
                    );

                ParentNode.ReplaceChild(boe, replacement);
                VisitReplacement(replacement);
                return;
            }
            else
            {
                VisitChildren(boe);
            }
        }
Exemple #3
0
        public void VisitNode(JSPointerAddExpression pae)
        {
            var pointerType = pae.Pointer.GetActualType(TypeSystem);
            var synthesized = new JSBinaryOperatorExpression(
                JSOperator.Add, pae.Pointer, pae.Delta, pointerType
                );

            if (pae.MutateInPlace)
            {
                synthesized = new JSBinaryOperatorExpression(
                    JSOperator.Assignment, pae.Pointer, synthesized, pointerType
                    );
            }

            Visit(synthesized);
        }
        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(JSPointerAddExpression pae)
 {
     VisitChildren(pae);
 }
        public void VisitNode(JSBinaryOperatorExpression boe)
        {
            var leftType  = boe.Left.GetActualType(TypeSystem);
            var rightType = boe.Right.GetActualType(TypeSystem);

            // We can end up with a pointer literal in an arithmetic expression.
            // In this case we want to switch it back to a normal integer literal so that the math operations work.
            var leftPointer  = boe.Left as JSPointerLiteral;
            var rightPointer = boe.Right as JSPointerLiteral;

            if (!(boe.Operator is JSAssignmentOperator))
            {
                if (leftPointer != null)
                {
                    boe.ReplaceChild(boe.Left, JSLiteral.New(leftPointer.Value));
                }
                if (rightPointer != null)
                {
                    boe.ReplaceChild(boe.Right, JSLiteral.New(rightPointer.Value));
                }
            }

            JSExpression replacement = null;

            if (leftType.IsPointer && TypeUtil.IsIntegral(rightType))
            {
                if (
                    (boe.Operator == JSOperator.Add) ||
                    (boe.Operator == JSOperator.AddAssignment)
                    )
                {
                    replacement = new JSPointerAddExpression(
                        boe.Left, boe.Right,
                        boe.Operator == JSOperator.AddAssignment
                        );
                }
                else if (
                    (boe.Operator == JSOperator.Subtract) ||
                    (boe.Operator == JSOperator.SubtractAssignment)
                    )
                {
                    // FIXME: Int32 is probably wrong
                    replacement = new JSPointerAddExpression(
                        boe.Left,
                        new JSUnaryOperatorExpression(JSOperator.Negation, boe.Right, TypeSystem.Int32),
                        boe.Operator == JSOperator.SubtractAssignment
                        );
                }
            }
            else if (leftType.IsPointer && rightType.IsPointer)
            {
                if (boe.Operator == JSOperator.Subtract)
                {
                    // FIXME: Int32 is probably wrong
                    replacement = new JSPointerDeltaExpression(
                        boe.Left, boe.Right, TypeSystem.Int32
                        );
                }
                else if (boe.Operator is JSComparisonOperator)
                {
                    replacement = new JSPointerComparisonExpression(boe.Operator, boe.Left, boe.Right, boe.ActualType);
                }
            }

            if (replacement != null)
            {
                ParentNode.ReplaceChild(boe, replacement);
                VisitReplacement(replacement);
            }
            else
            {
                VisitChildren(boe);
            }
        }
        public void VisitNode (JSBinaryOperatorExpression boe) {
            var leftType = boe.Left.GetActualType(TypeSystem);
            var rightType = boe.Right.GetActualType(TypeSystem);

            // We can end up with a pointer literal in an arithmetic expression.
            // In this case we want to switch it back to a normal integer literal so that the math operations work.
            var leftPointer = boe.Left as JSPointerLiteral;
            var rightPointer = boe.Right as JSPointerLiteral;
            if (!(boe.Operator is JSAssignmentOperator)) {
                if (leftPointer != null)
                    boe.ReplaceChild(boe.Left, JSLiteral.New(leftPointer.Value));
                if (rightPointer != null)
                    boe.ReplaceChild(boe.Right, JSLiteral.New(rightPointer.Value));
            }

            JSExpression replacement = null;
            if (leftType.IsPointer && TypeUtil.IsIntegral(rightType)) {
                if (
                    (boe.Operator == JSOperator.Add) ||
                    (boe.Operator == JSOperator.AddAssignment)
                ) {
                    replacement = new JSPointerAddExpression(
                        boe.Left, boe.Right,
                        boe.Operator == JSOperator.AddAssignment
                    );
                } else if (
                    (boe.Operator == JSOperator.Subtract) ||
                    (boe.Operator == JSOperator.SubtractAssignment)
                ) {
                    // FIXME: Int32 is probably wrong
                    replacement = new JSPointerAddExpression(
                        boe.Left,
                        new JSUnaryOperatorExpression(JSOperator.Negation, boe.Right, TypeSystem.Int32),
                        boe.Operator == JSOperator.SubtractAssignment
                    );
                }
            } else if (leftType.IsPointer && rightType.IsPointer) {
                if (boe.Operator == JSOperator.Subtract) {
                    // FIXME: Int32 is probably wrong
                    replacement = new JSPointerDeltaExpression(
                        boe.Left, boe.Right, TypeSystem.Int32
                    );
                } else if (boe.Operator is JSComparisonOperator) {
                    replacement = new JSPointerComparisonExpression(boe.Operator, boe.Left, boe.Right, boe.ActualType);
                }
            }

            if (replacement != null) {
                ParentNode.ReplaceChild(boe, replacement);
                VisitReplacement(replacement);
            } else {
                VisitChildren(boe);
            }
        }
 public void VisitNode (JSPointerAddExpression pae) {
     VisitChildren(pae);
 }
        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 (JSBinaryOperatorExpression boe) {
            var leftType = boe.Left.GetActualType(TypeSystem);
            var rightType = boe.Right.GetActualType(TypeSystem);

            JSVariable leftVar;
            JSPointerAddExpression rightAdd;

            if (
                TypeUtil.IsPointer(leftType) && 
                TypeUtil.IsPointer(rightType) &&
                (boe.Operator is JSAssignmentOperator) &&
                ((leftVar = boe.Left as JSVariable) != null) &&
                ((rightAdd = boe.Right as JSPointerAddExpression) != null) &&
                rightAdd.Pointer.Equals(leftVar) &&
                !rightAdd.MutateInPlace
            ) {
                var replacement = new JSPointerAddExpression(
                    leftVar, rightAdd.Delta, true
                );

                ParentNode.ReplaceChild(boe, replacement);
                VisitReplacement(replacement);
                return;
            } else {
                VisitChildren(boe);
            }
        }