DXR is a code search and navigation tool aimed at making sense of large projects. It supports full-text and regex searches as well as structural queries.

Untracked file

Line Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
 *
 * ***** BEGIN LICENSE BLOCK *****
 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
 *
 * The contents of this file are subject to the Mozilla Public License Version
 * 1.1 (the "License"); you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 * http://www.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * The Original Code is the JavaScript 2 Prototype.
 *
 * The Initial Developer of the Original Code is
 * Netscape Communications Corporation.
 * Portions created by the Initial Developer are Copyright (C) 1998
 * the Initial Developer. All Rights Reserved.
 *
 * Contributor(s):
 *
 * Alternatively, the contents of this file may be used under the terms of
 * either the GNU General Public License Version 2 or later (the "GPL"), or
 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 * in which case the provisions of the GPL or the LGPL are applicable instead
 * of those above. If you wish to allow use of your version of this file only
 * under the terms of either the GPL or the LGPL, and not to allow others to
 * use your version of this file under the terms of the MPL, indicate your
 * decision by deleting the provisions above and replace them with the notice
 * and other provisions required by the GPL or the LGPL. If you do not delete
 * the provisions above, a recipient may use your version of this file under
 * the terms of any one of the MPL, the GPL or the LGPL.
 *
 * ***** END LICENSE BLOCK ***** */

#ifndef js2value_h___
#define js2value_h___


/*
 * Type tags stored in the low bits of a js2val.
 */
#define JS2VAL_OBJECT            0x0     /* untagged reference to object */
#define JS2VAL_INT               0x1     /* tagged 31-bit integer value */
#define JS2VAL_DOUBLE            0x2     /* tagged reference to double */
#define JS2VAL_LONG              0x4     /* tagged reference to long */
#define JS2VAL_ULONG             0x6     /* tagged reference to unsigned long */
#define JS2VAL_FLOAT             0x8     /* tagged reference to float */
#define JS2VAL_STRING            0xA     /* tagged reference to string */
#define JS2VAL_BOOLEAN           0xC     /* tagged boolean value */

#define JS2VAL_UNINITIALIZED     0x80    /* reserve this object reference value as an indication
                                            that a variable has yet to be initialized  */
#define JS2VAL_IS_INITIALIZED(v)      (v != JS2VAL_UNINITIALIZED)
#define JS2VAL_IS_UNINITIALIZED(v)    (v == JS2VAL_UNINITIALIZED)

#define JS2VAL_INACCESSIBLE      0x90    /* reserve this object reference value as an indication
                                            that a variable has yet to become available  */
#define JS2VAL_IS_ACCESSIBLE(v)      (v != JS2VAL_INACCESSIBLE)
#define JS2VAL_IS_INACCESSIBLE(v)    (v == JS2VAL_INACCESSIBLE)

#define JS2VAL_FUTUREVALUE       0xA0    /* reserve this object reference value as an indication
                                            that a variable has to have it's initializer run */
#define JS2VAL_IS_FUTURE(v)      (v == JS2VAL_FUTUREVALUE)

#define JS2VAL_IS_SPECIALREF(v)     (v &&  ((v | 0xF0) == 0xF0))

/* Type tag bitfield length and derived macros. */
#define JS2VAL_TAGBITS           4
#define JS2VAL_TAGMASK           JS_BITMASK(JS2VAL_TAGBITS)
#define JS2VAL_TAG(v)            ((v) & JS2VAL_TAGMASK)
#define JS2VAL_SETTAG(v,t)       ((v) | (t))
#define JS2VAL_CLRTAG(v)         ((v) & ~(js2val)JS2VAL_TAGMASK)
#define JS2VAL_ALIGN             JS_BIT(JS2VAL_TAGBITS)

#define JS2VAL_INT_POW2(n)       ((js2val)1 << (n))
#define JS2VAL_INT_MIN           ((js2val)1 - JS2VAL_INT_POW2(30))
#define JS2VAL_INT_MAX           (JS2VAL_INT_POW2(30) - 1)
#define INT_TO_JS2VAL(i)         (((js2val)(i) << 1) | JS2VAL_INT)
#define JS2VAL_TO_INT(v)         ((int32)(v) >> 1)
#define INT_FITS_IN_JS2VAL(i)    ((uint32)((i)+JS2VAL_INT_MAX) <= 2*JS2VAL_INT_MAX)
#define INT_FITS_IN_JSVAL(i)     ((jsuint)((i)+JSVAL_INT_MAX) <= 2*JSVAL_INT_MAX)

#define LONG_IS_INT(x)           (JSLL_CMP((x), >, -20) && JSLL_CMP(20, >, (x)))
#define ULONG_IS_INT(x)          (JSLL_CMP(JS2VAL_INT_MAX, >, (x)))

#define JS2VAL_VOID              INT_TO_JS2VAL(0 - JS2VAL_INT_POW2(30))
#define JS2VAL_NULL              OBJECT_TO_JS2VAL(0)
#define JS2VAL_FALSE             BOOLEAN_TO_JS2VAL(false)
#define JS2VAL_TRUE              BOOLEAN_TO_JS2VAL(true)
#define JS2VAL_ZERO              INT_TO_JS2VAL(0)

/* Predicates for type testing. */
#define JS2VAL_IS_OBJECT(v)      ((JS2VAL_TAG(v) == JS2VAL_OBJECT) && !JS2VAL_IS_SPECIALREF(v))
// XXX think about some way of making this faster...
#define JS2VAL_IS_NUMBER(v)      (JS2VAL_IS_INT(v) || JS2VAL_IS_DOUBLE(v) || JS2VAL_IS_LONG(v) || JS2VAL_IS_ULONG(v) || JS2VAL_IS_FLOAT(v)) 
#define JS2VAL_IS_INT(v)         (((v) & JS2VAL_INT) && (v) != JS2VAL_VOID)
#define JS2VAL_IS_DOUBLE(v)      (JS2VAL_TAG(v) == JS2VAL_DOUBLE)
#define JS2VAL_IS_STRING(v)      (JS2VAL_TAG(v) == JS2VAL_STRING)
#define JS2VAL_IS_BOOLEAN(v)     (JS2VAL_TAG(v) == JS2VAL_BOOLEAN)
#define JS2VAL_IS_NULL(v)        ((v) == JS2VAL_NULL)
#define JS2VAL_IS_VOID(v)        ((v) == JS2VAL_VOID)
#define JS2VAL_IS_PRIMITIVE(v)   (!JS2VAL_IS_OBJECT(v) || JS2VAL_IS_NULL(v))
#define JS2VAL_IS_LONG(v)        (JS2VAL_TAG(v) == JS2VAL_LONG)
#define JS2VAL_IS_ULONG(v)       (JS2VAL_TAG(v) == JS2VAL_ULONG)
#define JS2VAL_IS_FLOAT(v)       (JS2VAL_TAG(v) == JS2VAL_FLOAT)

/* Objects, strings, and doubles are GC'ed. */
#define JS2VAL_IS_GCTHING(v)     (!((v) & JS2VAL_INT) && !JS2VAL_IS_BOOLEAN(v))
#define JS2VAL_TO_GCTHING(v)     ((void *)JS2VAL_CLRTAG(v))
#define JS2VAL_TO_OBJECT(v)      ((JS2Object *)JS2VAL_TO_GCTHING(v))
#define JS2VAL_TO_DOUBLE(v)      ((float64 *)JS2VAL_TO_GCTHING(v))
#define JS2VAL_TO_STRING(v)      ((String *)JS2VAL_TO_GCTHING(v))
#define JS2VAL_TO_LONG(v)        ((int64 *)JS2VAL_TO_GCTHING(v))
#define JS2VAL_TO_ULONG(v)       ((uint64 *)JS2VAL_TO_GCTHING(v))
#define JS2VAL_TO_FLOAT(v)       ((float32 *)JS2VAL_TO_GCTHING(v))
#define OBJECT_TO_JS2VAL(obj)    ((js2val)(obj))
#define DOUBLE_TO_JS2VAL(dp)     JS2VAL_SETTAG((js2val)(dp), JS2VAL_DOUBLE)
#define STRING_TO_JS2VAL(str)    JS2VAL_SETTAG((js2val)(str), JS2VAL_STRING)
#define LONG_TO_JS2VAL(dp)       JS2VAL_SETTAG((js2val)(dp), JS2VAL_LONG)
#define ULONG_TO_JS2VAL(dp)      JS2VAL_SETTAG((js2val)(dp), JS2VAL_ULONG)
#define FLOAT_TO_JS2VAL(dp)      JS2VAL_SETTAG((js2val)(dp), JS2VAL_FLOAT)

/* Convert between boolean and js2val. */
#define JS2VAL_TO_BOOLEAN(v)     (((v) >> JS2VAL_TAGBITS) != 0)
#define BOOLEAN_TO_JS2VAL(b)     JS2VAL_SETTAG((js2val)(b) << JS2VAL_TAGBITS,     \
                                             JS2VAL_BOOLEAN)

#ifdef IS_LITTLE_ENDIAN
#define JSDOUBLE_HI32(x)        (((uint32 *)&(x))[1])
#define JSDOUBLE_LO32(x)        (((uint32 *)&(x))[0])
#else
#define JSDOUBLE_HI32(x)        (((uint32 *)&(x))[0])
#define JSDOUBLE_LO32(x)        (((uint32 *)&(x))[1])
#endif

#define JSDOUBLE_HI32_SIGNBIT   0x80000000
#define JSDOUBLE_HI32_EXPMASK   0x7ff00000
#define JSDOUBLE_HI32_MANTMASK  0x000fffff

#define JSDOUBLE_IS_NaN(x)                                                    \
    ((JSDOUBLE_HI32(x) & JSDOUBLE_HI32_EXPMASK) == JSDOUBLE_HI32_EXPMASK &&   \
     (JSDOUBLE_LO32(x) || (JSDOUBLE_HI32(x) & JSDOUBLE_HI32_MANTMASK)))

#define JSDOUBLE_IS_INFINITE(x)                                               \
    ((JSDOUBLE_HI32(x) & ~JSDOUBLE_HI32_SIGNBIT) == JSDOUBLE_HI32_EXPMASK &&   \
     !JSDOUBLE_LO32(x))

#define JSDOUBLE_IS_FINITE(x)                                                 \
    ((JSDOUBLE_HI32(x) & JSDOUBLE_HI32_EXPMASK) != JSDOUBLE_HI32_EXPMASK)

#define JSDOUBLE_IS_POSZERO(d)  (JSDOUBLE_HI32(d) == 0 && JSDOUBLE_LO32(d) == 0)

#define JSDOUBLE_IS_NEGZERO(d)  (JSDOUBLE_HI32(d) == JSDOUBLE_HI32_SIGNBIT && \
                                 JSDOUBLE_LO32(d) == 0)



/*
 * JSDOUBLE_IS_INT first checks that d is neither NaN nor infinite, to avoid
 * raising SIGFPE on platforms such as Alpha Linux, then (only if the cast is
 * safe) leaves i as (jsint)d.  This also avoid anomalous NaN floating point
 * comparisons under MSVC.
 */
#define JSDOUBLE_IS_INT(d, i) (JSDOUBLE_IS_FINITE(d)                          \
                               && !JSDOUBLE_IS_NEGZERO(d)                     \
			       && ((d) == (i = (int32)(d))))


#define JS2VAL_IS_UNDEFINED(v)  JS2VAL_IS_VOID(v)
#define JS2VAL_UNDEFINED JS2VAL_VOID

typedef uint32 js2val;
enum Phase  { CompilePhase, RunPhase };

// XXX where should these be?
typedef uint8 AccessSet;
enum Access { ReadAccess = 0x1, WriteAccess = 0x2, ReadWriteAccess = ReadAccess | WriteAccess};

typedef std::vector<js2val> ValueList;

#endif