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