diff --git a/js/public/OldDebugAPI.h b/js/public/OldDebugAPI.h index d78bfef19a3d..fbdd9c7c1145 100644 --- a/js/public/OldDebugAPI.h +++ b/js/public/OldDebugAPI.h @@ -130,83 +130,6 @@ JS_GetScriptBaseLineNumber(JSContext *cx, JSScript *script); extern JS_PUBLIC_API(unsigned) JS_GetScriptLineExtent(JSContext *cx, JSScript *script); -/************************************************************************/ - -/* - * JSAbstractFramePtr is the public version of AbstractFramePtr, a pointer to a - * StackFrame or baseline JIT frame. - */ -class JS_PUBLIC_API(JSAbstractFramePtr) -{ - uintptr_t ptr_; - jsbytecode *pc_; - - protected: - JSAbstractFramePtr() - : ptr_(0), pc_(nullptr) - { } - - public: - JSAbstractFramePtr(void *raw, jsbytecode *pc); - - uintptr_t raw() const { return ptr_; } - jsbytecode *pc() const { return pc_; } - - operator bool() const { return !!ptr_; } - - JSObject *scopeChain(JSContext *cx); - JSObject *callObject(JSContext *cx); - - JSFunction *maybeFun(); - JSScript *script(); - - bool getThisValue(JSContext *cx, JS::MutableHandleValue thisv); - - bool isDebuggerFrame(); - - bool evaluateInStackFrame(JSContext *cx, - const char *bytes, unsigned length, - const char *filename, unsigned lineno, - JS::MutableHandleValue rval); - - bool evaluateUCInStackFrame(JSContext *cx, - const jschar *chars, unsigned length, - const char *filename, unsigned lineno, - JS::MutableHandleValue rval); -}; - -class JS_PUBLIC_API(JSNullFramePtr) : public JSAbstractFramePtr -{ - public: - JSNullFramePtr() - : JSAbstractFramePtr() - {} -}; - -/* - * This class does not work when IonMonkey is active. It's only used by jsd, - * which can only be used when IonMonkey is disabled. - * - * To find the calling script and line number, use JS_DescribeSciptedCaller. - * To summarize the call stack, use JS::DescribeStack. - */ -class JS_PUBLIC_API(JSBrokenFrameIterator) -{ - void *data_; - - public: - explicit JSBrokenFrameIterator(JSContext *cx); - ~JSBrokenFrameIterator(); - - bool done() const; - JSBrokenFrameIterator& operator++(); - - JSAbstractFramePtr abstractFramePtr() const; - jsbytecode *pc() const; - - bool isConstructing() const; -}; - /************************************************************************/ diff --git a/js/src/shell/js.cpp b/js/src/shell/js.cpp index faf6cf91c168..c561a9f41415 100644 --- a/js/src/shell/js.cpp +++ b/js/src/shell/js.cpp @@ -62,6 +62,7 @@ #include "shell/jsheaptools.h" #include "shell/jsoptparse.h" #include "vm/ArgumentsObject.h" +#include "vm/Debugger.h" #include "vm/HelperThreads.h" #include "vm/Monitor.h" #include "vm/Shape.h" @@ -71,6 +72,9 @@ #include "jscompartmentinlines.h" #include "jsobjinlines.h" +#include "vm/Interpreter-inl.h" +#include "vm/Stack-inl.h" + #ifdef XP_WIN # define PATH_MAX (MAX_PATH > _MAX_DIR ? MAX_PATH : _MAX_DIR) #else @@ -2677,14 +2681,29 @@ EvalInFrame(JSContext *cx, unsigned argc, jsval *vp) if (!stableChars.initTwoByte(cx, str)) return JSTRAP_ERROR; - mozilla::Range chars = stableChars.twoByteRange(); - JSAbstractFramePtr frame(fi.abstractFramePtr().raw(), fi.pc()); + AbstractFramePtr frame = fi.abstractFramePtr(); RootedScript fpscript(cx, frame.script()); - bool ok = !!frame.evaluateUCInStackFrame(cx, chars.start().get(), chars.length(), - fpscript->filename(), - JS_PCToLineNumber(cx, fpscript, - fi.pc()), - MutableHandleValue::fromMarkedLocation(vp)); + + RootedObject scope(cx); + { + RootedObject scopeChain(cx, frame.scopeChain()); + AutoCompartment ac(cx, scopeChain); + scope = GetDebugScopeForFrame(cx, frame, fi.pc()); + } + Rooted env(cx, scope); + if (!env) + return false; + + if (!ComputeThis(cx, frame)) + return false; + RootedValue thisv(cx, frame.thisValue()); + + bool ok; + { + AutoCompartment ac(cx, env); + ok = EvaluateInEnv(cx, env, thisv, frame, stableChars.twoByteRange(), fpscript->filename(), + JS_PCToLineNumber(cx, fpscript, fi.pc()), args.rval()); + } return ok; } diff --git a/js/src/vm/OldDebugAPI.cpp b/js/src/vm/OldDebugAPI.cpp index a384810a1ba8..0466b3fd4a11 100644 --- a/js/src/vm/OldDebugAPI.cpp +++ b/js/src/vm/OldDebugAPI.cpp @@ -501,175 +501,3 @@ JS::FormatStackDump(JSContext *cx, char *buf, bool showArgs, bool showLocals, bo return buf; } - -JSAbstractFramePtr::JSAbstractFramePtr(void *raw, jsbytecode *pc) - : ptr_(uintptr_t(raw)), pc_(pc) -{ } - -JSObject * -JSAbstractFramePtr::scopeChain(JSContext *cx) -{ - AbstractFramePtr frame(*this); - RootedObject scopeChain(cx, frame.scopeChain()); - AutoCompartment ac(cx, scopeChain); - return GetDebugScopeForFrame(cx, frame, pc()); -} - -JSObject * -JSAbstractFramePtr::callObject(JSContext *cx) -{ - AbstractFramePtr frame(*this); - if (!frame.isFunctionFrame()) - return nullptr; - - JSObject *o = GetDebugScopeForFrame(cx, frame, pc()); - - /* - * Given that fp is a function frame and GetDebugScopeForFrame always fills - * in missing scopes, we can expect to find fp's CallObject on 'o'. Note: - * - GetDebugScopeForFrame wraps every ScopeObject (missing or not) with - * a DebugScopeObject proxy. - * - If fp is an eval-in-function, then fp has no callobj of its own and - * JS_GetFrameCallObject will return the innermost function's callobj. - */ - while (o) { - ScopeObject &scope = o->as().scope(); - if (scope.is()) - return o; - o = o->enclosingScope(); - } - return nullptr; -} - -JSFunction * -JSAbstractFramePtr::maybeFun() -{ - AbstractFramePtr frame(*this); - return frame.maybeFun(); -} - -JSScript * -JSAbstractFramePtr::script() -{ - AbstractFramePtr frame(*this); - return frame.script(); -} - -bool -JSAbstractFramePtr::getThisValue(JSContext *cx, MutableHandleValue thisv) -{ - AbstractFramePtr frame(*this); - - RootedObject scopeChain(cx, frame.scopeChain()); - js::AutoCompartment ac(cx, scopeChain); - if (!ComputeThis(cx, frame)) - return false; - - thisv.set(frame.thisValue()); - return true; -} - -bool -JSAbstractFramePtr::isDebuggerFrame() -{ - AbstractFramePtr frame(*this); - return frame.isDebuggerFrame(); -} - -bool -JSAbstractFramePtr::evaluateInStackFrame(JSContext *cx, - const char *bytes, unsigned length, - const char *filename, unsigned lineno, - MutableHandleValue rval) -{ - if (!CheckDebugMode(cx)) - return false; - - size_t len = length; - jschar *chars = InflateString(cx, bytes, &len); - if (!chars) - return false; - length = (unsigned) len; - - bool ok = evaluateUCInStackFrame(cx, chars, length, filename, lineno, rval); - js_free(chars); - - return ok; -} - -bool -JSAbstractFramePtr::evaluateUCInStackFrame(JSContext *cx, - const jschar *chars, unsigned length, - const char *filename, unsigned lineno, - MutableHandleValue rval) -{ - if (!CheckDebugMode(cx)) - return false; - - RootedObject scope(cx, scopeChain(cx)); - Rooted env(cx, scope); - if (!env) - return false; - - AbstractFramePtr frame(*this); - if (!ComputeThis(cx, frame)) - return false; - RootedValue thisv(cx, frame.thisValue()); - - js::AutoCompartment ac(cx, env); - return EvaluateInEnv(cx, env, thisv, frame, mozilla::Range(chars, length), - filename, lineno, rval); -} - -JSBrokenFrameIterator::JSBrokenFrameIterator(JSContext *cx) -{ - // Show all frames on the stack whose principal is subsumed by the current principal. - NonBuiltinScriptFrameIter iter(cx, - ScriptFrameIter::ALL_CONTEXTS, - ScriptFrameIter::GO_THROUGH_SAVED, - cx->compartment()->principals); - data_ = iter.copyData(); -} - -JSBrokenFrameIterator::~JSBrokenFrameIterator() -{ - js_free((ScriptFrameIter::Data *)data_); -} - -bool -JSBrokenFrameIterator::done() const -{ - NonBuiltinScriptFrameIter iter(*(ScriptFrameIter::Data *)data_); - return iter.done(); -} - -JSBrokenFrameIterator & -JSBrokenFrameIterator::operator++() -{ - ScriptFrameIter::Data *data = (ScriptFrameIter::Data *)data_; - NonBuiltinScriptFrameIter iter(*data); - ++iter; - *data = iter.data_; - return *this; -} - -JSAbstractFramePtr -JSBrokenFrameIterator::abstractFramePtr() const -{ - NonBuiltinScriptFrameIter iter(*(ScriptFrameIter::Data *)data_); - return JSAbstractFramePtr(iter.abstractFramePtr().raw(), iter.pc()); -} - -jsbytecode * -JSBrokenFrameIterator::pc() const -{ - NonBuiltinScriptFrameIter iter(*(ScriptFrameIter::Data *)data_); - return iter.pc(); -} - -bool -JSBrokenFrameIterator::isConstructing() const -{ - NonBuiltinScriptFrameIter iter(*(ScriptFrameIter::Data *)data_); - return iter.isConstructing(); -} diff --git a/js/src/vm/Stack.h b/js/src/vm/Stack.h index eb0d32aae8b0..cb06acb20149 100644 --- a/js/src/vm/Stack.h +++ b/js/src/vm/Stack.h @@ -135,11 +135,6 @@ class AbstractFramePtr MOZ_ASSERT_IF(fp, asRematerializedFrame() == fp); } - explicit AbstractFramePtr(JSAbstractFramePtr frame) - : ptr_(uintptr_t(frame.raw())) - { - } - static AbstractFramePtr FromRaw(void *raw) { AbstractFramePtr frame; frame.ptr_ = uintptr_t(raw); @@ -1679,8 +1674,6 @@ class FrameIter void popJitFrame(); void popAsmJSFrame(); void settleOnActivation(); - - friend class ::JSBrokenFrameIterator; }; class ScriptFrameIter : public FrameIter diff --git a/js/xpconnect/idl/nsIXPConnect.idl b/js/xpconnect/idl/nsIXPConnect.idl index 3dd07076bd67..202c965fa235 100644 --- a/js/xpconnect/idl/nsIXPConnect.idl +++ b/js/xpconnect/idl/nsIXPConnect.idl @@ -274,7 +274,7 @@ interface nsIXPCFunctionThisTranslator : nsISupports { 0xbd, 0xd6, 0x0, 0x0, 0x64, 0x65, 0x73, 0x74 } } %} -[noscript, uuid(9ec7367c-0dde-4b7a-963c-5a590ee3ee42)] +[noscript, uuid(89b8525d-5c22-48bd-8a79-66aac9cd705e)] interface nsIXPConnect : nsISupports { %{ C++ @@ -434,8 +434,6 @@ interface nsIXPConnect : nsISupports void debugDumpJSStack(in boolean showArgs, in boolean showLocals, in boolean showThisProps); - void debugDumpEvalInJSStackFrame(in uint32_t aFrameNumber, - in string aSourceText); /** * wrapJSAggregatedToNative is just like wrapJS except it is used in cases diff --git a/js/xpconnect/src/XPCDebug.cpp b/js/xpconnect/src/XPCDebug.cpp index 278412d813e3..97c282e59842 100644 --- a/js/xpconnect/src/XPCDebug.cpp +++ b/js/xpconnect/src/XPCDebug.cpp @@ -55,60 +55,3 @@ xpc_PrintJSStack(JSContext* cx, bool showArgs, bool showLocals, state.restore(); return buf; } - -/***************************************************************************/ - -static void -xpcDumpEvalErrorReporter(JSContext *cx, const char *message, - JSErrorReport *report) -{ - DebugDump("Error: %s\n", message); -} - -bool -xpc_DumpEvalInJSStackFrame(JSContext* cx, uint32_t frameno, const char* text) -{ - if (!cx || !text) { - DebugDump("%s", "invalid params passed to xpc_DumpEvalInJSStackFrame!\n"); - return false; - } - - DebugDump("js[%d]> %s\n", frameno, text); - - uint32_t num = 0; - - JSAbstractFramePtr frame = JSNullFramePtr(); - - JSBrokenFrameIterator iter(cx); - while (!iter.done()) { - if (num == frameno) { - frame = iter.abstractFramePtr(); - break; - } - ++iter; - num++; - } - - if (!frame) { - DebugDump("%s", "invalid frame number!\n"); - return false; - } - - JS::AutoSaveExceptionState exceptionState(cx); - JSErrorReporter older = JS_SetErrorReporter(cx, xpcDumpEvalErrorReporter); - - JS::RootedValue rval(cx); - JSString* str; - JSAutoByteString bytes; - if (frame.evaluateInStackFrame(cx, text, strlen(text), "eval", 1, &rval) && - nullptr != (str = ToString(cx, rval)) && - bytes.encodeLatin1(cx, str)) { - DebugDump("%s\n", bytes.ptr()); - } else { - DebugDump("%s", "eval failed!\n"); - } - - JS_SetErrorReporter(cx, older); - exceptionState.restore(); - return true; -} diff --git a/js/xpconnect/src/nsXPConnect.cpp b/js/xpconnect/src/nsXPConnect.cpp index 01174ac1cf32..5b2aa9eb422e 100644 --- a/js/xpconnect/src/nsXPConnect.cpp +++ b/js/xpconnect/src/nsXPConnect.cpp @@ -945,19 +945,6 @@ nsXPConnect::DebugPrintJSStack(bool showArgs, return nullptr; } -/* void debugDumpEvalInJSStackFrame (in uint32_t aFrameNumber, in string aSourceText); */ -NS_IMETHODIMP -nsXPConnect::DebugDumpEvalInJSStackFrame(uint32_t aFrameNumber, const char *aSourceText) -{ - JSContext* cx = GetCurrentJSContext(); - if (!cx) - printf("there is no JSContext on the nsIThreadJSContextStack!\n"); - else - xpc_DumpEvalInJSStackFrame(cx, aFrameNumber, aSourceText); - - return NS_OK; -} - /* jsval variantToJS (in JSContextPtr ctx, in JSObjectPtr scope, in nsIVariant value); */ NS_IMETHODIMP nsXPConnect::VariantToJS(JSContext* ctx, JSObject* scopeArg, nsIVariant* value, @@ -1408,16 +1395,6 @@ JS_EXPORT_API(char*) PrintJSStack() nullptr; } -JS_EXPORT_API(void) DumpJSEval(uint32_t frameno, const char* text) -{ - nsresult rv; - nsCOMPtr xpc(do_GetService(nsIXPConnect::GetCID(), &rv)); - if (NS_SUCCEEDED(rv) && xpc) - xpc->DebugDumpEvalInJSStackFrame(frameno, text); - else - printf("failed to get XPConnect service!\n"); -} - JS_EXPORT_API(void) DumpCompleteHeap() { nsCOMPtr listener = diff --git a/js/xpconnect/src/xpcprivate.h b/js/xpconnect/src/xpcprivate.h index aec80ba7c7ed..3c3f4489704a 100644 --- a/js/xpconnect/src/xpcprivate.h +++ b/js/xpconnect/src/xpcprivate.h @@ -2967,10 +2967,6 @@ extern char* xpc_PrintJSStack(JSContext* cx, bool showArgs, bool showLocals, bool showThisProps); -extern bool -xpc_DumpEvalInJSStackFrame(JSContext* cx, uint32_t frameno, const char* text); - - /***************************************************************************/ // Definition of nsScriptError, defined here because we lack a place to put