1/* 2 * Copyright (C) 2011 Google Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions are 6 * met: 7 * 8 * * Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * * Redistributions in binary form must reproduce the above 11 * copyright notice, this list of conditions and the following disclaimer 12 * in the documentation and/or other materials provided with the 13 * distribution. 14 * * Neither the name of Google Inc. nor the names of its 15 * contributors may be used to endorse or promote products derived from 16 * this software without specific prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 */ 30 31#include "config.h" 32 33#if ENABLE(INSPECTOR) 34 35#include "InspectorRuntimeAgent.h" 36 37#include "InjectedScript.h" 38#include "InjectedScriptManager.h" 39#include "InspectorValues.h" 40#include "JSDOMWindowBase.h" 41#include <parser/ParserError.h> 42#include <parser/SourceCode.h> 43#include <runtime/Completion.h> 44#include <runtime/JSLock.h> 45#include <wtf/PassRefPtr.h> 46 47#if ENABLE(JAVASCRIPT_DEBUGGER) 48#include "ScriptDebugServer.h" 49#endif 50 51using namespace JSC; 52 53namespace WebCore { 54 55static bool asBool(const bool* const b) 56{ 57 return b ? *b : false; 58} 59 60InspectorRuntimeAgent::InspectorRuntimeAgent(InstrumentingAgents* instrumentingAgents, InspectorCompositeState* state, InjectedScriptManager* injectedScriptManager) 61 : InspectorBaseAgent<InspectorRuntimeAgent>("Runtime", instrumentingAgents, state) 62 , m_enabled(false) 63 , m_injectedScriptManager(injectedScriptManager) 64#if ENABLE(JAVASCRIPT_DEBUGGER) 65 , m_scriptDebugServer(0) 66#endif 67{ 68} 69 70InspectorRuntimeAgent::~InspectorRuntimeAgent() 71{ 72} 73 74#if ENABLE(JAVASCRIPT_DEBUGGER) 75static ScriptDebugServer::PauseOnExceptionsState setPauseOnExceptionsState(ScriptDebugServer* scriptDebugServer, ScriptDebugServer::PauseOnExceptionsState newState) 76{ 77 ASSERT(scriptDebugServer); 78 ScriptDebugServer::PauseOnExceptionsState presentState = scriptDebugServer->pauseOnExceptionsState(); 79 if (presentState != newState) 80 scriptDebugServer->setPauseOnExceptionsState(newState); 81 return presentState; 82} 83#endif 84 85static PassRefPtr<TypeBuilder::Runtime::ErrorRange> buildErrorRangeObject(const JSTokenLocation& tokenLocation) 86{ 87 RefPtr<TypeBuilder::Runtime::ErrorRange> result = TypeBuilder::Runtime::ErrorRange::create() 88 .setStartOffset(tokenLocation.startOffset) 89 .setEndOffset(tokenLocation.endOffset); 90 return result.release(); 91} 92 93void InspectorRuntimeAgent::parse(ErrorString*, const String& expression, TypeBuilder::Runtime::SyntaxErrorType::Enum* result, TypeBuilder::OptOutput<String>* message, RefPtr<TypeBuilder::Runtime::ErrorRange>& range) 94{ 95 VM* vm = JSDOMWindowBase::commonVM(); 96 JSLockHolder lock(vm); 97 98 ParserError error; 99 checkSyntax(*vm, JSC::makeSource(expression), error); 100 101 switch (error.m_syntaxErrorType) { 102 case ParserError::SyntaxErrorNone: 103 *result = TypeBuilder::Runtime::SyntaxErrorType::None; 104 break; 105 case ParserError::SyntaxErrorIrrecoverable: 106 *result = TypeBuilder::Runtime::SyntaxErrorType::Irrecoverable; 107 break; 108 case ParserError::SyntaxErrorUnterminatedLiteral: 109 *result = TypeBuilder::Runtime::SyntaxErrorType::Unterminated_literal; 110 break; 111 case ParserError::SyntaxErrorRecoverable: 112 *result = TypeBuilder::Runtime::SyntaxErrorType::Recoverable; 113 break; 114 } 115 116 if (error.m_syntaxErrorType != ParserError::SyntaxErrorNone) { 117 *message = error.m_message; 118 range = buildErrorRangeObject(error.m_token.m_location); 119 } 120} 121 122void InspectorRuntimeAgent::evaluate(ErrorString* errorString, const String& expression, const String* const objectGroup, const bool* const includeCommandLineAPI, const bool* const doNotPauseOnExceptionsAndMuteConsole, const int* executionContextId, const bool* const returnByValue, const bool* generatePreview, RefPtr<TypeBuilder::Runtime::RemoteObject>& result, TypeBuilder::OptOutput<bool>* wasThrown) 123{ 124 InjectedScript injectedScript = injectedScriptForEval(errorString, executionContextId); 125 if (injectedScript.hasNoValue()) 126 return; 127#if ENABLE(JAVASCRIPT_DEBUGGER) 128 ScriptDebugServer::PauseOnExceptionsState previousPauseOnExceptionsState = ScriptDebugServer::DontPauseOnExceptions; 129 if (asBool(doNotPauseOnExceptionsAndMuteConsole)) 130 previousPauseOnExceptionsState = setPauseOnExceptionsState(m_scriptDebugServer, ScriptDebugServer::DontPauseOnExceptions); 131#endif 132 if (asBool(doNotPauseOnExceptionsAndMuteConsole)) 133 muteConsole(); 134 135 injectedScript.evaluate(errorString, expression, objectGroup ? *objectGroup : "", asBool(includeCommandLineAPI), asBool(returnByValue), asBool(generatePreview), &result, wasThrown); 136 137 if (asBool(doNotPauseOnExceptionsAndMuteConsole)) { 138 unmuteConsole(); 139#if ENABLE(JAVASCRIPT_DEBUGGER) 140 setPauseOnExceptionsState(m_scriptDebugServer, previousPauseOnExceptionsState); 141#endif 142 } 143} 144 145void InspectorRuntimeAgent::callFunctionOn(ErrorString* errorString, const String& objectId, const String& expression, const RefPtr<InspectorArray>* const optionalArguments, const bool* const doNotPauseOnExceptionsAndMuteConsole, const bool* const returnByValue, const bool* generatePreview, RefPtr<TypeBuilder::Runtime::RemoteObject>& result, TypeBuilder::OptOutput<bool>* wasThrown) 146{ 147 InjectedScript injectedScript = m_injectedScriptManager->injectedScriptForObjectId(objectId); 148 if (injectedScript.hasNoValue()) { 149 *errorString = "Inspected frame has gone"; 150 return; 151 } 152 String arguments; 153 if (optionalArguments) 154 arguments = (*optionalArguments)->toJSONString(); 155 156#if ENABLE(JAVASCRIPT_DEBUGGER) 157 ScriptDebugServer::PauseOnExceptionsState previousPauseOnExceptionsState = ScriptDebugServer::DontPauseOnExceptions; 158 if (asBool(doNotPauseOnExceptionsAndMuteConsole)) 159 previousPauseOnExceptionsState = setPauseOnExceptionsState(m_scriptDebugServer, ScriptDebugServer::DontPauseOnExceptions); 160#endif 161 if (asBool(doNotPauseOnExceptionsAndMuteConsole)) 162 muteConsole(); 163 164 injectedScript.callFunctionOn(errorString, objectId, expression, arguments, asBool(returnByValue), asBool(generatePreview), &result, wasThrown); 165 166 if (asBool(doNotPauseOnExceptionsAndMuteConsole)) { 167 unmuteConsole(); 168#if ENABLE(JAVASCRIPT_DEBUGGER) 169 setPauseOnExceptionsState(m_scriptDebugServer, previousPauseOnExceptionsState); 170#endif 171 } 172} 173 174void InspectorRuntimeAgent::getProperties(ErrorString* errorString, const String& objectId, const bool* const ownProperties, RefPtr<TypeBuilder::Array<TypeBuilder::Runtime::PropertyDescriptor> >& result, RefPtr<TypeBuilder::Array<TypeBuilder::Runtime::InternalPropertyDescriptor> >& internalProperties) 175{ 176 InjectedScript injectedScript = m_injectedScriptManager->injectedScriptForObjectId(objectId); 177 if (injectedScript.hasNoValue()) { 178 *errorString = "Inspected frame has gone"; 179 return; 180 } 181 182#if ENABLE(JAVASCRIPT_DEBUGGER) 183 ScriptDebugServer::PauseOnExceptionsState previousPauseOnExceptionsState = setPauseOnExceptionsState(m_scriptDebugServer, ScriptDebugServer::DontPauseOnExceptions); 184#endif 185 muteConsole(); 186 187 injectedScript.getProperties(errorString, objectId, ownProperties ? *ownProperties : false, &result); 188 injectedScript.getInternalProperties(errorString, objectId, &internalProperties); 189 190 unmuteConsole(); 191#if ENABLE(JAVASCRIPT_DEBUGGER) 192 setPauseOnExceptionsState(m_scriptDebugServer, previousPauseOnExceptionsState); 193#endif 194} 195 196void InspectorRuntimeAgent::releaseObject(ErrorString*, const String& objectId) 197{ 198 InjectedScript injectedScript = m_injectedScriptManager->injectedScriptForObjectId(objectId); 199 if (!injectedScript.hasNoValue()) 200 injectedScript.releaseObject(objectId); 201} 202 203void InspectorRuntimeAgent::releaseObjectGroup(ErrorString*, const String& objectGroup) 204{ 205 m_injectedScriptManager->releaseObjectGroup(objectGroup); 206} 207 208void InspectorRuntimeAgent::run(ErrorString*) 209{ 210} 211 212#if ENABLE(JAVASCRIPT_DEBUGGER) 213void InspectorRuntimeAgent::setScriptDebugServer(ScriptDebugServer* scriptDebugServer) 214{ 215 m_scriptDebugServer = scriptDebugServer; 216} 217#endif // ENABLE(JAVASCRIPT_DEBUGGER) 218 219} // namespace WebCore 220 221#endif // ENABLE(INSPECTOR) 222