Backed out changeset 6e043a8ce335 (bug 996060) for cgc test failure in testCall.js. r=backout

This commit is contained in:
Sebastian Hengst 2016-05-22 00:00:13 +02:00
Родитель 14189e51f1
Коммит bcf24386ee
11 изменённых файлов: 15 добавлений и 207 удалений

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

@ -4,8 +4,6 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * 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/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "mozilla/ScopeExit.h"
#include "jscompartment.h" #include "jscompartment.h"
#include "jsfriendapi.h" #include "jsfriendapi.h"
#include "jsstr.h" #include "jsstr.h"
@ -204,100 +202,3 @@ BEGIN_TEST(testSavedStacks_selfHostedFrames)
return true; return true;
} }
END_TEST(testSavedStacks_selfHostedFrames) 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_PUBLIC_API(void)
JS_SetPendingException(JSContext* cx, HandleValue value, JS::ExceptionStackBehavior behavior) JS_SetPendingException(JSContext* cx, HandleValue value)
{ {
AssertHeapIsIdle(cx); AssertHeapIsIdle(cx);
CHECK_REQUEST(cx); CHECK_REQUEST(cx);
assertSameCompartment(cx, value); assertSameCompartment(cx, value);
cx->setPendingException(value, behavior); cx->setPendingException(value);
} }
JS_PUBLIC_API(void) JS_PUBLIC_API(void)
@ -6702,11 +6702,3 @@ JS::GCThingTraceKind(void* thing)
MOZ_ASSERT(thing); MOZ_ASSERT(thing);
return static_cast<js::gc::Cell*>(thing)->getTraceKind(); 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) extern JS_PUBLIC_API(bool)
JS_IsExceptionPending(JSContext* cx); JS_IsExceptionPending(JSContext* cx);
@ -5482,8 +5470,7 @@ extern JS_PUBLIC_API(bool)
JS_GetPendingException(JSContext* cx, JS::MutableHandleValue vp); JS_GetPendingException(JSContext* cx, JS::MutableHandleValue vp);
extern JS_PUBLIC_API(void) extern JS_PUBLIC_API(void)
JS_SetPendingException(JSContext* cx, JS::HandleValue v, JS_SetPendingException(JSContext* cx, JS::HandleValue v);
JS::ExceptionStackBehavior behavior = JS::ExceptionStackBehavior::Capture);
extern JS_PUBLIC_API(void) extern JS_PUBLIC_API(void)
JS_ClearPendingException(JSContext* cx); JS_ClearPendingException(JSContext* cx);
@ -5993,32 +5980,6 @@ SetOutOfMemoryCallback(JSRuntime* rt, OutOfMemoryCallback cb, void* data);
extern JS_PUBLIC_API(bool) extern JS_PUBLIC_API(bool)
CaptureCurrentStack(JSContext* cx, MutableHandleObject stackp, unsigned maxFrameCount = 0); 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 * 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 * 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); oomCallback(cx, cx->runtime()->oomCallbackData);
if (cx->options().autoJSAPIOwnsErrorReporting() || JS_IsRunning(cx)) { if (cx->options().autoJSAPIOwnsErrorReporting() || JS_IsRunning(cx)) {
RootedValue v(cx, StringValue(cx->names().outOfMemory)); cx->setPendingException(StringValue(cx->names().outOfMemory));
cx->setPendingException(v);
return; return;
} }
@ -962,7 +961,6 @@ JSContext::JSContext(JSRuntime* rt)
: ExclusiveContext(rt, &rt->mainThread, Context_JS), : ExclusiveContext(rt, &rt->mainThread, Context_JS),
throwing(false), throwing(false),
unwrappedException_(this), unwrappedException_(this),
unwrappedPendingExceptionStack_(this),
options_(), options_(),
overRecursed_(false), overRecursed_(false),
propagatingForcedReturn_(false), propagatingForcedReturn_(false),
@ -999,28 +997,11 @@ JSContext::getPendingException(MutableHandleValue rval)
if (!compartment()->wrap(this, rval)) if (!compartment()->wrap(this, rval))
return false; return false;
assertSameCompartment(this, rval); assertSameCompartment(this, rval);
setPendingException(rval, JS::ExceptionStackBehavior::DoNotCapture); setPendingException(rval);
overRecursed_ = wasOverRecursed; overRecursed_ = wasOverRecursed;
return true; 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 bool
JSContext::isThrowingOutOfMemory() JSContext::isThrowingOutOfMemory()
{ {

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

@ -317,12 +317,6 @@ struct JSContext : public js::ExclusiveContext,
/* Exception state -- the exception member is a GC root by definition. */ /* Exception state -- the exception member is a GC root by definition. */
bool throwing; /* is there a pending exception? */ bool throwing; /* is there a pending exception? */
JS::PersistentRooted<JS::Value> unwrappedException_; /* most-recently-thrown 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. */ /* Per-context options. */
JS::ContextOptions options_; JS::ContextOptions options_;
@ -444,22 +438,17 @@ struct JSContext : public js::ExclusiveContext,
MOZ_MUST_USE MOZ_MUST_USE
bool getPendingException(JS::MutableHandleValue rval); bool getPendingException(JS::MutableHandleValue rval);
MOZ_MUST_USE
bool getPendingExceptionStack(JS::MutableHandleObject stackp);
bool isThrowingOutOfMemory(); bool isThrowingOutOfMemory();
bool isThrowingDebuggeeWouldRun(); bool isThrowingDebuggeeWouldRun();
bool isClosingGenerator(); bool isClosingGenerator();
void setPendingException( void setPendingException(js::Value v);
js::HandleValue v,
JS::ExceptionStackBehavior behavior = JS::ExceptionStackBehavior::Capture);
void clearPendingException() { void clearPendingException() {
throwing = false; throwing = false;
overRecursed_ = false; overRecursed_ = false;
unwrappedException_.setUndefined(); unwrappedException_.setUndefined();
unwrappedPendingExceptionStack_ = nullptr;
} }
bool isThrowingOverRecursed() const { return throwing && overRecursed_; } bool isThrowingOverRecursed() const { return throwing && overRecursed_; }

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

@ -365,18 +365,8 @@ ExclusiveContext::typeLifoAlloc()
} /* namespace js */ } /* namespace js */
inline void 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. // overRecursed_ is set after the fact by ReportOverRecursed.
this->overRecursed_ = false; this->overRecursed_ = false;
this->throwing = true; this->throwing = true;

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

@ -678,7 +678,7 @@ js::ReportUncaughtException(JSContext* cx)
return false; return false;
} }
cx->setPendingException(exn, JS::ExceptionStackBehavior::DoNotCapture); cx->setPendingException(exn);
CallErrorReporter(cx, err.message(), err.report()); CallErrorReporter(cx, err.message(), err.report());
cx->clearPendingException(); cx->clearPendingException();
return true; return true;

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

@ -975,10 +975,8 @@ js::ThrowStopIteration(JSContext* cx)
// StopIteration isn't a constructor, but it's stored in GlobalObject // StopIteration isn't a constructor, but it's stored in GlobalObject
// as one, out of laziness. Hence the GetBuiltinConstructor call here. // as one, out of laziness. Hence the GetBuiltinConstructor call here.
RootedObject ctor(cx); RootedObject ctor(cx);
if (GetBuiltinConstructor(cx, JSProto_StopIteration, &ctor)) { if (GetBuiltinConstructor(cx, JSProto_StopIteration, &ctor))
RootedValue v(cx, ObjectValue(*ctor)); cx->setPendingException(ObjectValue(*ctor));
cx->setPendingException(v);
}
return false; return false;
} }
@ -1252,7 +1250,7 @@ js::UnwindIteratorForException(JSContext* cx, HandleObject obj)
return false; return false;
if (!getOk) if (!getOk)
return false; return false;
cx->setPendingException(v, JS::ExceptionStackBehavior::DoNotCapture); cx->setPendingException(v);
return true; return true;
} }

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

@ -410,10 +410,8 @@ ErrorCopier::~ErrorCopier()
ac.reset(); ac.reset();
Rooted<ErrorObject*> errObj(cx, &exc.toObject().as<ErrorObject>()); Rooted<ErrorObject*> errObj(cx, &exc.toObject().as<ErrorObject>());
JSObject* copyobj = CopyErrorObject(cx, errObj); JSObject* copyobj = CopyErrorObject(cx, errObj);
if (copyobj) { if (copyobj)
RootedValue v(cx, ObjectValue(*copyobj)); cx->setPendingException(ObjectValue(*copyobj));
cx->setPendingException(v, JS::ExceptionStackBehavior::DoNotCapture);
}
} }
} }
} }

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

@ -137,8 +137,7 @@ js::GeneratorThrowOrClose(JSContext* cx, AbstractFramePtr frame, Handle<Generato
MOZ_ASSERT(arg.isUndefined()); MOZ_ASSERT(arg.isUndefined());
} }
RootedValue v(cx, MagicValue(JS_GENERATOR_CLOSING)); cx->setPendingException(MagicValue(JS_GENERATOR_CLOSING));
cx->setPendingException(v);
genObj->setClosing(); genObj->setClosing();
} }
return false; return false;

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

@ -3634,8 +3634,7 @@ CASE(JSOP_RETSUB)
* be necessary, but it seems clearer. And it points out a FIXME: * be necessary, but it seems clearer. And it points out a FIXME:
* 350509, due to Igor Bukanov. * 350509, due to Igor Bukanov.
*/ */
ReservedRooted<Value> v(&rootValue0, rval); cx->setPendingException(rval);
cx->setPendingException(v);
goto error; goto error;
} }
MOZ_ASSERT(rval.isInt32()); MOZ_ASSERT(rval.isInt32());