/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /* Call and construct API. */ #ifndef js_CallAndConstruct_h #define js_CallAndConstruct_h #include "mozilla/Assertions.h" // MOZ_ASSERT #include "jstypes.h" // JS_PUBLIC_API #include "js/RootingAPI.h" // JS::Handle, JS::MutableHandle #include "js/Value.h" // JS::Value, JS::ObjectValue #include "js/ValueArray.h" // JS::HandleValueArray struct JSContext; class JSObject; class JSFunction; /* * API for determining callability and constructability. [[Call]] and * [[Construct]] are internal methods that aren't present on all objects, so it * is useful to ask if they are there or not. The standard itself asks these * questions routinely. */ namespace JS { /** * Return true if the given object is callable. In ES6 terms, an object is * callable if it has a [[Call]] internal method. * * Implements: ES6 7.2.3 IsCallable(argument). * * Functions are callable. A scripted proxy or wrapper is callable if its * target is callable. Most other objects aren't callable. */ extern JS_PUBLIC_API bool IsCallable(JSObject* obj); /** * Return true if the given object is a constructor. In ES6 terms, an object is * a constructor if it has a [[Construct]] internal method. The expression * `new obj()` throws a TypeError if obj is not a constructor. * * Implements: ES6 7.2.4 IsConstructor(argument). * * JS functions and classes are constructors. Arrow functions and most builtin * functions are not. A scripted proxy or wrapper is a constructor if its * target is a constructor. */ extern JS_PUBLIC_API bool IsConstructor(JSObject* obj); } /* namespace JS */ /** * Call a function, passing a this-value and arguments. This is the C++ * equivalent of `rval = Reflect.apply(fun, obj, args)`. * * Implements: ES6 7.3.12 Call(F, V, [argumentsList]). * Use this function to invoke the [[Call]] internal method. */ extern JS_PUBLIC_API bool JS_CallFunctionValue( JSContext* cx, JS::Handle obj, JS::Handle fval, const JS::HandleValueArray& args, JS::MutableHandle rval); extern JS_PUBLIC_API bool JS_CallFunction(JSContext* cx, JS::Handle obj, JS::Handle fun, const JS::HandleValueArray& args, JS::MutableHandle rval); /** * Perform the method call `rval = obj[name](args)`. */ extern JS_PUBLIC_API bool JS_CallFunctionName( JSContext* cx, JS::Handle obj, const char* name, const JS::HandleValueArray& args, JS::MutableHandle rval); namespace JS { static inline bool Call(JSContext* cx, Handle thisObj, Handle fun, const HandleValueArray& args, MutableHandle rval) { return !!JS_CallFunction(cx, thisObj, fun, args, rval); } static inline bool Call(JSContext* cx, Handle thisObj, Handle fun, const HandleValueArray& args, MutableHandle rval) { return !!JS_CallFunctionValue(cx, thisObj, fun, args, rval); } static inline bool Call(JSContext* cx, Handle thisObj, const char* name, const HandleValueArray& args, MutableHandle rval) { return !!JS_CallFunctionName(cx, thisObj, name, args, rval); } extern JS_PUBLIC_API bool Call(JSContext* cx, Handle thisv, Handle fun, const HandleValueArray& args, MutableHandle rval); static inline bool Call(JSContext* cx, Handle thisv, Handle funObj, const HandleValueArray& args, MutableHandle rval) { MOZ_ASSERT(funObj); Rooted fun(cx, ObjectValue(*funObj)); return Call(cx, thisv, fun, args, rval); } /** * Invoke a constructor. This is the C++ equivalent of * `rval = Reflect.construct(fun, args, newTarget)`. * * Construct() takes a `newTarget` argument that most callers don't need. * Consider using the four-argument Construct signature instead. (But if you're * implementing a subclass or a proxy handler's construct() method, this is the * right function to call.) * * Implements: ES6 7.3.13 Construct(F, [argumentsList], [newTarget]). * Use this function to invoke the [[Construct]] internal method. */ extern JS_PUBLIC_API bool Construct(JSContext* cx, Handle fun, Handle newTarget, const HandleValueArray& args, MutableHandle objp); /** * Invoke a constructor. This is the C++ equivalent of * `rval = new fun(...args)`. * * Implements: ES6 7.3.13 Construct(F, [argumentsList], [newTarget]), when * newTarget is omitted. */ extern JS_PUBLIC_API bool Construct(JSContext* cx, Handle fun, const HandleValueArray& args, MutableHandle objp); } /* namespace JS */ #endif /* js_CallAndConstruct_h */