Back to index

lightning-sunbird  0.9+nobinonly
Classes | Defines | Typedefs | Enumerations | Functions | Variables
jsparse.h File Reference
#include "jsconfig.h"
#include "jsprvtd.h"
#include "jspubtd.h"
#include "jsscan.h"
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Classes

struct  JSParseNode
union  JSParseNode.pn_u
struct  JSParseNode.pn_u.func
struct  JSParseNode.pn_u.list
struct  JSParseNode.pn_u.ternary
struct  JSParseNode.pn_u.binary
struct  JSParseNode.pn_u.unary
struct  JSParseNode.pn_u.name
struct  JSParseNode.pn_u.apair

Defines

#define pn_funAtom   pn_u.func.funAtom
#define pn_body   pn_u.func.body
#define pn_flags   pn_u.func.flags
#define pn_tryCount   pn_u.func.tryCount
#define pn_head   pn_u.list.head
#define pn_tail   pn_u.list.tail
#define pn_count   pn_u.list.count
#define pn_extra   pn_u.list.extra
#define pn_kid1   pn_u.ternary.kid1
#define pn_kid2   pn_u.ternary.kid2
#define pn_kid3   pn_u.ternary.kid3
#define pn_left   pn_u.binary.left
#define pn_right   pn_u.binary.right
#define pn_val   pn_u.binary.val
#define pn_kid   pn_u.unary.kid
#define pn_num   pn_u.unary.num
#define pn_atom   pn_u.name.atom
#define pn_expr   pn_u.name.expr
#define pn_slot   pn_u.name.slot
#define pn_attrs   pn_u.name.attrs
#define pn_dval   pn_u.dval
#define pn_atom2   pn_u.apair.atom2
#define PNX_STRCAT   0x01 /* TOK_PLUS list has string term */
#define PNX_CANTFOLD   0x02 /* TOK_PLUS list has unfoldable term */
#define PNX_POPVAR   0x04 /* TOK_VAR last result needs popping */
#define PNX_FORINVAR
#define PNX_ENDCOMMA   0x10 /* array literal has comma at end */
#define PNX_XMLROOT   0x20 /* top-most node in XML literal tree */
#define PNX_GROUPINIT   0x40 /* var [a, b] = [c, d]; unit list */
#define PNX_NEEDBRACES   0x80 /* braces necessary due to closure */
#define PN_MOVE_NODE(pn, pn2)
#define PN_CLEAR_NODE(pn)
#define PN_IS_CONSTANT(pn)
#define PN_LAST(list)   ((JSParseNode *)((char *)(list)->pn_tail - offsetof(JSParseNode, pn_next)))
#define PN_INIT_LIST(list)
#define PN_INIT_LIST_1(list, pn)
#define PN_APPEND(list, pn)

Typedefs

typedef JS_BEGIN_EXTERN_C enum
JSParseNodeArity 
JSParseNodeArity

Enumerations

enum  JSParseNodeArity {
  PN_FUNC = -3, PN_LIST = -2, PN_TERNARY = 3, PN_BINARY = 2,
  PN_UNARY = 1, PN_NAME = -1, PN_NULLARY = 0
}

Functions

 JS_FRIEND_API (JSParseNode *) js_ParseTokenStream(JSContext *cx
 JS_FRIEND_API (JSBool) js_CompileTokenStream(JSContext *cx
JSBool js_CompileFunctionBody (JSContext *cx, JSTokenStream *ts, JSFunction *fun)
JSBool js_FoldConstants (JSContext *cx, JSParseNode *pn, JSTreeContext *tc)
 js_ParseXMLTokenStream (JSContext *cx, JSObject *chain, JSTokenStream *ts, JSBool allowList)

Variables

JSObjectchain
JSObject JSTokenStreamts
JSObject JSTokenStream
JSCodeGenerator
cg

Class Documentation

struct JSParseNode

Definition at line 272 of file jsparse.h.

Collaboration diagram for JSParseNode:
Class Members
int8 pn_arity
JSParseNode * pn_next
ptrdiff_t pn_offset
uint8 pn_op
JSTokenPos pn_pos
JSAtom * pn_source
JSTokenStream * pn_ts
uint16 pn_type
union JSParseNode pn_u
union JSParseNode.pn_u

Definition at line 278 of file jsparse.h.

Class Members
pn_u apair
pn_u binary
jsdouble dval
pn_u func
pn_u list
pn_u name
pn_u ternary
pn_u unary
struct JSParseNode.pn_u.func

Definition at line 279 of file jsparse.h.

Class Members
JSParseNode * body
uint32 flags
JSAtom * funAtom
uint32 tryCount
struct JSParseNode.pn_u.list

Definition at line 285 of file jsparse.h.

Class Members
uint32 count
uint32 extra
JSParseNode * head
JSParseNode ** tail
struct JSParseNode.pn_u.ternary

Definition at line 291 of file jsparse.h.

Class Members
JSParseNode * kid1
JSParseNode * kid2
JSParseNode * kid3
struct JSParseNode.pn_u.binary

Definition at line 296 of file jsparse.h.

Class Members
JSParseNode * left
JSParseNode * right
jsval val
struct JSParseNode.pn_u.unary

Definition at line 301 of file jsparse.h.

Class Members
JSParseNode * kid
jsint num
struct JSParseNode.pn_u.name

Definition at line 305 of file jsparse.h.

Class Members
JSAtom * atom
uintN attrs
JSParseNode * expr
jsint slot
struct JSParseNode.pn_u.apair

Definition at line 311 of file jsparse.h.

Class Members
JSAtom * atom
JSAtom * atom2

Define Documentation

#define PN_APPEND (   list,
  pn 
)
Value:
JS_BEGIN_MACRO                                                            \
        *(list)->pn_tail = (pn);                                              \
        (list)->pn_tail = &(pn)->pn_next;                                     \
        (list)->pn_count++;                                                   \
    JS_END_MACRO

Definition at line 403 of file jsparse.h.

Definition at line 338 of file jsparse.h.

#define pn_atom2   pn_u.apair.atom2

Definition at line 343 of file jsparse.h.

Definition at line 341 of file jsparse.h.

#define pn_body   pn_u.func.body

Definition at line 323 of file jsparse.h.

#define PN_CLEAR_NODE (   pn)
Value:
JS_BEGIN_MACRO                                                            \
        (pn)->pn_type = TOK_EOF;                                              \
        (pn)->pn_op = JSOP_NOP;                                               \
        (pn)->pn_arity = PN_NULLARY;                                          \
    JS_END_MACRO

Definition at line 368 of file jsparse.h.

Definition at line 328 of file jsparse.h.

Definition at line 342 of file jsparse.h.

#define pn_expr   pn_u.name.expr

Definition at line 339 of file jsparse.h.

#define pn_extra   pn_u.list.extra

Definition at line 329 of file jsparse.h.

Definition at line 324 of file jsparse.h.

#define pn_funAtom   pn_u.func.funAtom

Definition at line 322 of file jsparse.h.

Definition at line 326 of file jsparse.h.

Value:
JS_BEGIN_MACRO                                                            \
        (list)->pn_head = NULL;                                               \
        (list)->pn_tail = &(list)->pn_head;                                   \
        (list)->pn_count = (list)->pn_extra = 0;                              \
    JS_END_MACRO

Definition at line 388 of file jsparse.h.

#define PN_INIT_LIST_1 (   list,
  pn 
)
Value:
JS_BEGIN_MACRO                                                            \
        (list)->pn_head = (pn);                                               \
        (list)->pn_tail = &(pn)->pn_next;                                     \
        (list)->pn_count = 1;                                                 \
        (list)->pn_extra = 0;                                                 \
    JS_END_MACRO

Definition at line 395 of file jsparse.h.

Value:
((pn)->pn_type == TOK_NUMBER ||                                           \
     (pn)->pn_type == TOK_STRING ||                                           \
     ((pn)->pn_type == TOK_PRIMARY && (pn)->pn_op != JSOP_THIS))

Definition at line 376 of file jsparse.h.

#define pn_kid   pn_u.unary.kid

Definition at line 336 of file jsparse.h.

#define pn_kid1   pn_u.ternary.kid1

Definition at line 330 of file jsparse.h.

#define pn_kid2   pn_u.ternary.kid2

Definition at line 331 of file jsparse.h.

#define pn_kid3   pn_u.ternary.kid3

Definition at line 332 of file jsparse.h.

#define PN_LAST (   list)    ((JSParseNode *)((char *)(list)->pn_tail - offsetof(JSParseNode, pn_next)))

Definition at line 385 of file jsparse.h.

Definition at line 333 of file jsparse.h.

#define PN_MOVE_NODE (   pn,
  pn2 
)
Value:
JS_BEGIN_MACRO                                                            \
        (pn)->pn_type = (pn2)->pn_type;                                       \
        (pn)->pn_op = (pn2)->pn_op;                                           \
        (pn)->pn_arity = (pn2)->pn_arity;                                     \
        (pn)->pn_u = (pn2)->pn_u;                                             \
        PN_CLEAR_NODE(pn2);                                                   \
    JS_END_MACRO

Definition at line 359 of file jsparse.h.

Definition at line 337 of file jsparse.h.

Definition at line 334 of file jsparse.h.

Definition at line 340 of file jsparse.h.

#define pn_tail   pn_u.list.tail

Definition at line 327 of file jsparse.h.

#define pn_tryCount   pn_u.func.tryCount

Definition at line 325 of file jsparse.h.

Definition at line 335 of file jsparse.h.

#define PNX_CANTFOLD   0x02 /* TOK_PLUS list has unfoldable term */

Definition at line 347 of file jsparse.h.

#define PNX_ENDCOMMA   0x10 /* array literal has comma at end */

Definition at line 350 of file jsparse.h.

Value:
0x08            /* TOK_VAR is left kid of TOK_IN node,
                                           which is left kid of TOK_FOR */

Definition at line 349 of file jsparse.h.

#define PNX_GROUPINIT   0x40 /* var [a, b] = [c, d]; unit list */

Definition at line 352 of file jsparse.h.

#define PNX_NEEDBRACES   0x80 /* braces necessary due to closure */

Definition at line 353 of file jsparse.h.

#define PNX_POPVAR   0x04 /* TOK_VAR last result needs popping */

Definition at line 348 of file jsparse.h.

#define PNX_STRCAT   0x01 /* TOK_PLUS list has string term */

Definition at line 346 of file jsparse.h.

#define PNX_XMLROOT   0x20 /* top-most node in XML literal tree */

Definition at line 351 of file jsparse.h.


Typedef Documentation


Enumeration Type Documentation

Enumerator:
PN_FUNC 
PN_LIST 
PN_TERNARY 
PN_BINARY 
PN_UNARY 
PN_NAME 
PN_NULLARY 

Definition at line 262 of file jsparse.h.

                              {
    PN_FUNC     = -3,
    PN_LIST     = -2,
    PN_TERNARY  =  3,
    PN_BINARY   =  2,
    PN_UNARY    =  1,
    PN_NAME     = -1,
    PN_NULLARY  =  0
} JSParseNodeArity;

Function Documentation

Definition at line 777 of file jsparse.c.

{
    JSArenaPool codePool, notePool;
    JSCodeGenerator funcg;
    JSStackFrame *fp, frame;
    JSObject *funobj;
    JSParseNode *pn;

    JS_InitArenaPool(&codePool, "code", 1024, sizeof(jsbytecode));
    JS_InitArenaPool(&notePool, "note", 1024, sizeof(jssrcnote));
    if (!js_InitCodeGenerator(cx, &funcg, &codePool, &notePool,
                              ts->filename, ts->lineno,
                              ts->principals)) {
        return JS_FALSE;
    }

    /* Prevent GC activation while compiling. */
    JS_KEEP_ATOMS(cx->runtime);

    /* Push a JSStackFrame for use by FunctionBody. */
    fp = cx->fp;
    funobj = fun->object;
    JS_ASSERT(!fp || (fp->fun != fun && fp->varobj != funobj &&
                      fp->scopeChain != funobj));
    memset(&frame, 0, sizeof frame);
    frame.fun = fun;
    frame.varobj = frame.scopeChain = funobj;
    frame.down = fp;
    frame.flags = JS_HAS_COMPILE_N_GO_OPTION(cx)
                  ? JSFRAME_COMPILING | JSFRAME_COMPILE_N_GO
                  : JSFRAME_COMPILING;
    cx->fp = &frame;

    /*
     * Farble the body so that it looks like a block statement to js_EmitTree,
     * which is called beneath FunctionBody; see Statements, further below in
     * this file.  FunctionBody pushes a STMT_BLOCK record around its call to
     * Statements, so Statements will not compile each statement as it loops
     * to save JSParseNode space -- it will not compile at all, only build a
     * JSParseNode tree.
     *
     * Therefore we must fold constants, allocate try notes, and generate code
     * for this function, including a stop opcode at the end.
     */
    CURRENT_TOKEN(ts).type = TOK_LC;
    pn = FunctionBody(cx, ts, fun, &funcg.treeContext);
    if (pn && !js_NewScriptFromCG(cx, &funcg, fun))
        pn = NULL;

    /* Restore saved state and release code generation arenas. */
    cx->fp = fp;
    JS_UNKEEP_ATOMS(cx->runtime);
    js_FinishCodeGenerator(cx, &funcg);
    JS_FinishArenaPool(&codePool);
    JS_FinishArenaPool(&notePool);
    return pn != NULL;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 6124 of file jsparse.c.

{
    JSParseNode *pn1 = NULL, *pn2 = NULL, *pn3 = NULL;
    int stackDummy;

    if (!JS_CHECK_STACK_SIZE(cx, stackDummy)) {
        JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_OVER_RECURSED);
        return JS_FALSE;
    }

    switch (pn->pn_arity) {
      case PN_FUNC:
      {
        uint16 oldflags = tc->flags;

        tc->flags = (uint16) pn->pn_flags;
        if (!js_FoldConstants(cx, pn->pn_body, tc))
            return JS_FALSE;
        tc->flags = oldflags;
        break;
      }

      case PN_LIST:
#if 0 /* JS_HAS_XML_SUPPORT */
        switch (pn->pn_type) {
          case TOK_XMLELEM:
          case TOK_XMLLIST:
          case TOK_XMLPTAGC:
            /*
             * Try to fold this XML parse tree once, from the top down, into
             * a JSXML tree with just one object wrapping the tree root.
             *
             * Certain subtrees could be folded similarly, but we'd have to
             * ensure that none used namespace prefixes declared elsewhere in
             * its super-tree, and we would have to convert each XML object
             * created at runtime for such sub-trees back into a string, and
             * concatenate and re-parse anyway.
             */
            if ((pn->pn_extra & (PNX_XMLROOT | PNX_CANTFOLD)) == PNX_XMLROOT &&
                !(tc->flags & TCF_HAS_DEFXMLNS)) {
                JSObject *obj;
                JSAtom *atom;

                obj = js_ParseNodeToXMLObject(cx, pn);
                if (!obj)
                    return JS_FALSE;
                atom = js_AtomizeObject(cx, obj, 0);
                if (!atom)
                    return JS_FALSE;
                pn->pn_op = JSOP_XMLOBJECT;
                pn->pn_arity = PN_NULLARY;
                pn->pn_atom = atom;
                return JS_TRUE;
            }

            /*
             * Can't fold from parse node to XML tree -- try folding strings
             * as much as possible, and folding XML sub-trees bottom up to
             * minimize string concatenation and ToXML/ToXMLList operations
             * at runtime.
             */
            break;

          default:;
        }
#endif

        /* Save the list head in pn1 for later use. */
        for (pn1 = pn2 = pn->pn_head; pn2; pn2 = pn2->pn_next) {
            if (!js_FoldConstants(cx, pn2, tc))
                return JS_FALSE;
        }
        break;

      case PN_TERNARY:
        /* Any kid may be null (e.g. for (;;)). */
        pn1 = pn->pn_kid1;
        pn2 = pn->pn_kid2;
        pn3 = pn->pn_kid3;
        if (pn1 && !js_FoldConstants(cx, pn1, tc))
            return JS_FALSE;
        if (pn2 && !js_FoldConstants(cx, pn2, tc))
            return JS_FALSE;
        if (pn3 && !js_FoldConstants(cx, pn3, tc))
            return JS_FALSE;
        break;

      case PN_BINARY:
        /* First kid may be null (for default case in switch). */
        pn1 = pn->pn_left;
        pn2 = pn->pn_right;
        if (pn1 && !js_FoldConstants(cx, pn1, tc))
            return JS_FALSE;
        if (!js_FoldConstants(cx, pn2, tc))
            return JS_FALSE;
        break;

      case PN_UNARY:
        /* Our kid may be null (e.g. return; vs. return e;). */
        pn1 = pn->pn_kid;
        if (pn1 && !js_FoldConstants(cx, pn1, tc))
            return JS_FALSE;
        break;

      case PN_NAME:
        /*
         * Skip pn1 down along a chain of dotted member expressions to avoid
         * excessive recursion.  Our only goal here is to fold constants (if
         * any) in the primary expression operand to the left of the first
         * dot in the chain.
         */
        pn1 = pn->pn_expr;
        while (pn1 && pn1->pn_arity == PN_NAME)
            pn1 = pn1->pn_expr;
        if (pn1 && !js_FoldConstants(cx, pn1, tc))
            return JS_FALSE;
        break;

      case PN_NULLARY:
        break;
    }

    switch (pn->pn_type) {
      case TOK_IF:
        if (ContainsStmt(pn2, TOK_VAR) || ContainsStmt(pn3, TOK_VAR))
            break;
        /* FALL THROUGH */

      case TOK_HOOK:
        /* Reduce 'if (C) T; else E' into T for true C, E for false. */
        while (pn1->pn_type == TOK_RP)
            pn1 = pn1->pn_kid;
        switch (pn1->pn_type) {
          case TOK_NUMBER:
            if (pn1->pn_dval == 0)
                pn2 = pn3;
            break;
          case TOK_STRING:
            if (JSSTRING_LENGTH(ATOM_TO_STRING(pn1->pn_atom)) == 0)
                pn2 = pn3;
            break;
          case TOK_PRIMARY:
            if (pn1->pn_op == JSOP_TRUE)
                break;
            if (pn1->pn_op == JSOP_FALSE || pn1->pn_op == JSOP_NULL) {
                pn2 = pn3;
                break;
            }
            /* FALL THROUGH */
          default:
            /* Early return to dodge common code that copies pn2 to pn. */
            return JS_TRUE;
        }

        if (pn2) {
            /*
             * pn2 is the then- or else-statement subtree to compile.  Take
             * care not to expose an object initialiser, which would be parsed
             * as a block, to the Statement parser via eval(uneval(e)) where e
             * is '1 ? {p:2, q:3}[i] : r;' or the like.
             */
            if (pn->pn_type == TOK_HOOK && StartsWith(pn2, TOK_RC)) {
                pn->pn_type = TOK_RP;
                pn->pn_arity = PN_UNARY;
                pn->pn_kid = pn2;
            } else {
                PN_MOVE_NODE(pn, pn2);
            }
        }
        if (!pn2 || (pn->pn_type == TOK_SEMI && !pn->pn_kid)) {
            /*
             * False condition and no else, or an empty then-statement was
             * moved up over pn.  Either way, make pn an empty block (not an
             * empty statement, which does not decompile, even when labeled).
             * NB: pn must be a TOK_IF as TOK_HOOK can never have a null kid
             * or an empty statement for a child.
             */
            pn->pn_type = TOK_LC;
            pn->pn_arity = PN_LIST;
            PN_INIT_LIST(pn);
        }
        RecycleTree(pn2, tc);
        if (pn3 && pn3 != pn2)
            RecycleTree(pn3, tc);
        break;

      case TOK_ASSIGN:
        /*
         * Compound operators such as *= should be subject to folding, in case
         * the left-hand side is constant, and so that the decompiler produces
         * the same string that you get from decompiling a script or function
         * compiled from that same string.  As with +, += is special.
         */
        if (pn->pn_op == JSOP_NOP)
            break;
        if (pn->pn_op != JSOP_ADD)
            goto do_binary_op;
        /* FALL THROUGH */

      case TOK_PLUS:
        if (pn->pn_arity == PN_LIST) {
            size_t length, length2;
            jschar *chars;
            JSString *str, *str2;

            /*
             * Any string literal term with all others number or string means
             * this is a concatenation.  If any term is not a string or number
             * literal, we can't fold.
             */
            JS_ASSERT(pn->pn_count > 2);
            if (pn->pn_extra & PNX_CANTFOLD)
                return JS_TRUE;
            if (pn->pn_extra != PNX_STRCAT)
                goto do_binary_op;

            /* Ok, we're concatenating: convert non-string constant operands. */
            length = 0;
            for (pn2 = pn1; pn2; pn2 = pn2->pn_next) {
                if (!FoldType(cx, pn2, TOK_STRING))
                    return JS_FALSE;
                /* XXX fold only if all operands convert to string */
                if (pn2->pn_type != TOK_STRING)
                    return JS_TRUE;
                length += ATOM_TO_STRING(pn2->pn_atom)->length;
            }

            /* Allocate a new buffer and string descriptor for the result. */
            chars = (jschar *) JS_malloc(cx, (length + 1) * sizeof(jschar));
            if (!chars)
                return JS_FALSE;
            str = js_NewString(cx, chars, length, 0);
            if (!str) {
                JS_free(cx, chars);
                return JS_FALSE;
            }

            /* Fill the buffer, advancing chars and recycling kids as we go. */
            for (pn2 = pn1; pn2; pn2 = RecycleTree(pn2, tc)) {
                str2 = ATOM_TO_STRING(pn2->pn_atom);
                length2 = str2->length;
                js_strncpy(chars, str2->chars, length2);
                chars += length2;
            }
            *chars = 0;

            /* Atomize the result string and mutate pn to refer to it. */
            pn->pn_atom = js_AtomizeString(cx, str, 0);
            if (!pn->pn_atom)
                return JS_FALSE;
            pn->pn_type = TOK_STRING;
            pn->pn_op = JSOP_STRING;
            pn->pn_arity = PN_NULLARY;
            break;
        }

        /* Handle a binary string concatenation. */
        JS_ASSERT(pn->pn_arity == PN_BINARY);
        if (pn1->pn_type == TOK_STRING || pn2->pn_type == TOK_STRING) {
            JSString *left, *right, *str;

            if (!FoldType(cx, (pn1->pn_type != TOK_STRING) ? pn1 : pn2,
                          TOK_STRING)) {
                return JS_FALSE;
            }
            if (pn1->pn_type != TOK_STRING || pn2->pn_type != TOK_STRING)
                return JS_TRUE;
            left = ATOM_TO_STRING(pn1->pn_atom);
            right = ATOM_TO_STRING(pn2->pn_atom);
            str = js_ConcatStrings(cx, left, right);
            if (!str)
                return JS_FALSE;
            pn->pn_atom = js_AtomizeString(cx, str, 0);
            if (!pn->pn_atom)
                return JS_FALSE;
            pn->pn_type = TOK_STRING;
            pn->pn_op = JSOP_STRING;
            pn->pn_arity = PN_NULLARY;
            RecycleTree(pn1, tc);
            RecycleTree(pn2, tc);
            break;
        }

        /* Can't concatenate string literals, let's try numbers. */
        goto do_binary_op;

      case TOK_STAR:
        /* The * in 'import *;' parses as a nullary star node. */
        if (pn->pn_arity == PN_NULLARY)
            break;
        /* FALL THROUGH */

      case TOK_SHOP:
      case TOK_MINUS:
      case TOK_DIVOP:
      do_binary_op:
        if (pn->pn_arity == PN_LIST) {
            JS_ASSERT(pn->pn_count > 2);
            for (pn2 = pn1; pn2; pn2 = pn2->pn_next) {
                if (!FoldType(cx, pn2, TOK_NUMBER))
                    return JS_FALSE;
            }
            for (pn2 = pn1; pn2; pn2 = pn2->pn_next) {
                /* XXX fold only if all operands convert to number */
                if (pn2->pn_type != TOK_NUMBER)
                    break;
            }
            if (!pn2) {
                JSOp op = pn->pn_op;

                pn2 = pn1->pn_next;
                pn3 = pn2->pn_next;
                if (!FoldBinaryNumeric(cx, op, pn1, pn2, pn, tc))
                    return JS_FALSE;
                while ((pn2 = pn3) != NULL) {
                    pn3 = pn2->pn_next;
                    if (!FoldBinaryNumeric(cx, op, pn, pn2, pn, tc))
                        return JS_FALSE;
                }
            }
        } else {
            JS_ASSERT(pn->pn_arity == PN_BINARY);
            if (!FoldType(cx, pn1, TOK_NUMBER) ||
                !FoldType(cx, pn2, TOK_NUMBER)) {
                return JS_FALSE;
            }
            if (pn1->pn_type == TOK_NUMBER && pn2->pn_type == TOK_NUMBER) {
                if (!FoldBinaryNumeric(cx, pn->pn_op, pn1, pn2, pn, tc))
                    return JS_FALSE;
            }
        }
        break;

      case TOK_UNARYOP:
        while (pn1->pn_type == TOK_RP)
            pn1 = pn1->pn_kid;
        if (pn1->pn_type == TOK_NUMBER) {
            jsdouble d;
            int32 i;

            /* Operate on one numeric constant. */
            d = pn1->pn_dval;
            switch (pn->pn_op) {
              case JSOP_BITNOT:
                if (!js_DoubleToECMAInt32(cx, d, &i))
                    return JS_FALSE;
                d = ~i;
                break;

              case JSOP_NEG:
#ifdef HPUX
                /*
                 * Negation of a zero doesn't produce a negative
                 * zero on HPUX. Perform the operation by bit
                 * twiddling.
                 */
                JSDOUBLE_HI32(d) ^= JSDOUBLE_HI32_SIGNBIT;
#else
                d = -d;
#endif
                break;

              case JSOP_POS:
                break;

              case JSOP_NOT:
                pn->pn_type = TOK_PRIMARY;
                pn->pn_op = (d == 0) ? JSOP_TRUE : JSOP_FALSE;
                pn->pn_arity = PN_NULLARY;
                /* FALL THROUGH */

              default:
                /* Return early to dodge the common TOK_NUMBER code. */
                return JS_TRUE;
            }
            pn->pn_type = TOK_NUMBER;
            pn->pn_op = JSOP_NUMBER;
            pn->pn_arity = PN_NULLARY;
            pn->pn_dval = d;
            RecycleTree(pn1, tc);
        }
        break;

#if JS_HAS_XML_SUPPORT
      case TOK_XMLELEM:
      case TOK_XMLLIST:
      case TOK_XMLPTAGC:
      case TOK_XMLSTAGO:
      case TOK_XMLETAGO:
      case TOK_XMLNAME:
        if (pn->pn_arity == PN_LIST) {
            JS_ASSERT(pn->pn_type == TOK_XMLLIST || pn->pn_count != 0);
            if (!FoldXMLConstants(cx, pn, tc))
                return JS_FALSE;
        }
        break;

      case TOK_AT:
        if (pn1->pn_type == TOK_XMLNAME) {
            jsval v;
            JSAtom *atom;

            v = ATOM_KEY(pn1->pn_atom);
            if (!js_ToAttributeName(cx, &v))
                return JS_FALSE;
            JS_ASSERT(!JSVAL_IS_PRIMITIVE(v));
            atom = js_AtomizeObject(cx, JSVAL_TO_OBJECT(v), 0);
            if (!atom)
                return JS_FALSE;

            pn->pn_type = TOK_XMLNAME;
            pn->pn_op = JSOP_OBJECT;
            pn->pn_arity = PN_NULLARY;
            pn->pn_atom = atom;
            RecycleTree(pn1, tc);
        }
        break;
#endif /* JS_HAS_XML_SUPPORT */

      default:;
    }

    return JS_TRUE;
}

Here is the call graph for this function:

Here is the caller graph for this function:

js_ParseXMLTokenStream ( JSContext cx,
JSObject chain,
JSTokenStream ts,
JSBool  allowList 
)

Definition at line 5107 of file jsparse.c.

{
    JSStackFrame *fp, frame;
    JSParseNode *pn;
    JSTreeContext tc;
    JSTokenType tt;

    /*
     * Push a compiler frame if we have no frames, or if the top frame is a
     * lightweight function activation, or if its scope chain doesn't match
     * the one passed to us.
     */
    fp = cx->fp;
    MaybeSetupFrame(cx, chain, fp, &frame);
    JS_KEEP_ATOMS(cx->runtime);
    TREE_CONTEXT_INIT(&tc);

    /* Set XML-only mode to turn off special treatment of {expr} in XML. */
    ts->flags |= TSF_OPERAND | TSF_XMLONLYMODE;
    tt = js_GetToken(cx, ts);
    ts->flags &= ~TSF_OPERAND;

    if (tt != TOK_XMLSTAGO) {
        js_ReportCompileErrorNumber(cx, ts, JSREPORT_TS | JSREPORT_ERROR,
                                    JSMSG_BAD_XML_MARKUP);
        pn = NULL;
    } else {
        pn = XMLElementOrListRoot(cx, ts, &tc, allowList);
    }

    ts->flags &= ~TSF_XMLONLYMODE;
    TREE_CONTEXT_FINISH(&tc);
    JS_UNKEEP_ATOMS(cx->runtime);
    cx->fp = fp;
    return pn;
}

Here is the call graph for this function:

Here is the caller graph for this function:


Variable Documentation

Definition at line 420 of file jsparse.h.

Definition at line 417 of file jsparse.h.

Definition at line 417 of file jsparse.h.