/ runtime / JSArrayBufferViewInlines.h
JSArrayBufferViewInlines.h
  1  /*
  2   * Copyright (C) 2013, 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 "ArrayBufferView.h"
 29  #include "JSArrayBufferView.h"
 30  #include "JSDataView.h"
 31  
 32  namespace JSC {
 33  
 34  inline bool JSArrayBufferView::isShared()
 35  {
 36      switch (m_mode) {
 37      case WastefulTypedArray:
 38          return existingBufferInButterfly()->isShared();
 39      case DataViewMode:
 40          return jsCast<JSDataView*>(this)->possiblySharedBuffer()->isShared();
 41      default:
 42          return false;
 43      }
 44  }
 45  
 46  template<JSArrayBufferView::Requester requester>
 47  inline ArrayBuffer* JSArrayBufferView::possiblySharedBufferImpl()
 48  {
 49      if (requester == ConcurrentThread)
 50          ASSERT(m_mode != FastTypedArray && m_mode != OversizeTypedArray);
 51  
 52      switch (m_mode) {
 53      case WastefulTypedArray:
 54          return existingBufferInButterfly();
 55      case DataViewMode:
 56          return jsCast<JSDataView*>(this)->possiblySharedBuffer();
 57      case FastTypedArray:
 58      case OversizeTypedArray:
 59          return slowDownAndWasteMemory();
 60      }
 61      ASSERT_NOT_REACHED();
 62      return nullptr;
 63  }
 64  
 65  inline ArrayBuffer* JSArrayBufferView::possiblySharedBuffer()
 66  {
 67      return possiblySharedBufferImpl<Mutator>();
 68  }
 69  
 70  inline ArrayBuffer* JSArrayBufferView::existingBufferInButterfly()
 71  {
 72      ASSERT(m_mode == WastefulTypedArray);
 73      return butterfly()->indexingHeader()->arrayBuffer();
 74  }
 75  
 76  inline RefPtr<ArrayBufferView> JSArrayBufferView::unsharedImpl()
 77  {
 78      RefPtr<ArrayBufferView> result = possiblySharedImpl();
 79      RELEASE_ASSERT(!result->isShared());
 80      return result;
 81  }
 82  
 83  template<JSArrayBufferView::Requester requester, typename ResultType>
 84  inline ResultType JSArrayBufferView::byteOffsetImpl()
 85  {
 86      if (!hasArrayBuffer())
 87          return 0;
 88  
 89      if (requester == ConcurrentThread)
 90          WTF::loadLoadFence();
 91  
 92      ArrayBuffer* buffer = possiblySharedBufferImpl<requester>();
 93      ASSERT(buffer);
 94      if (requester == Mutator) {
 95          ASSERT(!isCompilationThread());
 96          ASSERT(!vector() == !buffer->data());
 97      }
 98  
 99      ptrdiff_t delta =
100          bitwise_cast<uint8_t*>(vector()) - static_cast<uint8_t*>(buffer->data());
101  
102      unsigned result = static_cast<unsigned>(delta);
103      if (requester == Mutator)
104          ASSERT(static_cast<ptrdiff_t>(result) == delta);
105      else {
106          if (static_cast<ptrdiff_t>(result) != delta)
107              return { };
108      }
109  
110      return result;
111  }
112  
113  inline unsigned JSArrayBufferView::byteOffset()
114  {
115      return byteOffsetImpl<Mutator, unsigned>();
116  }
117  
118  inline Optional<unsigned> JSArrayBufferView::byteOffsetConcurrently()
119  {
120      return byteOffsetImpl<ConcurrentThread, Optional<unsigned>>();
121  }
122  
123  inline RefPtr<ArrayBufferView> JSArrayBufferView::toWrapped(VM& vm, JSValue value)
124  {
125      if (JSArrayBufferView* view = jsDynamicCast<JSArrayBufferView*>(vm, value)) {
126          if (!view->isShared())
127              return view->unsharedImpl();
128      }
129      return nullptr;
130  }
131  
132  inline RefPtr<ArrayBufferView> JSArrayBufferView::toWrappedAllowShared(VM& vm, JSValue value)
133  {
134      if (JSArrayBufferView* view = jsDynamicCast<JSArrayBufferView*>(vm, value))
135          return view->possiblySharedImpl();
136      return nullptr;
137  }
138  
139  
140  } // namespace JSC