Bug 1470558: Use Completion type for Debugger eval-related methods. r=jorendorff
authorJim Blandy <jimb@mozilla.com>
Sun, 07 Jul 2019 09:47:52 +0000
changeset 544420 4f26d027343a0b26ddfb0410082bc2a46c3d9537
parent 544419 f82f7c40443dc5fe196a73a7eb972e332321051e
child 544421 3800d671c64ee26d9f59a773488cc18a6da3587a
push id2131
push userffxbld-merge
push dateMon, 26 Aug 2019 18:30:20 +0000
treeherdermozilla-release@b19ffb3ca153 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjorendorff
bugs1470558
milestone69.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1470558: Use Completion type for Debugger eval-related methods. r=jorendorff DebuggerFrame::eval and DebuggerObject::evalInGlobal are two more invocation functions that can reasonably use Completion to report the results of the operation. Differential Revision: https://phabricator.services.mozilla.com/D33077
js/src/vm/Debugger.cpp
js/src/vm/Debugger.h
--- a/js/src/vm/Debugger.cpp
+++ b/js/src/vm/Debugger.cpp
@@ -9796,125 +9796,122 @@ static bool EvaluateInEnv(JSContext* cx,
     if (!script) {
       return false;
     }
   }
 
   return ExecuteKernel(cx, script, *env, NullValue(), frame, rval.address());
 }
 
-static bool DebuggerGenericEval(
+static Result<Completion> DebuggerGenericEval(
     JSContext* cx, const mozilla::Range<const char16_t> chars,
-    HandleObject bindings, const EvalOptions& options, ResumeMode& resumeMode,
-    MutableHandleValue value, MutableHandleSavedFrame exnStack, Debugger* dbg,
+    HandleObject bindings, const EvalOptions& options, Debugger* dbg,
     HandleObject envArg, FrameIter* iter) {
   // Either we're specifying the frame, or a global.
   MOZ_ASSERT_IF(iter, !envArg);
   MOZ_ASSERT_IF(!iter, envArg && IsGlobalLexicalEnvironment(envArg));
 
   // Gather keys and values of bindings, if any. This must be done in the
   // debugger compartment, since that is where any exceptions must be thrown.
   RootedIdVector keys(cx);
   RootedValueVector values(cx);
   if (bindings) {
     if (!GetPropertyKeys(cx, bindings, JSITER_OWNONLY, &keys) ||
         !values.growBy(keys.length())) {
-      return false;
+      return cx->alreadyReportedError();
     }
     for (size_t i = 0; i < keys.length(); i++) {
       MutableHandleValue valp = values[i];
       if (!GetProperty(cx, bindings, bindings, keys[i], valp) ||
           !dbg->unwrapDebuggeeValue(cx, valp)) {
-        return false;
+        return cx->alreadyReportedError();
       }
     }
   }
 
   Maybe<AutoRealm> ar;
   if (iter) {
     ar.emplace(cx, iter->environmentChain(cx));
   } else {
     ar.emplace(cx, envArg);
   }
 
   Rooted<Env*> env(cx);
   if (iter) {
     env = GetDebugEnvironmentForFrame(cx, iter->abstractFramePtr(), iter->pc());
     if (!env) {
-      return false;
+      return cx->alreadyReportedError();
     }
   } else {
     env = envArg;
   }
 
   // If evalWithBindings, create the inner environment.
   if (bindings) {
     RootedPlainObject nenv(cx,
                            NewObjectWithGivenProto<PlainObject>(cx, nullptr));
     if (!nenv) {
-      return false;
+      return cx->alreadyReportedError();
     }
     RootedId id(cx);
     for (size_t i = 0; i < keys.length(); i++) {
       id = keys[i];
       cx->markId(id);
       MutableHandleValue val = values[i];
       if (!cx->compartment()->wrap(cx, val) ||
           !NativeDefineDataProperty(cx, nenv, id, val, 0)) {
-        return false;
+        return cx->alreadyReportedError();
       }
     }
 
     RootedObjectVector envChain(cx);
     if (!envChain.append(nenv)) {
-      return false;
+      return cx->alreadyReportedError();
     }
 
     RootedObject newEnv(cx);
     if (!CreateObjectsForEnvironmentChain(cx, envChain, env, &newEnv)) {
-      return false;
+      return cx->alreadyReportedError();
     }
 
     env = newEnv;
   }
 
   // Run the code and produce the completion value.
   LeaveDebuggeeNoExecute nnx(cx);
   RootedValue rval(cx);
   AbstractFramePtr frame = iter ? iter->abstractFramePtr() : NullFramePtr();
 
   bool ok = EvaluateInEnv(
       cx, env, frame, chars,
       options.filename() ? options.filename() : "debugger eval code",
       options.lineno(), &rval);
-  Debugger::resultToCompletion(cx, ok, rval, &resumeMode, value, exnStack);
+  Rooted<Completion> completion(cx, Completion::fromJSResult(cx, ok, rval));
   ar.reset();
-  return dbg->wrapDebuggeeValue(cx, value);
-}
-
-/* static */
-bool DebuggerFrame::eval(JSContext* cx, HandleDebuggerFrame frame,
-                         mozilla::Range<const char16_t> chars,
-                         HandleObject bindings, const EvalOptions& options,
-                         ResumeMode& resumeMode, MutableHandleValue value,
-                         MutableHandleSavedFrame exnStack) {
+  return completion.get();
+}
+
+/* static */
+Result<Completion> DebuggerFrame::eval(JSContext* cx, HandleDebuggerFrame frame,
+                                       mozilla::Range<const char16_t> chars,
+                                       HandleObject bindings,
+                                       const EvalOptions& options) {
   MOZ_ASSERT(frame->isLive());
 
   Debugger* dbg = frame->owner();
 
   Maybe<FrameIter> maybeIter;
   if (!DebuggerFrame::getFrameIter(cx, frame, maybeIter)) {
-    return false;
+    return cx->alreadyReportedError();
   }
   FrameIter& iter = *maybeIter;
 
   UpdateFrameIterPc(iter);
 
-  return DebuggerGenericEval(cx, chars, bindings, options, resumeMode, value,
-                             exnStack, dbg, nullptr, &iter);
+  return DebuggerGenericEval(cx, chars, bindings, options, dbg, nullptr, &iter);
 }
 
 /* static */
 bool DebuggerFrame::isLive() const { return !!getPrivate(); }
 
 OnStepHandler* DebuggerFrame::onStepHandler() const {
   Value value = getReservedSlot(ONSTEP_HANDLER_SLOT);
   return value.isUndefined() ? nullptr
@@ -10498,26 +10495,20 @@ bool DebuggerFrame::evalMethod(JSContext
   }
   mozilla::Range<const char16_t> chars = stableChars.twoByteRange();
 
   EvalOptions options;
   if (!ParseEvalOptions(cx, args.get(1), options)) {
     return false;
   }
 
-  ResumeMode resumeMode;
-  RootedValue value(cx);
-  RootedSavedFrame exnStack(cx);
-  if (!DebuggerFrame::eval(cx, frame, chars, nullptr, options, resumeMode,
-                           &value, &exnStack)) {
-    return false;
-  }
-
-  return frame->owner()->newCompletionValue(cx, resumeMode, value, exnStack,
-                                            args.rval());
+  Rooted<Completion> comp(cx);
+  JS_TRY_VAR_OR_RETURN_FALSE(
+      cx, comp, DebuggerFrame::eval(cx, frame, chars, nullptr, options));
+  return comp.get().buildCompletionValue(cx, frame->owner(), args.rval());
 }
 
 /* static */
 bool DebuggerFrame::evalWithBindingsMethod(JSContext* cx, unsigned argc,
                                            Value* vp) {
   THIS_DEBUGGER_FRAME(cx, argc, vp, "evalWithBindings", args, frame);
   if (!args.requireAtLeast(cx, "Debugger.Frame.prototype.evalWithBindings",
                            2)) {
@@ -10536,26 +10527,20 @@ bool DebuggerFrame::evalWithBindingsMeth
     return false;
   }
 
   EvalOptions options;
   if (!ParseEvalOptions(cx, args.get(2), options)) {
     return false;
   }
 
-  ResumeMode resumeMode;
-  RootedValue value(cx);
-  RootedSavedFrame exnStack(cx);
-  if (!DebuggerFrame::eval(cx, frame, chars, bindings, options, resumeMode,
-                           &value, &exnStack)) {
-    return false;
-  }
-
-  return frame->owner()->newCompletionValue(cx, resumeMode, value, exnStack,
-                                            args.rval());
+  Rooted<Completion> comp(cx);
+  JS_TRY_VAR_OR_RETURN_FALSE(
+      cx, comp, DebuggerFrame::eval(cx, frame, chars, bindings, options));
+  return comp.get().buildCompletionValue(cx, frame->owner(), args.rval());
 }
 
 /* static */
 bool DebuggerFrame::construct(JSContext* cx, unsigned argc, Value* vp) {
   JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_NO_CONSTRUCTOR,
                             "Debugger.Frame");
   return false;
 }
@@ -11675,26 +11660,21 @@ bool DebuggerObject::executeInGlobalMeth
   }
   mozilla::Range<const char16_t> chars = stableChars.twoByteRange();
 
   EvalOptions options;
   if (!ParseEvalOptions(cx, args.get(1), options)) {
     return false;
   }
 
-  ResumeMode resumeMode;
-  RootedValue value(cx);
-  RootedSavedFrame exnStack(cx);
-  if (!DebuggerObject::executeInGlobal(cx, object, chars, nullptr, options,
-                                       resumeMode, &value, &exnStack)) {
-    return false;
-  }
-
-  return object->owner()->newCompletionValue(cx, resumeMode, value, exnStack,
-                                             args.rval());
+  Rooted<Completion> comp(cx);
+  JS_TRY_VAR_OR_RETURN_FALSE(
+      cx, comp,
+      DebuggerObject::executeInGlobal(cx, object, chars, nullptr, options));
+  return comp.get().buildCompletionValue(cx, object->owner(), args.rval());
 }
 
 /* static */
 bool DebuggerObject::executeInGlobalWithBindingsMethod(JSContext* cx,
                                                        unsigned argc,
                                                        Value* vp) {
   THIS_DEBUGOBJECT(cx, argc, vp, "executeInGlobalWithBindings", args, object);
   if (!args.requireAtLeast(
@@ -11719,26 +11699,21 @@ bool DebuggerObject::executeInGlobalWith
     return false;
   }
 
   EvalOptions options;
   if (!ParseEvalOptions(cx, args.get(2), options)) {
     return false;
   }
 
-  ResumeMode resumeMode;
-  RootedValue value(cx);
-  RootedSavedFrame exnStack(cx);
-  if (!DebuggerObject::executeInGlobal(cx, object, chars, bindings, options,
-                                       resumeMode, &value, &exnStack)) {
-    return false;
-  }
-
-  return object->owner()->newCompletionValue(cx, resumeMode, value, exnStack,
-                                             args.rval());
+  Rooted<Completion> comp(cx);
+  JS_TRY_VAR_OR_RETURN_FALSE(
+      cx, comp,
+      DebuggerObject::executeInGlobal(cx, object, chars, bindings, options));
+  return comp.get().buildCompletionValue(cx, object->owner(), args.rval());
 }
 
 /* static */
 bool DebuggerObject::makeDebuggeeValueMethod(JSContext* cx, unsigned argc,
                                              Value* vp) {
   THIS_DEBUGOBJECT(cx, argc, vp, "makeDebuggeeValue", args, object);
   if (!args.requireAtLeast(cx, "Debugger.Object.prototype.makeDebuggeeValue",
                            1)) {
@@ -12688,31 +12663,28 @@ bool DebuggerObject::forceLexicalInitial
       result = true;
     }
   }
 
   return true;
 }
 
 /* static */
-bool DebuggerObject::executeInGlobal(JSContext* cx, HandleDebuggerObject object,
-                                     mozilla::Range<const char16_t> chars,
-                                     HandleObject bindings,
-                                     const EvalOptions& options,
-                                     ResumeMode& resumeMode,
-                                     MutableHandleValue value,
-                                     MutableHandleSavedFrame exnStack) {
+Result<Completion> DebuggerObject::executeInGlobal(
+    JSContext* cx, HandleDebuggerObject object,
+    mozilla::Range<const char16_t> chars, HandleObject bindings,
+    const EvalOptions& options) {
   MOZ_ASSERT(object->isGlobal());
 
   Rooted<GlobalObject*> referent(cx, &object->referent()->as<GlobalObject>());
   Debugger* dbg = object->owner();
 
   RootedObject globalLexical(cx, &referent->lexicalEnvironment());
-  return DebuggerGenericEval(cx, chars, bindings, options, resumeMode, value,
-                             exnStack, dbg, globalLexical, nullptr);
+  return DebuggerGenericEval(cx, chars, bindings, options, dbg, globalLexical,
+                             nullptr);
 }
 
 /* static */
 bool DebuggerObject::makeDebuggeeValue(JSContext* cx,
                                        HandleDebuggerObject object,
                                        HandleValue value_,
                                        MutableHandleValue result) {
   RootedObject referent(cx, object->referent());
--- a/js/src/vm/Debugger.h
+++ b/js/src/vm/Debugger.h
@@ -1643,23 +1643,20 @@ class DebuggerFrame : public NativeObjec
                                    MutableHandleValue result);
   static DebuggerFrameType getType(HandleDebuggerFrame frame);
   static DebuggerFrameImplementation getImplementation(
       HandleDebuggerFrame frame);
   static MOZ_MUST_USE bool setOnStepHandler(JSContext* cx,
                                             HandleDebuggerFrame frame,
                                             OnStepHandler* handler);
 
-  static MOZ_MUST_USE bool eval(JSContext* cx, HandleDebuggerFrame frame,
-                                mozilla::Range<const char16_t> chars,
-                                HandleObject bindings,
-                                const EvalOptions& options,
-                                ResumeMode& resumeMode,
-                                MutableHandleValue value,
-                                MutableHandleSavedFrame exnStack);
+  static MOZ_MUST_USE JS::Result<Completion> eval(
+      JSContext* cx, HandleDebuggerFrame frame,
+      mozilla::Range<const char16_t> chars, HandleObject bindings,
+      const EvalOptions& options);
 
   MOZ_MUST_USE bool requireLive(JSContext* cx);
   static MOZ_MUST_USE DebuggerFrame* checkThis(JSContext* cx,
                                                const CallArgs& args,
                                                const char* fnname,
                                                bool checkLive);
 
   bool isLive() const;
@@ -1872,21 +1869,20 @@ class DebuggerObject : public NativeObje
   static MOZ_MUST_USE bool deleteProperty(JSContext* cx,
                                           HandleDebuggerObject object,
                                           HandleId id, ObjectOpResult& result);
   static MOZ_MUST_USE bool call(JSContext* cx, HandleDebuggerObject object,
                                 HandleValue thisv, Handle<ValueVector> args,
                                 MutableHandleValue result);
   static MOZ_MUST_USE bool forceLexicalInitializationByName(
       JSContext* cx, HandleDebuggerObject object, HandleId id, bool& result);
-  static MOZ_MUST_USE bool executeInGlobal(
+  static MOZ_MUST_USE JS::Result<Completion> executeInGlobal(
       JSContext* cx, HandleDebuggerObject object,
       mozilla::Range<const char16_t> chars, HandleObject bindings,
-      const EvalOptions& options, ResumeMode& resumeMode,
-      MutableHandleValue value, MutableHandleSavedFrame exnStack);
+      const EvalOptions& options);
   static MOZ_MUST_USE bool makeDebuggeeValue(JSContext* cx,
                                              HandleDebuggerObject object,
                                              HandleValue value,
                                              MutableHandleValue result);
   static MOZ_MUST_USE bool unsafeDereference(JSContext* cx,
                                              HandleDebuggerObject object,
                                              MutableHandleObject result);
   static MOZ_MUST_USE bool unwrap(JSContext* cx, HandleDebuggerObject object,