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); } }
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); } }