LCOV - code coverage report
Current view: directory - objdir/dist/include - jsval.h (source / functions) Found Hit Coverage
Test: app.info Lines: 84 83 98.8 %
Date: 2012-06-02 Functions: 30 30 100.0 %

       1                 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
       2                 :  * vim: set ts=4 sw=4 et tw=99 ft=cpp:
       3                 :  *
       4                 :  * ***** BEGIN LICENSE BLOCK *****
       5                 :  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
       6                 :  *
       7                 :  * The contents of this file are subject to the Mozilla Public License Version
       8                 :  * 1.1 (the "License"); you may not use this file except in compliance with
       9                 :  * the License. You may obtain a copy of the License at
      10                 :  * http://www.mozilla.org/MPL/
      11                 :  *
      12                 :  * Software distributed under the License is distributed on an "AS IS" basis,
      13                 :  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
      14                 :  * for the specific language governing rights and limitations under the
      15                 :  * License.
      16                 :  *
      17                 :  * The Original Code is Mozilla SpiderMonkey JavaScript 1.9 code, released
      18                 :  * June 30, 2010
      19                 :  *
      20                 :  * The Initial Developer of the Original Code is
      21                 :  *   the Mozilla Corporation.
      22                 :  *
      23                 :  * Contributor(s):
      24                 :  *   Luke Wagner <lw@mozilla.com>
      25                 :  *
      26                 :  * Alternatively, the contents of this file may be used under the terms of
      27                 :  * either of the GNU General Public License Version 2 or later (the "GPL"),
      28                 :  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
      29                 :  * in which case the provisions of the GPL or the LGPL are applicable instead
      30                 :  * of those above. If you wish to allow use of your version of this file only
      31                 :  * under the terms of either the GPL or the LGPL, and not to allow others to
      32                 :  * use your version of this file under the terms of the MPL, indicate your
      33                 :  * decision by deleting the provisions above and replace them with the notice
      34                 :  * and other provisions required by the GPL or the LGPL. If you do not delete
      35                 :  * the provisions above, a recipient may use your version of this file under
      36                 :  * the terms of any one of the MPL, the GPL or the LGPL.
      37                 :  *
      38                 :  * ***** END LICENSE BLOCK ***** */
      39                 : 
      40                 : #ifndef jsvalimpl_h__
      41                 : #define jsvalimpl_h__
      42                 : /*
      43                 :  * Implementation details for js::Value in jsapi.h.
      44                 :  */
      45                 : #include "js/Utility.h"
      46                 : 
      47                 : JS_BEGIN_EXTERN_C
      48                 : 
      49                 : /******************************************************************************/
      50                 : 
      51                 : /* To avoid a circular dependency, pull in the necessary pieces of jsnum.h. */
      52                 : 
      53                 : #define JSDOUBLE_SIGNBIT (((uint64_t) 1) << 63)
      54                 : #define JSDOUBLE_EXPMASK (((uint64_t) 0x7ff) << 52)
      55                 : #define JSDOUBLE_MANTMASK ((((uint64_t) 1) << 52) - 1)
      56                 : #define JSDOUBLE_HI32_SIGNBIT   0x80000000
      57                 : 
      58                 : static JS_ALWAYS_INLINE JSBool
      59         6734396 : JSDOUBLE_IS_NEGZERO(double d)
      60                 : {
      61                 :     union {
      62                 :         struct {
      63                 : #if defined(IS_LITTLE_ENDIAN) && !defined(FPU_IS_ARM_FPA)
      64                 :             uint32_t lo, hi;
      65                 : #else
      66                 :             uint32_t hi, lo;
      67                 : #endif
      68                 :         } s;
      69                 :         double d;
      70                 :     } x;
      71         6734396 :     if (d != 0)
      72         6418595 :         return JS_FALSE;
      73          315801 :     x.d = d;
      74          315801 :     return (x.s.hi & JSDOUBLE_HI32_SIGNBIT) != 0;
      75                 : }
      76                 : 
      77                 : static JS_ALWAYS_INLINE JSBool
      78         6734396 : JSDOUBLE_IS_INT32(double d, int32_t* pi)
      79                 : {
      80         6734396 :     if (JSDOUBLE_IS_NEGZERO(d))
      81              41 :         return JS_FALSE;
      82         6734355 :     return d == (*pi = (int32_t)d);
      83                 : }
      84                 : 
      85                 : /******************************************************************************/
      86                 : 
      87                 : /*
      88                 :  * Try to get jsvals 64-bit aligned. We could almost assert that all values are
      89                 :  * aligned, but MSVC and GCC occasionally break alignment.
      90                 :  */
      91                 : #if defined(__GNUC__) || defined(__xlc__) || defined(__xlC__)
      92                 : # define JSVAL_ALIGNMENT        __attribute__((aligned (8)))
      93                 : #elif defined(_MSC_VER)
      94                 :   /*
      95                 :    * Structs can be aligned with MSVC, but not if they are used as parameters,
      96                 :    * so we just don't try to align.
      97                 :    */
      98                 : # define JSVAL_ALIGNMENT
      99                 : #elif defined(__SUNPRO_C) || defined(__SUNPRO_CC)
     100                 : # define JSVAL_ALIGNMENT
     101                 : #elif defined(__HP_cc) || defined(__HP_aCC)
     102                 : # define JSVAL_ALIGNMENT
     103                 : #endif
     104                 : 
     105                 : #if JS_BITS_PER_WORD == 64
     106                 : # define JSVAL_TAG_SHIFT 47
     107                 : #endif
     108                 : 
     109                 : /*
     110                 :  * We try to use enums so that printing a jsval_layout in the debugger shows
     111                 :  * nice symbolic type tags, however we can only do this when we can force the
     112                 :  * underlying type of the enum to be the desired size.
     113                 :  */
     114                 : #if defined(__cplusplus) && !defined(__SUNPRO_CC) && !defined(__xlC__)
     115                 : 
     116                 : #if defined(_MSC_VER)
     117                 : # define JS_ENUM_HEADER(id, type)              enum id : type
     118                 : # define JS_ENUM_MEMBER(id, type, value)       id = (type)value,
     119                 : # define JS_LAST_ENUM_MEMBER(id, type, value)  id = (type)value
     120                 : # define JS_ENUM_FOOTER(id)
     121                 : #else
     122                 : # define JS_ENUM_HEADER(id, type)              enum id
     123                 : # define JS_ENUM_MEMBER(id, type, value)       id = (type)value,
     124                 : # define JS_LAST_ENUM_MEMBER(id, type, value)  id = (type)value
     125                 : # define JS_ENUM_FOOTER(id)                    __attribute__((packed))
     126                 : #endif
     127                 : 
     128                 : /* Remember to propagate changes to the C defines below. */
     129                 : JS_ENUM_HEADER(JSValueType, uint8_t)
     130                 : {
     131                 :     JSVAL_TYPE_DOUBLE              = 0x00,
     132                 :     JSVAL_TYPE_INT32               = 0x01,
     133                 :     JSVAL_TYPE_UNDEFINED           = 0x02,
     134                 :     JSVAL_TYPE_BOOLEAN             = 0x03,
     135                 :     JSVAL_TYPE_MAGIC               = 0x04,
     136                 :     JSVAL_TYPE_STRING              = 0x05,
     137                 :     JSVAL_TYPE_NULL                = 0x06,
     138                 :     JSVAL_TYPE_OBJECT              = 0x07,
     139                 : 
     140                 :     /* These never appear in a jsval; they are only provided as an out-of-band value. */
     141                 :     JSVAL_TYPE_UNKNOWN             = 0x20,
     142                 :     JSVAL_TYPE_MISSING             = 0x21
     143                 : } JS_ENUM_FOOTER(JSValueType);
     144                 : 
     145                 : JS_STATIC_ASSERT(sizeof(JSValueType) == 1);
     146                 : 
     147                 : #if JS_BITS_PER_WORD == 32
     148                 : 
     149                 : /* Remember to propagate changes to the C defines below. */
     150                 : JS_ENUM_HEADER(JSValueTag, uint32_t)
     151                 : {
     152                 :     JSVAL_TAG_CLEAR                = 0xFFFFFF80,
     153                 :     JSVAL_TAG_INT32                = JSVAL_TAG_CLEAR | JSVAL_TYPE_INT32,
     154                 :     JSVAL_TAG_UNDEFINED            = JSVAL_TAG_CLEAR | JSVAL_TYPE_UNDEFINED,
     155                 :     JSVAL_TAG_STRING               = JSVAL_TAG_CLEAR | JSVAL_TYPE_STRING,
     156                 :     JSVAL_TAG_BOOLEAN              = JSVAL_TAG_CLEAR | JSVAL_TYPE_BOOLEAN,
     157                 :     JSVAL_TAG_MAGIC                = JSVAL_TAG_CLEAR | JSVAL_TYPE_MAGIC,
     158                 :     JSVAL_TAG_NULL                 = JSVAL_TAG_CLEAR | JSVAL_TYPE_NULL,
     159                 :     JSVAL_TAG_OBJECT               = JSVAL_TAG_CLEAR | JSVAL_TYPE_OBJECT
     160                 : } JS_ENUM_FOOTER(JSValueTag);
     161                 : 
     162                 : JS_STATIC_ASSERT(sizeof(JSValueTag) == 4);
     163                 : 
     164                 : #elif JS_BITS_PER_WORD == 64
     165                 : 
     166                 : /* Remember to propagate changes to the C defines below. */
     167                 : JS_ENUM_HEADER(JSValueTag, uint32_t)
     168                 : {
     169                 :     JSVAL_TAG_MAX_DOUBLE           = 0x1FFF0,
     170                 :     JSVAL_TAG_INT32                = JSVAL_TAG_MAX_DOUBLE | JSVAL_TYPE_INT32,
     171                 :     JSVAL_TAG_UNDEFINED            = JSVAL_TAG_MAX_DOUBLE | JSVAL_TYPE_UNDEFINED,
     172                 :     JSVAL_TAG_STRING               = JSVAL_TAG_MAX_DOUBLE | JSVAL_TYPE_STRING,
     173                 :     JSVAL_TAG_BOOLEAN              = JSVAL_TAG_MAX_DOUBLE | JSVAL_TYPE_BOOLEAN,
     174                 :     JSVAL_TAG_MAGIC                = JSVAL_TAG_MAX_DOUBLE | JSVAL_TYPE_MAGIC,
     175                 :     JSVAL_TAG_NULL                 = JSVAL_TAG_MAX_DOUBLE | JSVAL_TYPE_NULL,
     176                 :     JSVAL_TAG_OBJECT               = JSVAL_TAG_MAX_DOUBLE | JSVAL_TYPE_OBJECT
     177                 : } JS_ENUM_FOOTER(JSValueTag);
     178                 : 
     179                 : JS_STATIC_ASSERT(sizeof(JSValueTag) == sizeof(uint32_t));
     180                 : 
     181                 : JS_ENUM_HEADER(JSValueShiftedTag, uint64_t)
     182                 : {
     183                 :     JSVAL_SHIFTED_TAG_MAX_DOUBLE   = ((((uint64_t)JSVAL_TAG_MAX_DOUBLE) << JSVAL_TAG_SHIFT) | 0xFFFFFFFF),
     184                 :     JSVAL_SHIFTED_TAG_INT32        = (((uint64_t)JSVAL_TAG_INT32)      << JSVAL_TAG_SHIFT),
     185                 :     JSVAL_SHIFTED_TAG_UNDEFINED    = (((uint64_t)JSVAL_TAG_UNDEFINED)  << JSVAL_TAG_SHIFT),
     186                 :     JSVAL_SHIFTED_TAG_STRING       = (((uint64_t)JSVAL_TAG_STRING)     << JSVAL_TAG_SHIFT),
     187                 :     JSVAL_SHIFTED_TAG_BOOLEAN      = (((uint64_t)JSVAL_TAG_BOOLEAN)    << JSVAL_TAG_SHIFT),
     188                 :     JSVAL_SHIFTED_TAG_MAGIC        = (((uint64_t)JSVAL_TAG_MAGIC)      << JSVAL_TAG_SHIFT),
     189                 :     JSVAL_SHIFTED_TAG_NULL         = (((uint64_t)JSVAL_TAG_NULL)       << JSVAL_TAG_SHIFT),
     190                 :     JSVAL_SHIFTED_TAG_OBJECT       = (((uint64_t)JSVAL_TAG_OBJECT)     << JSVAL_TAG_SHIFT)
     191                 : } JS_ENUM_FOOTER(JSValueShiftedTag);
     192                 : 
     193                 : JS_STATIC_ASSERT(sizeof(JSValueShiftedTag) == sizeof(uint64_t));
     194                 : 
     195                 : #endif
     196                 : 
     197                 : #else  /* defined(__cplusplus) */
     198                 : 
     199                 : typedef uint8_t JSValueType;
     200                 : #define JSVAL_TYPE_DOUBLE            ((uint8_t)0x00)
     201                 : #define JSVAL_TYPE_INT32             ((uint8_t)0x01)
     202                 : #define JSVAL_TYPE_UNDEFINED         ((uint8_t)0x02)
     203                 : #define JSVAL_TYPE_BOOLEAN           ((uint8_t)0x03)
     204                 : #define JSVAL_TYPE_MAGIC             ((uint8_t)0x04)
     205                 : #define JSVAL_TYPE_STRING            ((uint8_t)0x05)
     206                 : #define JSVAL_TYPE_NULL              ((uint8_t)0x06)
     207                 : #define JSVAL_TYPE_OBJECT            ((uint8_t)0x07)
     208                 : #define JSVAL_TYPE_UNKNOWN           ((uint8_t)0x20)
     209                 : 
     210                 : #if JS_BITS_PER_WORD == 32
     211                 : 
     212                 : typedef uint32_t JSValueTag;
     213                 : #define JSVAL_TAG_CLEAR              ((uint32_t)(0xFFFFFF80))
     214                 : #define JSVAL_TAG_INT32              ((uint32_t)(JSVAL_TAG_CLEAR | JSVAL_TYPE_INT32))
     215                 : #define JSVAL_TAG_UNDEFINED          ((uint32_t)(JSVAL_TAG_CLEAR | JSVAL_TYPE_UNDEFINED))
     216                 : #define JSVAL_TAG_STRING             ((uint32_t)(JSVAL_TAG_CLEAR | JSVAL_TYPE_STRING))
     217                 : #define JSVAL_TAG_BOOLEAN            ((uint32_t)(JSVAL_TAG_CLEAR | JSVAL_TYPE_BOOLEAN))
     218                 : #define JSVAL_TAG_MAGIC              ((uint32_t)(JSVAL_TAG_CLEAR | JSVAL_TYPE_MAGIC))
     219                 : #define JSVAL_TAG_NULL               ((uint32_t)(JSVAL_TAG_CLEAR | JSVAL_TYPE_NULL))
     220                 : #define JSVAL_TAG_OBJECT             ((uint32_t)(JSVAL_TAG_CLEAR | JSVAL_TYPE_OBJECT))
     221                 : 
     222                 : #elif JS_BITS_PER_WORD == 64
     223                 : 
     224                 : typedef uint32_t JSValueTag;
     225                 : #define JSVAL_TAG_MAX_DOUBLE         ((uint32_t)(0x1FFF0))
     226                 : #define JSVAL_TAG_INT32              (uint32_t)(JSVAL_TAG_MAX_DOUBLE | JSVAL_TYPE_INT32)
     227                 : #define JSVAL_TAG_UNDEFINED          (uint32_t)(JSVAL_TAG_MAX_DOUBLE | JSVAL_TYPE_UNDEFINED)
     228                 : #define JSVAL_TAG_STRING             (uint32_t)(JSVAL_TAG_MAX_DOUBLE | JSVAL_TYPE_STRING)
     229                 : #define JSVAL_TAG_BOOLEAN            (uint32_t)(JSVAL_TAG_MAX_DOUBLE | JSVAL_TYPE_BOOLEAN)
     230                 : #define JSVAL_TAG_MAGIC              (uint32_t)(JSVAL_TAG_MAX_DOUBLE | JSVAL_TYPE_MAGIC)
     231                 : #define JSVAL_TAG_NULL               (uint32_t)(JSVAL_TAG_MAX_DOUBLE | JSVAL_TYPE_NULL)
     232                 : #define JSVAL_TAG_OBJECT             (uint32_t)(JSVAL_TAG_MAX_DOUBLE | JSVAL_TYPE_OBJECT)
     233                 : 
     234                 : typedef uint64_t JSValueShiftedTag;
     235                 : #define JSVAL_SHIFTED_TAG_MAX_DOUBLE ((((uint64_t)JSVAL_TAG_MAX_DOUBLE) << JSVAL_TAG_SHIFT) | 0xFFFFFFFF)
     236                 : #define JSVAL_SHIFTED_TAG_INT32      (((uint64_t)JSVAL_TAG_INT32)      << JSVAL_TAG_SHIFT)
     237                 : #define JSVAL_SHIFTED_TAG_UNDEFINED  (((uint64_t)JSVAL_TAG_UNDEFINED)  << JSVAL_TAG_SHIFT)
     238                 : #define JSVAL_SHIFTED_TAG_STRING     (((uint64_t)JSVAL_TAG_STRING)     << JSVAL_TAG_SHIFT)
     239                 : #define JSVAL_SHIFTED_TAG_BOOLEAN    (((uint64_t)JSVAL_TAG_BOOLEAN)    << JSVAL_TAG_SHIFT)
     240                 : #define JSVAL_SHIFTED_TAG_MAGIC      (((uint64_t)JSVAL_TAG_MAGIC)      << JSVAL_TAG_SHIFT)
     241                 : #define JSVAL_SHIFTED_TAG_NULL       (((uint64_t)JSVAL_TAG_NULL)       << JSVAL_TAG_SHIFT)
     242                 : #define JSVAL_SHIFTED_TAG_OBJECT     (((uint64_t)JSVAL_TAG_OBJECT)     << JSVAL_TAG_SHIFT)
     243                 : 
     244                 : #endif  /* JS_BITS_PER_WORD */
     245                 : #endif  /* defined(__cplusplus) && !defined(__SUNPRO_CC) */
     246                 : 
     247                 : #define JSVAL_LOWER_INCL_TYPE_OF_OBJ_OR_NULL_SET        JSVAL_TYPE_NULL
     248                 : #define JSVAL_UPPER_EXCL_TYPE_OF_PRIMITIVE_SET          JSVAL_TYPE_OBJECT
     249                 : #define JSVAL_UPPER_INCL_TYPE_OF_NUMBER_SET             JSVAL_TYPE_INT32
     250                 : #define JSVAL_LOWER_INCL_TYPE_OF_PTR_PAYLOAD_SET        JSVAL_TYPE_MAGIC
     251                 : 
     252                 : #if JS_BITS_PER_WORD == 32
     253                 : 
     254                 : #define JSVAL_TYPE_TO_TAG(type)      ((JSValueTag)(JSVAL_TAG_CLEAR | (type)))
     255                 : 
     256                 : #define JSVAL_LOWER_INCL_TAG_OF_OBJ_OR_NULL_SET         JSVAL_TAG_NULL
     257                 : #define JSVAL_UPPER_EXCL_TAG_OF_PRIMITIVE_SET           JSVAL_TAG_OBJECT
     258                 : #define JSVAL_UPPER_INCL_TAG_OF_NUMBER_SET              JSVAL_TAG_INT32
     259                 : #define JSVAL_LOWER_INCL_TAG_OF_GCTHING_SET             JSVAL_TAG_STRING
     260                 : 
     261                 : #elif JS_BITS_PER_WORD == 64
     262                 : 
     263                 : #define JSVAL_PAYLOAD_MASK           0x00007FFFFFFFFFFFLL
     264                 : #define JSVAL_TAG_MASK               0xFFFF800000000000LL
     265                 : #define JSVAL_TYPE_TO_TAG(type)      ((JSValueTag)(JSVAL_TAG_MAX_DOUBLE | (type)))
     266                 : #define JSVAL_TYPE_TO_SHIFTED_TAG(type) (((uint64_t)JSVAL_TYPE_TO_TAG(type)) << JSVAL_TAG_SHIFT)
     267                 : 
     268                 : #define JSVAL_LOWER_INCL_SHIFTED_TAG_OF_OBJ_OR_NULL_SET  JSVAL_SHIFTED_TAG_NULL
     269                 : #define JSVAL_UPPER_EXCL_SHIFTED_TAG_OF_PRIMITIVE_SET    JSVAL_SHIFTED_TAG_OBJECT
     270                 : #define JSVAL_UPPER_EXCL_SHIFTED_TAG_OF_NUMBER_SET       JSVAL_SHIFTED_TAG_UNDEFINED
     271                 : #define JSVAL_LOWER_INCL_SHIFTED_TAG_OF_GCTHING_SET      JSVAL_SHIFTED_TAG_STRING
     272                 : 
     273                 : #endif /* JS_BITS_PER_WORD */
     274                 : 
     275                 : typedef enum JSWhyMagic
     276                 : {
     277                 :     JS_ARRAY_HOLE,               /* a hole in a dense array */
     278                 :     JS_ARGS_HOLE,                /* a hole in the args object's array */
     279                 :     JS_NATIVE_ENUMERATE,         /* indicates that a custom enumerate hook forwarded
     280                 :                                   * to JS_EnumerateState, which really means the object can be
     281                 :                                   * enumerated like a native object. */
     282                 :     JS_NO_ITER_VALUE,            /* there is not a pending iterator value */
     283                 :     JS_GENERATOR_CLOSING,        /* exception value thrown when closing a generator */
     284                 :     JS_NO_CONSTANT,              /* compiler sentinel value */
     285                 :     JS_THIS_POISON,              /* used in debug builds to catch tracing errors */
     286                 :     JS_ARG_POISON,               /* used in debug builds to catch tracing errors */
     287                 :     JS_SERIALIZE_NO_NODE,        /* an empty subnode in the AST serializer */
     288                 :     JS_LAZY_ARGUMENTS,           /* lazy arguments value on the stack */
     289                 :     JS_UNASSIGNED_ARGUMENTS,     /* the initial value of callobj.arguments */
     290                 :     JS_IS_CONSTRUCTING,          /* magic value passed to natives to indicate construction */
     291                 :     JS_GENERIC_MAGIC             /* for local use */
     292                 : } JSWhyMagic;
     293                 : 
     294                 : #if defined(IS_LITTLE_ENDIAN)
     295                 : # if JS_BITS_PER_WORD == 32
     296                 : typedef union jsval_layout
     297                 : {
     298                 :     uint64_t asBits;
     299                 :     struct {
     300                 :         union {
     301                 :             int32_t        i32;
     302                 :             uint32_t       u32;
     303                 :             JSBool         boo;
     304                 :             JSString       *str;
     305                 :             JSObject       *obj;
     306                 :             void           *ptr;
     307                 :             JSWhyMagic     why;
     308                 :             size_t         word;
     309                 :         } payload;
     310                 :         JSValueTag tag;
     311                 :     } s;
     312                 :     double asDouble;
     313                 :     void *asPtr;
     314                 : } JSVAL_ALIGNMENT jsval_layout;
     315                 : # elif JS_BITS_PER_WORD == 64
     316                 : typedef union jsval_layout
     317                 : {
     318                 :     uint64_t asBits;
     319                 : #if (!defined(_WIN64) && defined(__cplusplus))
     320                 :     /* MSVC does not pack these correctly :-( */
     321                 :     struct {
     322                 :         uint64_t           payload47 : 47;
     323                 :         JSValueTag         tag : 17;
     324                 :     } debugView;
     325                 : #endif
     326                 :     struct {
     327                 :         union {
     328                 :             int32_t        i32;
     329                 :             uint32_t       u32;
     330                 :             JSWhyMagic     why;
     331                 :         } payload;
     332                 :     } s;
     333                 :     double asDouble;
     334                 :     void *asPtr;
     335                 :     size_t asWord;
     336                 : } JSVAL_ALIGNMENT jsval_layout;
     337                 : # endif  /* JS_BITS_PER_WORD */
     338                 : #else   /* defined(IS_LITTLE_ENDIAN) */
     339                 : # if JS_BITS_PER_WORD == 32
     340                 : typedef union jsval_layout
     341                 : {
     342                 :     uint64_t asBits;
     343                 :     struct {
     344                 :         JSValueTag tag;
     345                 :         union {
     346                 :             int32_t        i32;
     347                 :             uint32_t       u32;
     348                 :             JSBool         boo;
     349                 :             JSString       *str;
     350                 :             JSObject       *obj;
     351                 :             void           *ptr;
     352                 :             JSWhyMagic     why;
     353                 :             size_t         word;
     354                 :         } payload;
     355                 :     } s;
     356                 :     double asDouble;
     357                 :     void *asPtr;
     358                 : } JSVAL_ALIGNMENT jsval_layout;
     359                 : # elif JS_BITS_PER_WORD == 64
     360                 : typedef union jsval_layout
     361                 : {
     362                 :     uint64_t asBits;
     363                 :     struct {
     364                 :         JSValueTag         tag : 17;
     365                 :         uint64_t           payload47 : 47;
     366                 :     } debugView;
     367                 :     struct {
     368                 :         uint32_t           padding;
     369                 :         union {
     370                 :             int32_t        i32;
     371                 :             uint32_t       u32;
     372                 :             JSWhyMagic     why;
     373                 :         } payload;
     374                 :     } s;
     375                 :     double asDouble;
     376                 :     void *asPtr;
     377                 :     size_t asWord;
     378                 : } JSVAL_ALIGNMENT jsval_layout;
     379                 : # endif /* JS_BITS_PER_WORD */
     380                 : #endif  /* defined(IS_LITTLE_ENDIAN) */
     381                 : 
     382                 : JS_STATIC_ASSERT(sizeof(jsval_layout) == 8);
     383                 : 
     384                 : #if JS_BITS_PER_WORD == 32
     385                 : 
     386                 : /*
     387                 :  * N.B. GCC, in some but not all cases, chooses to emit signed comparison of
     388                 :  * JSValueTag even though its underlying type has been forced to be uint32_t.
     389                 :  * Thus, all comparisons should explicitly cast operands to uint32_t.
     390                 :  */
     391                 : 
     392                 : static JS_ALWAYS_INLINE jsval_layout
     393        56818697 : BUILD_JSVAL(JSValueTag tag, uint32_t payload)
     394                 : {
     395                 :     jsval_layout l;
     396        56818697 :     l.asBits = (((uint64_t)(uint32_t)tag) << 32) | payload;
     397                 :     return l;
     398                 : }
     399                 : 
     400                 : static JS_ALWAYS_INLINE JSBool
     401        41986431 : JSVAL_IS_DOUBLE_IMPL(jsval_layout l)
     402                 : {
     403        41986431 :     return (uint32_t)l.s.tag <= (uint32_t)JSVAL_TAG_CLEAR;
     404                 : }
     405                 : 
     406                 : static JS_ALWAYS_INLINE jsval_layout
     407          168683 : DOUBLE_TO_JSVAL_IMPL(double d)
     408                 : {
     409                 :     jsval_layout l;
     410          168683 :     l.asDouble = d;
     411          168683 :     JS_ASSERT(JSVAL_IS_DOUBLE_IMPL(l));
     412                 :     return l;
     413                 : }
     414                 : 
     415                 : static JS_ALWAYS_INLINE JSBool
     416       215046372 : JSVAL_IS_INT32_IMPL(jsval_layout l)
     417                 : {
     418       215046372 :     return l.s.tag == JSVAL_TAG_INT32;
     419                 : }
     420                 : 
     421                 : static JS_ALWAYS_INLINE int32_t
     422       104662956 : JSVAL_TO_INT32_IMPL(jsval_layout l)
     423                 : {
     424       104662956 :     return l.s.payload.i32;
     425                 : }
     426                 : 
     427                 : static JS_ALWAYS_INLINE jsval_layout
     428        67733223 : INT32_TO_JSVAL_IMPL(int32_t i)
     429                 : {
     430                 :     jsval_layout l;
     431        67733223 :     l.s.tag = JSVAL_TAG_INT32;
     432        67733223 :     l.s.payload.i32 = i;
     433                 :     return l;
     434                 : }
     435                 : 
     436                 : static JS_ALWAYS_INLINE JSBool
     437        16114603 : JSVAL_IS_NUMBER_IMPL(jsval_layout l)
     438                 : {
     439        16114603 :     JSValueTag tag = l.s.tag;
     440        16114603 :     JS_ASSERT(tag != JSVAL_TAG_CLEAR);
     441        16114603 :     return (uint32_t)tag <= (uint32_t)JSVAL_UPPER_INCL_TAG_OF_NUMBER_SET;
     442                 : }
     443                 : 
     444                 : static JS_ALWAYS_INLINE JSBool
     445        77450614 : JSVAL_IS_UNDEFINED_IMPL(jsval_layout l)
     446                 : {
     447        77450614 :     return l.s.tag == JSVAL_TAG_UNDEFINED;
     448                 : }
     449                 : 
     450                 : static JS_ALWAYS_INLINE JSBool
     451       594224621 : JSVAL_IS_STRING_IMPL(jsval_layout l)
     452                 : {
     453       594224621 :     return l.s.tag == JSVAL_TAG_STRING;
     454                 : }
     455                 : 
     456                 : static JS_ALWAYS_INLINE jsval_layout
     457        29190803 : STRING_TO_JSVAL_IMPL(JSString *str)
     458                 : {
     459                 :     jsval_layout l;
     460        29190803 :     JS_ASSERT(str);
     461        29190803 :     l.s.tag = JSVAL_TAG_STRING;
     462        29190803 :     l.s.payload.str = str;
     463               0 :     return l;
     464                 : }
     465                 : 
     466                 : static JS_ALWAYS_INLINE JSString *
     467       147362260 : JSVAL_TO_STRING_IMPL(jsval_layout l)
     468                 : {
     469       147362260 :     return l.s.payload.str;
     470                 : }
     471                 : 
     472                 : static JS_ALWAYS_INLINE JSBool
     473           24802 : JSVAL_IS_BOOLEAN_IMPL(jsval_layout l)
     474                 : {
     475           24802 :     return l.s.tag == JSVAL_TAG_BOOLEAN;
     476                 : }
     477                 : 
     478                 : static JS_ALWAYS_INLINE JSBool
     479             404 : JSVAL_TO_BOOLEAN_IMPL(jsval_layout l)
     480                 : {
     481             404 :     return l.s.payload.boo;
     482                 : }
     483                 : 
     484                 : static JS_ALWAYS_INLINE jsval_layout
     485        11649786 : BOOLEAN_TO_JSVAL_IMPL(JSBool b)
     486                 : {
     487                 :     jsval_layout l;
     488        11649786 :     JS_ASSERT(b == JS_TRUE || b == JS_FALSE);
     489        11649786 :     l.s.tag = JSVAL_TAG_BOOLEAN;
     490        11649786 :     l.s.payload.boo = b;
     491                 :     return l;
     492                 : }
     493                 : 
     494                 : static JS_ALWAYS_INLINE JSBool
     495                 : JSVAL_IS_MAGIC_IMPL(jsval_layout l)
     496                 : {
     497                 :     return l.s.tag == JSVAL_TAG_MAGIC;
     498                 : }
     499                 : 
     500                 : static JS_ALWAYS_INLINE JSBool
     501       804192467 : JSVAL_IS_OBJECT_IMPL(jsval_layout l)
     502                 : {
     503       804192467 :     return l.s.tag == JSVAL_TAG_OBJECT;
     504                 : }
     505                 : 
     506                 : static JS_ALWAYS_INLINE JSBool
     507         8534633 : JSVAL_IS_PRIMITIVE_IMPL(jsval_layout l)
     508                 : {
     509         8534633 :     return (uint32_t)l.s.tag < (uint32_t)JSVAL_UPPER_EXCL_TAG_OF_PRIMITIVE_SET;
     510                 : }
     511                 : 
     512                 : static JS_ALWAYS_INLINE JSBool
     513        28849709 : JSVAL_IS_OBJECT_OR_NULL_IMPL(jsval_layout l)
     514                 : {
     515        28849709 :     JS_ASSERT((uint32_t)l.s.tag <= (uint32_t)JSVAL_TAG_OBJECT);
     516        28849709 :     return (uint32_t)l.s.tag >= (uint32_t)JSVAL_LOWER_INCL_TAG_OF_OBJ_OR_NULL_SET;
     517                 : }
     518                 : 
     519                 : static JS_ALWAYS_INLINE JSObject *
     520       309070102 : JSVAL_TO_OBJECT_IMPL(jsval_layout l)
     521                 : {
     522       309070102 :     return l.s.payload.obj;
     523                 : }
     524                 : 
     525                 : static JS_ALWAYS_INLINE jsval_layout
     526        86680742 : OBJECT_TO_JSVAL_IMPL(JSObject *obj)
     527                 : {
     528                 :     jsval_layout l;
     529        86680742 :     JS_ASSERT(obj);
     530        86680742 :     l.s.tag = JSVAL_TAG_OBJECT;
     531        86680742 :     l.s.payload.obj = obj;
     532               3 :     return l;
     533                 : }
     534                 : 
     535                 : static JS_ALWAYS_INLINE JSBool
     536         6183871 : JSVAL_IS_NULL_IMPL(jsval_layout l)
     537                 : {
     538         6183871 :     return l.s.tag == JSVAL_TAG_NULL;
     539                 : }
     540                 : 
     541                 : static JS_ALWAYS_INLINE jsval_layout
     542         5055787 : PRIVATE_PTR_TO_JSVAL_IMPL(void *ptr)
     543                 : {
     544                 :     jsval_layout l;
     545         5055787 :     JS_ASSERT(((uint32_t)ptr & 1) == 0);
     546         5055787 :     l.s.tag = (JSValueTag)0;
     547         5055787 :     l.s.payload.ptr = ptr;
     548         5055787 :     JS_ASSERT(JSVAL_IS_DOUBLE_IMPL(l));
     549               6 :     return l;
     550                 : }
     551                 : 
     552                 : static JS_ALWAYS_INLINE void *
     553        17378848 : JSVAL_TO_PRIVATE_PTR_IMPL(jsval_layout l)
     554                 : {
     555        17378848 :     return l.s.payload.ptr;
     556                 : }
     557                 : 
     558                 : static JS_ALWAYS_INLINE JSBool
     559           14996 : JSVAL_IS_GCTHING_IMPL(jsval_layout l)
     560                 : {
     561                 :     /* gcc sometimes generates signed < without explicit casts. */
     562           14996 :     return (uint32_t)l.s.tag >= (uint32_t)JSVAL_LOWER_INCL_TAG_OF_GCTHING_SET;
     563                 : }
     564                 : 
     565                 : static JS_ALWAYS_INLINE void *
     566            1216 : JSVAL_TO_GCTHING_IMPL(jsval_layout l)
     567                 : {
     568            1216 :     return l.s.payload.ptr;
     569                 : }
     570                 : 
     571                 : static JS_ALWAYS_INLINE JSBool
     572       101755069 : JSVAL_IS_TRACEABLE_IMPL(jsval_layout l)
     573                 : {
     574       101755069 :     return l.s.tag == JSVAL_TAG_STRING || l.s.tag == JSVAL_TAG_OBJECT;
     575                 : }
     576                 : 
     577                 : static JS_ALWAYS_INLINE uint32_t
     578             557 : JSVAL_TRACE_KIND_IMPL(jsval_layout l)
     579                 : {
     580             557 :     return (uint32_t)(JSBool)JSVAL_IS_STRING_IMPL(l);
     581                 : }
     582                 : 
     583                 : static JS_ALWAYS_INLINE JSBool
     584                 : JSVAL_IS_SPECIFIC_INT32_IMPL(jsval_layout l, int32_t i32)
     585                 : {
     586                 :     return l.s.tag == JSVAL_TAG_INT32 && l.s.payload.i32 == i32;
     587                 : }
     588                 : 
     589                 : static JS_ALWAYS_INLINE JSBool
     590                 : JSVAL_IS_SPECIFIC_BOOLEAN(jsval_layout l, JSBool b)
     591                 : {
     592                 :     return (l.s.tag == JSVAL_TAG_BOOLEAN) && (l.s.payload.boo == b);
     593                 : }
     594                 : 
     595                 : static JS_ALWAYS_INLINE jsval_layout
     596                 : MAGIC_TO_JSVAL_IMPL(JSWhyMagic why)
     597                 : {
     598                 :     jsval_layout l;
     599                 :     l.s.tag = JSVAL_TAG_MAGIC;
     600                 :     l.s.payload.why = why;
     601                 :     return l;
     602                 : }
     603                 : 
     604                 : static JS_ALWAYS_INLINE JSBool
     605                 : JSVAL_SAME_TYPE_IMPL(jsval_layout lhs, jsval_layout rhs)
     606                 : {
     607                 :     JSValueTag ltag = lhs.s.tag, rtag = rhs.s.tag;
     608                 :     return ltag == rtag || (ltag < JSVAL_TAG_CLEAR && rtag < JSVAL_TAG_CLEAR);
     609                 : }
     610                 : 
     611                 : static JS_ALWAYS_INLINE jsval_layout
     612          871399 : PRIVATE_UINT32_TO_JSVAL_IMPL(uint32_t ui)
     613                 : {
     614                 :     jsval_layout l;
     615          871399 :     l.s.tag = (JSValueTag)0;
     616          871399 :     l.s.payload.u32 = ui;
     617          871399 :     JS_ASSERT(JSVAL_IS_DOUBLE_IMPL(l));
     618                 :     return l;
     619                 : }
     620                 : 
     621                 : static JS_ALWAYS_INLINE uint32_t
     622         2680456 : JSVAL_TO_PRIVATE_UINT32_IMPL(jsval_layout l)
     623                 : {
     624         2680456 :     return l.s.payload.u32;
     625                 : }
     626                 : 
     627                 : static JS_ALWAYS_INLINE JSValueType
     628                 : JSVAL_EXTRACT_NON_DOUBLE_TYPE_IMPL(jsval_layout l)
     629                 : {
     630                 :     uint32_t type = l.s.tag & 0xF;
     631                 :     JS_ASSERT(type > JSVAL_TYPE_DOUBLE);
     632                 :     return (JSValueType)type;
     633                 : }
     634                 : 
     635                 : #elif JS_BITS_PER_WORD == 64
     636                 : 
     637                 : static JS_ALWAYS_INLINE jsval_layout
     638                 : BUILD_JSVAL(JSValueTag tag, uint64_t payload)
     639                 : {
     640                 :     jsval_layout l;
     641                 :     l.asBits = (((uint64_t)(uint32_t)tag) << JSVAL_TAG_SHIFT) | payload;
     642                 :     return l;
     643                 : }
     644                 : 
     645                 : static JS_ALWAYS_INLINE JSBool
     646                 : JSVAL_IS_DOUBLE_IMPL(jsval_layout l)
     647                 : {
     648                 :     return l.asBits <= JSVAL_SHIFTED_TAG_MAX_DOUBLE;
     649                 : }
     650                 : 
     651                 : static JS_ALWAYS_INLINE jsval_layout
     652                 : DOUBLE_TO_JSVAL_IMPL(double d)
     653                 : {
     654                 :     jsval_layout l;
     655                 :     l.asDouble = d;
     656                 :     JS_ASSERT(l.asBits <= JSVAL_SHIFTED_TAG_MAX_DOUBLE);
     657                 :     return l;
     658                 : }
     659                 : 
     660                 : static JS_ALWAYS_INLINE JSBool
     661                 : JSVAL_IS_INT32_IMPL(jsval_layout l)
     662                 : {
     663                 :     return (uint32_t)(l.asBits >> JSVAL_TAG_SHIFT) == JSVAL_TAG_INT32;
     664                 : }
     665                 : 
     666                 : static JS_ALWAYS_INLINE int32_t
     667                 : JSVAL_TO_INT32_IMPL(jsval_layout l)
     668                 : {
     669                 :     return (int32_t)l.asBits;
     670                 : }
     671                 : 
     672                 : static JS_ALWAYS_INLINE jsval_layout
     673                 : INT32_TO_JSVAL_IMPL(int32_t i32)
     674                 : {
     675                 :     jsval_layout l;
     676                 :     l.asBits = ((uint64_t)(uint32_t)i32) | JSVAL_SHIFTED_TAG_INT32;
     677                 :     return l;
     678                 : }
     679                 : 
     680                 : static JS_ALWAYS_INLINE JSBool
     681                 : JSVAL_IS_NUMBER_IMPL(jsval_layout l)
     682                 : {
     683                 :     return l.asBits < JSVAL_UPPER_EXCL_SHIFTED_TAG_OF_NUMBER_SET;
     684                 : }
     685                 : 
     686                 : static JS_ALWAYS_INLINE JSBool
     687                 : JSVAL_IS_UNDEFINED_IMPL(jsval_layout l)
     688                 : {
     689                 :     return l.asBits == JSVAL_SHIFTED_TAG_UNDEFINED;
     690                 : }
     691                 : 
     692                 : static JS_ALWAYS_INLINE JSBool
     693                 : JSVAL_IS_STRING_IMPL(jsval_layout l)
     694                 : {
     695                 :     return (uint32_t)(l.asBits >> JSVAL_TAG_SHIFT) == JSVAL_TAG_STRING;
     696                 : }
     697                 : 
     698                 : static JS_ALWAYS_INLINE jsval_layout
     699                 : STRING_TO_JSVAL_IMPL(JSString *str)
     700                 : {
     701                 :     jsval_layout l;
     702                 :     uint64_t strBits = (uint64_t)str;
     703                 :     JS_ASSERT(str);
     704                 :     JS_ASSERT((strBits >> JSVAL_TAG_SHIFT) == 0);
     705                 :     l.asBits = strBits | JSVAL_SHIFTED_TAG_STRING;
     706                 :     return l;
     707                 : }
     708                 : 
     709                 : static JS_ALWAYS_INLINE JSString *
     710                 : JSVAL_TO_STRING_IMPL(jsval_layout l)
     711                 : {
     712                 :     return (JSString *)(l.asBits & JSVAL_PAYLOAD_MASK);
     713                 : }
     714                 : 
     715                 : static JS_ALWAYS_INLINE JSBool
     716                 : JSVAL_IS_BOOLEAN_IMPL(jsval_layout l)
     717                 : {
     718                 :     return (uint32_t)(l.asBits >> JSVAL_TAG_SHIFT) == JSVAL_TAG_BOOLEAN;
     719                 : }
     720                 : 
     721                 : static JS_ALWAYS_INLINE JSBool
     722                 : JSVAL_TO_BOOLEAN_IMPL(jsval_layout l)
     723                 : {
     724                 :     return (JSBool)l.asBits;
     725                 : }
     726                 : 
     727                 : static JS_ALWAYS_INLINE jsval_layout
     728                 : BOOLEAN_TO_JSVAL_IMPL(JSBool b)
     729                 : {
     730                 :     jsval_layout l;
     731                 :     JS_ASSERT(b == JS_TRUE || b == JS_FALSE);
     732                 :     l.asBits = ((uint64_t)(uint32_t)b) | JSVAL_SHIFTED_TAG_BOOLEAN;
     733                 :     return l;
     734                 : }
     735                 : 
     736                 : static JS_ALWAYS_INLINE JSBool
     737                 : JSVAL_IS_MAGIC_IMPL(jsval_layout l)
     738                 : {
     739                 :     return (l.asBits >> JSVAL_TAG_SHIFT) == JSVAL_TAG_MAGIC;
     740                 : }
     741                 : 
     742                 : static JS_ALWAYS_INLINE JSBool
     743                 : JSVAL_IS_PRIMITIVE_IMPL(jsval_layout l)
     744                 : {
     745                 :     return l.asBits < JSVAL_UPPER_EXCL_SHIFTED_TAG_OF_PRIMITIVE_SET;
     746                 : }
     747                 : 
     748                 : static JS_ALWAYS_INLINE JSBool
     749                 : JSVAL_IS_OBJECT_IMPL(jsval_layout l)
     750                 : {
     751                 :     JS_ASSERT((l.asBits >> JSVAL_TAG_SHIFT) <= JSVAL_SHIFTED_TAG_OBJECT);
     752                 :     return l.asBits >= JSVAL_SHIFTED_TAG_OBJECT;
     753                 : }
     754                 : 
     755                 : static JS_ALWAYS_INLINE JSBool
     756                 : JSVAL_IS_OBJECT_OR_NULL_IMPL(jsval_layout l)
     757                 : {
     758                 :     JS_ASSERT((l.asBits >> JSVAL_TAG_SHIFT) <= JSVAL_TAG_OBJECT);
     759                 :     return l.asBits >= JSVAL_LOWER_INCL_SHIFTED_TAG_OF_OBJ_OR_NULL_SET;
     760                 : }
     761                 : 
     762                 : static JS_ALWAYS_INLINE JSObject *
     763                 : JSVAL_TO_OBJECT_IMPL(jsval_layout l)
     764                 : {
     765                 :     uint64_t ptrBits = l.asBits & JSVAL_PAYLOAD_MASK;
     766                 :     JS_ASSERT((ptrBits & 0x7) == 0);
     767                 :     return (JSObject *)ptrBits;
     768                 : }
     769                 : 
     770                 : static JS_ALWAYS_INLINE jsval_layout
     771                 : OBJECT_TO_JSVAL_IMPL(JSObject *obj)
     772                 : {
     773                 :     jsval_layout l;
     774                 :     uint64_t objBits = (uint64_t)obj;
     775                 :     JS_ASSERT(obj);
     776                 :     JS_ASSERT((objBits >> JSVAL_TAG_SHIFT) == 0);
     777                 :     l.asBits = objBits | JSVAL_SHIFTED_TAG_OBJECT;
     778                 :     return l;
     779                 : }
     780                 : 
     781                 : static JS_ALWAYS_INLINE JSBool
     782                 : JSVAL_IS_NULL_IMPL(jsval_layout l)
     783                 : {
     784                 :     return l.asBits == JSVAL_SHIFTED_TAG_NULL;
     785                 : }
     786                 : 
     787                 : static JS_ALWAYS_INLINE JSBool
     788                 : JSVAL_IS_GCTHING_IMPL(jsval_layout l)
     789                 : {
     790                 :     return l.asBits >= JSVAL_LOWER_INCL_SHIFTED_TAG_OF_GCTHING_SET;
     791                 : }
     792                 : 
     793                 : static JS_ALWAYS_INLINE void *
     794                 : JSVAL_TO_GCTHING_IMPL(jsval_layout l)
     795                 : {
     796                 :     uint64_t ptrBits = l.asBits & JSVAL_PAYLOAD_MASK;
     797                 :     JS_ASSERT((ptrBits & 0x7) == 0);
     798                 :     return (void *)ptrBits;
     799                 : }
     800                 : 
     801                 : static JS_ALWAYS_INLINE JSBool
     802                 : JSVAL_IS_TRACEABLE_IMPL(jsval_layout l)
     803                 : {
     804                 :     return JSVAL_IS_GCTHING_IMPL(l) && !JSVAL_IS_NULL_IMPL(l);
     805                 : }
     806                 : 
     807                 : static JS_ALWAYS_INLINE uint32_t
     808                 : JSVAL_TRACE_KIND_IMPL(jsval_layout l)
     809                 : {
     810                 :     return (uint32_t)(JSBool)!(JSVAL_IS_OBJECT_IMPL(l));
     811                 : }
     812                 : 
     813                 : static JS_ALWAYS_INLINE jsval_layout
     814                 : PRIVATE_PTR_TO_JSVAL_IMPL(void *ptr)
     815                 : {
     816                 :     jsval_layout l;
     817                 :     uint64_t ptrBits = (uint64_t)ptr;
     818                 :     JS_ASSERT((ptrBits & 1) == 0);
     819                 :     l.asBits = ptrBits >> 1;
     820                 :     JS_ASSERT(JSVAL_IS_DOUBLE_IMPL(l));
     821                 :     return l;
     822                 : }
     823                 : 
     824                 : static JS_ALWAYS_INLINE void *
     825                 : JSVAL_TO_PRIVATE_PTR_IMPL(jsval_layout l)
     826                 : {
     827                 :     JS_ASSERT((l.asBits & 0x8000000000000000LL) == 0);
     828                 :     return (void *)(l.asBits << 1);
     829                 : }
     830                 : 
     831                 : static JS_ALWAYS_INLINE JSBool
     832                 : JSVAL_IS_SPECIFIC_INT32_IMPL(jsval_layout l, int32_t i32)
     833                 : {
     834                 :     return l.asBits == (((uint64_t)(uint32_t)i32) | JSVAL_SHIFTED_TAG_INT32);
     835                 : }
     836                 : 
     837                 : static JS_ALWAYS_INLINE JSBool
     838                 : JSVAL_IS_SPECIFIC_BOOLEAN(jsval_layout l, JSBool b)
     839                 : {
     840                 :     return l.asBits == (((uint64_t)(uint32_t)b) | JSVAL_SHIFTED_TAG_BOOLEAN);
     841                 : }
     842                 : 
     843                 : static JS_ALWAYS_INLINE jsval_layout
     844                 : MAGIC_TO_JSVAL_IMPL(JSWhyMagic why)
     845                 : {
     846                 :     jsval_layout l;
     847                 :     l.asBits = ((uint64_t)(uint32_t)why) | JSVAL_SHIFTED_TAG_MAGIC;
     848                 :     return l;
     849                 : }
     850                 : 
     851                 : static JS_ALWAYS_INLINE JSBool
     852                 : JSVAL_SAME_TYPE_IMPL(jsval_layout lhs, jsval_layout rhs)
     853                 : {
     854                 :     uint64_t lbits = lhs.asBits, rbits = rhs.asBits;
     855                 :     return (lbits <= JSVAL_SHIFTED_TAG_MAX_DOUBLE && rbits <= JSVAL_SHIFTED_TAG_MAX_DOUBLE) ||
     856                 :            (((lbits ^ rbits) & 0xFFFF800000000000LL) == 0);
     857                 : }
     858                 : 
     859                 : static JS_ALWAYS_INLINE jsval_layout
     860                 : PRIVATE_UINT32_TO_JSVAL_IMPL(uint32_t ui)
     861                 : {
     862                 :     jsval_layout l;
     863                 :     l.asBits = (uint64_t)ui;
     864                 :     JS_ASSERT(JSVAL_IS_DOUBLE_IMPL(l));
     865                 :     return l;
     866                 : }
     867                 : 
     868                 : static JS_ALWAYS_INLINE uint32_t
     869                 : JSVAL_TO_PRIVATE_UINT32_IMPL(jsval_layout l)
     870                 : {
     871                 :     JS_ASSERT((l.asBits >> 32) == 0);
     872                 :     return (uint32_t)l.asBits;
     873                 : }
     874                 : 
     875                 : static JS_ALWAYS_INLINE JSValueType
     876                 : JSVAL_EXTRACT_NON_DOUBLE_TYPE_IMPL(jsval_layout l)
     877                 : {
     878                 :    uint64_t type = (l.asBits >> JSVAL_TAG_SHIFT) & 0xF;
     879                 :    JS_ASSERT(type > JSVAL_TYPE_DOUBLE);
     880                 :    return (JSValueType)type;
     881                 : }
     882                 : 
     883                 : #endif  /* JS_BITS_PER_WORD */
     884                 : 
     885                 : static JS_ALWAYS_INLINE double
     886                 : JS_CANONICALIZE_NAN(double d)
     887                 : {
     888                 :     if (JS_UNLIKELY(d != d)) {
     889                 :         jsval_layout l;
     890                 :         l.asBits = 0x7FF8000000000000LL;
     891                 :         return l.asDouble;
     892                 :     }
     893                 :     return d;
     894                 : }
     895                 : 
     896                 : JS_END_EXTERN_C
     897                 : 
     898                 : #ifdef __cplusplus
     899                 : static jsval_layout JSVAL_TO_IMPL(JS::Value);
     900                 : static JS::Value IMPL_TO_JSVAL(jsval_layout);
     901                 : #endif
     902                 : 
     903                 : #endif /* jsvalimpl_h__ */

Generated by: LCOV version 1.7