[JSC] Web Inspector: CRASH running $0, $1, etc before they are set
[WebKit-https.git] / Source / WebCore / bindings / js / JSInjectedScriptHostCustom.cpp
1 /*
2  * Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
3  * Copyright (C) 2008 Matt Lilek <webkit@mattlilek.com>
4  * Copyright (C) 2010-2011 Google Inc. All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions are
8  * met:
9  *
10  *     * Redistributions of source code must retain the above copyright
11  * notice, this list of conditions and the following disclaimer.
12  *     * Redistributions in binary form must reproduce the above
13  * copyright notice, this list of conditions and the following disclaimer
14  * in the documentation and/or other materials provided with the
15  * distribution.
16  *     * Neither the name of Google Inc. nor the names of its
17  * contributors may be used to endorse or promote products derived from
18  * this software without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  */
32
33 #include "config.h"
34
35 #if ENABLE(INSPECTOR)
36
37 #include "JSInjectedScriptHost.h"
38
39 #if ENABLE(SQL_DATABASE)
40 #include "Database.h"
41 #include "JSDatabase.h"
42 #endif
43 #include "ExceptionCode.h"
44 #include "InjectedScriptHost.h"
45 #include "InspectorDebuggerAgent.h"
46 #include "InspectorValues.h"
47 #include "JSFloat32Array.h"
48 #include "JSFloat64Array.h"
49 #include "JSHTMLAllCollection.h"
50 #include "JSHTMLCollection.h"
51 #include "JSInt16Array.h"
52 #include "JSInt32Array.h"
53 #include "JSInt8Array.h"
54 #include "JSNode.h"
55 #include "JSNodeList.h"
56 #include "JSStorage.h"
57 #include "ScriptValue.h"
58 #include "Storage.h"
59 #include <parser/SourceCode.h>
60 #include <runtime/DateInstance.h>
61 #include <runtime/Error.h>
62 #include <runtime/JSArray.h>
63 #include <runtime/JSFunction.h>
64 #include <runtime/JSLock.h>
65 #include <runtime/RegExpObject.h>
66
67 using namespace JSC;
68
69 namespace WebCore {
70
71 Node* InjectedScriptHost::scriptValueAsNode(ScriptValue value)
72 {
73     if (!value.isObject() || value.isNull())
74         return 0;
75     return toNode(value.jsValue());
76 }
77
78 ScriptValue InjectedScriptHost::nodeAsScriptValue(ScriptState* state, Node* node)
79 {
80     JSLock lock(SilenceAssertionsOnly);
81     return ScriptValue(state->globalData(), toJS(state, deprecatedGlobalObjectForPrototype(state), node));
82 }
83
84 JSValue JSInjectedScriptHost::inspectedObject(ExecState* exec)
85 {
86     if (exec->argumentCount() < 1)
87         return jsUndefined();
88
89     InjectedScriptHost::InspectableObject* object = impl()->inspectedObject(exec->argument(0).toInt32(exec));
90     if (!object)
91         return jsUndefined();
92
93     JSLock lock(SilenceAssertionsOnly);
94     ScriptValue scriptValue = object->get(exec);
95     if (scriptValue.hasNoValue())
96         return jsUndefined();
97
98     return scriptValue.jsValue();
99 }
100
101 JSValue JSInjectedScriptHost::internalConstructorName(ExecState* exec)
102 {
103     if (exec->argumentCount() < 1)
104         return jsUndefined();
105
106     JSObject* thisObject = exec->argument(0).toThisObject(exec);
107     UString result = thisObject->methodTable()->className(thisObject);
108     return jsString(exec, result);
109 }
110
111 JSValue JSInjectedScriptHost::isHTMLAllCollection(ExecState* exec)
112 {
113     if (exec->argumentCount() < 1)
114         return jsUndefined();
115
116     JSValue value = exec->argument(0);
117     return jsBoolean(value.inherits(&JSHTMLAllCollection::s_info));
118 }
119
120 JSValue JSInjectedScriptHost::type(ExecState* exec)
121 {
122     if (exec->argumentCount() < 1)
123         return jsUndefined();
124
125     JSValue value = exec->argument(0);
126     if (value.isString())
127         return jsString(exec, String("string"));
128     if (value.inherits(&JSArray::s_info))
129         return jsString(exec, String("array"));
130     if (value.isBoolean())
131         return jsString(exec, String("boolean"));
132     if (value.isNumber())
133         return jsString(exec, String("number"));
134     if (value.inherits(&DateInstance::s_info))
135         return jsString(exec, String("date"));
136     if (value.inherits(&RegExpObject::s_info))
137         return jsString(exec, String("regexp"));
138     if (value.inherits(&JSNode::s_info))
139         return jsString(exec, String("node"));
140     if (value.inherits(&JSNodeList::s_info))
141         return jsString(exec, String("array"));
142     if (value.inherits(&JSHTMLCollection::s_info))
143         return jsString(exec, String("array"));
144     if (value.inherits(&JSInt8Array::s_info) || value.inherits(&JSInt16Array::s_info) || value.inherits(&JSInt32Array::s_info))
145         return jsString(exec, String("array"));
146     if (value.inherits(&JSFloat32Array::s_info) || value.inherits(&JSFloat64Array::s_info))
147         return jsString(exec, String("array"));
148     return jsUndefined();
149 }
150
151 JSValue JSInjectedScriptHost::functionDetails(ExecState* exec)
152 {
153     if (exec->argumentCount() < 1)
154         return jsUndefined();
155     JSValue value = exec->argument(0);
156     if (!value.asCell()->inherits(&JSFunction::s_info))
157         return jsUndefined();
158     JSFunction* function = asFunction(value);
159
160     const SourceCode* sourceCode = function->sourceCode();
161     if (!sourceCode)
162         return jsUndefined();
163     int lineNumber = sourceCode->firstLine();
164     if (lineNumber)
165         lineNumber -= 1; // In the inspector protocol all positions are 0-based while in SourceCode they are 1-based
166     UString scriptId = UString::number(sourceCode->provider()->asID());
167
168     JSObject* location = constructEmptyObject(exec);
169     location->putDirect(exec->globalData(), Identifier(exec, "lineNumber"), jsNumber(lineNumber));
170     location->putDirect(exec->globalData(), Identifier(exec, "scriptId"), jsString(exec, scriptId));
171
172     JSObject* result = constructEmptyObject(exec);
173     result->putDirect(exec->globalData(), Identifier(exec, "location"), location);
174     UString name = function->name(exec);
175     if (!name.isEmpty())
176         result->putDirect(exec->globalData(), Identifier(exec, "name"), jsString(exec, name));
177     UString displayName = function->displayName(exec);
178     if (!displayName.isEmpty())
179         result->putDirect(exec->globalData(), Identifier(exec, "displayName"), jsString(exec, displayName));
180     return result;
181 }
182
183 JSValue JSInjectedScriptHost::inspect(ExecState* exec)
184 {
185     if (exec->argumentCount() >= 2) {
186         ScriptValue object(exec->globalData(), exec->argument(0));
187         ScriptValue hints(exec->globalData(), exec->argument(1));
188         impl()->inspectImpl(object.toInspectorValue(exec), hints.toInspectorValue(exec));
189     }
190     return jsUndefined();
191 }
192
193 JSValue JSInjectedScriptHost::databaseId(ExecState* exec)
194 {
195     if (exec->argumentCount() < 1)
196         return jsUndefined();
197 #if ENABLE(SQL_DATABASE)
198     Database* database = toDatabase(exec->argument(0));
199     if (database)
200         return jsNumber(impl()->databaseIdImpl(database));
201 #endif
202     return jsUndefined();
203 }
204
205 JSValue JSInjectedScriptHost::storageId(ExecState* exec)
206 {
207     if (exec->argumentCount() < 1)
208         return jsUndefined();
209     Storage* storage = toStorage(exec->argument(0));
210     if (storage)
211         return jsNumber(impl()->storageIdImpl(storage));
212     return jsUndefined();
213 }
214
215 } // namespace WebCore
216
217 #endif // ENABLE(INSPECTOR)