1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2; -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 #include "nsJSInspector.h"
7 #include "mozilla/HoldDropJSObjects.h"
8 #include "mozilla/SpinEventLoopUntil.h"
9 #include "mozilla/dom/ScriptSettings.h"
12 #define JSINSPECTOR_CONTRACTID "@mozilla.org/jsinspector;1"
14 #define JSINSPECTOR_CID \
16 0xec5aa99c, 0x7abb, 0x4142, { \
17 0xac, 0x5f, 0xaa, 0xb2, 0x41, 0x9e, 0x38, 0xe2 \
22 namespace jsinspector
{
24 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsJSInspector
)
25 NS_INTERFACE_MAP_ENTRY(nsISupports
)
26 NS_INTERFACE_MAP_ENTRY(nsIJSInspector
)
29 NS_IMPL_CYCLE_COLLECTION_CLASS(nsJSInspector
)
31 NS_IMPL_CYCLE_COLLECTING_ADDREF(nsJSInspector
)
32 NS_IMPL_CYCLE_COLLECTING_RELEASE(nsJSInspector
)
34 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsJSInspector
)
35 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
37 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsJSInspector
)
38 tmp
->mRequestors
.Clear();
39 tmp
->mLastRequestor
= JS::NullValue();
40 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
42 NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(nsJSInspector
)
43 for (uint32_t i
= 0; i
< tmp
->mRequestors
.Length(); ++i
) {
44 NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mRequestors
[i
])
46 NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mLastRequestor
)
47 NS_IMPL_CYCLE_COLLECTION_TRACE_END
49 nsJSInspector::nsJSInspector()
50 : mNestedLoopLevel(0), mRequestors(1), mLastRequestor(JS::NullValue()) {}
52 nsJSInspector::~nsJSInspector() {
53 MOZ_ASSERT(mRequestors
.Length() == 0);
54 MOZ_ASSERT(mLastRequestor
.isNull());
55 mozilla::DropJSObjects(this);
59 nsJSInspector::EnterNestedEventLoop(JS::Handle
<JS::Value
> requestor
,
63 mLastRequestor
= requestor
;
64 mRequestors
.AppendElement(requestor
);
65 mozilla::HoldJSObjects(this);
67 mozilla::dom::AutoNoJSAPI nojsapi
;
69 uint32_t nestLevel
= ++mNestedLoopLevel
;
70 if (!SpinEventLoopUntil("nsJSInspector::EnterNestedEventLoop"_ns
,
71 [&]() { return mNestedLoopLevel
< nestLevel
; })) {
72 rv
= NS_ERROR_UNEXPECTED
;
75 NS_ASSERTION(mNestedLoopLevel
<= nestLevel
,
76 "nested event didn't unwind properly");
78 if (mNestedLoopLevel
== nestLevel
) {
79 mLastRequestor
= mRequestors
.ElementAt(--mNestedLoopLevel
);
82 *out
= mNestedLoopLevel
;
87 nsJSInspector::ExitNestedEventLoop(uint32_t* out
) {
88 if (mNestedLoopLevel
> 0) {
89 mRequestors
.RemoveElementAt(--mNestedLoopLevel
);
90 if (mNestedLoopLevel
> 0)
91 mLastRequestor
= mRequestors
.ElementAt(mNestedLoopLevel
- 1);
93 mLastRequestor
= JS::NullValue();
95 return NS_ERROR_FAILURE
;
98 *out
= mNestedLoopLevel
;
104 nsJSInspector::GetEventLoopNestLevel(uint32_t* out
) {
105 *out
= mNestedLoopLevel
;
110 nsJSInspector::GetLastNestRequestor(JS::MutableHandle
<JS::Value
> out
) {
111 out
.set(mLastRequestor
);
115 } // namespace jsinspector
116 } // namespace mozilla