diff options
author | Lorry Tar Creator <lorry-tar-importer@baserock.org> | 2013-12-11 22:24:18 +0000 |
---|---|---|
committer | <> | 2014-07-24 09:30:59 +0000 |
commit | 59e2936f588aa945e8dcd6c737523c299067e9d0 (patch) | |
tree | 97e74980cc54baa19de5faa11f5a50a0121a48ea /mfbt/decimal | |
download | mozjs24-master.tar.gz |
Imported from /home/lorry/working-area/delta_mozilla_mozjs24/mozjs-24.2.0.tar.bz2.HEADmozjs-24.2.0master
Diffstat (limited to 'mfbt/decimal')
-rw-r--r-- | mfbt/decimal/Decimal.cpp | 1054 | ||||
-rw-r--r-- | mfbt/decimal/Decimal.h | 213 | ||||
-rw-r--r-- | mfbt/decimal/LICENSE-APPLE | 21 | ||||
-rw-r--r-- | mfbt/decimal/LICENSE-LGPL-2 | 481 | ||||
-rw-r--r-- | mfbt/decimal/LICENSE-LGPL-2.1 | 502 | ||||
-rw-r--r-- | mfbt/decimal/comparison-with-nan.patch | 67 | ||||
-rw-r--r-- | mfbt/decimal/floor-ceiling.patch | 89 | ||||
-rw-r--r-- | mfbt/decimal/mfbt-abi-markers.patch | 150 | ||||
-rw-r--r-- | mfbt/decimal/moz-decimal-utils.h | 109 | ||||
-rw-r--r-- | mfbt/decimal/to-moz-dependencies.patch | 333 | ||||
-rwxr-xr-x | mfbt/decimal/update.sh | 66 | ||||
-rw-r--r-- | mfbt/decimal/zero-serialization.patch | 22 |
12 files changed, 3107 insertions, 0 deletions
diff --git a/mfbt/decimal/Decimal.cpp b/mfbt/decimal/Decimal.cpp new file mode 100644 index 0000000..de10f83 --- /dev/null +++ b/mfbt/decimal/Decimal.cpp @@ -0,0 +1,1054 @@ +/* + * Copyright (C) 2012 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "Decimal.h" +#include "moz-decimal-utils.h" + +#include <algorithm> +#include <float.h> + +namespace WebCore { + +namespace DecimalPrivate { + +static int const ExponentMax = 1023; +static int const ExponentMin = -1023; +static int const Precision = 18; + +static const uint64_t MaxCoefficient = UINT64_C(0x16345785D89FFFF); // 999999999999999999 == 18 9's + +// This class handles Decimal special values. +class SpecialValueHandler { + WTF_MAKE_NONCOPYABLE(SpecialValueHandler); +public: + enum HandleResult { + BothFinite, + BothInfinity, + EitherNaN, + LHSIsInfinity, + RHSIsInfinity, + }; + + SpecialValueHandler(const Decimal& lhs, const Decimal& rhs); + HandleResult handle(); + Decimal value() const; + +private: + enum Result { + ResultIsLHS, + ResultIsRHS, + ResultIsUnknown, + }; + + const Decimal& m_lhs; + const Decimal& m_rhs; + Result m_result; +}; + +SpecialValueHandler::SpecialValueHandler(const Decimal& lhs, const Decimal& rhs) + : m_lhs(lhs), m_rhs(rhs), m_result(ResultIsUnknown) +{ +} + +SpecialValueHandler::HandleResult SpecialValueHandler::handle() +{ + if (m_lhs.isFinite() && m_rhs.isFinite()) + return BothFinite; + + const Decimal::EncodedData::FormatClass lhsClass = m_lhs.value().formatClass(); + const Decimal::EncodedData::FormatClass rhsClass = m_rhs.value().formatClass(); + if (lhsClass == Decimal::EncodedData::ClassNaN) { + m_result = ResultIsLHS; + return EitherNaN; + } + + if (rhsClass == Decimal::EncodedData::ClassNaN) { + m_result = ResultIsRHS; + return EitherNaN; + } + + if (lhsClass == Decimal::EncodedData::ClassInfinity) + return rhsClass == Decimal::EncodedData::ClassInfinity ? BothInfinity : LHSIsInfinity; + + if (rhsClass == Decimal::EncodedData::ClassInfinity) + return RHSIsInfinity; + + ASSERT_NOT_REACHED(); + return BothFinite; +} + +Decimal SpecialValueHandler::value() const +{ + switch (m_result) { + case ResultIsLHS: + return m_lhs; + case ResultIsRHS: + return m_rhs; + case ResultIsUnknown: + default: + ASSERT_NOT_REACHED(); + return m_lhs; + } +} + +// This class is used for 128 bit unsigned integer arithmetic. +class UInt128 { +public: + UInt128(uint64_t low, uint64_t high) + : m_high(high), m_low(low) + { + } + + UInt128& operator/=(uint32_t); + + uint64_t high() const { return m_high; } + uint64_t low() const { return m_low; } + + static UInt128 multiply(uint64_t u, uint64_t v) { return UInt128(u * v, multiplyHigh(u, v)); } + +private: + static uint32_t highUInt32(uint64_t x) { return static_cast<uint32_t>(x >> 32); } + static uint32_t lowUInt32(uint64_t x) { return static_cast<uint32_t>(x & ((static_cast<uint64_t>(1) << 32) - 1)); } + bool isZero() const { return !m_low && !m_high; } + static uint64_t makeUInt64(uint32_t low, uint32_t high) { return low | (static_cast<uint64_t>(high) << 32); } + + static uint64_t multiplyHigh(uint64_t, uint64_t); + + uint64_t m_high; + uint64_t m_low; +}; + +UInt128& UInt128::operator/=(const uint32_t divisor) +{ + ASSERT(divisor); + + if (!m_high) { + m_low /= divisor; + return *this; + } + + uint32_t dividend[4]; + dividend[0] = lowUInt32(m_low); + dividend[1] = highUInt32(m_low); + dividend[2] = lowUInt32(m_high); + dividend[3] = highUInt32(m_high); + + uint32_t quotient[4]; + uint32_t remainder = 0; + for (int i = 3; i >= 0; --i) { + const uint64_t work = makeUInt64(dividend[i], remainder); + remainder = static_cast<uint32_t>(work % divisor); + quotient[i] = static_cast<uint32_t>(work / divisor); + } + m_low = makeUInt64(quotient[0], quotient[1]); + m_high = makeUInt64(quotient[2], quotient[3]); + return *this; +} + +// Returns high 64bit of 128bit product. +uint64_t UInt128::multiplyHigh(uint64_t u, uint64_t v) +{ + const uint64_t uLow = lowUInt32(u); + const uint64_t uHigh = highUInt32(u); + const uint64_t vLow = lowUInt32(v); + const uint64_t vHigh = highUInt32(v); + const uint64_t partialProduct = uHigh * vLow + highUInt32(uLow * vLow); + return uHigh * vHigh + highUInt32(partialProduct) + highUInt32(uLow * vHigh + lowUInt32(partialProduct)); +} + +static int countDigits(uint64_t x) +{ + int numberOfDigits = 0; + for (uint64_t powerOfTen = 1; x >= powerOfTen; powerOfTen *= 10) { + ++numberOfDigits; + if (powerOfTen >= std::numeric_limits<uint64_t>::max() / 10) + break; + } + return numberOfDigits; +} + +static uint64_t scaleDown(uint64_t x, int n) +{ + ASSERT(n >= 0); + while (n > 0 && x) { + x /= 10; + --n; + } + return x; +} + +static uint64_t scaleUp(uint64_t x, int n) +{ + ASSERT(n >= 0); + ASSERT(n < Precision); + + uint64_t y = 1; + uint64_t z = 10; + for (;;) { + if (n & 1) + y = y * z; + + n >>= 1; + if (!n) + return x * y; + + z = z * z; + } +} + +} // namespace DecimalPrivate + +using namespace DecimalPrivate; + +Decimal::EncodedData::EncodedData(Sign sign, FormatClass formatClass) + : m_coefficient(0) + , m_exponent(0) + , m_formatClass(formatClass) + , m_sign(sign) +{ +} + +Decimal::EncodedData::EncodedData(Sign sign, int exponent, uint64_t coefficient) + : m_formatClass(coefficient ? ClassNormal : ClassZero) + , m_sign(sign) +{ + if (exponent >= ExponentMin && exponent <= ExponentMax) { + while (coefficient > MaxCoefficient) { + coefficient /= 10; + ++exponent; + } + } + + if (exponent > ExponentMax) { + m_coefficient = 0; + m_exponent = 0; + m_formatClass = ClassInfinity; + return; + } + + if (exponent < ExponentMin) { + m_coefficient = 0; + m_exponent = 0; + m_formatClass = ClassZero; + return; + } + + m_coefficient = coefficient; + m_exponent = static_cast<int16_t>(exponent); +} + +bool Decimal::EncodedData::operator==(const EncodedData& another) const +{ + return m_sign == another.m_sign + && m_formatClass == another.m_formatClass + && m_exponent == another.m_exponent + && m_coefficient == another.m_coefficient; +} + +Decimal::Decimal(int32_t i32) + : m_data(i32 < 0 ? Negative : Positive, 0, i32 < 0 ? static_cast<uint64_t>(-static_cast<int64_t>(i32)) : static_cast<uint64_t>(i32)) +{ +} + +Decimal::Decimal(Sign sign, int exponent, uint64_t coefficient) + : m_data(sign, coefficient ? exponent : 0, coefficient) +{ +} + +Decimal::Decimal(const EncodedData& data) + : m_data(data) +{ +} + +Decimal::Decimal(const Decimal& other) + : m_data(other.m_data) +{ +} + +Decimal& Decimal::operator=(const Decimal& other) +{ + m_data = other.m_data; + return *this; +} + +Decimal& Decimal::operator+=(const Decimal& other) +{ + m_data = (*this + other).m_data; + return *this; +} + +Decimal& Decimal::operator-=(const Decimal& other) +{ + m_data = (*this - other).m_data; + return *this; +} + +Decimal& Decimal::operator*=(const Decimal& other) +{ + m_data = (*this * other).m_data; + return *this; +} + +Decimal& Decimal::operator/=(const Decimal& other) +{ + m_data = (*this / other).m_data; + return *this; +} + +Decimal Decimal::operator-() const +{ + if (isNaN()) + return *this; + + Decimal result(*this); + result.m_data.setSign(invertSign(m_data.sign())); + return result; +} + +Decimal Decimal::operator+(const Decimal& rhs) const +{ + const Decimal& lhs = *this; + const Sign lhsSign = lhs.sign(); + const Sign rhsSign = rhs.sign(); + + SpecialValueHandler handler(lhs, rhs); + switch (handler.handle()) { + case SpecialValueHandler::BothFinite: + break; + + case SpecialValueHandler::BothInfinity: + return lhsSign == rhsSign ? lhs : nan(); + + case SpecialValueHandler::EitherNaN: + return handler.value(); + + case SpecialValueHandler::LHSIsInfinity: + return lhs; + + case SpecialValueHandler::RHSIsInfinity: + return rhs; + } + + const AlignedOperands alignedOperands = alignOperands(lhs, rhs); + + const uint64_t result = lhsSign == rhsSign + ? alignedOperands.lhsCoefficient + alignedOperands.rhsCoefficient + : alignedOperands.lhsCoefficient - alignedOperands.rhsCoefficient; + + if (lhsSign == Negative && rhsSign == Positive && !result) + return Decimal(Positive, alignedOperands.exponent, 0); + + return static_cast<int64_t>(result) >= 0 + ? Decimal(lhsSign, alignedOperands.exponent, result) + : Decimal(invertSign(lhsSign), alignedOperands.exponent, -static_cast<int64_t>(result)); +} + +Decimal Decimal::operator-(const Decimal& rhs) const +{ + const Decimal& lhs = *this; + const Sign lhsSign = lhs.sign(); + const Sign rhsSign = rhs.sign(); + + SpecialValueHandler handler(lhs, rhs); + switch (handler.handle()) { + case SpecialValueHandler::BothFinite: + break; + + case SpecialValueHandler::BothInfinity: + return lhsSign == rhsSign ? nan() : lhs; + + case SpecialValueHandler::EitherNaN: + return handler.value(); + + case SpecialValueHandler::LHSIsInfinity: + return lhs; + + case SpecialValueHandler::RHSIsInfinity: + return infinity(invertSign(rhsSign)); + } + + const AlignedOperands alignedOperands = alignOperands(lhs, rhs); + + const uint64_t result = lhsSign == rhsSign + ? alignedOperands.lhsCoefficient - alignedOperands.rhsCoefficient + : alignedOperands.lhsCoefficient + alignedOperands.rhsCoefficient; + + if (lhsSign == Negative && rhsSign == Negative && !result) + return Decimal(Positive, alignedOperands.exponent, 0); + + return static_cast<int64_t>(result) >= 0 + ? Decimal(lhsSign, alignedOperands.exponent, result) + : Decimal(invertSign(lhsSign), alignedOperands.exponent, -static_cast<int64_t>(result)); +} + +Decimal Decimal::operator*(const Decimal& rhs) const +{ + const Decimal& lhs = *this; + const Sign lhsSign = lhs.sign(); + const Sign rhsSign = rhs.sign(); + const Sign resultSign = lhsSign == rhsSign ? Positive : Negative; + + SpecialValueHandler handler(lhs, rhs); + switch (handler.handle()) { + case SpecialValueHandler::BothFinite: { + const uint64_t lhsCoefficient = lhs.m_data.coefficient(); + const uint64_t rhsCoefficient = rhs.m_data.coefficient(); + int resultExponent = lhs.exponent() + rhs.exponent(); + UInt128 work(UInt128::multiply(lhsCoefficient, rhsCoefficient)); + while (work.high()) { + work /= 10; + ++resultExponent; + } + return Decimal(resultSign, resultExponent, work.low()); + } + + case SpecialValueHandler::BothInfinity: + return infinity(resultSign); + + case SpecialValueHandler::EitherNaN: + return handler.value(); + + case SpecialValueHandler::LHSIsInfinity: + return rhs.isZero() ? nan() : infinity(resultSign); + + case SpecialValueHandler::RHSIsInfinity: + return lhs.isZero() ? nan() : infinity(resultSign); + } + + ASSERT_NOT_REACHED(); + return nan(); +} + +Decimal Decimal::operator/(const Decimal& rhs) const +{ + const Decimal& lhs = *this; + const Sign lhsSign = lhs.sign(); + const Sign rhsSign = rhs.sign(); + const Sign resultSign = lhsSign == rhsSign ? Positive : Negative; + + SpecialValueHandler handler(lhs, rhs); + switch (handler.handle()) { + case SpecialValueHandler::BothFinite: + break; + + case SpecialValueHandler::BothInfinity: + return nan(); + + case SpecialValueHandler::EitherNaN: + return handler.value(); + + case SpecialValueHandler::LHSIsInfinity: + return infinity(resultSign); + + case SpecialValueHandler::RHSIsInfinity: + return zero(resultSign); + } + + ASSERT(lhs.isFinite()); + ASSERT(rhs.isFinite()); + + if (rhs.isZero()) + return lhs.isZero() ? nan() : infinity(resultSign); + + int resultExponent = lhs.exponent() - rhs.exponent(); + + if (lhs.isZero()) + return Decimal(resultSign, resultExponent, 0); + + uint64_t remainder = lhs.m_data.coefficient(); + const uint64_t divisor = rhs.m_data.coefficient(); + uint64_t result = 0; + while (result < MaxCoefficient / 100) { + while (remainder < divisor) { + remainder *= 10; + result *= 10; + --resultExponent; + } + result += remainder / divisor; + remainder %= divisor; + if (!remainder) + break; + } + + if (remainder > divisor / 2) + ++result; + + return Decimal(resultSign, resultExponent, result); +} + +bool Decimal::operator==(const Decimal& rhs) const +{ + if (isNaN() || rhs.isNaN()) + return false; + return m_data == rhs.m_data || compareTo(rhs).isZero(); +} + +bool Decimal::operator!=(const Decimal& rhs) const +{ + if (isNaN() || rhs.isNaN()) + return true; + if (m_data == rhs.m_data) + return false; + const Decimal result = compareTo(rhs); + if (result.isNaN()) + return false; + return !result.isZero(); +} + +bool Decimal::operator<(const Decimal& rhs) const +{ + const Decimal result = compareTo(rhs); + if (result.isNaN()) + return false; + return !result.isZero() && result.isNegative(); +} + +bool Decimal::operator<=(const Decimal& rhs) const +{ + if (isNaN() || rhs.isNaN()) + return false; + if (m_data == rhs.m_data) + return true; + const Decimal result = compareTo(rhs); + if (result.isNaN()) + return false; + return result.isZero() || result.isNegative(); +} + +bool Decimal::operator>(const Decimal& rhs) const +{ + const Decimal result = compareTo(rhs); + if (result.isNaN()) + return false; + return !result.isZero() && result.isPositive(); +} + +bool Decimal::operator>=(const Decimal& rhs) const +{ + if (isNaN() || rhs.isNaN()) + return false; + if (m_data == rhs.m_data) + return true; + const Decimal result = compareTo(rhs); + if (result.isNaN()) + return false; + return result.isZero() || !result.isNegative(); +} + +Decimal Decimal::abs() const +{ + Decimal result(*this); + result.m_data.setSign(Positive); + return result; +} + +Decimal::AlignedOperands Decimal::alignOperands(const Decimal& lhs, const Decimal& rhs) +{ + ASSERT(lhs.isFinite()); + ASSERT(rhs.isFinite()); + + const int lhsExponent = lhs.exponent(); + const int rhsExponent = rhs.exponent(); + int exponent = std::min(lhsExponent, rhsExponent); + uint64_t lhsCoefficient = lhs.m_data.coefficient(); + uint64_t rhsCoefficient = rhs.m_data.coefficient(); + + if (lhsExponent > rhsExponent) { + const int numberOfLHSDigits = countDigits(lhsCoefficient); + if (numberOfLHSDigits) { + const int lhsShiftAmount = lhsExponent - rhsExponent; + const int overflow = numberOfLHSDigits + lhsShiftAmount - Precision; + if (overflow <= 0) + lhsCoefficient = scaleUp(lhsCoefficient, lhsShiftAmount); + else { + lhsCoefficient = scaleUp(lhsCoefficient, lhsShiftAmount - overflow); + rhsCoefficient = scaleDown(rhsCoefficient, overflow); + exponent += overflow; + } + } + + } else if (lhsExponent < rhsExponent) { + const int numberOfRHSDigits = countDigits(rhsCoefficient); + if (numberOfRHSDigits) { + const int rhsShiftAmount = rhsExponent - lhsExponent; + const int overflow = numberOfRHSDigits + rhsShiftAmount - Precision; + if (overflow <= 0) + rhsCoefficient = scaleUp(rhsCoefficient, rhsShiftAmount); + else { + rhsCoefficient = scaleUp(rhsCoefficient, rhsShiftAmount - overflow); + lhsCoefficient = scaleDown(lhsCoefficient, overflow); + exponent += overflow; + } + } + } + + AlignedOperands alignedOperands; + alignedOperands.exponent = exponent; + alignedOperands.lhsCoefficient = lhsCoefficient; + alignedOperands.rhsCoefficient = rhsCoefficient; + return alignedOperands; +} + +// Round toward positive infinity. +// Note: Mac ports defines ceil(x) as wtf_ceil(x), so we can't use name "ceil" here. +Decimal Decimal::ceiling() const +{ + if (isSpecial()) + return *this; + + if (exponent() >= 0) + return *this; + + uint64_t coefficient = m_data.coefficient(); + const int numberOfDigits = countDigits(coefficient); + const int numberOfDropDigits = -exponent(); + if (numberOfDigits < numberOfDropDigits) + return isPositive() ? Decimal(1) : zero(Positive); + + uint64_t result = scaleDown(coefficient, numberOfDropDigits); + uint64_t droppedDigits = coefficient - scaleUp(result, numberOfDropDigits); + if (droppedDigits && isPositive()) + result += 1; + return Decimal(sign(), 0, result); +} + +Decimal Decimal::compareTo(const Decimal& rhs) const +{ + const Decimal result(*this - rhs); + switch (result.m_data.formatClass()) { + case EncodedData::ClassInfinity: + return result.isNegative() ? Decimal(-1) : Decimal(1); + + case EncodedData::ClassNaN: + case EncodedData::ClassNormal: + return result; + + case EncodedData::ClassZero: + return zero(Positive); + + default: + ASSERT_NOT_REACHED(); + return nan(); + } +} + +// Round toward negative infinity. +Decimal Decimal::floor() const +{ + if (isSpecial()) + return *this; + + if (exponent() >= 0) + return *this; + + uint64_t coefficient = m_data.coefficient(); + const int numberOfDigits = countDigits(coefficient); + const int numberOfDropDigits = -exponent(); + if (numberOfDigits < numberOfDropDigits) + return isPositive() ? zero(Positive) : Decimal(-1); + + uint64_t result = scaleDown(coefficient, numberOfDropDigits); + uint64_t droppedDigits = coefficient - scaleUp(result, numberOfDropDigits); + if (droppedDigits && isNegative()) { + result += 1; + } + return Decimal(sign(), 0, result); +} + +Decimal Decimal::fromDouble(double doubleValue) +{ + if (std::isfinite(doubleValue)) + return fromString(mozToString(doubleValue)); + + if (std::isinf(doubleValue)) + return infinity(doubleValue < 0 ? Negative : Positive); + + return nan(); +} + +Decimal Decimal::fromString(const String& str) +{ + int exponent = 0; + Sign exponentSign = Positive; + int numberOfDigits = 0; + int numberOfDigitsAfterDot = 0; + int numberOfExtraDigits = 0; + Sign sign = Positive; + + enum { + StateDigit, + StateDot, + StateDotDigit, + StateE, + StateEDigit, + StateESign, + StateSign, + StateStart, + StateZero, + } state = StateStart; + +#define HandleCharAndBreak(expected, nextState) \ + if (ch == expected) { \ + state = nextState; \ + break; \ + } + +#define HandleTwoCharsAndBreak(expected1, expected2, nextState) \ + if (ch == expected1 || ch == expected2) { \ + state = nextState; \ + break; \ + } + + uint64_t accumulator = 0; + for (unsigned index = 0; index < str.length(); ++index) { + const int ch = str[index]; + switch (state) { + case StateDigit: + if (ch >= '0' && ch <= '9') { + if (numberOfDigits < Precision) { + ++numberOfDigits; + accumulator *= 10; + accumulator += ch - '0'; + } else + ++numberOfExtraDigits; + break; + } + + HandleCharAndBreak('.', StateDot); + HandleTwoCharsAndBreak('E', 'e', StateE); + return nan(); + + case StateDot: + if (ch >= '0' && ch <= '9') { + if (numberOfDigits < Precision) { + ++numberOfDigits; + ++numberOfDigitsAfterDot; + accumulator *= 10; + accumulator += ch - '0'; + } + state = StateDotDigit; + break; + } + + case StateDotDigit: + if (ch >= '0' && ch <= '9') { + if (numberOfDigits < Precision) { + ++numberOfDigits; + ++numberOfDigitsAfterDot; + accumulator *= 10; + accumulator += ch - '0'; + } + break; + } + + HandleTwoCharsAndBreak('E', 'e', StateE); + return nan(); + + case StateE: + if (ch == '+') { + exponentSign = Positive; + state = StateESign; + break; + } + + if (ch == '-') { + exponentSign = Negative; + state = StateESign; + break; + } + + if (ch >= '0' && ch <= '9') { + exponent = ch - '0'; + state = StateEDigit; + break; + } + + return nan(); + + case StateEDigit: + if (ch >= '0' && ch <= '9') { + exponent *= 10; + exponent += ch - '0'; + if (exponent > ExponentMax + Precision) { + if (accumulator) + return exponentSign == Negative ? zero(Positive) : infinity(sign); + return zero(sign); + } + state = StateEDigit; + break; + } + + return nan(); + + case StateESign: + if (ch >= '0' && ch <= '9') { + exponent = ch - '0'; + state = StateEDigit; + break; + } + + return nan(); + + case StateSign: + if (ch >= '1' && ch <= '9') { + accumulator = ch - '0'; + numberOfDigits = 1; + state = StateDigit; + break; + } + + HandleCharAndBreak('0', StateZero); + return nan(); + + case StateStart: + if (ch >= '1' && ch <= '9') { + accumulator = ch - '0'; + numberOfDigits = 1; + state = StateDigit; + break; + } + + if (ch == '-') { + sign = Negative; + state = StateSign; + break; + } + + if (ch == '+') { + sign = Positive; + state = StateSign; + break; + } + + HandleCharAndBreak('0', StateZero); + HandleCharAndBreak('.', StateDot); + return nan(); + + case StateZero: + if (ch == '0') + break; + + if (ch >= '1' && ch <= '9') { + accumulator = ch - '0'; + numberOfDigits = 1; + state = StateDigit; + break; + } + + HandleCharAndBreak('.', StateDot); + HandleTwoCharsAndBreak('E', 'e', StateE); + return nan(); + + default: + ASSERT_NOT_REACHED(); + return nan(); + } + } + + if (state == StateZero) + return zero(sign); + + if (state == StateDigit || state == StateEDigit || state == StateDotDigit) { + int resultExponent = exponent * (exponentSign == Negative ? -1 : 1) - numberOfDigitsAfterDot + numberOfExtraDigits; + if (resultExponent < ExponentMin) + return zero(Positive); + + const int overflow = resultExponent - ExponentMax + 1; + if (overflow > 0) { + if (overflow + numberOfDigits - numberOfDigitsAfterDot > Precision) + return infinity(sign); + accumulator = scaleUp(accumulator, overflow); + resultExponent -= overflow; + } + + return Decimal(sign, resultExponent, accumulator); + } + + return nan(); +} + +Decimal Decimal::infinity(const Sign sign) +{ + return Decimal(EncodedData(sign, EncodedData::ClassInfinity)); +} + +Decimal Decimal::nan() +{ + return Decimal(EncodedData(Positive, EncodedData::ClassNaN)); +} + +Decimal Decimal::remainder(const Decimal& rhs) const +{ + const Decimal quotient = *this / rhs; + return quotient.isSpecial() ? quotient : *this - (quotient.isNegative() ? quotient.ceiling() : quotient.floor()) * rhs; +} + +Decimal Decimal::round() const +{ + if (isSpecial()) + return *this; + + if (exponent() >= 0) + return *this; + + uint64_t result = m_data.coefficient(); + const int numberOfDigits = countDigits(result); + const int numberOfDropDigits = -exponent(); + if (numberOfDigits < numberOfDropDigits) + return zero(Positive); + + // We're implementing round-half-away-from-zero, so we only need the one + // (the most significant) fractional digit: + result = scaleDown(result, numberOfDropDigits - 1); + if (result % 10 >= 5) + result += 10; + result /= 10; + return Decimal(sign(), 0, result); +} + +double Decimal::toDouble() const +{ + if (isFinite()) { + bool valid; + const double doubleValue = mozToDouble(toString(), &valid); + return valid ? doubleValue : std::numeric_limits<double>::quiet_NaN(); + } + + if (isInfinity()) + return isNegative() ? -std::numeric_limits<double>::infinity() : std::numeric_limits<double>::infinity(); + + return std::numeric_limits<double>::quiet_NaN(); +} + +String Decimal::toString() const +{ + switch (m_data.formatClass()) { + case EncodedData::ClassInfinity: + return sign() ? "-Infinity" : "Infinity"; + + case EncodedData::ClassNaN: + return "NaN"; + + case EncodedData::ClassNormal: + case EncodedData::ClassZero: + break; + + default: + ASSERT_NOT_REACHED(); + return ""; + } + + StringBuilder builder; + if (sign()) + builder.append('-'); + + int originalExponent = exponent(); + uint64_t coefficient = m_data.coefficient(); + + if (originalExponent < 0) { + const int maxDigits = DBL_DIG; + uint64_t lastDigit = 0; + while (countDigits(coefficient) > maxDigits) { + lastDigit = coefficient % 10; + coefficient /= 10; + ++originalExponent; + } + + if (lastDigit >= 5) + ++coefficient; + + while (originalExponent < 0 && coefficient && !(coefficient % 10)) { + coefficient /= 10; + ++originalExponent; + } + } + + const String digits = mozToString(coefficient); + int coefficientLength = static_cast<int>(digits.length()); + const int adjustedExponent = originalExponent + coefficientLength - 1; + if (originalExponent <= 0 && adjustedExponent >= -6) { + if (!originalExponent) { + builder.append(digits); + return builder.toString(); + } + + if (adjustedExponent >= 0) { + for (int i = 0; i < coefficientLength; ++i) { + builder.append(digits[i]); + if (i == adjustedExponent) + builder.append('.'); + } + return builder.toString(); + } + + builder.appendLiteral("0."); + for (int i = adjustedExponent + 1; i < 0; ++i) + builder.append('0'); + + builder.append(digits); + + } else { + builder.append(digits[0]); + while (coefficientLength >= 2 && digits[coefficientLength - 1] == '0') + --coefficientLength; + if (coefficientLength >= 2) { + builder.append('.'); + for (int i = 1; i < coefficientLength; ++i) + builder.append(digits[i]); + } + + if (adjustedExponent) { + builder.append(adjustedExponent < 0 ? "e" : "e+"); + builder.appendNumber(adjustedExponent); + } + } + return builder.toString(); +} + +bool Decimal::toString(char* strBuf, size_t bufLength) const +{ + ASSERT(bufLength > 0); + String str = toString(); + size_t length = str.copy(strBuf, bufLength); + if (length < bufLength) { + strBuf[length] = '\0'; + return true; + } + strBuf[bufLength - 1] = '\0'; + return false; +} + +Decimal Decimal::zero(Sign sign) +{ + return Decimal(EncodedData(sign, EncodedData::ClassZero)); +} + +} // namespace WebCore + diff --git a/mfbt/decimal/Decimal.h b/mfbt/decimal/Decimal.h new file mode 100644 index 0000000..8032fd6 --- /dev/null +++ b/mfbt/decimal/Decimal.h @@ -0,0 +1,213 @@ +/* + * Copyright (C) 2012 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * Imported from: + * http://src.chromium.org/viewvc/blink/trunk/Source/core/platform/Decimal.h + * Check hg log for the svn rev of the last update from Blink core. + */ + +#ifndef Decimal_h +#define Decimal_h + +#include "mozilla/Assertions.h" +#include "mozilla/StandardInteger.h" +#include "mozilla/Types.h" + +#include <string> + +#ifndef ASSERT +#define DEFINED_ASSERT_FOR_DECIMAL_H 1 +#define ASSERT MOZ_ASSERT +#endif + +// To use WTF_MAKE_FAST_ALLOCATED we'd need: +// http://src.chromium.org/viewvc/blink/trunk/Source/wtf/FastMalloc.h +// Since we don't allocate Decimal objects, no need. +#define WTF_MAKE_FAST_ALLOCATED \ + void ignore_this_dummy_method() MOZ_DELETE + +namespace WebCore { + +namespace DecimalPrivate { +class SpecialValueHandler; +} + +// This class represents decimal base floating point number. +// +// FIXME: Once all C++ compiler support decimal type, we should replace this +// class to compiler supported one. See below URI for current status of decimal +// type for C++: // http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n1977.html +class Decimal { + WTF_MAKE_FAST_ALLOCATED; +public: + enum Sign { + Positive, + Negative, + }; + + // You should not use EncodedData other than unit testing. + class EncodedData { + // For accessing FormatClass. + friend class Decimal; + friend class DecimalPrivate::SpecialValueHandler; + public: + EncodedData(Sign, int exponent, uint64_t coefficient); + + bool operator==(const EncodedData&) const; + bool operator!=(const EncodedData& another) const { return !operator==(another); } + + uint64_t coefficient() const { return m_coefficient; } + int countDigits() const; + int exponent() const { return m_exponent; } + bool isFinite() const { return !isSpecial(); } + bool isInfinity() const { return m_formatClass == ClassInfinity; } + bool isNaN() const { return m_formatClass == ClassNaN; } + bool isSpecial() const { return m_formatClass == ClassInfinity || m_formatClass == ClassNaN; } + bool isZero() const { return m_formatClass == ClassZero; } + Sign sign() const { return m_sign; } + void setSign(Sign sign) { m_sign = sign; } + + private: + enum FormatClass { + ClassInfinity, + ClassNormal, + ClassNaN, + ClassZero, + }; + + EncodedData(Sign, FormatClass); + FormatClass formatClass() const { return m_formatClass; } + + uint64_t m_coefficient; + int16_t m_exponent; + FormatClass m_formatClass; + Sign m_sign; + }; + + MFBT_API Decimal(int32_t = 0); + MFBT_API Decimal(Sign, int exponent, uint64_t coefficient); + MFBT_API Decimal(const Decimal&); + + MFBT_API Decimal& operator=(const Decimal&); + MFBT_API Decimal& operator+=(const Decimal&); + MFBT_API Decimal& operator-=(const Decimal&); + MFBT_API Decimal& operator*=(const Decimal&); + MFBT_API Decimal& operator/=(const Decimal&); + + MFBT_API Decimal operator-() const; + + MFBT_API bool operator==(const Decimal&) const; + MFBT_API bool operator!=(const Decimal&) const; + MFBT_API bool operator<(const Decimal&) const; + MFBT_API bool operator<=(const Decimal&) const; + MFBT_API bool operator>(const Decimal&) const; + MFBT_API bool operator>=(const Decimal&) const; + + MFBT_API Decimal operator+(const Decimal&) const; + MFBT_API Decimal operator-(const Decimal&) const; + MFBT_API Decimal operator*(const Decimal&) const; + MFBT_API Decimal operator/(const Decimal&) const; + + int exponent() const + { + ASSERT(isFinite()); + return m_data.exponent(); + } + + bool isFinite() const { return m_data.isFinite(); } + bool isInfinity() const { return m_data.isInfinity(); } + bool isNaN() const { return m_data.isNaN(); } + bool isNegative() const { return sign() == Negative; } + bool isPositive() const { return sign() == Positive; } + bool isSpecial() const { return m_data.isSpecial(); } + bool isZero() const { return m_data.isZero(); } + + MFBT_API Decimal abs() const; + MFBT_API Decimal ceiling() const; + MFBT_API Decimal floor() const; + MFBT_API Decimal remainder(const Decimal&) const; + MFBT_API Decimal round() const; + + MFBT_API double toDouble() const; + // Note: toString method supports infinity and nan but fromString not. + MFBT_API std::string toString() const; + MFBT_API bool toString(char* strBuf, size_t bufLength) const; + + static MFBT_API Decimal fromDouble(double); + // fromString supports following syntax EBNF: + // number ::= sign? digit+ ('.' digit*) (exponent-marker sign? digit+)? + // | sign? '.' digit+ (exponent-marker sign? digit+)? + // sign ::= '+' | '-' + // exponent-marker ::= 'e' | 'E' + // digit ::= '0' | '1' | ... | '9' + // Note: fromString doesn't support "infinity" and "nan". + static MFBT_API Decimal fromString(const std::string& aValue); + static MFBT_API Decimal infinity(Sign); + static MFBT_API Decimal nan(); + static MFBT_API Decimal zero(Sign); + + // You should not use below methods. We expose them for unit testing. + MFBT_API explicit Decimal(const EncodedData&); + const EncodedData& value() const { return m_data; } + +private: + struct AlignedOperands { + uint64_t lhsCoefficient; + uint64_t rhsCoefficient; + int exponent; + }; + + MFBT_API Decimal(double); + MFBT_API Decimal compareTo(const Decimal&) const; + + static MFBT_API AlignedOperands alignOperands(const Decimal& lhs, const Decimal& rhs); + static inline Sign invertSign(Sign sign) { return sign == Negative ? Positive : Negative; } + + Sign sign() const { return m_data.sign(); } + + EncodedData m_data; +}; + +} // namespace WebCore + +namespace mozilla { + typedef WebCore::Decimal Decimal; +} + +#undef WTF_MAKE_FAST_ALLOCATED + +#ifdef DEFINED_ASSERT_FOR_DECIMAL_H +#undef DEFINED_ASSERT_FOR_DECIMAL_H +#undef ASSERT +#endif + +#endif // Decimal_h + diff --git a/mfbt/decimal/LICENSE-APPLE b/mfbt/decimal/LICENSE-APPLE new file mode 100644 index 0000000..f29b41c --- /dev/null +++ b/mfbt/decimal/LICENSE-APPLE @@ -0,0 +1,21 @@ +Copyright (C) 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/mfbt/decimal/LICENSE-LGPL-2 b/mfbt/decimal/LICENSE-LGPL-2 new file mode 100644 index 0000000..0e1187b --- /dev/null +++ b/mfbt/decimal/LICENSE-LGPL-2 @@ -0,0 +1,481 @@ + GNU LIBRARY GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1991 Free Software Foundation, Inc. + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the library GPL. It is + numbered 2 because it goes with version 2 of the ordinary GPL.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Library General Public License, applies to some +specially designated Free Software Foundation software, and to any +other libraries whose authors decide to use it. You can use it for +your libraries, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if +you distribute copies of the library, or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link a program with the library, you must provide +complete object files to the recipients so that they can relink them +with the library, after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + Our method of protecting your rights has two steps: (1) copyright +the library, and (2) offer you this license which gives you legal +permission to copy, distribute and/or modify the library. + + Also, for each distributor's protection, we want to make certain +that everyone understands that there is no warranty for this free +library. If the library is modified by someone else and passed on, we +want its recipients to know that what they have is not the original +version, so that any problems introduced by others will not reflect on +the original authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that companies distributing free +software will individually obtain patent licenses, thus in effect +transforming the program into proprietary software. To prevent this, +we have made it clear that any patent must be licensed for everyone's +free use or not licensed at all. + + Most GNU software, including some libraries, is covered by the ordinary +GNU General Public License, which was designed for utility programs. This +license, the GNU Library General Public License, applies to certain +designated libraries. This license is quite different from the ordinary +one; be sure to read it in full, and don't assume that anything in it is +the same as in the ordinary license. + + The reason we have a separate public license for some libraries is that +they blur the distinction we usually make between modifying or adding to a +program and simply using it. Linking a program with a library, without +changing the library, is in some sense simply using the library, and is +analogous to running a utility program or application program. However, in +a textual and legal sense, the linked executable is a combined work, a +derivative of the original library, and the ordinary General Public License +treats it as such. + + Because of this blurred distinction, using the ordinary General +Public License for libraries did not effectively promote software +sharing, because most developers did not use the libraries. We +concluded that weaker conditions might promote sharing better. + + However, unrestricted linking of non-free programs would deprive the +users of those programs of all benefit from the free status of the +libraries themselves. This Library General Public License is intended to +permit developers of non-free programs to use free libraries, while +preserving your freedom as a user of such programs to change the free +libraries that are incorporated in them. (We have not seen how to achieve +this as regards changes in header files, but we have achieved it as regards +changes in the actual functions of the Library.) The hope is that this +will lead to faster development of free libraries. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, while the latter only +works together with the library. + + Note that it is possible for a library to be covered by the ordinary +General Public License rather than by this special one. + + GNU LIBRARY GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library which +contains a notice placed by the copyright holder or other authorized +party saying it may be distributed under the terms of this Library +General Public License (also called "this License"). Each licensee is +addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also compile or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + c) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + d) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the source code distributed need not include anything that is normally +distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Library General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + <one line to give the library's name and a brief idea of what it does.> + Copyright (C) <year> <name of author> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + <signature of Ty Coon>, 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! diff --git a/mfbt/decimal/LICENSE-LGPL-2.1 b/mfbt/decimal/LICENSE-LGPL-2.1 new file mode 100644 index 0000000..b2787a6 --- /dev/null +++ b/mfbt/decimal/LICENSE-LGPL-2.1 @@ -0,0 +1,502 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations below. + + When we speak of free software, we are referring to freedom of use, +not price. Our General Public Licenses are designed to make sure that +you have the freedom to distribute copies of free software (and charge +for this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. + + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it becomes +a de-facto standard. To achieve this, non-free programs must be +allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. + + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + <one line to give the library's name and a brief idea of what it does.> + Copyright (C) <year> <name of author> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + <signature of Ty Coon>, 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! diff --git a/mfbt/decimal/comparison-with-nan.patch b/mfbt/decimal/comparison-with-nan.patch new file mode 100644 index 0000000..72afc9a --- /dev/null +++ b/mfbt/decimal/comparison-with-nan.patch @@ -0,0 +1,67 @@ +diff --git a/mfbt/decimal/Decimal.cpp b/mfbt/decimal/Decimal.cpp +--- a/mfbt/decimal/Decimal.cpp ++++ b/mfbt/decimal/Decimal.cpp +@@ -505,21 +505,25 @@ Decimal Decimal::operator/(const Decimal + if (remainder > divisor / 2) + ++result; + + return Decimal(resultSign, resultExponent, result); + } + + bool Decimal::operator==(const Decimal& rhs) const + { ++ if (isNaN() || rhs.isNaN()) ++ return false; + return m_data == rhs.m_data || compareTo(rhs).isZero(); + } + + bool Decimal::operator!=(const Decimal& rhs) const + { ++ if (isNaN() || rhs.isNaN()) ++ return true; + if (m_data == rhs.m_data) + return false; + const Decimal result = compareTo(rhs); + if (result.isNaN()) + return false; + return !result.isZero(); + } + +@@ -528,16 +532,18 @@ bool Decimal::operator<(const Decimal& r + const Decimal result = compareTo(rhs); + if (result.isNaN()) + return false; + return !result.isZero() && result.isNegative(); + } + + bool Decimal::operator<=(const Decimal& rhs) const + { ++ if (isNaN() || rhs.isNaN()) ++ return false; + if (m_data == rhs.m_data) + return true; + const Decimal result = compareTo(rhs); + if (result.isNaN()) + return false; + return result.isZero() || result.isNegative(); + } + +@@ -546,16 +552,18 @@ bool Decimal::operator>(const Decimal& r + const Decimal result = compareTo(rhs); + if (result.isNaN()) + return false; + return !result.isZero() && result.isPositive(); + } + + bool Decimal::operator>=(const Decimal& rhs) const + { ++ if (isNaN() || rhs.isNaN()) ++ return false; + if (m_data == rhs.m_data) + return true; + const Decimal result = compareTo(rhs); + if (result.isNaN()) + return false; + return result.isZero() || !result.isNegative(); + } + diff --git a/mfbt/decimal/floor-ceiling.patch b/mfbt/decimal/floor-ceiling.patch new file mode 100644 index 0000000..9e26787 --- /dev/null +++ b/mfbt/decimal/floor-ceiling.patch @@ -0,0 +1,89 @@ +diff --git a/mfbt/decimal/Decimal.cpp b/mfbt/decimal/Decimal.cpp +--- a/mfbt/decimal/Decimal.cpp ++++ b/mfbt/decimal/Decimal.cpp +@@ -618,26 +618,26 @@ Decimal::AlignedOperands Decimal::alignO + Decimal Decimal::ceiling() const + { + if (isSpecial()) + return *this; + + if (exponent() >= 0) + return *this; + +- uint64_t result = m_data.coefficient(); +- const int numberOfDigits = countDigits(result); ++ uint64_t coefficient = m_data.coefficient(); ++ const int numberOfDigits = countDigits(coefficient); + const int numberOfDropDigits = -exponent(); + if (numberOfDigits < numberOfDropDigits) + return isPositive() ? Decimal(1) : zero(Positive); + +- result = scaleDown(result, numberOfDropDigits - 1); +- if (sign() == Positive && result % 10 > 0) +- result += 10; +- result /= 10; ++ uint64_t result = scaleDown(coefficient, numberOfDropDigits); ++ uint64_t droppedDigits = coefficient - scaleUp(result, numberOfDropDigits); ++ if (droppedDigits && isPositive()) ++ result += 1; + return Decimal(sign(), 0, result); + } + + Decimal Decimal::compareTo(const Decimal& rhs) const + { + const Decimal result(*this - rhs); + switch (result.m_data.formatClass()) { + case EncodedData::ClassInfinity: +@@ -660,26 +660,27 @@ Decimal Decimal::compareTo(const Decimal + Decimal Decimal::floor() const + { + if (isSpecial()) + return *this; + + if (exponent() >= 0) + return *this; + +- uint64_t result = m_data.coefficient(); +- const int numberOfDigits = countDigits(result); ++ uint64_t coefficient = m_data.coefficient(); ++ const int numberOfDigits = countDigits(coefficient); + const int numberOfDropDigits = -exponent(); + if (numberOfDigits < numberOfDropDigits) + return isPositive() ? zero(Positive) : Decimal(-1); + +- result = scaleDown(result, numberOfDropDigits - 1); +- if (isNegative() && result % 10 > 0) +- result += 10; +- result /= 10; ++ uint64_t result = scaleDown(coefficient, numberOfDropDigits); ++ uint64_t droppedDigits = coefficient - scaleUp(result, numberOfDropDigits); ++ if (droppedDigits && isNegative()) { ++ result += 1; ++ } + return Decimal(sign(), 0, result); + } + + Decimal Decimal::fromDouble(double doubleValue) + { + if (std::isfinite(doubleValue)) + return fromString(String::numberToStringECMAScript(doubleValue)); + +@@ -915,16 +916,18 @@ Decimal Decimal::round() const + return *this; + + uint64_t result = m_data.coefficient(); + const int numberOfDigits = countDigits(result); + const int numberOfDropDigits = -exponent(); + if (numberOfDigits < numberOfDropDigits) + return zero(Positive); + ++ // We're implementing round-half-away-from-zero, so we only need the one ++ // (the most significant) fractional digit: + result = scaleDown(result, numberOfDropDigits - 1); + if (result % 10 >= 5) + result += 10; + result /= 10; + return Decimal(sign(), 0, result); + } + + double Decimal::toDouble() const diff --git a/mfbt/decimal/mfbt-abi-markers.patch b/mfbt/decimal/mfbt-abi-markers.patch new file mode 100644 index 0000000..834ee4b --- /dev/null +++ b/mfbt/decimal/mfbt-abi-markers.patch @@ -0,0 +1,150 @@ +diff --git a/mfbt/decimal/Decimal.h b/mfbt/decimal/Decimal.h +--- a/mfbt/decimal/Decimal.h ++++ b/mfbt/decimal/Decimal.h +@@ -26,16 +26,18 @@ + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + #ifndef Decimal_h + #define Decimal_h + ++#include "mozilla/Types.h" ++ + #include <stdint.h> + #include <wtf/Assertions.h> + #include <wtf/text/WTFString.h> + + namespace WebCore { + + namespace DecimalPrivate { + class SpecialValueHandler; +@@ -88,92 +90,92 @@ public: + FormatClass formatClass() const { return m_formatClass; } + + uint64_t m_coefficient; + int16_t m_exponent; + FormatClass m_formatClass; + Sign m_sign; + }; + +- Decimal(int32_t = 0); +- Decimal(Sign, int exponent, uint64_t coefficient); +- Decimal(const Decimal&); ++ MFBT_API Decimal(int32_t = 0); ++ MFBT_API Decimal(Sign, int exponent, uint64_t coefficient); ++ MFBT_API Decimal(const Decimal&); + +- Decimal& operator=(const Decimal&); +- Decimal& operator+=(const Decimal&); +- Decimal& operator-=(const Decimal&); +- Decimal& operator*=(const Decimal&); +- Decimal& operator/=(const Decimal&); ++ MFBT_API Decimal& operator=(const Decimal&); ++ MFBT_API Decimal& operator+=(const Decimal&); ++ MFBT_API Decimal& operator-=(const Decimal&); ++ MFBT_API Decimal& operator*=(const Decimal&); ++ MFBT_API Decimal& operator/=(const Decimal&); + +- Decimal operator-() const; ++ MFBT_API Decimal operator-() const; + +- bool operator==(const Decimal&) const; +- bool operator!=(const Decimal&) const; +- bool operator<(const Decimal&) const; +- bool operator<=(const Decimal&) const; +- bool operator>(const Decimal&) const; +- bool operator>=(const Decimal&) const; ++ MFBT_API bool operator==(const Decimal&) const; ++ MFBT_API bool operator!=(const Decimal&) const; ++ MFBT_API bool operator<(const Decimal&) const; ++ MFBT_API bool operator<=(const Decimal&) const; ++ MFBT_API bool operator>(const Decimal&) const; ++ MFBT_API bool operator>=(const Decimal&) const; + +- Decimal operator+(const Decimal&) const; +- Decimal operator-(const Decimal&) const; +- Decimal operator*(const Decimal&) const; +- Decimal operator/(const Decimal&) const; ++ MFBT_API Decimal operator+(const Decimal&) const; ++ MFBT_API Decimal operator-(const Decimal&) const; ++ MFBT_API Decimal operator*(const Decimal&) const; ++ MFBT_API Decimal operator/(const Decimal&) const; + + int exponent() const + { + ASSERT(isFinite()); + return m_data.exponent(); + } + + bool isFinite() const { return m_data.isFinite(); } + bool isInfinity() const { return m_data.isInfinity(); } + bool isNaN() const { return m_data.isNaN(); } + bool isNegative() const { return sign() == Negative; } + bool isPositive() const { return sign() == Positive; } + bool isSpecial() const { return m_data.isSpecial(); } + bool isZero() const { return m_data.isZero(); } + +- Decimal abs() const; +- Decimal ceiling() const; +- Decimal floor() const; +- Decimal remainder(const Decimal&) const; +- Decimal round() const; ++ MFBT_API Decimal abs() const; ++ MFBT_API Decimal ceiling() const; ++ MFBT_API Decimal floor() const; ++ MFBT_API Decimal remainder(const Decimal&) const; ++ MFBT_API Decimal round() const; + +- double toDouble() const; ++ MFBT_API double toDouble() const; + // Note: toString method supports infinity and nan but fromString not. +- String toString() const; ++ MFBT_API String toString() const; + +- static Decimal fromDouble(double); ++ static MFBT_API Decimal fromDouble(double); + // fromString supports following syntax EBNF: + // number ::= sign? digit+ ('.' digit*) (exponent-marker sign? digit+)? + // | sign? '.' digit+ (exponent-marker sign? digit+)? + // sign ::= '+' | '-' + // exponent-marker ::= 'e' | 'E' + // digit ::= '0' | '1' | ... | '9' + // Note: fromString doesn't support "infinity" and "nan". +- static Decimal fromString(const String&); +- static Decimal infinity(Sign); +- static Decimal nan(); +- static Decimal zero(Sign); ++ static MFBT_API Decimal fromString(const String&); ++ static MFBT_API Decimal infinity(Sign); ++ static MFBT_API Decimal nan(); ++ static MFBT_API Decimal zero(Sign); + + // You should not use below methods. We expose them for unit testing. +- explicit Decimal(const EncodedData&); ++ MFBT_API explicit Decimal(const EncodedData&); + const EncodedData& value() const { return m_data; } + + private: + struct AlignedOperands { + uint64_t lhsCoefficient; + uint64_t rhsCoefficient; + int exponent; + }; + +- Decimal(double); +- Decimal compareTo(const Decimal&) const; ++ MFBT_API Decimal(double); ++ MFBT_API Decimal compareTo(const Decimal&) const; + +- static AlignedOperands alignOperands(const Decimal& lhs, const Decimal& rhs); ++ static MFBT_API AlignedOperands alignOperands(const Decimal& lhs, const Decimal& rhs); + static inline Sign invertSign(Sign sign) { return sign == Negative ? Positive : Negative; } + + Sign sign() const { return m_data.sign(); } + + EncodedData m_data; + }; + + } // namespace WebCore diff --git a/mfbt/decimal/moz-decimal-utils.h b/mfbt/decimal/moz-decimal-utils.h new file mode 100644 index 0000000..7f96d30 --- /dev/null +++ b/mfbt/decimal/moz-decimal-utils.h @@ -0,0 +1,109 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef MOZ_DECIMAL_UTILS_H +#define MOZ_DECIMAL_UTILS_H + +// This file contains extra includes, defines and typedefs to allow compilation +// of Decimal.cpp under the Mozilla source without blink core dependencies. Do +// not include it into any file other than Decimal.cpp. + +#include "../double-conversion/double-conversion.h" +#include "mozilla/Util.h" +#include "mozilla/Casting.h" +#include "mozilla/FloatingPoint.h" +#include "mozilla/NullPtr.h" + +#include <cmath> +#include <cstring> +#include <iomanip> +#include <limits> +#include <sstream> + +#ifndef UINT64_C +// For Android toolchain +#define UINT64_C(c) (c ## ULL) +#endif + +#ifdef ASSERT +#undef ASSERT +#endif +#define ASSERT MOZ_ASSERT + +#define ASSERT_NOT_REACHED() MOZ_NOT_REACHED("") + +#define WTF_MAKE_NONCOPYABLE(ClassName) \ + private: \ + ClassName(const ClassName&) MOZ_DELETE; \ + void operator=(const ClassName&) MOZ_DELETE; + +#if defined(_MSC_VER) && (_MSC_VER <= 1700) +namespace std { + inline bool isinf(double num) { return mozilla::IsInfinite(num); } + inline bool isnan(double num) { return mozilla::IsNaN(num); } + inline bool isfinite(double num) { return mozilla::IsFinite(num); } +} +#endif + +typedef std::string String; + +double mozToDouble(const String &aStr, bool *valid) { + double_conversion::StringToDoubleConverter converter( + double_conversion::StringToDoubleConverter::NO_FLAGS, + mozilla::UnspecifiedNaN(), mozilla::UnspecifiedNaN(), nullptr, nullptr); + const char* str = aStr.c_str(); + int length = mozilla::SafeCast<int>(strlen(str)); + int processed_char_count; // unused - NO_FLAGS requires the whole string to parse + double result = converter.StringToDouble(str, length, &processed_char_count); + *valid = mozilla::IsFinite(result); + return result; +} + +String mozToString(double aNum) { + char buffer[64]; + int buffer_length = mozilla::ArrayLength(buffer); + const double_conversion::DoubleToStringConverter& converter = + double_conversion::DoubleToStringConverter::EcmaScriptConverter(); + double_conversion::StringBuilder builder(buffer, buffer_length); + converter.ToShortest(aNum, &builder); + return String(builder.Finalize()); +} + +String mozToString(int64_t aNum) { + std::ostringstream o; + o << std::setprecision(std::numeric_limits<int64_t>::digits10) << aNum; + return o.str(); +} + +String mozToString(uint64_t aNum) { + std::ostringstream o; + o << std::setprecision(std::numeric_limits<uint64_t>::digits10) << aNum; + return o.str(); +} + +class StringBuilder +{ +public: + void append(char c) { + mStr += c; + } + void appendLiteral(const char *aStr) { + mStr += aStr; + } + void appendNumber(int aNum) { + mStr += mozToString(int64_t(aNum)); + } + void append(const String& aStr) { + mStr += aStr; + } + std::string toString() const { + return mStr; + } +private: + std::string mStr; +}; + +#endif + diff --git a/mfbt/decimal/to-moz-dependencies.patch b/mfbt/decimal/to-moz-dependencies.patch new file mode 100644 index 0000000..824f65c --- /dev/null +++ b/mfbt/decimal/to-moz-dependencies.patch @@ -0,0 +1,333 @@ +diff --git a/mfbt/decimal/Decimal.cpp b/mfbt/decimal/Decimal.cpp +--- a/mfbt/decimal/Decimal.cpp ++++ b/mfbt/decimal/Decimal.cpp +@@ -23,27 +23,22 @@ + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +-#include "config.h" + #include "Decimal.h" ++#include "moz-decimal-utils.h" + + #include <algorithm> + #include <float.h> + +-#include <wtf/Assertions.h> +-#include <wtf/MathExtras.h> +-#include <wtf/Noncopyable.h> +-#include <wtf/text/StringBuilder.h> +- + namespace WebCore { + + namespace DecimalPrivate { + + static int const ExponentMax = 1023; + static int const ExponentMin = -1023; + static int const Precision = 18; + +@@ -685,17 +680,17 @@ Decimal Decimal::floor() const + result += 1; + } + return Decimal(sign(), 0, result); + } + + Decimal Decimal::fromDouble(double doubleValue) + { + if (std::isfinite(doubleValue)) +- return fromString(String::numberToStringECMAScript(doubleValue)); ++ return fromString(mozToString(doubleValue)); + + if (std::isinf(doubleValue)) + return infinity(doubleValue < 0 ? Negative : Positive); + + return nan(); + } + + Decimal Decimal::fromString(const String& str) +@@ -937,17 +932,17 @@ Decimal Decimal::round() const + result /= 10; + return Decimal(sign(), 0, result); + } + + double Decimal::toDouble() const + { + if (isFinite()) { + bool valid; +- const double doubleValue = toString().toDouble(&valid); ++ const double doubleValue = mozToDouble(toString(), &valid); + return valid ? doubleValue : std::numeric_limits<double>::quiet_NaN(); + } + + if (isInfinity()) + return isNegative() ? -std::numeric_limits<double>::infinity() : std::numeric_limits<double>::infinity(); + + return std::numeric_limits<double>::quiet_NaN(); + } +@@ -990,17 +985,17 @@ String Decimal::toString() const + ++coefficient; + + while (originalExponent < 0 && coefficient && !(coefficient % 10)) { + coefficient /= 10; + ++originalExponent; + } + } + +- const String digits = String::number(coefficient); ++ const String digits = mozToString(coefficient); + int coefficientLength = static_cast<int>(digits.length()); + const int adjustedExponent = originalExponent + coefficientLength - 1; + if (originalExponent <= 0 && adjustedExponent >= -6) { + if (!originalExponent) { + builder.append(digits); + return builder.toString(); + } + +@@ -1032,15 +1027,28 @@ String Decimal::toString() const + if (adjustedExponent) { + builder.append(adjustedExponent < 0 ? "e" : "e+"); + builder.appendNumber(adjustedExponent); + } + } + return builder.toString(); + } + ++bool Decimal::toString(char* strBuf, size_t bufLength) const ++{ ++ ASSERT(bufLength > 0); ++ String str = toString(); ++ size_t length = str.copy(strBuf, bufLength); ++ if (length < bufLength) { ++ strBuf[length] = '\0'; ++ return true; ++ } ++ strBuf[bufLength - 1] = '\0'; ++ return false; ++} ++ + Decimal Decimal::zero(Sign sign) + { + return Decimal(EncodedData(sign, EncodedData::ClassZero)); + } + + } // namespace WebCore + +diff --git a/mfbt/decimal/Decimal.h b/mfbt/decimal/Decimal.h +--- a/mfbt/decimal/Decimal.h ++++ b/mfbt/decimal/Decimal.h +@@ -23,24 +23,41 @@ + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + ++/** ++ * Imported from: ++ * http://src.chromium.org/viewvc/blink/trunk/Source/core/platform/Decimal.h ++ * Check hg log for the svn rev of the last update from Blink core. ++ */ ++ + #ifndef Decimal_h + #define Decimal_h + ++#include "mozilla/Assertions.h" ++#include "mozilla/StandardInteger.h" + #include "mozilla/Types.h" + +-#include <stdint.h> +-#include <wtf/Assertions.h> +-#include <wtf/text/WTFString.h> ++#include <string> ++ ++#ifndef ASSERT ++#define DEFINED_ASSERT_FOR_DECIMAL_H 1 ++#define ASSERT MOZ_ASSERT ++#endif ++ ++// To use WTF_MAKE_FAST_ALLOCATED we'd need: ++// http://src.chromium.org/viewvc/blink/trunk/Source/wtf/FastMalloc.h ++// Since we don't allocate Decimal objects, no need. ++#define WTF_MAKE_FAST_ALLOCATED \ ++ void ignore_this_dummy_method() MOZ_DELETE + + namespace WebCore { + + namespace DecimalPrivate { + class SpecialValueHandler; + } + + // This class represents decimal base floating point number. +@@ -136,27 +153,28 @@ public: + MFBT_API Decimal abs() const; + MFBT_API Decimal ceiling() const; + MFBT_API Decimal floor() const; + MFBT_API Decimal remainder(const Decimal&) const; + MFBT_API Decimal round() const; + + MFBT_API double toDouble() const; + // Note: toString method supports infinity and nan but fromString not. +- MFBT_API String toString() const; ++ MFBT_API std::string toString() const; ++ MFBT_API bool toString(char* strBuf, size_t bufLength) const; + + static MFBT_API Decimal fromDouble(double); + // fromString supports following syntax EBNF: + // number ::= sign? digit+ ('.' digit*) (exponent-marker sign? digit+)? + // | sign? '.' digit+ (exponent-marker sign? digit+)? + // sign ::= '+' | '-' + // exponent-marker ::= 'e' | 'E' + // digit ::= '0' | '1' | ... | '9' + // Note: fromString doesn't support "infinity" and "nan". +- static MFBT_API Decimal fromString(const String&); ++ static MFBT_API Decimal fromString(const std::string& aValue); + static MFBT_API Decimal infinity(Sign); + static MFBT_API Decimal nan(); + static MFBT_API Decimal zero(Sign); + + // You should not use below methods. We expose them for unit testing. + MFBT_API explicit Decimal(const EncodedData&); + const EncodedData& value() const { return m_data; } + +@@ -175,10 +193,21 @@ private: + + Sign sign() const { return m_data.sign(); } + + EncodedData m_data; + }; + + } // namespace WebCore + ++namespace mozilla { ++ typedef WebCore::Decimal Decimal; ++} ++ ++#undef WTF_MAKE_FAST_ALLOCATED ++ ++#ifdef DEFINED_ASSERT_FOR_DECIMAL_H ++#undef DEFINED_ASSERT_FOR_DECIMAL_H ++#undef ASSERT ++#endif ++ + #endif // Decimal_h + +diff --git a/mfbt/decimal/moz-decimal-utils.h b/mfbt/decimal/moz-decimal-utils.h +new file mode 100644 +--- /dev/null ++++ b/mfbt/decimal/moz-decimal-utils.h +@@ -0,0 +1,109 @@ ++/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ ++/* This Source Code Form is subject to the terms of the Mozilla Public ++ * License, v. 2.0. If a copy of the MPL was not distributed with this ++ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ ++ ++#ifndef MOZ_DECIMAL_UTILS_H ++#define MOZ_DECIMAL_UTILS_H ++ ++// This file contains extra includes, defines and typedefs to allow compilation ++// of Decimal.cpp under the Mozilla source without blink core dependencies. Do ++// not include it into any file other than Decimal.cpp. ++ ++#include "../double-conversion/double-conversion.h" ++#include "mozilla/Util.h" ++#include "mozilla/Casting.h" ++#include "mozilla/FloatingPoint.h" ++#include "mozilla/NullPtr.h" ++ ++#include <cmath> ++#include <cstring> ++#include <iomanip> ++#include <limits> ++#include <sstream> ++ ++#ifndef UINT64_C ++// For Android toolchain ++#define UINT64_C(c) (c ## ULL) ++#endif ++ ++#ifdef ASSERT ++#undef ASSERT ++#endif ++#define ASSERT MOZ_ASSERT ++ ++#define ASSERT_NOT_REACHED() MOZ_NOT_REACHED("") ++ ++#define WTF_MAKE_NONCOPYABLE(ClassName) \ ++ private: \ ++ ClassName(const ClassName&) MOZ_DELETE; \ ++ void operator=(const ClassName&) MOZ_DELETE; ++ ++#if defined(_MSC_VER) && (_MSC_VER <= 1700) ++namespace std { ++ inline bool isinf(double num) { return MOZ_DOUBLE_IS_INFINITE(num); } ++ inline bool isnan(double num) { return MOZ_DOUBLE_IS_NaN(num); } ++ inline bool isfinite(double num) { return MOZ_DOUBLE_IS_FINITE(num); } ++} ++#endif ++ ++typedef std::string String; ++ ++double mozToDouble(const String &aStr, bool *valid) { ++ double_conversion::StringToDoubleConverter converter( ++ double_conversion::StringToDoubleConverter::NO_FLAGS, ++ MOZ_DOUBLE_NaN(), MOZ_DOUBLE_NaN(), nullptr, nullptr); ++ const char* str = aStr.c_str(); ++ int length = mozilla::SafeCast<int>(strlen(str)); ++ int processed_char_count; // unused - NO_FLAGS requires the whole string to parse ++ double result = converter.StringToDouble(str, length, &processed_char_count); ++ *valid = MOZ_DOUBLE_IS_FINITE(result); ++ return result; ++} ++ ++String mozToString(double aNum) { ++ char buffer[64]; ++ int buffer_length = mozilla::ArrayLength(buffer); ++ const double_conversion::DoubleToStringConverter& converter = ++ double_conversion::DoubleToStringConverter::EcmaScriptConverter(); ++ double_conversion::StringBuilder builder(buffer, buffer_length); ++ converter.ToShortest(aNum, &builder); ++ return String(builder.Finalize()); ++} ++ ++String mozToString(int64_t aNum) { ++ std::ostringstream o; ++ o << std::setprecision(std::numeric_limits<int64_t>::digits10) << aNum; ++ return o.str(); ++} ++ ++String mozToString(uint64_t aNum) { ++ std::ostringstream o; ++ o << std::setprecision(std::numeric_limits<uint64_t>::digits10) << aNum; ++ return o.str(); ++} ++ ++class StringBuilder ++{ ++public: ++ void append(char c) { ++ mStr += c; ++ } ++ void appendLiteral(const char *aStr) { ++ mStr += aStr; ++ } ++ void appendNumber(int aNum) { ++ mStr += mozToString(int64_t(aNum)); ++ } ++ void append(const String& aStr) { ++ mStr += aStr; ++ } ++ std::string toString() const { ++ return mStr; ++ } ++private: ++ std::string mStr; ++}; ++ ++#endif ++ diff --git a/mfbt/decimal/update.sh b/mfbt/decimal/update.sh new file mode 100755 index 0000000..5422b5c --- /dev/null +++ b/mfbt/decimal/update.sh @@ -0,0 +1,66 @@ +# Usage: ./update.sh [blink-core-source-directory] +# +# Copies the needed files from a directory containing the original +# Decimal.h and Decimal.cpp source that we need. +# If [blink-core-source-directory] is not specified, this script will +# attempt to download the latest versions using svn. + +# This was last updated with svn r148833 + +set -e + +FILES=( + "LICENSE-APPLE" + "LICENSE-LGPL-2" + "LICENSE-LGPL-2.1" + "platform/Decimal.h" + "platform/Decimal.cpp" +) + +OWN_NAME=`basename $0` + +if [ $# -gt 1 ]; then + echo "$OWN_NAME: Too many arguments">&2 + exit 1 +fi + +if [ $# -eq 1 ]; then + BLINK_CORE_DIR="$1" + for F in "${FILES[@]}" + do + P="$BLINK_CORE_DIR/$F" + if [ ! -f "$P" ]; then + echo "$OWN_NAME: Couldn't find file: $P">&2 + exit 1 + fi + done + for F in "${FILES[@]}" + do + P="$BLINK_CORE_DIR/$F" + cp "$P" . + done +else + SVN="svn --non-interactive --trust-server-cert" + REPO_PATH="https://src.chromium.org/blink/trunk/Source/core" + #REPO_PATH="https://svn.webkit.org/repository/webkit/trunk/Source/WebCore" + + printf "Looking up latest Blink revision number..." + LATEST_REV=`$SVN info $REPO_PATH | grep '^Revision: ' | cut -c11-` + echo done. + + for F in "${FILES[@]}" + do + printf "Exporting r$LATEST_REV of `basename $F`..." + $SVN export -r $LATEST_REV $REPO_PATH/$F 2>/dev/null 1>&2 + echo done. + done +fi + +# Apply patches: + +patch -p3 < floor-ceiling.patch +patch -p3 < zero-serialization.patch +patch -p3 < comparison-with-nan.patch +patch -p3 < mfbt-abi-markers.patch +patch -p3 < to-moz-dependencies.patch + diff --git a/mfbt/decimal/zero-serialization.patch b/mfbt/decimal/zero-serialization.patch new file mode 100644 index 0000000..b058e09 --- /dev/null +++ b/mfbt/decimal/zero-serialization.patch @@ -0,0 +1,22 @@ +diff --git a/mfbt/decimal/Decimal.cpp b/mfbt/decimal/Decimal.cpp +--- a/mfbt/decimal/Decimal.cpp ++++ b/mfbt/decimal/Decimal.cpp +@@ -278,17 +278,17 @@ bool Decimal::EncodedData::operator==(co + } + + Decimal::Decimal(int32_t i32) + : m_data(i32 < 0 ? Negative : Positive, 0, i32 < 0 ? static_cast<uint64_t>(-static_cast<int64_t>(i32)) : static_cast<uint64_t>(i32)) + { + } + + Decimal::Decimal(Sign sign, int exponent, uint64_t coefficient) +- : m_data(sign, exponent, coefficient) ++ : m_data(sign, coefficient ? exponent : 0, coefficient) + { + } + + Decimal::Decimal(const EncodedData& data) + : m_data(data) + { + } + |