Bug 1708450 - Move call and construct functions into js/public/CallAndConstruct.h. r=nbp

Depends on D119619

Differential Revision: https://phabricator.services.mozilla.com/D119620
This commit is contained in:
Tooru Fujisawa 2021-07-13 11:52:43 +00:00
parent cc92ef732d
commit 8f6310e25c
56 changed files with 401 additions and 295 deletions

View File

@ -10,6 +10,7 @@
#include "mozilla/dom/BindingUtils.h"
#include "mozilla/dom/DOMJSProxyHandler.h"
#include "mozilla/dom/RemoteObjectProxy.h"
#include "js/CallAndConstruct.h" // JS::Call
#include "js/friend/WindowProxy.h" // js::IsWindowProxy
#include "js/Object.h" // JS::GetClass
#include "js/PropertyAndElement.h" // JS_DefineFunctions, JS_DefineProperties

View File

@ -17,6 +17,7 @@
#include "mozilla/ProfilerLabels.h"
#include "base/process_util.h"
#include "chrome/common/ipc_channel.h"
#include "js/CallAndConstruct.h" // JS::IsCallable, JS_CallFunctionValue
#include "js/CompilationAndEvaluation.h"
#include "js/JSON.h"
#include "js/PropertyAndElement.h" // JS_GetProperty

View File

@ -79,6 +79,7 @@
#include "nsJSUtils.h"
#include "jsapi.h"
#include "jsfriendapi.h"
#include "js/CallAndConstruct.h" // JS::Call
#include "js/friend/StackLimits.h" // js::AutoCheckRecursionLimit
#include "js/friend/WindowProxy.h" // js::IsWindowProxy, js::SetWindowProxy
#include "js/PropertyAndElement.h" // JS_DefineObject, JS_GetProperty

View File

@ -21,6 +21,7 @@
#include "mozilla/UseCounter.h"
#include "AccessCheck.h"
#include "js/CallAndConstruct.h" // JS::Call, JS::IsCallable
#include "js/experimental/JitInfo.h" // JSJit{Getter,Setter,Method}CallArgs, JSJit{Getter,Setter}Op, JSJitInfo
#include "js/friend/StackLimits.h" // js::AutoCheckRecursionLimit
#include "js/Id.h"

View File

@ -6,6 +6,7 @@
#include "mozilla/dom/CallbackInterface.h"
#include "jsapi.h"
#include "js/CallAndConstruct.h" // JS::IsCallable
#include "js/CharacterEncoding.h"
#include "js/PropertyAndElement.h" // JS_GetProperty, JS_GetPropertyById
#include "mozilla/dom/BindingUtils.h"

View File

@ -18139,6 +18139,9 @@ class CGBindingRoot(CGThing):
# dependency logic.
bindingHeaders["js/Object.h"] = True
# JS::IsCallable, JS::Call, JS::Construct
bindingHeaders["js/CallAndConstruct.h"] = True
# JS_DefineElement, JS_DefineProperty, JS_DefinePropertyById,
# JS_DefineUCProperty, JS_ForwardGetPropertyTo, JS_GetProperty,
# JS_GetPropertyById, JS_HasPropertyById, JS_SetProperty,

View File

@ -13,6 +13,7 @@
#include "mozilla/ScopeExit.h"
#include "mozJSComponentLoader.h"
#include "jsapi.h"
#include "js/CallAndConstruct.h" // JS::Construct
#include "js/PropertyAndElement.h" // JS_GetProperty
#include "nsContentUtils.h"

View File

@ -10,6 +10,7 @@
#include "AudioParamMap.h"
#include "AudioWorkletImpl.h"
#include "js/Array.h" // JS::{Get,Set}ArrayLength, JS::NewArrayLength
#include "js/CallAndConstruct.h" // JS::Call, JS::IsCallable
#include "js/Exception.h"
#include "js/experimental/TypedData.h" // JS_NewFloat32Array, JS_GetFloat32ArrayData, JS_GetTypedArrayLength, JS_GetArrayBufferViewBuffer
#include "js/PropertyAndElement.h" // JS_DefineElement, JS_DefineUCProperty, JS_GetProperty

View File

@ -8,6 +8,7 @@
#include <utility>
#include "js/CallAndConstruct.h" // JS_CallFunctionValue
#include "js/CompilationAndEvaluation.h"
#include "js/ContextOptions.h"
#include "js/Exception.h"

View File

@ -6,6 +6,7 @@
/* This must occur *after* TestShellParent.h to avoid typedefs conflicts. */
#include "jsfriendapi.h"
#include "js/CallAndConstruct.h" // JS_CallFunctionValue
#include "mozilla/ArrayUtils.h"
#include "mozilla/dom/AutoEntryScript.h"

View File

@ -0,0 +1,143 @@
/* -*- 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<JSObject*> obj, JS::Handle<JS::Value> fval,
const JS::HandleValueArray& args, JS::MutableHandle<JS::Value> rval);
extern JS_PUBLIC_API bool JS_CallFunction(JSContext* cx,
JS::Handle<JSObject*> obj,
JS::Handle<JSFunction*> fun,
const JS::HandleValueArray& args,
JS::MutableHandle<JS::Value> rval);
/**
* Perform the method call `rval = obj[name](args)`.
*/
extern JS_PUBLIC_API bool JS_CallFunctionName(
JSContext* cx, JS::Handle<JSObject*> obj, const char* name,
const JS::HandleValueArray& args, JS::MutableHandle<JS::Value> rval);
namespace JS {
static inline bool Call(JSContext* cx, Handle<JSObject*> thisObj,
Handle<JSFunction*> fun, const HandleValueArray& args,
MutableHandle<Value> rval) {
return !!JS_CallFunction(cx, thisObj, fun, args, rval);
}
static inline bool Call(JSContext* cx, Handle<JSObject*> thisObj,
Handle<Value> fun, const HandleValueArray& args,
MutableHandle<Value> rval) {
return !!JS_CallFunctionValue(cx, thisObj, fun, args, rval);
}
static inline bool Call(JSContext* cx, Handle<JSObject*> thisObj,
const char* name, const HandleValueArray& args,
MutableHandle<Value> rval) {
return !!JS_CallFunctionName(cx, thisObj, name, args, rval);
}
extern JS_PUBLIC_API bool Call(JSContext* cx, Handle<Value> thisv,
Handle<Value> fun, const HandleValueArray& args,
MutableHandle<Value> rval);
static inline bool Call(JSContext* cx, Handle<Value> thisv,
Handle<JSObject*> funObj, const HandleValueArray& args,
MutableHandle<Value> rval) {
MOZ_ASSERT(funObj);
Rooted<Value> 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<Value> fun,
Handle<JSObject*> newTarget,
const HandleValueArray& args,
MutableHandle<JSObject*> 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<Value> fun,
const HandleValueArray& args,
MutableHandle<JSObject*> objp);
} /* namespace JS */
#endif /* js_CallAndConstruct_h */

View File

@ -23,6 +23,7 @@
#include "ds/Sort.h"
#include "gc/Allocator.h"
#include "jit/InlinableNatives.h"
#include "js/CallAndConstruct.h" // JS::Construct, JS::IsCallable, JS::IsConstructor
#include "js/Class.h"
#include "js/Conversions.h"
#include "js/experimental/JitInfo.h" // JSJitGetterOp, JSJitInfo

View File

@ -21,6 +21,7 @@
#include "builtin/Array.h"
#include "jit/AtomicOperations.h"
#include "jit/InlinableNatives.h"
#include "js/CallAndConstruct.h" // JS::Construct
#include "js/Conversions.h"
#include "js/experimental/TypedData.h" // JS_NewDataView
#include "js/friend/ErrorMessages.h" // js::GetErrorMessage, JSMSG_*

View File

@ -18,6 +18,7 @@
#include "builtin/Array.h"
#include "builtin/BigInt.h"
#include "js/CallAndConstruct.h" // JS::IsCallable
#include "js/friend/ErrorMessages.h" // js::GetErrorMessage, JSMSG_*
#include "js/friend/StackLimits.h" // js::AutoCheckRecursionLimit
#include "js/Object.h" // JS::GetBuiltinClass

View File

@ -14,6 +14,7 @@
#include "jsexn.h"
#include "jsfriendapi.h"
#include "js/CallAndConstruct.h" // JS::Construct, JS::IsCallable
#include "js/Debug.h"
#include "js/experimental/JitInfo.h" // JSJitGetterOp, JSJitInfo
#include "js/ForOfIterator.h" // JS::ForOfIterator

View File

@ -62,6 +62,7 @@
#include "jit/TrialInlining.h"
#include "js/Array.h" // JS::NewArrayObject
#include "js/ArrayBuffer.h" // JS::{DetachArrayBuffer,GetArrayBufferLengthAndData,NewArrayBufferWithContents}
#include "js/CallAndConstruct.h" // JS::Call, JS::IsCallable, JS::IsConstructor, JS_CallFunction
#include "js/CharacterEncoding.h"
#include "js/CompilationAndEvaluation.h"
#include "js/CompileOptions.h"

View File

@ -13,14 +13,15 @@
#include "mozilla/Assertions.h" // MOZ_ASSERT
#include "js/Promise.h" // JS::{Resolve,Reject}Promise
#include "js/RootingAPI.h" // JS::Rooted, JS::{,Mutable}Handle
#include "js/Value.h" // JS::UndefinedHandleValue, JS::Value
#include "vm/Compartment.h" // JS::Compartment
#include "vm/Interpreter.h" // js::Call
#include "vm/JSContext.h" // JSContext
#include "vm/JSObject.h" // JSObject
#include "vm/PromiseObject.h" // js::PromiseObject
#include "js/CallAndConstruct.h" // JS::IsCallable
#include "js/Promise.h" // JS::{Resolve,Reject}Promise
#include "js/RootingAPI.h" // JS::Rooted, JS::{,Mutable}Handle
#include "js/Value.h" // JS::UndefinedHandleValue, JS::Value
#include "vm/Compartment.h" // JS::Compartment
#include "vm/Interpreter.h" // js::Call
#include "vm/JSContext.h" // JSContext
#include "vm/JSObject.h" // JSObject
#include "vm/PromiseObject.h" // js::PromiseObject
#include "vm/Compartment-inl.h" // JS::Compartment::wrap
#include "vm/JSContext-inl.h" // JSContext::check

View File

@ -13,6 +13,7 @@
#include "jsapi.h" // JS_ReportErrorNumberASCII
#include "js/CallAndConstruct.h" // JS::IsCallable
#include "js/Conversions.h" // JS::ToNumber
#include "js/friend/ErrorMessages.h" // js::GetErrorMessage, JSMSG_*
#include "js/RootingAPI.h" // JS::{,Mutable}Handle, JS::Rooted

View File

@ -19,6 +19,7 @@
#include "builtin/streams/ReadableStreamInternals.h" // js::ReadableStream{CloseInternal,ErrorInternal,FulfillReadOrReadIntoRequest,GetNumReadRequests}
#include "builtin/streams/ReadableStreamOperations.h" // js::ReadableStreamTee_Pull, js::SetUpReadableStreamDefaultController
#include "builtin/streams/TeeState.h" // js::TeeState
#include "js/CallAndConstruct.h" // JS::IsCallable
#include "js/CallArgs.h" // JS::CallArgs{,FromVp}
#include "js/Promise.h" // JS::AddPromiseReactions
#include "js/RootingAPI.h" // JS::Handle, JS::Rooted

View File

@ -19,6 +19,7 @@
#include "builtin/streams/ReadableStreamInternals.h" // js::ReadableStreamCancel
#include "builtin/streams/ReadableStreamReader.h" // js::CreateReadableStreamDefaultReader, js::ForAuthorCodeBool, js::ReadableStream{,Default}Reader, js::ReadableStreamDefaultReaderRead
#include "builtin/streams/TeeState.h" // js::TeeState
#include "js/CallAndConstruct.h" // JS::IsCallable
#include "js/CallArgs.h" // JS::CallArgs{,FromVp}
#include "js/Promise.h" // JS::CallOriginalPromiseThen, JS::AddPromiseReactions
#include "js/RootingAPI.h" // JS::{,Mutable}Handle, JS::Rooted

View File

@ -17,6 +17,7 @@
#include "builtin/streams/WritableStream.h" // js::WritableStream
#include "builtin/streams/WritableStreamDefaultController.h" // js::WritableStreamDefaultController
#include "builtin/streams/WritableStreamOperations.h" // js::WritableStream{CloseQueuedOrInFlight,DealWithRejection,{Start,Finish}Erroring,UpdateBackpressure,Mark{Close,FirstWrite}RequestInFlight}
#include "js/CallAndConstruct.h" // JS::IsCallable
#include "js/CallArgs.h" // JS::CallArgs{,FromVp}
#include "js/Promise.h" // JS::AddPromiseReactions
#include "js/RootingAPI.h" // JS::Handle, JS::Rooted

View File

@ -41,6 +41,7 @@
#include "jit/AtomicOperations.h"
#include "js/Array.h" // JS::GetArrayLength, JS::IsArrayObject, JS::NewArrayObject
#include "js/ArrayBuffer.h" // JS::{IsArrayBufferObject,GetArrayBufferData,GetArrayBuffer{ByteLength,Data}}
#include "js/CallAndConstruct.h" // JS::IsCallable, JS_CallFunctionValue
#include "js/CharacterEncoding.h"
#include "js/experimental/TypedData.h" // JS_GetArrayBufferView{Type,Data}, JS_GetTypedArrayByteLength, JS_IsArrayBufferViewObject, JS_IsTypedArrayObject
#include "js/friend/ErrorMessages.h" // js::GetErrorMessage, JSMSG_*

View File

@ -61,6 +61,7 @@
#include "jit/JitScript.h" // for JitScript
#include "jit/JSJitFrameIter.h" // for InlineFrameIterator
#include "jit/RematerializedFrame.h" // for RematerializedFrame
#include "js/CallAndConstruct.h" // JS::IsCallable
#include "js/Conversions.h" // for ToBoolean, ToUint32
#include "js/Debug.h" // for Builder::Object, Builder
#include "js/friend/ErrorMessages.h" // for GetErrorMessage, JSMSG_*

View File

@ -20,6 +20,7 @@
#include "jit/JitRuntime.h"
#include "jit/mips32/Simulator-mips32.h"
#include "jit/mips64/Simulator-mips64.h"
#include "js/CallAndConstruct.h" // JS::Construct, JS::IsConstructor
#include "js/friend/ErrorMessages.h" // js::GetErrorMessage, JSMSG_*
#include "js/friend/StackLimits.h" // js::AutoCheckRecursionLimit
#include "js/friend/WindowProxy.h" // js::IsWindow

View File

@ -6,6 +6,7 @@
#include "mozilla/Utf8.h" // mozilla::Utf8Unit
#include "js/CallAndConstruct.h" // JS_CallFunctionValue
#include "js/CompilationAndEvaluation.h" // JS::CompileFunction
#include "js/ContextOptions.h"
#include "js/PropertyAndElement.h" // JS_DefineProperty

View File

@ -4,6 +4,7 @@
#include "jsapi.h"
#include "js/CallAndConstruct.h" // JS::Construct
#include "jsapi-tests/tests.h"
BEGIN_TEST(testDifferentNewTargetInvokeConstructor) {

View File

@ -5,6 +5,7 @@
* 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/. */
#include "js/CallAndConstruct.h" // JS_CallFunctionValue
#include "js/PropertyAndElement.h" // JS_GetProperty
#include "jsapi-tests/tests.h"

View File

@ -2,6 +2,7 @@
* 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/. */
#include "js/CallAndConstruct.h" // JS::IsCallable
#include "js/PropertyDescriptor.h" // JS::FromPropertyDescriptor, JS_GetPropertyDescriptor
#include "js/RootingAPI.h"
#include "jsapi-tests/tests.h"

View File

@ -6,6 +6,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "js/Array.h" // JS::GetArrayLength, JS::IsArrayObject
#include "js/CallAndConstruct.h" // JS::Construct
#include "js/Object.h" // JS::GetClass
#include "js/PropertyAndElement.h" // JS_GetElement, JS_SetElement
#include "jsapi-tests/tests.h"

View File

@ -4,6 +4,7 @@
#include "jsapi.h"
#include "js/CallAndConstruct.h" // JS::Construct
#include "jsapi-tests/tests.h"
BEGIN_TEST(testNewTargetInvokeConstructor) {

View File

@ -50,6 +50,7 @@
#include "gc/WeakMap.h"
#include "jit/JitCommon.h"
#include "jit/JitSpewer.h"
#include "js/CallAndConstruct.h" // JS::IsCallable
#include "js/CharacterEncoding.h"
#include "js/CompilationAndEvaluation.h"
#include "js/CompileOptions.h"
@ -1960,143 +1961,6 @@ JS_PUBLIC_API bool JS_SetImmutablePrototype(JSContext* cx, JS::HandleObject obj,
return SetImmutablePrototype(cx, obj, succeeded);
}
JS_PUBLIC_API bool JS::IsCallable(JSObject* obj) { return obj->isCallable(); }
JS_PUBLIC_API bool JS::IsConstructor(JSObject* obj) {
return obj->isConstructor();
}
JS_PUBLIC_API bool JS_CallFunctionValue(JSContext* cx, HandleObject obj,
HandleValue fval,
const HandleValueArray& args,
MutableHandleValue rval) {
MOZ_ASSERT(!cx->zone()->isAtomsZone());
AssertHeapIsIdle();
CHECK_THREAD(cx);
cx->check(obj, fval, args);
InvokeArgs iargs(cx);
if (!FillArgumentsFromArraylike(cx, iargs, args)) {
return false;
}
RootedValue thisv(cx, ObjectOrNullValue(obj));
return Call(cx, fval, thisv, iargs, rval);
}
JS_PUBLIC_API bool JS_CallFunction(JSContext* cx, HandleObject obj,
HandleFunction fun,
const HandleValueArray& args,
MutableHandleValue rval) {
MOZ_ASSERT(!cx->zone()->isAtomsZone());
AssertHeapIsIdle();
CHECK_THREAD(cx);
cx->check(obj, fun, args);
InvokeArgs iargs(cx);
if (!FillArgumentsFromArraylike(cx, iargs, args)) {
return false;
}
RootedValue fval(cx, ObjectValue(*fun));
RootedValue thisv(cx, ObjectOrNullValue(obj));
return Call(cx, fval, thisv, iargs, rval);
}
JS_PUBLIC_API bool JS_CallFunctionName(JSContext* cx, HandleObject obj,
const char* name,
const HandleValueArray& args,
MutableHandleValue rval) {
MOZ_ASSERT(!cx->zone()->isAtomsZone());
AssertHeapIsIdle();
CHECK_THREAD(cx);
cx->check(obj, args);
JSAtom* atom = Atomize(cx, name, strlen(name));
if (!atom) {
return false;
}
RootedValue fval(cx);
RootedId id(cx, AtomToId(atom));
if (!GetProperty(cx, obj, obj, id, &fval)) {
return false;
}
InvokeArgs iargs(cx);
if (!FillArgumentsFromArraylike(cx, iargs, args)) {
return false;
}
RootedValue thisv(cx, ObjectOrNullValue(obj));
return Call(cx, fval, thisv, iargs, rval);
}
JS_PUBLIC_API bool JS::Call(JSContext* cx, HandleValue thisv, HandleValue fval,
const JS::HandleValueArray& args,
MutableHandleValue rval) {
AssertHeapIsIdle();
CHECK_THREAD(cx);
cx->check(thisv, fval, args);
InvokeArgs iargs(cx);
if (!FillArgumentsFromArraylike(cx, iargs, args)) {
return false;
}
return Call(cx, fval, thisv, iargs, rval);
}
JS_PUBLIC_API bool JS::Construct(JSContext* cx, HandleValue fval,
HandleObject newTarget,
const JS::HandleValueArray& args,
MutableHandleObject objp) {
AssertHeapIsIdle();
CHECK_THREAD(cx);
cx->check(fval, newTarget, args);
if (!IsConstructor(fval)) {
ReportValueError(cx, JSMSG_NOT_CONSTRUCTOR, JSDVG_IGNORE_STACK, fval,
nullptr);
return false;
}
RootedValue newTargetVal(cx, ObjectValue(*newTarget));
if (!IsConstructor(newTargetVal)) {
ReportValueError(cx, JSMSG_NOT_CONSTRUCTOR, JSDVG_IGNORE_STACK,
newTargetVal, nullptr);
return false;
}
ConstructArgs cargs(cx);
if (!FillArgumentsFromArraylike(cx, cargs, args)) {
return false;
}
return js::Construct(cx, fval, cargs, newTargetVal, objp);
}
JS_PUBLIC_API bool JS::Construct(JSContext* cx, HandleValue fval,
const JS::HandleValueArray& args,
MutableHandleObject objp) {
AssertHeapIsIdle();
CHECK_THREAD(cx);
cx->check(fval, args);
if (!IsConstructor(fval)) {
ReportValueError(cx, JSMSG_NOT_CONSTRUCTOR, JSDVG_IGNORE_STACK, fval,
nullptr);
return false;
}
ConstructArgs cargs(cx);
if (!FillArgumentsFromArraylike(cx, cargs, args)) {
return false;
}
return js::Construct(cx, fval, cargs, fval, objp);
}
/* * */
JS_PUBLIC_API bool JS_FreezeObject(JSContext* cx, HandleObject obj) {

View File

@ -27,6 +27,7 @@
#include "jspubtd.h"
#include "js/AllocPolicy.h"
#include "js/CallAndConstruct.h" // JS::Call, JS_CallFunction, JS_CallFunctionName, JS_CallFunctionValue
#include "js/CallArgs.h"
#include "js/CharacterEncoding.h"
#include "js/Class.h"
@ -669,132 +670,6 @@ extern JS_PUBLIC_API bool JS_AssignObject(JSContext* cx,
JS::HandleObject target,
JS::HandleObject src);
/*
* 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::HandleObject obj,
JS::HandleValue fval,
const JS::HandleValueArray& args,
JS::MutableHandleValue rval);
extern JS_PUBLIC_API bool JS_CallFunction(JSContext* cx, JS::HandleObject obj,
JS::HandleFunction fun,
const JS::HandleValueArray& args,
JS::MutableHandleValue rval);
/**
* Perform the method call `rval = obj[name](args)`.
*/
extern JS_PUBLIC_API bool JS_CallFunctionName(JSContext* cx,
JS::HandleObject obj,
const char* name,
const JS::HandleValueArray& args,
JS::MutableHandleValue rval);
namespace JS {
static inline bool Call(JSContext* cx, JS::HandleObject thisObj,
JS::HandleFunction fun,
const JS::HandleValueArray& args,
MutableHandleValue rval) {
return !!JS_CallFunction(cx, thisObj, fun, args, rval);
}
static inline bool Call(JSContext* cx, JS::HandleObject thisObj,
JS::HandleValue fun, const JS::HandleValueArray& args,
MutableHandleValue rval) {
return !!JS_CallFunctionValue(cx, thisObj, fun, args, rval);
}
static inline bool Call(JSContext* cx, JS::HandleObject thisObj,
const char* name, const JS::HandleValueArray& args,
MutableHandleValue rval) {
return !!JS_CallFunctionName(cx, thisObj, name, args, rval);
}
extern JS_PUBLIC_API bool Call(JSContext* cx, JS::HandleValue thisv,
JS::HandleValue fun,
const JS::HandleValueArray& args,
MutableHandleValue rval);
static inline bool Call(JSContext* cx, JS::HandleValue thisv,
JS::HandleObject funObj,
const JS::HandleValueArray& args,
MutableHandleValue rval) {
MOZ_ASSERT(funObj);
JS::RootedValue fun(cx, JS::ObjectValue(*funObj));
return Call(cx, thisv, fun, args, rval);
}
/**
* Invoke a constructor. This is the C++ equivalent of
* `rval = Reflect.construct(fun, args, newTarget)`.
*
* JS::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, JS::HandleValue fun,
HandleObject newTarget,
const JS::HandleValueArray& args,
MutableHandleObject 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, JS::HandleValue fun,
const JS::HandleValueArray& args,
MutableHandleObject objp);
} /* namespace JS */
namespace JS {
/**

View File

@ -33,6 +33,7 @@
#include "jsnum.h"
#include "jstypes.h"
#include "js/CallAndConstruct.h" // JS::IsCallable
#include "js/Conversions.h"
#include "js/Date.h"
#include "js/friend/ErrorMessages.h" // js::GetErrorMessage, JSMSG_*

View File

@ -133,6 +133,7 @@ EXPORTS.js += [
"../public/ArrayBufferMaybeShared.h",
"../public/BigInt.h",
"../public/BuildId.h",
"../public/CallAndConstruct.h",
"../public/CallArgs.h",
"../public/CallNonGenericMethod.h",
"../public/CharacterEncoding.h",
@ -375,6 +376,7 @@ UNIFIED_SOURCES += [
"vm/BytecodeLocation.cpp",
"vm/BytecodeUtil.cpp",
"vm/Caches.cpp",
"vm/CallAndConstruct.cpp",
"vm/CallNonGenericMethod.cpp",
"vm/CharacterEncoding.cpp",
"vm/CodeCoverage.cpp",

View File

@ -10,6 +10,7 @@
#include "jsapi.h"
#include "js/CallAndConstruct.h" // JS::Construct, JS::IsCallable
#include "js/CharacterEncoding.h"
#include "js/friend/ErrorMessages.h" // js::GetErrorMessage, JSMSG_*
#include "js/PropertyDescriptor.h" // JS::FromPropertyDescriptor

View File

@ -8,6 +8,7 @@
#include "jsexn.h"
#include "js/CallAndConstruct.h" // JS::Construct, JS::IsConstructor
#include "js/friend/ErrorMessages.h" // js::GetErrorMessage, JSMSG_*
#include "js/friend/WindowProxy.h" // js::IsWindowProxy
#include "js/Object.h" // JS::GetBuiltinClass

View File

@ -107,6 +107,7 @@
#include "js/Array.h" // JS::NewArrayObject
#include "js/ArrayBuffer.h" // JS::{CreateMappedArrayBufferContents,NewMappedArrayBufferWithContents,IsArrayBufferObject,GetArrayBufferLengthAndData}
#include "js/BuildId.h" // JS::BuildIdCharVector, JS::SetProcessBuildIdOp
#include "js/CallAndConstruct.h" // JS::Call, JS::IsCallable, JS_CallFunction, JS_CallFunctionValue
#include "js/CharacterEncoding.h" // JS::StringIsASCII
#include "js/CompilationAndEvaluation.h"
#include "js/CompileOptions.h"

View File

@ -15,27 +15,28 @@
#include "jsfriendapi.h" // js::WeakMapTracer
#include "jstypes.h" // JS_PUBLIC_API
#include "gc/Allocator.h" // js::CanGC
#include "gc/Cell.h" // js::gc::Cell, js::gc::TenuredCell
#include "gc/GC.h" // js::TraceRuntimeWithoutEviction
#include "gc/Heap.h" // js::gc::Arena
#include "gc/Tracer.h" // js::TraceChildren
#include "gc/WeakMap.h" // js::IterateHeapUnbarriered, js::WeakMapBase
#include "js/GCAPI.h" // JS::GCReason
#include "js/GCVector.h" // JS::RootedVector
#include "js/HeapAPI.h" // JS::GCCellPtr, js::gc::IsInsideNursery
#include "js/Id.h" // JS::PropertyKey
#include "js/RootingAPI.h" // JS::Handle, JS::Rooted
#include "js/TracingAPI.h" // JS::CallbackTracer, JS_GetTraceThingInfo
#include "js/UbiNode.h" // JS::ubi::Node
#include "js/Value.h" // JS::Value
#include "js/Wrapper.h" // js::UncheckedUnwrapWithoutExpose
#include "vm/BigIntType.h" // JS::BigInt::dump
#include "vm/FrameIter.h" // js::AllFramesIter, js::FrameIter
#include "vm/JSContext.h" // JSContext
#include "vm/JSFunction.h" // JSFunction
#include "vm/JSObject.h" // JSObject
#include "vm/JSScript.h" // JSScript
#include "gc/Allocator.h" // js::CanGC
#include "gc/Cell.h" // js::gc::Cell, js::gc::TenuredCell
#include "gc/GC.h" // js::TraceRuntimeWithoutEviction
#include "gc/Heap.h" // js::gc::Arena
#include "gc/Tracer.h" // js::TraceChildren
#include "gc/WeakMap.h" // js::IterateHeapUnbarriered, js::WeakMapBase
#include "js/CallAndConstruct.h" // JS::IsCallable
#include "js/GCAPI.h" // JS::GCReason
#include "js/GCVector.h" // JS::RootedVector
#include "js/HeapAPI.h" // JS::GCCellPtr, js::gc::IsInsideNursery
#include "js/Id.h" // JS::PropertyKey
#include "js/RootingAPI.h" // JS::Handle, JS::Rooted
#include "js/TracingAPI.h" // JS::CallbackTracer, JS_GetTraceThingInfo
#include "js/UbiNode.h" // JS::ubi::Node
#include "js/Value.h" // JS::Value
#include "js/Wrapper.h" // js::UncheckedUnwrapWithoutExpose
#include "vm/BigIntType.h" // JS::BigInt::dump
#include "vm/FrameIter.h" // js::AllFramesIter, js::FrameIter
#include "vm/JSContext.h" // JSContext
#include "vm/JSFunction.h" // JSFunction
#include "vm/JSObject.h" // JSObject
#include "vm/JSScript.h" // JSScript
#include "vm/Printer.h" // js::GenericPrinter, js::QuoteString, js::Sprinter
#include "vm/Realm.h" // JS::Realm
#include "vm/Runtime.h" // JSRuntime

View File

@ -0,0 +1,168 @@
/* -*- Mode.h: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* vim: set ts=8 sts=2 et sw=2 tw=80:
* 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/. */
#include "js/CallAndConstruct.h"
#include "mozilla/Assertions.h" // MOZ_ASSERT
#include "jstypes.h" // JS_PUBLIC_API
#include "gc/Zone.h" // js::Zone
#include "js/Context.h" // AssertHeapIsIdle
#include "js/friend/ErrorMessages.h" // JSMSG_*
#include "js/RootingAPI.h" // JS::Rooted, JS::Handle, JS::MutableHandle
#include "js/Value.h" // JS::Value, JS::*Value
#include "js/ValueArray.h" // JS::HandleValueArray
#include "vm/BytecodeUtil.h" // JSDVG_IGNORE_STACK
#include "vm/Interpreter.h" // js::Call, js::Construct
#include "vm/JSAtom.h" // JSAtom, js::Atomize
#include "vm/JSContext.h" // JSContext, CHECK_THREAD, ReportValueError
#include "vm/JSObject.h" // JSObject
#include "vm/Stack.h" // js::InvokeArgs, js::FillArgumentsFromArraylike, js::ConstructArgs
#include "vm/JSContext-inl.h" // JSContext::check
#include "vm/JSObject-inl.h" // js::IsConstructor
#include "vm/ObjectOperations-inl.h" // js::GetProperty
using namespace js;
JS_PUBLIC_API bool JS::IsCallable(JSObject* obj) { return obj->isCallable(); }
JS_PUBLIC_API bool JS::IsConstructor(JSObject* obj) {
return obj->isConstructor();
}
JS_PUBLIC_API bool JS_CallFunctionValue(JSContext* cx,
JS::Handle<JSObject*> obj,
JS::Handle<JS::Value> fval,
const JS::HandleValueArray& args,
JS::MutableHandle<JS::Value> rval) {
MOZ_ASSERT(!cx->zone()->isAtomsZone());
AssertHeapIsIdle();
CHECK_THREAD(cx);
cx->check(obj, fval, args);
js::InvokeArgs iargs(cx);
if (!FillArgumentsFromArraylike(cx, iargs, args)) {
return false;
}
JS::Rooted<JS::Value> thisv(cx, JS::ObjectOrNullValue(obj));
return js::Call(cx, fval, thisv, iargs, rval);
}
JS_PUBLIC_API bool JS_CallFunction(JSContext* cx, JS::Handle<JSObject*> obj,
JS::Handle<JSFunction*> fun,
const JS::HandleValueArray& args,
JS::MutableHandle<JS::Value> rval) {
MOZ_ASSERT(!cx->zone()->isAtomsZone());
AssertHeapIsIdle();
CHECK_THREAD(cx);
cx->check(obj, fun, args);
js::InvokeArgs iargs(cx);
if (!FillArgumentsFromArraylike(cx, iargs, args)) {
return false;
}
JS::Rooted<JS::Value> fval(cx, JS::ObjectValue(*fun));
JS::Rooted<JS::Value> thisv(cx, JS::ObjectOrNullValue(obj));
return js::Call(cx, fval, thisv, iargs, rval);
}
JS_PUBLIC_API bool JS_CallFunctionName(JSContext* cx, JS::Handle<JSObject*> obj,
const char* name,
const JS::HandleValueArray& args,
JS::MutableHandle<JS::Value> rval) {
MOZ_ASSERT(!cx->zone()->isAtomsZone());
AssertHeapIsIdle();
CHECK_THREAD(cx);
cx->check(obj, args);
JSAtom* atom = Atomize(cx, name, strlen(name));
if (!atom) {
return false;
}
JS::Rooted<JS::Value> fval(cx);
JS::Rooted<jsid> id(cx, AtomToId(atom));
if (!GetProperty(cx, obj, obj, id, &fval)) {
return false;
}
js::InvokeArgs iargs(cx);
if (!FillArgumentsFromArraylike(cx, iargs, args)) {
return false;
}
JS::Rooted<JS::Value> thisv(cx, JS::ObjectOrNullValue(obj));
return js::Call(cx, fval, thisv, iargs, rval);
}
JS_PUBLIC_API bool JS::Call(JSContext* cx, JS::Handle<JS::Value> thisv,
JS::Handle<JS::Value> fval,
const JS::HandleValueArray& args,
JS::MutableHandle<JS::Value> rval) {
AssertHeapIsIdle();
CHECK_THREAD(cx);
cx->check(thisv, fval, args);
js::InvokeArgs iargs(cx);
if (!FillArgumentsFromArraylike(cx, iargs, args)) {
return false;
}
return js::Call(cx, fval, thisv, iargs, rval);
}
JS_PUBLIC_API bool JS::Construct(JSContext* cx, JS::Handle<JS::Value> fval,
JS::Handle<JSObject*> newTarget,
const JS::HandleValueArray& args,
JS::MutableHandle<JSObject*> objp) {
AssertHeapIsIdle();
CHECK_THREAD(cx);
cx->check(fval, newTarget, args);
if (!js::IsConstructor(fval)) {
ReportValueError(cx, JSMSG_NOT_CONSTRUCTOR, JSDVG_IGNORE_STACK, fval,
nullptr);
return false;
}
JS::Rooted<JS::Value> newTargetVal(cx, JS::ObjectValue(*newTarget));
if (!js::IsConstructor(newTargetVal)) {
ReportValueError(cx, JSMSG_NOT_CONSTRUCTOR, JSDVG_IGNORE_STACK,
newTargetVal, nullptr);
return false;
}
js::ConstructArgs cargs(cx);
if (!FillArgumentsFromArraylike(cx, cargs, args)) {
return false;
}
return js::Construct(cx, fval, cargs, newTargetVal, objp);
}
JS_PUBLIC_API bool JS::Construct(JSContext* cx, JS::Handle<JS::Value> fval,
const JS::HandleValueArray& args,
JS::MutableHandle<JSObject*> objp) {
AssertHeapIsIdle();
CHECK_THREAD(cx);
cx->check(fval, args);
if (!js::IsConstructor(fval)) {
ReportValueError(cx, JSMSG_NOT_CONSTRUCTOR, JSDVG_IGNORE_STACK, fval,
nullptr);
return false;
}
js::ConstructArgs cargs(cx);
if (!FillArgumentsFromArraylike(cx, cargs, args)) {
return false;
}
return js::Construct(cx, fval, cargs, fval, objp);
}

View File

@ -33,6 +33,7 @@
#include "jit/IonAnalysis.h"
#include "jit/Jit.h"
#include "jit/JitRuntime.h"
#include "js/CallAndConstruct.h" // JS::Construct, JS::IsCallable, JS::IsConstructor
#include "js/CharacterEncoding.h"
#include "js/experimental/JitInfo.h" // JSJitInfo
#include "js/friend/ErrorMessages.h" // js::GetErrorMessage, JSMSG_*

View File

@ -25,6 +25,7 @@
#include "ds/Sort.h"
#include "gc/FreeOp.h"
#include "gc/Marking.h"
#include "js/CallAndConstruct.h" // JS::IsCallable
#include "js/friend/ErrorMessages.h" // js::GetErrorMessage, JSMSG_*
#include "js/PropertySpec.h"
#include "js/Proxy.h"

View File

@ -40,6 +40,7 @@
#include "jit/Ion.h"
#include "jit/PcScriptCache.h"
#include "jit/Simulator.h"
#include "js/CallAndConstruct.h" // JS::Call
#include "js/CharacterEncoding.h"
#include "js/ContextOptions.h" // JS::ContextOptions
#include "js/friend/ErrorMessages.h" // js::GetErrorMessage, JSMSG_*

View File

@ -35,6 +35,7 @@
#include "gc/Policy.h"
#include "jit/InlinableNatives.h"
#include "jit/Ion.h"
#include "js/CallAndConstruct.h" // JS::IsCallable
#include "js/CallNonGenericMethod.h"
#include "js/CompilationAndEvaluation.h"
#include "js/CompileOptions.h"

View File

@ -35,6 +35,7 @@
#include "frontend/BytecodeCompiler.h"
#include "gc/Policy.h"
#include "jit/BaselineJIT.h"
#include "js/CallAndConstruct.h" // JS::IsCallable, JS::IsConstructor
#include "js/CharacterEncoding.h"
#include "js/friend/DumpFunctions.h" // js::DumpObject
#include "js/friend/ErrorMessages.h" // JSErrNum, js::GetErrorMessage, JSMSG_*

View File

@ -20,6 +20,7 @@
#include "jit/JitOptions.h"
#include "jit/JitRealm.h"
#include "jit/JitRuntime.h"
#include "js/CallAndConstruct.h" // JS::IsCallable
#include "js/Date.h"
#include "js/friend/ErrorMessages.h" // js::GetErrorMessage, JSMSG_*
#include "js/Proxy.h"

View File

@ -48,6 +48,7 @@
#include "gc/Policy.h"
#include "jit/AtomicOperations.h"
#include "jit/InlinableNatives.h"
#include "js/CallAndConstruct.h" // JS::Construct, JS::IsCallable, JS::IsConstructor
#include "js/CharacterEncoding.h"
#include "js/CompilationAndEvaluation.h"
#include "js/Conversions.h"

View File

@ -18,6 +18,7 @@
#include "builtin/Boolean.h" // BooleanToString
#include "builtin/Object.h" // ObjectToSource
#include "gc/Allocator.h" // CanGC
#include "js/CallAndConstruct.h" // JS::IsCallable
#include "js/Class.h" // ESClass
#include "js/friend/StackLimits.h" // js::AutoCheckRecursionLimit
#include "js/Object.h" // JS::GetBuiltinClass

View File

@ -8,6 +8,7 @@
#include "WrapperFactory.h"
#include "AccessCheck.h"
#include "jsfriendapi.h"
#include "js/CallAndConstruct.h" // JS::Call, JS::Construct, JS::IsCallable
#include "js/Exception.h"
#include "js/PropertyAndElement.h" // JS_DefineProperty, JS_DefinePropertyById
#include "js/Proxy.h"

View File

@ -10,7 +10,8 @@
#include "AccessCheck.h"
#include "jsfriendapi.h"
#include "js/Array.h" // JS::GetArrayLength, JS::IsArrayObject
#include "js/Array.h" // JS::GetArrayLength, JS::IsArrayObject
#include "js/CallAndConstruct.h" // JS::Call, JS::IsCallable
#include "js/CharacterEncoding.h"
#include "js/CompilationAndEvaluation.h"
#include "js/Object.h" // JS::GetClass, JS::GetCompartment, JS::GetReservedSlot

View File

@ -17,6 +17,7 @@
#include "nsCycleCollector.h"
#include "jsfriendapi.h"
#include "js/Array.h" // JS::IsArrayObject
#include "js/CallAndConstruct.h" // JS::IsCallable, JS_CallFunctionName, JS_CallFunctionValue
#include "js/CharacterEncoding.h"
#include "js/ContextOptions.h"
#include "js/friend/WindowProxy.h" // js::ToWindowProxyIfWindow

View File

@ -7,7 +7,8 @@
#include "nsXULAppAPI.h"
#include "jsapi.h"
#include "jsfriendapi.h"
#include "js/Array.h" // JS::NewArrayObject
#include "js/Array.h" // JS::NewArrayObject
#include "js/CallAndConstruct.h" // JS_CallFunctionValue
#include "js/CharacterEncoding.h"
#include "js/CompilationAndEvaluation.h" // JS::Evaluate
#include "js/ContextOptions.h"

View File

@ -7,7 +7,8 @@
/* Sharable code and data for wrapper around JSObjects. */
#include "xpcprivate.h"
#include "js/Object.h" // JS::GetClass
#include "js/CallAndConstruct.h" // JS_CallFunctionValue
#include "js/Object.h" // JS::GetClass
#include "js/Printf.h"
#include "js/PropertyAndElement.h" // JS_Enumerate, JS_GetProperty, JS_GetPropertyById, JS_HasProperty, JS_HasPropertyById, JS_SetProperty, JS_SetPropertyById
#include "nsArrayEnumerator.h"

View File

@ -7,6 +7,7 @@
#include "WaiveXrayWrapper.h"
#include "WrapperFactory.h"
#include "jsapi.h"
#include "js/CallAndConstruct.h" // JS::IsCallable
using namespace JS;

View File

@ -19,6 +19,7 @@
#include "xpcprivate.h"
#include "jsapi.h"
#include "js/CallAndConstruct.h" // JS::Call, JS::Construct, JS::IsCallable
#include "js/experimental/TypedData.h" // JS_GetTypedArrayLength
#include "js/friend/WindowProxy.h" // js::IsWindowProxy
#include "js/friend/XrayJitInfo.h" // JS::XrayJitInfo

View File

@ -15,6 +15,7 @@
#include "nsIURLParser.h"
#include "nsJSUtils.h"
#include "jsfriendapi.h"
#include "js/CallAndConstruct.h" // JS_CallFunctionName
#include "js/CompilationAndEvaluation.h" // JS::Compile
#include "js/ContextOptions.h"
#include "js/Initialization.h"

View File

@ -17,6 +17,8 @@
#include "mozilla/dom/SerializedStackHolder.h"
#include "mozilla/dom/FunctionBinding.h"
#include "js/CallAndConstruct.h" // JS::IsCallable
namespace mozilla {
namespace extensions {