Bug 1913305 - Add test. r=mtigley
[gecko.git] / js / public / CallAndConstruct.h
blobcd3007cbb901ee813a72517277e9a66e803d9465
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/. */
6 /* Call and construct API. */
8 #ifndef js_CallAndConstruct_h
9 #define js_CallAndConstruct_h
11 #include "mozilla/Assertions.h" // MOZ_ASSERT
13 #include "jstypes.h" // JS_PUBLIC_API
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
19 struct JSContext;
20 class JSObject;
21 class JSFunction;
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.
29 namespace JS {
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.
35 * Implements: ES6 7.2.3 IsCallable(argument).
37 * Functions are callable. A scripted proxy or wrapper is callable if its
38 * target is callable. Most other objects aren't callable.
40 extern JS_PUBLIC_API bool IsCallable(JSObject* obj);
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.
47 * Implements: ES6 7.2.4 IsConstructor(argument).
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.
53 extern JS_PUBLIC_API bool IsConstructor(JSObject* obj);
55 } /* namespace JS */
57 /**
58 * Call a function, passing a this-value and arguments. This is the C++
59 * equivalent of `rval = Reflect.apply(fun, obj, args)`.
61 * Implements: ES6 7.3.12 Call(F, V, [argumentsList]).
62 * Use this function to invoke the [[Call]] internal method.
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);
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);
74 /**
75 * Perform the method call `rval = obj[name](args)`.
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);
81 namespace JS {
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);
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);
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);
101 extern JS_PUBLIC_API bool Call(JSContext* cx, Handle<Value> thisv,
102 Handle<Value> fun, const HandleValueArray& args,
103 MutableHandle<Value> rval);
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);
114 * Invoke a constructor. This is the C++ equivalent of
115 * `rval = Reflect.construct(fun, args, newTarget)`.
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.)
122 * Implements: ES6 7.3.13 Construct(F, [argumentsList], [newTarget]).
123 * Use this function to invoke the [[Construct]] internal method.
125 extern JS_PUBLIC_API bool Construct(JSContext* cx, Handle<Value> fun,
126 Handle<JSObject*> newTarget,
127 const HandleValueArray& args,
128 MutableHandle<JSObject*> objp);
131 * Invoke a constructor. This is the C++ equivalent of
132 * `rval = new fun(...args)`.
134 * Implements: ES6 7.3.13 Construct(F, [argumentsList], [newTarget]), when
135 * newTarget is omitted.
137 extern JS_PUBLIC_API bool Construct(JSContext* cx, Handle<Value> fun,
138 const HandleValueArray& args,
139 MutableHandle<JSObject*> objp);
141 } /* namespace JS */
143 #endif /* js_CallAndConstruct_h */