tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

JSFunction-inl.h (4785B)


      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/. */
      6 
      7 #ifndef vm_JSFunction_inl_h
      8 #define vm_JSFunction_inl_h
      9 
     10 #include "vm/JSFunction.h"
     11 
     12 #include "gc/GCProbes.h"
     13 
     14 #include "gc/ObjectKind-inl.h"
     15 #include "vm/JSContext-inl.h"
     16 #include "vm/JSObject-inl.h"
     17 #include "vm/NativeObject-inl.h"
     18 
     19 namespace js {
     20 
     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;
     27    }
     28 
     29    *bytes = StringToNewUTF8CharsZ(cx, *name);
     30    return bytes->get();
     31  }
     32 
     33  if (JSAtom* name = fun->fullExplicitName()) {
     34    *bytes = StringToNewUTF8CharsZ(cx, *name);
     35    return bytes->get();
     36  }
     37 
     38  return "anonymous";
     39 }
     40 
     41 } /* namespace js */
     42 
     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                                      js::gc::AllocSite* site) {
     48  MOZ_ASSERT(kind == js::gc::AllocKind::FUNCTION ||
     49             kind == js::gc::AllocKind::FUNCTION_EXTENDED);
     50 
     51  debugCheckNewObject(shape, kind, heap);
     52 
     53  const JSClass* clasp = shape->getObjectClass();
     54  MOZ_ASSERT(clasp->isNativeObject());
     55  MOZ_ASSERT(clasp->isJSFunction());
     56  MOZ_ASSERT_IF(kind == js::gc::AllocKind::FUNCTION,
     57                clasp == js::FunctionClassPtr);
     58  MOZ_ASSERT_IF(kind == js::gc::AllocKind::FUNCTION_EXTENDED,
     59                clasp == js::FunctionExtendedClassPtr);
     60 
     61  MOZ_ASSERT(calculateDynamicSlots(shape->numFixedSlots(), shape->slotSpan(),
     62                                   clasp) == 0);
     63 
     64  NativeObject* nobj = cx->newCell<NativeObject>(kind, heap, clasp, site);
     65  if (!nobj) {
     66    return nullptr;
     67  }
     68 
     69  nobj->initShape(shape);
     70 
     71  nobj->initEmptyDynamicSlots();
     72  nobj->setEmptyElements();
     73 
     74  JSFunction* fun = static_cast<JSFunction*>(nobj);
     75  fun->initFixedSlots(JSCLASS_RESERVED_SLOTS(clasp));
     76  fun->initFlagsAndArgCount();
     77  fun->initFixedSlot(NativeJitInfoOrInterpretedScriptSlot,
     78                     JS::PrivateValue(nullptr));
     79 
     80  if (kind == js::gc::AllocKind::FUNCTION_EXTENDED) {
     81    fun->setFlags(FunctionFlags::EXTENDED);
     82  }
     83 
     84  MOZ_ASSERT(!clasp->shouldDelayMetadataBuilder(),
     85             "Function has no extra data hanging off it, that wouldn't be "
     86             "allocated at this point, that would require delaying the "
     87             "building of metadata for it");
     88  if (MOZ_UNLIKELY(cx->realm()->hasAllocationMetadataBuilder())) {
     89    fun = SetNewObjectMetadata(cx, fun);
     90  }
     91 
     92  js::gc::gcprobes::CreateObject(fun);
     93 
     94  return fun;
     95 }
     96 
     97 /* static */
     98 inline bool JSFunction::getLength(JSContext* cx, js::HandleFunction fun,
     99                                  uint16_t* length) {
    100  if (fun->isNativeFun()) {
    101    *length = fun->nargs();
    102    return true;
    103  }
    104 
    105  JSScript* script = getOrCreateScript(cx, fun);
    106  if (!script) {
    107    return false;
    108  }
    109 
    110  *length = script->funLength();
    111  return true;
    112 }
    113 
    114 /* static */
    115 inline bool JSFunction::getUnresolvedLength(JSContext* cx,
    116                                            js::HandleFunction fun,
    117                                            uint16_t* length) {
    118  MOZ_ASSERT(!IsInternalFunctionObject(*fun));
    119  MOZ_ASSERT(!fun->hasResolvedLength());
    120 
    121  return JSFunction::getLength(cx, fun, length);
    122 }
    123 
    124 inline JSAtom* JSFunction::getUnresolvedName(JSContext* cx) {
    125  if (isAccessorWithLazyName()) {
    126    return getAccessorNameForLazy(cx);
    127  }
    128 
    129  return infallibleGetUnresolvedName(cx);
    130 }
    131 
    132 inline JSAtom* JSFunction::infallibleGetUnresolvedName(JSContext* cx) {
    133  MOZ_ASSERT(!IsInternalFunctionObject(*this));
    134  MOZ_ASSERT(!isAccessorWithLazyName());
    135  MOZ_ASSERT(!hasResolvedName());
    136 
    137  if (JSAtom* name = fullExplicitOrInferredName()) {
    138    return name;
    139  }
    140 
    141  return cx->names().empty_;
    142 }
    143 
    144 /* static */ inline bool JSFunction::getAllocKindForThis(
    145    JSContext* cx, js::HandleFunction func, js::gc::AllocKind& allocKind) {
    146  JSScript* script = getOrCreateScript(cx, func);
    147  if (!script) {
    148    return false;
    149  }
    150 
    151  size_t propertyCountEstimate =
    152      script->immutableScriptData()->propertyCountEstimate;
    153 
    154  // Choose the alloc assuming at least the default NewObjectKind slots, but
    155  // bigger if our estimate shows we need it.
    156  allocKind = js::gc::GetGCObjectKind(std::max(
    157      js::gc::GetGCKindSlots(js::NewObjectGCKind()), propertyCountEstimate));
    158  return true;
    159 }
    160 
    161 #endif /* vm_JSFunction_inl_h */