1 /* 2 * Copyright (c) 2010, 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 #include "core/inspector/JavaScriptCallFrame.h" 33 34 #include "bindings/v8/V8Binding.h" 35 36 namespace WebCore { 37 38 JavaScriptCallFrame::JavaScriptCallFrame(v8::Handle<v8::Context> debuggerContext, v8::Handle<v8::Object> callFrame) 39 : m_debuggerContext(debuggerContext) 40 , m_callFrame(callFrame) 41 , m_isolate(v8::Isolate::GetCurrent()) 42 { 43 ScriptWrappable::init(this); 44 } 45 46 JavaScriptCallFrame::~JavaScriptCallFrame() 47 { 48 } 49 50 JavaScriptCallFrame* JavaScriptCallFrame::caller() 51 { 52 if (!m_caller) { 53 v8::HandleScope handleScope(m_isolate); 54 v8::Handle<v8::Context> debuggerContext = m_debuggerContext.newLocal(m_isolate); 55 v8::Context::Scope contextScope(debuggerContext); 56 v8::Handle<v8::Value> callerFrame = m_callFrame.newLocal(m_isolate)->Get(v8::String::NewSymbol("caller")); 57 if (!callerFrame->IsObject()) 58 return 0; 59 m_caller = JavaScriptCallFrame::create(debuggerContext, v8::Handle<v8::Object>::Cast(callerFrame)); 60 } 61 return m_caller.get(); 62 } 63 64 int JavaScriptCallFrame::sourceID() const 65 { 66 v8::HandleScope handleScope(m_isolate); 67 v8::Context::Scope contextScope(m_debuggerContext.newLocal(m_isolate)); 68 v8::Handle<v8::Value> result = m_callFrame.newLocal(m_isolate)->Get(v8::String::NewSymbol("sourceID")); 69 if (result->IsInt32()) 70 return result->Int32Value(); 71 return 0; 72 } 73 74 int JavaScriptCallFrame::line() const 75 { 76 v8::HandleScope handleScope(m_isolate); 77 v8::Context::Scope contextScope(m_debuggerContext.newLocal(m_isolate)); 78 v8::Handle<v8::Value> result = m_callFrame.newLocal(m_isolate)->Get(v8::String::NewSymbol("line")); 79 if (result->IsInt32()) 80 return result->Int32Value(); 81 return 0; 82 } 83 84 int JavaScriptCallFrame::column() const 85 { 86 v8::HandleScope handleScope(m_isolate); 87 v8::Context::Scope contextScope(m_debuggerContext.newLocal(m_isolate)); 88 v8::Handle<v8::Value> result = m_callFrame.newLocal(m_isolate)->Get(v8::String::NewSymbol("column")); 89 if (result->IsInt32()) 90 return result->Int32Value(); 91 return 0; 92 } 93 94 String JavaScriptCallFrame::functionName() const 95 { 96 v8::HandleScope handleScope(m_isolate); 97 v8::Context::Scope contextScope(m_debuggerContext.newLocal(m_isolate)); 98 v8::Handle<v8::Value> result = m_callFrame.newLocal(m_isolate)->Get(v8::String::NewSymbol("functionName")); 99 return toWebCoreStringWithUndefinedOrNullCheck(result); 100 } 101 102 v8::Handle<v8::Value> JavaScriptCallFrame::scopeChain() const 103 { 104 v8::Handle<v8::Array> scopeChain = v8::Handle<v8::Array>::Cast(m_callFrame.newLocal(m_isolate)->Get(v8::String::NewSymbol("scopeChain"))); 105 v8::Handle<v8::Array> result = v8::Array::New(scopeChain->Length()); 106 for (uint32_t i = 0; i < scopeChain->Length(); i++) 107 result->Set(i, scopeChain->Get(i)); 108 return result; 109 } 110 111 int JavaScriptCallFrame::scopeType(int scopeIndex) const 112 { 113 v8::Handle<v8::Array> scopeType = v8::Handle<v8::Array>::Cast(m_callFrame.newLocal(m_isolate)->Get(v8::String::NewSymbol("scopeType"))); 114 return scopeType->Get(scopeIndex)->Int32Value(); 115 } 116 117 v8::Handle<v8::Value> JavaScriptCallFrame::thisObject() const 118 { 119 return m_callFrame.newLocal(m_isolate)->Get(v8::String::NewSymbol("thisObject")); 120 } 121 122 String JavaScriptCallFrame::stepInPositions() const 123 { 124 v8::Handle<v8::Object> callFrame = m_callFrame.newLocal(m_isolate); 125 v8::Handle<v8::Function> stepInPositions = v8::Handle<v8::Function>::Cast(callFrame->Get(v8::String::NewSymbol("stepInPositions"))); 126 v8::Handle<v8::Value> result = stepInPositions->Call(callFrame, 0, 0); 127 return toWebCoreStringWithUndefinedOrNullCheck(result); 128 } 129 130 v8::Handle<v8::Value> JavaScriptCallFrame::evaluate(const String& expression) 131 { 132 v8::Handle<v8::Object> callFrame = m_callFrame.newLocal(m_isolate); 133 v8::Handle<v8::Function> evalFunction = v8::Handle<v8::Function>::Cast(callFrame->Get(v8::String::NewSymbol("evaluate"))); 134 v8::Handle<v8::Value> argv[] = { v8String(expression, m_debuggerContext.newLocal(m_isolate)->GetIsolate()) }; 135 return evalFunction->Call(callFrame, 1, argv); 136 } 137 138 v8::Handle<v8::Value> JavaScriptCallFrame::restart() 139 { 140 v8::Handle<v8::Object> callFrame = m_callFrame.newLocal(m_isolate); 141 v8::Handle<v8::Function> restartFunction = v8::Handle<v8::Function>::Cast(callFrame->Get(v8::String::NewSymbol("restart"))); 142 v8::Debug::SetLiveEditEnabled(true); 143 v8::Handle<v8::Value> result = restartFunction->Call(callFrame, 0, 0); 144 v8::Debug::SetLiveEditEnabled(false); 145 return result; 146 } 147 148 v8::Handle<v8::Value> JavaScriptCallFrame::setVariableValue(int scopeNumber, const String& variableName, v8::Handle<v8::Value> newValue) 149 { 150 v8::Handle<v8::Object> callFrame = m_callFrame.newLocal(m_isolate); 151 v8::Handle<v8::Function> setVariableValueFunction = v8::Handle<v8::Function>::Cast(callFrame->Get(v8::String::NewSymbol("setVariableValue"))); 152 v8::Handle<v8::Value> argv[] = { 153 v8::Handle<v8::Value>(v8::Integer::New(scopeNumber)), 154 v8String(variableName, m_isolate), 155 newValue 156 }; 157 return setVariableValueFunction->Call(callFrame, 3, argv); 158 } 159 160 } // namespace WebCore 161