CallAndConstruct.h (5485B)
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* This Source Code Form is subject to the terms of the Mozilla Public 3 * License, v. 2.0. If a copy of the MPL was not distributed with this 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 5 6 /* Call and construct API. */ 7 8 #ifndef js_CallAndConstruct_h 9 #define js_CallAndConstruct_h 10 11 #include "mozilla/Assertions.h" // MOZ_ASSERT 12 13 #include "jstypes.h" // JS_PUBLIC_API 14 15 #include "js/RootingAPI.h" // JS::Handle, JS::MutableHandle 16 #include "js/Value.h" // JS::Value, JS::ObjectValue 17 #include "js/ValueArray.h" // JS::HandleValueArray 18 19 struct JSContext; 20 class JSObject; 21 class JSFunction; 22 23 /* 24 * API for determining callability and constructability. [[Call]] and 25 * [[Construct]] are internal methods that aren't present on all objects, so it 26 * is useful to ask if they are there or not. The standard itself asks these 27 * questions routinely. 28 */ 29 namespace JS { 30 31 /** 32 * Return true if the given object is callable. In ES6 terms, an object is 33 * callable if it has a [[Call]] internal method. 34 * 35 * Implements: ES6 7.2.3 IsCallable(argument). 36 * 37 * Functions are callable. A scripted proxy or wrapper is callable if its 38 * target is callable. Most other objects aren't callable. 39 */ 40 extern JS_PUBLIC_API bool IsCallable(JSObject* obj); 41 42 /** 43 * Return true if the given object is a constructor. In ES6 terms, an object is 44 * a constructor if it has a [[Construct]] internal method. The expression 45 * `new obj()` throws a TypeError if obj is not a constructor. 46 * 47 * Implements: ES6 7.2.4 IsConstructor(argument). 48 * 49 * JS functions and classes are constructors. Arrow functions and most builtin 50 * functions are not. A scripted proxy or wrapper is a constructor if its 51 * target is a constructor. 52 */ 53 extern JS_PUBLIC_API bool IsConstructor(JSObject* obj); 54 55 } /* namespace JS */ 56 57 /** 58 * Call a function, passing a this-value and arguments. This is the C++ 59 * equivalent of `rval = Reflect.apply(fun, obj, args)`. 60 * 61 * Implements: ES6 7.3.12 Call(F, V, [argumentsList]). 62 * Use this function to invoke the [[Call]] internal method. 63 */ 64 extern JS_PUBLIC_API bool JS_CallFunctionValue( 65 JSContext* cx, JS::Handle<JSObject*> obj, JS::Handle<JS::Value> fval, 66 const JS::HandleValueArray& args, JS::MutableHandle<JS::Value> rval); 67 68 extern JS_PUBLIC_API bool JS_CallFunction(JSContext* cx, 69 JS::Handle<JSObject*> obj, 70 JS::Handle<JSFunction*> fun, 71 const JS::HandleValueArray& args, 72 JS::MutableHandle<JS::Value> rval); 73 74 /** 75 * Perform the method call `rval = obj[name](args)`. 76 */ 77 extern JS_PUBLIC_API bool JS_CallFunctionName( 78 JSContext* cx, JS::Handle<JSObject*> obj, const char* name, 79 const JS::HandleValueArray& args, JS::MutableHandle<JS::Value> rval); 80 81 namespace JS { 82 83 static inline bool Call(JSContext* cx, Handle<JSObject*> thisObj, 84 Handle<JSFunction*> fun, const HandleValueArray& args, 85 MutableHandle<Value> rval) { 86 return !!JS_CallFunction(cx, thisObj, fun, args, rval); 87 } 88 89 static inline bool Call(JSContext* cx, Handle<JSObject*> thisObj, 90 Handle<Value> fun, const HandleValueArray& args, 91 MutableHandle<Value> rval) { 92 return !!JS_CallFunctionValue(cx, thisObj, fun, args, rval); 93 } 94 95 static inline bool Call(JSContext* cx, Handle<JSObject*> thisObj, 96 const char* name, const HandleValueArray& args, 97 MutableHandle<Value> rval) { 98 return !!JS_CallFunctionName(cx, thisObj, name, args, rval); 99 } 100 101 extern JS_PUBLIC_API bool Call(JSContext* cx, Handle<Value> thisv, 102 Handle<Value> fun, const HandleValueArray& args, 103 MutableHandle<Value> rval); 104 105 static inline bool Call(JSContext* cx, Handle<Value> thisv, 106 Handle<JSObject*> funObj, const HandleValueArray& args, 107 MutableHandle<Value> rval) { 108 MOZ_ASSERT(funObj); 109 Rooted<Value> fun(cx, ObjectValue(*funObj)); 110 return Call(cx, thisv, fun, args, rval); 111 } 112 113 /** 114 * Invoke a constructor. This is the C++ equivalent of 115 * `rval = Reflect.construct(fun, args, newTarget)`. 116 * 117 * Construct() takes a `newTarget` argument that most callers don't need. 118 * Consider using the four-argument Construct signature instead. (But if you're 119 * implementing a subclass or a proxy handler's construct() method, this is the 120 * right function to call.) 121 * 122 * Implements: ES6 7.3.13 Construct(F, [argumentsList], [newTarget]). 123 * Use this function to invoke the [[Construct]] internal method. 124 */ 125 extern JS_PUBLIC_API bool Construct(JSContext* cx, Handle<Value> fun, 126 Handle<JSObject*> newTarget, 127 const HandleValueArray& args, 128 MutableHandle<JSObject*> objp); 129 130 /** 131 * Invoke a constructor. This is the C++ equivalent of 132 * `rval = new fun(...args)`. 133 * 134 * Implements: ES6 7.3.13 Construct(F, [argumentsList], [newTarget]), when 135 * newTarget is omitted. 136 */ 137 extern JS_PUBLIC_API bool Construct(JSContext* cx, Handle<Value> fun, 138 const HandleValueArray& args, 139 MutableHandle<JSObject*> objp); 140 141 } /* namespace JS */ 142 143 #endif /* js_CallAndConstruct_h */