зеркало из https://github.com/mozilla/gecko-dev.git
Back out Bug 810644 part 1 to fix b2g test_closeOnGC.html orange on CLOSED TREE
This commit is contained in:
Родитель
ecb207e1b0
Коммит
d95ba48131
|
@ -228,7 +228,6 @@
|
|||
#include "TimeChangeObserver.h"
|
||||
#include "nsPISocketTransportService.h"
|
||||
#include "mozilla/dom/AudioContext.h"
|
||||
#include "mozilla/dom/FunctionBinding.h"
|
||||
|
||||
#ifdef MOZ_WEBSPEECH
|
||||
#include "mozilla/dom/SpeechSynthesis.h"
|
||||
|
@ -1704,12 +1703,8 @@ nsGlobalWindow::UnmarkGrayTimers()
|
|||
timeout;
|
||||
timeout = timeout->getNext()) {
|
||||
if (timeout->mScriptHandler) {
|
||||
Function* f = timeout->mScriptHandler->GetCallback();
|
||||
if (f) {
|
||||
// Callable() already does xpc_UnmarkGrayObject.
|
||||
DebugOnly<JSObject*> o = f->Callable();
|
||||
MOZ_ASSERT(!xpc_IsGrayGCThing(o), "Should have been unmarked");
|
||||
}
|
||||
JSObject* o = timeout->mScriptHandler->GetScriptObject();
|
||||
xpc_UnmarkGrayObject(o);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -10157,8 +10152,8 @@ nsGlobalWindow::RunTimeoutHandler(nsTimeout* aTimeout,
|
|||
}
|
||||
|
||||
nsCOMPtr<nsIScriptTimeoutHandler> handler(timeout->mScriptHandler);
|
||||
nsRefPtr<Function> callback = handler->GetCallback();
|
||||
if (!callback) {
|
||||
JSObject* scriptObject = handler->GetScriptObject();
|
||||
if (!scriptObject) {
|
||||
// Evaluate the timeout expression.
|
||||
const PRUnichar* script = handler->GetHandlerText();
|
||||
NS_ASSERTION(script, "timeout has no script nor handler text!");
|
||||
|
@ -10174,14 +10169,18 @@ nsGlobalWindow::RunTimeoutHandler(nsTimeout* aTimeout,
|
|||
aScx->EvaluateString(nsDependentString(script), *FastGetGlobalJSObject(),
|
||||
options, /*aCoerceToString = */ false, nullptr);
|
||||
} else {
|
||||
// Hold strong ref to ourselves while we call the callback.
|
||||
nsCOMPtr<nsIVariant> dummy;
|
||||
nsCOMPtr<nsISupports> me(static_cast<nsIDOMWindow *>(this));
|
||||
ErrorResult ignored;
|
||||
callback->Call(me, handler->GetArgs(), ignored);
|
||||
aScx->CallEventHandler(me, FastGetGlobalJSObject(),
|
||||
scriptObject, handler->GetArgv(),
|
||||
// XXXmarkh - consider allowing CallEventHandler to
|
||||
// accept nullptr?
|
||||
getter_AddRefs(dummy));
|
||||
|
||||
}
|
||||
|
||||
// We ignore any failures from calling EvaluateString() on the context or
|
||||
// Call() on a Function here since we're in a loop
|
||||
// We ignore any failures from calling EvaluateString() or
|
||||
// CallEventHandler() on the context here since we're in a loop
|
||||
// where we're likely to be running timeouts whose OS timers
|
||||
// didn't fire in time and we don't want to not fire those timers
|
||||
// now just because execution of one timer failed. We can't
|
||||
|
|
|
@ -6,20 +6,11 @@
|
|||
#ifndef nsIScriptTimeoutHandler_h___
|
||||
#define nsIScriptTimeoutHandler_h___
|
||||
|
||||
#include "nsTArray.h"
|
||||
|
||||
namespace JS {
|
||||
class Value;
|
||||
} // namespace JS
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
class Function;
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
class nsIArray;
|
||||
|
||||
#define NS_ISCRIPTTIMEOUTHANDLER_IID \
|
||||
{ 0x53c8e80e, 0xcc78, 0x48bc, \
|
||||
{ 0xba, 0x63, 0x0c, 0xb9, 0xdb, 0xf7, 0x06, 0x34 } }
|
||||
{ 0xcaf520a5, 0x8078, 0x4cba, \
|
||||
{ 0x8a, 0xb9, 0xb6, 0x8a, 0x12, 0x43, 0x4f, 0x05 } }
|
||||
|
||||
/**
|
||||
* Abstraction of the script objects etc required to do timeouts in a
|
||||
|
@ -31,9 +22,10 @@ class nsIScriptTimeoutHandler : public nsISupports
|
|||
public:
|
||||
NS_DECLARE_STATIC_IID_ACCESSOR(NS_ISCRIPTTIMEOUTHANDLER_IID)
|
||||
|
||||
// Get the Function to call. If this returns nullptr, GetHandlerText() will
|
||||
// be called to get the string.
|
||||
virtual mozilla::dom::Function *GetCallback() = 0;
|
||||
// Get a script object for the language suitable for passing back to
|
||||
// the language's context as an event handler. If this returns nullptr,
|
||||
// GetHandlerText() will be called to get the string.
|
||||
virtual JSObject *GetScriptObject() = 0;
|
||||
|
||||
// Get the handler text of not a compiled object.
|
||||
virtual const PRUnichar *GetHandlerText() = 0;
|
||||
|
@ -43,8 +35,9 @@ public:
|
|||
// nsIScriptTimeoutHandler and should not be freed by the caller.
|
||||
virtual void GetLocation(const char **aFileName, uint32_t *aLineNo) = 0;
|
||||
|
||||
// If we have a Function, get the arguments for passing to it.
|
||||
virtual const nsTArray<JS::Value>& GetArgs() = 0;
|
||||
// If a script object, get the argv suitable for passing back to the
|
||||
// script context.
|
||||
virtual nsIArray *GetArgv() = 0;
|
||||
};
|
||||
|
||||
NS_DEFINE_STATIC_IID_ACCESSOR(nsIScriptTimeoutHandler,
|
||||
|
|
|
@ -23,13 +23,10 @@
|
|||
#include "mozilla/Attributes.h"
|
||||
#include "mozilla/Likely.h"
|
||||
#include <algorithm>
|
||||
#include "mozilla/dom/FunctionBinding.h"
|
||||
|
||||
static const char kSetIntervalStr[] = "setInterval";
|
||||
static const char kSetTimeoutStr[] = "setTimeout";
|
||||
|
||||
using namespace mozilla::dom;
|
||||
|
||||
// Our JS nsIScriptTimeoutHandler implementation.
|
||||
class nsJSScriptTimeoutHandler MOZ_FINAL : public nsIScriptTimeoutHandler
|
||||
{
|
||||
|
@ -42,19 +39,16 @@ public:
|
|||
~nsJSScriptTimeoutHandler();
|
||||
|
||||
virtual const PRUnichar *GetHandlerText();
|
||||
virtual Function* GetCallback()
|
||||
{
|
||||
return mFunction;
|
||||
virtual JSObject *GetScriptObject() {
|
||||
return mFunObj;
|
||||
}
|
||||
virtual void GetLocation(const char **aFileName, uint32_t *aLineNo)
|
||||
{
|
||||
virtual void GetLocation(const char **aFileName, uint32_t *aLineNo) {
|
||||
*aFileName = mFileName.get();
|
||||
*aLineNo = mLineNo;
|
||||
}
|
||||
|
||||
virtual const nsTArray<JS::Value>& GetArgs()
|
||||
{
|
||||
return mArgs;
|
||||
virtual nsIArray *GetArgv() {
|
||||
return mArgv;
|
||||
}
|
||||
|
||||
nsresult Init(nsGlobalWindow *aWindow, bool *aIsInterval,
|
||||
|
@ -63,15 +57,18 @@ public:
|
|||
void ReleaseJSObjects();
|
||||
|
||||
private:
|
||||
|
||||
nsCOMPtr<nsIScriptContext> mContext;
|
||||
|
||||
// filename, line number and JS language version string of the
|
||||
// caller of setTimeout()
|
||||
nsCString mFileName;
|
||||
uint32_t mLineNo;
|
||||
nsTArray<JS::Value> mArgs;
|
||||
nsCOMPtr<nsIJSArgArray> mArgv;
|
||||
|
||||
// The JS expression to evaluate or function to call, if !mExpr
|
||||
JSFlatString *mExpr;
|
||||
nsRefPtr<Function> mFunction;
|
||||
JSObject *mFunObj;
|
||||
};
|
||||
|
||||
|
||||
|
@ -90,9 +87,8 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INTERNAL(nsJSScriptTimeoutHandler)
|
|||
name.AppendInt(tmp->mLineNo);
|
||||
name.AppendLiteral("]");
|
||||
}
|
||||
else if (tmp->mFunction) {
|
||||
JSFunction* fun =
|
||||
JS_GetObjectFunction(js::UnwrapObject(tmp->mFunction->Callable()));
|
||||
else if (tmp->mFunObj) {
|
||||
JSFunction* fun = JS_GetObjectFunction(tmp->mFunObj);
|
||||
if (fun && JS_GetFunctionId(fun)) {
|
||||
JSFlatString *funId = JS_ASSERT_STRING_IS_FLAT(JS_GetFunctionId(fun));
|
||||
size_t size = 1 + JS_PutEscapedFlatString(NULL, 0, funId, 0);
|
||||
|
@ -113,15 +109,14 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INTERNAL(nsJSScriptTimeoutHandler)
|
|||
tmp->mRefCnt.get())
|
||||
}
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mFunction)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mContext)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mArgv)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(nsJSScriptTimeoutHandler)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mExpr)
|
||||
for (uint32_t i = 0; i < tmp->mArgs.Length(); ++i) {
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_JSVAL_MEMBER_CALLBACK(mArgs[i])
|
||||
}
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mFunObj)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_END
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsJSScriptTimeoutHandler)
|
||||
|
@ -134,7 +129,8 @@ NS_IMPL_CYCLE_COLLECTING_RELEASE(nsJSScriptTimeoutHandler)
|
|||
|
||||
nsJSScriptTimeoutHandler::nsJSScriptTimeoutHandler() :
|
||||
mLineNo(0),
|
||||
mExpr(nullptr)
|
||||
mExpr(nullptr),
|
||||
mFunObj(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -149,8 +145,7 @@ nsJSScriptTimeoutHandler::ReleaseJSObjects()
|
|||
if (mExpr) {
|
||||
mExpr = nullptr;
|
||||
} else {
|
||||
mFunction = nullptr;
|
||||
mArgs.Clear();
|
||||
mFunObj = nullptr;
|
||||
}
|
||||
NS_DROP_JS_OBJECTS(this, nsJSScriptTimeoutHandler);
|
||||
}
|
||||
|
@ -159,7 +154,8 @@ nsresult
|
|||
nsJSScriptTimeoutHandler::Init(nsGlobalWindow *aWindow, bool *aIsInterval,
|
||||
int32_t *aInterval)
|
||||
{
|
||||
if (!aWindow->GetContextInternal() || !aWindow->FastGetGlobalJSObject()) {
|
||||
mContext = aWindow->GetContextInternal();
|
||||
if (!mContext) {
|
||||
// This window was already closed, or never properly initialized,
|
||||
// don't let a timer be scheduled on such a window.
|
||||
|
||||
|
@ -293,28 +289,33 @@ nsJSScriptTimeoutHandler::Init(nsGlobalWindow *aWindow, bool *aIsInterval,
|
|||
} else if (funobj) {
|
||||
NS_HOLD_JS_OBJECTS(this, nsJSScriptTimeoutHandler);
|
||||
|
||||
bool ok;
|
||||
mFunction = new Function(cx, aWindow->FastGetGlobalJSObject(), funobj, &ok);
|
||||
if (!ok) {
|
||||
NS_DROP_JS_OBJECTS(this, nsJSScriptTimeoutHandler);
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
mFunObj = funobj;
|
||||
|
||||
// Create our arg array. argc is the number of arguments passed
|
||||
// to setTimeout or setInterval; the first two are our callback
|
||||
// and the delay, so only arguments after that need to go in our
|
||||
// array.
|
||||
nsCOMPtr<nsIJSArgArray> array;
|
||||
// std::max(argc - 2, 0) wouldn't work right because argc is unsigned.
|
||||
uint32_t argCount = std::max(argc, 2u) - 2;
|
||||
FallibleTArray<JS::Value> args;
|
||||
if (!args.SetCapacity(argCount)) {
|
||||
// No need to drop here, since we already have a non-null mFunction
|
||||
rv = NS_CreateJSArgv(cx, std::max(argc, 2u) - 2, nullptr,
|
||||
getter_AddRefs(array));
|
||||
if (NS_FAILED(rv)) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
for (uint32_t idx = 0; idx < argCount; ++idx) {
|
||||
*args.AppendElement() = argv[idx + 2];
|
||||
|
||||
uint32_t dummy;
|
||||
jsval *jsargv = nullptr;
|
||||
array->GetArgs(&dummy, reinterpret_cast<void **>(&jsargv));
|
||||
|
||||
// jsargv might be null if we have argc <= 2
|
||||
if (jsargv) {
|
||||
for (int32_t i = 2; (uint32_t)i < argc; ++i) {
|
||||
jsargv[i - 2] = argv[i];
|
||||
}
|
||||
} else {
|
||||
NS_ASSERTION(argc <= 2, "Why do we have no jsargv when we have arguments?");
|
||||
}
|
||||
args.SwapElements(mArgs);
|
||||
mArgv = array;
|
||||
} else {
|
||||
NS_WARNING("No func and no expr - why are we here?");
|
||||
}
|
||||
|
@ -335,13 +336,17 @@ nsresult NS_CreateJSTimeoutHandler(nsGlobalWindow *aWindow,
|
|||
nsIScriptTimeoutHandler **aRet)
|
||||
{
|
||||
*aRet = nullptr;
|
||||
nsRefPtr<nsJSScriptTimeoutHandler> handler = new nsJSScriptTimeoutHandler();
|
||||
nsJSScriptTimeoutHandler *handler = new nsJSScriptTimeoutHandler();
|
||||
if (!handler)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
nsresult rv = handler->Init(aWindow, aIsInterval, aInterval);
|
||||
if (NS_FAILED(rv)) {
|
||||
delete handler;
|
||||
return rv;
|
||||
}
|
||||
|
||||
handler.forget(aRet);
|
||||
NS_ADDREF(*aRet = handler);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
|
@ -14,7 +14,6 @@ interface DummyInterface {
|
|||
CFStateChangeEventDict cfstateChangeEvent();
|
||||
USSDReceivedEventDict ussdReceivedEvent();
|
||||
InspectorRGBTriple rgbTriple();
|
||||
Function getFunction();
|
||||
};
|
||||
|
||||
interface DummyInterfaceWorkers {
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"></script>
|
||||
<script><![CDATA[
|
||||
var is = window.opener.SimpleTest.is;
|
||||
window.onerror = window.opener.onerror;
|
||||
|
||||
const anchorPositions =
|
||||
[ "before_start", "before_end", "after_start", "after_end",
|
||||
|
|
Загрузка…
Ссылка в новой задаче