/// <inheritdoc /> public override void VisitUndefinedValue(UndefinedValue value) { // When comparing, both operands are converted to boolean switch (operation) { case Operations.BitOr: case Operations.BitXor: case Operations.ShiftLeft: case Operations.ShiftRight: IntervalValue <int> convertedValue; if (TypeConversion.TryConvertToIntegerInterval(OutSet, leftOperand, out convertedValue)) { result = convertedValue; } else { result = OutSet.AnyIntegerValue; } break; case Operations.Mul: result = OutSet.CreateDouble(0.0); break; default: base.VisitUndefinedValue(value); break; } }
/// <inheritdoc /> public override void VisitLongintValue(LongintValue value) { if (isIncrement) { if (value.Value < long.MaxValue) { result = OutSet.CreateLong(value.Value + 1); } else { result = OutSet.CreateDouble(TypeConversion.ToFloat(value.Value) + 1.0); } } else { if (value.Value > long.MinValue) { result = OutSet.CreateLong(value.Value - 1); } else { result = OutSet.CreateDouble(TypeConversion.ToFloat(value.Value) - 1.0); } } }
/// <inheritdoc /> public override void VisitUndefinedValue(UndefinedValue value) { switch (operation) { case Operations.Add: case Operations.Sub: result = OutSet.AnyFloatValue; break; case Operations.Mul: result = OutSet.CreateDouble(0.0); break; case Operations.BitOr: case Operations.BitXor: case Operations.ShiftLeft: case Operations.ShiftRight: result = OutSet.AnyIntegerValue; break; default: base.VisitUndefinedValue(value); break; } }
/// <inheritdoc /> public override void VisitIntegerValue(IntegerValue value) { if (isIncrement) { if (value.Value < int.MaxValue) { result = OutSet.CreateInt(value.Value + 1); } else { result = OutSet.CreateDouble(TypeConversion.ToFloat(value.Value) + 1.0); } } else { if (value.Value > int.MinValue) { result = OutSet.CreateInt(value.Value - 1); } else { result = OutSet.CreateDouble(TypeConversion.ToFloat(value.Value) - 1.0); } } }
/// <inheritdoc /> public override void VisitUndefinedValue(UndefinedValue value) { int integerValue; double floatValue; bool isInteger; switch (operation) { case Operations.Or: case Operations.Xor: result = TypeConversion.ToBoolean(OutSet, leftOperand); break; case Operations.Add: case Operations.Sub: TypeConversion.TryConvertToNumber(leftOperand.Value, true, out integerValue, out floatValue, out isInteger); if (isInteger) { result = OutSet.CreateInt(integerValue); } else { result = OutSet.CreateDouble(floatValue); } break; case Operations.Mul: TypeConversion.TryConvertToNumber(leftOperand.Value, true, out integerValue, out floatValue, out isInteger); if (isInteger) { result = OutSet.CreateInt(0); } else { result = OutSet.CreateDouble(0.0); } break; case Operations.BitOr: case Operations.BitXor: case Operations.ShiftLeft: case Operations.ShiftRight: result = TypeConversion.ToInteger(OutSet, leftOperand); break; default: result = Comparison.Compare(OutSet, operation, leftOperand.Value, string.Empty); if (result != null) { break; } base.VisitUndefinedValue(value); break; } }
/// <inheritdoc /> public override void VisitFloatValue(FloatValue value) { if (isIncrement) { result = OutSet.CreateDouble(value.Value + 1.0); } else { result = OutSet.CreateDouble(value.Value - 1.0); } }
/// <inheritdoc /> public override void VisitIntervalFloatValue(FloatIntervalValue value) { if (value.Start == value.End) { VisitFloatValue(OutSet.CreateDouble(value.Start)); return; } IntervalValue <int> integerInterval; switch (operation) { case Operations.Minus: result = OutSet.CreateFloatInterval(-value.End, -value.Start); break; case Operations.BitNegation: if (TypeConversion.TryConvertToIntegerInterval(OutSet, value, out integerInterval)) { result = OutSet.CreateIntegerInterval(~integerInterval.End, ~integerInterval.Start); } else { result = OutSet.AnyIntegerValue; } break; case Operations.Int32Cast: if (TypeConversion.TryConvertToIntegerInterval(OutSet, value, out integerInterval)) { result = integerInterval; } else { result = OutSet.AnyIntegerValue; } break; case Operations.FloatCast: case Operations.DoubleCast: result = value; break; default: base.VisitIntervalFloatValue(value); break; } }
/// <inheritdoc /> public override void VisitLongintValue(LongintValue value) { switch (operation) { case Operations.Plus: result = value; break; case Operations.Minus: // Result of arithmetic negation can overflow if ((value.Value == 0) || ((-value.Value) != 0)) { result = OutSet.CreateLong(-value.Value); } else { // <seealso cref="UnaryOperationEvaluator.VisitIntegerValue" /> result = OutSet.CreateDouble(-(TypeConversion.ToFloat(value.Value))); } break; case Operations.BitNegation: result = OutSet.CreateLong(~value.Value); break; case Operations.Int32Cast: IntegerValue convertedValue; if (TypeConversion.TryConvertToInteger(OutSet, value, out convertedValue)) { result = convertedValue; } else { result = OutSet.AnyIntegerValue; } break; case Operations.FloatCast: case Operations.DoubleCast: result = TypeConversion.ToFloat(Snapshot, value); break; default: base.VisitLongintValue(value); break; } }
/// <inheritdoc /> public override void VisitFloatValue(FloatValue value) { switch (operation) { case Operations.Plus: result = value; break; case Operations.Minus: result = OutSet.CreateDouble(-value.Value); break; case Operations.BitNegation: int nativeIntegerValue; if (TypeConversion.TryConvertToInteger(value.Value, out nativeIntegerValue)) { result = OutSet.CreateInt(~nativeIntegerValue); } else { result = OutSet.AnyIntegerValue; } break; case Operations.Int32Cast: IntegerValue integerValue; if (TypeConversion.TryConvertToInteger(OutSet, value, out integerValue)) { result = integerValue; } else { result = OutSet.AnyIntegerValue; } break; case Operations.FloatCast: case Operations.DoubleCast: result = value; break; default: base.VisitFloatValue(value); break; } }
/// <inheritdoc /> public override void VisitIntegerValue(IntegerValue value) { switch (operation) { case Operations.Plus: result = value; break; case Operations.Minus: // Result of arithmetic negation can overflow if ((value.Value == 0) || ((-value.Value) != 0)) { result = OutSet.CreateInt(-value.Value); } else { // If the number has the lowest value (the most important bit is 1, others are 0 // in binary), arithmetic negation of it is zero. PHP behaves differently. // It converts the number to the same positive value, but that cause overflow. // Then integer value is converted to appropriate float value result = OutSet.CreateDouble(-TypeConversion.ToFloat(value.Value)); } break; case Operations.BitNegation: result = OutSet.CreateInt(~value.Value); break; case Operations.Int32Cast: result = value; break; case Operations.FloatCast: case Operations.DoubleCast: result = OutSet.CreateDouble(value.Value); break; default: base.VisitIntegerValue(value); break; } }
/// <inheritdoc /> public override void VisitUndefinedValue(UndefinedValue value) { // When comparing, both operands are converted to boolean switch (operation) { case Operations.Equal: case Operations.LessThanOrEqual: result = OutSet.CreateBool(!TypeConversion.ToBoolean(leftOperand.Value)); break; case Operations.NotEqual: case Operations.GreaterThan: case Operations.Or: case Operations.Xor: result = TypeConversion.ToBoolean(OutSet, leftOperand); break; case Operations.Mul: result = OutSet.CreateDouble(0.0); break; case Operations.BitOr: case Operations.BitXor: case Operations.ShiftLeft: case Operations.ShiftRight: int leftInteger; if (TypeConversion.TryConvertToInteger(leftOperand.Value, out leftInteger)) { result = OutSet.CreateInt(leftInteger); } else { result = OutSet.AnyIntegerValue; } break; default: base.VisitUndefinedValue(value); break; } }
/// <inheritdoc /> public override void VisitUndefinedValue(UndefinedValue value) { // When comparing, both operands are converted to boolean switch (operation) { case Operations.BitOr: case Operations.BitXor: case Operations.ShiftLeft: case Operations.ShiftRight: result = OutSet.AnyIntegerValue; break; case Operations.Mul: result = OutSet.CreateDouble(0.0); break; default: base.VisitUndefinedValue(value); break; } }
/// <inheritdoc /> public override void VisitFloatValue(FloatValue value) { // When comparing, both operands are converted to boolean switch (operation) { case Operations.Equal: case Operations.GreaterThanOrEqual: result = OutSet.CreateBool(!TypeConversion.ToBoolean(value.Value)); break; case Operations.NotEqual: case Operations.LessThan: case Operations.Or: case Operations.Xor: result = TypeConversion.ToBoolean(OutSet, value); break; case Operations.Add: result = OutSet.CreateDouble(value.Value); break; case Operations.Sub: result = OutSet.CreateDouble(-value.Value); break; case Operations.Mul: result = OutSet.CreateDouble(0.0); break; case Operations.BitOr: case Operations.BitXor: int rightInteger; if (TypeConversion.TryConvertToInteger(value.Value, out rightInteger)) { result = OutSet.CreateInt(rightInteger); } else { result = OutSet.AnyIntegerValue; } break; case Operations.Div: if (value.Value != 0.0) { // 0 (null) divided or modulo by anything is always 0 result = OutSet.CreateDouble(0.0); } else { SetWarning("Division by floating-point zero", AnalysisWarningCause.DIVISION_BY_ZERO); // Division by floating-point zero does not return NaN // or infinite, but false boolean value result = OutSet.CreateBool(false); } break; case Operations.Mod: result = ModuloOperation.Modulo(flow, TypeConversion.ToInteger(leftOperand), value.Value); break; default: base.VisitFloatValue(value); break; } }
/// <summary> /// Create double representation of given literal /// </summary> /// <param name="x">Literal value</param> /// <returns>Created literal value representation</returns> public virtual MemoryEntry DoubleLiteral(DoubleLiteral x) { return(new MemoryEntry(OutSet.CreateDouble((double)x.Value))); }
/// <inheritdoc /> public override void VisitStringValue(StringValue value) { int integerValue; double floatValue; bool isInteger; switch (operation) { case Operations.Plus: TypeConversion.TryConvertToNumber(value.Value, true, out integerValue, out floatValue, out isInteger); if (isInteger) { result = OutSet.CreateInt(integerValue); } else { result = OutSet.CreateDouble(floatValue); } break; case Operations.Minus: TypeConversion.TryConvertToNumber(value.Value, true, out integerValue, out floatValue, out isInteger); if (isInteger) { if ((integerValue == 0) || ((-integerValue) != 0)) { result = OutSet.CreateInt(-integerValue); } else { // <seealso cref="UnaryOperationEvaluator.VisitIntegerValue" /> result = OutSet.CreateDouble(-TypeConversion.ToFloat(integerValue)); } } else { result = OutSet.CreateDouble(floatValue); } break; case Operations.LogicNegation: result = OutSet.CreateBool(!TypeConversion.ToBoolean(value.Value)); break; case Operations.BitNegation: // Bit negation is defined for every character, not for the entire string // TODO: Implement. PHP string is stored as array of bytes, but printed in UTF8 encoding result = OutSet.AnyStringValue; break; case Operations.Int32Cast: result = TypeConversion.ToInteger(OutSet, value); break; case Operations.FloatCast: case Operations.DoubleCast: result = TypeConversion.ToFloat(Snapshot, value); break; default: base.VisitStringValue(value); break; } }
/// <inheritdoc /> public override void VisitIntegerValue(IntegerValue value) { // When comparing, both operands are converted to boolean switch (operation) { case Operations.Equal: case Operations.GreaterThanOrEqual: result = OutSet.CreateBool(!TypeConversion.ToBoolean(value.Value)); break; case Operations.NotEqual: case Operations.LessThan: case Operations.Or: case Operations.Xor: result = TypeConversion.ToBoolean(OutSet, value); break; case Operations.Add: case Operations.BitOr: case Operations.BitXor: result = value; break; case Operations.Sub: // Result of subtraction can overflow if ((value.Value == 0) || ((-value.Value) != 0)) { result = OutSet.CreateInt(-value.Value); } else { // <seealso cref="UnaryOperationEvaluator.VisitIntegerValue" /> result = OutSet.CreateDouble(-(TypeConversion.ToFloat(value.Value))); } break; case Operations.Mul: result = OutSet.CreateInt(0); break; case Operations.Div: case Operations.Mod: if (value.Value != 0) { // 0 (null) divided or modulo by anything is always 0 result = OutSet.CreateInt(0); } else { SetWarning("Division by zero", AnalysisWarningCause.DIVISION_BY_ZERO); // Division or modulo by zero returns false boolean value result = OutSet.CreateBool(false); } break; default: base.VisitIntegerValue(value); break; } }
/// <inheritdoc /> public override void VisitAnyValue(AnyValue value) { switch (operation) { case Operations.Equal: case Operations.NotEqual: case Operations.GreaterThanOrEqual: case Operations.LessThan: case Operations.Or: case Operations.Xor: result = OutSet.AnyBooleanValue; break; case Operations.Add: case Operations.Sub: // Ommitted warning message that object cannot be converted to integer // Ommitted error report that array is unsupported operand in arithmetic operation result = OutSet.AnyFloatValue; break; case Operations.Mul: // Ommitted warning message that object cannot be converted to integer // Ommitted error report that array is unsupported operand in arithmetic operation result = OutSet.CreateDouble(0.0); break; case Operations.Div: // Ommitted warning message that object cannot be converted to integer // Ommitted warning message of division by zero // Ommitted error report that array is unsupported operand in arithmetic operation result = OutSet.AnyValue; break; case Operations.BitAnd: case Operations.ShiftLeft: case Operations.ShiftRight: // Ommitted warning message that object cannot be converted to integer result = OutSet.CreateInt(0); break; case Operations.BitOr: case Operations.BitXor: // Ommitted warning message that object cannot be converted to integer result = OutSet.AnyIntegerValue; break; case Operations.Mod: // Ommitted warning message that object cannot be converted to integer result = ModuloOperation.AbstractModulo(flow); break; default: if (PerformCommonAnyOperandOperations()) { break; } base.VisitAnyValue(value); break; } }
/// <inheritdoc /> public override void VisitUndefinedValue(UndefinedValue value) { switch (operation) { case Operations.Equal: case Operations.NotEqual: case Operations.GreaterThan: case Operations.LessThanOrEqual: result = OutSet.AnyBooleanValue; break; case Operations.GreaterThanOrEqual: result = OutSet.CreateBool(true); break; case Operations.LessThan: result = OutSet.CreateBool(false); break; case Operations.Add: case Operations.Sub: // Ommitted warning message that object cannot be converted to integer // Ommitted error report that array is unsupported operand in arithmetic operation result = OutSet.AnyFloatValue; break; case Operations.Mul: // Ommitted warning message that object cannot be converted to integer // Ommitted error report that array is unsupported operand in arithmetic operation result = OutSet.CreateDouble(0.0); break; case Operations.Div: // Ommitted warning message that object cannot be converted to integer // Ommitted warning message of division by zero // Ommitted error report that array is unsupported operand in arithmetic operation result = OutSet.AnyValue; break; case Operations.Mod: // Ommitted warning message that object cannot be converted to integer result = ModuloOperation.ModuloByNull(flow); break; case Operations.BitAnd: // Ommitted warning message that object cannot be converted to integer result = OutSet.CreateInt(0); break; case Operations.BitOr: case Operations.BitXor: case Operations.ShiftLeft: case Operations.ShiftRight: // Ommitted warning message that object cannot be converted to integer result = OutSet.AnyIntegerValue; break; default: result = LogicalOperation.AbstractLogical(OutSet, operation, TypeConversion.ToBoolean(value)); if (result != null) { break; } base.VisitUndefinedValue(value); break; } }