1 /* -*- Mode.h: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 * vim: set ts=8 sts=2 et sw=2 tw=80:
3 * This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include "js/CallAndConstruct.h"
9 #include "mozilla/Assertions.h" // MOZ_ASSERT
11 #include "jstypes.h" // JS_PUBLIC_API
12 #include "gc/Zone.h" // js::Zone
13 #include "js/Context.h" // AssertHeapIsIdle
14 #include "js/friend/ErrorMessages.h" // JSMSG_*
15 #include "js/RootingAPI.h" // JS::Rooted, JS::Handle, JS::MutableHandle
16 #include "js/Value.h" // JS::Value, JS::*Value
17 #include "js/ValueArray.h" // JS::HandleValueArray
18 #include "vm/BytecodeUtil.h" // JSDVG_IGNORE_STACK
19 #include "vm/Interpreter.h" // js::Call, js::Construct
20 #include "vm/JSAtomUtils.h" // js::Atomize
21 #include "vm/JSContext.h" // JSContext, CHECK_THREAD, ReportValueError
22 #include "vm/JSObject.h" // JSObject
23 #include "vm/Stack.h" // js::InvokeArgs, js::FillArgumentsFromArraylike, js::ConstructArgs
24 #include "vm/StringType.h" // JSAtom
26 #include "vm/JSAtomUtils-inl.h" // js::AtomToId
27 #include "vm/JSContext-inl.h" // JSContext::check
28 #include "vm/JSObject-inl.h" // js::IsConstructor
29 #include "vm/ObjectOperations-inl.h" // js::GetProperty
33 JS_PUBLIC_API
bool JS::IsCallable(JSObject
* obj
) { return obj
->isCallable(); }
35 JS_PUBLIC_API
bool JS::IsConstructor(JSObject
* obj
) {
36 return obj
->isConstructor();
39 JS_PUBLIC_API
bool JS_CallFunctionValue(JSContext
* cx
,
40 JS::Handle
<JSObject
*> obj
,
41 JS::Handle
<JS::Value
> fval
,
42 const JS::HandleValueArray
& args
,
43 JS::MutableHandle
<JS::Value
> rval
) {
44 MOZ_ASSERT(!cx
->zone()->isAtomsZone());
47 cx
->check(obj
, fval
, args
);
49 js::InvokeArgs
iargs(cx
);
50 if (!FillArgumentsFromArraylike(cx
, iargs
, args
)) {
54 JS::Rooted
<JS::Value
> thisv(cx
, JS::ObjectOrNullValue(obj
));
55 return js::Call(cx
, fval
, thisv
, iargs
, rval
);
58 JS_PUBLIC_API
bool JS_CallFunction(JSContext
* cx
, JS::Handle
<JSObject
*> obj
,
59 JS::Handle
<JSFunction
*> fun
,
60 const JS::HandleValueArray
& args
,
61 JS::MutableHandle
<JS::Value
> rval
) {
62 MOZ_ASSERT(!cx
->zone()->isAtomsZone());
65 cx
->check(obj
, fun
, args
);
67 js::InvokeArgs
iargs(cx
);
68 if (!FillArgumentsFromArraylike(cx
, iargs
, args
)) {
72 JS::Rooted
<JS::Value
> fval(cx
, JS::ObjectValue(*fun
));
73 JS::Rooted
<JS::Value
> thisv(cx
, JS::ObjectOrNullValue(obj
));
74 return js::Call(cx
, fval
, thisv
, iargs
, rval
);
77 JS_PUBLIC_API
bool JS_CallFunctionName(JSContext
* cx
, JS::Handle
<JSObject
*> obj
,
79 const JS::HandleValueArray
& args
,
80 JS::MutableHandle
<JS::Value
> rval
) {
81 MOZ_ASSERT(!cx
->zone()->isAtomsZone());
86 JSAtom
* atom
= Atomize(cx
, name
, strlen(name
));
91 JS::Rooted
<JS::Value
> fval(cx
);
92 JS::Rooted
<jsid
> id(cx
, AtomToId(atom
));
93 if (!GetProperty(cx
, obj
, obj
, id
, &fval
)) {
97 js::InvokeArgs
iargs(cx
);
98 if (!FillArgumentsFromArraylike(cx
, iargs
, args
)) {
102 JS::Rooted
<JS::Value
> thisv(cx
, JS::ObjectOrNullValue(obj
));
103 return js::Call(cx
, fval
, thisv
, iargs
, rval
);
106 JS_PUBLIC_API
bool JS::Call(JSContext
* cx
, JS::Handle
<JS::Value
> thisv
,
107 JS::Handle
<JS::Value
> fval
,
108 const JS::HandleValueArray
& args
,
109 JS::MutableHandle
<JS::Value
> rval
) {
112 cx
->check(thisv
, fval
, args
);
114 js::InvokeArgs
iargs(cx
);
115 if (!FillArgumentsFromArraylike(cx
, iargs
, args
)) {
119 return js::Call(cx
, fval
, thisv
, iargs
, rval
);
122 JS_PUBLIC_API
bool JS::Construct(JSContext
* cx
, JS::Handle
<JS::Value
> fval
,
123 JS::Handle
<JSObject
*> newTarget
,
124 const JS::HandleValueArray
& args
,
125 JS::MutableHandle
<JSObject
*> objp
) {
128 cx
->check(fval
, newTarget
, args
);
130 if (!js::IsConstructor(fval
)) {
131 ReportValueError(cx
, JSMSG_NOT_CONSTRUCTOR
, JSDVG_IGNORE_STACK
, fval
,
136 JS::Rooted
<JS::Value
> newTargetVal(cx
, JS::ObjectValue(*newTarget
));
137 if (!js::IsConstructor(newTargetVal
)) {
138 ReportValueError(cx
, JSMSG_NOT_CONSTRUCTOR
, JSDVG_IGNORE_STACK
,
139 newTargetVal
, nullptr);
143 js::ConstructArgs
cargs(cx
);
144 if (!FillArgumentsFromArraylike(cx
, cargs
, args
)) {
148 return js::Construct(cx
, fval
, cargs
, newTargetVal
, objp
);
151 JS_PUBLIC_API
bool JS::Construct(JSContext
* cx
, JS::Handle
<JS::Value
> fval
,
152 const JS::HandleValueArray
& args
,
153 JS::MutableHandle
<JSObject
*> objp
) {
156 cx
->check(fval
, args
);
158 if (!js::IsConstructor(fval
)) {
159 ReportValueError(cx
, JSMSG_NOT_CONSTRUCTOR
, JSDVG_IGNORE_STACK
, fval
,
164 js::ConstructArgs
cargs(cx
);
165 if (!FillArgumentsFromArraylike(cx
, cargs
, args
)) {
169 return js::Construct(cx
, fval
, cargs
, fval
, objp
);