diff options
-rw-r--r-- | NOTICE | 11 | ||||
-rw-r--r-- | expectations/knownfailures.txt | 17 | ||||
-rw-r--r-- | libart/src/main/java/dalvik/system/VMRuntime.java | 4 | ||||
-rw-r--r-- | luni/src/main/java/java/io/ObjectStreamField.java | 8 | ||||
-rw-r--r-- | luni/src/main/java/java/lang/StrictMath.java | 1552 | ||||
-rw-r--r-- | luni/src/main/java/java/util/logging/FileHandler.java | 14 | ||||
-rw-r--r-- | luni/src/main/java/java/util/logging/SocketHandler.java | 6 | ||||
-rw-r--r-- | luni/src/main/java/java/util/logging/XMLFormatter.java | 66 | ||||
-rw-r--r-- | luni/src/main/java/java/util/zip/ZipEntry.java | 7 | ||||
-rw-r--r-- | luni/src/main/native/java_lang_StrictMath.cpp | 95 | ||||
-rw-r--r-- | luni/src/main/native/java_util_jar_StrictJarFile.cpp | 28 | ||||
-rw-r--r-- | luni/src/main/native/libcore_io_Posix.cpp | 3 | ||||
-rw-r--r-- | luni/src/test/java/libcore/java/security/cert/CertificateFactoryTest.java | 4 |
13 files changed, 1594 insertions, 221 deletions
@@ -104,3 +104,14 @@ WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See W3C License http://www.w3.org/Consortium/Legal/ for more details. + + ========================================================================= + == NOTICE file for the fdlibm License. == + ========================================================================= + +Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + +Developed at SunSoft, a Sun Microsystems, Inc. business. +Permission to use, copy, modify, and distribute this +software is freely granted, provided that this notice +is preserved. diff --git a/expectations/knownfailures.txt b/expectations/knownfailures.txt index 94d0562..fc2ab7e 100644 --- a/expectations/knownfailures.txt +++ b/expectations/knownfailures.txt @@ -1419,11 +1419,20 @@ name: "com.android.org.apache.harmony.logging.tests.java.util.logging.LevelTest#testSerializationCompatibility" }, { - description: "java.util.logging: Tests that require java.util.logging code changes to fix.", - bug: 13882147, + description: "java.util.beans: the harmony tests were broken by Android commit 19a270e90b1e992c1f6639f355ae13564c2f3a6a", + bug: 17394106, + names: [ + "com.android.org.apache.harmony.beans.tests.java.beans.PropertyChangeSupportTest#testSerialization", + "com.android.org.apache.harmony.beans.tests.java.beans.PropertyChangeSupportTest#testGetPropertyChangeListener_String_Normal", + "com.android.org.apache.harmony.beans.tests.java.beans.PropertyChangeSupportTest#testAddPropertyChangeListener_PropertyChangeListener_String_Normal", + "com.android.org.apache.harmony.beans.tests.java.beans.PropertyChangeSupportTest#testAddPropertyChangeListener_PropertyChangeListener_Normal" + ] +}, +{ + description: "java.util.beans: the serialized form references org.apache not com.android.org.apache", + bug: 17394106, names: [ - "com.android.org.apache.harmony.logging.tests.java.util.logging.SocketHandlerTest#testConstructor_NoProperties", - "com.android.org.apache.harmony.logging.tests.java.util.logging.XMLFormatterTest#test_TestFileHandlerClass_constructor" + "com.android.org.apache.harmony.beans.tests.java.beans.PropertyChangeSupportTest#testSerializationCompatibility" ] }, { diff --git a/libart/src/main/java/dalvik/system/VMRuntime.java b/libart/src/main/java/dalvik/system/VMRuntime.java index a905c71..fca64c7 100644 --- a/libart/src/main/java/dalvik/system/VMRuntime.java +++ b/libart/src/main/java/dalvik/system/VMRuntime.java @@ -33,6 +33,10 @@ public final class VMRuntime { */ private static final VMRuntime THE_ONE = new VMRuntime(); + // Note: Instruction set names are used to construct the names of some + // system properties. To be sure that the properties stay valid the + // instruction set name should not exceed 7 characters. See installd + // and the package manager for the actual propeties. private static final Map<String, String> ABI_TO_INSTRUCTION_SET_MAP = new HashMap<String, String>(); static { diff --git a/luni/src/main/java/java/io/ObjectStreamField.java b/luni/src/main/java/java/io/ObjectStreamField.java index 78a6903..2a9b107 100644 --- a/luni/src/main/java/java/io/ObjectStreamField.java +++ b/luni/src/main/java/java/io/ObjectStreamField.java @@ -58,13 +58,7 @@ public class ObjectStreamField implements Comparable<Object> { * if {@code name} or {@code cl} is {@code null}. */ public ObjectStreamField(String name, Class<?> cl) { - if (name == null) { - throw new NullPointerException("name == null"); - } else if (cl == null) { - throw new NullPointerException("cl == null"); - } - this.name = name; - this.type = new WeakReference<Class<?>>(cl); + this(name, cl, false); } /** diff --git a/luni/src/main/java/java/lang/StrictMath.java b/luni/src/main/java/java/lang/StrictMath.java index f409c06..0cf9883 100644 --- a/luni/src/main/java/java/lang/StrictMath.java +++ b/luni/src/main/java/java/lang/StrictMath.java @@ -15,6 +15,19 @@ * limitations under the License. */ +/* + * acos, asin, atan, cosh, sinh, tanh, exp, expm1, log, log10, log1p, cbrt, + * ceil, floor, IEEEremainder, rint, nextafter, and hypot + * have been implemented with the following license. + * ==================================================== + * Copyright (C) 2004 by Sun Microsystems, Inc. All rights reserved. + * + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + package java.lang; /** @@ -102,6 +115,21 @@ public final class StrictMath { return Math.abs(l); } + private static final double PIO2_HI = 1.57079632679489655800e+00; + private static final double PIO2_LO = 6.12323399573676603587e-17; + private static final double PS0 = 1.66666666666666657415e-01; + private static final double PS1 = -3.25565818622400915405e-01; + private static final double PS2 = 2.01212532134862925881e-01; + private static final double PS3 = -4.00555345006794114027e-02; + private static final double PS4 = 7.91534994289814532176e-04; + private static final double PS5 = 3.47933107596021167570e-05; + private static final double QS1 = -2.40339491173441421878e+00; + private static final double QS2 = 2.02094576023350569471e+00; + private static final double QS3 = -6.88283971605453293030e-01; + private static final double QS4 = 7.70381505559019352791e-02; + private static final double HUGE = 1.000e+300; + private static final double PIO4_HI = 7.85398163397448278999e-01; + /** * Returns the closest double approximation of the arc cosine of the * argument within the range {@code [0..pi]}. @@ -113,11 +141,62 @@ public final class StrictMath { * <li>{@code acos(NaN) = NaN}</li> * </ul> * - * @param d + * @param x * the value to compute arc cosine of. * @return the arc cosine of the argument. */ - public static native double acos(double d); + public static double acos(double x) { + double z, p, q, r, w, s, c, df; + int hx, ix; + final long bits = Double.doubleToRawLongBits(x); + hx = (int) (bits >>> 32); + ix = hx & 0x7fffffff; + if (ix >= 0x3ff00000) { /* |x| >= 1 */ + if ((((ix - 0x3ff00000) | ((int) bits))) == 0) { /* |x|==1 */ + if (hx > 0) { + return 0.0; /* ieee_acos(1) = 0 */ + } else { + return 3.14159265358979311600e+00 + 2.0 * PIO2_LO; /* ieee_acos(-1)= pi */ + } + } + return (x - x) / (x - x); /* ieee_acos(|x|>1) is NaN */ + } + + if (ix < 0x3fe00000) { /* |x| < 0.5 */ + if (ix <= 0x3c600000) { + return PIO2_HI + PIO2_LO;/* if|x|<2**-57 */ + } + + z = x * x; + p = z * (PS0 + z + * (PS1 + z * (PS2 + z * (PS3 + z * (PS4 + z * PS5))))); + q = 1.00000000000000000000e+00 + z * (QS1 + z * (QS2 + z * (QS3 + z * QS4))); + r = p / q; + return PIO2_HI - (x - (PIO2_LO - x * r)); + } else if (hx < 0) { /* x < -0.5 */ + z = (1.00000000000000000000e+00 + x) * 0.5; + p = z * (PS0 + z + * (PS1 + z * (PS2 + z * (PS3 + z * (PS4 + z * PS5))))); + q = 1.00000000000000000000e+00 + z * (QS1 + z * (QS2 + z * (QS3 + z * QS4))); + s = StrictMath.sqrt(z); + r = p / q; + w = r * s - PIO2_LO; + return 3.14159265358979311600e+00 - 2.0 * (s + w); + } else { /* x > 0.5 */ + z = (1.00000000000000000000e+00 - x) * 0.5; + s = StrictMath.sqrt(z); + df = s; + df = Double.longBitsToDouble( + Double.doubleToRawLongBits(df) & 0xffffffffL << 32); + c = (z - df * df) / (s + df); + p = z * (PS0 + z + * (PS1 + z * (PS2 + z * (PS3 + z * (PS4 + z * PS5))))); + q = 1.00000000000000000000e+00 + z * (QS1 + z * (QS2 + z * (QS3 + z * QS4))); + r = p / q; + w = r * s + c; + return 2.0 * (df + w); + } + } /** * Returns the closest double approximation of the arc sine of the argument @@ -130,11 +209,75 @@ public final class StrictMath { * <li>{@code asin(NaN) = NaN}</li> * </ul> * - * @param d + * @param x * the value whose arc sine has to be computed. * @return the arc sine of the argument. */ - public static native double asin(double d); + public static double asin(double x) { + double t, w, p, q, c, r, s; + int hx, ix; + final long bits = Double.doubleToRawLongBits(x); + hx = (int) (bits >>> 32); + ix = hx & 0x7fffffff; + if (ix >= 0x3ff00000) { /* |x|>= 1 */ + if ((((ix - 0x3ff00000) | ((int) bits))) == 0) { + /* ieee_asin(1)=+-pi/2 with inexact */ + return x * PIO2_HI + x * PIO2_LO; + } + return (x - x) / (x - x); /* ieee_asin(|x|>1) is NaN */ + } else if (ix < 0x3fe00000) { /* |x|<0.5 */ + if (ix < 0x3e400000) { /* if |x| < 2**-27 */ + if (HUGE + x > 1.00000000000000000000e+00) { + return x;/* return x with inexact if x!=0 */ + } + } else { + t = x * x; + p = t * (PS0 + t + * (PS1 + t * (PS2 + t * (PS3 + t * (PS4 + t * PS5))))); + q = 1.00000000000000000000e+00 + t * (QS1 + t * (QS2 + t * (QS3 + t * QS4))); + w = p / q; + return x + x * w; + } + } + /* 1> |x|>= 0.5 */ + w = 1.00000000000000000000e+00 - Math.abs(x); + t = w * 0.5; + p = t * (PS0 + t * (PS1 + t * (PS2 + t * (PS3 + t * (PS4 + t * PS5))))); + q = 1.00000000000000000000e+00 + t * (QS1 + t * (QS2 + t * (QS3 + t * QS4))); + s = StrictMath.sqrt(t); + if (ix >= 0x3FEF3333) { /* if |x| > 0.975 */ + w = p / q; + t = PIO2_HI - (2.0 * (s + s * w) - PIO2_LO); + } else { + w = s; + w = Double.longBitsToDouble( + Double.doubleToRawLongBits(w) & 0xffffffffL << 32); + c = (t - w * w) / (s + w); + r = p / q; + p = 2.0 * s * r - (PIO2_LO - 2.0 * c); + q = PIO4_HI - 2.0 * w; + t = PIO4_HI - (p - q); + } + return (hx > 0) ? t : -t; + } + + private static final double[] ATANHI = { 4.63647609000806093515e-01, + 7.85398163397448278999e-01, 9.82793723247329054082e-01, + 1.57079632679489655800e+00 }; + private static final double[] ATANLO = { 2.26987774529616870924e-17, + 3.06161699786838301793e-17, 1.39033110312309984516e-17, + 6.12323399573676603587e-17 }; + private static final double AT0 = 3.33333333333329318027e-01; + private static final double AT1 = -1.99999999998764832476e-01; + private static final double AT2 = 1.42857142725034663711e-01; + private static final double AT3 = -1.11111104054623557880e-01; + private static final double AT4 = 9.09088713343650656196e-02; + private static final double AT5 = -7.69187620504482999495e-02; + private static final double AT6 = 6.66107313738753120669e-02; + private static final double AT7= -5.83357013379057348645e-02; + private static final double AT8 = 4.97687799461593236017e-02; + private static final double AT9 = -3.65315727442169155270e-02; + private static final double AT10 = 1.62858201153657823623e-02; /** * Returns the closest double approximation of the arc tangent of the @@ -149,11 +292,73 @@ public final class StrictMath { * <li>{@code atan(NaN) = NaN}</li> * </ul> * - * @param d + * @param x * the value whose arc tangent has to be computed. * @return the arc tangent of the argument. */ - public static native double atan(double d); + public static double atan(double x) { + double w, s1, s2, z; + int ix, hx, id; + + final long bits = Double.doubleToRawLongBits(x); + hx = (int) (bits >>> 32); + ix = hx & 0x7fffffff; + if (ix >= 0x44100000) { /* if |x| >= 2^66 */ + if (ix > 0x7ff00000 || (ix == 0x7ff00000 && (((int) bits) != 0))) { + return x + x; /* NaN */ + } + if (hx > 0) { + return ATANHI[3] + ATANLO[3]; + } else { + return -ATANHI[3] - ATANLO[3]; + } + } + if (ix < 0x3fdc0000) { /* |x| < 0.4375 */ + if (ix < 0x3e200000) { /* |x| < 2^-29 */ + if (HUGE + x > 1.00000000000000000000e+00) { + return x; /* raise inexact */ + } + } + id = -1; + } else { + x = Math.abs(x); + if (ix < 0x3ff30000) { /* |x| < 1.1875 */ + if (ix < 0x3fe60000) { /* 7/16 <=|x|<11/16 */ + id = 0; + x = (2.0 * x - 1.00000000000000000000e+00) / (2.0 + x); + } else { /* 11/16<=|x|< 19/16 */ + id = 1; + x = (x - 1.00000000000000000000e+00) / (x + 1.00000000000000000000e+00); + } + } else { + if (ix < 0x40038000) { /* |x| < 2.4375 */ + id = 2; + x = (x - 1.5) / (1.00000000000000000000e+00 + 1.5 * x); + } else { /* 2.4375 <= |x| < 2^66 */ + id = 3; + x = -1.0 / x; + } + } + } + + /* end of argument reduction */ + z = x * x; + w = z * z; + /* break sum from i=0 to 10 aT[i]z**(i+1) into odd and even poly */ + s1 = z * (AT0 + w * (AT2 + w + * (AT4 + w * (AT6 + w * (AT8 + w * AT10))))); + s2 = w * (AT1 + w * (AT3 + w * (AT5 + w * (AT7 + w * AT9)))); + if (id < 0) { + return x - x * (s1 + s2); + } else { + z = ATANHI[id] - ((x * (s1 + s2) - ATANLO[id]) - x); + return (hx < 0) ? -z : z; + } + } + + private static final double PI_O_4 = 7.8539816339744827900E-01; + private static final double PI_O_2 = 1.5707963267948965580E+00; + private static final double PI_LO = 1.2246467991473531772E-16; /** * Returns the closest double approximation of the arc tangent of @@ -192,7 +397,108 @@ public final class StrictMath { * the denominator of the value whose atan has to be computed. * @return the arc tangent of {@code y/x}. */ - public static native double atan2(double y, double x); + public static double atan2(double y, double x) { + double z; + int k, m, hx, hy, ix, iy; + int lx, ly; // watch out, should be unsigned + + final long yBits = Double.doubleToRawLongBits(y); + final long xBits = Double.doubleToRawLongBits(x); + + hx = (int) (xBits >>> 32); // __HI(x); + ix = hx & 0x7fffffff; + lx = (int) xBits; // __LO(x); + hy = (int) (yBits >>> 32); // __HI(y); + iy = hy & 0x7fffffff; + ly = (int) yBits; // __LO(y); + if (((ix | ((lx | -lx) >> 31)) > 0x7ff00000) + || ((iy | ((ly | -ly) >> 31)) > 0x7ff00000)) { /* x or y is NaN */ + return x + y; + } + if ((hx - 0x3ff00000 | lx) == 0) { + return StrictMath.atan(y); /* x=1.0 */ + } + + m = ((hy >> 31) & 1) | ((hx >> 30) & 2); /* 2*sign(x)+sign(y) */ + + /* when y = 0 */ + if ((iy | ly) == 0) { + switch (m) { + case 0: + case 1: + return y; /* ieee_atan(+-0,+anything)=+-0 */ + case 2: + return 3.14159265358979311600e+00 + TINY;/* ieee_atan(+0,-anything) = pi */ + case 3: + return -3.14159265358979311600e+00 - TINY;/* ieee_atan(-0,-anything) =-pi */ + } + } + /* when x = 0 */ + if ((ix | lx) == 0) + return (hy < 0) ? -PI_O_2 - TINY : PI_O_2 + TINY; + + /* when x is INF */ + if (ix == 0x7ff00000) { + if (iy == 0x7ff00000) { + switch (m) { + case 0: + return PI_O_4 + TINY;/* ieee_atan(+INF,+INF) */ + case 1: + return -PI_O_4 - TINY;/* ieee_atan(-INF,+INF) */ + case 2: + return 3.0 * PI_O_4 + TINY;/* ieee_atan(+INF,-INF) */ + case 3: + return -3.0 * PI_O_4 - TINY;/* ieee_atan(-INF,-INF) */ + } + } else { + switch (m) { + case 0: + return 0.0; /* ieee_atan(+...,+INF) */ + case 1: + return -0.0; /* ieee_atan(-...,+INF) */ + case 2: + return 3.14159265358979311600e+00 + TINY; /* ieee_atan(+...,-INF) */ + case 3: + return -3.14159265358979311600e+00 - TINY; /* ieee_atan(-...,-INF) */ + } + } + } + /* when y is INF */ + if (iy == 0x7ff00000) + return (hy < 0) ? -PI_O_2 - TINY : PI_O_2 + TINY; + + /* compute y/x */ + k = (iy - ix) >> 20; + if (k > 60) { + z = PI_O_2 + 0.5 * PI_LO; /* |y/x| > 2**60 */ + } else if (hx < 0 && k < -60) { + z = 0.0; /* |y|/x < -2**60 */ + } else { + z = StrictMath.atan(Math.abs(y / x)); /* safe to do y/x */ + } + + switch (m) { + case 0: + return z; /* ieee_atan(+,+) */ + case 1: + // __HI(z) ^= 0x80000000; + z = Double.longBitsToDouble( + Double.doubleToRawLongBits(z) ^ (0x80000000L << 32)); + return z; /* ieee_atan(-,+) */ + case 2: + return 3.14159265358979311600e+00 - (z - PI_LO);/* ieee_atan(+,-) */ + default: /* case 3 */ + return (z - PI_LO) - 3.14159265358979311600e+00;/* ieee_atan(-,-) */ + } + } + + private static final int B1 = 715094163; + private static final int B2 = 696219795; + private static final double C = 5.42857142857142815906e-01; + private static final double D = -7.05306122448979611050e-01; + private static final double CBRTE = 1.41428571428571436819e+00; + private static final double F = 1.60714285714285720630e+00; + private static final double G = 3.57142857142857150787e-01; /** * Returns the closest double approximation of the cube root of the @@ -207,11 +513,79 @@ public final class StrictMath { * <li>{@code cbrt(NaN) = NaN}</li> * </ul> * - * @param d + * @param x * the value whose cube root has to be computed. * @return the cube root of the argument. */ - public static native double cbrt(double d); + public static double cbrt(double x) { + if (x < 0) { + return -cbrt(-x); + } + int hx; + double r, s, w; + int sign; // caution: should be unsigned + long bits = Double.doubleToRawLongBits(x); + + hx = (int) (bits >>> 32); + sign = hx & 0x80000000; /* sign= sign(x) */ + hx ^= sign; + if (hx >= 0x7ff00000) { + return (x + x); /* ieee_cbrt(NaN,INF) is itself */ + } + + if ((hx | ((int) bits)) == 0) { + return x; /* ieee_cbrt(0) is itself */ + } + + // __HI(x) = hx; /* x <- |x| */ + bits &= 0x00000000ffffffffL; + bits |= ((long) hx << 32); + + long tBits = Double.doubleToRawLongBits(0.0) & 0x00000000ffffffffL; + double t = 0.0; + /* rough cbrt to 5 bits */ + if (hx < 0x00100000) { /* subnormal number */ + // __HI(t)=0x43500000; /*set t= 2**54*/ + tBits |= 0x43500000L << 32; + t = Double.longBitsToDouble(tBits); + t *= x; + + // __HI(t)=__HI(t)/3+B2; + tBits = Double.doubleToRawLongBits(t); + long tBitsHigh = tBits >> 32; + tBits &= 0x00000000ffffffffL; + tBits |= ((tBitsHigh / 3) + B2) << 32; + t = Double.longBitsToDouble(tBits); + + } else { + // __HI(t)=hx/3+B1; + tBits |= ((long) ((hx / 3) + B1)) << 32; + t = Double.longBitsToDouble(tBits); + } + + /* new cbrt to 23 bits, may be implemented in single precision */ + r = t * t / x; + s = C + r * t; + t *= G + F / (s + CBRTE + D / s); + + /* chopped to 20 bits and make it larger than ieee_cbrt(x) */ + tBits = Double.doubleToRawLongBits(t); + tBits &= 0xFFFFFFFFL << 32; + tBits += 0x00000001L << 32; + t = Double.longBitsToDouble(tBits); + + /* one step newton iteration to 53 bits with error less than 0.667 ulps */ + s = t * t; /* t*t is exact */ + r = x / s; + w = t + t; + r = (r - t) / (w + r); /* r-s is exact */ + t = t + t * r; + + /* retore the sign bit */ + tBits = Double.doubleToRawLongBits(t); + tBits |= ((long) sign) << 32; + return Double.longBitsToDouble(tBits); + } /** * Returns the double conversion of the most negative (closest to negative @@ -227,8 +601,74 @@ public final class StrictMath { * <li>{@code ceil(NaN) = NaN}</li> * </ul> */ - public static native double ceil(double d); + public static double ceil(double x) { + final long x_asRawLongBits = Double.doubleToRawLongBits(x); + int i0 = (int) (x_asRawLongBits >>> 32); + int i1 = (int) x_asRawLongBits; + final int j0 = ((i0 >> 20) & 0x7ff) - 0x3ff; + + if (j0 < 20) { + // Case where x is not zero. + if (j0 < 0) { + // Case where absolute value of x is less than 1. + if (HUGE + x > 0.0) { + if (i0 < 0) { + i0 = 0x80000000; + i1 = 0; + } else if ((i0 | i1) != 0) { + i0 = 0x3ff00000; + i1 = 0; + } + } + } else { + int i = (0x000fffff) >> j0; + if (((i0 & i) | i1) == 0) { + return x; + } else if (HUGE + x > 0.0) { + if (i0 > 0) { + i0 += (0x00100000) >> j0; + } + i0 &= (~i); + i1 = 0; + } + } + } else if (j0 > 51) { + if (j0 == 0x400) { + return x + x; + } else { + return x; + } + } else { + int i = (0xffffffff) >>> (j0 - 20); + if ((i1 & i) == 0) { + return x; + } + if (HUGE + x > 0.0) { + if (i0 > 0) { + if (j0 == 20) { + i0 += 1; + } else { + int j = i1 + (1 << (52 - j0)); + if ((j ^ Integer.MIN_VALUE) < (i1 ^ Integer.MIN_VALUE)) { + // Carry value over for rounding purposes. + i0 += 1; + } + i1 = j; + } + } + i1 &= (~i); + } + } + x = Double.doubleToRawLongBits(i1); + long bits = Double.doubleToRawLongBits(x); + bits &= 0x00000000FFFFFFFF; + bits |= ((long) i0) << 32; + x = Double.longBitsToDouble(bits); + return x; + } + private static final long ONEBITS = Double.doubleToRawLongBits(1.00000000000000000000e+00) + & 0x00000000ffffffffL; /** * Returns the closest double approximation of the hyperbolic cosine of the @@ -241,11 +681,54 @@ public final class StrictMath { * <li>{@code cosh(NaN) = NaN}</li> * </ul> * - * @param d + * @param x * the value whose hyperbolic cosine has to be computed. * @return the hyperbolic cosine of the argument. */ - public static native double cosh(double d); + public static double cosh(double x) { + double t, w; + int ix; + final long bits = Double.doubleToRawLongBits(x); + ix = (int) (bits >>> 32) & 0x7fffffff; + + /* x is INF or NaN */ + if (ix >= 0x7ff00000) { + return x * x; + } + + /* |x| in [0,0.5*ln2], return 1+ieee_expm1(|x|)^2/(2*ieee_exp(|x|)) */ + if (ix < 0x3fd62e43) { + t = expm1(Math.abs(x)); + w = 1.00000000000000000000e+00 + t; + if (ix < 0x3c800000) + return w; /* ieee_cosh(tiny) = 1 */ + return 1.00000000000000000000e+00 + (t * t) / (w + w); + } + + /* |x| in [0.5*ln2,22], return (ieee_exp(|x|)+1/ieee_exp(|x|)/2; */ + if (ix < 0x40360000) { + t = exp(Math.abs(x)); + return 0.5 * t + 0.5 / t; + } + + /* |x| in [22, ieee_log(maxdouble)] return half*ieee_exp(|x|) */ + if (ix < 0x40862E42) { + return 0.5 * exp(Math.abs(x)); + } + + /* |x| in [log(maxdouble), overflowthresold] */ + final long lx = ((ONEBITS >>> 29) + ((int) bits)) & 0x00000000ffffffffL; + // watch out: lx should be an unsigned int + // lx = *( (((*(unsigned*)&one)>>29)) + (unsigned*)&x); + if (ix < 0x408633CE || (ix == 0x408633ce) && (lx <= 0x8fb9f87dL)) { + w = exp(0.5 * Math.abs(x)); + t = 0.5 * w; + return t * w; + } + + /* |x| > overflowthresold, ieee_cosh(x) overflow */ + return HUGE * HUGE; + } /** * Returns the closest double approximation of the cosine of the argument. @@ -263,6 +746,19 @@ public final class StrictMath { */ public static native double cos(double d); + private static final double TWON24 = 5.96046447753906250000e-08; + private static final double TWO54 = 1.80143985094819840000e+16, + TWOM54 = 5.55111512312578270212e-17; + private static final double TWOM1000 = 9.33263618503218878990e-302; + private static final double O_THRESHOLD = 7.09782712893383973096e+02; + private static final double U_THRESHOLD = -7.45133219101941108420e+02; + private static final double INVLN2 = 1.44269504088896338700e+00; + private static final double P1 = 1.66666666666666019037e-01; + private static final double P2 = -2.77777777770155933842e-03; + private static final double P3 = 6.61375632143793436117e-05; + private static final double P4 = -1.65339022054652515390e-06; + private static final double P5 = 4.13813679705723846039e-08; + /** * Returns the closest double approximation of the raising "e" to the power * of the argument. @@ -274,11 +770,88 @@ public final class StrictMath { * <li>{@code exp(NaN) = NaN}</li> * </ul> * - * @param d + * @param x * the value whose exponential has to be computed. * @return the exponential of the argument. */ - public static native double exp(double d); + public static double exp(double x) { + double y, c, t; + double hi = 0, lo = 0; + int k = 0, xsb; + int hx; // should be unsigned, be careful! + final long bits = Double.doubleToRawLongBits(x); + int lowBits = (int) bits; + int highBits = (int) (bits >>> 32); + hx = highBits & 0x7fffffff; + xsb = (highBits >>> 31) & 1; + + /* filter out non-finite argument */ + if (hx >= 0x40862E42) { /* if |x|>=709.78... */ + if (hx >= 0x7ff00000) { + if (((hx & 0xfffff) | lowBits) != 0) { + return x + x; /* NaN */ + } else { + return (xsb == 0) ? x : 0.0; /* ieee_exp(+-inf)={inf,0} */ + } + } + + if (x > O_THRESHOLD) { + return HUGE * HUGE; /* overflow */ + } + + if (x < U_THRESHOLD) { + return TWOM1000 * TWOM1000; /* underflow */ + } + } + + /* argument reduction */ + if (hx > 0x3fd62e42) { /* if |x| > 0.5 ln2 */ + if (hx < 0x3FF0A2B2) { /* and |x| < 1.5 ln2 */ + hi = x - ((xsb == 0) ? 6.93147180369123816490e-01 : + -6.93147180369123816490e-01); // LN2HI[xsb]; + lo = (xsb == 0) ? 1.90821492927058770002e-10 : + -1.90821492927058770002e-10; // LN2LO[xsb]; + k = 1 - xsb - xsb; + } else { + k = (int) (INVLN2 * x + ((xsb == 0) ? 0.5 : -0.5 ));//halF[xsb]); + t = k; + hi = x - t * 6.93147180369123816490e-01; //ln2HI[0]; /* t*ln2HI is exact here */ + lo = t * 1.90821492927058770002e-10; //ln2LO[0]; + } + x = hi - lo; + } else if (hx < 0x3e300000) { /* when |x|<2**-28 */ + if (HUGE + x > 1.00000000000000000000e+00) + return 1.00000000000000000000e+00 + x;/* trigger inexact */ + } else { + k = 0; + } + + /* x is now in primary range */ + t = x * x; + c = x - t * (P1 + t * (P2 + t * (P3 + t * (P4 + t * P5)))); + if (k == 0) { + return 1.00000000000000000000e+00 - ((x * c) / (c - 2.0) - x); + } else { + y = 1.00000000000000000000e+00 - ((lo - (x * c) / (2.0 - c)) - hi); + } + long yBits = Double.doubleToRawLongBits(y); + if (k >= -1021) { + yBits += ((long) (k << 20)) << 32; /* add k to y's exponent */ + return Double.longBitsToDouble(yBits); + } else { + yBits += ((long) ((k + 1000) << 20)) << 32;/* add k to y's exponent */ + return Double.longBitsToDouble(yBits) * TWOM1000; + } + } + + private static final double TINY = 1.0e-300; + private static final double LN2_HI = 6.93147180369123816490e-01; + private static final double LN2_LO = 1.90821492927058770002e-10; + private static final double Q1 = -3.33333333333331316428e-02; + private static final double Q2 = 1.58730158725481460165e-03; + private static final double Q3 = -7.93650757867487942473e-05; + private static final double Q4 = 4.00821782732936239552e-06; + private static final double Q5 = -2.01099218183624371326e-07; /** * Returns the closest double approximation of <i>{@code e}</i><sup> @@ -295,17 +868,124 @@ public final class StrictMath { * <li>{@code expm1(NaN) = NaN}</li> * </ul> * - * @param d + * @param x * the value to compute the <i>{@code e}</i><sup>{@code d}</sup> * {@code - 1} of. - * @return the <i>{@code e}</i><sup>{@code d}</sup>{@code - 1} value - * of the argument. + * @return the <i>{@code e}</i><sup>{@code d}</sup>{@code - 1} value of the + * argument. */ - public static native double expm1(double d); + public static double expm1(double x) { + double y, hi, lo, t, e, hxs, hfx, r1, c = 0.0; + int k, xsb; + long yBits = 0; + final long bits = Double.doubleToRawLongBits(x); + int highBits = (int) (bits >>> 32); + int lowBits = (int) (bits); + int hx = highBits & 0x7fffffff; // caution: should be unsigned! + xsb = highBits & 0x80000000; /* sign bit of x */ + y = xsb == 0 ? x : -x; /* y = |x| */ + + /* filter out HUGE and non-finite argument */ + if (hx >= 0x4043687A) { /* if |x|>=56*ln2 */ + if (hx >= 0x40862E42) { /* if |x|>=709.78... */ + if (hx >= 0x7ff00000) { + if (((hx & 0xfffff) | lowBits) != 0) { + return x + x; /* NaN */ + } else { + return (xsb == 0) ? x : -1.0;/* ieee_exp(+-inf)={inf,-1} */ + } + } + if (x > O_THRESHOLD) { + return HUGE * HUGE; /* overflow */ + } + } + if (xsb != 0) { /* x < -56*ln2, return -1.0 with inexact */ + if (x + TINY < 0.0) { /* raise inexact */ + return TINY - 1.00000000000000000000e+00; /* return -1 */ + } + } + } + /* argument reduction */ + if (hx > 0x3fd62e42) { /* if |x| > 0.5 ln2 */ + if (hx < 0x3FF0A2B2) { /* and |x| < 1.5 ln2 */ + if (xsb == 0) { + hi = x - LN2_HI; + lo = LN2_LO; + k = 1; + } else { + hi = x + LN2_HI; + lo = -LN2_LO; + k = -1; + } + } else { + k = (int) (INVLN2 * x + ((xsb == 0) ? 0.5 : -0.5)); + t = k; + hi = x - t * LN2_HI; /* t*ln2_hi is exact here */ + lo = t * LN2_LO; + } + x = hi - lo; + c = (hi - x) - lo; + } else if (hx < 0x3c900000) { /* when |x|<2**-54, return x */ + // t = huge+x; /* return x with inexact flags when x!=0 */ + // return x - (t-(huge+x)); + return x; // inexact flag is not set, but Java ignors this flag + // anyway + } else { + k = 0; + } + + /* x is now in primary range */ + hfx = 0.5 * x; + hxs = x * hfx; + r1 = 1.00000000000000000000e+00 + hxs * (Q1 + hxs * (Q2 + hxs * (Q3 + hxs * (Q4 + hxs * Q5)))); + t = 3.0 - r1 * hfx; + e = hxs * ((r1 - t) / (6.0 - x * t)); + if (k == 0) { + return x - (x * e - hxs); /* c is 0 */ + } else { + e = (x * (e - c) - c); + e -= hxs; + if (k == -1) { + return 0.5 * (x - e) - 0.5; + } + + if (k == 1) { + if (x < -0.25) { + return -2.0 * (e - (x + 0.5)); + } else { + return 1.00000000000000000000e+00 + 2.0 * (x - e); + } + } + + if (k <= -2 || k > 56) { /* suffice to return ieee_exp(x)-1 */ + y = 1.00000000000000000000e+00 - (e - x); + yBits = Double.doubleToRawLongBits(y); + yBits += (((long) k) << 52); /* add k to y's exponent */ + return Double.longBitsToDouble(yBits) - 1.00000000000000000000e+00; + } + + long tBits = Double.doubleToRawLongBits(1.00000000000000000000e+00) & 0x00000000ffffffffL; + + if (k < 20) { + tBits |= (((long) 0x3ff00000) - (0x200000 >> k)) << 32; + y = Double.longBitsToDouble(tBits) - (e - x); + yBits = Double.doubleToRawLongBits(y); + yBits += (((long) k) << 52); /* add k to y's exponent */ + return Double.longBitsToDouble(yBits); + } else { + tBits |= ((((long) 0x3ff) - k) << 52); /* 2^-k */ + y = x - (e + Double.longBitsToDouble(tBits)); + y += 1.00000000000000000000e+00; + yBits = Double.doubleToRawLongBits(y); + yBits += (((long) k) << 52); /* add k to y's exponent */ + return Double.longBitsToDouble(yBits); + } + } + } /** - * Returns the double conversion of the most positive (closest to - * positive infinity) integer less than or equal to the argument. + * Returns the double conversion of the most positive (closest to positive + * infinity) integer less than or equal to the argument. * <p> * Special cases: * <ul> @@ -316,12 +996,77 @@ public final class StrictMath { * <li>{@code floor(NaN) = NaN}</li> * </ul> */ - public static native double floor(double d); + public static double floor(double x) { + final long x_asRawLongBits = Double.doubleToRawLongBits(x); + int i0 = (int) (x_asRawLongBits >>> 32); + int i1 = (int) x_asRawLongBits; + int j0 = ((i0 >> 20) & 0x7ff) - 0x3ff; + + if (j0 < 20) { + // Case where x is not zero. + if (j0 < 0) { + // Case where absolute value of x is less than 1. + if (HUGE + x > 0.0) { + if (i0 >= 0) { + i0 = 0; + i1 = 0; + } else if (((i0 & 0x7fffffff) | i1) != 0) { + i0 = 0xbff00000; + i1 = 0; + } + } + } else { + int i = (0x000fffff) >> j0; + if (((i0 & i) | i1) == 0) { + return x; + } + if (HUGE + x > 0.0) { + if (i0 < 0) { + i0 += (0x00100000) >> j0; + } + i0 &= (~i); + i1 = 0; + } + } + } else if (j0 > 51) { + if (j0 == 0x400) { + return x + x; + } else { + return x; + } + } else { + int i = (0xffffffff) >>> (j0 - 20); + if ((i1 & i) == 0) { + return x; + } + if (HUGE + x > 0.0) { + if (i0 < 0) { + if (j0 == 20) { + i0 += 1; + } else { + int j = i1 + (1 << (52 - j0)); + if (j < i1) { + // Carry value over for rounding purposes. + i0 += 1; + } + i1 = j; + } + } + i1 &= (~i); + } + } + x = Double.doubleToRawLongBits(i1); + long bits = Double.doubleToRawLongBits(x); + bits &= 0x00000000FFFFFFFF; + bits |= ((long) i0) << 32; + x = Double.longBitsToDouble(bits); + return x; + } /** - * Returns {@code sqrt(}<i>{@code x}</i><sup>{@code 2}</sup>{@code +} - * <i> {@code y}</i><sup>{@code 2}</sup>{@code )}. The final result is - * without medium underflow or overflow. + * Returns {@code sqrt(}<i>{@code x}</i><sup>{@code 2}</sup>{@code +} <i> + * {@code y}</i><sup>{@code 2}</sup>{@code )}. The final result is without + * medium underflow or overflow. * <p> * Special cases: * <ul> @@ -340,7 +1085,134 @@ public final class StrictMath { * <i> {@code y}</i><sup>{@code 2}</sup>{@code )} value of the * arguments. */ - public static native double hypot(double x, double y); + public static double hypot(double x, double y) { + double a; + double b; + double t1; + double t2; + double y1; + double y2; + double w; + int j; + long bits; + x = StrictMath.abs(x); + y = StrictMath.abs(y); + // Convert x and y to long values for bitwise manipulation. + long x_asRawLongBits = Double.doubleToRawLongBits(x); + long y_asRawLongBits = Double.doubleToRawLongBits(y); + long ha = (x_asRawLongBits >> 32) & 0x7fffffff; + long hb = (y_asRawLongBits >> 32) & 0x7fffffff; + // Ensures that a is always the larger value. + if (hb > ha) { + a = y; + b = x; + j = (int) ha; + ha = hb; + hb = j; + } else { + a = x; + b = y; + } + // Deals with edge case where x is significantly larger than y. + if ((ha - hb) > 0x3c00000) { + if (a + b == Double.NEGATIVE_INFINITY) { + return Double.POSITIVE_INFINITY; + } else { + return a + b; + } + } + int k = 0; + // Deals with edge cases where numbers are infinite or invalid. + if (ha > 0x5f300000) { + if (ha >= 0x7ff00000) { + w = a + b; + if (((ha & 0xfffff) | Double.doubleToRawLongBits(a)) == 0) { + w = a; + } + if (((hb ^ 0x7ff00000) | Double.doubleToRawLongBits(b)) == 0) { + w = b; + } + return w; + } + // Scale a and b by 2**-600. + ha -= 0x25800000; + hb -= 0x25800000; + k += 600; + bits = Double.doubleToRawLongBits(a); + bits &= 0x00000000FFFFFFFF; + bits |= ((long) ha) << 32; + a = Double.longBitsToDouble(bits); + + bits = Double.doubleToRawLongBits(b); + bits &= 0x00000000FFFFFFFF; + bits |= ((long) hb) << 32; + b = Double.longBitsToDouble(bits); + } + // Deals with cases where lesser number is abnormally small. + if (hb < 0x20b00000) { + if (hb <= 0x000fffff) { + if ((hb | (Double.doubleToRawLongBits(b))) == 0) { + return a; + } + t1 = 0; + bits = Double.doubleToRawLongBits(t1); + bits &= 0x00000000FFFFFFFF; + bits |= ((long) 0x7fd00000) << 32; + t1 = Double.longBitsToDouble(bits); + b *= t1; + a *= t1; + k -= 1022; + } else { + ha += 0x25800000; + hb += 0x25800000; + k -= 600; + bits = Double.doubleToRawLongBits(a); + bits &= 0x00000000FFFFFFFF; + bits |= ((long) ha) << 32; + a = Double.longBitsToDouble(bits); + bits = Double.doubleToRawLongBits(b); + bits &= 0x00000000FFFFFFFF; + bits |= ((long) hb) << 32; + b = Double.longBitsToDouble(bits); + } + } + // Deals with cases where both numbers are not overly large or small. + w = a - b; + if (w > b) { + t1 = 0; + bits = Double.doubleToRawLongBits(t1); + bits &= 0x00000000FFFFFFFF; + bits |= ((long) ha) << 32; + t1 = Double.longBitsToDouble(bits); + t2 = a - t1; + w = StrictMath.sqrt(t1 * t1 - (b * (-b) - t2 * (a + t1))); + } else { + a = a + a; + y1 = 0; + bits = Double.doubleToRawLongBits(y1); + bits &= 0x00000000FFFFFFFF; + bits |= ((long) hb) << 32; + y1 = Double.longBitsToDouble(bits); + y2 = b - y1; + t1 = 0; + bits = Double.doubleToRawLongBits(t1); + bits &= 0x00000000FFFFFFFF; + bits |= ((long) ha + 0x00100000) << 32; + t1 = Double.longBitsToDouble(bits); + t2 = a - t1; + w = StrictMath.sqrt(t1 * y1 - (w * (-w) - (t1 * y2 + t2 * b))); + } + if (k != 0) { + t1 = 1.0; + bits = Double.doubleToRawLongBits(t1); + bits &= 0x00000000FFFFFFFF; + bits |= ((long) (k << 20)) << 32; + t1 = Double.longBitsToDouble(bits); + return t1 * w; + } else { + return w; + } + } /** * Returns the remainder of dividing {@code x} by {@code y} using the IEEE @@ -367,7 +1239,80 @@ public final class StrictMath { * the denominator of the operation. * @return the IEEE754 floating point reminder of of {@code x/y}. */ - public static native double IEEEremainder(double x, double y); + public static double IEEEremainder(double x, double y) { + final double zero = 0.0; + // Convert x and y to long data types. + final long x_asRawLongBits = Double.doubleToRawLongBits(x); + int hx = (int) (x_asRawLongBits >>> 32); + int lx = (int) x_asRawLongBits; + final long y_asRawLongBits = Double.doubleToRawLongBits(y); + int hy = (int) (y_asRawLongBits >>> 32); + int ly = (int) y_asRawLongBits; + long sx = hx & 0x80000000; + hy &= 0x7fffffff; + hx &= 0x7fffffff; + + // Deals with edge cases like y = 0 and x or y is NaN. + if ((hy | ly) == 0) { + return (x * y) / (x * y); + } + if ((hx >= 0x7ff00000) || ((hy >= 0x7ff00000) && (((hy - 0x7ff00000) | ly) != 0))) { + return (x * y) / (x * y); + } + if (hy <= 0x7fdfffff) { + x = x % (y + y); + } + if (((hx - hy) | (lx - ly)) == 0) { + return zero * x; + } + + // Ensures positive remainders are returned. + double x1 = x; + double y1 = y; + x = StrictMath.abs(x); + y = StrictMath.abs(y); + double z = x; + if (hy < 0x00200000) { + if (x + x > y) { + z -= y; + if (z + z >= y) { + z -= y; + } + } + } else { + double y_half = 0.5 * y; + if (x > y_half) { + z -= y; + if (z >= y_half) { + z -= y; + } + } + } + + long bits = Double.doubleToRawLongBits(z); + bits &= 0x00000000FFFFFFFF; + bits |= ((long) (sx)) << 32; + z = Double.longBitsToDouble(bits); + + if (x < y && x1 < 0) { + if ((y - x) < x) { + z *= -1; + } + } else if (x >= y && x1 < 0) { + if ((x - y) > y / 2) { + z *= -1; + } + } + return z; + } + + private static final double LG1 = 6.666666666666735130e-01; + private static final double LG2 = 3.999999999940941908e-01; + private static final double LG3 = 2.857142874366239149e-01; + private static final double LG4 = 2.222219843214978396e-01; + private static final double LG5 = 1.818357216161805012e-01; + private static final double LG6 = 1.531383769920937332e-01; + private static final double LG7 = 1.479819860511658591e-01; /** * Returns the closest double approximation of the natural logarithm of the @@ -383,11 +1328,95 @@ public final class StrictMath { * <li>{@code log(NaN) = NaN}</li> * </ul> * - * @param d + * @param x * the value whose log has to be computed. * @return the natural logarithm of the argument. */ - public static native double log(double d); + public static double log(double x) { + double hfsq, f, s, z, R, w, t1, t2, dk; + int hx, i, j, k = 0; + int lx; // watch out, should be unsigned + + long bits = Double.doubleToRawLongBits(x); + hx = (int) (bits >>> 32); /* high word of x */ + lx = (int) bits; /* low word of x */ + + if (hx < 0x00100000) { /* x < 2**-1022 */ + if (((hx & 0x7fffffff) | lx) == 0) { + return -TWO54 / 0.0; /* ieee_log(+-0)=-inf */ + } + + if (hx < 0) { + return (x - x) / 0.0; /* ieee_log(-#) = NaN */ + } + + k -= 54; + x *= TWO54; /* subnormal number, scale up x */ + bits = Double.doubleToRawLongBits(x); + hx = (int) (bits >>> 32); /* high word of x */ + } + + if (hx >= 0x7ff00000) { + return x + x; + } + + k += (hx >> 20) - 1023; + hx &= 0x000fffff; + bits &= 0x00000000ffffffffL; + i = (hx + 0x95f64) & 0x100000; + bits |= ((long) hx | (i ^ 0x3ff00000)) << 32; /* normalize x or x/2 */ + x = Double.longBitsToDouble(bits); + k += (i >> 20); + f = x - 1.0; + + if ((0x000fffff & (2 + hx)) < 3) { /* |f| < 2**-20 */ + if (f == 0.0) { + if (k == 0) { + return 0.0; + } else { + dk = k; + } + return dk * LN2_HI + dk * LN2_LO; + } + + R = f * f * (0.5 - 0.33333333333333333 * f); + if (k == 0) { + return f - R; + } else { + dk = k; + return dk * LN2_HI - ((R - dk * LN2_LO) - f); + } + } + s = f / (2.0 + f); + dk = k; + z = s * s; + i = hx - 0x6147a; + w = z * z; + j = 0x6b851 - hx; + t1 = w * (LG2 + w * (LG4 + w * LG6)); + t2 = z * (LG1 + w * (LG3 + w * (LG5 + w * LG7))); + i |= j; + R = t2 + t1; + if (i > 0) { + hfsq = 0.5 * f * f; + if (k == 0) { + return f - (hfsq - s * (hfsq + R)); + } else { + return dk * LN2_HI + - ((hfsq - (s * (hfsq + R) + dk * LN2_LO)) - f); + } + } else { + if (k == 0) { + return f - s * (f - R); + } else { + return dk * LN2_HI - ((s * (f - R) - dk * LN2_LO) - f); + } + } + } + + private static final double IVLN10 = 4.34294481903251816668e-01; + private static final double LOG10_2HI = 3.01029995663611771306e-01; + private static final double LOG10_2LO = 3.69423907715893078616e-13; /** * Returns the closest double approximation of the base 10 logarithm of the @@ -403,11 +1432,54 @@ public final class StrictMath { * <li>{@code log10(NaN) = NaN}</li> * </ul> * - * @param d + * @param x * the value whose base 10 log has to be computed. - * @return the natural logarithm of the argument. + * @return the the base 10 logarithm of x */ - public static native double log10(double d); + public static double log10(double x) { + double y, z; + int i, k = 0, hx; + int lx; // careful: lx should be unsigned! + long bits = Double.doubleToRawLongBits(x); + hx = (int) (bits >> 32); /* high word of x */ + lx = (int) bits; /* low word of x */ + if (hx < 0x00100000) { /* x < 2**-1022 */ + if (((hx & 0x7fffffff) | lx) == 0) { + return -TWO54 / 0.0; /* ieee_log(+-0)=-inf */ + } + + if (hx < 0) { + return (x - x) / 0.0; /* ieee_log(-#) = NaN */ + } + + k -= 54; + x *= TWO54; /* subnormal number, scale up x */ + bits = Double.doubleToRawLongBits(x); + hx = (int) (bits >> 32); /* high word of x */ + } + + if (hx >= 0x7ff00000) { + return x + x; + } + + k += (hx >> 20) - 1023; + i = (int) (((k & 0x00000000ffffffffL) & 0x80000000) >>> 31); + hx = (hx & 0x000fffff) | ((0x3ff - i) << 20); + y = k + i; + bits &= 0x00000000ffffffffL; + bits |= ((long) hx) << 32; + x = Double.longBitsToDouble(bits); // __HI(x) = hx; + z = y * LOG10_2LO + IVLN10 * log(x); + return z + y * LOG10_2HI; + } + + private static final double LP1 = 6.666666666666735130e-01, + LP2 = 3.999999999940941908e-01, /* 3FD99999 9997FA04 */ + LP3 = 2.857142874366239149e-01, /* 3FD24924 94229359 */ + LP4 = 2.222219843214978396e-01, /* 3FCC71C5 1D8E78AF */ + LP5 = 1.818357216161805012e-01, /* 3FC74664 96CB03DE */ + LP6 = 1.531383769920937332e-01, /* 3FC39A09 D078C69F */ + LP7 = 1.479819860511658591e-01; /* 3FC2F112 DF3E5244 */ /** * Returns the closest double approximation of the natural logarithm of the @@ -426,11 +1498,107 @@ public final class StrictMath { * <li>{@code log1p(NaN) = NaN}</li> * </ul> * - * @param d + * @param x * the value to compute the {@code ln(1+d)} of. * @return the natural logarithm of the sum of the argument and 1. */ - public static native double log1p(double d); + + public static double log1p(double x) { + double hfsq, f = 0.0, c = 0.0, s, z, R, u = 0.0; + int k, hx, hu = 0, ax; + + final long bits = Double.doubleToRawLongBits(x); + hx = (int) (bits >>> 32); /* high word of x */ + ax = hx & 0x7fffffff; + + k = 1; + if (hx < 0x3FDA827A) { /* x < 0.41422 */ + if (ax >= 0x3ff00000) { /* x <= -1.0 */ + if (x == -1.0) { + return -TWO54 / 0.0; /* ieee_log1p(-1)=+inf */ + } else { + return (x - x) / (x - x); /* ieee_log1p(x<-1)=NaN */ + } + } + if (ax < 0x3e200000) { + if (TWO54 + x > 0.0 && ax < 0x3c900000) { + return x; + } else { + return x - x * x * 0.5; + } + } + if (hx > 0 || hx <= 0xbfd2bec3) { + k = 0; + f = x; + hu = 1; + } /* -0.2929<x<0.41422 */ + } + + if (hx >= 0x7ff00000) { + return x + x; + } + + if (k != 0) { + long uBits; + if (hx < 0x43400000) { + u = 1.0 + x; + uBits = Double.doubleToRawLongBits(u); + hu = (int) (uBits >>> 32); + k = (hu >> 20) - 1023; + c = (k > 0) ? 1.0 - (u - x) : x - (u - 1.0);/* correction term */ + c /= u; + } else { + uBits = Double.doubleToRawLongBits(x); + hu = (int) (uBits >>> 32); + k = (hu >> 20) - 1023; + c = 0; + } + hu &= 0x000fffff; + if (hu < 0x6a09e) { + // __HI(u) = hu|0x3ff00000; /* normalize u */ + uBits &= 0x00000000ffffffffL; + uBits |= ((long) hu | 0x3ff00000) << 32; + u = Double.longBitsToDouble(uBits); + } else { + k += 1; + // __HI(u) = hu|0x3fe00000; /* normalize u/2 */ + uBits &= 0xffffffffL; + uBits |= ((long) hu | 0x3fe00000) << 32; + u = Double.longBitsToDouble(uBits); + hu = (0x00100000 - hu) >> 2; + } + f = u - 1.0; + } + hfsq = 0.5 * f * f; + if (hu == 0) { /* |f| < 2**-20 */ + if (f == 0.0) { + if (k == 0) { + return 0.0; + } else { + c += k * LN2_LO; + return k * LN2_HI + c; + } + } + + R = hfsq * (1.0 - 0.66666666666666666 * f); + if (k == 0) { + return f - R; + } else { + return k * LN2_HI - ((R - (k * LN2_LO + c)) - f); + } + } + + s = f / (2.0 + f); + z = s * s; + R = z * (LP1 + z * (LP2 + z + * (LP3 + z * (LP4 + z * (LP5 + z * (LP6 + z * LP7)))))); + if (k == 0) { + return f - (hfsq - s * (hfsq + R)); + } else { + return k * LN2_HI + - ((hfsq - (s * (hfsq + R) + (k * LN2_LO + c))) - f); + } + } /** * Returns the most positive (closest to positive infinity) of the two @@ -453,8 +1621,8 @@ public final class StrictMath { if (d1 != d2) return Double.NaN; /* max( +0.0,-0.0) == +0.0 */ - if (d1 == 0.0 - && ((Double.doubleToLongBits(d1) & Double.doubleToLongBits(d2)) & 0x8000000000000000L) == 0) + if (d1 == 0.0 && + ((Double.doubleToLongBits(d1) & Double.doubleToLongBits(d2)) & 0x8000000000000000L) == 0) return 0.0; return d1; } @@ -480,8 +1648,8 @@ public final class StrictMath { if (f1 != f2) return Float.NaN; /* max( +0.0,-0.0) == +0.0 */ - if (f1 == 0.0f - && ((Float.floatToIntBits(f1) & Float.floatToIntBits(f2)) & 0x80000000) == 0) + if (f1 == 0.0f && + ((Float.floatToIntBits(f1) & Float.floatToIntBits(f2)) & 0x80000000) == 0) return 0.0f; return f1; } @@ -523,8 +1691,8 @@ public final class StrictMath { if (d1 != d2) return Double.NaN; /* min( +0.0,-0.0) == -0.0 */ - if (d1 == 0.0 - && ((Double.doubleToLongBits(d1) | Double.doubleToLongBits(d2)) & 0x8000000000000000l) != 0) + if (d1 == 0.0 && + ((Double.doubleToLongBits(d1) | Double.doubleToLongBits(d2)) & 0x8000000000000000l) != 0) return 0.0 * (-1.0); return d1; } @@ -550,8 +1718,8 @@ public final class StrictMath { if (f1 != f2) return Float.NaN; /* min( +0.0,-0.0) == -0.0 */ - if (f1 == 0.0f - && ((Float.floatToIntBits(f1) | Float.floatToIntBits(f2)) & 0x80000000) != 0) + if (f1 == 0.0f && + ((Float.floatToIntBits(f1) | Float.floatToIntBits(f2)) & 0x80000000) != 0) return 0.0f * (-1.0f); return f1; } @@ -635,11 +1803,91 @@ public final class StrictMath { * <li>{@code rint(NaN) = NaN}</li> * </ul> * - * @param d + * @param x * the value to be rounded. * @return the closest integer to the argument (as a double). */ - public static native double rint(double d); + public static double rint(double x) { + double w; + double t; + long bits; + // Magic numbers from the fdlibm code. + double m0 = 4.50359962737049600000e+15; + double m1 = -4.50359962737049600000e+15; + + // Converting x to a long type for bitwise operations. + final long x_asRawLongBits = Double.doubleToRawLongBits(x); + int i0 = (int) (x_asRawLongBits >>> 32); + int i1 = (int) x_asRawLongBits; + int sx = (i0 >> 31) & 1; + int j0 = ((i0 >> 20) & 0x7ff) - 0x3ff; + + if (j0 < 20) { + if (j0 < 0) { + if (((i0 & 0x7fffffff) | i1) == 0) { + return x; + } + i1 |= (i0 & 0x0fffff); + i0 &= 0xfffe0000; + i0 |= ((i1 | -i1) >> 12) & 0x80000; + + // Convert x to long and replace its upper bits with i0. + bits = Double.doubleToRawLongBits(x); + bits &= 0x00000000FFFFFFFF; + bits |= ((long) (i0)) << 32; + x = Double.longBitsToDouble(bits); + + if (sx == 0) { + w = m0 + x; + t = w - m0; + } else { + w = m1 + x; + t = w - m1; + } + i0 = (int) (Double.doubleToRawLongBits(t) >>> 32); + bits = Double.doubleToRawLongBits(t); + bits &= 0x00000000FFFFFFFF; + bits |= ((long) ((i0 & 0x7fffffff) | (sx << 31))) << 32; + t = Double.longBitsToDouble(bits); + return t; + } else { + int i = (0x000fffff) >> j0; + if (((i0 & i) | i1) == 0) { + return x; + } + i >>= 1; + if (((i0 & i) | i1) != 0) { + if (j0 == 19) { + i1 = 0x40000000; + } else { + i0 = (i0 & (~i)) | ((0x20000) >> j0); + } + } + } + } else if (j0 > 51) { + if (j0 == 0x400) { + return x + x; + } else { + return x; + } + } else { + int i = ((int) (0xffffffff)) >> (j0 - 20); + if ((i1 & i) == 0) { + return x; + } + i >>= 1; + if ((i1 & i) != 0) { + i1 = (i1 & (~i)) | ((0x40000000) >> (j0 - 20)); + } + } + if (sx == 0) { + w = m0 + x; + return w - m0; + } else { + w = m1 + x; + return w - m1; + } + } /** * Returns the result of rounding the argument to an integer. The result is @@ -706,7 +1954,7 @@ public final class StrictMath { * the value whose signum has to be computed. * @return the value of the signum function. */ - public static double signum(double d){ + public static double signum(double d) { return Math.signum(d); } @@ -729,10 +1977,12 @@ public final class StrictMath { * the value whose signum has to be computed. * @return the value of the signum function. */ - public static float signum(float f){ + public static float signum(float f) { return Math.signum(f); } + private static final double shuge = 1.0e307; + /** * Returns the closest double approximation of the hyperbolic sine of the * argument. @@ -746,11 +1996,57 @@ public final class StrictMath { * <li>{@code sinh(NaN) = NaN}</li> * </ul> * - * @param d + * @param x * the value whose hyperbolic sine has to be computed. * @return the hyperbolic sine of the argument. */ - public static native double sinh(double d); + public static double sinh(double x) { + double t, w, h; + int ix, jx; + final long bits = Double.doubleToRawLongBits(x); + + jx = (int) (bits >>> 32); + ix = jx & 0x7fffffff; + + /* x is INF or NaN */ + if (ix >= 0x7ff00000) { + return x + x; + } + + h = 0.5; + if (jx < 0) { + h = -h; + } + + /* |x| in [0,22], return sign(x)*0.5*(E+E/(E+1))) */ + if (ix < 0x40360000) { /* |x|<22 */ + if (ix < 0x3e300000) /* |x|<2**-28 */ + if (shuge + x > 1.00000000000000000000e+00) { + return x;/* ieee_sinh(tiny) = tiny with inexact */ + } + t = expm1(Math.abs(x)); + if (ix < 0x3ff00000) + return h * (2.0 * t - t * t / (t + 1.00000000000000000000e+00)); + return h * (t + t / (t + 1.00000000000000000000e+00)); + } + + /* |x| in [22, ieee_log(maxdouble)] return 0.5*ieee_exp(|x|) */ + if (ix < 0x40862E42) { + return h * exp(Math.abs(x)); + } + + /* |x| in [log(maxdouble), overflowthresold] */ + final long lx = ((ONEBITS >>> 29) + ((int) bits)) & 0x00000000ffffffffL; + // lx = *( (((*(unsigned*)&one)>>29)) + (unsigned*)&x); + if (ix < 0x408633CE || (ix == 0x408633ce) && (lx <= 0x8fb9f87dL)) { + w = exp(0.5 * Math.abs(x)); + t = h * w; + return t * w; + } + + /* |x| > overflowthresold, ieee_sinh(x) overflow */ + return x * shuge; + } /** * Returns the closest double approximation of the sine of the argument. @@ -816,11 +2112,47 @@ public final class StrictMath { * <li>{@code tanh(NaN) = NaN}</li> * </ul> * - * @param d + * @param x * the value whose hyperbolic tangent has to be computed. * @return the hyperbolic tangent of the argument */ - public static native double tanh(double d); + public static double tanh(double x) { + double t, z; + int jx, ix; + + final long bits = Double.doubleToRawLongBits(x); + /* High word of |x|. */ + jx = (int) (bits >>> 32); + ix = jx & 0x7fffffff; + + /* x is INF or NaN */ + if (ix >= 0x7ff00000) { + if (jx >= 0) { + return 1.00000000000000000000e+00 / x + 1.00000000000000000000e+00; /* ieee_tanh(+-inf)=+-1 */ + } else { + return 1.00000000000000000000e+00 / x - 1.00000000000000000000e+00; /* ieee_tanh(NaN) = NaN */ + } + } + + /* |x| < 22 */ + if (ix < 0x40360000) { /* |x|<22 */ + if (ix < 0x3c800000) { /* |x|<2**-55 */ + return x * (1.00000000000000000000e+00 + x);/* ieee_tanh(small) = small */ + } + + if (ix >= 0x3ff00000) { /* |x|>=1 */ + t = Math.expm1(2.0 * Math.abs(x)); + z = 1.00000000000000000000e+00 - 2.0 / (t + 2.0); + } else { + t = Math.expm1(-2.0 * Math.abs(x)); + z = -t / (t + 2.0); + } + /* |x| > 22, return +-1 */ + } else { + z = 1.00000000000000000000e+00 - TINY; /* raised inexact flag */ + } + return (jx >= 0) ? z : -z; + } /** * Returns the measure in degrees of the supplied radian angle. The result @@ -917,11 +2249,78 @@ public final class StrictMath { return Math.ulp(f); } - private static native double nextafter(double x, double y); + /** + * Returns the next machine floating-point number of x in the direction + * toward y. + */ + private static double nextafter(double x, double y) { + double small = 1.4e-45; + long bits; + boolean raise = false; + boolean lower = false; + final long x_asRawLongBits = Double.doubleToRawLongBits(x); + final long y_asRawLongBits = Double.doubleToRawLongBits(y); + int hx = (int) x_asRawLongBits; + int lx = ((int) (x_asRawLongBits >>> 32)) & 0x7fffffff; + int hy = (int) y_asRawLongBits; + int ly = ((int) (y_asRawLongBits >>> 32)) & 0x7fffffff; + int ix = hx & 0x7fffffff; + int iy = hy & 0x7fffffff; + // Deals with edge cases where x and y are 0, invalid, or equal. + if (Double.isNaN(x) || Double.isNaN(y)) { + return Double.NaN; + } + if (x == y) { + return x; + } + if ((ix | lx) == 0) { + return small; + } + // Sets boolean to adjust return value depending on the signs of x and y. + if (x >= 0) { + if (x > y || ((hx == hy) && (lx > ly))) { + lower = true; + } else { + raise = true; + } + } else { + if (x > y || ((hx == hy) && (lx > ly))) { + raise = true; + } else { + lower = true; + } + } + hy = hx & 0x7ff00000; + if (hy >= 0x7ff00000) { + return x + x; + } + if (hy < 0x00100000) { + y = x * x; + if (y != x) { + bits = Double.doubleToRawLongBits(y); + bits &= 0x00000000FFFFFFFF; + bits |= ((long) (hy)) << 32; + y = Double.longBitsToDouble(bits); + return y; + } + } + // Adjust the return value if necessary. + bits = Double.doubleToRawLongBits(x); + bits &= 0x00000000FFFFFFFF; + if (lower) { + bits -= 1; + } + if (raise) { + bits += 1; + } + x = Double.longBitsToDouble(bits); + return x; + } /** * Returns a double with the given magnitude and the sign of {@code sign}. * If {@code sign} is NaN, the sign of the result is positive. + * * @since 1.6 */ public static double copySign(double magnitude, double sign) { @@ -932,13 +2331,15 @@ public final class StrictMath { // (Tested on a Nexus One.) long magnitudeBits = Double.doubleToRawLongBits(magnitude); long signBits = Double.doubleToRawLongBits((sign != sign) ? 1.0 : sign); - magnitudeBits = (magnitudeBits & ~Double.SIGN_MASK) | (signBits & Double.SIGN_MASK); + magnitudeBits = (magnitudeBits & ~Double.SIGN_MASK) + | (signBits & Double.SIGN_MASK); return Double.longBitsToDouble(magnitudeBits); } /** - * Returns a float with the given magnitude and the sign of {@code sign}. - * If {@code sign} is NaN, the sign of the result is positive. + * Returns a float with the given magnitude and the sign of {@code sign}. If + * {@code sign} is NaN, the sign of the result is positive. + * * @since 1.6 */ public static float copySign(float magnitude, float sign) { @@ -949,12 +2350,14 @@ public final class StrictMath { // (Tested on a Nexus One.) int magnitudeBits = Float.floatToRawIntBits(magnitude); int signBits = Float.floatToRawIntBits((sign != sign) ? 1.0f : sign); - magnitudeBits = (magnitudeBits & ~Float.SIGN_MASK) | (signBits & Float.SIGN_MASK); + magnitudeBits = (magnitudeBits & ~Float.SIGN_MASK) + | (signBits & Float.SIGN_MASK); return Float.intBitsToFloat(magnitudeBits); } /** * Returns the exponent of float {@code f}. + * * @since 1.6 */ public static int getExponent(float f) { @@ -963,14 +2366,17 @@ public final class StrictMath { /** * Returns the exponent of double {@code d}. + * * @since 1.6 */ - public static int getExponent(double d){ + public static int getExponent(double d) { return Math.getExponent(d); } /** - * Returns the next double after {@code start} in the given {@code direction}. + * Returns the next double after {@code start} in the given + * {@code direction}. + * * @since 1.6 */ public static double nextAfter(double start, double direction) { @@ -981,7 +2387,9 @@ public final class StrictMath { } /** - * Returns the next float after {@code start} in the given {@code direction}. + * Returns the next float after {@code start} in the given {@code direction} + * . + * * @since 1.6 */ public static float nextAfter(float start, double direction) { @@ -990,6 +2398,7 @@ public final class StrictMath { /** * Returns the next double larger than {@code d}. + * * @since 1.6 */ public static double nextUp(double d) { @@ -998,6 +2407,7 @@ public final class StrictMath { /** * Returns the next float larger than {@code f}. + * * @since 1.6 */ public static float nextUp(float f) { @@ -1006,6 +2416,7 @@ public final class StrictMath { /** * Returns {@code d} * 2^{@code scaleFactor}. The result may be rounded. + * * @since 1.6 */ public static double scalb(double d, int scaleFactor) { @@ -1049,12 +2460,10 @@ public final class StrictMath { } else { if (Math.abs(d) >= Double.MIN_NORMAL) { // common situation - result = ((factor + Double.EXPONENT_BIAS) << Double.MANTISSA_BITS) - | (bits & Double.MANTISSA_MASK); + result = ((factor + Double.EXPONENT_BIAS) << Double.MANTISSA_BITS) | (bits & Double.MANTISSA_MASK); } else { // origin d is sub-normal, change mantissa to normal style - result = ((factor + Double.EXPONENT_BIAS) << Double.MANTISSA_BITS) - | ((bits << (subNormalFactor + 1)) & Double.MANTISSA_MASK); + result = ((factor + Double.EXPONENT_BIAS) << Double.MANTISSA_BITS) | ((bits << (subNormalFactor + 1)) & Double.MANTISSA_MASK); } } return Double.longBitsToDouble(result | sign); @@ -1062,6 +2471,7 @@ public final class StrictMath { /** * Returns {@code d} * 2^{@code scaleFactor}. The result may be rounded. + * * @since 1.6 */ public static float scalb(float d, int scaleFactor) { @@ -1073,8 +2483,7 @@ public final class StrictMath { int factor = ((bits & Float.EXPONENT_MASK) >> Float.MANTISSA_BITS) - Float.EXPONENT_BIAS + scaleFactor; // calculates the factor of sub-normal values - int subNormalFactor = Integer.numberOfLeadingZeros(bits & ~Float.SIGN_MASK) - - Float.EXPONENT_BITS; + int subNormalFactor = Integer.numberOfLeadingZeros(bits & ~Float.SIGN_MASK) - Float.EXPONENT_BITS; if (subNormalFactor < 0) { // not sub-normal values subNormalFactor = 0; @@ -1105,8 +2514,9 @@ public final class StrictMath { | (bits & Float.MANTISSA_MASK); } else { // origin d is sub-normal, change mantissa to normal style - result = ((factor + Float.EXPONENT_BIAS) << Float.MANTISSA_BITS) - | ((bits << (subNormalFactor + 1)) & Float.MANTISSA_MASK); + result = ((factor + Float.EXPONENT_BIAS) + << Float.MANTISSA_BITS) | ( + (bits << (subNormalFactor + 1)) & Float.MANTISSA_MASK); } } return Float.intBitsToFloat(result | sign); @@ -1120,10 +2530,10 @@ public final class StrictMath { } // change it to positive int absDigits = -digits; - if (Integer.numberOfLeadingZeros(bits & ~Float.SIGN_MASK) <= (32 - absDigits)) { + if (Integer.numberOfLeadingZeros(bits & ~Float.SIGN_MASK) + <= (32 - absDigits)) { // some bits will remain after shifting, calculates its carry - if ((((bits >> (absDigits - 1)) & 0x1) == 0) - || Integer.numberOfTrailingZeros(bits) == (absDigits - 1)) { + if ((((bits >> (absDigits - 1)) & 0x1) == 0) || Integer.numberOfTrailingZeros(bits) == (absDigits - 1)) { return bits >> absDigits; } return ((bits >> absDigits) + 1); @@ -1139,10 +2549,10 @@ public final class StrictMath { } // change it to positive long absDigits = -digits; - if (Long.numberOfLeadingZeros(bits & ~Double.SIGN_MASK) <= (64 - absDigits)) { + if (Long.numberOfLeadingZeros(bits & ~Double.SIGN_MASK) + <= (64 - absDigits)) { // some bits will remain after shifting, calculates its carry - if ((((bits >> (absDigits - 1)) & 0x1) == 0) - || Long.numberOfTrailingZeros(bits) == (absDigits - 1)) { + if ((((bits >> (absDigits - 1)) & 0x1) == 0) || Long.numberOfTrailingZeros(bits) == (absDigits - 1)) { return bits >> absDigits; } return ((bits >> absDigits) + 1); diff --git a/luni/src/main/java/java/util/logging/FileHandler.java b/luni/src/main/java/java/util/logging/FileHandler.java index 6ffef87..1fd1dbf 100644 --- a/luni/src/main/java/java/util/logging/FileHandler.java +++ b/luni/src/main/java/java/util/logging/FileHandler.java @@ -261,15 +261,15 @@ public class FileHandler extends StreamHandler { boolean hasUniqueID = false; boolean hasGeneration = false; - // TODO privilege code? + String homePath = System.getProperty("user.home"); + if (homePath == null) { + throw new NullPointerException("System property \"user.home\" is null"); + } + boolean homePathHasSepEnd = homePath.endsWith(File.separator); String tempPath = System.getProperty("java.io.tmpdir"); - boolean tempPathHasSepEnd = (tempPath == null ? false : tempPath - .endsWith(File.separator)); - - String homePath = System.getProperty("user.home"); - boolean homePathHasSepEnd = (homePath == null ? false : homePath - .endsWith(File.separator)); + tempPath = tempPath == null ? homePath : tempPath; + boolean tempPathHasSepEnd = tempPath.endsWith(File.separator); StringBuilder sb = new StringBuilder(); pattern = pattern.replace('/', File.separatorChar); diff --git a/luni/src/main/java/java/util/logging/SocketHandler.java b/luni/src/main/java/java/util/logging/SocketHandler.java index 48bfc0e..c6d4be0 100644 --- a/luni/src/main/java/java/util/logging/SocketHandler.java +++ b/luni/src/main/java/java/util/logging/SocketHandler.java @@ -106,9 +106,13 @@ public class SocketHandler extends StreamHandler { throw new IllegalArgumentException("host == null || host.isEmpty()"); } // check the validity of the port number - int p = 0; + int p; try { p = Integer.parsePositiveInt(port); + // Must be >= 0 to get this far. 0 is invalid too. + if (p == 0) { + throw new IllegalArgumentException("Illegal port argument " + port); + } } catch (NumberFormatException e) { throw new IllegalArgumentException("Illegal port argument " + port); } diff --git a/luni/src/main/java/java/util/logging/XMLFormatter.java b/luni/src/main/java/java/util/logging/XMLFormatter.java index 0d80b3e..3952596 100644 --- a/luni/src/main/java/java/util/logging/XMLFormatter.java +++ b/luni/src/main/java/java/util/logging/XMLFormatter.java @@ -17,6 +17,7 @@ package java.util.logging; +import java.io.IOException; import java.text.MessageFormat; import java.util.Date; import java.util.ResourceBundle; @@ -50,7 +51,7 @@ public class XMLFormatter extends Formatter { // call a method of LogRecord to ensure not null long time = r.getMillis(); // format to date - String date = MessageFormat.format("{0, date} {0, time}", new Object[] { new Date(time) }); + String date = MessageFormat.format("{0, date} {0, time}", new Date(time)); String nl = System.lineSeparator(); StringBuilder sb = new StringBuilder(); @@ -59,21 +60,21 @@ public class XMLFormatter extends Formatter { append(sb, 1, "millis", time); append(sb, 1, "sequence", r.getSequenceNumber()); if (r.getLoggerName() != null) { - append(sb, 1, "logger", r.getLoggerName()); + escapeAndAppend(sb, 1, "logger", r.getLoggerName()); } append(sb, 1, "level", r.getLevel().getName()); if (r.getSourceClassName() != null) { append(sb, 1, "class", r.getSourceClassName()); } if (r.getSourceMethodName() != null) { - append(sb, 1, "method", r.getSourceMethodName()); + escapeAndAppend(sb, 1, "method", r.getSourceMethodName()); } append(sb, 1, "thread", r.getThreadID()); formatMessages(r, sb); Object[] params = r.getParameters(); if (params != null) { for (Object element : params) { - append(sb, 1, "param", element); + escapeAndAppend(sb, 1, "param", element); } } formatThrowable(r, sb); @@ -96,14 +97,14 @@ public class XMLFormatter extends Formatter { if (message == null) { message = pattern; - append(sb, 1, "message", message); + escapeAndAppend(sb, 1, "message", message); } else { - append(sb, 1, "message", message); - append(sb, 1, "key", pattern); - append(sb, 1, "catalog", r.getResourceBundleName()); + escapeAndAppend(sb, 1, "message", message); + escapeAndAppend(sb, 1, "key", pattern); + escapeAndAppend(sb, 1, "catalog", r.getResourceBundleName()); } } else if (pattern != null) { - append(sb, 1, "message", pattern); + escapeAndAppend(sb, 1, "message", pattern); } else { sb.append(indent).append("<message/>"); } @@ -114,13 +115,13 @@ public class XMLFormatter extends Formatter { if ((t = r.getThrown()) != null) { String nl = System.lineSeparator(); sb.append(indent).append("<exception>").append(nl); - append(sb, 2, "message", t.toString()); + escapeAndAppend(sb, 2, "message", t.toString()); // format throwable's stack trace StackTraceElement[] elements = t.getStackTrace(); for (StackTraceElement e : elements) { sb.append(indent).append(indent).append("<frame>").append(nl); append(sb, 3, "class", e.getClassName()); - append(sb, 3, "method", e.getMethodName()); + escapeAndAppend(sb, 3, "method", e.getMethodName()); append(sb, 3, "line", e.getLineNumber()); sb.append(indent).append(indent).append("</frame>").append(nl); } @@ -138,6 +139,49 @@ public class XMLFormatter extends Formatter { sb.append(System.lineSeparator()); } + private static void escapeAndAppend(StringBuilder sb, int indentCount, String tag, Object value) { + if (value == null) { + append(sb, indentCount, tag, value); + } else { + for (int i = 0; i < indentCount; ++i) { + sb.append(indent); + } + sb.append("<").append(tag).append(">"); + try { + escapeXml(sb, value.toString()); + } catch (IOException e) { + throw new AssertionError(); + } + sb.append("</").append(tag).append(">"); + sb.append(System.lineSeparator()); + } + } + + private static void escapeXml(Appendable valueBuilder, String value) throws IOException { + for (int i = 0; i < value.length(); i++) { + char c = value.charAt(i); + switch (c) { + case '\"': + valueBuilder.append("""); + break; + case '>': + valueBuilder.append(">"); + break; + case '<': + valueBuilder.append("<"); + break; + case '&': + valueBuilder.append("&"); + break; + case '\'': + valueBuilder.append("'"); + break; + default: + valueBuilder.append(c); + } + } + } + /** * Returns the header string for a set of log records formatted as XML * strings, using the output handler's encoding if it is defined, otherwise diff --git a/luni/src/main/java/java/util/zip/ZipEntry.java b/luni/src/main/java/java/util/zip/ZipEntry.java index 217cc3c..d007b0f 100644 --- a/luni/src/main/java/java/util/zip/ZipEntry.java +++ b/luni/src/main/java/java/util/zip/ZipEntry.java @@ -52,7 +52,6 @@ public class ZipEntry implements ZipConstants, Cloneable { byte[] extra; - int nameLength = -1; long localHeaderRelOffset = -1; long dataOffset = -1; @@ -69,7 +68,7 @@ public class ZipEntry implements ZipConstants, Cloneable { ZipEntry(String name, String comment, long crc, long compressedSize, long size, int compressionMethod, int time, int modDate, byte[] extra, - int nameLength, long localHeaderRelOffset, long dataOffset) { + long localHeaderRelOffset, long dataOffset) { this.name = name; this.comment = comment; this.crc = crc; @@ -79,7 +78,6 @@ public class ZipEntry implements ZipConstants, Cloneable { this.time = time; this.modDate = modDate; this.extra = extra; - this.nameLength = nameLength; this.localHeaderRelOffset = localHeaderRelOffset; this.dataOffset = dataOffset; } @@ -340,7 +338,6 @@ public class ZipEntry implements ZipConstants, Cloneable { compressionMethod = ze.compressionMethod; modDate = ze.modDate; extra = ze.extra; - nameLength = ze.nameLength; localHeaderRelOffset = ze.localHeaderRelOffset; dataOffset = ze.dataOffset; } @@ -412,7 +409,7 @@ public class ZipEntry implements ZipConstants, Cloneable { compressedSize = ((long) it.readInt()) & 0xffffffffL; size = ((long) it.readInt()) & 0xffffffffL; - nameLength = it.readShort() & 0xffff; + int nameLength = it.readShort() & 0xffff; int extraLength = it.readShort() & 0xffff; int commentByteCount = it.readShort() & 0xffff; diff --git a/luni/src/main/native/java_lang_StrictMath.cpp b/luni/src/main/native/java_lang_StrictMath.cpp index cfe375e..972e272 100644 --- a/luni/src/main/native/java_lang_StrictMath.cpp +++ b/luni/src/main/native/java_lang_StrictMath.cpp @@ -34,115 +34,20 @@ static jdouble StrictMath_tan(JNIEnv*, jclass, jdouble a) { return ieee_tan(a); } -static jdouble StrictMath_asin(JNIEnv*, jclass, jdouble a) { - return ieee_asin(a); -} - -static jdouble StrictMath_acos(JNIEnv*, jclass, jdouble a) { - return ieee_acos(a); -} - -static jdouble StrictMath_atan(JNIEnv*, jclass, jdouble a) { - return ieee_atan(a); -} - -static jdouble StrictMath_exp(JNIEnv*, jclass, jdouble a) { - return ieee_exp(a); -} - -static jdouble StrictMath_log(JNIEnv*, jclass, jdouble a) { - return ieee_log(a); -} - static jdouble StrictMath_sqrt(JNIEnv*, jclass, jdouble a) { return ieee_sqrt(a); } -static jdouble StrictMath_IEEEremainder(JNIEnv*, jclass, jdouble a, jdouble b) { - return ieee_remainder(a, b); -} - -static jdouble StrictMath_floor(JNIEnv*, jclass, jdouble a) { - return ieee_floor(a); -} - -static jdouble StrictMath_ceil(JNIEnv*, jclass, jdouble a) { - return ieee_ceil(a); -} - -static jdouble StrictMath_rint(JNIEnv*, jclass, jdouble a) { - return ieee_rint(a); -} - -static jdouble StrictMath_atan2(JNIEnv*, jclass, jdouble a, jdouble b) { - return ieee_atan2(a, b); -} - static jdouble StrictMath_pow(JNIEnv*, jclass, jdouble a, jdouble b) { return ieee_pow(a,b); } -static jdouble StrictMath_sinh(JNIEnv*, jclass, jdouble a) { - return ieee_sinh(a); -} - -static jdouble StrictMath_tanh(JNIEnv*, jclass, jdouble a) { - return ieee_tanh(a); -} - -static jdouble StrictMath_cosh(JNIEnv*, jclass, jdouble a) { - return ieee_cosh(a); -} - -static jdouble StrictMath_log10(JNIEnv*, jclass, jdouble a) { - return ieee_log10(a); -} - -static jdouble StrictMath_cbrt(JNIEnv*, jclass, jdouble a) { - return ieee_cbrt(a); -} - -static jdouble StrictMath_expm1(JNIEnv*, jclass, jdouble a) { - return ieee_expm1(a); -} - -static jdouble StrictMath_hypot(JNIEnv*, jclass, jdouble a, jdouble b) { - return ieee_hypot(a, b); -} - -static jdouble StrictMath_log1p(JNIEnv*, jclass, jdouble a) { - return ieee_log1p(a); -} - -static jdouble StrictMath_nextafter(JNIEnv*, jclass, jdouble a, jdouble b) { - return ieee_nextafter(a, b); -} - static JNINativeMethod gMethods[] = { - NATIVE_METHOD(StrictMath, IEEEremainder, "!(DD)D"), - NATIVE_METHOD(StrictMath, acos, "!(D)D"), - NATIVE_METHOD(StrictMath, asin, "!(D)D"), - NATIVE_METHOD(StrictMath, atan, "!(D)D"), - NATIVE_METHOD(StrictMath, atan2, "!(DD)D"), - NATIVE_METHOD(StrictMath, cbrt, "!(D)D"), - NATIVE_METHOD(StrictMath, ceil, "!(D)D"), NATIVE_METHOD(StrictMath, cos, "!(D)D"), - NATIVE_METHOD(StrictMath, cosh, "!(D)D"), - NATIVE_METHOD(StrictMath, exp, "!(D)D"), - NATIVE_METHOD(StrictMath, expm1, "!(D)D"), - NATIVE_METHOD(StrictMath, floor, "!(D)D"), - NATIVE_METHOD(StrictMath, hypot, "!(DD)D"), - NATIVE_METHOD(StrictMath, log, "!(D)D"), - NATIVE_METHOD(StrictMath, log10, "!(D)D"), - NATIVE_METHOD(StrictMath, log1p, "!(D)D"), - NATIVE_METHOD(StrictMath, nextafter, "!(DD)D"), NATIVE_METHOD(StrictMath, pow, "!(DD)D"), - NATIVE_METHOD(StrictMath, rint, "!(D)D"), NATIVE_METHOD(StrictMath, sin, "!(D)D"), - NATIVE_METHOD(StrictMath, sinh, "!(D)D"), NATIVE_METHOD(StrictMath, sqrt, "!(D)D"), NATIVE_METHOD(StrictMath, tan, "!(D)D"), - NATIVE_METHOD(StrictMath, tanh, "!(D)D"), }; void register_java_lang_StrictMath(JNIEnv* env) { jniRegisterNativeMethods(env, "java/lang/StrictMath", gMethods, NELEM(gMethods)); diff --git a/luni/src/main/native/java_util_jar_StrictJarFile.cpp b/luni/src/main/native/java_util_jar_StrictJarFile.cpp index 7611749..b10ec43 100644 --- a/luni/src/main/native/java_util_jar_StrictJarFile.cpp +++ b/luni/src/main/native/java_util_jar_StrictJarFile.cpp @@ -32,11 +32,10 @@ static void throwIoException(JNIEnv* env, const int32_t errorCode) { jniThrowException(env, "java/io/IOException", ErrorCodeString(errorCode)); } -static jobject newZipEntry(JNIEnv* env, const ZipEntry& entry, jstring entryName, - const uint16_t nameLength) { +static jobject newZipEntry(JNIEnv* env, const ZipEntry& entry, jstring entryName) { ScopedLocalRef<jclass> zipEntryClass(env, env->FindClass("java/util/zip/ZipEntry")); const jmethodID zipEntryCtor = env->GetMethodID(zipEntryClass.get(), "<init>", - "(Ljava/lang/String;Ljava/lang/String;JJJIII[BIJJ)V"); + "(Ljava/lang/String;Ljava/lang/String;JJJIII[BJJ)V"); return env->NewObject(zipEntryClass.get(), zipEntryCtor, @@ -49,7 +48,6 @@ static jobject newZipEntry(JNIEnv* env, const ZipEntry& entry, jstring entryName static_cast<jint>(0), // time static_cast<jint>(0), // modData NULL, // byte[] extra - static_cast<jint>(nameLength), static_cast<jlong>(-1), // local header offset static_cast<jlong>(entry.offset)); } @@ -72,25 +70,20 @@ static jlong StrictJarFile_nativeOpenJarFile(JNIEnv* env, jobject, jstring fileN class IterationHandle { public: - IterationHandle(const char* prefix) : - cookie_(NULL), prefix_(strdup(prefix)) { + IterationHandle() : + cookie_(NULL) { } void** CookieAddress() { return &cookie_; } - const char* Prefix() const { - return prefix_; - } - ~IterationHandle() { - free(prefix_); + EndIteration(cookie_); } private: void* cookie_; - char* prefix_; }; @@ -101,14 +94,15 @@ static jlong StrictJarFile_nativeStartIteration(JNIEnv* env, jobject, jlong nati return static_cast<jlong>(-1); } - IterationHandle* handle = new IterationHandle(prefixChars.c_str()); + IterationHandle* handle = new IterationHandle(); int32_t error = 0; if (prefixChars.size() == 0) { error = StartIteration(reinterpret_cast<ZipArchiveHandle>(nativeHandle), handle->CookieAddress(), NULL); } else { + ZipEntryName entry_name(prefixChars.c_str()); error = StartIteration(reinterpret_cast<ZipArchiveHandle>(nativeHandle), - handle->CookieAddress(), handle->Prefix()); + handle->CookieAddress(), &entry_name); } if (error) { @@ -135,7 +129,7 @@ static jobject StrictJarFile_nativeNextEntry(JNIEnv* env, jobject, jlong iterati entryNameCString[entryName.name_length] = '\0'; ScopedLocalRef<jstring> entryNameString(env, env->NewStringUTF(entryNameCString.get())); - return newZipEntry(env, data, entryNameString.get(), entryName.name_length); + return newZipEntry(env, data, entryNameString.get()); } static jobject StrictJarFile_nativeFindEntry(JNIEnv* env, jobject, jlong nativeHandle, @@ -147,12 +141,12 @@ static jobject StrictJarFile_nativeFindEntry(JNIEnv* env, jobject, jlong nativeH ZipEntry data; const int32_t error = FindEntry(reinterpret_cast<ZipArchiveHandle>(nativeHandle), - entryNameChars.c_str(), &data); + ZipEntryName(entryNameChars.c_str()), &data); if (error) { return NULL; } - return newZipEntry(env, data, entryName, entryNameChars.size()); + return newZipEntry(env, data, entryName); } static void StrictJarFile_nativeClose(JNIEnv*, jobject, jlong nativeHandle) { diff --git a/luni/src/main/native/libcore_io_Posix.cpp b/luni/src/main/native/libcore_io_Posix.cpp index e8e8efb..6808dd6 100644 --- a/luni/src/main/native/libcore_io_Posix.cpp +++ b/luni/src/main/native/libcore_io_Posix.cpp @@ -873,8 +873,9 @@ static jint Posix_gettid(JNIEnv* env __unused, jobject) { return 0; } return static_cast<jint>(owner); +#elif defined(__BIONIC__) + return gettid(); #else - // Neither bionic nor glibc exposes gettid(2). return syscall(__NR_gettid); #endif } diff --git a/luni/src/test/java/libcore/java/security/cert/CertificateFactoryTest.java b/luni/src/test/java/libcore/java/security/cert/CertificateFactoryTest.java index e2f21e8..30185d1 100644 --- a/luni/src/test/java/libcore/java/security/cert/CertificateFactoryTest.java +++ b/luni/src/test/java/libcore/java/security/cert/CertificateFactoryTest.java @@ -17,10 +17,10 @@ package libcore.java.security.cert; import com.android.org.bouncycastle.asn1.x509.BasicConstraints; +import com.android.org.bouncycastle.asn1.x509.SubjectKeyIdentifier; import com.android.org.bouncycastle.asn1.x509.X509Extensions; import com.android.org.bouncycastle.x509.X509V3CertificateGenerator; import com.android.org.bouncycastle.x509.extension.AuthorityKeyIdentifierStructure; -import com.android.org.bouncycastle.x509.extension.SubjectKeyIdentifierStructure; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; @@ -571,7 +571,7 @@ public class CertificateFactoryTest extends TestCase { } certGen.addExtension(X509Extensions.SubjectKeyIdentifier, false, - new SubjectKeyIdentifierStructure(keyPair.getPublic())); + SubjectKeyIdentifier.getInstance(keyPair.getPublic().getEncoded())); certGen.addExtension(X509Extensions.BasicConstraints, true, basicConstraints); X509Certificate cert = certGen.generate(caKey); |