Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 


Quelle  BoundFunctionObject.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_BoundFunctionObject_h
#define vm_BoundFunctionObject_h

#include "jstypes.h"

#include "gc/Policy.h"
#include "vm/ArrayObject.h"
#include "vm/JSObject.h"

namespace js {

// Implementation of Bound Function Exotic Objects.
// ES2023 10.4.1
// https://tc39.es/ecma262/#sec-bound-function-exotic-objects
class BoundFunctionObject : public NativeObject {
 public:
  static const JSClass class_;

  // FlagsSlot uses the low bit for the is-constructor flag and the other bits
  // for the number of arguments.
  static constexpr size_t IsConstructorFlag = 0b1;
  static constexpr size_t NumBoundArgsShift = 1;

  // The maximum number of bound arguments that can be stored inline in
  // BoundArg*Slot.
  static constexpr size_t MaxInlineBoundArgs = 3;

 private:
  enum {
    // The [[BoundTargetFunction]] (a callable object).
    TargetSlot,

    // The number of arguments + the is-constructor flag, stored as Int32Value.
    FlagsSlot,

    // The [[BoundThis]] Value.
    BoundThisSlot,

    // The [[BoundArguments]]. If numBoundArgs exceeds MaxInlineBoundArgs,
    // BoundArg0Slot will contain an array object that stores the values and the
    // other two slots will be unused.
    BoundArg0Slot,
    BoundArg1Slot,
    BoundArg2Slot,

    // Initial slots for the `length` and `name` own data properties. Note that
    // these properties are configurable, so these slots can be mutated when the
    // object is exposed to JS.
    LengthSlot,
    NameSlot,

    SlotCount
  };

  // The AllocKind should match SlotCount. See assertion in functionBindImpl.
  static constexpr gc::AllocKind allocKind = gc::AllocKind::OBJECT8_BACKGROUND;

  void initFlags(size_t numBoundArgs, bool isConstructor) {
    int32_t val = (numBoundArgs << NumBoundArgsShift) | isConstructor;
    initReservedSlot(FlagsSlot, Int32Value(val));
  }

 public:
  size_t numBoundArgs() const {
    int32_t v = getReservedSlot(FlagsSlot).toInt32();
    MOZ_ASSERT(v >= 0);
    return v >> NumBoundArgsShift;
  }
  bool isConstructor() const {
    int32_t v = getReservedSlot(FlagsSlot).toInt32();
    return v & IsConstructorFlag;
  }

  Value getTargetVal() const { return getReservedSlot(TargetSlot); }
  JSObject* getTarget() const { return &getTargetVal().toObject(); }

  Value getBoundThis() const { return getReservedSlot(BoundThisSlot); }

  Value getInlineBoundArg(size_t i) const {
    MOZ_ASSERT(i < numBoundArgs());
    MOZ_ASSERT(numBoundArgs() <= MaxInlineBoundArgs);
    return getReservedSlot(BoundArg0Slot + i);
  }
  ArrayObject* getBoundArgsArray() const {
    MOZ_ASSERT(numBoundArgs() > MaxInlineBoundArgs);
    return &getReservedSlot(BoundArg0Slot).toObject().as<ArrayObject>();
  }
  Value getBoundArg(size_t i) const {
    MOZ_ASSERT(i < numBoundArgs());
    if (numBoundArgs() <= MaxInlineBoundArgs) {
      return getInlineBoundArg(i);
    }
    return getBoundArgsArray()->getDenseElement(i);
  }

  void initLength(double len) {
    MOZ_ASSERT(getReservedSlot(LengthSlot).isUndefined());
    initReservedSlot(LengthSlot, NumberValue(len));
  }
  void initName(JSAtom* name) {
    MOZ_ASSERT(getReservedSlot(NameSlot).isUndefined());
    initReservedSlot(NameSlot, StringValue(name));
  }

  // Get the `length` and `name` property values when the object has the
  // original shape. See comment for LengthSlot and NameSlot.
  Value getLengthForInitialShape() const { return getReservedSlot(LengthSlot); }
  Value getNameForInitialShape() const { return getReservedSlot(NameSlot); }

  // The [[Call]] and [[Construct]] hooks.
  static bool call(JSContext* cx, unsigned argc, Value* vp);
  static bool construct(JSContext* cx, unsigned argc, Value* vp);

  // The JSFunToStringOp implementation for Function.prototype.toString.
  static JSString* funToString(JSContext* cx, Handle<JSObject*> obj,
                               bool isToSource);

  // Implementation of Function.prototype.bind.
  static bool functionBind(JSContext* cx, unsigned argc, Value* vp);

  static SharedShape* assignInitialShape(JSContext* cx,
                                         Handle<BoundFunctionObject*> obj);

  static BoundFunctionObject* functionBindImpl(
      JSContext* cx, Handle<JSObject*> target, Value* args, uint32_t argc,
      Handle<BoundFunctionObject*> maybeBound);

  static BoundFunctionObject* createWithTemplate(
      JSContext* cx, Handle<BoundFunctionObject*> templateObj);
  static BoundFunctionObject* functionBindSpecializedBaseline(
      JSContext* cx, Handle<JSObject*> target, Value* args, uint32_t argc,
      Handle<BoundFunctionObject*> templateObj);

  static BoundFunctionObject* createTemplateObject(JSContext* cx);

  bool initTemplateSlotsForSpecializedBind(JSContext* cx, uint32_t numBoundArgs,
                                           bool targetIsConstructor,
                                           uint32_t targetLength,
                                           JSAtom* targetName);

  static constexpr size_t offsetOfTargetSlot() {
    return getFixedSlotOffset(TargetSlot);
  }
  static constexpr size_t offsetOfFlagsSlot() {
    return getFixedSlotOffset(FlagsSlot);
  }
  static constexpr size_t offsetOfBoundThisSlot() {
    return getFixedSlotOffset(BoundThisSlot);
  }
  static constexpr size_t offsetOfFirstInlineBoundArg() {
    return getFixedSlotOffset(BoundArg0Slot);
  }
  static constexpr size_t offsetOfLengthSlot() {
    return getFixedSlotOffset(LengthSlot);
  }
  static constexpr size_t offsetOfNameSlot() {
    return getFixedSlotOffset(NameSlot);
  }

  static constexpr size_t targetSlot() { return TargetSlot; }
  static constexpr size_t boundThisSlot() { return BoundThisSlot; }
  static constexpr size_t firstInlineBoundArgSlot() { return BoundArg0Slot; }
};

};  // namespace js

#endif /* vm_BoundFunctionObject_h */

Messung V0.5
C=93 H=92 G=92

¤ Dauer der Verarbeitung: 0.3 Sekunden  ¤

*© 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.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Produkte
     Quellcodebibliothek

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....
    

Besucherstatistik

Besucherstatistik

Monitoring

Montastic status badge