diff options
Diffstat (limited to '')
-rw-r--r-- | js/src/vm/JSFunction-inl.h | 105 |
1 files changed, 105 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..9ffe003c3d --- /dev/null +++ b/js/src/vm/JSFunction-inl.h @@ -0,0 +1,105 @@ +/* -*- 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 "js/CharacterEncoding.h" +#include "vm/EnvironmentObject.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; +} + +inline JSFunction* CloneFunctionObject(JSContext* cx, HandleFunction fun, + HandleObject enclosingEnv, + HandleObject proto = nullptr) { + // These intermediate variables are needed to avoid link errors on some + // platforms. Sigh. + gc::AllocKind finalizeKind = gc::AllocKind::FUNCTION; + gc::AllocKind extendedFinalizeKind = gc::AllocKind::FUNCTION_EXTENDED; + gc::AllocKind kind = fun->isExtended() ? extendedFinalizeKind : finalizeKind; + + MOZ_ASSERT(CanReuseScriptForClone(cx->realm(), fun, enclosingEnv)); + return CloneFunctionReuseScript(cx, fun, enclosingEnv, kind, proto); +} + +} /* namespace js */ + +/* static */ inline JS::Result<JSFunction*, JS::OOM> JSFunction::create( + JSContext* cx, js::gc::AllocKind kind, js::gc::InitialHeap heap, + js::HandleShape shape, js::HandleObjectGroup group) { + MOZ_ASSERT(kind == js::gc::AllocKind::FUNCTION || + kind == js::gc::AllocKind::FUNCTION_EXTENDED); + + debugCheckNewObject(group, shape, kind, heap); + + const JSClass* clasp = group->clasp(); + MOZ_ASSERT(clasp->isJSFunction()); + + static constexpr size_t NumDynamicSlots = 0; + MOZ_ASSERT(calculateDynamicSlots(shape->numFixedSlots(), shape->slotSpan(), + clasp) == NumDynamicSlots); + + JSObject* obj = js::AllocateObject(cx, kind, NumDynamicSlots, heap, clasp); + if (!obj) { + return cx->alreadyReportedOOM(); + } + + NativeObject* nobj = static_cast<NativeObject*>(obj); + nobj->initGroup(group); + nobj->initShape(shape); + + nobj->initEmptyDynamicSlots(); + nobj->setEmptyElements(); + + MOZ_ASSERT(!clasp->hasPrivate()); + MOZ_ASSERT(shape->slotSpan() == 0); + + JSFunction* fun = static_cast<JSFunction*>(nobj); + fun->nargs_ = 0; + + // This must be overwritten by some ultimate caller: there's no default + // value to which we could sensibly initialize this. + MOZ_MAKE_MEM_UNDEFINED(&fun->u, sizeof(u)); + + fun->atom_.init(nullptr); + + if (kind == js::gc::AllocKind::FUNCTION_EXTENDED) { + fun->setFlags(FunctionFlags::EXTENDED); + for (js::GCPtrValue& extendedSlot : fun->toExtended()->extendedSlots) { + extendedSlot.init(JS::UndefinedValue()); + } + } else { + fun->setFlags(0); + } + + 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"); + fun = SetNewObjectMetadata(cx, fun); + + js::gc::gcprobes::CreateObject(fun); + + return fun; +} + +#endif /* vm_JSFunction_inl_h */ |