tizen beta release
[profile/ivi/webkit-efl.git] / Source / WebCore / bindings / v8 / ScriptFunctionCall.cpp
1 /*
2  * Copyright (C) 2009 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 "ScriptFunctionCall.h"
33
34 #include "ScriptScope.h"
35 #include "ScriptState.h"
36 #include "ScriptValue.h"
37
38 #include "V8Binding.h"
39 #include "V8Proxy.h"
40 #include "V8Utilities.h"
41
42 #include <v8.h>
43 #include <wtf/OwnArrayPtr.h>
44
45 namespace WebCore {
46
47 void ScriptCallArgumentHandler::appendArgument(const ScriptObject& argument)
48 {
49     if (argument.scriptState() != m_scriptState) {
50         ASSERT_NOT_REACHED();
51         return;
52     }
53     m_arguments.append(argument);
54 }
55
56 void ScriptCallArgumentHandler::appendArgument(const ScriptValue& argument)
57 {
58     m_arguments.append(argument);
59 }
60
61 void ScriptCallArgumentHandler::appendArgument(const String& argument)
62 {
63     ScriptScope scope(m_scriptState);
64     m_arguments.append(v8String(argument));
65 }
66
67 void ScriptCallArgumentHandler::appendArgument(const char* argument)
68 {
69     ScriptScope scope(m_scriptState);
70     m_arguments.append(v8String(argument));
71 }
72
73 void ScriptCallArgumentHandler::appendArgument(long argument)
74 {
75     ScriptScope scope(m_scriptState);
76     m_arguments.append(v8::Number::New(argument));
77 }
78
79 void ScriptCallArgumentHandler::appendArgument(long long argument)
80 {
81     ScriptScope scope(m_scriptState);
82     m_arguments.append(v8::Number::New(argument));
83 }
84
85 void ScriptCallArgumentHandler::appendArgument(unsigned int argument)
86 {
87     ScriptScope scope(m_scriptState);
88     m_arguments.append(v8::Number::New(argument));
89 }
90
91 void ScriptCallArgumentHandler::appendArgument(unsigned long argument)
92 {
93     ScriptScope scope(m_scriptState);
94     m_arguments.append(v8::Number::New(argument));
95 }
96
97 void ScriptCallArgumentHandler::appendArgument(int argument)
98 {
99     ScriptScope scope(m_scriptState);
100     m_arguments.append(v8::Number::New(argument));
101 }
102
103 void ScriptCallArgumentHandler::appendArgument(bool argument)
104 {
105     m_arguments.append(v8Boolean(argument));
106 }
107
108 ScriptFunctionCall::ScriptFunctionCall(const ScriptObject& thisObject, const String& name)
109     : ScriptCallArgumentHandler(thisObject.scriptState())
110     , m_thisObject(thisObject)
111     , m_name(name)
112 {
113 }
114
115 ScriptValue ScriptFunctionCall::call(bool& hadException, bool reportExceptions)
116 {
117     ScriptScope scope(m_scriptState, reportExceptions);
118
119     v8::Local<v8::Object> thisObject = m_thisObject.v8Object();
120     v8::Local<v8::Value> value = thisObject->Get(v8String(m_name));
121     if (!scope.success()) {
122         hadException = true;
123         return ScriptValue();
124     }
125
126     ASSERT(value->IsFunction());
127
128     v8::Local<v8::Function> function(v8::Function::Cast(*value));
129     OwnArrayPtr<v8::Handle<v8::Value> > args = adoptArrayPtr(new v8::Handle<v8::Value>[m_arguments.size()]);
130     for (size_t i = 0; i < m_arguments.size(); ++i)
131         args[i] = m_arguments[i].v8Value();
132
133     v8::Local<v8::Value> result = function->Call(thisObject, m_arguments.size(), args.get());
134     if (!scope.success()) {
135         hadException = true;
136         return ScriptValue();
137     }
138
139     return ScriptValue(result);
140 }
141
142 ScriptValue ScriptFunctionCall::call()
143 {
144     bool hadException = false;
145     return call(hadException);
146 }
147
148 ScriptObject ScriptFunctionCall::construct(bool& hadException, bool reportExceptions)
149 {
150     ScriptScope scope(m_scriptState, reportExceptions);
151
152     v8::Local<v8::Object> thisObject = m_thisObject.v8Object();
153     v8::Local<v8::Value> value = thisObject->Get(v8String(m_name));
154     if (!scope.success()) {
155         hadException = true;
156         return ScriptObject();
157     }
158
159     ASSERT(value->IsFunction());
160
161     v8::Local<v8::Function> constructor(v8::Function::Cast(*value));
162     OwnArrayPtr<v8::Handle<v8::Value> > args = adoptArrayPtr(new v8::Handle<v8::Value>[m_arguments.size()]);
163     for (size_t i = 0; i < m_arguments.size(); ++i)
164         args[i] = m_arguments[i].v8Value();
165
166     v8::Local<v8::Object> result = SafeAllocation::newInstance(constructor, m_arguments.size(), args.get());
167     if (!scope.success()) {
168         hadException = true;
169         return ScriptObject();
170     }
171
172     return ScriptObject(m_scriptState, result);
173 }
174
175 ScriptCallback::ScriptCallback(ScriptState* state, ScriptValue function)
176     : ScriptCallArgumentHandler(state)
177     , m_function(function)
178 {
179 }
180
181 ScriptValue ScriptCallback::call()
182 {
183     bool hadException = false;
184     return call(hadException);
185 }
186
187 ScriptValue ScriptCallback::call(bool& hadException)
188 {
189     ASSERT(v8::Context::InContext());
190     ASSERT(m_function.v8Value()->IsFunction());
191
192     v8::TryCatch exceptionCatcher;
193     v8::Handle<v8::Object> object = v8::Context::GetCurrent()->Global();
194     v8::Handle<v8::Function> function = v8::Handle<v8::Function>::Cast(m_function.v8Value());
195
196     OwnArrayPtr<v8::Handle<v8::Value> > args = adoptArrayPtr(new v8::Handle<v8::Value>[m_arguments.size()]);
197     for (size_t i = 0; i < m_arguments.size(); ++i)
198         args[i] = m_arguments[i].v8Value();
199
200     v8::Handle<v8::Value> result = V8Proxy::instrumentedCallFunction(0 /* page */, function, object, m_arguments.size(), args.get());
201
202     if (exceptionCatcher.HasCaught()) {
203         hadException = true;
204         m_scriptState->setException(exceptionCatcher.Exception());
205         return ScriptValue();
206     }
207
208     return ScriptValue(result);
209 }
210
211 } // namespace WebCore