зеркало из https://github.com/mozilla/gecko-dev.git
Backed out changeset 6e043a8ce335 (bug 996060) for cgc test failure in testCall.js. r=backout
This commit is contained in:
Родитель
14189e51f1
Коммит
bcf24386ee
|
@ -4,8 +4,6 @@
|
|||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "mozilla/ScopeExit.h"
|
||||
|
||||
#include "jscompartment.h"
|
||||
#include "jsfriendapi.h"
|
||||
#include "jsstr.h"
|
||||
|
@ -204,100 +202,3 @@ BEGIN_TEST(testSavedStacks_selfHostedFrames)
|
|||
return true;
|
||||
}
|
||||
END_TEST(testSavedStacks_selfHostedFrames)
|
||||
|
||||
BEGIN_TEST(test_JS_GetPendingExceptionStack)
|
||||
{
|
||||
CHECK(js::DefineTestingFunctions(cx, global, false, false));
|
||||
|
||||
const char* sourceText =
|
||||
// 1 2 3
|
||||
// 123456789012345678901234567890123456789
|
||||
"(function one() { \n" // 1
|
||||
" (function two() { \n" // 2
|
||||
" (function three() { \n" // 3
|
||||
" throw 5; \n" // 4
|
||||
" }()); \n" // 5
|
||||
" }()); \n" // 6
|
||||
"}()) \n"; // 7
|
||||
|
||||
JS::RootedValue val(cx);
|
||||
JS::CompileOptions opts(cx);
|
||||
opts.setFileAndLine("filename.js", 1U);
|
||||
JS::ContextOptionsRef(cx).setDontReportUncaught(true);
|
||||
JSContext* context = cx;
|
||||
auto resetReportUncaught = mozilla::MakeScopeExit([=]() {
|
||||
JS::ContextOptionsRef(context).setDontReportUncaught(false);
|
||||
});
|
||||
bool ok = JS::Evaluate(cx, opts, sourceText, strlen(sourceText), &val);
|
||||
|
||||
CHECK(!ok);
|
||||
CHECK(JS_IsExceptionPending(cx));
|
||||
CHECK(val.isUndefined());
|
||||
|
||||
JS::RootedObject stack(cx);
|
||||
CHECK(JS::GetPendingExceptionStack(cx, &stack));
|
||||
CHECK(stack);
|
||||
CHECK(stack->is<js::SavedFrame>());
|
||||
JS::Rooted<js::SavedFrame*> savedFrameStack(cx, &stack->as<SavedFrame>());
|
||||
|
||||
JS_GetPendingException(cx, &val);
|
||||
CHECK(val.isInt32());
|
||||
CHECK(val.toInt32() == 5);
|
||||
|
||||
struct {
|
||||
uint32_t line;
|
||||
uint32_t column;
|
||||
const char* source;
|
||||
const char* functionDisplayName;
|
||||
} expected[] = {
|
||||
{ 4, 7, "filename.js", "three" },
|
||||
{ 3, 15, "filename.js", "two" },
|
||||
{ 2, 13, "filename.js", "one" },
|
||||
{ 1, 11, "filename.js", nullptr }
|
||||
};
|
||||
|
||||
size_t i = 0;
|
||||
for (JS::Handle<js::SavedFrame*> frame : js::SavedFrame::RootedRange(cx, savedFrameStack)) {
|
||||
CHECK(i < 4);
|
||||
|
||||
// Line
|
||||
uint32_t line = 123;
|
||||
JS::SavedFrameResult result = JS::GetSavedFrameLine(cx, frame, &line,
|
||||
JS::SavedFrameSelfHosted::Exclude);
|
||||
CHECK(result == JS::SavedFrameResult::Ok);
|
||||
CHECK_EQUAL(line, expected[i].line);
|
||||
|
||||
// Column
|
||||
uint32_t column = 123;
|
||||
result = JS::GetSavedFrameColumn(cx, frame, &column,
|
||||
JS::SavedFrameSelfHosted::Exclude);
|
||||
CHECK(result == JS::SavedFrameResult::Ok);
|
||||
CHECK_EQUAL(column, expected[i].column);
|
||||
|
||||
// Source
|
||||
JS::RootedString str(cx);
|
||||
result = JS::GetSavedFrameSource(cx, frame, &str, JS::SavedFrameSelfHosted::Exclude);
|
||||
CHECK(result == JS::SavedFrameResult::Ok);
|
||||
JSLinearString* linear = str->ensureLinear(cx);
|
||||
CHECK(linear);
|
||||
CHECK(js::StringEqualsAscii(linear, expected[i].source));
|
||||
|
||||
// Function display name
|
||||
result = JS::GetSavedFrameFunctionDisplayName(cx, frame, &str,
|
||||
JS::SavedFrameSelfHosted::Exclude);
|
||||
CHECK(result == JS::SavedFrameResult::Ok);
|
||||
if (auto expectedName = expected[i].functionDisplayName) {
|
||||
CHECK(str);
|
||||
linear = str->ensureLinear(cx);
|
||||
CHECK(linear);
|
||||
CHECK(js::StringEqualsAscii(linear, expectedName));
|
||||
} else {
|
||||
CHECK(!str);
|
||||
}
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
END_TEST(test_JS_GetPendingExceptionStack)
|
||||
|
|
|
@ -5994,12 +5994,12 @@ JS_GetPendingException(JSContext* cx, MutableHandleValue vp)
|
|||
}
|
||||
|
||||
JS_PUBLIC_API(void)
|
||||
JS_SetPendingException(JSContext* cx, HandleValue value, JS::ExceptionStackBehavior behavior)
|
||||
JS_SetPendingException(JSContext* cx, HandleValue value)
|
||||
{
|
||||
AssertHeapIsIdle(cx);
|
||||
CHECK_REQUEST(cx);
|
||||
assertSameCompartment(cx, value);
|
||||
cx->setPendingException(value, behavior);
|
||||
cx->setPendingException(value);
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(void)
|
||||
|
@ -6702,11 +6702,3 @@ JS::GCThingTraceKind(void* thing)
|
|||
MOZ_ASSERT(thing);
|
||||
return static_cast<js::gc::Cell*>(thing)->getTraceKind();
|
||||
}
|
||||
|
||||
|
||||
JS_PUBLIC_API(bool)
|
||||
JS::GetPendingExceptionStack(JSContext* cx, JS::MutableHandleObject stackp)
|
||||
{
|
||||
MOZ_ASSERT(cx);
|
||||
return cx->getPendingExceptionStack(stackp);
|
||||
}
|
||||
|
|
|
@ -5463,18 +5463,6 @@ JS_GetRegExpSource(JSContext* cx, JS::HandleObject obj);
|
|||
|
||||
/************************************************************************/
|
||||
|
||||
namespace JS {
|
||||
|
||||
enum class ExceptionStackBehavior: bool {
|
||||
// Capture the current JS stack when setting the exception. It may be
|
||||
// retrieved by JS::GetPendingExceptionStack.
|
||||
Capture,
|
||||
// Do not capture any stack.
|
||||
DoNotCapture
|
||||
};
|
||||
|
||||
} // namespace JS
|
||||
|
||||
extern JS_PUBLIC_API(bool)
|
||||
JS_IsExceptionPending(JSContext* cx);
|
||||
|
||||
|
@ -5482,8 +5470,7 @@ extern JS_PUBLIC_API(bool)
|
|||
JS_GetPendingException(JSContext* cx, JS::MutableHandleValue vp);
|
||||
|
||||
extern JS_PUBLIC_API(void)
|
||||
JS_SetPendingException(JSContext* cx, JS::HandleValue v,
|
||||
JS::ExceptionStackBehavior behavior = JS::ExceptionStackBehavior::Capture);
|
||||
JS_SetPendingException(JSContext* cx, JS::HandleValue v);
|
||||
|
||||
extern JS_PUBLIC_API(void)
|
||||
JS_ClearPendingException(JSContext* cx);
|
||||
|
@ -5993,32 +5980,6 @@ SetOutOfMemoryCallback(JSRuntime* rt, OutOfMemoryCallback cb, void* data);
|
|||
extern JS_PUBLIC_API(bool)
|
||||
CaptureCurrentStack(JSContext* cx, MutableHandleObject stackp, unsigned maxFrameCount = 0);
|
||||
|
||||
/**
|
||||
* Get the `SavedFrame` stack object captured when the pending exception was set
|
||||
* on the `JSContext`. This will correspond to a 'throw' statement in JS, or the
|
||||
* state at which `JS_SetPendingException` is called by VM code or a JSAPI
|
||||
* consumer.
|
||||
*
|
||||
* This is not the same stack as `e.stack` when `e` is an `Error` object. (That
|
||||
* would be `JS::ExceptionStackOrNull`). That stack is the stack when the
|
||||
* `Error` object was created, which could be much earlier than when it is
|
||||
* thrown.
|
||||
*
|
||||
* Note that it is possible that `stackp` is null with a `true` return value
|
||||
* when any of the following situations:
|
||||
* - There is no pending exception (and hence no stack for the pending
|
||||
* exception).
|
||||
* - The exception was set on the `cx` when there was no JS on
|
||||
* the stack (and therefore the stack is correctly empty).
|
||||
* - The exception being thrown is an out of memory exception.
|
||||
* a stack via `JS::ExceptionStackBehavior::DoNotCapture`.
|
||||
*
|
||||
* If `stackp` is non-null after this call, it is guaranteed to be in the same
|
||||
* compartment that `cx` is in.
|
||||
*/
|
||||
extern JS_PUBLIC_API(MOZ_MUST_USE bool)
|
||||
GetPendingExceptionStack(JSContext* cx, MutableHandleObject stackp);
|
||||
|
||||
/*
|
||||
* This is a utility function for preparing an async stack to be used
|
||||
* by some other object. This may be used when you need to treat a
|
||||
|
|
|
@ -302,8 +302,7 @@ js::ReportOutOfMemory(ExclusiveContext* cxArg)
|
|||
oomCallback(cx, cx->runtime()->oomCallbackData);
|
||||
|
||||
if (cx->options().autoJSAPIOwnsErrorReporting() || JS_IsRunning(cx)) {
|
||||
RootedValue v(cx, StringValue(cx->names().outOfMemory));
|
||||
cx->setPendingException(v);
|
||||
cx->setPendingException(StringValue(cx->names().outOfMemory));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -962,7 +961,6 @@ JSContext::JSContext(JSRuntime* rt)
|
|||
: ExclusiveContext(rt, &rt->mainThread, Context_JS),
|
||||
throwing(false),
|
||||
unwrappedException_(this),
|
||||
unwrappedPendingExceptionStack_(this),
|
||||
options_(),
|
||||
overRecursed_(false),
|
||||
propagatingForcedReturn_(false),
|
||||
|
@ -999,28 +997,11 @@ JSContext::getPendingException(MutableHandleValue rval)
|
|||
if (!compartment()->wrap(this, rval))
|
||||
return false;
|
||||
assertSameCompartment(this, rval);
|
||||
setPendingException(rval, JS::ExceptionStackBehavior::DoNotCapture);
|
||||
setPendingException(rval);
|
||||
overRecursed_ = wasOverRecursed;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
JSContext::getPendingExceptionStack(MutableHandleObject stackp)
|
||||
{
|
||||
if (!unwrappedPendingExceptionStack_) {
|
||||
stackp.set(nullptr);
|
||||
return true;
|
||||
}
|
||||
|
||||
stackp.set(unwrappedPendingExceptionStack_);
|
||||
if (!compartment()->wrap(this, stackp)) {
|
||||
stackp.set(nullptr);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
JSContext::isThrowingOutOfMemory()
|
||||
{
|
||||
|
|
|
@ -317,12 +317,6 @@ struct JSContext : public js::ExclusiveContext,
|
|||
/* Exception state -- the exception member is a GC root by definition. */
|
||||
bool throwing; /* is there a pending exception? */
|
||||
JS::PersistentRooted<JS::Value> unwrappedException_; /* most-recently-thrown exception */
|
||||
/*
|
||||
* The SavedFrame stack captured when we set a pending exception, and
|
||||
* cleared out when we clear pending exceptions.
|
||||
*/
|
||||
JS::PersistentRooted<js::SavedFrame*> unwrappedPendingExceptionStack_;
|
||||
|
||||
|
||||
/* Per-context options. */
|
||||
JS::ContextOptions options_;
|
||||
|
@ -444,22 +438,17 @@ struct JSContext : public js::ExclusiveContext,
|
|||
|
||||
MOZ_MUST_USE
|
||||
bool getPendingException(JS::MutableHandleValue rval);
|
||||
MOZ_MUST_USE
|
||||
bool getPendingExceptionStack(JS::MutableHandleObject stackp);
|
||||
|
||||
bool isThrowingOutOfMemory();
|
||||
bool isThrowingDebuggeeWouldRun();
|
||||
bool isClosingGenerator();
|
||||
|
||||
void setPendingException(
|
||||
js::HandleValue v,
|
||||
JS::ExceptionStackBehavior behavior = JS::ExceptionStackBehavior::Capture);
|
||||
void setPendingException(js::Value v);
|
||||
|
||||
void clearPendingException() {
|
||||
throwing = false;
|
||||
overRecursed_ = false;
|
||||
unwrappedException_.setUndefined();
|
||||
unwrappedPendingExceptionStack_ = nullptr;
|
||||
}
|
||||
|
||||
bool isThrowingOverRecursed() const { return throwing && overRecursed_; }
|
||||
|
|
|
@ -365,18 +365,8 @@ ExclusiveContext::typeLifoAlloc()
|
|||
} /* namespace js */
|
||||
|
||||
inline void
|
||||
JSContext::setPendingException(js::HandleValue v, JS::ExceptionStackBehavior behavior)
|
||||
JSContext::setPendingException(js::Value v)
|
||||
{
|
||||
if (behavior == JS::ExceptionStackBehavior::Capture &&
|
||||
compartment() &&
|
||||
v != StringValue(names().outOfMemory))
|
||||
{
|
||||
js::RootedSavedFrame stack(this);
|
||||
if (!compartment()->savedStacks().saveCurrentStack(this, &stack))
|
||||
clearPendingException();
|
||||
unwrappedPendingExceptionStack_ = stack;
|
||||
}
|
||||
|
||||
// overRecursed_ is set after the fact by ReportOverRecursed.
|
||||
this->overRecursed_ = false;
|
||||
this->throwing = true;
|
||||
|
|
|
@ -678,7 +678,7 @@ js::ReportUncaughtException(JSContext* cx)
|
|||
return false;
|
||||
}
|
||||
|
||||
cx->setPendingException(exn, JS::ExceptionStackBehavior::DoNotCapture);
|
||||
cx->setPendingException(exn);
|
||||
CallErrorReporter(cx, err.message(), err.report());
|
||||
cx->clearPendingException();
|
||||
return true;
|
||||
|
|
|
@ -975,10 +975,8 @@ js::ThrowStopIteration(JSContext* cx)
|
|||
// StopIteration isn't a constructor, but it's stored in GlobalObject
|
||||
// as one, out of laziness. Hence the GetBuiltinConstructor call here.
|
||||
RootedObject ctor(cx);
|
||||
if (GetBuiltinConstructor(cx, JSProto_StopIteration, &ctor)) {
|
||||
RootedValue v(cx, ObjectValue(*ctor));
|
||||
cx->setPendingException(v);
|
||||
}
|
||||
if (GetBuiltinConstructor(cx, JSProto_StopIteration, &ctor))
|
||||
cx->setPendingException(ObjectValue(*ctor));
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -1252,7 +1250,7 @@ js::UnwindIteratorForException(JSContext* cx, HandleObject obj)
|
|||
return false;
|
||||
if (!getOk)
|
||||
return false;
|
||||
cx->setPendingException(v, JS::ExceptionStackBehavior::DoNotCapture);
|
||||
cx->setPendingException(v);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -410,10 +410,8 @@ ErrorCopier::~ErrorCopier()
|
|||
ac.reset();
|
||||
Rooted<ErrorObject*> errObj(cx, &exc.toObject().as<ErrorObject>());
|
||||
JSObject* copyobj = CopyErrorObject(cx, errObj);
|
||||
if (copyobj) {
|
||||
RootedValue v(cx, ObjectValue(*copyobj));
|
||||
cx->setPendingException(v, JS::ExceptionStackBehavior::DoNotCapture);
|
||||
}
|
||||
if (copyobj)
|
||||
cx->setPendingException(ObjectValue(*copyobj));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -137,8 +137,7 @@ js::GeneratorThrowOrClose(JSContext* cx, AbstractFramePtr frame, Handle<Generato
|
|||
MOZ_ASSERT(arg.isUndefined());
|
||||
}
|
||||
|
||||
RootedValue v(cx, MagicValue(JS_GENERATOR_CLOSING));
|
||||
cx->setPendingException(v);
|
||||
cx->setPendingException(MagicValue(JS_GENERATOR_CLOSING));
|
||||
genObj->setClosing();
|
||||
}
|
||||
return false;
|
||||
|
|
|
@ -3634,8 +3634,7 @@ CASE(JSOP_RETSUB)
|
|||
* be necessary, but it seems clearer. And it points out a FIXME:
|
||||
* 350509, due to Igor Bukanov.
|
||||
*/
|
||||
ReservedRooted<Value> v(&rootValue0, rval);
|
||||
cx->setPendingException(v);
|
||||
cx->setPendingException(rval);
|
||||
goto error;
|
||||
}
|
||||
MOZ_ASSERT(rval.isInt32());
|
||||
|
|
Загрузка…
Ссылка в новой задаче