summaryrefslogtreecommitdiffstats
path: root/js/src/vm/JSFunction-inl.h
diff options
context:
space:
mode:
Diffstat (limited to 'js/src/vm/JSFunction-inl.h')
-rw-r--r--js/src/vm/JSFunction-inl.h141
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 */