mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-17 07:15:46 +00:00
Bug 674171: Separate the construction of a completion value from the debuggee->debugger compartment transition. r=jorendorff
In class Debugger, split newCompletionValue into: - resultToCompletion, which takes a standard SpiderMonkey (success, value, context's exception) triple and produces the corresponding (JSTrapStatus, value) pair; and - newCompletionValue, which takes a (JSTrapStatus, value) pair and produces a JavaScript completion value. Define receiveCompletionValue to do exactly what newCompletionValue used to do: the above two operations, with a compartment 'leave' in the middle. Substitute receiveCompletionValue where newCompletionValue is used now.
This commit is contained in:
parent
fe12baec16
commit
20514714b0
@ -700,39 +700,79 @@ Debugger::handleUncaughtException(AutoCompartment &ac, Value *vp, bool callHook)
|
||||
return JSTRAP_ERROR;
|
||||
}
|
||||
|
||||
bool
|
||||
Debugger::newCompletionValue(AutoCompartment &ac, bool ok, Value val, Value *vp)
|
||||
void
|
||||
Debugger::resultToCompletion(JSContext *cx, bool ok, const Value &rv,
|
||||
JSTrapStatus *status, Value *value)
|
||||
{
|
||||
JS_ASSERT_IF(ok, !ac.context->isExceptionPending());
|
||||
JS_ASSERT_IF(ok, !cx->isExceptionPending());
|
||||
|
||||
JSContext *cx = ac.context;
|
||||
jsid key;
|
||||
if (ok) {
|
||||
ac.leave();
|
||||
key = ATOM_TO_JSID(cx->runtime->atomState.returnAtom);
|
||||
*status = JSTRAP_RETURN;
|
||||
*value = rv;
|
||||
} else if (cx->isExceptionPending()) {
|
||||
key = ATOM_TO_JSID(cx->runtime->atomState.throwAtom);
|
||||
val = cx->getPendingException();
|
||||
*status = JSTRAP_THROW;
|
||||
*value = cx->getPendingException();
|
||||
cx->clearPendingException();
|
||||
ac.leave();
|
||||
} else {
|
||||
ac.leave();
|
||||
vp->setNull();
|
||||
*status = JSTRAP_ERROR;
|
||||
value->setUndefined();
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
Debugger::newCompletionValue(JSContext *cx, JSTrapStatus status, Value value, Value *result)
|
||||
{
|
||||
/*
|
||||
* We must be in the debugger's compartment, since that's where we want
|
||||
* to construct the completion value.
|
||||
*/
|
||||
assertSameCompartment(cx, object.get());
|
||||
|
||||
jsid key;
|
||||
|
||||
switch (status) {
|
||||
case JSTRAP_RETURN:
|
||||
key = ATOM_TO_JSID(cx->runtime->atomState.returnAtom);
|
||||
break;
|
||||
|
||||
case JSTRAP_THROW:
|
||||
key = ATOM_TO_JSID(cx->runtime->atomState.throwAtom);
|
||||
break;
|
||||
|
||||
case JSTRAP_ERROR:
|
||||
result->setNull();
|
||||
return true;
|
||||
|
||||
default:
|
||||
JS_NOT_REACHED("bad status passed to Debugger::newCompletionValue");
|
||||
}
|
||||
|
||||
/* Common tail for JSTRAP_RETURN and JSTRAP_THROW. */
|
||||
JSObject *obj = NewBuiltinClassInstance(cx, &ObjectClass);
|
||||
if (!obj ||
|
||||
!wrapDebuggeeValue(cx, &val) ||
|
||||
!DefineNativeProperty(cx, obj, key, val, JS_PropertyStub, JS_StrictPropertyStub,
|
||||
!wrapDebuggeeValue(cx, &value) ||
|
||||
!DefineNativeProperty(cx, obj, key, value, JS_PropertyStub, JS_StrictPropertyStub,
|
||||
JSPROP_ENUMERATE, 0, 0))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
vp->setObject(*obj);
|
||||
|
||||
result->setObject(*obj);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
Debugger::receiveCompletionValue(AutoCompartment &ac, bool ok, Value val, Value *vp)
|
||||
{
|
||||
JSContext *cx = ac.context;
|
||||
|
||||
JSTrapStatus status;
|
||||
Value value;
|
||||
resultToCompletion(cx, ok, val, &status, &value);
|
||||
ac.leave();
|
||||
return newCompletionValue(cx, status, value, vp);
|
||||
}
|
||||
|
||||
JSTrapStatus
|
||||
Debugger::parseResumptionValue(AutoCompartment &ac, bool ok, const Value &rv, Value *vp,
|
||||
bool callHook)
|
||||
@ -2986,7 +3026,7 @@ DebuggerFrameEval(JSContext *cx, unsigned argc, Value *vp, EvalBindingsMode mode
|
||||
JS::Anchor<JSString *> anchor(linearStr);
|
||||
bool ok = EvaluateInEnv(cx, env, fp, linearStr->chars(), linearStr->length(),
|
||||
"debugger eval code", 1, &rval);
|
||||
return dbg->newCompletionValue(ac, ok, rval, vp);
|
||||
return dbg->receiveCompletionValue(ac, ok, rval, vp);
|
||||
}
|
||||
|
||||
static JSBool
|
||||
@ -3624,12 +3664,12 @@ ApplyOrCall(JSContext *cx, unsigned argc, Value *vp, ApplyOrCallMode mode)
|
||||
}
|
||||
|
||||
/*
|
||||
* Call the function. Use newCompletionValue to return to the debugger
|
||||
* Call the function. Use receiveCompletionValue to return to the debugger
|
||||
* compartment and populate args.rval().
|
||||
*/
|
||||
Value rval;
|
||||
bool ok = Invoke(cx, thisv, calleev, callArgc, callArgv, &rval);
|
||||
return dbg->newCompletionValue(ac, ok, rval, &args.rval());
|
||||
return dbg->receiveCompletionValue(ac, ok, rval, &args.rval());
|
||||
}
|
||||
|
||||
static JSBool
|
||||
|
@ -331,6 +331,23 @@ class Debugger {
|
||||
/* Store the Debugger.Frame object for the frame fp in *vp. */
|
||||
bool getScriptFrame(JSContext *cx, StackFrame *fp, Value *vp);
|
||||
|
||||
/*
|
||||
* Set |*status| and |*value| to a (JSTrapStatus, Value) pair reflecting a
|
||||
* standard SpiderMonkey call state: a boolean success value |ok|, a return
|
||||
* value |rv|, and a context |cx| that may or may not have an exception set.
|
||||
* If an exception was pending on |cx|, it is cleared (and |ok| is asserted
|
||||
* to be false).
|
||||
*/
|
||||
static void resultToCompletion(JSContext *cx, bool ok, const Value &rv,
|
||||
JSTrapStatus *status, Value *value);
|
||||
|
||||
/*
|
||||
* Set |*result| to a JavaScript completion value corresponding to |status|
|
||||
* and |value|. |value| should be the return value or exception value, not
|
||||
* wrapped as a debuggee value. |cx| must be in the debugger compartment.
|
||||
*/
|
||||
bool newCompletionValue(JSContext *cx, JSTrapStatus status, Value value, Value *result);
|
||||
|
||||
/*
|
||||
* Precondition: we are in the debuggee compartment (ac is entered) and ok
|
||||
* is true if the operation in the debuggee compartment succeeded, false on
|
||||
@ -343,7 +360,7 @@ class Debugger {
|
||||
* pending exception. (This ordinarily returns true even if the ok argument
|
||||
* is false.)
|
||||
*/
|
||||
bool newCompletionValue(AutoCompartment &ac, bool ok, Value val, Value *vp);
|
||||
bool receiveCompletionValue(AutoCompartment &ac, bool ok, Value val, Value *vp);
|
||||
|
||||
/*
|
||||
* Return the Debugger.Script object for |script|, or create a new one if
|
||||
|
Loading…
Reference in New Issue
Block a user