Bug 696941 - Make Token::u::reflags private and hidden behind accessors. r=cdleary

This commit is contained in:
Jeff Walden 2011-10-24 19:22:27 -07:00
parent f67b311efc
commit 2b6d3e6f09
4 changed files with 46 additions and 22 deletions

View File

@ -7637,7 +7637,7 @@ Parser::primaryExpr(TokenKind tt, JSBool afterDot)
const jschar *chars = tokenStream.getTokenbuf().begin();
size_t length = tokenStream.getTokenbuf().length();
RegExpFlag flags = RegExpFlag(tokenStream.currentToken().t_reflags);
RegExpFlag flags = tokenStream.currentToken().regExpFlags();
RegExpStatics *res = context->regExpStatics();
RegExpObject *reobj;

View File

@ -1960,10 +1960,9 @@ TokenStream::getTokenInternal()
* Look for a regexp.
*/
if (flags & TSF_OPERAND) {
uintN reflags, length;
JSBool inCharClass = JS_FALSE;
tokenbuf.clear();
bool inCharClass = false;
for (;;) {
c = getChar();
if (c == '\\') {
@ -1971,9 +1970,9 @@ TokenStream::getTokenInternal()
goto error;
c = getChar();
} else if (c == '[') {
inCharClass = JS_TRUE;
inCharClass = true;
} else if (c == ']') {
inCharClass = JS_FALSE;
inCharClass = false;
} else if (c == '/' && !inCharClass) {
/* For compat with IE, allow unescaped / in char classes. */
break;
@ -1987,31 +1986,36 @@ TokenStream::getTokenInternal()
if (!tokenbuf.append(c))
goto error;
}
for (reflags = 0, length = tokenbuf.length() + 1; ; length++) {
RegExpFlag reflags = NoFlags;
uintN length = tokenbuf.length() + 1;
while (true) {
c = peekChar();
if (c == 'g' && !(reflags & JSREG_GLOB))
reflags |= JSREG_GLOB;
if (c == 'g' && !(reflags & GlobalFlag))
reflags = RegExpFlag(reflags | GlobalFlag);
else if (c == 'i' && !(reflags & IgnoreCaseFlag))
reflags |= IgnoreCaseFlag;
reflags = RegExpFlag(reflags | IgnoreCaseFlag);
else if (c == 'm' && !(reflags & MultilineFlag))
reflags |= MultilineFlag;
reflags = RegExpFlag(reflags | MultilineFlag);
else if (c == 'y' && !(reflags & StickyFlag))
reflags |= StickyFlag;
reflags = RegExpFlag(reflags | StickyFlag);
else
break;
getChar();
length++;
}
c = peekChar();
if (JS7_ISLET(c)) {
char buf[2] = { '\0' };
char buf[2] = { '\0', '\0' };
tp->pos.begin.index += length + 1;
buf[0] = (char)c;
buf[0] = char(c);
ReportCompileErrorNumber(cx, this, NULL, JSREPORT_ERROR, JSMSG_BAD_REGEXP_FLAG,
buf);
(void) getChar();
goto error;
}
tp->t_reflags = reflags;
tp->setRegExpFlags(reflags);
tt = TOK_REGEXP;
break;
}

View File

@ -265,18 +265,25 @@ struct Token {
JSAtom *atom; /* potentially-numeric atom */
} n;
} s;
uintN reflags; /* regexp flags, use tokenbuf to access
regexp chars */
class { /* pair for <?target data?> XML PI */
friend struct Token;
JSAtom *data; /* auxiliary atom table entry */
PropertyName *target; /* main atom table entry */
} xmlpi;
jsdouble dval; /* floating point number */
private:
friend struct Token;
RegExpFlag reflags; /* regexp flags, use tokenbuf to access
regexp chars */
} u;
/* Mutators */
/*
* FIXME: Init type early enough such that all mutators can assert
* type-safety. See bug 697000.
*/
void setName(JSOp op, PropertyName *name) {
JS_ASSERT(op == JSOP_NAME);
u.s.op = op;
@ -294,6 +301,11 @@ struct Token {
u.xmlpi.data = data;
}
void setRegExpFlags(js::RegExpFlag flags) {
JS_ASSERT((flags & AllFlags) == flags);
u.reflags = flags;
}
/* Type-safe accessors */
PropertyName *name() const {
@ -320,10 +332,15 @@ struct Token {
JS_ASSERT(type == TOK_XMLPI);
return u.xmlpi.data;
}
js::RegExpFlag regExpFlags() const {
JS_ASSERT(type == TOK_REGEXP);
JS_ASSERT((u.reflags & AllFlags) == u.reflags);
return u.reflags;
}
};
#define t_op u.s.op
#define t_reflags u.reflags
#define t_dval u.dval
enum TokenStreamFlags

View File

@ -129,10 +129,13 @@ class MatchPairs;
enum RegExpFlag
{
IgnoreCaseFlag = JS_BIT(0),
GlobalFlag = JS_BIT(1),
MultilineFlag = JS_BIT(2),
StickyFlag = JS_BIT(3)
IgnoreCaseFlag = 0x01,
GlobalFlag = 0x02,
MultilineFlag = 0x04,
StickyFlag = 0x08,
NoFlags = 0x00,
AllFlags = 0x0f
};
enum RegExpExecType