mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-28 13:21:28 +00:00
Bug 977371 - Allow more than 2^20 blockids (r=jorendorff)
This commit is contained in:
parent
51ccb33a0d
commit
b907526e5a
@ -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 {
|
||||
|
Loading…
x
Reference in New Issue
Block a user