diff options
Diffstat (limited to 'js/src/vm/JSFunction-inl.h')
-rw-r--r-- | js/src/vm/JSFunction-inl.h | 141 |
1 files changed, 141 insertions, 0 deletions
diff --git a/js/src/vm/JSFunction-inl.h b/js/src/vm/JSFunction-inl.h new file mode 100644 index 0000000000..39563bbd67 --- /dev/null +++ b/js/src/vm/JSFunction-inl.h @@ -0,0 +1,141 @@ +/* -*- Mode: 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/. */ + +#ifndef vm_JSFunction_inl_h +#define vm_JSFunction_inl_h + +#include "vm/JSFunction.h" + +#include "gc/Allocator.h" +#include "gc/GCProbes.h" +#include "vm/WellKnownAtom.h" // js_*_str + +#include "gc/ObjectKind-inl.h" +#include "vm/JSObject-inl.h" +#include "vm/NativeObject-inl.h" + +namespace js { + +inline const char* GetFunctionNameBytes(JSContext* cx, JSFunction* fun, + UniqueChars* bytes) { + if (JSAtom* name = fun->explicitName()) { + *bytes = StringToNewUTF8CharsZ(cx, *name); + return bytes->get(); + } + return js_anonymous_str; +} + +} /* namespace js */ + +/* static */ +inline JSFunction* JSFunction::create(JSContext* cx, js::gc::AllocKind kind, + js::gc::Heap heap, + js::Handle<js::SharedShape*> shape) { + MOZ_ASSERT(kind == js::gc::AllocKind::FUNCTION || + kind == js::gc::AllocKind::FUNCTION_EXTENDED); + + debugCheckNewObject(shape, kind, heap); + + const JSClass* clasp = shape->getObjectClass(); + MOZ_ASSERT(clasp->isNativeObject()); + MOZ_ASSERT(clasp->isJSFunction()); + MOZ_ASSERT_IF(kind == js::gc::AllocKind::FUNCTION, + clasp == js::FunctionClassPtr); + MOZ_ASSERT_IF(kind == js::gc::AllocKind::FUNCTION_EXTENDED, + clasp == js::FunctionExtendedClassPtr); + + MOZ_ASSERT(calculateDynamicSlots(shape->numFixedSlots(), shape->slotSpan(), + clasp) == 0); + + NativeObject* nobj = cx->newCell<NativeObject>(kind, heap, clasp); + if (!nobj) { + return nullptr; + } + + nobj->initShape(shape); + + nobj->initEmptyDynamicSlots(); + nobj->setEmptyElements(); + + JSFunction* fun = static_cast<JSFunction*>(nobj); + fun->initFixedSlots(JSCLASS_RESERVED_SLOTS(clasp)); + fun->initFlagsAndArgCount(); + fun->initFixedSlot(NativeJitInfoOrInterpretedScriptSlot, + JS::PrivateValue(nullptr)); + + if (kind == js::gc::AllocKind::FUNCTION_EXTENDED) { + fun->setFlags(FunctionFlags::EXTENDED); + } + + MOZ_ASSERT(!clasp->shouldDelayMetadataBuilder(), + "Function has no extra data hanging off it, that wouldn't be " + "allocated at this point, that would require delaying the " + "building of metadata for it"); + if (MOZ_UNLIKELY(cx->realm()->hasAllocationMetadataBuilder())) { + fun = SetNewObjectMetadata(cx, fun); + } + + js::gc::gcprobes::CreateObject(fun); + + return fun; +} + +/* static */ +inline bool JSFunction::getLength(JSContext* cx, js::HandleFunction fun, + uint16_t* length) { + if (fun->isNativeFun()) { + *length = fun->nargs(); + return true; + } + + JSScript* script = getOrCreateScript(cx, fun); + if (!script) { + return false; + } + + *length = script->funLength(); + return true; +} + +/* static */ +inline bool JSFunction::getUnresolvedLength(JSContext* cx, + js::HandleFunction fun, + uint16_t* length) { + MOZ_ASSERT(!IsInternalFunctionObject(*fun)); + MOZ_ASSERT(!fun->hasResolvedLength()); + + return JSFunction::getLength(cx, fun, length); +} + +inline JSAtom* JSFunction::infallibleGetUnresolvedName(JSContext* cx) { + MOZ_ASSERT(!IsInternalFunctionObject(*this)); + MOZ_ASSERT(!hasResolvedName()); + + if (JSAtom* name = explicitOrInferredName()) { + return name; + } + + return cx->names().empty; +} + +/* static */ inline bool JSFunction::getAllocKindForThis( + JSContext* cx, js::HandleFunction func, js::gc::AllocKind& allocKind) { + JSScript* script = getOrCreateScript(cx, func); + if (!script) { + return false; + } + + size_t propertyCountEstimate = + script->immutableScriptData()->propertyCountEstimate; + + // Choose the alloc assuming at least the default NewObjectKind slots, but + // bigger if our estimate shows we need it. + allocKind = js::gc::GetGCObjectKind(std::max( + js::gc::GetGCKindSlots(js::NewObjectGCKind()), propertyCountEstimate)); + return true; +} + +#endif /* vm_JSFunction_inl_h */ |