js/src/frontend/SourceNotes.h

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
     2  * vim: set ts=8 sts=4 et sw=4 tw=99:
     3  * This Source Code Form is subject to the terms of the Mozilla Public
     4  * License, v. 2.0. If a copy of the MPL was not distributed with this
     5  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     7 #ifndef frontend_SourceNotes_h
     8 #define frontend_SourceNotes_h
    10 #include <stdint.h>
    12 #include "jstypes.h"
    14 typedef uint8_t jssrcnote;
    16 namespace js {
    18 /*
    19  * Source notes generated along with bytecode for decompiling and debugging.
    20  * A source note is a uint8_t with 5 bits of type and 3 of offset from the pc
    21  * of the previous note. If 3 bits of offset aren't enough, extended delta
    22  * notes (SRC_XDELTA) consisting of 2 set high order bits followed by 6 offset
    23  * bits are emitted before the next note. Some notes have operand offsets
    24  * encoded immediately after them, in note bytes or byte-triples.
    25  *
    26  *                 Source Note               Extended Delta
    27  *              +7-6-5-4-3+2-1-0+           +7-6-5+4-3-2-1-0+
    28  *              |note-type|delta|           |1 1| ext-delta |
    29  *              +---------+-----+           +---+-----------+
    30  *
    31  * At most one "gettable" note (i.e., a note of type other than SRC_NEWLINE,
    32  * SRC_COLSPAN, SRC_SETLINE, and SRC_XDELTA) applies to a given bytecode.
    33  *
    34  * NB: the js_SrcNoteSpec array in BytecodeEmitter.cpp is indexed by this
    35  * enum, so its initializers need to match the order here.
    36  *
    37  * Don't forget to update XDR_BYTECODE_VERSION in vm/Xdr.h for all such
    38  * incompatible source note or other bytecode changes.
    39  */
    40 #define FOR_EACH_SRC_NOTE_TYPE(M)                                                                  \
    41     M(SRC_NULL,         "null",        0)  /* Terminates a note vector. */                         \
    42     M(SRC_IF,           "if",          0)  /* JSOP_IFEQ bytecode is from an if-then. */            \
    43     M(SRC_IF_ELSE,      "if-else",     1)  /* JSOP_IFEQ bytecode is from an if-then-else. */       \
    44     M(SRC_COND,         "cond",        1)  /* JSOP_IFEQ is from conditional ?: operator. */        \
    45     M(SRC_FOR,          "for",         3)  /* JSOP_NOP or JSOP_POP in for(;;) loop head. */        \
    46     M(SRC_WHILE,        "while",       1)  /* JSOP_GOTO to for or while loop condition from before \
    47                                               loop, else JSOP_NOP at top of do-while loop. */      \
    48     M(SRC_FOR_IN,       "for-in",      1)  /* JSOP_GOTO to for-in loop condition from before       \
    49                                               loop. */                                             \
    50     M(SRC_FOR_OF,       "for-of",      1)  /* JSOP_GOTO to for-of loop condition from before       \
    51                                               loop. */                                             \
    52     M(SRC_CONTINUE,     "continue",    0)  /* JSOP_GOTO is a continue. */                          \
    53     M(SRC_BREAK,        "break",       0)  /* JSOP_GOTO is a break. */                             \
    54     M(SRC_BREAK2LABEL,  "break2label", 0)  /* JSOP_GOTO for 'break label'. */                      \
    55     M(SRC_SWITCHBREAK,  "switchbreak", 0)  /* JSOP_GOTO is a break in a switch. */                 \
    56     M(SRC_TABLESWITCH,  "tableswitch", 1)  /* JSOP_TABLESWITCH; offset points to end of switch. */ \
    57     M(SRC_CONDSWITCH,   "condswitch",  2)  /* JSOP_CONDSWITCH; 1st offset points to end of switch, \
    58                                               2nd points to first JSOP_CASE. */                    \
    59     M(SRC_NEXTCASE,     "nextcase",    1)  /* Distance forward from one CASE in a CONDSWITCH to    \
    60                                               the next. */                                         \
    61     M(SRC_ASSIGNOP,     "assignop",    0)  /* += or another assign-op follows. */                  \
    62     M(SRC_TRY,          "try",         1)  /* JSOP_TRY, offset points to goto at the end of the    \
    63                                               try block. */                                        \
    64     /* All notes below here are "gettable".  See SN_IS_GETTABLE below. */                          \
    65     M(SRC_COLSPAN,      "colspan",     1)  /* Number of columns this opcode spans. */              \
    66     M(SRC_NEWLINE,      "newline",     0)  /* Bytecode follows a source newline. */                \
    67     M(SRC_SETLINE,      "setline",     1)  /* A file-absolute source line number note. */          \
    68     M(SRC_UNUSED20,     "unused20",    0)  /* Unused. */                                           \
    69     M(SRC_UNUSED21,     "unused21",    0)  /* Unused. */                                           \
    70     M(SRC_UNUSED22,     "unused22",    0)  /* Unused. */                                           \
    71     M(SRC_UNUSED23,     "unused23",    0)  /* Unused. */                                           \
    72     M(SRC_XDELTA,       "xdelta",      0)  /* 24-31 are for extended delta notes. */
    74 enum SrcNoteType {
    75 #define DEFINE_SRC_NOTE_TYPE(sym, name, arity) sym,
    76     FOR_EACH_SRC_NOTE_TYPE(DEFINE_SRC_NOTE_TYPE)
    77 #undef DEFINE_SRC_NOTE_TYPE
    79     SRC_LAST,
    80     SRC_LAST_GETTABLE = SRC_TRY
    81 };
    83 static_assert(SRC_XDELTA == 24, "SRC_XDELTA should be 24");
    85 /* A source note array is terminated by an all-zero element. */
    86 inline void
    87 SN_MAKE_TERMINATOR(jssrcnote *sn)
    88 {
    89     *sn = SRC_NULL;
    90 }
    92 inline bool
    93 SN_IS_TERMINATOR(jssrcnote *sn)
    94 {
    95     return *sn == SRC_NULL;
    96 }
    98 }  // namespace js
   100 #define SN_TYPE_BITS            5
   101 #define SN_DELTA_BITS           3
   102 #define SN_XDELTA_BITS          6
   103 #define SN_TYPE_MASK            (JS_BITMASK(SN_TYPE_BITS) << SN_DELTA_BITS)
   104 #define SN_DELTA_MASK           ((ptrdiff_t)JS_BITMASK(SN_DELTA_BITS))
   105 #define SN_XDELTA_MASK          ((ptrdiff_t)JS_BITMASK(SN_XDELTA_BITS))
   107 #define SN_MAKE_NOTE(sn,t,d)    (*(sn) = (jssrcnote)                          \
   108                                           (((t) << SN_DELTA_BITS)             \
   109                                            | ((d) & SN_DELTA_MASK)))
   110 #define SN_MAKE_XDELTA(sn,d)    (*(sn) = (jssrcnote)                          \
   111                                           ((SRC_XDELTA << SN_DELTA_BITS)      \
   112                                            | ((d) & SN_XDELTA_MASK)))
   114 #define SN_IS_XDELTA(sn)        ((*(sn) >> SN_DELTA_BITS) >= SRC_XDELTA)
   115 #define SN_TYPE(sn)             ((js::SrcNoteType)(SN_IS_XDELTA(sn)           \
   116                                                    ? SRC_XDELTA               \
   117                                                    : *(sn) >> SN_DELTA_BITS))
   118 #define SN_SET_TYPE(sn,type)    SN_MAKE_NOTE(sn, type, SN_DELTA(sn))
   119 #define SN_IS_GETTABLE(sn)      (SN_TYPE(sn) <= SRC_LAST_GETTABLE)
   121 #define SN_DELTA(sn)            ((ptrdiff_t)(SN_IS_XDELTA(sn)                 \
   122                                              ? *(sn) & SN_XDELTA_MASK         \
   123                                              : *(sn) & SN_DELTA_MASK))
   124 #define SN_SET_DELTA(sn,delta)  (SN_IS_XDELTA(sn)                             \
   125                                  ? SN_MAKE_XDELTA(sn, delta)                  \
   126                                  : SN_MAKE_NOTE(sn, SN_TYPE(sn), delta))
   128 #define SN_DELTA_LIMIT          ((ptrdiff_t)JS_BIT(SN_DELTA_BITS))
   129 #define SN_XDELTA_LIMIT         ((ptrdiff_t)JS_BIT(SN_XDELTA_BITS))
   131 /*
   132  * Offset fields follow certain notes and are frequency-encoded: an offset in
   133  * [0,0x7f] consumes one byte, an offset in [0x80,0x7fffffff] takes four, and
   134  * the high bit of the first byte is set.
   135  */
   136 #define SN_4BYTE_OFFSET_FLAG    0x80
   137 #define SN_4BYTE_OFFSET_MASK    0x7f
   139 /*
   140  * Negative SRC_COLSPAN offsets are rare, but can arise with for(;;) loops and
   141  * other constructs that generate code in non-source order. They can also arise
   142  * due to failure to update pn->pn_pos.end to be the last child's end -- such
   143  * failures are bugs to fix.
   144  *
   145  * Source note offsets in general must be non-negative and less than 0x800000,
   146  * per the above SN_4BYTE_* definitions. To encode negative colspans, we bias
   147  * them by the offset domain size and restrict non-negative colspans to less
   148  * than half this domain.
   149  */
   150 #define SN_COLSPAN_DOMAIN       ptrdiff_t(1 << 23)
   152 #define SN_MAX_OFFSET ((size_t)((ptrdiff_t)SN_4BYTE_OFFSET_FLAG << 24) - 1)
   154 #define SN_LENGTH(sn)           ((js_SrcNoteSpec[SN_TYPE(sn)].arity == 0) ? 1 \
   155                                  : js_SrcNoteLength(sn))
   156 #define SN_NEXT(sn)             ((sn) + SN_LENGTH(sn))
   158 struct JSSrcNoteSpec {
   159     const char      *name;      /* name for disassembly/debugging output */
   160     int8_t          arity;      /* number of offset operands */
   161 };
   163 extern JS_FRIEND_DATA(const JSSrcNoteSpec) js_SrcNoteSpec[];
   164 extern JS_FRIEND_API(unsigned)         js_SrcNoteLength(jssrcnote *sn);
   166 /*
   167  * Get and set the offset operand identified by which (0 for the first, etc.).
   168  */
   169 extern JS_FRIEND_API(ptrdiff_t)
   170 js_GetSrcNoteOffset(jssrcnote *sn, unsigned which);
   172 #endif /* frontend_SourceNotes_h */

mercurial