1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include "TimeoutHandler.h"
9 #include "mozilla/Assertions.h"
10 #include "mozilla/HoldDropJSObjects.h"
11 #include "nsJSUtils.h"
13 namespace mozilla::dom
{
15 //-----------------------------------------------------------------------------
17 //-----------------------------------------------------------------------------
19 TimeoutHandler::TimeoutHandler(JSContext
* aCx
) : TimeoutHandler() {
20 nsJSUtils::GetCallingLocation(aCx
, mFileName
, &mLineNo
, &mColumn
);
23 bool TimeoutHandler::Call(const char* /* unused */) { return false; }
25 void TimeoutHandler::GetLocation(const char** aFileName
, uint32_t* aLineNo
,
27 *aFileName
= mFileName
.get();
32 void TimeoutHandler::GetDescription(nsACString
& aOutString
) {
33 aOutString
.AppendPrintf("<generic handler> (%s:%d:%d)", mFileName
.get(),
37 //-----------------------------------------------------------------------------
38 // ScriptTimeoutHandler
39 //-----------------------------------------------------------------------------
41 ScriptTimeoutHandler::ScriptTimeoutHandler(JSContext
* aCx
,
42 nsIGlobalObject
* aGlobal
,
43 const nsAString
& aExpression
)
44 : TimeoutHandler(aCx
), mGlobal(aGlobal
), mExpr(aExpression
) {}
46 NS_IMPL_CYCLE_COLLECTION_CLASS(ScriptTimeoutHandler
)
48 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(ScriptTimeoutHandler
)
49 NS_IMPL_CYCLE_COLLECTION_UNLINK(mGlobal
)
50 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
52 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INTERNAL(ScriptTimeoutHandler
)
53 if (MOZ_UNLIKELY(cb
.WantDebugInfo())) {
54 nsAutoCString
name("ScriptTimeoutHandler");
55 name
.AppendLiteral(" [");
56 name
.Append(tmp
->mFileName
);
58 name
.AppendInt(tmp
->mLineNo
);
60 name
.AppendInt(tmp
->mColumn
);
62 cb
.DescribeRefCountedNode(tmp
->mRefCnt
.get(), name
.get());
64 NS_IMPL_CYCLE_COLLECTION_DESCRIBE(ScriptTimeoutHandler
, tmp
->mRefCnt
.get())
67 // If we need to make TimeoutHandler CCed, don't call its Traverse method
68 // here, otherwise we ends up report same object twice if logging is on. See
69 // https://bugzilla.mozilla.org/show_bug.cgi?id=1588208.
71 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mGlobal
)
72 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
74 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(ScriptTimeoutHandler
)
75 NS_INTERFACE_MAP_ENTRY(nsISupports
)
78 NS_IMPL_CYCLE_COLLECTING_ADDREF(ScriptTimeoutHandler
)
79 NS_IMPL_CYCLE_COLLECTING_RELEASE(ScriptTimeoutHandler
)
81 void ScriptTimeoutHandler::GetDescription(nsACString
& aOutString
) {
82 if (mExpr
.Length() > 15) {
83 aOutString
.AppendPrintf(
84 "<string handler (truncated): \"%s...\"> (%s:%d:%d)",
85 NS_ConvertUTF16toUTF8(Substring(mExpr
, 0, 13)).get(), mFileName
.get(),
88 aOutString
.AppendPrintf("<string handler: \"%s\"> (%s:%d:%d)",
89 NS_ConvertUTF16toUTF8(mExpr
).get(), mFileName
.get(),
94 //-----------------------------------------------------------------------------
95 // CallbackTimeoutHandler
96 //-----------------------------------------------------------------------------
98 CallbackTimeoutHandler::CallbackTimeoutHandler(
99 JSContext
* aCx
, nsIGlobalObject
* aGlobal
, Function
* aFunction
,
100 nsTArray
<JS::Heap
<JS::Value
>>&& aArguments
)
101 : TimeoutHandler(aCx
), mGlobal(aGlobal
), mFunction(aFunction
) {
102 mozilla::HoldJSObjects(this);
103 mArgs
= std::move(aArguments
);
106 NS_IMPL_CYCLE_COLLECTION_CLASS(CallbackTimeoutHandler
)
108 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(CallbackTimeoutHandler
)
109 NS_IMPL_CYCLE_COLLECTION_UNLINK(mGlobal
)
110 NS_IMPL_CYCLE_COLLECTION_UNLINK(mFunction
)
111 tmp
->ReleaseJSObjects();
112 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
114 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INTERNAL(CallbackTimeoutHandler
)
115 if (MOZ_UNLIKELY(cb
.WantDebugInfo())) {
116 nsAutoCString
name("CallbackTimeoutHandler");
117 JSObject
* obj
= tmp
->mFunction
->CallablePreserveColor();
119 JS_GetObjectFunction(js::UncheckedUnwrapWithoutExpose(obj
));
120 if (fun
&& JS_GetMaybePartialFunctionId(fun
)) {
121 JSLinearString
* funId
=
122 JS_ASSERT_STRING_IS_LINEAR(JS_GetMaybePartialFunctionId(fun
));
123 size_t size
= 1 + JS_PutEscapedLinearString(nullptr, 0, funId
, 0);
124 char* funIdName
= new char[size
];
126 JS_PutEscapedLinearString(funIdName
, size
, funId
, 0);
127 name
.AppendLiteral(" [");
128 name
.Append(funIdName
);
133 cb
.DescribeRefCountedNode(tmp
->mRefCnt
.get(), name
.get());
135 NS_IMPL_CYCLE_COLLECTION_DESCRIBE(CallbackTimeoutHandler
,
139 // If we need to make TimeoutHandler CCed, don't call its Traverse method
140 // here, otherwise we ends up report same object twice if logging is on. See
141 // https://bugzilla.mozilla.org/show_bug.cgi?id=1588208.
143 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mGlobal
)
144 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mFunction
)
145 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
147 NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(CallbackTimeoutHandler
)
148 for (size_t i
= 0; i
< tmp
->mArgs
.Length(); ++i
) {
149 NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mArgs
[i
])
151 NS_IMPL_CYCLE_COLLECTION_TRACE_END
153 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(CallbackTimeoutHandler
)
154 NS_INTERFACE_MAP_ENTRY(nsISupports
)
157 NS_IMPL_CYCLE_COLLECTING_ADDREF(CallbackTimeoutHandler
)
158 NS_IMPL_CYCLE_COLLECTING_RELEASE(CallbackTimeoutHandler
)
160 void CallbackTimeoutHandler::ReleaseJSObjects() {
162 mozilla::DropJSObjects(this);
165 bool CallbackTimeoutHandler::Call(const char* aExecutionReason
) {
166 IgnoredErrorResult rv
;
167 JS::Rooted
<JS::Value
> ignoredVal(RootingCx());
168 MOZ_KnownLive(mFunction
)->Call(MOZ_KnownLive(mGlobal
), mArgs
, &ignoredVal
, rv
,
170 return !rv
.IsUncatchableException();
173 void CallbackTimeoutHandler::MarkForCC() { mFunction
->MarkForCC(); }
175 void CallbackTimeoutHandler::GetDescription(nsACString
& aOutString
) {
176 mFunction
->GetDescription(aOutString
);
179 } // namespace mozilla::dom