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:
Yury Delendik 2017-03-02 22:28:01 -06:00
Родитель 4d301ff840
Коммит 5cb89346cc
3 изменённых файлов: 86 добавлений и 46 удалений

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

@ -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;
} }