mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1234702 - Part 1: Allow opt-in calls to content invoking spread opts in self-hosted code. (r=till)
This commit is contained in:
parent
f0aed3b4d8
commit
6f61ae17c2
@ -3972,9 +3972,9 @@ BytecodeEmitter::emitDestructuringLHS(ParseNode* target, VarEmitOption emitOptio
|
||||
}
|
||||
|
||||
bool
|
||||
BytecodeEmitter::emitIteratorNext(ParseNode* pn)
|
||||
BytecodeEmitter::emitIteratorNext(ParseNode* pn, bool allowSelfHosted)
|
||||
{
|
||||
MOZ_ASSERT(emitterMode != BytecodeEmitter::SelfHosting,
|
||||
MOZ_ASSERT(allowSelfHosted || emitterMode != BytecodeEmitter::SelfHosting,
|
||||
".next() iteration is prohibited in self-hosted code because it "
|
||||
"can run user-modifiable iteration code");
|
||||
|
||||
@ -5514,7 +5514,7 @@ BytecodeEmitter::emitForInOrOfVariables(ParseNode* pn)
|
||||
}
|
||||
|
||||
bool
|
||||
BytecodeEmitter::emitForOf(StmtType type, ParseNode* pn)
|
||||
BytecodeEmitter::emitForOf(StmtType type, ParseNode* pn, bool allowSelfHosted)
|
||||
{
|
||||
MOZ_ASSERT(type == StmtType::FOR_OF_LOOP || type == StmtType::SPREAD);
|
||||
#ifdef DEBUG
|
||||
@ -5623,7 +5623,7 @@ BytecodeEmitter::emitForOf(StmtType type, ParseNode* pn)
|
||||
if (!emitDupAt(2)) // ITER ARR I ITER
|
||||
return false;
|
||||
}
|
||||
if (!emitIteratorNext(forHead)) // ... RESULT
|
||||
if (!emitIteratorNext(forHead, allowSelfHosted)) // ... RESULT
|
||||
return false;
|
||||
if (!emit1(JSOP_DUP)) // ... RESULT RESULT
|
||||
return false;
|
||||
@ -7269,6 +7269,18 @@ BytecodeEmitter::emitSelfHostedForceInterpreter(ParseNode* pn)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
BytecodeEmitter::emitSelfHostedAllowContentSpread(ParseNode* pn)
|
||||
{
|
||||
if (pn->pn_count != 2) {
|
||||
reportError(pn, JSMSG_MORE_ARGS_NEEDED, "allowContentSpread", "1", "");
|
||||
return false;
|
||||
}
|
||||
|
||||
// We're just here as a sentinel. Pass the value through directly.
|
||||
return emitTree(pn->pn_head->pn_next);
|
||||
}
|
||||
|
||||
bool
|
||||
BytecodeEmitter::emitCallOrNew(ParseNode* pn)
|
||||
{
|
||||
@ -7317,6 +7329,8 @@ BytecodeEmitter::emitCallOrNew(ParseNode* pn)
|
||||
return emitSelfHostedResumeGenerator(pn);
|
||||
if (pn2->name() == cx->names().forceInterpreter)
|
||||
return emitSelfHostedForceInterpreter(pn);
|
||||
if (pn2->name() == cx->names().allowContentSpread)
|
||||
return emitSelfHostedAllowContentSpread(pn);
|
||||
// Fall through.
|
||||
}
|
||||
if (!emitNameOp(pn2, callop))
|
||||
@ -7932,9 +7946,9 @@ BytecodeEmitter::emitArrayComp(ParseNode* pn)
|
||||
}
|
||||
|
||||
bool
|
||||
BytecodeEmitter::emitSpread()
|
||||
BytecodeEmitter::emitSpread(bool allowSelfHosted)
|
||||
{
|
||||
return emitForOf(StmtType::SPREAD, nullptr);
|
||||
return emitForOf(StmtType::SPREAD, nullptr, allowSelfHosted);
|
||||
}
|
||||
|
||||
bool
|
||||
@ -8024,11 +8038,25 @@ BytecodeEmitter::emitArray(ParseNode* pn, uint32_t count, JSOp op)
|
||||
}
|
||||
if (!updateSourceCoordNotes(pn2->pn_pos.begin))
|
||||
return false;
|
||||
|
||||
bool allowSelfHostedSpread = false;
|
||||
if (pn2->isKind(PNK_ELISION)) {
|
||||
if (!emit1(JSOP_HOLE))
|
||||
return false;
|
||||
} else {
|
||||
ParseNode* expr = pn2->isKind(PNK_SPREAD) ? pn2->pn_kid : pn2;
|
||||
ParseNode* expr;
|
||||
if (pn2->isKind(PNK_SPREAD)) {
|
||||
expr = pn2->pn_kid;
|
||||
|
||||
if (emitterMode == BytecodeEmitter::SelfHosting &&
|
||||
expr->isKind(PNK_CALL) &&
|
||||
expr->pn_head->name() == cx->names().allowContentSpread)
|
||||
{
|
||||
allowSelfHostedSpread = true;
|
||||
}
|
||||
} else {
|
||||
expr = pn2;
|
||||
}
|
||||
if (!emitTree(expr)) // ARRAY INDEX? VALUE
|
||||
return false;
|
||||
}
|
||||
@ -8039,7 +8067,7 @@ BytecodeEmitter::emitArray(ParseNode* pn, uint32_t count, JSOp op)
|
||||
return false;
|
||||
if (!emit2(JSOP_PICK, 2)) // ITER ARRAY INDEX
|
||||
return false;
|
||||
if (!emitSpread()) // ARRAY INDEX
|
||||
if (!emitSpread(allowSelfHostedSpread)) // ARRAY INDEX
|
||||
return false;
|
||||
} else if (afterSpread) {
|
||||
if (!emit1(JSOP_INITELEM_INC))
|
||||
|
@ -577,7 +577,7 @@ struct BytecodeEmitter
|
||||
|
||||
// Pops iterator from the top of the stack. Pushes the result of |.next()|
|
||||
// onto the stack.
|
||||
bool emitIteratorNext(ParseNode* pn);
|
||||
bool emitIteratorNext(ParseNode* pn, bool allowSelfHosted = false);
|
||||
|
||||
// Check if the value on top of the stack is "undefined". If so, replace
|
||||
// that value on the stack with the value defined by |defaultExpr|.
|
||||
@ -614,6 +614,7 @@ struct BytecodeEmitter
|
||||
bool emitSelfHostedCallFunction(ParseNode* pn);
|
||||
bool emitSelfHostedResumeGenerator(ParseNode* pn);
|
||||
bool emitSelfHostedForceInterpreter(ParseNode* pn);
|
||||
bool emitSelfHostedAllowContentSpread(ParseNode* pn);
|
||||
|
||||
bool emitComprehensionFor(ParseNode* compFor);
|
||||
bool emitComprehensionForIn(ParseNode* pn);
|
||||
@ -643,7 +644,7 @@ struct BytecodeEmitter
|
||||
// |.next()| and put the results into the I-th element of array with
|
||||
// incrementing I, then push the result I (it will be original I +
|
||||
// iteration count). The stack after iteration will look like |ARRAY INDEX|.
|
||||
bool emitSpread();
|
||||
bool emitSpread(bool allowSelfHosted = false);
|
||||
|
||||
// If type is StmtType::FOR_OF_LOOP, emit bytecode for a for-of loop.
|
||||
// pn should be PNK_FOR, and pn->pn_left should be PNK_FOROF.
|
||||
@ -653,7 +654,7 @@ struct BytecodeEmitter
|
||||
//
|
||||
// Please refer the comment above emitSpread for additional information about
|
||||
// stack convention.
|
||||
bool emitForOf(StmtType type, ParseNode* pn);
|
||||
bool emitForOf(StmtType type, ParseNode* pn, bool allowSelfHosted = false);
|
||||
|
||||
bool emitClass(ParseNode* pn);
|
||||
bool emitSuperPropLHS(ParseNode* superBase, bool isCall = false);
|
||||
|
@ -13,6 +13,7 @@
|
||||
|
||||
#define FOR_EACH_COMMON_PROPERTYNAME(macro) \
|
||||
macro(add, add, "add") \
|
||||
macro(allowContentSpread, allowContentSpread, "allowContentSpread") \
|
||||
macro(anonymous, anonymous, "anonymous") \
|
||||
macro(Any, Any, "Any") \
|
||||
macro(apply, apply, "apply") \
|
||||
|
Loading…
Reference in New Issue
Block a user