From 7a7d850eb6820c9dd2ec0db3ea7c9d103c166cf2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Bargull?= Date: Thu, 27 Apr 2017 09:24:08 -0700 Subject: [PATCH] Bug 1360220 - Replace emitRequireObjectCoercible with JSOP_CHECKOBJCOERCIBLE. r=shu --HG-- extra : rebase_source : cef0f46847a0aded63dbbcdfa497dc9b5a7d5259 --- js/src/frontend/BytecodeEmitter.cpp | 38 +------------------ js/src/frontend/BytecodeEmitter.h | 4 -- .../tests/basic/expression-autopsy.js | 20 ++-------- 3 files changed, 5 insertions(+), 57 deletions(-) diff --git a/js/src/frontend/BytecodeEmitter.cpp b/js/src/frontend/BytecodeEmitter.cpp index b866492a07fd..d6e4ae297890 100644 --- a/js/src/frontend/BytecodeEmitter.cpp +++ b/js/src/frontend/BytecodeEmitter.cpp @@ -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) { diff --git a/js/src/frontend/BytecodeEmitter.h b/js/src/frontend/BytecodeEmitter.h index 4f60bf8b0550..6c339d2b67aa 100644 --- a/js/src/frontend/BytecodeEmitter.h +++ b/js/src/frontend/BytecodeEmitter.h @@ -708,10 +708,6 @@ struct MOZ_STACK_CLASS BytecodeEmitter template 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 }; diff --git a/js/src/jit-test/tests/basic/expression-autopsy.js b/js/src/jit-test/tests/basic/expression-autopsy.js index de2d0a5efa11..e942ff2deafb 100644 --- a/js/src/jit-test/tests/basic/expression-autopsy.js +++ b/js/src/jit-test/tests/basic/expression-autopsy.js @@ -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() {