mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-25 11:15:34 +00:00
Bug 1552766: Handle optimised out this
when reporting missing bindings. r=jimb
In addition to normal bindings, which always use a proper identifier name, the |this| binding can also be optimised out for arrow functions. The |this| binding is stored in a binding named ".this", which, because it doesn't match the IdentifierName syntax, triggered an assertion when generating its printable representation. Workaround this assertion by special-casing ".this" when reporting optimised out bindings. Differential Revision: https://phabricator.services.mozilla.com/D47238 --HG-- extra : moz-landing-system : lando
This commit is contained in:
parent
3b9287f8d2
commit
14b2bea568
38
js/src/jit-test/tests/debug/optimized-out-arrow-this.js
Normal file
38
js/src/jit-test/tests/debug/optimized-out-arrow-this.js
Normal file
@ -0,0 +1,38 @@
|
||||
var g = newGlobal({newCompartment: true});
|
||||
var dbg = new Debugger(g);
|
||||
|
||||
g.eval(`
|
||||
function f() {
|
||||
// |this| in arrow-functions refers to the |this| binding in outer functions.
|
||||
// So when |frame.eval("this")| is executed, the outer |this| binding should
|
||||
// be returned, unless it has been optimised out.
|
||||
(() => {})();
|
||||
|
||||
// Ensure a |this| binding is created for |f|.
|
||||
return this;
|
||||
}
|
||||
`);
|
||||
|
||||
var errors = [];
|
||||
|
||||
function enterFrame(frame) {
|
||||
// Disable the handler so we don't call it recursively through |frame.eval|.
|
||||
dbg.onEnterFrame = undefined;
|
||||
|
||||
// Store the error when resolving |this| was unsuccessful.
|
||||
var r = frame.eval("this");
|
||||
if (r.throw) {
|
||||
errors.push(r.throw);
|
||||
}
|
||||
|
||||
// Re-enable the handler.
|
||||
dbg.onEnterFrame = enterFrame;
|
||||
};
|
||||
|
||||
dbg.onEnterFrame = enterFrame;
|
||||
|
||||
g.f();
|
||||
|
||||
assertEq(errors.length, 1);
|
||||
assertEq(errors[0].unsafeDereference().toString(),
|
||||
"Error: variable `this' has been optimized out");
|
@ -1426,14 +1426,6 @@ void LiveEnvironmentVal::staticAsserts() {
|
||||
|
||||
namespace {
|
||||
|
||||
static void ReportOptimizedOut(JSContext* cx, HandleId id) {
|
||||
if (UniqueChars printable =
|
||||
IdToPrintableUTF8(cx, id, IdToPrintableBehavior::IdIsIdentifier)) {
|
||||
JS_ReportErrorNumberUTF8(cx, GetErrorMessage, nullptr,
|
||||
JSMSG_DEBUG_OPTIMIZED_OUT, printable.get());
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* DebugEnvironmentProxy is the handler for DebugEnvironmentProxy proxy
|
||||
* objects. Having a custom handler (rather than trying to reuse js::Wrapper)
|
||||
@ -1962,6 +1954,20 @@ class DebugEnvironmentProxyHandler : public BaseProxyHandler {
|
||||
return true;
|
||||
}
|
||||
|
||||
static void reportOptimizedOut(JSContext* cx, HandleId id) {
|
||||
if (isThis(cx, id)) {
|
||||
JS_ReportErrorNumberUTF8(cx, GetErrorMessage, nullptr,
|
||||
JSMSG_DEBUG_OPTIMIZED_OUT, "this");
|
||||
return;
|
||||
}
|
||||
|
||||
if (UniqueChars printable =
|
||||
IdToPrintableUTF8(cx, id, IdToPrintableBehavior::IdIsIdentifier)) {
|
||||
JS_ReportErrorNumberUTF8(cx, GetErrorMessage, nullptr,
|
||||
JSMSG_DEBUG_OPTIMIZED_OUT, printable.get());
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
static const char family;
|
||||
static const DebugEnvironmentProxyHandler singleton;
|
||||
@ -2077,7 +2083,7 @@ class DebugEnvironmentProxyHandler : public BaseProxyHandler {
|
||||
case ACCESS_GENERIC:
|
||||
return JS_GetOwnPropertyDescriptorById(cx, env, id, desc);
|
||||
case ACCESS_LOST:
|
||||
ReportOptimizedOut(cx, id);
|
||||
reportOptimizedOut(cx, id);
|
||||
return false;
|
||||
default:
|
||||
MOZ_CRASH("bad AccessResult");
|
||||
@ -2157,7 +2163,7 @@ class DebugEnvironmentProxyHandler : public BaseProxyHandler {
|
||||
}
|
||||
return true;
|
||||
case ACCESS_LOST:
|
||||
ReportOptimizedOut(cx, id);
|
||||
reportOptimizedOut(cx, id);
|
||||
return false;
|
||||
default:
|
||||
MOZ_CRASH("bad AccessResult");
|
||||
|
Loading…
Reference in New Issue
Block a user