OSDN Git Service

Merge WebKit at r73109: Initial merge by git.
[android-x86/external-webkit.git] / WebCore / bindings / v8 / ScriptCallStackFactory.cpp
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 "ScriptCallStackFactory.h"
33
34 #include "InspectorValues.h"
35 #include "ScriptArguments.h"
36 #include "ScriptCallFrame.h"
37 #include "ScriptCallStack.h"
38 #include "ScriptScope.h"
39 #include "ScriptValue.h"
40 #include "V8Binding.h"
41
42 #include <v8-debug.h>
43
44 namespace WebCore {
45
46 static ScriptCallFrame toScriptCallFrame(v8::Handle<v8::StackFrame> frame)
47 {
48     String sourceName;
49     v8::Local<v8::String> sourceNameValue(frame->GetScriptNameOrSourceURL());
50     if (!sourceNameValue.IsEmpty())
51         sourceName = toWebCoreString(sourceNameValue);
52
53     String functionName;
54     v8::Local<v8::String> functionNameValue(frame->GetFunctionName());
55     if (!functionNameValue.IsEmpty())
56         functionName = toWebCoreString(functionNameValue);
57
58     int sourceLineNumber = frame->GetLineNumber();
59     return ScriptCallFrame(functionName, sourceName, sourceLineNumber);
60 }
61
62 static void toScriptCallFramesVector(v8::Local<v8::Context> context, v8::Handle<v8::StackTrace> stackTrace, Vector<ScriptCallFrame>& scriptCallFrames, size_t maxStackSize)
63 {
64     // TODO(yurys): remove this???
65     v8::Context::Scope contextScope(context);
66     int frameCount = stackTrace->GetFrameCount();
67     if (frameCount > static_cast<int>(maxStackSize))
68         frameCount = maxStackSize;
69     for (int i = 0; i < frameCount; i++) {
70         v8::Local<v8::StackFrame> stackFrame = stackTrace->GetFrame(i);
71         scriptCallFrames.append(toScriptCallFrame(stackFrame));
72     }
73     
74     if (!frameCount) {
75         // Successfully grabbed stack trace, but there are no frames. It may happen in case of a syntax error for example.
76         // Fallback to setting lineNumber to 0, and source and function name to "undefined".
77         scriptCallFrames.append(ScriptCallFrame("undefined", "undefined", 0));
78     }
79 }
80
81 PassRefPtr<ScriptCallStack> createScriptCallStack(v8::Local<v8::Context> context, v8::Handle<v8::StackTrace> stackTrace, size_t maxStackSize)
82 {
83     v8::HandleScope scope;
84     v8::Context::Scope contextScope(context);
85
86     Vector<ScriptCallFrame> scriptCallFrames;
87     toScriptCallFramesVector(context, stackTrace, scriptCallFrames, maxStackSize);
88     return ScriptCallStack::create(scriptCallFrames);
89 }
90
91 PassRefPtr<ScriptCallStack> createScriptCallStack(size_t maxStackSize)
92 {
93     v8::HandleScope scope;
94     v8::Local<v8::Context> context = v8::Context::GetCurrent();
95     // TODO(yurys): remove?
96     v8::Context::Scope contextScope(context);
97     v8::Handle<v8::StackTrace> stackTrace(v8::StackTrace::CurrentStackTrace(maxStackSize, stackTraceOptions));
98     return createScriptCallStack(context, stackTrace, maxStackSize);
99 }
100
101 PassRefPtr<ScriptArguments> createScriptArguments(const v8::Arguments& v8arguments, unsigned skipArgumentCount)
102 {
103     v8::HandleScope scope;
104     v8::Local<v8::Context> context = v8::Context::GetCurrent();
105     ScriptState* state = ScriptState::forContext(context);
106
107     Vector<ScriptValue> arguments;
108     for (int i = skipArgumentCount; i < v8arguments.Length(); ++i)
109         arguments.append(ScriptValue(v8arguments[i]));
110
111     return ScriptArguments::create(state, arguments);
112 }
113
114 bool ScriptCallStack::stackTrace(int frameLimit, const RefPtr<InspectorArray>& stackTrace)
115 {
116 #if ENABLE(INSPECTOR)
117     if (!v8::Context::InContext())
118         return false;
119     v8::Handle<v8::Context> context = v8::Context::GetCurrent();
120     if (context.IsEmpty())
121         return false;
122     v8::HandleScope scope;
123     v8::Context::Scope contextScope(context);
124     v8::Handle<v8::StackTrace> trace(v8::StackTrace::CurrentStackTrace(frameLimit));
125     int frameCount = trace->GetFrameCount();
126     if (trace.IsEmpty() || !frameCount)
127         return false;
128     for (int i = 0; i < frameCount; ++i) {
129         v8::Handle<v8::StackFrame> frame = trace->GetFrame(i);
130         RefPtr<InspectorObject> frameObject = InspectorObject::create();
131         v8::Local<v8::String> scriptName = frame->GetScriptName();
132         frameObject->setString("scriptName", scriptName.IsEmpty() ? "" : toWebCoreString(scriptName));
133         v8::Local<v8::String> functionName = frame->GetFunctionName();
134         frameObject->setString("functionName", functionName.IsEmpty() ? "" : toWebCoreString(functionName));
135         frameObject->setNumber("lineNumber", frame->GetLineNumber());
136         frameObject->setNumber("column", frame->GetColumn());
137         stackTrace->pushObject(frameObject);
138     }
139     return true;
140 #else
141     return false;
142 #endif
143 }
144
145 } // namespace WebCore