Backed out changeset 2d5975fd02bd (bug 1288770) for asserting in ErrorResult.h when test test_errorPropagation.html runs. r=backout

This commit is contained in:
Sebastian Hengst 2016-08-16 17:11:22 +02:00
Родитель 3f3894ef5c
Коммит 167156e726
11 изменённых файлов: 123 добавлений и 232 удалений

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

@ -12213,8 +12213,8 @@ nsGlobalWindow::RunTimeoutHandler(nsTimeout* aTimeout,
RefPtr<Function> callback = handler->GetCallback();
if (!callback) {
// Evaluate the timeout expression.
nsAutoString script;
handler->GetHandlerText(script);
const char16_t* script = handler->GetHandlerText();
NS_ASSERTION(script, "timeout has no script nor handler text!");
const char* filename = nullptr;
uint32_t lineNo = 0, dummyColumn = 0;
@ -12228,7 +12228,9 @@ nsGlobalWindow::RunTimeoutHandler(nsTimeout* aTimeout,
options.setFileAndLine(filename, lineNo)
.setVersion(JSVERSION_DEFAULT);
JS::Rooted<JSObject*> global(aes.cx(), FastGetGlobalJSObject());
nsresult rv = nsJSUtils::EvaluateString(aes.cx(), script, global, options);
nsresult rv =
nsJSUtils::EvaluateString(aes.cx(), nsDependentString(script),
global, options);
if (rv == NS_SUCCESS_DOM_SCRIPT_EVALUATION_THREW_UNCATCHABLE) {
abortIntervalHandler = true;
}

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

@ -34,7 +34,7 @@ public:
virtual mozilla::dom::Function *GetCallback() = 0;
// Get the handler text of not a compiled object.
virtual void GetHandlerText(nsAString& aString) = 0;
virtual const char16_t *GetHandlerText() = 0;
// Get the location of the script.
// Note: The memory pointed to by aFileName is owned by the

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

@ -17,7 +17,6 @@
#include "mozilla/Likely.h"
#include <algorithm>
#include "mozilla/dom/FunctionBinding.h"
#include "WorkerPrivate.h"
#include "nsAXPCNativeCallContext.h"
static const char kSetIntervalStr[] = "setInterval";
@ -25,7 +24,6 @@ static const char kSetTimeoutStr[] = "setTimeout";
using namespace mozilla;
using namespace mozilla::dom;
using namespace mozilla::dom::workers;
// Our JS nsIScriptTimeoutHandler implementation.
class nsJSScriptTimeoutHandler final : public nsIScriptTimeoutHandler
@ -44,13 +42,8 @@ public:
nsJSScriptTimeoutHandler(JSContext* aCx, nsGlobalWindow *aWindow,
const nsAString& aExpression, bool* aAllowEval,
ErrorResult& aError);
nsJSScriptTimeoutHandler(JSContext* aCx, WorkerPrivate* aWorkerPrivate,
Function& aFunction,
FallibleTArray<JS::Heap<JS::Value> >& aArguments);
nsJSScriptTimeoutHandler(JSContext* aCx, WorkerPrivate* aWorkerPrivate,
const nsAString& aExpression);
virtual void GetHandlerText(nsAString& aString) override;
virtual const char16_t* GetHandlerText() override;
virtual Function* GetCallback() override
{
return mFunction;
@ -73,10 +66,6 @@ public:
private:
~nsJSScriptTimeoutHandler();
void Init(JSContext* aCx,
FallibleTArray<JS::Heap<JS::Value>>& aArguments);
void Init(JSContext* aCx);
// filename, line number and JS language version string of the
// caller of setTimeout()
nsCString mFileName;
@ -209,7 +198,7 @@ nsJSScriptTimeoutHandler::nsJSScriptTimeoutHandler()
nsJSScriptTimeoutHandler::nsJSScriptTimeoutHandler(JSContext* aCx,
nsGlobalWindow *aWindow,
Function& aFunction,
FallibleTArray<JS::Heap<JS::Value>>& aArguments,
FallibleTArray<JS::Heap<JS::Value> >& aArguments,
ErrorResult& aError)
: mLineNo(0)
, mColumn(0)
@ -222,7 +211,11 @@ nsJSScriptTimeoutHandler::nsJSScriptTimeoutHandler(JSContext* aCx,
return;
}
Init(aCx, aArguments);
mozilla::HoldJSObjects(this);
mArgs.SwapElements(aArguments);
// Get the calling location.
nsJSUtils::GetCallingLocation(aCx, mFileName, &mLineNo, &mColumn);
}
nsJSScriptTimeoutHandler::nsJSScriptTimeoutHandler(JSContext* aCx,
@ -246,34 +239,8 @@ nsJSScriptTimeoutHandler::nsJSScriptTimeoutHandler(JSContext* aCx,
return;
}
Init(aCx);
}
nsJSScriptTimeoutHandler::nsJSScriptTimeoutHandler(JSContext* aCx,
WorkerPrivate* aWorkerPrivate,
Function& aFunction,
FallibleTArray<JS::Heap<JS::Value>>& aArguments)
: mLineNo(0)
, mColumn(0)
, mFunction(&aFunction)
{
MOZ_ASSERT(aWorkerPrivate);
aWorkerPrivate->AssertIsOnWorkerThread();
Init(aCx, aArguments);
}
nsJSScriptTimeoutHandler::nsJSScriptTimeoutHandler(JSContext* aCx,
WorkerPrivate* aWorkerPrivate,
const nsAString& aExpression)
: mLineNo(0)
, mColumn(0)
, mExpr(aExpression)
{
MOZ_ASSERT(aWorkerPrivate);
aWorkerPrivate->AssertIsOnWorkerThread();
Init(aCx);
// Get the calling location.
nsJSUtils::GetCallingLocation(aCx, mFileName, &mLineNo, &mColumn);
}
nsJSScriptTimeoutHandler::~nsJSScriptTimeoutHandler()
@ -281,23 +248,6 @@ nsJSScriptTimeoutHandler::~nsJSScriptTimeoutHandler()
ReleaseJSObjects();
}
void
nsJSScriptTimeoutHandler::Init(JSContext* aCx,
FallibleTArray<JS::Heap<JS::Value>>& aArguments)
{
mozilla::HoldJSObjects(this);
mArgs.SwapElements(aArguments);
Init(aCx);
}
void
nsJSScriptTimeoutHandler::Init(JSContext* aCx)
{
// Get the calling location.
nsJSUtils::GetCallingLocation(aCx, mFileName, &mLineNo, &mColumn);
}
void
nsJSScriptTimeoutHandler::ReleaseJSObjects()
{
@ -308,11 +258,11 @@ nsJSScriptTimeoutHandler::ReleaseJSObjects()
}
}
void
nsJSScriptTimeoutHandler::GetHandlerText(nsAString& aString)
const char16_t *
nsJSScriptTimeoutHandler::GetHandlerText()
{
NS_ASSERTION(!mFunction, "No expression, so no handler text!");
aString = mExpr;
return mExpr.get();
}
already_AddRefed<nsIScriptTimeoutHandler>
@ -345,29 +295,3 @@ NS_CreateJSTimeoutHandler(JSContext* aCx, nsGlobalWindow *aWindow,
return handler.forget();
}
already_AddRefed<nsIScriptTimeoutHandler>
NS_CreateJSTimeoutHandler(JSContext *aCx, WorkerPrivate* aWorkerPrivate,
Function& aFunction,
const Sequence<JS::Value>& aArguments,
ErrorResult& aError)
{
FallibleTArray<JS::Heap<JS::Value>> args;
if (!args.AppendElements(aArguments, fallible)) {
aError.Throw(NS_ERROR_OUT_OF_MEMORY);
return nullptr;
}
RefPtr<nsJSScriptTimeoutHandler> handler =
new nsJSScriptTimeoutHandler(aCx, aWorkerPrivate, aFunction, args);
return handler.forget();
}
already_AddRefed<nsIScriptTimeoutHandler>
NS_CreateJSTimeoutHandler(JSContext* aCx, WorkerPrivate* aWorkerPrivate,
const nsAString& aExpression)
{
RefPtr<nsJSScriptTimeoutHandler> handler =
new nsJSScriptTimeoutHandler(aCx, aWorkerPrivate, aExpression);
return handler.forget();
}

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

@ -784,7 +784,6 @@ skip-if = toolkit == 'android'
skip-if = debug == false
[test_settimeout_extra_arguments.html]
[test_settimeout_inner.html]
[test_setTimeoutWith0.html]
[test_setting_opener.html]
skip-if = (buildapp == 'b2g' && toolkit != 'gonk') #Bug 931116, b2g desktop specific, initial triage
[test_simplecontentpolicy.html]

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

@ -1,22 +0,0 @@
<html>
<head>
<title>Test for setTimeout and strings containing 0</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<script>
var x = 0;
setTimeout("x++; '\x00'; x++;");
setTimeout(function() {
is(x, 2, "We want to see 2 here");
SimpleTest.finish();
});
SimpleTest.waitForExplicitFinish();
</script>
</body>
</html>

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

@ -21,7 +21,6 @@
#include "nsIScriptError.h"
#include "nsIScriptGlobalObject.h"
#include "nsIScriptSecurityManager.h"
#include "nsIScriptTimeoutHandler.h"
#include "nsITabChild.h"
#include "nsITextToSubURI.h"
#include "nsIThreadInternal.h"
@ -2129,7 +2128,8 @@ NS_IMPL_QUERY_INTERFACE(WorkerLoadInfo::InterfaceRequestor, nsIInterfaceRequesto
struct WorkerPrivate::TimeoutInfo
{
TimeoutInfo()
: mId(0), mIsInterval(false), mCanceled(false)
: mTimeoutCallable(JS::UndefinedValue()), mLineNumber(0), mId(0),
mIsInterval(false), mCanceled(false)
{
MOZ_COUNT_CTOR(mozilla::dom::workers::WorkerPrivate::TimeoutInfo);
}
@ -2149,9 +2149,13 @@ struct WorkerPrivate::TimeoutInfo
return mTargetTime < aOther.mTargetTime;
}
nsCOMPtr<nsIScriptTimeoutHandler> mHandler;
JS::Heap<JS::Value> mTimeoutCallable;
nsString mTimeoutString;
nsTArray<JS::Heap<JS::Value> > mExtraArgVals;
mozilla::TimeStamp mTargetTime;
mozilla::TimeDuration mInterval;
nsCString mFilename;
uint32_t mLineNumber;
int32_t mId;
bool mIsInterval;
bool mCanceled;
@ -5172,18 +5176,23 @@ WorkerPrivate::ThawInternal()
}
void
WorkerPrivate::TraverseTimeouts(nsCycleCollectionTraversalCallback& cb)
WorkerPrivate::TraceTimeouts(const TraceCallbacks& aCallbacks,
void* aClosure) const
{
for (uint32_t i = 0; i < mTimeouts.Length(); ++i) {
TimeoutInfo* tmp = mTimeouts[i];
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mHandler)
}
}
AssertIsOnWorkerThread();
void
WorkerPrivate::UnlinkTimeouts()
{
mTimeouts.Clear();
for (uint32_t index = 0; index < mTimeouts.Length(); index++) {
TimeoutInfo* info = mTimeouts[index];
if (info->mTimeoutCallable.isUndefined()) {
continue;
}
aCallbacks.Trace(&info->mTimeoutCallable, "mTimeoutCallable", aClosure);
for (uint32_t index2 = 0; index2 < info->mExtraArgVals.Length(); index2++) {
aCallbacks.Trace(&info->mExtraArgVals[index2], "mExtraArgVals[i]", aClosure);
}
}
}
bool
@ -5972,12 +5981,14 @@ WorkerPrivate::ReportErrorToConsole(const char* aMessage)
int32_t
WorkerPrivate::SetTimeout(JSContext* aCx,
nsIScriptTimeoutHandler* aHandler,
int32_t aTimeout, bool aIsInterval,
dom::Function* aHandler,
const nsAString& aStringHandler,
int32_t aTimeout,
const Sequence<JS::Value>& aArguments,
bool aIsInterval,
ErrorResult& aRv)
{
AssertIsOnWorkerThread();
MOZ_ASSERT(aHandler);
const int32_t timerId = mNextTimeoutId++;
@ -6010,14 +6021,42 @@ WorkerPrivate::SetTimeout(JSContext* aCx,
mNextTimeoutId = 1;
}
newInfo->mHandler = aHandler;
// Take care of the main argument.
if (aHandler) {
newInfo->mTimeoutCallable = JS::ObjectValue(*aHandler->Callable());
}
else if (!aStringHandler.IsEmpty()) {
newInfo->mTimeoutString = aStringHandler;
}
else {
NS_NAMED_LITERAL_STRING(kSetInterval, "setInterval");
NS_NAMED_LITERAL_STRING(kSetTimeout, "setTimeout");
aRv.ThrowTypeError<MSG_USELESS_SETTIMEOUT>(aIsInterval ? kSetInterval
: kSetTimeout);
return 0;
}
// See if any of the optional arguments were passed.
aTimeout = std::max(0, aTimeout);
newInfo->mInterval = TimeDuration::FromMilliseconds(aTimeout);
uint32_t argc = aArguments.Length();
if (argc && !newInfo->mTimeoutCallable.isUndefined()) {
nsTArray<JS::Heap<JS::Value>> extraArgVals(argc);
for (uint32_t index = 0; index < argc; index++) {
extraArgVals.AppendElement(aArguments[index]);
}
newInfo->mExtraArgVals.SwapElements(extraArgVals);
}
newInfo->mTargetTime = TimeStamp::Now() + newInfo->mInterval;
if (!newInfo->mTimeoutString.IsEmpty()) {
if (!nsJSUtils::GetCallingLocation(aCx, newInfo->mFilename, &newInfo->mLineNumber)) {
NS_WARNING("Failed to get calling location!");
}
}
nsAutoPtr<TimeoutInfo>* insertedInfo =
mTimeouts.InsertElementSorted(newInfo.forget(), GetAutoPtrComparator(mTimeouts));
@ -6137,40 +6176,40 @@ WorkerPrivate::RunExpiredTimeouts(JSContext* aCx)
reason = "setTimeout handler";
}
RefPtr<Function> callback = info->mHandler->GetCallback();
if (!callback) {
// scope for the AutoEntryScript, so it comes off the stack before we do
{ // scope for the AutoEntryScript, so it comes off the stack before we do
// Promise::PerformMicroTaskCheckpoint.
AutoEntryScript aes(global, reason, false);
// Evaluate the timeout expression.
nsAutoString script;
info->mHandler->GetHandlerText(script);
const char* filename = nullptr;
uint32_t lineNo = 0, dummyColumn = 0;
info->mHandler->GetLocation(&filename, &lineNo, &dummyColumn);
JS::CompileOptions options(aes.cx());
options.setFileAndLine(filename, lineNo).setNoScriptRval(true);
JS::Rooted<JS::Value> unused(aes.cx());
if (!JS::Evaluate(aes.cx(), options, script.get(),
script.Length(), &unused) &&
!JS_IsExceptionPending(aCx)) {
retval = false;
break;
if (!info->mTimeoutCallable.isUndefined()) {
JS::ExposeValueToActiveJS(info->mTimeoutCallable);
for (uint32_t i = 0; i < info->mExtraArgVals.Length(); ++i) {
JS::ExposeValueToActiveJS(info->mExtraArgVals[i]);
}
JS::Rooted<JS::Value> rval(aCx);
JS::HandleValueArray args =
JS::HandleValueArray::fromMarkedLocation(info->mExtraArgVals.Length(),
info->mExtraArgVals.Elements()->address());
JS::Rooted<JS::Value> callable(aCx, info->mTimeoutCallable);
if (!JS_CallFunctionValue(aCx, global, callable, args, &rval) &&
!JS_IsExceptionPending(aCx)) {
retval = false;
break;
}
}
} else {
ErrorResult rv;
JS::Rooted<JS::Value> ignoredVal(aCx);
callback->Call(GlobalScope(), info->mHandler->GetArgs(), &ignoredVal, rv,
reason);
if (rv.IsUncatchableException()) {
rv.SuppressException();
retval = false;
break;
else {
nsString expression = info->mTimeoutString;
JS::CompileOptions options(aCx);
options.setFileAndLine(info->mFilename.get(), info->mLineNumber)
.setNoScriptRval(true);
JS::Rooted<JS::Value> unused(aCx);
if (!expression.IsEmpty() &&
!JS::Evaluate(aCx, options,
expression.get(), expression.Length(), &unused) &&
!JS_IsExceptionPending(aCx)) {
retval = false;
break;
}
}
}

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

@ -41,7 +41,6 @@ class nsIDocument;
class nsIEventTarget;
class nsIPrincipal;
class nsIScriptContext;
class nsIScriptTimeoutHandler;
class nsISerializable;
class nsIThread;
class nsIThreadInternal;
@ -1073,10 +1072,7 @@ public:
ThawInternal();
void
TraverseTimeouts(nsCycleCollectionTraversalCallback& aCallback);
void
UnlinkTimeouts();
TraceTimeouts(const TraceCallbacks& aCallbacks, void* aClosure) const;
bool
ModifyBusyCountFromWorker(bool aIncrease);
@ -1129,8 +1125,12 @@ public:
ReportErrorToConsole(const char* aMessage);
int32_t
SetTimeout(JSContext* aCx, nsIScriptTimeoutHandler* aHandler,
int32_t aTimeout, bool aIsInterval,
SetTimeout(JSContext* aCx,
Function* aHandler,
const nsAString& aStringHandler,
int32_t aTimeout,
const Sequence<JS::Value>& aArguments,
bool aIsInterval,
ErrorResult& aRv);
void

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

@ -32,7 +32,6 @@
#include "nsIDocument.h"
#include "nsIServiceWorkerManager.h"
#include "nsIScriptTimeoutHandler.h"
#ifdef ANDROID
#include <android/log.h>
@ -52,18 +51,6 @@
#undef PostMessage
#endif
extern already_AddRefed<nsIScriptTimeoutHandler>
NS_CreateJSTimeoutHandler(JSContext* aCx,
mozilla::dom::workers::WorkerPrivate* aWorkerPrivate,
mozilla::dom::Function& aFunction,
const mozilla::dom::Sequence<JS::Value>& aArguments,
mozilla::ErrorResult& aError);
extern already_AddRefed<nsIScriptTimeoutHandler>
NS_CreateJSTimeoutHandler(JSContext* aCx,
mozilla::dom::workers::WorkerPrivate* aWorkerPrivate,
const nsAString& aExpression);
using namespace mozilla;
using namespace mozilla::dom;
USING_WORKERS_NAMESPACE
@ -96,7 +83,6 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(WorkerGlobalScope,
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mIndexedDB)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mCacheStorage)
tmp->TraverseHostObjectURIs(cb);
tmp->mWorkerPrivate->TraverseTimeouts(cb);
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(WorkerGlobalScope,
@ -110,12 +96,13 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(WorkerGlobalScope,
NS_IMPL_CYCLE_COLLECTION_UNLINK(mIndexedDB)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mCacheStorage)
tmp->UnlinkHostObjectURIs();
tmp->mWorkerPrivate->UnlinkTimeouts();
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN_INHERITED(WorkerGlobalScope,
DOMEventTargetHelper)
tmp->mWorkerPrivate->AssertIsOnWorkerThread();
tmp->mWorkerPrivate->TraceTimeouts(aCallbacks, aClosure);
NS_IMPL_CYCLE_COLLECTION_TRACE_END
NS_IMPL_ADDREF_INHERITED(WorkerGlobalScope, DOMEventTargetHelper)
@ -260,14 +247,8 @@ WorkerGlobalScope::SetTimeout(JSContext* aCx,
ErrorResult& aRv)
{
mWorkerPrivate->AssertIsOnWorkerThread();
nsCOMPtr<nsIScriptTimeoutHandler> handler =
NS_CreateJSTimeoutHandler(aCx, mWorkerPrivate, aHandler, aArguments, aRv);
if (NS_WARN_IF(aRv.Failed())) {
return 0;
}
return mWorkerPrivate->SetTimeout(aCx, handler, aTimeout, false, aRv);
return mWorkerPrivate->SetTimeout(aCx, &aHandler, EmptyString(), aTimeout,
aArguments, false, aRv);
}
int32_t
@ -278,10 +259,9 @@ WorkerGlobalScope::SetTimeout(JSContext* aCx,
ErrorResult& aRv)
{
mWorkerPrivate->AssertIsOnWorkerThread();
nsCOMPtr<nsIScriptTimeoutHandler> handler =
NS_CreateJSTimeoutHandler(aCx, mWorkerPrivate, aHandler);
return mWorkerPrivate->SetTimeout(aCx, handler, aTimeout, false, aRv);
Sequence<JS::Value> dummy;
return mWorkerPrivate->SetTimeout(aCx, nullptr, aHandler, aTimeout, dummy,
false, aRv);
}
void
@ -303,13 +283,8 @@ WorkerGlobalScope::SetInterval(JSContext* aCx,
bool isInterval = aTimeout.WasPassed();
int32_t timeout = aTimeout.WasPassed() ? aTimeout.Value() : 0;
nsCOMPtr<nsIScriptTimeoutHandler> handler =
NS_CreateJSTimeoutHandler(aCx, mWorkerPrivate, aHandler, aArguments, aRv);
if (NS_WARN_IF(aRv.Failed())) {
return 0;
}
return mWorkerPrivate->SetTimeout(aCx, handler, timeout, isInterval, aRv);
return mWorkerPrivate->SetTimeout(aCx, &aHandler, EmptyString(), timeout,
aArguments, isInterval, aRv);
}
int32_t
@ -326,9 +301,8 @@ WorkerGlobalScope::SetInterval(JSContext* aCx,
bool isInterval = aTimeout.WasPassed();
int32_t timeout = aTimeout.WasPassed() ? aTimeout.Value() : 0;
nsCOMPtr<nsIScriptTimeoutHandler> handler =
NS_CreateJSTimeoutHandler(aCx, mWorkerPrivate, aHandler);
return mWorkerPrivate->SetTimeout(aCx, handler, timeout, isInterval, aRv);
return mWorkerPrivate->SetTimeout(aCx, nullptr, aHandler, timeout, dummy,
isInterval, aRv);
}
void

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

@ -105,7 +105,6 @@ support-files =
fileapi_chromeScript.js
importScripts_3rdParty_worker.js
worker_bug1278777.js
worker_setTimeoutWith0.js
!/dom/base/test/file_websocket_basic_wsh.py
!/dom/base/test/file_websocket_hello_wsh.py
!/dom/base/test/file_websocket_http_resource.txt
@ -231,4 +230,3 @@ skip-if = buildapp == 'b2g' || toolkit == 'android' #bug 982828
[test_fileReader.html]
[test_navigator_workers_hardwareConcurrency.html]
[test_bug1278777.html]
[test_setTimeoutWith0.html]

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

@ -1,20 +0,0 @@
<html>
<head>
<title>Test for DOM Worker setTimeout and strings containing 0</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<script>
var a = new Worker('worker_setTimeoutWith0.js');
a.onmessage = function(e) {
is(e.data, 2, "We want to see 2 here");
SimpleTest.finish();
}
SimpleTest.waitForExplicitFinish();
</script>
</body>
</html>

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

@ -1,3 +0,0 @@
var x = 0;
setTimeout("x++; '\x00'; x++;");
setTimeout("postMessage(x);");