Quellcodebibliothek Statistik Leitseite products/sources/formale Sprachen/C/Firefox/js/src/vm/   (Browser von der Mozilla Stiftung Version 136.0.1©)  Datei vom 10.2.2025 mit Größe 9 kB image not shown  

Quelle  SavedFrame.h   Sprache: C

 
/* -*- 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_SavedFrame_h
#define vm_SavedFrame_h

#include "mozilla/Attributes.h"

#include "gc/Policy.h"
#include "js/ColumnNumber.h"  // JS::TaggedColumnNumberOneOrigin
#include "js/GCHashTable.h"
#include "js/Principals.h"
#include "js/UbiNode.h"
#include "vm/NativeObject.h"

namespace js {

class SavedFrame : public NativeObject {
  friend class SavedStacks;
  friend struct ::JSStructuredCloneReader;

  static const ClassSpec classSpec_;

 public:
  static const JSClass class_;
  static const JSClass protoClass_;
  static const JSPropertySpec protoAccessors[];
  static const JSFunctionSpec protoFunctions[];
  static const JSFunctionSpec staticFunctions[];

  // Prototype methods and properties to be exposed to JS.
  static bool construct(JSContext* cx, unsigned argc, Value* vp);
  static bool sourceProperty(JSContext* cx, unsigned argc, Value* vp);
  static bool sourceIdProperty(JSContext* cx, unsigned argc, Value* vp);
  static bool lineProperty(JSContext* cx, unsigned argc, Value* vp);
  static bool columnProperty(JSContext* cx, unsigned argc, Value* vp);
  static bool functionDisplayNameProperty(JSContext* cx, unsigned argc,
                                          Value* vp);
  static bool asyncCauseProperty(JSContext* cx, unsigned argc, Value* vp);
  static bool asyncParentProperty(JSContext* cx, unsigned argc, Value* vp);
  static bool parentProperty(JSContext* cx, unsigned argc, Value* vp);
  static bool toStringMethod(JSContext* cx, unsigned argc, Value* vp);

  static void finalize(JS::GCContext* gcx, JSObject* obj);

  // Convenient getters for SavedFrame's reserved slots for use from C++.
  JSAtom* getSource();
  uint32_t getSourceId();
  // Line number (1-origin).
  uint32_t getLine();
  // Column number in UTF-16 code units.
  JS::TaggedColumnNumberOneOrigin getColumn();
  JSAtom* getFunctionDisplayName();
  JSAtom* getAsyncCause();
  SavedFrame* getParent() const;
  JSPrincipals* getPrincipals();
  bool getMutedErrors();
  bool isSelfHosted(JSContext* cx);
  bool isWasm();

  // When isWasm():
  uint32_t wasmFuncIndex();
  uint32_t wasmBytecodeOffset();

  // Iterator for use with C++11 range based for loops, eg:
  //
  //     Rooted<SavedFrame*> stack(cx, getSomeSavedFrameStack());
  //     for (Handle<SavedFrame*> frame : SavedFrame::RootedRange(cx, stack)) {
  //         ...
  //     }
  //
  // Each frame yielded by `SavedFrame::RootedRange` is only a valid handle to
  // a rooted `SavedFrame` within the loop's block for a single loop
  // iteration. When the next iteration begins, the value is invalidated.

  class RootedRange;

  class MOZ_STACK_CLASS RootedIterator {
    friend class RootedRange;
    RootedRange* range_;
    // For use by RootedRange::end() only.
    explicit RootedIterator() : range_(nullptr) {}

   public:
    explicit RootedIterator(RootedRange& range) : range_(&range) {}
    Handle<SavedFrame*> operator*() {
      MOZ_ASSERT(range_);
      return range_->frame_;
    }
    bool operator!=(const RootedIterator& rhs) const {
      // We should only ever compare to the null range, aka we are just
      // testing if this range is done.
      MOZ_ASSERT(rhs.range_ == nullptr);
      return range_->frame_ != nullptr;
    }
    inline void operator++();
  };

  class MOZ_STACK_CLASS RootedRange {
    friend class RootedIterator;
    Rooted<SavedFrame*> frame_;

   public:
    RootedRange(JSContext* cx, Handle<SavedFrame*> frame) : frame_(cx, frame) {}
    RootedIterator begin() { return RootedIterator(*this); }
    RootedIterator end() { return RootedIterator(); }
  };

  struct Lookup;
  struct HashPolicy;

  using Set =
      JS::GCHashSet<WeakHeapPtr<SavedFrame*>, HashPolicy, SystemAllocPolicy>;

 private:
  static SavedFrame* create(JSContext* cx);
  [[nodiscard]] static bool finishSavedFrameInit(JSContext* cx,
                                                 HandleObject ctor,
                                                 HandleObject proto);
  void initFromLookup(JSContext* cx, Handle<Lookup> lookup);
  void initSource(JSAtom* source);
  void initSourceId(uint32_t id);
  void initLine(uint32_t line);
  void initColumn(JS::TaggedColumnNumberOneOrigin column);
  void initFunctionDisplayName(JSAtom* maybeName);
  void initAsyncCause(JSAtom* maybeCause);
  void initParent(SavedFrame* maybeParent);
  void initPrincipalsAlreadyHeldAndMutedErrors(JSPrincipals* principals,
                                               bool mutedErrors);
  void initPrincipalsAndMutedErrors(JSPrincipals* principals, bool mutedErrors);

  enum {
    // The reserved slots in the SavedFrame class.
    JSSLOT_SOURCE,
    JSSLOT_SOURCEID,
    JSSLOT_LINE,
    JSSLOT_COLUMN,
    JSSLOT_FUNCTIONDISPLAYNAME,
    JSSLOT_ASYNCCAUSE,
    JSSLOT_PARENT,
    JSSLOT_PRINCIPALS,

    // The total number of reserved slots in the SavedFrame class.
    JSSLOT_COUNT
  };
};

struct SavedFrame::HashPolicy {
  using Lookup = SavedFrame::Lookup;
  using SavedFramePtrHasher = StableCellHasher<SavedFrame*>;
  using JSPrincipalsPtrHasher = PointerHasher<JSPrincipals*>;

  static bool maybeGetHash(const Lookup& l, HashNumber* hashOut);
  static bool ensureHash(const Lookup& l, HashNumber* hashOut);
  static HashNumber hash(const Lookup& lookup);
  static bool match(SavedFrame* existing, const Lookup& lookup);

  using Key = WeakHeapPtr<SavedFrame*>;
  static void rekey(Key& key, const Key& newKey);

 private:
  static HashNumber calculateHash(const Lookup& lookup, HashNumber parentHash);
};

}  // namespace js

namespace mozilla {

template <>
struct FallibleHashMethods<js::SavedFrame::HashPolicy> {
  template <typename Lookup>
  static bool maybeGetHash(Lookup&& l, HashNumber* hashOut) {
    return js::SavedFrame::HashPolicy::maybeGetHash(std::forward<Lookup>(l),
                                                    hashOut);
  }
  template <typename Lookup>
  static bool ensureHash(Lookup&& l, HashNumber* hashOut) {
    return js::SavedFrame::HashPolicy::ensureHash(std::forward<Lookup>(l),
                                                  hashOut);
  }
};

}  // namespace mozilla

namespace js {

// Assert that if the given object is not null, that it must be either a
// SavedFrame object or wrapper (Xray or CCW) around a SavedFrame object.
inline void AssertObjectIsSavedFrameOrWrapper(JSContext* cx,
                                              HandleObject stack);

// When we reconstruct a SavedFrame stack from a JS::ubi::StackFrame, we may not
// have access to the principals that the original stack was captured
// with. Instead, we use these two singleton principals based on whether
// JS::ubi::StackFrame::isSystem or not. These singletons should never be passed
// to the subsumes callback, and should be special cased with a shortcut before
// that.
struct ReconstructedSavedFramePrincipals : public JSPrincipals {
  explicit constexpr ReconstructedSavedFramePrincipals()
      : JSPrincipals(JSPrincipals::RefCount(1)) {
    MOZ_ASSERT(is(this));
  }

  [[nodiscard]] bool write(JSContext* cx,
                           JSStructuredCloneWriter* writer) override {
    MOZ_ASSERT(false,
               "ReconstructedSavedFramePrincipals should never be exposed to "
               "embedders");
    return false;
  }

  bool isSystemOrAddonPrincipal() override {
    MOZ_ASSERT(false,
               "ReconstructedSavedFramePrincipals should never be exposed to "
               "embedders");
    return false;
  }

  static ReconstructedSavedFramePrincipals IsSystem;
  static ReconstructedSavedFramePrincipals IsNotSystem;

  // Return true if the given JSPrincipals* points to one of the
  // ReconstructedSavedFramePrincipals singletons, false otherwise.
  static constexpr bool is(JSPrincipals* p) {
    return p == &IsSystem || p == &IsNotSystem;
  }

  // Get the appropriate ReconstructedSavedFramePrincipals singleton for the
  // given JS::ubi::StackFrame that is being reconstructed as a SavedFrame
  // stack.
  static JSPrincipals* getSingleton(JS::ubi::StackFrame& f) {
    return f.isSystem() ? &IsSystem : &IsNotSystem;
  }
};

inline void SavedFrame::RootedIterator::operator++() {
  MOZ_ASSERT(range_);
  range_->frame_ = range_->frame_->getParent();
}

}  // namespace js

namespace JS {
namespace ubi {

using js::SavedFrame;

// A concrete JS::ubi::StackFrame that is backed by a live SavedFrame object.
template <>
class ConcreteStackFrame<SavedFrame> : public BaseStackFrame {
  explicit ConcreteStackFrame(SavedFrame* ptr) : BaseStackFrame(ptr) {}
  SavedFrame& get() const { return *static_cast<SavedFrame*>(ptr); }

 public:
  static void construct(void* storage, SavedFrame* ptr) {
    new (storage) ConcreteStackFrame(ptr);
  }

  StackFrame parent() const override { return get().getParent(); }
  uint32_t line() const override { return get().getLine(); }
  JS::TaggedColumnNumberOneOrigin column() const override {
    return get().getColumn();
  }

  AtomOrTwoByteChars source() const override {
    auto source = get().getSource();
    return AtomOrTwoByteChars(source);
  }

  uint32_t sourceId() const override { return get().getSourceId(); }

  AtomOrTwoByteChars functionDisplayName() const override {
    auto name = get().getFunctionDisplayName();
    return AtomOrTwoByteChars(name);
  }

  void trace(JSTracer* trc) override {
    JSObject* prev = &get();
    JSObject* next = prev;
    js::TraceRoot(trc, &next, "ConcreteStackFrame::ptr");
    if (next != prev) {
      ptr = next;
    }
  }

  bool isSelfHosted(JSContext* cx) const override {
    return get().isSelfHosted(cx);
  }

  bool isSystem() const override;

  [[nodiscard]] bool constructSavedFrameStack(
      JSContext* cx, MutableHandleObject outSavedFrameStack) const override;
};

}  // namespace ubi
}  // namespace JS

#endif  // vm_SavedFrame_h

Messung V0.5
C=92 H=99 G=95

¤ Dauer der Verarbeitung: 0.20 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.