/ runtime / JSGlobalObjectInlines.h
JSGlobalObjectInlines.h
  1  /*
  2   * Copyright (C) 2016 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 "JSGlobalObject.h"
 29  
 30  #include "ArrayConstructor.h"
 31  #include "ArrayPrototype.h"
 32  #include "JSFunction.h"
 33  #include "LinkTimeConstant.h"
 34  #include "ObjectPrototype.h"
 35  
 36  namespace JSC {
 37  
 38  ALWAYS_INLINE bool JSGlobalObject::objectPrototypeIsSane()
 39  {
 40      return !hasIndexedProperties(m_objectPrototype->indexingType())
 41          && m_objectPrototype->getPrototypeDirect(vm()).isNull();
 42  }
 43  
 44  ALWAYS_INLINE bool JSGlobalObject::arrayPrototypeChainIsSane()
 45  {
 46      return !hasIndexedProperties(m_arrayPrototype->indexingType())
 47          && m_arrayPrototype->getPrototypeDirect(vm()) == m_objectPrototype.get()
 48          && objectPrototypeIsSane();
 49  }
 50  
 51  ALWAYS_INLINE bool JSGlobalObject::stringPrototypeChainIsSane()
 52  {
 53      return !hasIndexedProperties(m_stringPrototype->indexingType())
 54          && m_stringPrototype->getPrototypeDirect(vm()) == m_objectPrototype.get()
 55          && objectPrototypeIsSane();
 56  }
 57  
 58  ALWAYS_INLINE bool JSGlobalObject::isArrayPrototypeIteratorProtocolFastAndNonObservable()
 59  {
 60      // We're fast if we don't have any indexed properties on the prototype.
 61      // We're non-observable if the iteration protocol hasn't changed.
 62      //
 63      // Note: it only makes sense to call this from the main thread. If you're
 64      // trying to prove this behavior on the compiler thread, you'll want to
 65      // carefully set up watchpoints to have correct ordering while JS code is
 66      // executing concurrently.
 67  
 68      return arrayIteratorProtocolWatchpointSet().isStillValid() && !isHavingABadTime() && arrayPrototypeChainIsSane();
 69  }
 70  
 71  // We're non-observable if the iteration protocol hasn't changed.
 72  //
 73  // Note: it only makes sense to call this from the main thread. If you're
 74  // trying to prove this behavior on the compiler thread, you'll want to
 75  // carefully set up watchpoints to have correct ordering while JS code is
 76  // executing concurrently.
 77  ALWAYS_INLINE bool JSGlobalObject::isMapPrototypeIteratorProtocolFastAndNonObservable()
 78  {
 79      return mapIteratorProtocolWatchpointSet().isStillValid();
 80  }
 81  
 82  ALWAYS_INLINE bool JSGlobalObject::isSetPrototypeIteratorProtocolFastAndNonObservable()
 83  {
 84      return setIteratorProtocolWatchpointSet().isStillValid();
 85  }
 86  
 87  ALWAYS_INLINE bool JSGlobalObject::isStringPrototypeIteratorProtocolFastAndNonObservable()
 88  {
 89      return stringIteratorProtocolWatchpointSet().isStillValid();
 90  }
 91  
 92  ALWAYS_INLINE bool JSGlobalObject::isMapPrototypeSetFastAndNonObservable()
 93  {
 94      return mapSetWatchpointSet().isStillValid();
 95  }
 96  
 97  ALWAYS_INLINE bool JSGlobalObject::isSetPrototypeAddFastAndNonObservable()
 98  {
 99      return setAddWatchpointSet().isStillValid();
100  }
101  
102  ALWAYS_INLINE Structure* JSGlobalObject::arrayStructureForIndexingTypeDuringAllocation(JSGlobalObject* globalObject, IndexingType indexingType, JSValue newTarget) const
103  {
104      return !newTarget || newTarget == globalObject->arrayConstructor()
105          ? globalObject->arrayStructureForIndexingTypeDuringAllocation(indexingType)
106          : InternalFunction::createSubclassStructure(globalObject, asObject(newTarget), getFunctionRealm(globalObject->vm(), asObject(newTarget))->arrayStructureForIndexingTypeDuringAllocation(indexingType));
107  }
108  
109  inline JSFunction* JSGlobalObject::throwTypeErrorFunction() const { return jsCast<JSFunction*>(linkTimeConstant(LinkTimeConstant::throwTypeErrorFunction)); }
110  inline JSFunction* JSGlobalObject::newPromiseCapabilityFunction() const { return jsCast<JSFunction*>(linkTimeConstant(LinkTimeConstant::newPromiseCapability)); }
111  inline JSFunction* JSGlobalObject::resolvePromiseFunction() const { return jsCast<JSFunction*>(linkTimeConstant(LinkTimeConstant::resolvePromise)); }
112  inline JSFunction* JSGlobalObject::rejectPromiseFunction() const { return jsCast<JSFunction*>(linkTimeConstant(LinkTimeConstant::rejectPromise)); }
113  inline JSFunction* JSGlobalObject::promiseProtoThenFunction() const { return jsCast<JSFunction*>(linkTimeConstant(LinkTimeConstant::defaultPromiseThen)); }
114  inline JSFunction* JSGlobalObject::regExpProtoExecFunction() const { return jsCast<JSFunction*>(linkTimeConstant(LinkTimeConstant::regExpBuiltinExec)); }
115  inline GetterSetter* JSGlobalObject::regExpProtoGlobalGetter() const { return bitwise_cast<GetterSetter*>(linkTimeConstant(LinkTimeConstant::regExpProtoGlobalGetter)); }
116  inline GetterSetter* JSGlobalObject::regExpProtoUnicodeGetter() const { return bitwise_cast<GetterSetter*>(linkTimeConstant(LinkTimeConstant::regExpProtoUnicodeGetter)); }
117  
118  ALWAYS_INLINE VM& getVM(JSGlobalObject* globalObject)
119  {
120      return globalObject->vm();
121  }
122  
123  } // namespace JSC