mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 675694: add function to dump parse trees and use it in shell parse function, r=jorendorff
This commit is contained in:
parent
6e66fa3071
commit
d4067beac6
@ -64,6 +64,131 @@ ParseNode::isConstant()
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
inline void
|
||||
IndentNewLine(int indent)
|
||||
{
|
||||
fputc('\n', stderr);
|
||||
for (int i = 0; i < indent; ++i)
|
||||
fputc(' ', stderr);
|
||||
}
|
||||
|
||||
inline void
|
||||
ParseNode::dump(int indent)
|
||||
{
|
||||
switch (pn_arity) {
|
||||
case PN_NULLARY:
|
||||
((NullaryNode *) this)->dump();
|
||||
break;
|
||||
case PN_UNARY:
|
||||
((UnaryNode *) this)->dump(indent);
|
||||
break;
|
||||
case PN_BINARY:
|
||||
((BinaryNode *) this)->dump(indent);
|
||||
break;
|
||||
case PN_TERNARY:
|
||||
((TernaryNode *) this)->dump(indent);
|
||||
break;
|
||||
case PN_FUNC:
|
||||
((FunctionNode *) this)->dump(indent);
|
||||
break;
|
||||
case PN_LIST:
|
||||
((ListNode *) this)->dump(indent);
|
||||
break;
|
||||
case PN_NAME:
|
||||
((NameNode *) this)->dump(indent);
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "?");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
inline void
|
||||
NullaryNode::dump()
|
||||
{
|
||||
fprintf(stderr, "(%s)", js_CodeName[getOp()]);
|
||||
}
|
||||
|
||||
inline void
|
||||
UnaryNode::dump(int indent)
|
||||
{
|
||||
const char *name = js_CodeName[getOp()];
|
||||
fprintf(stderr, "(%s ", name);
|
||||
indent += strlen(name) + 2;
|
||||
DumpParseTree(pn_kid, indent);
|
||||
fprintf(stderr, ")");
|
||||
}
|
||||
|
||||
inline void
|
||||
BinaryNode::dump(int indent)
|
||||
{
|
||||
const char *name = js_CodeName[getOp()];
|
||||
fprintf(stderr, "(%s ", name);
|
||||
indent += strlen(name) + 2;
|
||||
DumpParseTree(pn_left, indent);
|
||||
IndentNewLine(indent);
|
||||
DumpParseTree(pn_right, indent);
|
||||
fprintf(stderr, ")");
|
||||
}
|
||||
|
||||
inline void
|
||||
TernaryNode::dump(int indent)
|
||||
{
|
||||
const char *name = js_CodeName[getOp()];
|
||||
fprintf(stderr, "(%s ", name);
|
||||
indent += strlen(name) + 2;
|
||||
DumpParseTree(pn_kid1, indent);
|
||||
IndentNewLine(indent);
|
||||
DumpParseTree(pn_kid2, indent);
|
||||
IndentNewLine(indent);
|
||||
DumpParseTree(pn_kid3, indent);
|
||||
fprintf(stderr, ")");
|
||||
}
|
||||
|
||||
inline void
|
||||
FunctionNode::dump(int indent)
|
||||
{
|
||||
const char *name = js_CodeName[getOp()];
|
||||
fprintf(stderr, "(%s ", name);
|
||||
indent += strlen(name) + 2;
|
||||
DumpParseTree(pn_body, indent);
|
||||
fprintf(stderr, ")");
|
||||
}
|
||||
|
||||
inline void
|
||||
ListNode::dump(int indent)
|
||||
{
|
||||
const char *name = js_CodeName[getOp()];
|
||||
fprintf(stderr, "(%s ", name);
|
||||
if (pn_head != NULL) {
|
||||
indent += strlen(name) + 2;
|
||||
DumpParseTree(pn_head, indent);
|
||||
ParseNode *pn = pn_head->pn_next;
|
||||
while (pn != NULL) {
|
||||
IndentNewLine(indent);
|
||||
DumpParseTree(pn, indent);
|
||||
pn = pn->pn_next;
|
||||
}
|
||||
}
|
||||
fprintf(stderr, ")");
|
||||
}
|
||||
|
||||
inline void
|
||||
NameNode::dump(int indent)
|
||||
{
|
||||
const char *name = js_CodeName[getOp()];
|
||||
if (isUsed())
|
||||
fprintf(stderr, "(%s)", name);
|
||||
else {
|
||||
fprintf(stderr, "(%s ", name);
|
||||
indent += strlen(name) + 2;
|
||||
DumpParseTree(expr(), indent);
|
||||
fprintf(stderr, ")");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
inline void
|
||||
NameNode::initCommon(TreeContext *tc)
|
||||
{
|
||||
|
@ -660,3 +660,14 @@ js::CloneLeftHandSide(ParseNode *opn, TreeContext *tc)
|
||||
}
|
||||
return pn;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
void
|
||||
js::DumpParseTree(ParseNode *pn, int indent)
|
||||
{
|
||||
if (pn == NULL)
|
||||
fprintf(stderr, "()");
|
||||
else
|
||||
pn->dump(indent);
|
||||
}
|
||||
#endif
|
||||
|
@ -929,12 +929,20 @@ struct ParseNode {
|
||||
#endif
|
||||
inline ConditionalExpression &asConditionalExpression();
|
||||
inline PropertyAccess &asPropertyAccess();
|
||||
|
||||
#ifdef DEBUG
|
||||
inline void dump(int indent);
|
||||
#endif
|
||||
};
|
||||
|
||||
struct NullaryNode : public ParseNode {
|
||||
static inline NullaryNode *create(ParseNodeKind kind, TreeContext *tc) {
|
||||
return (NullaryNode *)ParseNode::create(kind, PN_NULLARY, tc);
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
inline void dump();
|
||||
#endif
|
||||
};
|
||||
|
||||
struct UnaryNode : public ParseNode {
|
||||
@ -947,6 +955,10 @@ struct UnaryNode : public ParseNode {
|
||||
static inline UnaryNode *create(ParseNodeKind kind, TreeContext *tc) {
|
||||
return (UnaryNode *)ParseNode::create(kind, PN_UNARY, tc);
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
inline void dump(int indent);
|
||||
#endif
|
||||
};
|
||||
|
||||
struct BinaryNode : public ParseNode {
|
||||
@ -967,6 +979,10 @@ struct BinaryNode : public ParseNode {
|
||||
static inline BinaryNode *create(ParseNodeKind kind, TreeContext *tc) {
|
||||
return (BinaryNode *)ParseNode::create(kind, PN_BINARY, tc);
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
inline void dump(int indent);
|
||||
#endif
|
||||
};
|
||||
|
||||
struct TernaryNode : public ParseNode {
|
||||
@ -983,24 +999,40 @@ struct TernaryNode : public ParseNode {
|
||||
static inline TernaryNode *create(ParseNodeKind kind, TreeContext *tc) {
|
||||
return (TernaryNode *)ParseNode::create(kind, PN_TERNARY, tc);
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
inline void dump(int indent);
|
||||
#endif
|
||||
};
|
||||
|
||||
struct ListNode : public ParseNode {
|
||||
static inline ListNode *create(ParseNodeKind kind, TreeContext *tc) {
|
||||
return (ListNode *)ParseNode::create(kind, PN_LIST, tc);
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
inline void dump(int indent);
|
||||
#endif
|
||||
};
|
||||
|
||||
struct FunctionNode : public ParseNode {
|
||||
static inline FunctionNode *create(ParseNodeKind kind, TreeContext *tc) {
|
||||
return (FunctionNode *)ParseNode::create(kind, PN_FUNC, tc);
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
inline void dump(int indent);
|
||||
#endif
|
||||
};
|
||||
|
||||
struct NameNode : public ParseNode {
|
||||
static NameNode *create(ParseNodeKind kind, JSAtom *atom, TreeContext *tc);
|
||||
|
||||
inline void initCommon(TreeContext *tc);
|
||||
|
||||
#ifdef DEBUG
|
||||
inline void dump(int indent);
|
||||
#endif
|
||||
};
|
||||
|
||||
struct NameSetNode : public ParseNode {
|
||||
@ -1254,6 +1286,10 @@ class PropertyByValue : public ParseNode {
|
||||
ParseNode *
|
||||
CloneLeftHandSide(ParseNode *opn, TreeContext *tc);
|
||||
|
||||
#ifdef DEBUG
|
||||
void DumpParseTree(ParseNode *pn, int indent = 0);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* js::Definition is a degenerate subtype of the PN_FUNC and PN_NAME variants
|
||||
* of js::ParseNode, allocated only for function, var, const, and let
|
||||
|
@ -3704,8 +3704,12 @@ Parse(JSContext *cx, uintN argc, jsval *vp)
|
||||
js::Parser parser(cx);
|
||||
parser.init(JS_GetStringCharsZ(cx, scriptContents), JS_GetStringLength(scriptContents),
|
||||
"<string>", 0, cx->findVersion());
|
||||
if (!parser.parse(NULL))
|
||||
ParseNode *pn = parser.parse(NULL);
|
||||
if (!pn)
|
||||
return JS_FALSE;
|
||||
#ifdef DEBUG
|
||||
DumpParseTree(pn);
|
||||
#endif
|
||||
JS_SET_RVAL(cx, vp, JSVAL_VOID);
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user