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 "JSDOMBinding.h" 35#include "JSMainThreadExecState.h" 36#include "ScriptValue.h" 37 38#include <runtime/JSLock.h> 39#include <runtime/UString.h> 40 41using namespace JSC; 42 43namespace WebCore { 44 45void ScriptCallArgumentHandler::appendArgument(const ScriptObject& argument) 46{ 47 if (argument.scriptState() != m_exec) { 48 ASSERT_NOT_REACHED(); 49 return; 50 } 51 m_arguments.append(argument.jsObject()); 52} 53 54void ScriptCallArgumentHandler::appendArgument(const ScriptValue& argument) 55{ 56 m_arguments.append(argument.jsValue()); 57} 58 59void ScriptCallArgumentHandler::appendArgument(const String& argument) 60{ 61 JSLock lock(SilenceAssertionsOnly); 62 m_arguments.append(jsString(m_exec, argument)); 63} 64 65void ScriptCallArgumentHandler::appendArgument(const JSC::UString& argument) 66{ 67 JSLock lock(SilenceAssertionsOnly); 68 m_arguments.append(jsString(m_exec, argument)); 69} 70 71void ScriptCallArgumentHandler::appendArgument(const char* argument) 72{ 73 JSLock lock(SilenceAssertionsOnly); 74 m_arguments.append(jsString(m_exec, UString(argument))); 75} 76 77void ScriptCallArgumentHandler::appendArgument(JSC::JSValue argument) 78{ 79 m_arguments.append(argument); 80} 81 82void ScriptCallArgumentHandler::appendArgument(long argument) 83{ 84 JSLock lock(SilenceAssertionsOnly); 85 m_arguments.append(jsNumber(argument)); 86} 87 88void ScriptCallArgumentHandler::appendArgument(long long argument) 89{ 90 JSLock lock(SilenceAssertionsOnly); 91 m_arguments.append(jsNumber(argument)); 92} 93 94void ScriptCallArgumentHandler::appendArgument(unsigned int argument) 95{ 96 JSLock lock(SilenceAssertionsOnly); 97 m_arguments.append(jsNumber(argument)); 98} 99 100void ScriptCallArgumentHandler::appendArgument(unsigned long argument) 101{ 102 JSLock lock(SilenceAssertionsOnly); 103 m_arguments.append(jsNumber(argument)); 104} 105 106void ScriptCallArgumentHandler::appendArgument(int argument) 107{ 108 JSLock lock(SilenceAssertionsOnly); 109 m_arguments.append(jsNumber(argument)); 110} 111 112void ScriptCallArgumentHandler::appendArgument(bool argument) 113{ 114 m_arguments.append(jsBoolean(argument)); 115} 116 117ScriptFunctionCall::ScriptFunctionCall(const ScriptObject& thisObject, const String& name) 118 : ScriptCallArgumentHandler(thisObject.scriptState()) 119 , m_thisObject(thisObject) 120 , m_name(name) 121{ 122} 123 124ScriptValue ScriptFunctionCall::call(bool& hadException, bool reportExceptions) 125{ 126 JSObject* thisObject = m_thisObject.jsObject(); 127 128 JSLock lock(SilenceAssertionsOnly); 129 130 JSValue function = thisObject->get(m_exec, Identifier(m_exec, stringToUString(m_name))); 131 if (m_exec->hadException()) { 132 if (reportExceptions) 133 reportException(m_exec, m_exec->exception()); 134 135 hadException = true; 136 return ScriptValue(); 137 } 138 139 CallData callData; 140 CallType callType = getCallData(function, callData); 141 if (callType == CallTypeNone) 142 return ScriptValue(); 143 144 JSValue result = JSMainThreadExecState::call(m_exec, function, callType, callData, thisObject, m_arguments); 145 if (m_exec->hadException()) { 146 if (reportExceptions) 147 reportException(m_exec, m_exec->exception()); 148 149 hadException = true; 150 return ScriptValue(); 151 } 152 153 return ScriptValue(m_exec->globalData(), result); 154} 155 156ScriptValue ScriptFunctionCall::call() 157{ 158 bool hadException = false; 159 return call(hadException); 160} 161 162ScriptObject ScriptFunctionCall::construct(bool& hadException, bool reportExceptions) 163{ 164 JSObject* thisObject = m_thisObject.jsObject(); 165 166 JSLock lock(SilenceAssertionsOnly); 167 168 JSObject* constructor = asObject(thisObject->get(m_exec, Identifier(m_exec, stringToUString(m_name)))); 169 if (m_exec->hadException()) { 170 if (reportExceptions) 171 reportException(m_exec, m_exec->exception()); 172 173 hadException = true; 174 return ScriptObject(); 175 } 176 177 ConstructData constructData; 178 ConstructType constructType = constructor->getConstructData(constructData); 179 if (constructType == ConstructTypeNone) 180 return ScriptObject(); 181 182 JSValue result = JSC::construct(m_exec, constructor, constructType, constructData, m_arguments); 183 if (m_exec->hadException()) { 184 if (reportExceptions) 185 reportException(m_exec, m_exec->exception()); 186 187 hadException = true; 188 return ScriptObject(); 189 } 190 191 return ScriptObject(m_exec, asObject(result)); 192} 193 194ScriptCallback::ScriptCallback(ScriptState* state, ScriptValue function) 195 : ScriptCallArgumentHandler(state) 196 , m_function(function) 197{ 198} 199 200ScriptValue ScriptCallback::call() 201{ 202 bool hadException; 203 return call(hadException); 204} 205 206ScriptValue ScriptCallback::call(bool& hadException) 207{ 208 JSLock lock(SilenceAssertionsOnly); 209 210 CallData callData; 211 CallType callType = getCallData(m_function.jsValue(), callData); 212 if (callType == CallTypeNone) 213 return ScriptValue(); 214 215 JSValue result = JSC::call(m_exec, m_function.jsValue(), callType, callData, m_function.jsValue(), m_arguments); 216 hadException = m_exec->hadException(); 217 218 if (hadException) { 219 reportException(m_exec, m_exec->exception()); 220 return ScriptValue(); 221 } 222 223 return ScriptValue(m_exec->globalData(), result); 224} 225 226} // namespace WebCore 227