Bug 977371 - Allow more than 2^20 blockids (r=jorendorff)

This commit is contained in:
Luke Wagner 2014-02-27 11:31:31 -06:00
Родитель 51ccb33a0d
Коммит b907526e5a
4 изменённых файлов: 38 добавлений и 23 удалений

Просмотреть файл

@ -495,6 +495,14 @@ class ParseNode
bool isDefn() const { return pn_defn; }
void setDefn(bool enabled) { pn_defn = enabled; }
static const unsigned NumDefinitionFlagBits = 10;
static const unsigned NumListFlagBits = 10;
static const unsigned NumBlockIdBits = 22;
static_assert(NumDefinitionFlagBits == NumListFlagBits,
"Assumed below to achieve consistent blockid offset");
static_assert(NumDefinitionFlagBits + NumBlockIdBits <= 32,
"This is supposed to fit in a single uint32_t");
TokenPos pn_pos; /* two 16-bit pairs here, for 64 bits */
int32_t pn_offset; /* first generated bytecode offset */
ParseNode *pn_next; /* intrinsic link in parent PN_LIST */
@ -505,8 +513,8 @@ class ParseNode
ParseNode *head; /* first node in list */
ParseNode **tail; /* ptr to ptr to last node in list */
uint32_t count; /* number of nodes in list */
uint32_t xflags:12, /* extra flags, see below */
blockid:20; /* see name variant below */
uint32_t xflags:NumListFlagBits, /* see PNX_* below */
blockid:NumBlockIdBits; /* see name variant below */
} list;
struct { /* ternary: if, for(;;), ?: */
ParseNode *kid1; /* condition, discriminant, etc. */
@ -541,9 +549,9 @@ class ParseNode
UpvarCookie cookie; /* upvar cookie with absolute frame
level (not relative skip), possibly
in current frame */
uint32_t dflags:12, /* definition/use flags, see below */
blockid:20; /* block number, for subset dominance
computation */
uint32_t dflags:NumDefinitionFlagBits, /* see PND_* below */
blockid:NumBlockIdBits; /* block number, for subset dominance
computation */
} name;
struct {
double value; /* aligned numeric literal value */
@ -643,38 +651,42 @@ class ParseNode
#define PND_LET 0x01 /* let (block-scoped) binding */
#define PND_CONST 0x02 /* const binding (orthogonal to let) */
#define PND_ASSIGNED 0x04 /* set if ever LHS of assignment */
#define PND_PLACEHOLDER 0x10 /* placeholder definition for lexdep */
#define PND_BOUND 0x20 /* bound to a stack or global slot */
#define PND_DEOPTIMIZED 0x40 /* former pn_used name node, pn_lexdef
#define PND_PLACEHOLDER 0x08 /* placeholder definition for lexdep */
#define PND_BOUND 0x10 /* bound to a stack or global slot */
#define PND_DEOPTIMIZED 0x20 /* former pn_used name node, pn_lexdef
still valid, but this use no longer
optimizable via an upvar opcode */
#define PND_CLOSED 0x80 /* variable is closed over */
#define PND_DEFAULT 0x100 /* definition is an arg with a default */
#define PND_IMPLICITARGUMENTS 0x200 /* the definition is a placeholder for
#define PND_CLOSED 0x40 /* variable is closed over */
#define PND_DEFAULT 0x80 /* definition is an arg with a default */
#define PND_IMPLICITARGUMENTS 0x100 /* the definition is a placeholder for
'arguments' that has been converted
into a definition after the function
body has been parsed. */
#define PND_EMITTEDFUNCTION 0x400 /* hoisted function that was emitted */
#define PND_EMITTEDFUNCTION 0x200 /* hoisted function that was emitted */
static_assert(PND_EMITTEDFUNCTION < (1 << NumDefinitionFlagBits), "Not enough bits");
/* Flags to propagate from uses to definition. */
#define PND_USE2DEF_FLAGS (PND_ASSIGNED | PND_CLOSED)
/* PN_LIST pn_xflags bits. */
#define PNX_POPVAR 0x04 /* PNK_VAR or PNK_CONST last result
#define PNX_POPVAR 0x01 /* PNK_VAR or PNK_CONST last result
needs popping */
#define PNX_GROUPINIT 0x08 /* var [a, b] = [c, d]; unit list */
#define PNX_FUNCDEFS 0x10 /* contains top-level function statements */
#define PNX_SETCALL 0x20 /* call expression in lvalue context */
#define PNX_DESTRUCT 0x40 /* destructuring special cases:
#define PNX_GROUPINIT 0x02 /* var [a, b] = [c, d]; unit list */
#define PNX_FUNCDEFS 0x04 /* contains top-level function statements */
#define PNX_SETCALL 0x08 /* call expression in lvalue context */
#define PNX_DESTRUCT 0x10 /* destructuring special cases:
1. shorthand syntax used, at present
object destructuring ({x,y}) only;
2. code evaluating destructuring
arguments occurs before function
body */
#define PNX_SPECIALARRAYINIT 0x80 /* one or more of
#define PNX_SPECIALARRAYINIT 0x20 /* one or more of
1. array initialiser has holes
2. array initializer has spread node */
#define PNX_NONCONST 0x100 /* initialiser has non-constants */
#define PNX_NONCONST 0x40 /* initialiser has non-constants */
static_assert(PNX_NONCONST < (1 << NumListFlagBits), "Not enough bits");
unsigned frameLevel() const {
JS_ASSERT(pn_arity == PN_CODE || pn_arity == PN_NAME);

Просмотреть файл

@ -65,15 +65,17 @@ typedef Handle<NestedScopeObject*> HandleNestedScopeObject;
} \
JS_END_MACRO
static const unsigned BlockIdLimit = 1 << ParseNode::NumBlockIdBits;
template <typename ParseHandler>
bool
GenerateBlockId(TokenStream &ts, ParseContext<ParseHandler> *pc, uint32_t &blockid)
{
if (pc->blockidGen == JS_BIT(20)) {
if (pc->blockidGen == BlockIdLimit) {
ts.reportError(JSMSG_NEED_DIET, "program");
return false;
}
JS_ASSERT(pc->blockidGen < JS_BIT(20));
JS_ASSERT(pc->blockidGen < BlockIdLimit);
blockid = pc->blockidGen++;
return true;
}
@ -5825,7 +5827,7 @@ static bool
AdjustBlockId(TokenStream &ts, ParseNode *pn, unsigned adjust, ParseContext<ParseHandler> *pc)
{
JS_ASSERT(pn->isArity(PN_LIST) || pn->isArity(PN_CODE) || pn->isArity(PN_NAME));
if (JS_BIT(20) - pn->pn_blockid <= adjust + 1) {
if (BlockIdLimit - pn->pn_blockid <= adjust + 1) {
ts.reportError(JSMSG_NEED_DIET, "program");
return false;
}

Просмотреть файл

@ -4,6 +4,7 @@ Function("\
for each(l in[(let(c)([])\
for each(l in[]))(let(c)w for(u in[]))(let(u)w for(l in[]))(let(c)w for(u in[]))\
(let(u)w for each(l in[]))(let(c)w for(u in[]))(let(u)w for(l in[]))(let(c)w for(u in[]))\
(let(u)w for each(l in[]))(let(c)w for(u in[]))(let(u)w for(l in[]))(let(c)w for(u in[]))\
(let(l)w for(l in[]))(let(u)w for(l in['']))(let(c)w for(u in[]))(let(u)w for(l in[]))\
(let(c)w for(l in[]))(let(l)w for(l in[]))(let(c)w for(l in[]))(let(u)w for(l in[]))\
(let(c)w for(l in[]))(let(u)w for each(l in[x]))(let(w,x)w for(u in[]))]){}\

Просмотреть файл

@ -12,7 +12,7 @@ var actual;
* with 2^19 blocks, then test 2^20 - 1 blocks, finally test the limit.
*/
var s = "{}";
for (var i = 0; i < 19; i++)
for (var i = 0; i < 21; i++)
s += s;
try {