Bug 1615710 - Use js::BaseScript in DebuggerScriptVariant. r=jandem

Fold the JSScript* and LazyScript* variant arms into a single case. The
debugger now either uses BaseScript accessors directly, or uses
DelazifyScript to ensure bytecode exists if needed.

Note that there are still seperate instances for LazyScript and JSScript so
Debugger::wrapVariantReferent continues to be careful about normalizing
references.

Differential Revision: https://phabricator.services.mozilla.com/D64367

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Ted Campbell 2020-02-26 17:25:54 +00:00
Родитель 22182ef4f3
Коммит 9c42740b5c
5 изменённых файлов: 51 добавлений и 150 удалений

Просмотреть файл

@ -2355,7 +2355,8 @@ void DebugAPI::slowPathOnNewScript(JSContext* cx, HandleScript script) {
return dbg->observesNewScript() && dbg->observesScript(script);
},
[&](Debugger* dbg) -> bool {
Rooted<DebuggerScriptReferent> scriptReferent(cx, script.get());
BaseScript* base = script.get();
Rooted<DebuggerScriptReferent> scriptReferent(cx, base);
return dbg->fireNewScript(cx, scriptReferent);
});
}
@ -3608,14 +3609,10 @@ bool DebugAPI::edgeIsInDebuggerWeakmap(JSRuntime* rt, JSObject* src,
}
if (src->is<DebuggerScript>()) {
return src->as<DebuggerScript>().getReferent().match(
[=](JSScript* script) {
return dst.is<JSScript>() && script == &dst.as<JSScript>() &&
[=](BaseScript* script) {
return dst.is<BaseScript>() && script == &dst.as<BaseScript>() &&
dbg->scripts.hasEntry(script, src);
},
[=](LazyScript* lazy) {
return dst.is<LazyScript>() && lazy == &dst.as<LazyScript>() &&
dbg->scripts.hasEntry(lazy, src);
},
[=](WasmInstanceObject* instance) {
return dst.is<JSObject>() && instance == &dst.as<JSObject>() &&
dbg->wasmInstanceScripts.hasEntry(instance, src);
@ -6114,33 +6111,36 @@ DebuggerScript* Debugger::wrapVariantReferent(
//
// The LazyScript is canonical in all other cases.
if (referent.is<JSScript*>()) {
Handle<JSScript*> untaggedReferent = referent.template as<JSScript*>();
if (untaggedReferent->maybeLazyScript()) {
// This JSScript has a LazyScript, so the LazyScript is canonical.
Rooted<LazyScript*> lazyScript(cx, untaggedReferent->maybeLazyScript());
return wrapScript(cx, lazyScript);
}
// This JSScript doesn't have a LazyScript, so the JSScript is canonical.
obj = wrapVariantReferent<JSScript>(cx, scripts, referent);
} else if (referent.is<LazyScript*>()) {
Handle<LazyScript*> untaggedReferent = referent.template as<LazyScript*>();
if (untaggedReferent->maybeScript()) {
RootedScript script(cx, untaggedReferent->maybeScript());
if (!script->maybeLazyScript()) {
// Even though we have a LazyScript, we found a JSScript which doesn't
// have a LazyScript (which also means that no Debugger has wrapped this
// LazyScript), and the JSScript is canonical.
MOZ_ASSERT(!untaggedReferent->isWrappedByDebugger());
return wrapScript(cx, script);
if (referent.is<BaseScript*>()) {
Rooted<BaseScript*> base(cx, referent.as<BaseScript*>());
if (!base->isLazyScript()) {
RootedScript untaggedReferent(cx, static_cast<JSScript*>(base.get()));
if (untaggedReferent->maybeLazyScript()) {
// This JSScript has a LazyScript, so the LazyScript is canonical.
Rooted<LazyScript*> lazyScript(cx, untaggedReferent->maybeLazyScript());
return wrapScript(cx, lazyScript);
}
// This JSScript doesn't have a LazyScript, so the JSScript is canonical.
obj = wrapVariantReferent<BaseScript>(cx, scripts, referent);
} else {
Rooted<LazyScript*> untaggedReferent(
cx, static_cast<LazyScript*>(base.get()));
if (untaggedReferent->maybeScript()) {
RootedScript script(cx, untaggedReferent->maybeScript());
if (!script->maybeLazyScript()) {
// Even though we have a LazyScript, we found a JSScript which doesn't
// have a LazyScript (which also means that no Debugger has wrapped
// this LazyScript), and the JSScript is canonical.
MOZ_ASSERT(!untaggedReferent->isWrappedByDebugger());
return wrapScript(cx, script);
}
}
// If there is an associated JSScript, this LazyScript is reachable from
// it, so this LazyScript is canonical.
untaggedReferent->setWrappedByDebugger();
obj = wrapVariantReferent<BaseScript>(cx, scripts, referent);
}
// If there is an associated JSScript, this LazyScript is reachable from it,
// so this LazyScript is canonical.
untaggedReferent->setWrappedByDebugger();
obj = wrapVariantReferent<LazyScript>(cx, scripts, referent);
} else {
referent.template as<WasmInstanceObject*>();
obj = wrapVariantReferent<WasmInstanceObject>(cx, wasmInstanceScripts,
referent);
}
@ -6150,14 +6150,8 @@ DebuggerScript* Debugger::wrapVariantReferent(
DebuggerScript* Debugger::wrapScript(JSContext* cx,
Handle<BaseScript*> script) {
if (script->isLazyScript()) {
Rooted<DebuggerScriptReferent> referent(
cx, DebuggerScriptReferent(static_cast<LazyScript*>(script.get())));
return wrapVariantReferent(cx, referent);
}
Rooted<DebuggerScriptReferent> referent(
cx, DebuggerScriptReferent(static_cast<JSScript*>(script.get())));
Rooted<DebuggerScriptReferent> referent(cx,
DebuggerScriptReferent(script.get()));
return wrapVariantReferent(cx, referent);
}

Просмотреть файл

@ -455,7 +455,7 @@ using Env = JSObject;
// does point to something okay. Instead, we immediately build an instance of
// this type from the Cell* and use that instead, so we can benefit from
// Variant's static checks.
typedef mozilla::Variant<JSScript*, LazyScript*, WasmInstanceObject*>
typedef mozilla::Variant<BaseScript*, WasmInstanceObject*>
DebuggerScriptReferent;
// The referent of a Debugger.Source.

Просмотреть файл

@ -30,16 +30,13 @@ js::gc::Cell* js::DebuggerScript::getReferentCell() const {
js::DebuggerScriptReferent js::DebuggerScript::getReferent() const {
if (gc::Cell* cell = getReferentCell()) {
if (cell->is<BaseScript>()) {
if (cell->as<BaseScript>()->isLazyScript()) {
return mozilla::AsVariant(cell->as<LazyScript>());
}
return mozilla::AsVariant(cell->as<JSScript>());
return mozilla::AsVariant(cell->as<BaseScript>());
}
MOZ_ASSERT(cell->is<JSObject>());
return mozilla::AsVariant(
&static_cast<NativeObject*>(cell)->as<WasmInstanceObject>());
}
return mozilla::AsVariant(static_cast<JSScript*>(nullptr));
return mozilla::AsVariant(static_cast<BaseScript*>(nullptr));
}
js::BaseScript* js::DebuggerScript::getReferentScript() const {

Просмотреть файл

@ -195,7 +195,7 @@ struct MOZ_STACK_CLASS DebuggerScript::CallData {
script(cx) {}
MOZ_MUST_USE bool ensureScriptMaybeLazy() {
if (!referent.is<JSScript*>() && !referent.is<LazyScript*>()) {
if (!referent.is<BaseScript*>()) {
ReportValueError(cx, JSMSG_DEBUG_BAD_REFERENT, JSDVG_SEARCH_STACK,
args.thisv(), nullptr, "a JS script");
return false;
@ -207,14 +207,9 @@ struct MOZ_STACK_CLASS DebuggerScript::CallData {
if (!ensureScriptMaybeLazy()) {
return false;
}
if (referent.is<JSScript*>()) {
script = referent.as<JSScript*>();
} else {
Rooted<LazyScript*> lazyScript(cx, referent.as<LazyScript*>());
script = DelazifyScript(cx, lazyScript);
if (!script) {
return false;
}
script = DelazifyScript(cx, referent.as<BaseScript*>());
if (!script) {
return false;
}
return true;
}
@ -303,8 +298,9 @@ bool DebuggerScript::CallData::getIsModule() {
if (!ensureScriptMaybeLazy()) {
return false;
}
args.rval().setBoolean(referent.is<JSScript*>() &&
referent.as<JSScript*>()->isModule());
BaseScript* script = referent.as<BaseScript*>();
args.rval().setBoolean(script->isModule());
return true;
}
@ -334,12 +330,7 @@ bool DebuggerScript::CallData::getUrl() {
return false;
}
Rooted<BaseScript*> script(cx);
if (referent.is<JSScript*>()) {
script = referent.as<JSScript*>();
} else {
script = referent.as<LazyScript*>();
}
Rooted<BaseScript*> script(cx, referent.as<BaseScript*>());
if (script->filename()) {
JSString* str;
@ -361,16 +352,14 @@ bool DebuggerScript::CallData::getUrl() {
bool DebuggerScript::CallData::getStartLine() {
args.rval().setNumber(
referent.get().match([](JSScript*& s) { return s->lineno(); },
[](LazyScript*& s) { return s->lineno(); },
referent.get().match([](BaseScript*& s) { return s->lineno(); },
[](WasmInstanceObject*&) { return (uint32_t)1; }));
return true;
}
bool DebuggerScript::CallData::getStartColumn() {
args.rval().setNumber(
referent.get().match([](JSScript*& s) { return s->column(); },
[](LazyScript*& s) { return s->column(); },
referent.get().match([](BaseScript*& s) { return s->column(); },
[](WasmInstanceObject*&) { return (uint32_t)0; }));
return true;
}
@ -390,12 +379,6 @@ struct DebuggerScript::GetLineCountMatcher {
totalLines = double(GetScriptLineExtent(script));
return true;
}
ReturnType match(HandleScript script) {
return match(static_cast<Handle<BaseScript*>>(script));
}
ReturnType match(Handle<LazyScript*> lazyScript) {
return match(static_cast<Handle<BaseScript*>>(lazyScript));
}
ReturnType match(Handle<WasmInstanceObject*> instanceObj) {
wasm::Instance& instance = instanceObj->instance();
if (instance.debugEnabled()) {
@ -429,12 +412,6 @@ class DebuggerScript::GetSourceMatcher {
RootedScriptSourceObject source(cx_, script->sourceObject());
return dbg_->wrapSource(cx_, source);
}
ReturnType match(HandleScript script) {
return match(static_cast<Handle<BaseScript*>>(script));
}
ReturnType match(Handle<LazyScript*> lazyScript) {
return match(static_cast<Handle<BaseScript*>>(lazyScript));
}
ReturnType match(Handle<WasmInstanceObject*> wasmInstance) {
return dbg_->wrapWasmSource(cx_, wasmInstance);
}
@ -493,8 +470,7 @@ bool DebuggerScript::CallData::getGlobal() {
bool DebuggerScript::CallData::getFormat() {
args.rval().setString(referent.get().match(
[=](JSScript*&) { return cx->names().js.get(); },
[=](LazyScript*&) { return cx->names().js.get(); },
[=](BaseScript*&) { return cx->names().js.get(); },
[=](WasmInstanceObject*&) { return cx->names().wasm.get(); }));
return true;
}
@ -548,16 +524,9 @@ bool DebuggerScript::CallData::getChildScripts() {
return false;
}
if (obj->getReferent().is<JSScript*>()) {
RootedScript script(cx, obj->getReferent().as<JSScript*>());
if (!PushInnerFunctions(cx, dbg, result, script->gcthings())) {
return false;
}
} else {
Rooted<LazyScript*> lazy(cx, obj->getReferent().as<LazyScript*>());
if (!PushInnerFunctions(cx, dbg, result, lazy->gcthings())) {
return false;
}
Rooted<BaseScript*> script(cx, obj->getReferent().as<BaseScript*>());
if (!PushInnerFunctions(cx, dbg, result, script->gcthings())) {
return false;
}
args.rval().setObject(*result);
@ -873,12 +842,6 @@ class DebuggerScript::GetPossibleBreakpointsMatcher {
return true;
}
ReturnType match(HandleScript script) {
return match(static_cast<Handle<BaseScript*>>(script));
}
ReturnType match(Handle<LazyScript*> lazyScript) {
return match(static_cast<Handle<BaseScript*>>(lazyScript));
}
ReturnType match(Handle<WasmInstanceObject*> instanceObj) {
wasm::Instance& instance = instanceObj->instance();
@ -991,12 +954,6 @@ class DebuggerScript::GetOffsetMetadataMatcher {
return true;
}
ReturnType match(HandleScript script) {
return match(static_cast<Handle<BaseScript*>>(script));
}
ReturnType match(Handle<LazyScript*> lazyScript) {
return match(static_cast<Handle<BaseScript*>>(lazyScript));
}
ReturnType match(Handle<WasmInstanceObject*> instanceObj) {
wasm::Instance& instance = instanceObj->instance();
if (!instance.debugEnabled()) {
@ -1309,12 +1266,6 @@ class DebuggerScript::GetOffsetLocationMatcher {
return true;
}
ReturnType match(HandleScript script) {
return match(static_cast<Handle<BaseScript*>>(script));
}
ReturnType match(Handle<LazyScript*> lazyScript) {
return match(static_cast<Handle<BaseScript*>>(lazyScript));
}
ReturnType match(Handle<WasmInstanceObject*> instanceObj) {
wasm::Instance& instance = instanceObj->instance();
if (!instance.debugEnabled()) {
@ -1424,12 +1375,6 @@ class DebuggerScript::GetSuccessorOrPredecessorOffsetsMatcher {
}
return true;
}
ReturnType match(HandleScript script) {
return match(static_cast<Handle<BaseScript*>>(script));
}
ReturnType match(Handle<LazyScript*> lazyScript) {
return match(static_cast<Handle<BaseScript*>>(lazyScript));
}
ReturnType match(Handle<WasmInstanceObject*> instance) {
JS_ReportErrorASCII(
cx_, "getSuccessorOrPredecessorOffsets NYI on wasm instances");
@ -1878,12 +1823,6 @@ class DebuggerScript::GetAllColumnOffsetsMatcher {
}
return true;
}
ReturnType match(HandleScript script) {
return match(static_cast<Handle<BaseScript*>>(script));
}
ReturnType match(Handle<LazyScript*> lazyScript) {
return match(static_cast<Handle<BaseScript*>>(lazyScript));
}
ReturnType match(Handle<WasmInstanceObject*> instanceObj) {
wasm::Instance& instance = instanceObj->instance();
@ -1968,12 +1907,6 @@ class DebuggerScript::GetLineOffsetsMatcher {
return true;
}
ReturnType match(HandleScript script) {
return match(static_cast<Handle<BaseScript*>>(script));
}
ReturnType match(Handle<LazyScript*> lazyScript) {
return match(static_cast<Handle<BaseScript*>>(lazyScript));
}
ReturnType match(Handle<WasmInstanceObject*> instanceObj) {
wasm::Instance& instance = instanceObj->instance();
@ -2108,12 +2041,6 @@ struct DebuggerScript::SetBreakpointMatcher {
return true;
}
ReturnType match(HandleScript script) {
return match(static_cast<Handle<BaseScript*>>(script));
}
ReturnType match(Handle<LazyScript*> lazyScript) {
return match(static_cast<Handle<BaseScript*>>(lazyScript));
}
ReturnType match(Handle<WasmInstanceObject*> wasmInstance) {
wasm::Instance& instance = wasmInstance->instance();
if (!instance.debugEnabled() ||
@ -2245,12 +2172,6 @@ class DebuggerScript::ClearBreakpointMatcher {
dbg_, handler_);
return true;
}
ReturnType match(HandleScript script) {
return match(static_cast<Handle<BaseScript*>>(script));
}
ReturnType match(Handle<LazyScript*> lazyScript) {
return match(static_cast<Handle<BaseScript*>>(lazyScript));
}
ReturnType match(Handle<WasmInstanceObject*> instanceObj) {
wasm::Instance& instance = instanceObj->instance();
if (!instance.debugEnabled()) {
@ -2335,12 +2256,6 @@ class DebuggerScript::IsInCatchScopeMatcher {
isInCatch_ = false;
return true;
}
ReturnType match(HandleScript script) {
return match(static_cast<Handle<BaseScript*>>(script));
}
ReturnType match(Handle<LazyScript*> lazyScript) {
return match(static_cast<Handle<BaseScript*>>(lazyScript));
}
ReturnType match(Handle<WasmInstanceObject*> instance) {
isInCatch_ = false;
return true;

Просмотреть файл

@ -2236,7 +2236,7 @@ setterLevel: \
// N.B.: no setter -- custom logic in JSScript.
IMMUTABLE_FLAG_GETTER(argumentsHasVarBinding, ArgumentsHasVarBinding)
// IsForEval: custom logic below.
// IsModule: custom logic below.
IMMUTABLE_FLAG_GETTER(isModule, IsModule)
IMMUTABLE_FLAG_GETTER(needsFunctionEnvironmentObjects,
NeedsFunctionEnvironmentObjects)
IMMUTABLE_FLAG_GETTER_SETTER_PUBLIC(shouldDeclareArguments,
@ -2731,11 +2731,6 @@ class JSScript : public js::BaseScript {
void setLazyScript(js::LazyScript* lazy) { u.lazyScript = lazy; }
js::LazyScript* maybeLazyScript() { return u.lazyScript; }
bool isModule() const {
MOZ_ASSERT(hasFlag(ImmutableFlags::IsModule) ==
bodyScope()->is<js::ModuleScope>());
return hasFlag(ImmutableFlags::IsModule);
}
js::ModuleObject* module() const {
if (bodyScope()->is<js::ModuleScope>()) {
return bodyScope()->as<js::ModuleScope>().module();