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 46namespace WebCore { 47 48void 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 57void ScriptCallArgumentHandler::appendArgument(const ScriptValue& argument) 58{ 59 m_arguments.append(argument); 60} 61 62void ScriptCallArgumentHandler::appendArgument(const String& argument) 63{ 64 ScriptScope scope(m_scriptState); 65 m_arguments.append(v8String(argument, m_scriptState->isolate())); 66} 67 68void ScriptCallArgumentHandler::appendArgument(const char* argument) 69{ 70 ScriptScope scope(m_scriptState); 71 m_arguments.append(v8String(argument, m_scriptState->isolate())); 72} 73 74void ScriptCallArgumentHandler::appendArgument(long argument) 75{ 76 ScriptScope scope(m_scriptState); 77 m_arguments.append(v8::Number::New(argument)); 78} 79 80void ScriptCallArgumentHandler::appendArgument(long long argument) 81{ 82 ScriptScope scope(m_scriptState); 83 m_arguments.append(v8::Number::New(argument)); 84} 85 86void ScriptCallArgumentHandler::appendArgument(unsigned int argument) 87{ 88 ScriptScope scope(m_scriptState); 89 m_arguments.append(v8::Number::New(argument)); 90} 91 92void ScriptCallArgumentHandler::appendArgument(unsigned long argument) 93{ 94 ScriptScope scope(m_scriptState); 95 m_arguments.append(v8::Number::New(argument)); 96} 97 98void ScriptCallArgumentHandler::appendArgument(int argument) 99{ 100 ScriptScope scope(m_scriptState); 101 m_arguments.append(v8::Number::New(argument)); 102} 103 104void ScriptCallArgumentHandler::appendArgument(bool argument) 105{ 106 m_arguments.append(v8Boolean(argument)); 107} 108 109ScriptFunctionCall::ScriptFunctionCall(const ScriptObject& thisObject, const String& name) 110 : ScriptCallArgumentHandler(thisObject.scriptState()) 111 , m_thisObject(thisObject) 112 , m_name(name) 113{ 114} 115 116ScriptValue 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 145ScriptValue ScriptFunctionCall::call() 146{ 147 bool hadException = false; 148 return call(hadException); 149} 150 151ScriptObject 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 178ScriptCallback::ScriptCallback(ScriptState* state, const ScriptValue& function) 179 : ScriptCallArgumentHandler(state) 180 , m_function(function) 181{ 182} 183 184ScriptValue 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