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