Backed out changeset 8f976ed899d7 (bug 1847231) for causing bc failures on browser_se...
[gecko.git] / js / src / vm / CallAndConstruct.cpp
blob53a9345f8b0a1a7935abb0989f9ec0ffb7773fbe
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
31 using namespace js;
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());
45 AssertHeapIsIdle();
46 CHECK_THREAD(cx);
47 cx->check(obj, fval, args);
49 js::InvokeArgs iargs(cx);
50 if (!FillArgumentsFromArraylike(cx, iargs, args)) {
51 return false;
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());
63 AssertHeapIsIdle();
64 CHECK_THREAD(cx);
65 cx->check(obj, fun, args);
67 js::InvokeArgs iargs(cx);
68 if (!FillArgumentsFromArraylike(cx, iargs, args)) {
69 return false;
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,
78 const char* name,
79 const JS::HandleValueArray& args,
80 JS::MutableHandle<JS::Value> rval) {
81 MOZ_ASSERT(!cx->zone()->isAtomsZone());
82 AssertHeapIsIdle();
83 CHECK_THREAD(cx);
84 cx->check(obj, args);
86 JSAtom* atom = Atomize(cx, name, strlen(name));
87 if (!atom) {
88 return false;
91 JS::Rooted<JS::Value> fval(cx);
92 JS::Rooted<jsid> id(cx, AtomToId(atom));
93 if (!GetProperty(cx, obj, obj, id, &fval)) {
94 return false;
97 js::InvokeArgs iargs(cx);
98 if (!FillArgumentsFromArraylike(cx, iargs, args)) {
99 return false;
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) {
110 AssertHeapIsIdle();
111 CHECK_THREAD(cx);
112 cx->check(thisv, fval, args);
114 js::InvokeArgs iargs(cx);
115 if (!FillArgumentsFromArraylike(cx, iargs, args)) {
116 return false;
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) {
126 AssertHeapIsIdle();
127 CHECK_THREAD(cx);
128 cx->check(fval, newTarget, args);
130 if (!js::IsConstructor(fval)) {
131 ReportValueError(cx, JSMSG_NOT_CONSTRUCTOR, JSDVG_IGNORE_STACK, fval,
132 nullptr);
133 return false;
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);
140 return false;
143 js::ConstructArgs cargs(cx);
144 if (!FillArgumentsFromArraylike(cx, cargs, args)) {
145 return false;
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) {
154 AssertHeapIsIdle();
155 CHECK_THREAD(cx);
156 cx->check(fval, args);
158 if (!js::IsConstructor(fval)) {
159 ReportValueError(cx, JSMSG_NOT_CONSTRUCTOR, JSDVG_IGNORE_STACK, fval,
160 nullptr);
161 return false;
164 js::ConstructArgs cargs(cx);
165 if (!FillArgumentsFromArraylike(cx, cargs, args)) {
166 return false;
169 return js::Construct(cx, fval, cargs, fval, objp);