1/* 2 * Copyright (C) 2013 Apple 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 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 */ 25 26#ifndef APICallbackFunction_h 27#define APICallbackFunction_h 28 29#include "APICast.h" 30#include "Error.h" 31#include "JSCallbackConstructor.h" 32#include "JSLock.h" 33#include <wtf/Vector.h> 34 35namespace JSC { 36 37struct APICallbackFunction { 38 39template <typename T> static EncodedJSValue JSC_HOST_CALL call(ExecState*); 40template <typename T> static EncodedJSValue JSC_HOST_CALL construct(ExecState*); 41 42}; 43 44template <typename T> 45EncodedJSValue JSC_HOST_CALL APICallbackFunction::call(ExecState* exec) 46{ 47 JSContextRef execRef = toRef(exec); 48 JSObjectRef functionRef = toRef(exec->callee()); 49 JSObjectRef thisObjRef = toRef(jsCast<JSObject*>(exec->thisValue().toThis(exec, NotStrictMode))); 50 51 int argumentCount = static_cast<int>(exec->argumentCount()); 52 Vector<JSValueRef, 16> arguments; 53 arguments.reserveInitialCapacity(argumentCount); 54 for (int i = 0; i < argumentCount; i++) 55 arguments.uncheckedAppend(toRef(exec, exec->uncheckedArgument(i))); 56 57 JSValueRef exception = 0; 58 JSValueRef result; 59 { 60 JSLock::DropAllLocks dropAllLocks(exec); 61 result = jsCast<T*>(toJS(functionRef))->functionCallback()(execRef, functionRef, thisObjRef, argumentCount, arguments.data(), &exception); 62 } 63 if (exception) 64 exec->vm().throwException(exec, toJS(exec, exception)); 65 66 // result must be a valid JSValue. 67 if (!result) 68 return JSValue::encode(jsUndefined()); 69 70 return JSValue::encode(toJS(exec, result)); 71} 72 73template <typename T> 74EncodedJSValue JSC_HOST_CALL APICallbackFunction::construct(ExecState* exec) 75{ 76 JSObject* constructor = exec->callee(); 77 JSContextRef ctx = toRef(exec); 78 JSObjectRef constructorRef = toRef(constructor); 79 80 JSObjectCallAsConstructorCallback callback = jsCast<T*>(constructor)->constructCallback(); 81 if (callback) { 82 size_t argumentCount = exec->argumentCount(); 83 Vector<JSValueRef, 16> arguments; 84 arguments.reserveInitialCapacity(argumentCount); 85 for (size_t i = 0; i < argumentCount; ++i) 86 arguments.uncheckedAppend(toRef(exec, exec->uncheckedArgument(i))); 87 88 JSValueRef exception = 0; 89 JSObjectRef result; 90 { 91 JSLock::DropAllLocks dropAllLocks(exec); 92 result = callback(ctx, constructorRef, argumentCount, arguments.data(), &exception); 93 } 94 if (exception) { 95 exec->vm().throwException(exec, toJS(exec, exception)); 96 return JSValue::encode(toJS(exec, exception)); 97 } 98 // result must be a valid JSValue. 99 if (!result) 100 return throwVMTypeError(exec); 101 return JSValue::encode(toJS(result)); 102 } 103 104 return JSValue::encode(toJS(JSObjectMake(ctx, jsCast<JSCallbackConstructor*>(constructor)->classRef(), 0))); 105} 106 107} // namespace JSC 108 109#endif // APICallbackFunction_h 110