Changeset 29243 in webkit for trunk/JavaScriptCore/kjs/value.cpp


Ignore:
Timestamp:
Jan 7, 2008, 1:50:51 PM (17 years ago)
Author:
Darin Adler
Message:

Reviewed by David Kilzer.

  • fix alignment problem with NaN and Inf globals
  • kjs/fpconst.cpp: Move the contents of this file from here back to value.cpp. The reason this was in a separate file is that the DARWIN version of this used a declaration of the globals with a different type to avoid creating "init routines". That's no longer necessary for DARWIN and was never necessary for the non-DARWIN code path. To make this patch easy to merge, I didn't actually delete this file yet. We'll do that in a separate changeset.
  • kjs/value.cpp: If C99's NAN and INFINITY are present, then use them, othrewise use the union trick from fpconst.cpp. I think it would be better to eliminate KJS::NaN and KJS::Inf and just use NAN and INFINITY directly or std::numeric_limits<double>::quiet_nan() and std::numeric_limits<double>::infinity(). But when I tried that, it slowed down SunSpider. Someone else could do that cleanup if they could do it without slowing down the engine.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/kjs/value.cpp

    r27747 r29243  
    22 *  Copyright (C) 1999-2001 Harri Porten ([email protected])
    33 *  Copyright (C) 2001 Peter Kelly ([email protected])
    4  *  Copyright (C) 2003, 2007 Apple Inc. All rights reserved.
     4 *  Copyright (C) 2003, 2007, 2008 Apple Inc. All rights reserved.
    55 *
    66 *  This library is free software; you can redistribute it and/or
     
    3131
    3232namespace KJS {
     33
     34#if defined NAN && defined INFINITY
     35
     36extern const double NaN = NAN;
     37extern const double Inf = INFINITY;
     38
     39#else // !(defined NAN && defined INFINITY)
     40
     41// The trick is to define the NaN and Inf globals with a different type than the declaration.
     42// This trick works because the mangled name of the globals does not include the type, although
     43// I'm not sure that's guaranteed. There could be alignment issues with this, since arrays of
     44// characters don't necessarily need the same alignment doubles do, but for now it seems to work.
     45// It would be good to figure out a 100% clean way that still avoids code that runs at init time.
     46
     47// Note, we have to use union to ensure alignment. Otherwise, NaN_Bytes can start anywhere,
     48// while NaN_double has to be 4-byte aligned for 32-bits.
     49// With -fstrict-aliasing enabled, unions are the only safe way to do type masquerading.
     50
     51static const union {
     52    struct {
     53        unsigned char NaN_Bytes[8];
     54        unsigned char Inf_Bytes[8];
     55    } bytes;
     56   
     57    struct {
     58        double NaN_Double;
     59        double Inf_Double;
     60    } doubles;
     61   
     62} NaNInf = { {
     63#if PLATFORM(BIG_ENDIAN)
     64    { 0x7f, 0xf8, 0, 0, 0, 0, 0, 0 },
     65    { 0x7f, 0xf0, 0, 0, 0, 0, 0, 0 }
     66#elif PLATFORM(MIDDLE_ENDIAN)
     67    { 0, 0, 0xf8, 0x7f, 0, 0, 0, 0 },
     68    { 0, 0, 0xf0, 0x7f, 0, 0, 0, 0 }
     69#else
     70    { 0, 0, 0, 0, 0, 0, 0xf8, 0x7f },
     71    { 0, 0, 0, 0, 0, 0, 0xf0, 0x7f }
     72#endif
     73} } ;
     74
     75extern const double NaN = NaNInf.doubles.NaN_Double;
     76extern const double Inf = NaNInf.doubles.Inf_Double;
     77 
     78#endif // !(defined NAN && defined INFINITY)
    3379
    3480static const double D16 = 65536.0;
Note: See TracChangeset for help on using the changeset viewer.