Bug 1360220 - Backed out changeset ed8623eefe6c for causing fuzzblocker bug 1362590, rs=shu on IRC

This commit is contained in:
Gary Kwong 2017-05-05 16:04:52 -07:00
parent 52209697e6
commit a6f9d2dd99
3 changed files with 57 additions and 5 deletions

View File

@ -5886,7 +5886,7 @@ BytecodeEmitter::emitDestructuringOpsObject(ParseNode* pattern, DestructuringFla
MOZ_ASSERT(this->stackDepth > 0); // ... RHS
if (!emit1(JSOP_CHECKOBJCOERCIBLE)) // ... RHS
if (!emitRequireObjectCoercible()) // ... RHS
return false;
bool needsRestPropertyExcludedSet = pattern->pn_count > 1 &&
@ -6921,6 +6921,42 @@ BytecodeEmitter::emitWith(ParseNode* pn)
return emitterScope.leave(this);
}
bool
BytecodeEmitter::emitRequireObjectCoercible()
{
// For simplicity, handle this in self-hosted code, at cost of 13 bytes of
// bytecode versus 1 byte for a dedicated opcode. As more places need this
// behavior, we may want to reconsider this tradeoff.
#ifdef DEBUG
auto depth = this->stackDepth;
#endif
MOZ_ASSERT(depth > 0); // VAL
if (!emit1(JSOP_DUP)) // VAL VAL
return false;
// Note that "intrinsic" is a misnomer: we're calling a *self-hosted*
// function that's not an intrinsic! But it nonetheless works as desired.
if (!emitAtomOp(cx->names().RequireObjectCoercible,
JSOP_GETINTRINSIC)) // VAL VAL REQUIREOBJECTCOERCIBLE
{
return false;
}
if (!emit1(JSOP_UNDEFINED)) // VAL VAL REQUIREOBJECTCOERCIBLE UNDEFINED
return false;
if (!emit2(JSOP_PICK, 2)) // VAL REQUIREOBJECTCOERCIBLE UNDEFINED VAL
return false;
if (!emitCall(JSOP_CALL_IGNORES_RV, 1))// VAL IGNORED
return false;
checkTypeSet(JSOP_CALL_IGNORES_RV);
if (!emit1(JSOP_POP)) // VAL
return false;
MOZ_ASSERT(depth == this->stackDepth);
return true;
}
bool
BytecodeEmitter::emitCopyDataProperties(CopyOption option)
{

View File

@ -708,6 +708,10 @@ struct MOZ_STACK_CLASS BytecodeEmitter
template <typename NameEmitter>
MOZ_MUST_USE bool emitDestructuringDeclsWithEmitter(ParseNode* pattern, NameEmitter emitName);
// Throw a TypeError if the value atop the stack isn't convertible to an
// object, with no overall effect on the stack.
MOZ_MUST_USE bool emitRequireObjectCoercible();
enum class CopyOption {
Filtered, Unfiltered
};

View File

@ -183,10 +183,22 @@ check_one("[...].foo",
function() { [undefined, ...[]].foo(); },
" is not a function");
check_one("[...][Symbol.iterator](...).next(...).value",
function () { var [{x}] = [null, {}]; }, " is null");
check_one("[...][Symbol.iterator](...).next(...).value",
function () { var [{x}] = [void 0, {}]; }, " is undefined");
// Manual testing for this case: the only way to trigger an error is *not* on
// an attempted property access during destructuring, and the error message
// invoking ToObject(null) is different: "can't convert {0} to object".
try
{
(function() {
var [{x}] = [null, {}];
})();
throw new Error("didn't throw");
}
catch (e)
{
assertEq(e instanceof TypeError, true,
"expected TypeError, got " + e);
assertEq(e.message, "can't convert null to object");
}
try {
(function() {