LCOV - app.info - js/src/jsval.h

LCOV - code coverage report
| Current view: | directory - js/src - jsval.h (source / functions) |  | Found | Hit | Coverage |
| Test: | app.info | Lines: | 102 | 102 | 100.0 %
| Date: | 2012-04-07 | Functions: | 37 | 37 | 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        65960491 : 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        65960491 :     if (d != 0)
          72        63557900 :         return JS_FALSE;
          73         2402591 :     x.d = d;
          74         2402591 :     return (x.s.hi & JSDOUBLE_HI32_SIGNBIT) != 0;
          75                 : }
          76                 :
          77                 : static JS_ALWAYS_INLINE JSBool
          78        65877820 : JSDOUBLE_IS_INT32(double d, int32_t* pi)
          79                 : {
          80        65877820 :     if (JSDOUBLE_IS_NEGZERO(d))
          81          233602 :         return JS_FALSE;
          82        65644218 :     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_FOOTER(id)
         119                 : #else
         120                 : # define JS_ENUM_HEADER(id, type)              enum id
         121                 : # define JS_ENUM_FOOTER(id)                    __attribute__((packed))
         122                 : #endif
         123                 :
         124                 : /* Remember to propagate changes to the C defines below. */
         125                 : JS_ENUM_HEADER(JSValueType, uint8_t)
         126                 : {
         127                 :     JSVAL_TYPE_DOUBLE              = 0x00,
         128                 :     JSVAL_TYPE_INT32               = 0x01,
         129                 :     JSVAL_TYPE_UNDEFINED           = 0x02,
         130                 :     JSVAL_TYPE_BOOLEAN             = 0x03,
         131                 :     JSVAL_TYPE_MAGIC               = 0x04,
         132                 :     JSVAL_TYPE_STRING              = 0x05,
         133                 :     JSVAL_TYPE_NULL                = 0x06,
         134                 :     JSVAL_TYPE_OBJECT              = 0x07,
         135                 :
         136                 :     /* These never appear in a jsval; they are only provided as an out-of-band value. */
         137                 :     JSVAL_TYPE_UNKNOWN             = 0x20,
         138                 :     JSVAL_TYPE_MISSING             = 0x21
         139                 : } JS_ENUM_FOOTER(JSValueType);
         140                 :
         141                 : JS_STATIC_ASSERT(sizeof(JSValueType) == 1);
         142                 :
         143                 : #if JS_BITS_PER_WORD == 32
         144                 :
         145                 : /* Remember to propagate changes to the C defines below. */
         146                 : JS_ENUM_HEADER(JSValueTag, uint32_t)
         147                 : {
         148                 :     JSVAL_TAG_CLEAR                = 0xFFFFFF80,
         149                 :     JSVAL_TAG_INT32                = JSVAL_TAG_CLEAR | JSVAL_TYPE_INT32,
         150                 :     JSVAL_TAG_UNDEFINED            = JSVAL_TAG_CLEAR | JSVAL_TYPE_UNDEFINED,
         151                 :     JSVAL_TAG_STRING               = JSVAL_TAG_CLEAR | JSVAL_TYPE_STRING,
         152                 :     JSVAL_TAG_BOOLEAN              = JSVAL_TAG_CLEAR | JSVAL_TYPE_BOOLEAN,
         153                 :     JSVAL_TAG_MAGIC                = JSVAL_TAG_CLEAR | JSVAL_TYPE_MAGIC,
         154                 :     JSVAL_TAG_NULL                 = JSVAL_TAG_CLEAR | JSVAL_TYPE_NULL,
         155                 :     JSVAL_TAG_OBJECT               = JSVAL_TAG_CLEAR | JSVAL_TYPE_OBJECT
         156                 : } JS_ENUM_FOOTER(JSValueTag);
         157                 :
         158                 : JS_STATIC_ASSERT(sizeof(JSValueTag) == 4);
         159                 :
         160                 : #elif JS_BITS_PER_WORD == 64
         161                 :
         162                 : /* Remember to propagate changes to the C defines below. */
         163                 : JS_ENUM_HEADER(JSValueTag, uint32_t)
         164                 : {
         165                 :     JSVAL_TAG_MAX_DOUBLE           = 0x1FFF0,
         166                 :     JSVAL_TAG_INT32                = JSVAL_TAG_MAX_DOUBLE | JSVAL_TYPE_INT32,
         167                 :     JSVAL_TAG_UNDEFINED            = JSVAL_TAG_MAX_DOUBLE | JSVAL_TYPE_UNDEFINED,
         168                 :     JSVAL_TAG_STRING               = JSVAL_TAG_MAX_DOUBLE | JSVAL_TYPE_STRING,
         169                 :     JSVAL_TAG_BOOLEAN              = JSVAL_TAG_MAX_DOUBLE | JSVAL_TYPE_BOOLEAN,
         170                 :     JSVAL_TAG_MAGIC                = JSVAL_TAG_MAX_DOUBLE | JSVAL_TYPE_MAGIC,
         171                 :     JSVAL_TAG_NULL                 = JSVAL_TAG_MAX_DOUBLE | JSVAL_TYPE_NULL,
         172                 :     JSVAL_TAG_OBJECT               = JSVAL_TAG_MAX_DOUBLE | JSVAL_TYPE_OBJECT
         173                 : } JS_ENUM_FOOTER(JSValueTag);
         174                 :
         175                 : JS_STATIC_ASSERT(sizeof(JSValueTag) == sizeof(uint32_t));
         176                 :
         177                 : JS_ENUM_HEADER(JSValueShiftedTag, uint64_t)
         178                 : {
         179                 :     JSVAL_SHIFTED_TAG_MAX_DOUBLE   = ((((uint64_t)JSVAL_TAG_MAX_DOUBLE) << JSVAL_TAG_SHIFT) | 0xFFFFFFFF),
         180                 :     JSVAL_SHIFTED_TAG_INT32        = (((uint64_t)JSVAL_TAG_INT32)      << JSVAL_TAG_SHIFT),
         181                 :     JSVAL_SHIFTED_TAG_UNDEFINED    = (((uint64_t)JSVAL_TAG_UNDEFINED)  << JSVAL_TAG_SHIFT),
         182                 :     JSVAL_SHIFTED_TAG_STRING       = (((uint64_t)JSVAL_TAG_STRING)     << JSVAL_TAG_SHIFT),
         183                 :     JSVAL_SHIFTED_TAG_BOOLEAN      = (((uint64_t)JSVAL_TAG_BOOLEAN)    << JSVAL_TAG_SHIFT),
         184                 :     JSVAL_SHIFTED_TAG_MAGIC        = (((uint64_t)JSVAL_TAG_MAGIC)      << JSVAL_TAG_SHIFT),
         185                 :     JSVAL_SHIFTED_TAG_NULL         = (((uint64_t)JSVAL_TAG_NULL)       << JSVAL_TAG_SHIFT),
         186                 :     JSVAL_SHIFTED_TAG_OBJECT       = (((uint64_t)JSVAL_TAG_OBJECT)     << JSVAL_TAG_SHIFT)
         187                 : } JS_ENUM_FOOTER(JSValueShiftedTag);
         188                 :
         189                 : JS_STATIC_ASSERT(sizeof(JSValueShiftedTag) == sizeof(uint64_t));
         190                 :
         191                 : #endif
         192                 :
         193                 : #else  /* defined(__cplusplus) */
         194                 :
         195                 : typedef uint8_t JSValueType;
         196                 : #define JSVAL_TYPE_DOUBLE            ((uint8_t)0x00)
         197                 : #define JSVAL_TYPE_INT32             ((uint8_t)0x01)
         198                 : #define JSVAL_TYPE_UNDEFINED         ((uint8_t)0x02)
         199                 : #define JSVAL_TYPE_BOOLEAN           ((uint8_t)0x03)
         200                 : #define JSVAL_TYPE_MAGIC             ((uint8_t)0x04)
         201                 : #define JSVAL_TYPE_STRING            ((uint8_t)0x05)
         202                 : #define JSVAL_TYPE_NULL              ((uint8_t)0x06)
         203                 : #define JSVAL_TYPE_OBJECT            ((uint8_t)0x07)
         204                 : #define JSVAL_TYPE_UNKNOWN           ((uint8_t)0x20)
         205                 :
         206                 : #if JS_BITS_PER_WORD == 32
         207                 :
         208                 : typedef uint32_t JSValueTag;
         209                 : #define JSVAL_TAG_CLEAR              ((uint32_t)(0xFFFFFF80))
         210                 : #define JSVAL_TAG_INT32              ((uint32_t)(JSVAL_TAG_CLEAR | JSVAL_TYPE_INT32))
         211                 : #define JSVAL_TAG_UNDEFINED          ((uint32_t)(JSVAL_TAG_CLEAR | JSVAL_TYPE_UNDEFINED))
         212                 : #define JSVAL_TAG_STRING             ((uint32_t)(JSVAL_TAG_CLEAR | JSVAL_TYPE_STRING))
         213                 : #define JSVAL_TAG_BOOLEAN            ((uint32_t)(JSVAL_TAG_CLEAR | JSVAL_TYPE_BOOLEAN))
         214                 : #define JSVAL_TAG_MAGIC              ((uint32_t)(JSVAL_TAG_CLEAR | JSVAL_TYPE_MAGIC))
         215                 : #define JSVAL_TAG_NULL               ((uint32_t)(JSVAL_TAG_CLEAR | JSVAL_TYPE_NULL))
         216                 : #define JSVAL_TAG_OBJECT             ((uint32_t)(JSVAL_TAG_CLEAR | JSVAL_TYPE_OBJECT))
         217                 :
         218                 : #elif JS_BITS_PER_WORD == 64
         219                 :
         220                 : typedef uint32_t JSValueTag;
         221                 : #define JSVAL_TAG_MAX_DOUBLE         ((uint32_t)(0x1FFF0))
         222                 : #define JSVAL_TAG_INT32              (uint32_t)(JSVAL_TAG_MAX_DOUBLE | JSVAL_TYPE_INT32)
         223                 : #define JSVAL_TAG_UNDEFINED          (uint32_t)(JSVAL_TAG_MAX_DOUBLE | JSVAL_TYPE_UNDEFINED)
         224                 : #define JSVAL_TAG_STRING             (uint32_t)(JSVAL_TAG_MAX_DOUBLE | JSVAL_TYPE_STRING)
         225                 : #define JSVAL_TAG_BOOLEAN            (uint32_t)(JSVAL_TAG_MAX_DOUBLE | JSVAL_TYPE_BOOLEAN)
         226                 : #define JSVAL_TAG_MAGIC              (uint32_t)(JSVAL_TAG_MAX_DOUBLE | JSVAL_TYPE_MAGIC)
         227                 : #define JSVAL_TAG_NULL               (uint32_t)(JSVAL_TAG_MAX_DOUBLE | JSVAL_TYPE_NULL)
         228                 : #define JSVAL_TAG_OBJECT             (uint32_t)(JSVAL_TAG_MAX_DOUBLE | JSVAL_TYPE_OBJECT)
         229                 :
         230                 : typedef uint64_t JSValueShiftedTag;
         231                 : #define JSVAL_SHIFTED_TAG_MAX_DOUBLE ((((uint64_t)JSVAL_TAG_MAX_DOUBLE) << JSVAL_TAG_SHIFT) | 0xFFFFFFFF)
         232                 : #define JSVAL_SHIFTED_TAG_INT32      (((uint64_t)JSVAL_TAG_INT32)      << JSVAL_TAG_SHIFT)
         233                 : #define JSVAL_SHIFTED_TAG_UNDEFINED  (((uint64_t)JSVAL_TAG_UNDEFINED)  << JSVAL_TAG_SHIFT)
         234                 : #define JSVAL_SHIFTED_TAG_STRING     (((uint64_t)JSVAL_TAG_STRING)     << JSVAL_TAG_SHIFT)
         235                 : #define JSVAL_SHIFTED_TAG_BOOLEAN    (((uint64_t)JSVAL_TAG_BOOLEAN)    << JSVAL_TAG_SHIFT)
         236                 : #define JSVAL_SHIFTED_TAG_MAGIC      (((uint64_t)JSVAL_TAG_MAGIC)      << JSVAL_TAG_SHIFT)
         237                 : #define JSVAL_SHIFTED_TAG_NULL       (((uint64_t)JSVAL_TAG_NULL)       << JSVAL_TAG_SHIFT)
         238                 : #define JSVAL_SHIFTED_TAG_OBJECT     (((uint64_t)JSVAL_TAG_OBJECT)     << JSVAL_TAG_SHIFT)
         239                 :
         240                 : #endif  /* JS_BITS_PER_WORD */
         241                 : #endif  /* defined(__cplusplus) && !defined(__SUNPRO_CC) */
         242                 :
         243                 : #define JSVAL_LOWER_INCL_TYPE_OF_OBJ_OR_NULL_SET        JSVAL_TYPE_NULL
         244                 : #define JSVAL_UPPER_EXCL_TYPE_OF_PRIMITIVE_SET          JSVAL_TYPE_OBJECT
         245                 : #define JSVAL_UPPER_INCL_TYPE_OF_NUMBER_SET             JSVAL_TYPE_INT32
         246                 : #define JSVAL_LOWER_INCL_TYPE_OF_PTR_PAYLOAD_SET        JSVAL_TYPE_MAGIC
         247                 :
         248                 : #if JS_BITS_PER_WORD == 32
         249                 :
         250                 : #define JSVAL_TYPE_TO_TAG(type)      ((JSValueTag)(JSVAL_TAG_CLEAR | (type)))
         251                 :
         252                 : #define JSVAL_LOWER_INCL_TAG_OF_OBJ_OR_NULL_SET         JSVAL_TAG_NULL
         253                 : #define JSVAL_UPPER_EXCL_TAG_OF_PRIMITIVE_SET           JSVAL_TAG_OBJECT
         254                 : #define JSVAL_UPPER_INCL_TAG_OF_NUMBER_SET              JSVAL_TAG_INT32
         255                 : #define JSVAL_LOWER_INCL_TAG_OF_GCTHING_SET             JSVAL_TAG_STRING
         256                 :
         257                 : #elif JS_BITS_PER_WORD == 64
         258                 :
         259                 : #define JSVAL_PAYLOAD_MASK           0x00007FFFFFFFFFFFLL
         260                 : #define JSVAL_TAG_MASK               0xFFFF800000000000LL
         261                 : #define JSVAL_TYPE_TO_TAG(type)      ((JSValueTag)(JSVAL_TAG_MAX_DOUBLE | (type)))
         262                 : #define JSVAL_TYPE_TO_SHIFTED_TAG(type) (((uint64_t)JSVAL_TYPE_TO_TAG(type)) << JSVAL_TAG_SHIFT)
         263                 :
         264                 : #define JSVAL_LOWER_INCL_SHIFTED_TAG_OF_OBJ_OR_NULL_SET  JSVAL_SHIFTED_TAG_NULL
         265                 : #define JSVAL_UPPER_EXCL_SHIFTED_TAG_OF_PRIMITIVE_SET    JSVAL_SHIFTED_TAG_OBJECT
         266                 : #define JSVAL_UPPER_EXCL_SHIFTED_TAG_OF_NUMBER_SET       JSVAL_SHIFTED_TAG_UNDEFINED
         267                 : #define JSVAL_LOWER_INCL_SHIFTED_TAG_OF_GCTHING_SET      JSVAL_SHIFTED_TAG_STRING
         268                 :
         269                 : #endif /* JS_BITS_PER_WORD */
         270                 :
         271                 : typedef enum JSWhyMagic
         272                 : {
         273                 :     JS_ARRAY_HOLE,               /* a hole in a dense array */
         274                 :     JS_NATIVE_ENUMERATE,         /* indicates that a custom enumerate hook forwarded
         275                 :                                   * to JS_EnumerateState, which really means the object can be
         276                 :                                   * enumerated like a native object. */
         277                 :     JS_NO_ITER_VALUE,            /* there is not a pending iterator value */
         278                 :     JS_GENERATOR_CLOSING,        /* exception value thrown when closing a generator */
         279                 :     JS_NO_CONSTANT,              /* compiler sentinel value */
         280                 :     JS_THIS_POISON,              /* used in debug builds to catch tracing errors */
         281                 :     JS_ARG_POISON,               /* used in debug builds to catch tracing errors */
         282                 :     JS_SERIALIZE_NO_NODE,        /* an empty subnode in the AST serializer */
         283                 :     JS_LAZY_ARGUMENTS,           /* lazy arguments value on the stack */
         284                 :     JS_UNASSIGNED_ARGUMENTS,     /* the initial value of callobj.arguments */
         285                 :     JS_OPTIMIZED_ARGUMENTS,      /* optimized-away 'arguments' value */
         286                 :     JS_IS_CONSTRUCTING,          /* magic value passed to natives to indicate construction */
         287                 :     JS_OVERWRITTEN_CALLEE,       /* arguments.callee has been overwritten */
         288                 :     JS_GENERIC_MAGIC             /* for local use */
         289                 : } JSWhyMagic;
         290                 :
         291                 : #if defined(IS_LITTLE_ENDIAN)
         292                 : # if JS_BITS_PER_WORD == 32
         293                 : typedef union jsval_layout
         294                 : {
         295                 :     uint64_t asBits;
         296                 :     struct {
         297                 :         union {
         298                 :             int32_t        i32;
         299                 :             uint32_t       u32;
         300                 :             JSBool         boo;
         301                 :             JSString       *str;
         302                 :             JSObject       *obj;
         303                 :             void           *ptr;
         304                 :             JSWhyMagic     why;
         305                 :             size_t         word;
         306                 :         } payload;
         307                 :         JSValueTag tag;
         308                 :     } s;
         309                 :     double asDouble;
         310                 :     void *asPtr;
         311                 : } JSVAL_ALIGNMENT jsval_layout;
         312                 : # elif JS_BITS_PER_WORD == 64
         313                 : typedef union jsval_layout
         314                 : {
         315                 :     uint64_t asBits;
         316                 : #if (!defined(_WIN64) && defined(__cplusplus))
         317                 :     /* MSVC does not pack these correctly :-( */
         318                 :     struct {
         319                 :         uint64_t           payload47 : 47;
         320                 :         JSValueTag         tag : 17;
         321                 :     } debugView;
         322                 : #endif
         323                 :     struct {
         324                 :         union {
         325                 :             int32_t        i32;
         326                 :             uint32_t       u32;
         327                 :             JSWhyMagic     why;
         328                 :         } payload;
         329                 :     } s;
         330                 :     double asDouble;
         331                 :     void *asPtr;
         332                 :     size_t asWord;
         333                 : } JSVAL_ALIGNMENT jsval_layout;
         334                 : # endif  /* JS_BITS_PER_WORD */
         335                 : #else   /* defined(IS_LITTLE_ENDIAN) */
         336                 : # if JS_BITS_PER_WORD == 32
         337                 : typedef union jsval_layout
         338                 : {
         339                 :     uint64_t asBits;
         340                 :     struct {
         341                 :         JSValueTag tag;
         342                 :         union {
         343                 :             int32_t        i32;
         344                 :             uint32_t       u32;
         345                 :             JSBool         boo;
         346                 :             JSString       *str;
         347                 :             JSObject       *obj;
         348                 :             void           *ptr;
         349                 :             JSWhyMagic     why;
         350                 :             size_t         word;
         351                 :         } payload;
         352                 :     } s;
         353                 :     double asDouble;
         354                 :     void *asPtr;
         355                 : } JSVAL_ALIGNMENT jsval_layout;
         356                 : # elif JS_BITS_PER_WORD == 64
         357                 : typedef union jsval_layout
         358                 : {
         359                 :     uint64_t asBits;
         360                 :     struct {
         361                 :         JSValueTag         tag : 17;
         362                 :         uint64_t           payload47 : 47;
         363                 :     } debugView;
         364                 :     struct {
         365                 :         uint32_t           padding;
         366                 :         union {
         367                 :             int32_t        i32;
         368                 :             uint32_t       u32;
         369                 :             JSWhyMagic     why;
         370                 :         } payload;
         371                 :     } s;
         372                 :     double asDouble;
         373                 :     void *asPtr;
         374                 :     size_t asWord;
         375                 : } JSVAL_ALIGNMENT jsval_layout;
         376                 : # endif /* JS_BITS_PER_WORD */
         377                 : #endif  /* defined(IS_LITTLE_ENDIAN) */
         378                 :
         379                 : JS_STATIC_ASSERT(sizeof(jsval_layout) == 8);
         380                 :
         381                 : #if JS_BITS_PER_WORD == 32
         382                 :
         383                 : /*
         384                 :  * N.B. GCC, in some but not all cases, chooses to emit signed comparison of
         385                 :  * JSValueTag even though its underlying type has been forced to be uint32_t.
         386                 :  * Thus, all comparisons should explicitly cast operands to uint32_t.
         387                 :  */
         388                 :
         389                 : static JS_ALWAYS_INLINE jsval_layout
         390       168251037 : BUILD_JSVAL(JSValueTag tag, uint32_t payload)
         391                 : {
         392                 :     jsval_layout l;
         393       168251037 :     l.asBits = (((uint64_t)(uint32_t)tag) << 32) | payload;
         394                 :     return l;
         395                 : }
         396                 :
         397                 : static JS_ALWAYS_INLINE JSBool
         398       403998296 : JSVAL_IS_DOUBLE_IMPL(jsval_layout l)
         399                 : {
         400       403998296 :     return (uint32_t)l.s.tag <= (uint32_t)JSVAL_TAG_CLEAR;
         401                 : }
         402                 :
         403                 : static JS_ALWAYS_INLINE jsval_layout
         404        17662549 : DOUBLE_TO_JSVAL_IMPL(double d)
         405                 : {
         406                 :     jsval_layout l;
         407        17662549 :     l.asDouble = d;
         408        17662549 :     JS_ASSERT(JSVAL_IS_DOUBLE_IMPL(l));
         409                 :     return l;
         410                 : }
         411                 :
         412                 : static JS_ALWAYS_INLINE JSBool
         413      1971117360 : JSVAL_IS_INT32_IMPL(jsval_layout l)
         414                 : {
         415      1971117360 :     return l.s.tag == JSVAL_TAG_INT32;
         416                 : }
         417                 :
         418                 : static JS_ALWAYS_INLINE int32_t
         419      1055163544 : JSVAL_TO_INT32_IMPL(jsval_layout l)
         420                 : {
         421      1055163544 :     return l.s.payload.i32;
         422                 : }
         423                 :
         424                 : static JS_ALWAYS_INLINE jsval_layout
         425       683418925 : INT32_TO_JSVAL_IMPL(int32_t i)
         426                 : {
         427                 :     jsval_layout l;
         428       683418925 :     l.s.tag = JSVAL_TAG_INT32;
         429       683418925 :     l.s.payload.i32 = i;
         430                 :     return l;
         431                 : }
         432                 :
         433                 : static JS_ALWAYS_INLINE JSBool
         434       183677485 : JSVAL_IS_NUMBER_IMPL(jsval_layout l)
         435                 : {
         436       183677485 :     JSValueTag tag = l.s.tag;
         437       183677485 :     JS_ASSERT(tag != JSVAL_TAG_CLEAR);
         438       183677485 :     return (uint32_t)tag <= (uint32_t)JSVAL_UPPER_INCL_TAG_OF_NUMBER_SET;
         439                 : }
         440                 :
         441                 : static JS_ALWAYS_INLINE JSBool
         442        62842279 : JSVAL_IS_UNDEFINED_IMPL(jsval_layout l)
         443                 : {
         444        62842279 :     return l.s.tag == JSVAL_TAG_UNDEFINED;
         445                 : }
         446                 :
         447                 : static JS_ALWAYS_INLINE JSBool
         448      1345190888 : JSVAL_IS_STRING_IMPL(jsval_layout l)
         449                 : {
         450      1345190888 :     return l.s.tag == JSVAL_TAG_STRING;
         451                 : }
         452                 :
         453                 : static JS_ALWAYS_INLINE jsval_layout
         454       123774046 : STRING_TO_JSVAL_IMPL(JSString *str)
         455                 : {
         456                 :     jsval_layout l;
         457       123774046 :     JS_ASSERT(str);
         458       123774046 :     l.s.tag = JSVAL_TAG_STRING;
         459       123774046 :     l.s.payload.str = str;
         460                 :     return l;
         461                 : }
         462                 :
         463                 : static JS_ALWAYS_INLINE JSString *
         464       152083934 : JSVAL_TO_STRING_IMPL(jsval_layout l)
         465                 : {
         466       152083934 :     return l.s.payload.str;
         467                 : }
         468                 :
         469                 : static JS_ALWAYS_INLINE JSBool
         470        40958360 : JSVAL_IS_BOOLEAN_IMPL(jsval_layout l)
         471                 : {
         472        40958360 :     return l.s.tag == JSVAL_TAG_BOOLEAN;
         473                 : }
         474                 :
         475                 : static JS_ALWAYS_INLINE JSBool
         476        22808908 : JSVAL_TO_BOOLEAN_IMPL(jsval_layout l)
         477                 : {
         478        22808908 :     return l.s.payload.boo;
         479                 : }
         480                 :
         481                 : static JS_ALWAYS_INLINE jsval_layout
         482        32118119 : BOOLEAN_TO_JSVAL_IMPL(JSBool b)
         483                 : {
         484                 :     jsval_layout l;
         485        32118119 :     JS_ASSERT(b == JS_TRUE || b == JS_FALSE);
         486        32118119 :     l.s.tag = JSVAL_TAG_BOOLEAN;
         487        32118119 :     l.s.payload.boo = b;
         488                 :     return l;
         489                 : }
         490                 :
         491                 : static JS_ALWAYS_INLINE JSBool
         492       312567205 : JSVAL_IS_MAGIC_IMPL(jsval_layout l)
         493                 : {
         494       312567205 :     return l.s.tag == JSVAL_TAG_MAGIC;
         495                 : }
         496                 :
         497                 : static JS_ALWAYS_INLINE JSBool
         498     -2006412904 : JSVAL_IS_OBJECT_IMPL(jsval_layout l)
         499                 : {
         500     -2006412904 :     return l.s.tag == JSVAL_TAG_OBJECT;
         501                 : }
         502                 :
         503                 : static JS_ALWAYS_INLINE JSBool
         504        54390492 : JSVAL_IS_PRIMITIVE_IMPL(jsval_layout l)
         505                 : {
         506        54390492 :     return (uint32_t)l.s.tag < (uint32_t)JSVAL_UPPER_EXCL_TAG_OF_PRIMITIVE_SET;
         507                 : }
         508                 :
         509                 : static JS_ALWAYS_INLINE JSBool
         510         3735981 : JSVAL_IS_OBJECT_OR_NULL_IMPL(jsval_layout l)
         511                 : {
         512         3735981 :     JS_ASSERT((uint32_t)l.s.tag <= (uint32_t)JSVAL_TAG_OBJECT);
         513         3735981 :     return (uint32_t)l.s.tag >= (uint32_t)JSVAL_LOWER_INCL_TAG_OF_OBJ_OR_NULL_SET;
         514                 : }
         515                 :
         516                 : static JS_ALWAYS_INLINE JSObject *
         517       638829691 : JSVAL_TO_OBJECT_IMPL(jsval_layout l)
         518                 : {
         519       638829691 :     return l.s.payload.obj;
         520                 : }
         521                 :
         522                 : static JS_ALWAYS_INLINE jsval_layout
         523       111782739 : OBJECT_TO_JSVAL_IMPL(JSObject *obj)
         524                 : {
         525                 :     jsval_layout l;
         526       111782739 :     JS_ASSERT(obj);
         527       111782739 :     l.s.tag = JSVAL_TAG_OBJECT;
         528       111782739 :     l.s.payload.obj = obj;
         529                 :     return l;
         530                 : }
         531                 :
         532                 : static JS_ALWAYS_INLINE JSBool
         533        62584542 : JSVAL_IS_NULL_IMPL(jsval_layout l)
         534                 : {
         535        62584542 :     return l.s.tag == JSVAL_TAG_NULL;
         536                 : }
         537                 :
         538                 : static JS_ALWAYS_INLINE jsval_layout
         539         3298317 : PRIVATE_PTR_TO_JSVAL_IMPL(void *ptr)
         540                 : {
         541                 :     jsval_layout l;
         542         3298317 :     JS_ASSERT(((uint32_t)ptr & 1) == 0);
         543         3298317 :     l.s.tag = (JSValueTag)0;
         544         3298317 :     l.s.payload.ptr = ptr;
         545         3298317 :     JS_ASSERT(JSVAL_IS_DOUBLE_IMPL(l));
         546                 :     return l;
         547                 : }
         548                 :
         549                 : static JS_ALWAYS_INLINE void *
         550         3979268 : JSVAL_TO_PRIVATE_PTR_IMPL(jsval_layout l)
         551                 : {
         552         3979268 :     return l.s.payload.ptr;
         553                 : }
         554                 :
         555                 : static JS_ALWAYS_INLINE JSBool
         556        21042820 : JSVAL_IS_GCTHING_IMPL(jsval_layout l)
         557                 : {
         558                 :     /* gcc sometimes generates signed < without explicit casts. */
         559        21042820 :     return (uint32_t)l.s.tag >= (uint32_t)JSVAL_LOWER_INCL_TAG_OF_GCTHING_SET;
         560                 : }
         561                 :
         562                 : static JS_ALWAYS_INLINE void *
         563        21042772 : JSVAL_TO_GCTHING_IMPL(jsval_layout l)
         564                 : {
         565        21042772 :     return l.s.payload.ptr;
         566                 : }
         567                 :
         568                 : static JS_ALWAYS_INLINE JSBool
         569       131789308 : JSVAL_IS_TRACEABLE_IMPL(jsval_layout l)
         570                 : {
         571       131789308 :     return l.s.tag == JSVAL_TAG_STRING || l.s.tag == JSVAL_TAG_OBJECT;
         572                 : }
         573                 :
         574                 : static JS_ALWAYS_INLINE uint32_t
         575         6957567 : JSVAL_TRACE_KIND_IMPL(jsval_layout l)
         576                 : {
         577         6957567 :     return (uint32_t)(JSBool)JSVAL_IS_STRING_IMPL(l);
         578                 : }
         579                 :
         580                 : static JS_ALWAYS_INLINE JSBool
         581             306 : JSVAL_IS_SPECIFIC_INT32_IMPL(jsval_layout l, int32_t i32)
         582                 : {
         583             306 :     return l.s.tag == JSVAL_TAG_INT32 && l.s.payload.i32 == i32;
         584                 : }
         585                 :
         586                 : static JS_ALWAYS_INLINE JSBool
         587        44282328 : JSVAL_IS_SPECIFIC_BOOLEAN(jsval_layout l, JSBool b)
         588                 : {
         589        44282328 :     return (l.s.tag == JSVAL_TAG_BOOLEAN) && (l.s.payload.boo == b);
         590                 : }
         591                 :
         592                 : static JS_ALWAYS_INLINE jsval_layout
         593        26795126 : MAGIC_TO_JSVAL_IMPL(JSWhyMagic why)
         594                 : {
         595                 :     jsval_layout l;
         596        26795126 :     l.s.tag = JSVAL_TAG_MAGIC;
         597        26795126 :     l.s.payload.why = why;
         598                 :     return l;
         599                 : }
         600                 :
         601                 : static JS_ALWAYS_INLINE JSBool
         602        14958488 : JSVAL_SAME_TYPE_IMPL(jsval_layout lhs, jsval_layout rhs)
         603                 : {
         604        14958488 :     JSValueTag ltag = lhs.s.tag, rtag = rhs.s.tag;
         605        14958488 :     return ltag == rtag || (ltag < JSVAL_TAG_CLEAR && rtag < JSVAL_TAG_CLEAR);
         606                 : }
         607                 :
         608                 : static JS_ALWAYS_INLINE jsval_layout
         609          108780 : PRIVATE_UINT32_TO_JSVAL_IMPL(uint32_t ui)
         610                 : {
         611                 :     jsval_layout l;
         612          108780 :     l.s.tag = (JSValueTag)0;
         613          108780 :     l.s.payload.u32 = ui;
         614          108780 :     JS_ASSERT(JSVAL_IS_DOUBLE_IMPL(l));
         615                 :     return l;
         616                 : }
         617                 :
         618                 : static JS_ALWAYS_INLINE uint32_t
         619          180092 : JSVAL_TO_PRIVATE_UINT32_IMPL(jsval_layout l)
         620                 : {
         621          180092 :     return l.s.payload.u32;
         622                 : }
         623                 :
         624                 : static JS_ALWAYS_INLINE JSValueType
         625       116057337 : JSVAL_EXTRACT_NON_DOUBLE_TYPE_IMPL(jsval_layout l)
         626                 : {
         627       116057337 :     uint32_t type = l.s.tag & 0xF;
         628       116057337 :     JS_ASSERT(type > JSVAL_TYPE_DOUBLE);
         629       116057337 :     return (JSValueType)type;
         630                 : }
         631                 :
         632                 : #elif JS_BITS_PER_WORD == 64
         633                 :
         634                 : static JS_ALWAYS_INLINE jsval_layout
         635                 : BUILD_JSVAL(JSValueTag tag, uint64_t payload)
         636                 : {
         637                 :     jsval_layout l;
         638                 :     l.asBits = (((uint64_t)(uint32_t)tag) << JSVAL_TAG_SHIFT) | payload;
         639                 :     return l;
         640                 : }
         641                 :
         642                 : static JS_ALWAYS_INLINE JSBool
         643                 : JSVAL_IS_DOUBLE_IMPL(jsval_layout l)
         644                 : {
         645                 :     return l.asBits <= JSVAL_SHIFTED_TAG_MAX_DOUBLE;
         646                 : }
         647                 :
         648                 : static JS_ALWAYS_INLINE jsval_layout
         649                 : DOUBLE_TO_JSVAL_IMPL(double d)
         650                 : {
         651                 :     jsval_layout l;
         652                 :     l.asDouble = d;
         653                 :     JS_ASSERT(l.asBits <= JSVAL_SHIFTED_TAG_MAX_DOUBLE);
         654                 :     return l;
         655                 : }
         656                 :
         657                 : static JS_ALWAYS_INLINE JSBool
         658                 : JSVAL_IS_INT32_IMPL(jsval_layout l)
         659                 : {
         660                 :     return (uint32_t)(l.asBits >> JSVAL_TAG_SHIFT) == JSVAL_TAG_INT32;
         661                 : }
         662                 :
         663                 : static JS_ALWAYS_INLINE int32_t
         664                 : JSVAL_TO_INT32_IMPL(jsval_layout l)
         665                 : {
         666                 :     return (int32_t)l.asBits;
         667                 : }
         668                 :
         669                 : static JS_ALWAYS_INLINE jsval_layout
         670                 : INT32_TO_JSVAL_IMPL(int32_t i32)
         671                 : {
         672                 :     jsval_layout l;
         673                 :     l.asBits = ((uint64_t)(uint32_t)i32) | JSVAL_SHIFTED_TAG_INT32;
         674                 :     return l;
         675                 : }
         676                 :
         677                 : static JS_ALWAYS_INLINE JSBool
         678                 : JSVAL_IS_NUMBER_IMPL(jsval_layout l)
         679                 : {
         680                 :     return l.asBits < JSVAL_UPPER_EXCL_SHIFTED_TAG_OF_NUMBER_SET;
         681                 : }
         682                 :
         683                 : static JS_ALWAYS_INLINE JSBool
         684                 : JSVAL_IS_UNDEFINED_IMPL(jsval_layout l)
         685                 : {
         686                 :     return l.asBits == JSVAL_SHIFTED_TAG_UNDEFINED;
         687                 : }
         688                 :
         689                 : static JS_ALWAYS_INLINE JSBool
         690                 : JSVAL_IS_STRING_IMPL(jsval_layout l)
         691                 : {
         692                 :     return (uint32_t)(l.asBits >> JSVAL_TAG_SHIFT) == JSVAL_TAG_STRING;
         693                 : }
         694                 :
         695                 : static JS_ALWAYS_INLINE jsval_layout
         696                 : STRING_TO_JSVAL_IMPL(JSString *str)
         697                 : {
         698                 :     jsval_layout l;
         699                 :     uint64_t strBits = (uint64_t)str;
         700                 :     JS_ASSERT(str);
         701                 :     JS_ASSERT((strBits >> JSVAL_TAG_SHIFT) == 0);
         702                 :     l.asBits = strBits | JSVAL_SHIFTED_TAG_STRING;
         703                 :     return l;
         704                 : }
         705                 :
         706                 : static JS_ALWAYS_INLINE JSString *
         707                 : JSVAL_TO_STRING_IMPL(jsval_layout l)
         708                 : {
         709                 :     return (JSString *)(l.asBits & JSVAL_PAYLOAD_MASK);
         710                 : }
         711                 :
         712                 : static JS_ALWAYS_INLINE JSBool
         713                 : JSVAL_IS_BOOLEAN_IMPL(jsval_layout l)
         714                 : {
         715                 :     return (uint32_t)(l.asBits >> JSVAL_TAG_SHIFT) == JSVAL_TAG_BOOLEAN;
         716                 : }
         717                 :
         718                 : static JS_ALWAYS_INLINE JSBool
         719                 : JSVAL_TO_BOOLEAN_IMPL(jsval_layout l)
         720                 : {
         721                 :     return (JSBool)l.asBits;
         722                 : }
         723                 :
         724                 : static JS_ALWAYS_INLINE jsval_layout
         725                 : BOOLEAN_TO_JSVAL_IMPL(JSBool b)
         726                 : {
         727                 :     jsval_layout l;
         728                 :     JS_ASSERT(b == JS_TRUE || b == JS_FALSE);
         729                 :     l.asBits = ((uint64_t)(uint32_t)b) | JSVAL_SHIFTED_TAG_BOOLEAN;
         730                 :     return l;
         731                 : }
         732                 :
         733                 : static JS_ALWAYS_INLINE JSBool
         734                 : JSVAL_IS_MAGIC_IMPL(jsval_layout l)
         735                 : {
         736                 :     return (l.asBits >> JSVAL_TAG_SHIFT) == JSVAL_TAG_MAGIC;
         737                 : }
         738                 :
         739                 : static JS_ALWAYS_INLINE JSBool
         740                 : JSVAL_IS_PRIMITIVE_IMPL(jsval_layout l)
         741                 : {
         742                 :     return l.asBits < JSVAL_UPPER_EXCL_SHIFTED_TAG_OF_PRIMITIVE_SET;
         743                 : }
         744                 :
         745                 : static JS_ALWAYS_INLINE JSBool
         746                 : JSVAL_IS_OBJECT_IMPL(jsval_layout l)
         747                 : {
         748                 :     JS_ASSERT((l.asBits >> JSVAL_TAG_SHIFT) <= JSVAL_SHIFTED_TAG_OBJECT);
         749                 :     return l.asBits >= JSVAL_SHIFTED_TAG_OBJECT;
         750                 : }
         751                 :
         752                 : static JS_ALWAYS_INLINE JSBool
         753                 : JSVAL_IS_OBJECT_OR_NULL_IMPL(jsval_layout l)
         754                 : {
         755                 :     JS_ASSERT((l.asBits >> JSVAL_TAG_SHIFT) <= JSVAL_TAG_OBJECT);
         756                 :     return l.asBits >= JSVAL_LOWER_INCL_SHIFTED_TAG_OF_OBJ_OR_NULL_SET;
         757                 : }
         758                 :
         759                 : static JS_ALWAYS_INLINE JSObject *
         760                 : JSVAL_TO_OBJECT_IMPL(jsval_layout l)
         761                 : {
         762                 :     uint64_t ptrBits = l.asBits & JSVAL_PAYLOAD_MASK;
         763                 :     JS_ASSERT((ptrBits & 0x7) == 0);
         764                 :     return (JSObject *)ptrBits;
         765                 : }
         766                 :
         767                 : static JS_ALWAYS_INLINE jsval_layout
         768                 : OBJECT_TO_JSVAL_IMPL(JSObject *obj)
         769                 : {
         770                 :     jsval_layout l;
         771                 :     uint64_t objBits = (uint64_t)obj;
         772                 :     JS_ASSERT(obj);
         773                 :     JS_ASSERT((objBits >> JSVAL_TAG_SHIFT) == 0);
         774                 :     l.asBits = objBits | JSVAL_SHIFTED_TAG_OBJECT;
         775                 :     return l;
         776                 : }
         777                 :
         778                 : static JS_ALWAYS_INLINE JSBool
         779                 : JSVAL_IS_NULL_IMPL(jsval_layout l)
         780                 : {
         781                 :     return l.asBits == JSVAL_SHIFTED_TAG_NULL;
         782                 : }
         783                 :
         784                 : static JS_ALWAYS_INLINE JSBool
         785                 : JSVAL_IS_GCTHING_IMPL(jsval_layout l)
         786                 : {
         787                 :     return l.asBits >= JSVAL_LOWER_INCL_SHIFTED_TAG_OF_GCTHING_SET;
         788                 : }
         789                 :
         790                 : static JS_ALWAYS_INLINE void *
         791                 : JSVAL_TO_GCTHING_IMPL(jsval_layout l)
         792                 : {
         793                 :     uint64_t ptrBits = l.asBits & JSVAL_PAYLOAD_MASK;
         794                 :     JS_ASSERT((ptrBits & 0x7) == 0);
         795                 :     return (void *)ptrBits;
         796                 : }
         797                 :
         798                 : static JS_ALWAYS_INLINE JSBool
         799                 : JSVAL_IS_TRACEABLE_IMPL(jsval_layout l)
         800                 : {
         801                 :     return JSVAL_IS_GCTHING_IMPL(l) && !JSVAL_IS_NULL_IMPL(l);
         802                 : }
         803                 :
         804                 : static JS_ALWAYS_INLINE uint32_t
         805                 : JSVAL_TRACE_KIND_IMPL(jsval_layout l)
         806                 : {
         807                 :     return (uint32_t)(JSBool)!(JSVAL_IS_OBJECT_IMPL(l));
         808                 : }
         809                 :
         810                 : static JS_ALWAYS_INLINE jsval_layout
         811                 : PRIVATE_PTR_TO_JSVAL_IMPL(void *ptr)
         812                 : {
         813                 :     jsval_layout l;
         814                 :     uint64_t ptrBits = (uint64_t)ptr;
         815                 :     JS_ASSERT((ptrBits & 1) == 0);
         816                 :     l.asBits = ptrBits >> 1;
         817                 :     JS_ASSERT(JSVAL_IS_DOUBLE_IMPL(l));
         818                 :     return l;
         819                 : }
         820                 :
         821                 : static JS_ALWAYS_INLINE void *
         822                 : JSVAL_TO_PRIVATE_PTR_IMPL(jsval_layout l)
         823                 : {
         824                 :     JS_ASSERT((l.asBits & 0x8000000000000000LL) == 0);
         825                 :     return (void *)(l.asBits << 1);
         826                 : }
         827                 :
         828                 : static JS_ALWAYS_INLINE JSBool
         829                 : JSVAL_IS_SPECIFIC_INT32_IMPL(jsval_layout l, int32_t i32)
         830                 : {
         831                 :     return l.asBits == (((uint64_t)(uint32_t)i32) | JSVAL_SHIFTED_TAG_INT32);
         832                 : }
         833                 :
         834                 : static JS_ALWAYS_INLINE JSBool
         835                 : JSVAL_IS_SPECIFIC_BOOLEAN(jsval_layout l, JSBool b)
         836                 : {
         837                 :     return l.asBits == (((uint64_t)(uint32_t)b) | JSVAL_SHIFTED_TAG_BOOLEAN);
         838                 : }
         839                 :
         840                 : static JS_ALWAYS_INLINE jsval_layout
         841                 : MAGIC_TO_JSVAL_IMPL(JSWhyMagic why)
         842                 : {
         843                 :     jsval_layout l;
         844                 :     l.asBits = ((uint64_t)(uint32_t)why) | JSVAL_SHIFTED_TAG_MAGIC;
         845                 :     return l;
         846                 : }
         847                 :
         848                 : static JS_ALWAYS_INLINE JSBool
         849                 : JSVAL_SAME_TYPE_IMPL(jsval_layout lhs, jsval_layout rhs)
         850                 : {
         851                 :     uint64_t lbits = lhs.asBits, rbits = rhs.asBits;
         852                 :     return (lbits <= JSVAL_SHIFTED_TAG_MAX_DOUBLE && rbits <= JSVAL_SHIFTED_TAG_MAX_DOUBLE) ||
         853                 :            (((lbits ^ rbits) & 0xFFFF800000000000LL) == 0);
         854                 : }
         855                 :
         856                 : static JS_ALWAYS_INLINE jsval_layout
         857                 : PRIVATE_UINT32_TO_JSVAL_IMPL(uint32_t ui)
         858                 : {
         859                 :     jsval_layout l;
         860                 :     l.asBits = (uint64_t)ui;
         861                 :     JS_ASSERT(JSVAL_IS_DOUBLE_IMPL(l));
         862                 :     return l;
         863                 : }
         864                 :
         865                 : static JS_ALWAYS_INLINE uint32_t
         866                 : JSVAL_TO_PRIVATE_UINT32_IMPL(jsval_layout l)
         867                 : {
         868                 :     JS_ASSERT((l.asBits >> 32) == 0);
         869                 :     return (uint32_t)l.asBits;
         870                 : }
         871                 :
         872                 : static JS_ALWAYS_INLINE JSValueType
         873                 : JSVAL_EXTRACT_NON_DOUBLE_TYPE_IMPL(jsval_layout l)
         874                 : {
         875                 :    uint64_t type = (l.asBits >> JSVAL_TAG_SHIFT) & 0xF;
         876                 :    JS_ASSERT(type > JSVAL_TYPE_DOUBLE);
         877                 :    return (JSValueType)type;
         878                 : }
         879                 :
         880                 : #endif  /* JS_BITS_PER_WORD */
         881                 :
         882                 : static JS_ALWAYS_INLINE double
         883             432 : JS_CANONICALIZE_NAN(double d)
         884                 : {
         885             432 :     if (JS_UNLIKELY(d != d)) {
         886                 :         jsval_layout l;
         887              18 :         l.asBits = 0x7FF8000000000000LL;
         888              18 :         return l.asDouble;
         889                 :     }
         890             414 :     return d;
         891                 : }
         892                 :
         893                 : JS_END_EXTERN_C
         894                 :
         895                 : #ifdef __cplusplus
         896                 : static jsval_layout JSVAL_TO_IMPL(JS::Value);
         897                 : static JS::Value IMPL_TO_JSVAL(jsval_layout);
         898                 : #endif
         899                 :
         900                 : #endif /* jsvalimpl_h__ */

Generated by: LCOV version 1.7