1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/toolkit/devtools/server/nsJSInspector.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,148 @@ 1.4 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2; -*- */ 1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.8 + 1.9 +#include "nsJSInspector.h" 1.10 +#include "nsIXPConnect.h" 1.11 +#include "nsThreadUtils.h" 1.12 +#include "jsfriendapi.h" 1.13 +#include "js/OldDebugAPI.h" 1.14 +#include "mozilla/HoldDropJSObjects.h" 1.15 +#include "mozilla/ModuleUtils.h" 1.16 +#include "mozilla/dom/ScriptSettings.h" 1.17 +#include "nsServiceManagerUtils.h" 1.18 +#include "nsMemory.h" 1.19 +#include "nsArray.h" 1.20 +#include "nsTArray.h" 1.21 + 1.22 +#define JSINSPECTOR_CONTRACTID \ 1.23 + "@mozilla.org/jsinspector;1" 1.24 + 1.25 +#define JSINSPECTOR_CID \ 1.26 +{ 0xec5aa99c, 0x7abb, 0x4142, { 0xac, 0x5f, 0xaa, 0xb2, 0x41, 0x9e, 0x38, 0xe2 } } 1.27 + 1.28 +namespace mozilla { 1.29 +namespace jsinspector { 1.30 + 1.31 +NS_GENERIC_FACTORY_CONSTRUCTOR(nsJSInspector) 1.32 + 1.33 +NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsJSInspector) 1.34 + NS_INTERFACE_MAP_ENTRY(nsISupports) 1.35 + NS_INTERFACE_MAP_ENTRY(nsIJSInspector) 1.36 +NS_INTERFACE_MAP_END 1.37 + 1.38 +NS_IMPL_CYCLE_COLLECTION_CLASS(nsJSInspector) 1.39 + 1.40 +NS_IMPL_CYCLE_COLLECTING_ADDREF(nsJSInspector) 1.41 +NS_IMPL_CYCLE_COLLECTING_RELEASE(nsJSInspector) 1.42 + 1.43 +NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsJSInspector) 1.44 + NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS 1.45 +NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END 1.46 + 1.47 +NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsJSInspector) 1.48 + tmp->mRequestors.Clear(); 1.49 + tmp->mLastRequestor = JS::NullValue(); 1.50 +NS_IMPL_CYCLE_COLLECTION_UNLINK_END 1.51 + 1.52 +NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(nsJSInspector) 1.53 + for (uint32_t i = 0; i < tmp->mRequestors.Length(); ++i) { 1.54 + NS_IMPL_CYCLE_COLLECTION_TRACE_JSVAL_MEMBER_CALLBACK(mRequestors[i]) 1.55 + } 1.56 + NS_IMPL_CYCLE_COLLECTION_TRACE_JSVAL_MEMBER_CALLBACK(mLastRequestor) 1.57 +NS_IMPL_CYCLE_COLLECTION_TRACE_END 1.58 + 1.59 +nsJSInspector::nsJSInspector() : mNestedLoopLevel(0), mRequestors(1), mLastRequestor(JSVAL_NULL) 1.60 +{ 1.61 +} 1.62 + 1.63 +nsJSInspector::~nsJSInspector() 1.64 +{ 1.65 + MOZ_ASSERT(mRequestors.Length() == 0); 1.66 + MOZ_ASSERT(mLastRequestor.isNull()); 1.67 + mozilla::DropJSObjects(this); 1.68 +} 1.69 + 1.70 +NS_IMETHODIMP 1.71 +nsJSInspector::EnterNestedEventLoop(JS::Handle<JS::Value> requestor, uint32_t *out) 1.72 +{ 1.73 + nsresult rv = NS_OK; 1.74 + 1.75 + mLastRequestor = requestor; 1.76 + mRequestors.AppendElement(requestor); 1.77 + mozilla::HoldJSObjects(this); 1.78 + 1.79 + mozilla::dom::AutoNoJSAPI nojsapi; 1.80 + 1.81 + uint32_t nestLevel = ++mNestedLoopLevel; 1.82 + while (NS_SUCCEEDED(rv) && mNestedLoopLevel >= nestLevel) { 1.83 + if (!NS_ProcessNextEvent()) 1.84 + rv = NS_ERROR_UNEXPECTED; 1.85 + } 1.86 + 1.87 + NS_ASSERTION(mNestedLoopLevel <= nestLevel, 1.88 + "nested event didn't unwind properly"); 1.89 + 1.90 + if (mNestedLoopLevel == nestLevel) { 1.91 + mLastRequestor = mRequestors.ElementAt(--mNestedLoopLevel); 1.92 + } 1.93 + 1.94 + *out = mNestedLoopLevel; 1.95 + return rv; 1.96 +} 1.97 + 1.98 +NS_IMETHODIMP 1.99 +nsJSInspector::ExitNestedEventLoop(uint32_t *out) 1.100 +{ 1.101 + if (mNestedLoopLevel > 0) { 1.102 + mRequestors.RemoveElementAt(--mNestedLoopLevel); 1.103 + if (mNestedLoopLevel > 0) 1.104 + mLastRequestor = mRequestors.ElementAt(mNestedLoopLevel - 1); 1.105 + else 1.106 + mLastRequestor = JSVAL_NULL; 1.107 + } else { 1.108 + return NS_ERROR_FAILURE; 1.109 + } 1.110 + 1.111 + *out = mNestedLoopLevel; 1.112 + 1.113 + return NS_OK; 1.114 +} 1.115 + 1.116 +NS_IMETHODIMP 1.117 +nsJSInspector::GetEventLoopNestLevel(uint32_t *out) 1.118 +{ 1.119 + *out = mNestedLoopLevel; 1.120 + return NS_OK; 1.121 +} 1.122 + 1.123 +NS_IMETHODIMP 1.124 +nsJSInspector::GetLastNestRequestor(JS::MutableHandle<JS::Value> out) 1.125 +{ 1.126 + out.set(mLastRequestor); 1.127 + return NS_OK; 1.128 +} 1.129 + 1.130 +} 1.131 +} 1.132 + 1.133 +NS_DEFINE_NAMED_CID(JSINSPECTOR_CID); 1.134 + 1.135 +static const mozilla::Module::CIDEntry kJSInspectorCIDs[] = { 1.136 + { &kJSINSPECTOR_CID, false, nullptr, mozilla::jsinspector::nsJSInspectorConstructor }, 1.137 + { nullptr } 1.138 +}; 1.139 + 1.140 +static const mozilla::Module::ContractIDEntry kJSInspectorContracts[] = { 1.141 + { JSINSPECTOR_CONTRACTID, &kJSINSPECTOR_CID }, 1.142 + { nullptr } 1.143 +}; 1.144 + 1.145 +static const mozilla::Module kJSInspectorModule = { 1.146 + mozilla::Module::kVersion, 1.147 + kJSInspectorCIDs, 1.148 + kJSInspectorContracts 1.149 +}; 1.150 + 1.151 +NSMODULE_DEFN(jsinspector) = &kJSInspectorModule;