зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1343579 - Implements Debugger.Script.isInCatchScope for wasm scripts. r=shu
MozReview-Commit-ID: 29wj8APhtXW --HG-- extra : rebase_source : f386750b18ffea1101fa709c3d73a538dd52e909
This commit is contained in:
Родитель
4d301ff840
Коммит
5cb89346cc
|
@ -0,0 +1,26 @@
|
||||||
|
// |jit-test| test-also-wasm-baseline
|
||||||
|
// Checking if Debugger.Script.isInCatchScope return false for wasm.
|
||||||
|
|
||||||
|
load(libdir + "wasm.js");
|
||||||
|
|
||||||
|
var results;
|
||||||
|
wasmRunWithDebugger(
|
||||||
|
'(module (memory 1) ' +
|
||||||
|
'(func $func0 i32.const 1000000 i32.load drop) ' +
|
||||||
|
'(func (export "test") call $func0))',
|
||||||
|
undefined,
|
||||||
|
function ({dbg, wasmScript}) {
|
||||||
|
results = [];
|
||||||
|
dbg.onExceptionUnwind = function (frame, value) {
|
||||||
|
if (frame.type != 'wasmcall') return;
|
||||||
|
var result = wasmScript.isInCatchScope(frame.offset);
|
||||||
|
results.push(result);
|
||||||
|
};
|
||||||
|
},
|
||||||
|
function ({error}) {
|
||||||
|
assertEq(error !== undefined, true);
|
||||||
|
assertEq(results.length, 2);
|
||||||
|
assertEq(results[0], false);
|
||||||
|
assertEq(results[1], false);
|
||||||
|
}
|
||||||
|
);
|
|
@ -25,5 +25,4 @@ assertThrowsInstanceOf(() => s.getChildScripts(), Error);
|
||||||
assertThrowsInstanceOf(() => s.getAllOffsets(), Error);
|
assertThrowsInstanceOf(() => s.getAllOffsets(), Error);
|
||||||
assertThrowsInstanceOf(() => s.getAllColumnOffsets(), Error);
|
assertThrowsInstanceOf(() => s.getAllColumnOffsets(), Error);
|
||||||
assertThrowsInstanceOf(() => s.getBreakpoint(0), Error);
|
assertThrowsInstanceOf(() => s.getBreakpoint(0), Error);
|
||||||
assertThrowsInstanceOf(() => s.isInCatchScope(0), Error);
|
|
||||||
assertThrowsInstanceOf(() => s.getOffsetsCoverage(), Error);
|
assertThrowsInstanceOf(() => s.getOffsetsCoverage(), Error);
|
||||||
|
|
|
@ -5859,22 +5859,12 @@ ScriptOffset(JSContext* cx, const Value& v, size_t* offsetp)
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
ScriptOffset(JSContext* cx, JSScript* script, const Value& v, size_t* offsetp)
|
EnsureScriptOffsetIsValid(JSContext* cx, JSScript* script, size_t offset)
|
||||||
{
|
{
|
||||||
double d;
|
if (IsValidBytecodeOffset(cx, script, offset))
|
||||||
size_t off;
|
return true;
|
||||||
|
JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_DEBUG_BAD_OFFSET);
|
||||||
bool ok = v.isNumber();
|
return false;
|
||||||
if (ok) {
|
|
||||||
d = v.toNumber();
|
|
||||||
off = size_t(d);
|
|
||||||
}
|
|
||||||
if (!ok || off != d || !IsValidBytecodeOffset(cx, script, off)) {
|
|
||||||
JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_DEBUG_BAD_OFFSET);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
*offsetp = off;
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
@ -6179,10 +6169,8 @@ class DebuggerScriptGetOffsetLocationMatcher
|
||||||
: cx_(cx), offset_(offset), result_(result) { }
|
: cx_(cx), offset_(offset), result_(result) { }
|
||||||
using ReturnType = bool;
|
using ReturnType = bool;
|
||||||
ReturnType match(HandleScript script) {
|
ReturnType match(HandleScript script) {
|
||||||
if (!IsValidBytecodeOffset(cx_, script, offset_)) {
|
if (!EnsureScriptOffsetIsValid(cx_, script, offset_))
|
||||||
JS_ReportErrorNumberASCII(cx_, GetErrorMessage, nullptr, JSMSG_DEBUG_BAD_OFFSET);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
FlowGraphSummary flowData(cx_);
|
FlowGraphSummary flowData(cx_);
|
||||||
if (!flowData.populate(cx_, script))
|
if (!flowData.populate(cx_, script))
|
||||||
|
@ -6741,10 +6729,8 @@ struct DebuggerScriptSetBreakpointMatcher
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!IsValidBytecodeOffset(cx_, script, offset_)) {
|
if (!EnsureScriptOffsetIsValid(cx_, script, offset_))
|
||||||
JS_ReportErrorNumberASCII(cx_, GetErrorMessage, nullptr, JSMSG_DEBUG_BAD_OFFSET);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
// Ensure observability *before* setting the breakpoint. If the script is
|
// Ensure observability *before* setting the breakpoint. If the script is
|
||||||
// not already a debuggee, trying to ensure observability after setting
|
// not already a debuggee, trying to ensure observability after setting
|
||||||
|
@ -6815,7 +6801,7 @@ DebuggerScript_getBreakpoints(JSContext* cx, unsigned argc, Value* vp)
|
||||||
jsbytecode* pc;
|
jsbytecode* pc;
|
||||||
if (args.length() > 0) {
|
if (args.length() > 0) {
|
||||||
size_t offset;
|
size_t offset;
|
||||||
if (!ScriptOffset(cx, script, args[0], &offset))
|
if (!ScriptOffset(cx, args[0], &offset) || !EnsureScriptOffsetIsValid(cx, script, offset))
|
||||||
return false;
|
return false;
|
||||||
pc = script->offsetToPC(offset);
|
pc = script->offsetToPC(offset);
|
||||||
} else {
|
} else {
|
||||||
|
@ -6898,38 +6884,67 @@ DebuggerScript_clearAllBreakpoints(JSContext* cx, unsigned argc, Value* vp)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class DebuggerScriptIsInCatchScopeMatcher
|
||||||
|
{
|
||||||
|
JSContext* cx_;
|
||||||
|
size_t offset_;
|
||||||
|
bool isInCatch_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit DebuggerScriptIsInCatchScopeMatcher(JSContext* cx, size_t offset) : cx_(cx), offset_(offset) { }
|
||||||
|
using ReturnType = bool;
|
||||||
|
|
||||||
|
inline bool isInCatch() const { return isInCatch_; }
|
||||||
|
|
||||||
|
ReturnType match(HandleScript script) {
|
||||||
|
if (!EnsureScriptOffsetIsValid(cx_, script, offset_))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Try note ranges are relative to the mainOffset of the script, so adjust
|
||||||
|
* offset accordingly.
|
||||||
|
*/
|
||||||
|
size_t offset = offset_ - script->mainOffset();
|
||||||
|
|
||||||
|
if (script->hasTrynotes()) {
|
||||||
|
JSTryNote* tnBegin = script->trynotes()->vector;
|
||||||
|
JSTryNote* tnEnd = tnBegin + script->trynotes()->length;
|
||||||
|
while (tnBegin != tnEnd) {
|
||||||
|
if (tnBegin->start <= offset &&
|
||||||
|
offset <= tnBegin->start + tnBegin->length &&
|
||||||
|
tnBegin->kind == JSTRY_CATCH)
|
||||||
|
{
|
||||||
|
isInCatch_ = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
++tnBegin;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
isInCatch_ = false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
ReturnType match(Handle<WasmInstanceObject*> instance) {
|
||||||
|
isInCatch_ = false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
DebuggerScript_isInCatchScope(JSContext* cx, unsigned argc, Value* vp)
|
DebuggerScript_isInCatchScope(JSContext* cx, unsigned argc, Value* vp)
|
||||||
{
|
{
|
||||||
THIS_DEBUGSCRIPT_SCRIPT(cx, argc, vp, "isInCatchScope", args, obj, script);
|
THIS_DEBUGSCRIPT_REFERENT(cx, argc, vp, "isInCatchScope", args, obj, referent);
|
||||||
if (!args.requireAtLeast(cx, "Debugger.Script.isInCatchScope", 1))
|
if (!args.requireAtLeast(cx, "Debugger.Script.isInCatchScope", 1))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
size_t offset;
|
size_t offset;
|
||||||
if (!ScriptOffset(cx, script, args[0], &offset))
|
if (!ScriptOffset(cx, args[0], &offset))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
/*
|
DebuggerScriptIsInCatchScopeMatcher matcher(cx, offset);
|
||||||
* Try note ranges are relative to the mainOffset of the script, so adjust
|
if (!referent.match(matcher))
|
||||||
* offset accordingly.
|
return false;
|
||||||
*/
|
args.rval().setBoolean(matcher.isInCatch());
|
||||||
offset -= script->mainOffset();
|
|
||||||
|
|
||||||
args.rval().setBoolean(false);
|
|
||||||
if (script->hasTrynotes()) {
|
|
||||||
JSTryNote* tnBegin = script->trynotes()->vector;
|
|
||||||
JSTryNote* tnEnd = tnBegin + script->trynotes()->length;
|
|
||||||
while (tnBegin != tnEnd) {
|
|
||||||
if (tnBegin->start <= offset &&
|
|
||||||
offset <= tnBegin->start + tnBegin->length &&
|
|
||||||
tnBegin->kind == JSTRY_CATCH)
|
|
||||||
{
|
|
||||||
args.rval().setBoolean(true);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
++tnBegin;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче