зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1360220 - Replace emitRequireObjectCoercible with JSOP_CHECKOBJCOERCIBLE. r=shu
--HG-- extra : rebase_source : cef0f46847a0aded63dbbcdfa497dc9b5a7d5259
This commit is contained in:
Родитель
e32594a18e
Коммит
7a7d850eb6
|
@ -5894,7 +5894,7 @@ BytecodeEmitter::emitDestructuringOpsObject(ParseNode* pattern, DestructuringFla
|
|||
|
||||
MOZ_ASSERT(this->stackDepth > 0); // ... RHS
|
||||
|
||||
if (!emitRequireObjectCoercible()) // ... RHS
|
||||
if (!emit1(JSOP_CHECKOBJCOERCIBLE)) // ... RHS
|
||||
return false;
|
||||
|
||||
bool needsRestPropertyExcludedSet = pattern->pn_count > 1 &&
|
||||
|
@ -6929,42 +6929,6 @@ 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)
|
||||
{
|
||||
|
|
|
@ -708,10 +708,6 @@ 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
|
||||
};
|
||||
|
|
|
@ -183,22 +183,10 @@ check_one("[...].foo",
|
|||
function() { [undefined, ...[]].foo(); },
|
||||
" is not a function");
|
||||
|
||||
// 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");
|
||||
}
|
||||
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");
|
||||
|
||||
try {
|
||||
(function() {
|
||||
|
|
Загрузка…
Ссылка в новой задаче