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"
21 inline const char* GetFunctionNameBytes(JSContext
* cx
, JSFunction
* fun
,
23 if (fun
->isAccessorWithLazyName()) {
24 JSAtom
* name
= fun
->getAccessorNameForLazy(cx
);
29 *bytes
= StringToNewUTF8CharsZ(cx
, *name
);
33 if (JSAtom
* name
= fun
->fullExplicitName()) {
34 *bytes
= StringToNewUTF8CharsZ(cx
, *name
);
44 inline JSFunction
* JSFunction::create(JSContext
* cx
, js::gc::AllocKind kind
,
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(),
63 NativeObject
* nobj
= cx
->newCell
<NativeObject
>(kind
, heap
, clasp
);
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
);
97 inline bool JSFunction::getLength(JSContext
* cx
, js::HandleFunction fun
,
99 if (fun
->isNativeFun()) {
100 *length
= fun
->nargs();
104 JSScript
* script
= getOrCreateScript(cx
, fun
);
109 *length
= script
->funLength();
114 inline bool JSFunction::getUnresolvedLength(JSContext
* cx
,
115 js::HandleFunction fun
,
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()) {
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
);
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
));
160 #endif /* vm_JSFunction_inl_h */