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 41 using namespace JSC; 42 43 namespace WebCore { 44 45 void 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 54 void ScriptCallArgumentHandler::appendArgument(const ScriptValue& argument) 55 { 56 m_arguments.append(argument.jsValue()); 57 } 58 59 void ScriptCallArgumentHandler::appendArgument(const String& argument) 60 { 61 JSLock lock(SilenceAssertionsOnly); 62 m_arguments.append(jsString(m_exec, argument)); 63 } 64 65 void ScriptCallArgumentHandler::appendArgument(const JSC::UString& argument) 66 { 67 JSLock lock(SilenceAssertionsOnly); 68 m_arguments.append(jsString(m_exec, argument)); 69 } 70 71 void ScriptCallArgumentHandler::appendArgument(const char* argument) 72 { 73 JSLock lock(SilenceAssertionsOnly); 74 m_arguments.append(jsString(m_exec, UString(argument))); 75 } 76 77 void ScriptCallArgumentHandler::appendArgument(JSC::JSValue argument) 78 { 79 m_arguments.append(argument); 80 } 81 82 void ScriptCallArgumentHandler::appendArgument(long argument) 83 { 84 JSLock lock(SilenceAssertionsOnly); 85 m_arguments.append(jsNumber(argument)); 86 } 87 88 void ScriptCallArgumentHandler::appendArgument(long long argument) 89 { 90 JSLock lock(SilenceAssertionsOnly); 91 m_arguments.append(jsNumber(argument)); 92 } 93 94 void ScriptCallArgumentHandler::appendArgument(unsigned int argument) 95 { 96 JSLock lock(SilenceAssertionsOnly); 97 m_arguments.append(jsNumber(argument)); 98 } 99 100 void ScriptCallArgumentHandler::appendArgument(unsigned long argument) 101 { 102 JSLock lock(SilenceAssertionsOnly); 103 m_arguments.append(jsNumber(argument)); 104 } 105 106 void ScriptCallArgumentHandler::appendArgument(int argument) 107 { 108 JSLock lock(SilenceAssertionsOnly); 109 m_arguments.append(jsNumber(argument)); 110 } 111 112 void ScriptCallArgumentHandler::appendArgument(bool argument) 113 { 114 m_arguments.append(jsBoolean(argument)); 115 } 116 117 ScriptFunctionCall::ScriptFunctionCall(const ScriptObject& thisObject, const String& name) 118 : ScriptCallArgumentHandler(thisObject.scriptState()) 119 , m_thisObject(thisObject) 120 , m_name(name) 121 { 122 } 123 124 ScriptValue 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 156 ScriptValue ScriptFunctionCall::call() 157 { 158 bool hadException = false; 159 return call(hadException); 160 } 161 162 ScriptObject 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 194 ScriptCallback::ScriptCallback(ScriptState* state, ScriptValue function) 195 : ScriptCallArgumentHandler(state) 196 , m_function(function) 197 { 198 } 199 200 ScriptValue ScriptCallback::call() 201 { 202 bool hadException; 203 return call(hadException); 204 } 205 206 ScriptValue 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