Bug 1842773 - Part 32: Allow constructing growable SharedArrayBuffers. r=sfink
[gecko.git] / js / src / vm / JSFunction-inl.h
blobcbf821b720f88e06ae52a7705ca336e9008eefea
1 /* -*- Mode: 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 #ifndef vm_JSFunction_inl_h
8 #define vm_JSFunction_inl_h
10 #include "vm/JSFunction.h"
12 #include "gc/GCProbes.h"
14 #include "gc/ObjectKind-inl.h"
15 #include "vm/JSContext-inl.h"
16 #include "vm/JSObject-inl.h"
17 #include "vm/NativeObject-inl.h"
19 namespace js {
21 inline const char* GetFunctionNameBytes(JSContext* cx, JSFunction* fun,
22 UniqueChars* bytes) {
23 if (fun->isAccessorWithLazyName()) {
24 JSAtom* name = fun->getAccessorNameForLazy(cx);
25 if (!name) {
26 return nullptr;
29 *bytes = StringToNewUTF8CharsZ(cx, *name);
30 return bytes->get();
33 if (JSAtom* name = fun->fullExplicitName()) {
34 *bytes = StringToNewUTF8CharsZ(cx, *name);
35 return bytes->get();
38 return "anonymous";
41 } /* namespace js */
43 /* static */
44 inline JSFunction* JSFunction::create(JSContext* cx, js::gc::AllocKind kind,
45 js::gc::Heap heap,
46 js::Handle<js::SharedShape*> shape) {
47 MOZ_ASSERT(kind == js::gc::AllocKind::FUNCTION ||
48 kind == js::gc::AllocKind::FUNCTION_EXTENDED);
50 debugCheckNewObject(shape, kind, heap);
52 const JSClass* clasp = shape->getObjectClass();
53 MOZ_ASSERT(clasp->isNativeObject());
54 MOZ_ASSERT(clasp->isJSFunction());
55 MOZ_ASSERT_IF(kind == js::gc::AllocKind::FUNCTION,
56 clasp == js::FunctionClassPtr);
57 MOZ_ASSERT_IF(kind == js::gc::AllocKind::FUNCTION_EXTENDED,
58 clasp == js::FunctionExtendedClassPtr);
60 MOZ_ASSERT(calculateDynamicSlots(shape->numFixedSlots(), shape->slotSpan(),
61 clasp) == 0);
63 NativeObject* nobj = cx->newCell<NativeObject>(kind, heap, clasp);
64 if (!nobj) {
65 return nullptr;
68 nobj->initShape(shape);
70 nobj->initEmptyDynamicSlots();
71 nobj->setEmptyElements();
73 JSFunction* fun = static_cast<JSFunction*>(nobj);
74 fun->initFixedSlots(JSCLASS_RESERVED_SLOTS(clasp));
75 fun->initFlagsAndArgCount();
76 fun->initFixedSlot(NativeJitInfoOrInterpretedScriptSlot,
77 JS::PrivateValue(nullptr));
79 if (kind == js::gc::AllocKind::FUNCTION_EXTENDED) {
80 fun->setFlags(FunctionFlags::EXTENDED);
83 MOZ_ASSERT(!clasp->shouldDelayMetadataBuilder(),
84 "Function has no extra data hanging off it, that wouldn't be "
85 "allocated at this point, that would require delaying the "
86 "building of metadata for it");
87 if (MOZ_UNLIKELY(cx->realm()->hasAllocationMetadataBuilder())) {
88 fun = SetNewObjectMetadata(cx, fun);
91 js::gc::gcprobes::CreateObject(fun);
93 return fun;
96 /* static */
97 inline bool JSFunction::getLength(JSContext* cx, js::HandleFunction fun,
98 uint16_t* length) {
99 if (fun->isNativeFun()) {
100 *length = fun->nargs();
101 return true;
104 JSScript* script = getOrCreateScript(cx, fun);
105 if (!script) {
106 return false;
109 *length = script->funLength();
110 return true;
113 /* static */
114 inline bool JSFunction::getUnresolvedLength(JSContext* cx,
115 js::HandleFunction fun,
116 uint16_t* length) {
117 MOZ_ASSERT(!IsInternalFunctionObject(*fun));
118 MOZ_ASSERT(!fun->hasResolvedLength());
120 return JSFunction::getLength(cx, fun, length);
123 inline JSAtom* JSFunction::getUnresolvedName(JSContext* cx) {
124 if (isAccessorWithLazyName()) {
125 return getAccessorNameForLazy(cx);
128 return infallibleGetUnresolvedName(cx);
131 inline JSAtom* JSFunction::infallibleGetUnresolvedName(JSContext* cx) {
132 MOZ_ASSERT(!IsInternalFunctionObject(*this));
133 MOZ_ASSERT(!isAccessorWithLazyName());
134 MOZ_ASSERT(!hasResolvedName());
136 if (JSAtom* name = fullExplicitOrInferredName()) {
137 return name;
140 return cx->names().empty_;
143 /* static */ inline bool JSFunction::getAllocKindForThis(
144 JSContext* cx, js::HandleFunction func, js::gc::AllocKind& allocKind) {
145 JSScript* script = getOrCreateScript(cx, func);
146 if (!script) {
147 return false;
150 size_t propertyCountEstimate =
151 script->immutableScriptData()->propertyCountEstimate;
153 // Choose the alloc assuming at least the default NewObjectKind slots, but
154 // bigger if our estimate shows we need it.
155 allocKind = js::gc::GetGCObjectKind(std::max(
156 js::gc::GetGCKindSlots(js::NewObjectGCKind()), propertyCountEstimate));
157 return true;
160 #endif /* vm_JSFunction_inl_h */