1635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project/* 228040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu * Copyright (c) 2010 Google Inc. All rights reserved. 328040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu * 4635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * Redistribution and use in source and binary forms, with or without 5635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * modification, are permitted provided that the following conditions are 6635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * met: 728040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu * 8635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * * Redistributions of source code must retain the above copyright 9635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * notice, this list of conditions and the following disclaimer. 10635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * * Redistributions in binary form must reproduce the above 11635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * copyright notice, this list of conditions and the following disclaimer 12635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * in the documentation and/or other materials provided with the 13635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * distribution. 14635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * * Neither the name of Google Inc. nor the names of its 15635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * contributors may be used to endorse or promote products derived from 16635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * this software without specific prior written permission. 17635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * 18635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project */ 30635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 31635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#include "config.h" 3228040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu#include "ScriptCallStackFactory.h" 33635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 34e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke#include "InspectorValues.h" 3528040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu#include "ScriptArguments.h" 3628040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu#include "ScriptCallFrame.h" 3728040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu#include "ScriptCallStack.h" 38967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch#include "ScriptScope.h" 3928040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu#include "ScriptValue.h" 4021939df44de1705786c545cd1bf519d47250322dBen Murdoch#include "V8Binding.h" 41d0825bca7fe65beaee391d30da42e937db621564Steve Block 4221939df44de1705786c545cd1bf519d47250322dBen Murdoch#include <v8-debug.h> 43635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 44635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectnamespace WebCore { 45635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 4628040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhustatic ScriptCallFrame toScriptCallFrame(v8::Handle<v8::StackFrame> frame) 47dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block{ 4828040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu String sourceName; 49a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch v8::Local<v8::String> sourceNameValue(frame->GetScriptNameOrSourceURL()); 5028040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu if (!sourceNameValue.IsEmpty()) 5128040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu sourceName = toWebCoreString(sourceNameValue); 52967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch 53967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch String functionName; 5428040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu v8::Local<v8::String> functionNameValue(frame->GetFunctionName()); 5528040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu if (!functionNameValue.IsEmpty()) 5628040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu functionName = toWebCoreString(functionNameValue); 5728040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu 5828040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu int sourceLineNumber = frame->GetLineNumber(); 59f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch int sourceColumn = frame->GetColumn(); 60f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch return ScriptCallFrame(functionName, sourceName, sourceLineNumber, sourceColumn); 61967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch} 62967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch 63f05b935882198ccf7d81675736e3aeb089c5113aBen Murdochstatic void toScriptCallFramesVector(v8::Handle<v8::StackTrace> stackTrace, Vector<ScriptCallFrame>& scriptCallFrames, size_t maxStackSize, bool emptyStackIsAllowed) 64967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch{ 65f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch ASSERT(v8::Context::InContext()); 66967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch int frameCount = stackTrace->GetFrameCount(); 6728040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu if (frameCount > static_cast<int>(maxStackSize)) 6828040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu frameCount = maxStackSize; 69967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch for (int i = 0; i < frameCount; i++) { 70967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch v8::Local<v8::StackFrame> stackFrame = stackTrace->GetFrame(i); 71967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch scriptCallFrames.append(toScriptCallFrame(stackFrame)); 72967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch } 73f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch if (!frameCount && !emptyStackIsAllowed) { 74f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch // Successfully grabbed stack trace, but there are no frames. It may happen in case 75f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch // when a bound function is called from native code for example. 7628040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu // Fallback to setting lineNumber to 0, and source and function name to "undefined". 7728040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu scriptCallFrames.append(ScriptCallFrame("undefined", "undefined", 0)); 7828040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu } 79967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch} 80967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch 81f05b935882198ccf7d81675736e3aeb089c5113aBen Murdochstatic PassRefPtr<ScriptCallStack> createScriptCallStack(v8::Handle<v8::StackTrace> stackTrace, size_t maxStackSize, bool emptyStackIsAllowed) 82967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch{ 83f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch ASSERT(v8::Context::InContext()); 84967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch v8::HandleScope scope; 8528040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu Vector<ScriptCallFrame> scriptCallFrames; 86f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch toScriptCallFramesVector(stackTrace, scriptCallFrames, maxStackSize, emptyStackIsAllowed); 87f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch return ScriptCallStack::create(scriptCallFrames); 88967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch} 89967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch 90f05b935882198ccf7d81675736e3aeb089c5113aBen MurdochPassRefPtr<ScriptCallStack> createScriptCallStack(v8::Handle<v8::StackTrace> stackTrace, size_t maxStackSize) 91967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch{ 92f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch return createScriptCallStack(stackTrace, maxStackSize, true); 93f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch} 94f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch 95f05b935882198ccf7d81675736e3aeb089c5113aBen MurdochPassRefPtr<ScriptCallStack> createScriptCallStack(size_t maxStackSize, bool emptyStackIsAllowed) 96f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch{ 97f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch if (!v8::Context::InContext()) 98f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch return 0; 99f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch v8::HandleScope handleScope; 10028040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu v8::Handle<v8::StackTrace> stackTrace(v8::StackTrace::CurrentStackTrace(maxStackSize, stackTraceOptions)); 101f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch return createScriptCallStack(stackTrace, maxStackSize, emptyStackIsAllowed); 102635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project} 103635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 104f05b935882198ccf7d81675736e3aeb089c5113aBen MurdochPassRefPtr<ScriptArguments> createScriptArguments(const v8::Arguments& v8arguments, unsigned skipArgumentCount) 1058f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{ 10628040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu v8::HandleScope scope; 10728040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu v8::Local<v8::Context> context = v8::Context::GetCurrent(); 10828040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu ScriptState* state = ScriptState::forContext(context); 109635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 11028040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu Vector<ScriptValue> arguments; 11128040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu for (int i = skipArgumentCount; i < v8arguments.Length(); ++i) 11228040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu arguments.append(ScriptValue(v8arguments[i])); 113967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch 114f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch return ScriptArguments::create(state, arguments); 11521939df44de1705786c545cd1bf519d47250322dBen Murdoch} 11621939df44de1705786c545cd1bf519d47250322dBen Murdoch 1178f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian} // namespace WebCore 118