Sat, 03 Jan 2015 20:18:00 +0100
Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.
michael@0 | 1 | |
michael@0 | 2 | /* |
michael@0 | 3 | * Copyright 2008 The Android Open Source Project |
michael@0 | 4 | * |
michael@0 | 5 | * Use of this source code is governed by a BSD-style license that can be |
michael@0 | 6 | * found in the LICENSE file. |
michael@0 | 7 | */ |
michael@0 | 8 | |
michael@0 | 9 | |
michael@0 | 10 | #include "SkFloat.h" |
michael@0 | 11 | #include "SkMathPriv.h" |
michael@0 | 12 | |
michael@0 | 13 | #define EXP_BIAS (127+23) |
michael@0 | 14 | |
michael@0 | 15 | static int get_unsigned_exp(uint32_t packed) |
michael@0 | 16 | { |
michael@0 | 17 | return (packed << 1 >> 24); |
michael@0 | 18 | } |
michael@0 | 19 | |
michael@0 | 20 | static unsigned get_unsigned_value(uint32_t packed) |
michael@0 | 21 | { |
michael@0 | 22 | return (packed << 9 >> 9) | (1 << 23); |
michael@0 | 23 | } |
michael@0 | 24 | |
michael@0 | 25 | static int get_signed_value(int32_t packed) |
michael@0 | 26 | { |
michael@0 | 27 | return SkApplySign(get_unsigned_value(packed), SkExtractSign(packed)); |
michael@0 | 28 | } |
michael@0 | 29 | |
michael@0 | 30 | ///////////////////////////////////////////////////////////////////////// |
michael@0 | 31 | |
michael@0 | 32 | int SkFloat::GetShift(int32_t packed, int shift) |
michael@0 | 33 | { |
michael@0 | 34 | if (packed == 0) |
michael@0 | 35 | return 0; |
michael@0 | 36 | |
michael@0 | 37 | int exp = get_unsigned_exp(packed) - EXP_BIAS - shift; |
michael@0 | 38 | int value = get_unsigned_value(packed); |
michael@0 | 39 | |
michael@0 | 40 | if (exp >= 0) |
michael@0 | 41 | { |
michael@0 | 42 | if (exp > 8) // overflow |
michael@0 | 43 | value = SK_MaxS32; |
michael@0 | 44 | else |
michael@0 | 45 | value <<= exp; |
michael@0 | 46 | } |
michael@0 | 47 | else |
michael@0 | 48 | { |
michael@0 | 49 | exp = -exp; |
michael@0 | 50 | if (exp > 23) // underflow |
michael@0 | 51 | value = 0; |
michael@0 | 52 | else |
michael@0 | 53 | value >>= exp; |
michael@0 | 54 | } |
michael@0 | 55 | return SkApplySign(value, SkExtractSign(packed)); |
michael@0 | 56 | } |
michael@0 | 57 | |
michael@0 | 58 | ///////////////////////////////////////////////////////////////////////////////////// |
michael@0 | 59 | |
michael@0 | 60 | int32_t SkFloat::SetShift(int value, int shift) |
michael@0 | 61 | { |
michael@0 | 62 | if (value == 0) |
michael@0 | 63 | return 0; |
michael@0 | 64 | |
michael@0 | 65 | // record the sign and make value positive |
michael@0 | 66 | int sign = SkExtractSign(value); |
michael@0 | 67 | value = SkApplySign(value, sign); |
michael@0 | 68 | |
michael@0 | 69 | if (value >> 24) // value is too big (has more than 24 bits set) |
michael@0 | 70 | { |
michael@0 | 71 | int bias = 8 - SkCLZ(value); |
michael@0 | 72 | SkASSERT(bias > 0 && bias < 8); |
michael@0 | 73 | value >>= bias; |
michael@0 | 74 | shift += bias; |
michael@0 | 75 | } |
michael@0 | 76 | else |
michael@0 | 77 | { |
michael@0 | 78 | int zeros = SkCLZ(value << 8); |
michael@0 | 79 | SkASSERT(zeros >= 0 && zeros <= 23); |
michael@0 | 80 | value <<= zeros; |
michael@0 | 81 | shift -= zeros; |
michael@0 | 82 | } |
michael@0 | 83 | // now value is left-aligned to 24 bits |
michael@0 | 84 | SkASSERT((value >> 23) == 1); |
michael@0 | 85 | |
michael@0 | 86 | shift += EXP_BIAS; |
michael@0 | 87 | if (shift < 0) // underflow |
michael@0 | 88 | return 0; |
michael@0 | 89 | else |
michael@0 | 90 | { |
michael@0 | 91 | if (shift > 255) // overflow |
michael@0 | 92 | { |
michael@0 | 93 | shift = 255; |
michael@0 | 94 | value = 0x00FFFFFF; |
michael@0 | 95 | } |
michael@0 | 96 | int32_t packed = sign << 31; // set the sign-bit |
michael@0 | 97 | packed |= shift << 23; // store the packed exponent |
michael@0 | 98 | packed |= ((unsigned)(value << 9) >> 9); // clear 24th bit of value (its implied) |
michael@0 | 99 | |
michael@0 | 100 | #ifdef SK_DEBUG |
michael@0 | 101 | { |
michael@0 | 102 | int n; |
michael@0 | 103 | |
michael@0 | 104 | n = SkExtractSign(packed); |
michael@0 | 105 | SkASSERT(n == sign); |
michael@0 | 106 | n = get_unsigned_exp(packed); |
michael@0 | 107 | SkASSERT(n == shift); |
michael@0 | 108 | n = get_unsigned_value(packed); |
michael@0 | 109 | SkASSERT(n == value); |
michael@0 | 110 | } |
michael@0 | 111 | #endif |
michael@0 | 112 | return packed; |
michael@0 | 113 | } |
michael@0 | 114 | } |
michael@0 | 115 | |
michael@0 | 116 | int32_t SkFloat::Neg(int32_t packed) |
michael@0 | 117 | { |
michael@0 | 118 | if (packed) |
michael@0 | 119 | packed = packed ^ (1 << 31); |
michael@0 | 120 | return packed; |
michael@0 | 121 | } |
michael@0 | 122 | |
michael@0 | 123 | int32_t SkFloat::Add(int32_t packed_a, int32_t packed_b) |
michael@0 | 124 | { |
michael@0 | 125 | if (packed_a == 0) |
michael@0 | 126 | return packed_b; |
michael@0 | 127 | if (packed_b == 0) |
michael@0 | 128 | return packed_a; |
michael@0 | 129 | |
michael@0 | 130 | int exp_a = get_unsigned_exp(packed_a); |
michael@0 | 131 | int exp_b = get_unsigned_exp(packed_b); |
michael@0 | 132 | int exp_diff = exp_a - exp_b; |
michael@0 | 133 | |
michael@0 | 134 | int shift_a = 0, shift_b = 0; |
michael@0 | 135 | int exp; |
michael@0 | 136 | |
michael@0 | 137 | if (exp_diff >= 0) |
michael@0 | 138 | { |
michael@0 | 139 | if (exp_diff > 24) // B is too small to contribute |
michael@0 | 140 | return packed_a; |
michael@0 | 141 | shift_b = exp_diff; |
michael@0 | 142 | exp = exp_a; |
michael@0 | 143 | } |
michael@0 | 144 | else |
michael@0 | 145 | { |
michael@0 | 146 | exp_diff = -exp_diff; |
michael@0 | 147 | if (exp_diff > 24) // A is too small to contribute |
michael@0 | 148 | return packed_b; |
michael@0 | 149 | shift_a = exp_diff; |
michael@0 | 150 | exp = exp_b; |
michael@0 | 151 | } |
michael@0 | 152 | |
michael@0 | 153 | int value_a = get_signed_value(packed_a) >> shift_a; |
michael@0 | 154 | int value_b = get_signed_value(packed_b) >> shift_b; |
michael@0 | 155 | |
michael@0 | 156 | return SkFloat::SetShift(value_a + value_b, exp - EXP_BIAS); |
michael@0 | 157 | } |
michael@0 | 158 | |
michael@0 | 159 | static inline int32_t mul24(int32_t a, int32_t b) { |
michael@0 | 160 | int64_t tmp = (sk_64_mul(a, b) + (1 << 23)) >> 24; |
michael@0 | 161 | return sk_64_asS32(tmp); |
michael@0 | 162 | } |
michael@0 | 163 | |
michael@0 | 164 | int32_t SkFloat::Mul(int32_t packed_a, int32_t packed_b) |
michael@0 | 165 | { |
michael@0 | 166 | if (packed_a == 0 || packed_b == 0) |
michael@0 | 167 | return 0; |
michael@0 | 168 | |
michael@0 | 169 | int exp_a = get_unsigned_exp(packed_a); |
michael@0 | 170 | int exp_b = get_unsigned_exp(packed_b); |
michael@0 | 171 | |
michael@0 | 172 | int value_a = get_signed_value(packed_a); |
michael@0 | 173 | int value_b = get_signed_value(packed_b); |
michael@0 | 174 | |
michael@0 | 175 | return SkFloat::SetShift(mul24(value_a, value_b), exp_a + exp_b - 2*EXP_BIAS + 24); |
michael@0 | 176 | } |
michael@0 | 177 | |
michael@0 | 178 | int32_t SkFloat::MulInt(int32_t packed, int n) |
michael@0 | 179 | { |
michael@0 | 180 | return Mul(packed, SetShift(n, 0)); |
michael@0 | 181 | } |
michael@0 | 182 | |
michael@0 | 183 | int32_t SkFloat::Div(int32_t packed_n, int32_t packed_d) |
michael@0 | 184 | { |
michael@0 | 185 | SkASSERT(packed_d != 0); |
michael@0 | 186 | |
michael@0 | 187 | if (packed_n == 0) |
michael@0 | 188 | return 0; |
michael@0 | 189 | |
michael@0 | 190 | int exp_n = get_unsigned_exp(packed_n); |
michael@0 | 191 | int exp_d = get_unsigned_exp(packed_d); |
michael@0 | 192 | |
michael@0 | 193 | int value_n = get_signed_value(packed_n); |
michael@0 | 194 | int value_d = get_signed_value(packed_d); |
michael@0 | 195 | |
michael@0 | 196 | return SkFloat::SetShift(SkDivBits(value_n, value_d, 24), exp_n - exp_d - 24); |
michael@0 | 197 | } |
michael@0 | 198 | |
michael@0 | 199 | int32_t SkFloat::DivInt(int32_t packed, int n) |
michael@0 | 200 | { |
michael@0 | 201 | return Div(packed, SetShift(n, 0)); |
michael@0 | 202 | } |
michael@0 | 203 | |
michael@0 | 204 | int32_t SkFloat::Invert(int32_t packed) |
michael@0 | 205 | { |
michael@0 | 206 | return Div(packed, SetShift(1, 0)); |
michael@0 | 207 | } |
michael@0 | 208 | |
michael@0 | 209 | int32_t SkFloat::Sqrt(int32_t packed) |
michael@0 | 210 | { |
michael@0 | 211 | if (packed < 0) |
michael@0 | 212 | { |
michael@0 | 213 | SkDEBUGFAIL("can't sqrt a negative number"); |
michael@0 | 214 | return 0; |
michael@0 | 215 | } |
michael@0 | 216 | |
michael@0 | 217 | int exp = get_unsigned_exp(packed); |
michael@0 | 218 | int value = get_unsigned_value(packed); |
michael@0 | 219 | |
michael@0 | 220 | int nexp = exp - EXP_BIAS; |
michael@0 | 221 | int root = SkSqrtBits(value << (nexp & 1), 26); |
michael@0 | 222 | nexp >>= 1; |
michael@0 | 223 | return SkFloat::SetShift(root, nexp - 11); |
michael@0 | 224 | } |
michael@0 | 225 | |
michael@0 | 226 | #if defined _WIN32 && _MSC_VER >= 1300 // disable warning : unreachable code |
michael@0 | 227 | #pragma warning ( push ) |
michael@0 | 228 | #pragma warning ( disable : 4702 ) |
michael@0 | 229 | #endif |
michael@0 | 230 | |
michael@0 | 231 | int32_t SkFloat::CubeRoot(int32_t packed) |
michael@0 | 232 | { |
michael@0 | 233 | sk_throw(); |
michael@0 | 234 | return 0; |
michael@0 | 235 | } |
michael@0 | 236 | |
michael@0 | 237 | #if defined _WIN32 && _MSC_VER >= 1300 |
michael@0 | 238 | #pragma warning ( pop ) |
michael@0 | 239 | #endif |
michael@0 | 240 | |
michael@0 | 241 | static inline int32_t clear_high_bit(int32_t n) |
michael@0 | 242 | { |
michael@0 | 243 | return ((uint32_t)(n << 1)) >> 1; |
michael@0 | 244 | } |
michael@0 | 245 | |
michael@0 | 246 | static inline int int_sign(int32_t a, int32_t b) |
michael@0 | 247 | { |
michael@0 | 248 | return a > b ? 1 : (a < b ? -1 : 0); |
michael@0 | 249 | } |
michael@0 | 250 | |
michael@0 | 251 | int SkFloat::Cmp(int32_t packed_a, int32_t packed_b) |
michael@0 | 252 | { |
michael@0 | 253 | packed_a = SkApplySign(clear_high_bit(packed_a), SkExtractSign(packed_a)); |
michael@0 | 254 | packed_b = SkApplySign(clear_high_bit(packed_b), SkExtractSign(packed_b)); |
michael@0 | 255 | |
michael@0 | 256 | return int_sign(packed_a, packed_b); |
michael@0 | 257 | } |
michael@0 | 258 | |
michael@0 | 259 | ///////////////////////////////////////////////////////////////////////////////////// |
michael@0 | 260 | ///////////////////////////////////////////////////////////////////////////////////// |
michael@0 | 261 | |
michael@0 | 262 | #ifdef SK_DEBUG |
michael@0 | 263 | |
michael@0 | 264 | #include "SkRandom.h" |
michael@0 | 265 | #include "SkFloatingPoint.h" |
michael@0 | 266 | |
michael@0 | 267 | void SkFloat::UnitTest() |
michael@0 | 268 | { |
michael@0 | 269 | #if 0 // def SK_SUPPORT_UNITTEST |
michael@0 | 270 | SkFloat a, b, c, d; |
michael@0 | 271 | int n; |
michael@0 | 272 | |
michael@0 | 273 | a.setZero(); |
michael@0 | 274 | n = a.getInt(); |
michael@0 | 275 | SkASSERT(n == 0); |
michael@0 | 276 | |
michael@0 | 277 | b.setInt(5); |
michael@0 | 278 | n = b.getInt(); |
michael@0 | 279 | SkASSERT(n == 5); |
michael@0 | 280 | |
michael@0 | 281 | c.setInt(-3); |
michael@0 | 282 | n = c.getInt(); |
michael@0 | 283 | SkASSERT(n == -3); |
michael@0 | 284 | |
michael@0 | 285 | d.setAdd(c, b); |
michael@0 | 286 | SkDebugf("SkFloat: %d + %d = %d\n", c.getInt(), b.getInt(), d.getInt()); |
michael@0 | 287 | |
michael@0 | 288 | SkRandom rand; |
michael@0 | 289 | |
michael@0 | 290 | int i; |
michael@0 | 291 | for (i = 0; i < 1000; i++) |
michael@0 | 292 | { |
michael@0 | 293 | float fa, fb; |
michael@0 | 294 | int aa = rand.nextS() >> 14; |
michael@0 | 295 | int bb = rand.nextS() >> 14; |
michael@0 | 296 | a.setInt(aa); |
michael@0 | 297 | b.setInt(bb); |
michael@0 | 298 | SkASSERT(a.getInt() == aa); |
michael@0 | 299 | SkASSERT(b.getInt() == bb); |
michael@0 | 300 | |
michael@0 | 301 | c.setAdd(a, b); |
michael@0 | 302 | int cc = c.getInt(); |
michael@0 | 303 | SkASSERT(cc == aa + bb); |
michael@0 | 304 | |
michael@0 | 305 | c.setSub(a, b); |
michael@0 | 306 | cc = c.getInt(); |
michael@0 | 307 | SkASSERT(cc == aa - bb); |
michael@0 | 308 | |
michael@0 | 309 | aa >>= 5; |
michael@0 | 310 | bb >>= 5; |
michael@0 | 311 | a.setInt(aa); |
michael@0 | 312 | b.setInt(bb); |
michael@0 | 313 | c.setMul(a, b); |
michael@0 | 314 | cc = c.getInt(); |
michael@0 | 315 | SkASSERT(cc == aa * bb); |
michael@0 | 316 | ///////////////////////////////////// |
michael@0 | 317 | |
michael@0 | 318 | aa = rand.nextS() >> 11; |
michael@0 | 319 | a.setFixed(aa); |
michael@0 | 320 | cc = a.getFixed(); |
michael@0 | 321 | SkASSERT(aa == cc); |
michael@0 | 322 | |
michael@0 | 323 | bb = rand.nextS() >> 11; |
michael@0 | 324 | b.setFixed(bb); |
michael@0 | 325 | cc = b.getFixed(); |
michael@0 | 326 | SkASSERT(bb == cc); |
michael@0 | 327 | |
michael@0 | 328 | cc = SkFixedMul(aa, bb); |
michael@0 | 329 | c.setMul(a, b); |
michael@0 | 330 | SkFixed dd = c.getFixed(); |
michael@0 | 331 | int diff = cc - dd; |
michael@0 | 332 | SkASSERT(SkAbs32(diff) <= 1); |
michael@0 | 333 | |
michael@0 | 334 | fa = (float)aa / 65536.0f; |
michael@0 | 335 | fb = (float)bb / 65536.0f; |
michael@0 | 336 | a.assertEquals(fa); |
michael@0 | 337 | b.assertEquals(fb); |
michael@0 | 338 | fa = a.getFloat(); |
michael@0 | 339 | fb = b.getFloat(); |
michael@0 | 340 | |
michael@0 | 341 | c.assertEquals(fa * fb, 1); |
michael@0 | 342 | |
michael@0 | 343 | c.setDiv(a, b); |
michael@0 | 344 | cc = SkFixedDiv(aa, bb); |
michael@0 | 345 | dd = c.getFixed(); |
michael@0 | 346 | diff = cc - dd; |
michael@0 | 347 | SkASSERT(SkAbs32(diff) <= 3); |
michael@0 | 348 | |
michael@0 | 349 | c.assertEquals(fa / fb, 1); |
michael@0 | 350 | |
michael@0 | 351 | SkASSERT((aa == bb) == (a == b)); |
michael@0 | 352 | SkASSERT((aa != bb) == (a != b)); |
michael@0 | 353 | SkASSERT((aa < bb) == (a < b)); |
michael@0 | 354 | SkASSERT((aa <= bb) == (a <= b)); |
michael@0 | 355 | SkASSERT((aa > bb) == (a > b)); |
michael@0 | 356 | SkASSERT((aa >= bb) == (a >= b)); |
michael@0 | 357 | |
michael@0 | 358 | if (aa < 0) |
michael@0 | 359 | { |
michael@0 | 360 | aa = -aa; |
michael@0 | 361 | fa = -fa; |
michael@0 | 362 | } |
michael@0 | 363 | a.setFixed(aa); |
michael@0 | 364 | c.setSqrt(a); |
michael@0 | 365 | cc = SkFixedSqrt(aa); |
michael@0 | 366 | dd = c.getFixed(); |
michael@0 | 367 | SkASSERT(dd == cc); |
michael@0 | 368 | |
michael@0 | 369 | c.assertEquals(sk_float_sqrt(fa), 2); |
michael@0 | 370 | |
michael@0 | 371 | // cuberoot |
michael@0 | 372 | #if 0 |
michael@0 | 373 | a.setInt(1); |
michael@0 | 374 | a.cubeRoot(); |
michael@0 | 375 | a.assertEquals(1.0f, 0); |
michael@0 | 376 | a.setInt(8); |
michael@0 | 377 | a.cubeRoot(); |
michael@0 | 378 | a.assertEquals(2.0f, 0); |
michael@0 | 379 | a.setInt(27); |
michael@0 | 380 | a.cubeRoot(); |
michael@0 | 381 | a.assertEquals(3.0f, 0); |
michael@0 | 382 | #endif |
michael@0 | 383 | } |
michael@0 | 384 | #endif |
michael@0 | 385 | } |
michael@0 | 386 | |
michael@0 | 387 | #endif |