/ bytecode / GetByIdVariant.h
GetByIdVariant.h
  1  /*
  2   * Copyright (C) 2014-2020 Apple Inc. All rights reserved.
  3   *
  4   * Redistribution and use in source and binary forms, with or without
  5   * modification, are permitted provided that the following conditions
  6   * are met:
  7   * 1. Redistributions of source code must retain the above copyright
  8   *    notice, this list of conditions and the following disclaimer.
  9   * 2. Redistributions in binary form must reproduce the above copyright
 10   *    notice, this list of conditions and the following disclaimer in the
 11   *    documentation and/or other materials provided with the distribution.
 12   *
 13   * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
 14   * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 15   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 16   * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
 17   * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 18   * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 19   * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 20   * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 21   * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 22   * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 23   * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
 24   */
 25  
 26  #pragma once
 27  
 28  #include "CacheableIdentifier.h"
 29  #include "CallLinkStatus.h"
 30  #include "ObjectPropertyConditionSet.h"
 31  #include "PropertyOffset.h"
 32  #include "StructureSet.h"
 33  #include <wtf/Box.h>
 34  
 35  namespace JSC {
 36  namespace DOMJIT {
 37  class GetterSetter;
 38  }
 39  
 40  class CallLinkStatus;
 41  class GetByStatus;
 42  struct DumpContext;
 43  
 44  class GetByIdVariant {
 45      WTF_MAKE_FAST_ALLOCATED;
 46  public:
 47      GetByIdVariant(
 48          CacheableIdentifier,
 49          const StructureSet& structureSet = StructureSet(), PropertyOffset offset = invalidOffset,
 50          const ObjectPropertyConditionSet& = ObjectPropertyConditionSet(),
 51          std::unique_ptr<CallLinkStatus> = nullptr,
 52          JSFunction* = nullptr,
 53          FunctionPtr<CustomAccessorPtrTag> customAccessorGetter = nullptr,
 54          std::unique_ptr<DOMAttributeAnnotation> = nullptr);
 55  
 56      ~GetByIdVariant();
 57      
 58      GetByIdVariant(const GetByIdVariant&);
 59      GetByIdVariant& operator=(const GetByIdVariant&);
 60      
 61      bool isSet() const { return !!m_structureSet.size(); }
 62      explicit operator bool() const { return isSet(); }
 63      const StructureSet& structureSet() const { return m_structureSet; }
 64      StructureSet& structureSet() { return m_structureSet; }
 65  
 66      // A non-empty condition set means that this is a prototype load.
 67      const ObjectPropertyConditionSet& conditionSet() const { return m_conditionSet; }
 68      
 69      PropertyOffset offset() const { return m_offset; }
 70      CallLinkStatus* callLinkStatus() const { return m_callLinkStatus.get(); }
 71      JSFunction* intrinsicFunction() const { return m_intrinsicFunction; }
 72      Intrinsic intrinsic() const { return m_intrinsicFunction ? m_intrinsicFunction->intrinsic() : NoIntrinsic; }
 73      FunctionPtr<CustomAccessorPtrTag> customAccessorGetter() const { return m_customAccessorGetter; }
 74      DOMAttributeAnnotation* domAttribute() const { return m_domAttribute.get(); }
 75  
 76      bool isPropertyUnset() const { return offset() == invalidOffset; }
 77  
 78      bool attemptToMerge(const GetByIdVariant& other);
 79      
 80      void visitAggregate(SlotVisitor&);
 81      void markIfCheap(SlotVisitor&);
 82      bool finalize(VM&);
 83      
 84      void dump(PrintStream&) const;
 85      void dumpInContext(PrintStream&, DumpContext*) const;
 86  
 87      CacheableIdentifier identifier() const { return m_identifier; }
 88  
 89      bool overlaps(const GetByIdVariant& other)
 90      {
 91          if (!!m_identifier != !!other.m_identifier)
 92              return true;
 93          if (m_identifier) {
 94              if (m_identifier != other.m_identifier)
 95                  return false;
 96          }
 97          return structureSet().overlaps(other.structureSet());
 98      }
 99      
100  private:
101      friend class GetByStatus;
102  
103      bool canMergeIntrinsicStructures(const GetByIdVariant&) const;
104      
105      StructureSet m_structureSet;
106      ObjectPropertyConditionSet m_conditionSet;
107      PropertyOffset m_offset;
108      std::unique_ptr<CallLinkStatus> m_callLinkStatus;
109      JSFunction* m_intrinsicFunction;
110      FunctionPtr<CustomAccessorPtrTag> m_customAccessorGetter;
111      std::unique_ptr<DOMAttributeAnnotation> m_domAttribute;
112      CacheableIdentifier m_identifier;
113  };
114  
115  } // namespace JSC