Back out Bug 810644 part 1 to fix b2g test_closeOnGC.html orange on CLOSED TREE

This commit is contained in:
Boris Zbarsky 2013-04-08 22:56:06 -04:00
Родитель ecb207e1b0
Коммит d95ba48131
5 изменённых файлов: 67 добавлений и 72 удалений

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

@ -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",