[Readable Streams API] Implement cloneArrayBuffer in WebCore
authorcommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 31 Mar 2017 10:37:06 +0000 (10:37 +0000)
committercommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 31 Mar 2017 10:37:06 +0000 (10:37 +0000)
https://bugs.webkit.org/show_bug.cgi?id=170008

Patch by Romain Bellessort <romain.bellessort@crf.canon.fr> on 2017-03-31
Reviewed by Youenn Fablet.

Source/WebCore:

Implemented cloneArrayBuffer based on existing structuredCloneArrayBuffer
implementation. The code has been factorized so that both cloneArrayBuffer
and structuredCloneArrayBuffer rely on the same code (which is basically
the previous implementation of structuredCloneArrayBuffer + the ability
to clone only a part of considered buffer).

Added test to check cloneArrayBuffer behaviour.

* Modules/streams/ReadableByteStreamInternals.js: Deleted cloneArrayBuffer JS implementation.
* bindings/js/JSDOMGlobalObject.cpp:
(WebCore::JSDOMGlobalObject::addBuiltinGlobals): Add cloneArrayBuffer private declaration.
* bindings/js/StructuredClone.cpp:
(WebCore::cloneArrayBufferImpl): Added (mostly based on previous structuredCloneArrayBuffer).
(WebCore::cloneArrayBuffer): Added.
(WebCore::structuredCloneArrayBuffer): Updated.
* bindings/js/StructuredClone.h: Added cloneArrayBuffer declaration.
* bindings/js/WebCoreBuiltinNames.h: Added cloneArrayBuffer declaration.
* testing/Internals.cpp: Added support for testing cloneArrayBuffer.
* testing/Internals.h: Added support for testing cloneArrayBuffer.
* testing/Internals.idl: Added support for testing cloneArrayBuffer.

LayoutTests:

Added test to check cloneArrayBuffer behaviour.

* streams/readable-stream-byob-request.js:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@214663 268f45cc-cd09-0410-ab3c-d52691b4dbfc

12 files changed:
LayoutTests/ChangeLog
LayoutTests/streams/readable-stream-byob-request-expected.txt
LayoutTests/streams/readable-stream-byob-request.js
Source/WebCore/ChangeLog
Source/WebCore/Modules/streams/ReadableByteStreamInternals.js
Source/WebCore/bindings/js/JSDOMGlobalObject.cpp
Source/WebCore/bindings/js/StructuredClone.cpp
Source/WebCore/bindings/js/StructuredClone.h
Source/WebCore/bindings/js/WebCoreBuiltinNames.h
Source/WebCore/testing/Internals.cpp
Source/WebCore/testing/Internals.h
Source/WebCore/testing/Internals.idl

index 3eff958..47a3f57 100644 (file)
@@ -1,3 +1,14 @@
+2017-03-31  Romain Bellessort  <romain.bellessort@crf.canon.fr>
+
+        [Readable Streams API] Implement cloneArrayBuffer in WebCore
+        https://bugs.webkit.org/show_bug.cgi?id=170008
+
+        Reviewed by Youenn Fablet.
+
+        Added test to check cloneArrayBuffer behaviour. 
+
+        * streams/readable-stream-byob-request.js:
+
 2017-03-31  Oleksandr Skachkov  <gskachkov@gmail.com>
 
         String.prototype.replace incorrectly applies "special replacement parameters" when passed a function
index 1a6cf1c..671cac5 100644 (file)
@@ -10,6 +10,7 @@ PASS Calling respond() with a bytesWritten value different from 0 when stream is
 PASS Calling respond() with a bytesWritten value of 0 when stream is closed should succeed 
 PASS Calling respond() with a bytesWritten value greater than autoAllocateChunkSize should fail 
 PASS Calling respond() with a bytesWritten value lower than autoAllocateChunkSize should succeed 
+PASS Test cloneArrayBuffer implementation 
 PASS ReadableStreamBYOBRequest instances should have the correct list of properties 
 PASS By default, byobRequest should be undefined 
 PASS byobRequest.view length should be equal to autoAllocateChunkSize 
index b4ad4c4..96920a0 100644 (file)
@@ -241,4 +241,22 @@ promise_test(function() {
 // FIXME: when ReadableStreamBYOBReader is implemented, add tests with elementSize different from 1
 // so that more code can be covered.
 
+if (!self.importScripts) {
+    // Test only if not Worker.
+    const CloneArrayBuffer = internals.cloneArrayBuffer.bind(internals);
+
+    test(function() {
+        const typedArray = new Uint8Array([3, 5, 7]);
+        const clonedBuffer = CloneArrayBuffer(typedArray.buffer, 1, 1);
+        const otherArray = new Uint8Array(clonedBuffer);
+        assert_equals(otherArray.byteLength, 1);
+        assert_equals(otherArray.byteOffset, 0);
+        assert_equals(otherArray.buffer.byteLength, 1);
+        assert_equals(otherArray[0], 5);
+        // Check that when typedArray is modified, otherArray is not modified.
+        typedArray[1] = 0;
+        assert_equals(otherArray[0], 5);
+    }, "Test cloneArrayBuffer implementation");
+}
+
 done();
index f4b44a4..aa5b8a9 100644 (file)
@@ -1,3 +1,31 @@
+2017-03-31  Romain Bellessort  <romain.bellessort@crf.canon.fr>
+
+        [Readable Streams API] Implement cloneArrayBuffer in WebCore
+        https://bugs.webkit.org/show_bug.cgi?id=170008
+
+        Reviewed by Youenn Fablet.
+
+        Implemented cloneArrayBuffer based on existing structuredCloneArrayBuffer
+        implementation. The code has been factorized so that both cloneArrayBuffer
+        and structuredCloneArrayBuffer rely on the same code (which is basically
+        the previous implementation of structuredCloneArrayBuffer + the ability
+        to clone only a part of considered buffer).
+
+        Added test to check cloneArrayBuffer behaviour.
+
+        * Modules/streams/ReadableByteStreamInternals.js: Deleted cloneArrayBuffer JS implementation.
+        * bindings/js/JSDOMGlobalObject.cpp:
+        (WebCore::JSDOMGlobalObject::addBuiltinGlobals): Add cloneArrayBuffer private declaration.
+        * bindings/js/StructuredClone.cpp:
+        (WebCore::cloneArrayBufferImpl): Added (mostly based on previous structuredCloneArrayBuffer).
+        (WebCore::cloneArrayBuffer): Added.
+        (WebCore::structuredCloneArrayBuffer): Updated.
+        * bindings/js/StructuredClone.h: Added cloneArrayBuffer declaration.
+        * bindings/js/WebCoreBuiltinNames.h: Added cloneArrayBuffer declaration.
+        * testing/Internals.cpp: Added support for testing cloneArrayBuffer.
+        * testing/Internals.h: Added support for testing cloneArrayBuffer.
+        * testing/Internals.idl: Added support for testing cloneArrayBuffer.
+
 2017-03-31  Antoine Quint  <graouts@apple.com>
 
         [mac-wk1] LayoutTest media/modern-media-controls/airplay-button/airplay-button.html is a flaky timeout
index 3a755d8..d164a65 100644 (file)
@@ -378,17 +378,6 @@ function readableByteStreamControllerRespondInternal(controller, bytesWritten)
     }
 }
 
-function cloneArrayBuffer(srcBuffer, srcByteOffset, srcLength)
-{
-    "use strict";
-
-    // FIXME: Below implementation returns the appropriate data but does not perform
-    // exactly what is described by ECMAScript CloneArrayBuffer operation. This should
-    // be fixed in a follow up patch implementing cloneArrayBuffer in JSC (similarly to
-    // structuredCloneArrayBuffer implementation).
-    return srcBuffer.slice(srcByteOffset, srcByteOffset + srcLength);
-}
-
 function readableByteStreamControllerRespondInReadableState(controller, bytesWritten, pullIntoDescriptor)
 {
     "use strict";
index bd1bc06..4d184c7 100644 (file)
@@ -142,6 +142,8 @@ void JSDOMGlobalObject::addBuiltinGlobals(VM& vm)
             JSFunction::create(vm, this, 2, String(), makeThisTypeErrorForBuiltins), DontDelete | ReadOnly),
         JSDOMGlobalObject::GlobalPropertyInfo(clientData.builtinNames().makeGetterTypeErrorPrivateName(),
             JSFunction::create(vm, this, 2, String(), makeGetterTypeErrorForBuiltins), DontDelete | ReadOnly),
+        JSDOMGlobalObject::GlobalPropertyInfo(clientData.builtinNames().cloneArrayBufferPrivateName(),
+            JSFunction::create(vm, this, 3, String(), cloneArrayBuffer), DontDelete | ReadOnly),
         JSDOMGlobalObject::GlobalPropertyInfo(clientData.builtinNames().structuredCloneArrayBufferPrivateName(),
             JSFunction::create(vm, this, 1, String(), structuredCloneArrayBuffer), DontDelete | ReadOnly),
         JSDOMGlobalObject::GlobalPropertyInfo(clientData.builtinNames().structuredCloneArrayBufferViewPrivateName(),
index 4869ac0..86af25b 100644 (file)
@@ -35,7 +35,9 @@ using namespace JSC;
 
 namespace WebCore {
 
-EncodedJSValue JSC_HOST_CALL structuredCloneArrayBuffer(ExecState* state)
+EncodedJSValue JSC_HOST_CALL cloneArrayBufferImpl(ExecState*, bool);
+
+EncodedJSValue JSC_HOST_CALL cloneArrayBufferImpl(ExecState* state, bool isPartialClone)
 {
     ASSERT(state);
     ASSERT(state->argumentCount());
@@ -48,9 +50,25 @@ EncodedJSValue JSC_HOST_CALL structuredCloneArrayBuffer(ExecState* state)
         throwDataCloneError(*state, scope);
         return { };
     }
+    if (isPartialClone) {
+        ASSERT(state->argumentCount() == 3);
+        int srcByteOffset = static_cast<int>(state->uncheckedArgument(1).toNumber(state));
+        int srcLength = static_cast<int>(state->uncheckedArgument(2).toNumber(state));
+        buffer = buffer->slice(srcByteOffset, srcByteOffset + srcLength).get();
+    }
     return JSValue::encode(JSArrayBuffer::create(state->vm(), state->lexicalGlobalObject()->arrayBufferStructure(ArrayBufferSharingMode::Default), ArrayBuffer::tryCreate(buffer->data(), buffer->byteLength())));
 }
 
+EncodedJSValue JSC_HOST_CALL cloneArrayBuffer(ExecState* state)
+{
+    return cloneArrayBufferImpl(state, true);
+}
+
+EncodedJSValue JSC_HOST_CALL structuredCloneArrayBuffer(ExecState* state)
+{
+    return cloneArrayBufferImpl(state, false);
+}
+
 EncodedJSValue JSC_HOST_CALL structuredCloneArrayBufferView(ExecState* state)
 {
     ASSERT(state);
index ea6d01b..a6e4f83 100644 (file)
@@ -31,6 +31,7 @@ class ExecState;
 
 namespace WebCore {
 
+JSC::EncodedJSValue JSC_HOST_CALL cloneArrayBuffer(JSC::ExecState*);
 JSC::EncodedJSValue JSC_HOST_CALL structuredCloneArrayBuffer(JSC::ExecState*);
 JSC::EncodedJSValue JSC_HOST_CALL structuredCloneArrayBufferView(JSC::ExecState*);
 
index 25d2e47..39baa47 100644 (file)
@@ -39,6 +39,7 @@ namespace WebCore {
     macro(body) \
     macro(byobRequest) \
     macro(cancel) \
+    macro(cloneArrayBuffer) \
     macro(cloneForJS) \
     macro(closeRequested) \
     macro(closedPromiseCapability) \
index 13e13f5..672b4d4 100644 (file)
@@ -351,7 +351,7 @@ static bool markerTypeFrom(const String& markerType, DocumentMarker::MarkerType&
 #endif
     else
         return false;
-    
+
     return true;
 }
 
@@ -391,9 +391,9 @@ void Internals::resetToConsistentState(Page& page)
     page.setPaginationLineGridEnabled(false);
 
     page.setDefersLoading(false);
-    
+
     page.mainFrame().setTextZoomFactor(1.0f);
-    
+
     FrameView* mainFrameView = page.mainFrame().view();
     if (mainFrameView) {
         mainFrameView->setHeaderHeight(0);
@@ -596,7 +596,7 @@ bool Internals::isLoadingFromMemoryCache(const String& url)
 
     ResourceRequest request(contextDocument()->completeURL(url));
     request.setDomainForCachePartition(contextDocument()->topOrigin().domainForCachePartition());
-    
+
     CachedResource* resource = MemoryCache::singleton().resourceForRequest(request, contextDocument()->page()->sessionID());
     return resource && resource->status() == CachedResource::Cached;
 }
@@ -724,11 +724,11 @@ void Internals::setImageFrameDecodingDuration(HTMLImageElement& element, float d
     auto* cachedImage = element.cachedImage();
     if (!cachedImage)
         return;
-    
+
     auto* image = cachedImage->image();
     if (!is<BitmapImage>(image))
         return;
-    
+
     downcast<BitmapImage>(*image).setFrameDecodingDurationForTesting(duration);
 }
 
@@ -988,7 +988,7 @@ static unsigned deferredStyleRulesCountForList(const Vector<RefPtr<StyleRuleBase
                 count++;
             continue;
         }
-        
+
         StyleRuleGroup* groupRule = nullptr;
         if (is<StyleRuleMedia>(rule.get()))
             groupRule = downcast<StyleRuleMedia>(rule.get());
@@ -996,11 +996,11 @@ static unsigned deferredStyleRulesCountForList(const Vector<RefPtr<StyleRuleBase
             groupRule = downcast<StyleRuleSupports>(rule.get());
         if (!groupRule)
             continue;
-        
+
         auto* groupChildRules = groupRule->childRulesWithoutDeferredParsing();
         if (!groupChildRules)
             continue;
-        
+
         count += deferredStyleRulesCountForList(*groupChildRules);
     }
 
@@ -1023,7 +1023,7 @@ static unsigned deferredGroupRulesCountForList(const Vector<RefPtr<StyleRuleBase
             groupRule = downcast<StyleRuleSupports>(rule.get());
         if (!groupRule)
             continue;
-        
+
         auto* groupChildRules = groupRule->childRulesWithoutDeferredParsing();
         if (!groupChildRules)
             count++;
@@ -1048,7 +1048,7 @@ static unsigned deferredKeyframesRulesCountForList(const Vector<RefPtr<StyleRule
                 count++;
             continue;
         }
-        
+
         StyleRuleGroup* groupRule = nullptr;
         if (is<StyleRuleMedia>(rule.get()))
             groupRule = downcast<StyleRuleMedia>(rule.get());
@@ -1056,14 +1056,14 @@ static unsigned deferredKeyframesRulesCountForList(const Vector<RefPtr<StyleRule
             groupRule = downcast<StyleRuleSupports>(rule.get());
         if (!groupRule)
             continue;
-        
+
         auto* groupChildRules = groupRule->childRulesWithoutDeferredParsing();
         if (!groupChildRules)
             continue;
-        
+
         count += deferredKeyframesRulesCountForList(*groupChildRules);
     }
-    
+
     return count;
 }
 
@@ -1136,7 +1136,7 @@ std::optional<Internals::EventThrottlingBehavior> Internals::eventThrottlingBeha
     auto behavior = document->page()->eventThrottlingBehaviorOverride();
     if (!behavior)
         return std::nullopt;
-    
+
     switch (behavior.value()) {
     case WebCore::EventThrottlingBehavior::Responsive:
         return Internals::EventThrottlingBehavior::Responsive;
@@ -1201,7 +1201,7 @@ void Internals::enableMockSpeechSynthesizer()
     SpeechSynthesis* synthesis = DOMWindowSpeechSynthesis::speechSynthesis(*document->domWindow());
     if (!synthesis)
         return;
-    
+
     synthesis->setPlatformSynthesizer(std::make_unique<PlatformSpeechSynthesizerMock>(synthesis));
 }
 
@@ -1633,7 +1633,7 @@ ExceptionOr<RefPtr<Range>> Internals::rangeForDictionaryLookupAtLocation(int x,
         return Exception { INVALID_ACCESS_ERR };
 
     document->updateLayoutIgnorePendingStylesheets();
-    
+
     HitTestResult result = document->frame()->mainFrame().eventHandler().hitTestResultAtPoint(IntPoint(x, y));
     NSDictionary *options = nullptr;
     return DictionaryLookup::rangeAtHitTestResult(result, &options);
@@ -1789,7 +1789,7 @@ ExceptionOr<RefPtr<NodeList>> Internals::nodesFromRect(Document& document, int c
     } else {
         HitTestResult result(point, topPadding, rightPadding, bottomPadding, leftPadding);
         renderView->hitTest(request, result);
-        
+
         const HitTestResult::NodeSet& nodeSet = result.rectBasedTestResult();
         matches.reserveInitialCapacity(nodeSet.size());
         for (auto& node : nodeSet)
@@ -1910,7 +1910,7 @@ bool Internals::hasSpellingMarker(int from, int length)
 
     return document->frame()->editor().selectionStartHasMarkerFor(DocumentMarker::Spelling, from, length);
 }
-    
+
 bool Internals::hasAutocorrectedMarker(int from, int length)
 {
     Document* document = contextDocument();
@@ -2163,7 +2163,7 @@ unsigned Internals::numberOfScrollableAreas()
 
     return count;
 }
-    
+
 ExceptionOr<bool> Internals::isPageBoxVisible(int pageNumber)
 {
     Document* document = contextDocument();
@@ -2216,7 +2216,7 @@ ExceptionOr<uint64_t> Internals::layerIDForElement(Element& element)
     auto& layerModelObject = downcast<RenderLayerModelObject>(*element.renderer());
     if (!layerModelObject.layer()->isComposited())
         return Exception { NOT_FOUND_ERR };
-    
+
     auto* backing = layerModelObject.layer()->backing();
     return backing->graphicsLayer()->primaryLayerID();
 }
@@ -2285,11 +2285,11 @@ ExceptionOr<void> Internals::setElementUsesDisplayListDrawing(Element& element,
 
     if (!element.renderer()->hasLayer())
         return Exception { INVALID_ACCESS_ERR };
-    
+
     RenderLayer* layer = downcast<RenderLayerModelObject>(element.renderer())->layer();
     if (!layer->isComposited())
         return Exception { INVALID_ACCESS_ERR };
-    
+
     layer->backing()->setUsesDisplayListDrawing(usesDisplayListDrawing);
     return { };
 }
@@ -2314,7 +2314,7 @@ ExceptionOr<void> Internals::setElementTracksDisplayListReplay(Element& element,
     RenderLayer* layer = downcast<RenderLayerModelObject>(element.renderer())->layer();
     if (!layer->isComposited())
         return Exception { INVALID_ACCESS_ERR };
-    
+
     layer->backing()->setIsTrackingDisplayListReplay(isTrackingReplay);
     return { };
 }
@@ -2554,7 +2554,7 @@ void Internals::setFooterHeight(float height)
 
     document->view()->setFooterHeight(height);
 }
-    
+
 void Internals::setTopContentInset(float contentInset)
 {
     Document* document = contextDocument();
@@ -2698,7 +2698,7 @@ ExceptionOr<unsigned> Internals::styleRecalcCount()
     Document* document = contextDocument();
     if (!document)
         return Exception { INVALID_ACCESS_ERR };
-    
+
     return document->styleRecalcCount();
 }
 
@@ -2725,7 +2725,7 @@ ExceptionOr<unsigned> Internals::compositingUpdateCount()
     Document* document = contextDocument();
     if (!document || !document->renderView())
         return Exception { INVALID_ACCESS_ERR };
-    
+
     return document->renderView()->compositor().compositingUpdateCount();
 }
 
@@ -3017,10 +3017,10 @@ ExceptionOr<void> Internals::setCaptionDisplayMode(const String& mode)
     Document* document = contextDocument();
     if (!document || !document->page())
         return Exception { INVALID_ACCESS_ERR };
-    
+
 #if ENABLE(VIDEO_TRACK)
     auto& captionPreferences = document->page()->group().captionPreferences();
-    
+
     if (equalLettersIgnoringASCIICase(mode, "automatic"))
         captionPreferences.setCaptionDisplayMode(CaptionUserPreferences::Automatic);
     else if (equalLettersIgnoringASCIICase(mode, "forcedonly"))
@@ -3085,12 +3085,12 @@ ExceptionOr<bool> Internals::isPluginUnavailabilityIndicatorObscured(Element& el
 
     return downcast<RenderEmbeddedObject>(*renderer).isReplacementObscured();
 }
-    
+
 bool Internals::isPluginSnapshotted(Element& element)
 {
     return is<HTMLPlugInElement>(element) && downcast<HTMLPlugInElement>(element).displayState() <= HTMLPlugInElement::DisplayingSnapshot;
 }
-    
+
 #if ENABLE(MEDIA_SOURCE)
 
 void Internals::initializeMockMediaSource()
@@ -3108,7 +3108,7 @@ Vector<String> Internals::bufferedSamplesForTrackID(SourceBuffer& buffer, const
 {
     return buffer.bufferedSamplesForTrackID(trackID);
 }
-    
+
 Vector<String> Internals::enqueuedSamplesForTrackID(SourceBuffer& buffer, const AtomicString& trackID)
 {
     return buffer.enqueuedSamplesForTrackID(trackID);
@@ -3148,7 +3148,7 @@ void Internals::endMediaSessionInterruption(const String& flagsString)
 
     if (equalLettersIgnoringASCIICase(flagsString, "mayresumeplaying"))
         flags = PlatformMediaSession::MayResumePlaying;
-    
+
     PlatformMediaSessionManager::sharedManager().endInterruption(flags);
 }
 
@@ -3301,7 +3301,7 @@ ExceptionOr<void> Internals::postRemoteControlCommand(const String& commandStrin
         command = PlatformMediaSession::SeekToPlaybackPositionCommand;
     else
         return Exception { INVALID_ACCESS_ERR };
-    
+
     PlatformMediaSessionManager::sharedManager().didReceiveRemoteControlCommand(command, &parameter);
     return { };
 }
@@ -3572,12 +3572,12 @@ static void appendOffsets(StringBuilder& builder, const Vector<LayoutUnit>& snap
             builder.appendLiteral(", ");
         else
             justStarting = false;
-        
+
         builder.append(String::number(coordinate.toUnsigned()));
     }
     builder.appendLiteral(" }");
 }
-    
+
 void Internals::setPlatformMomentumScrollingPredictionEnabled(bool enabled)
 {
     ScrollingMomentumCalculator::setPlatformMomentumScrollingPredictionEnabled(enabled);
@@ -3592,13 +3592,13 @@ ExceptionOr<String> Internals::scrollSnapOffsets(Element& element)
 
     RenderBox& box = *element.renderBox();
     ScrollableArea* scrollableArea;
-    
+
     if (box.isBody()) {
         FrameView* frameView = box.frame().mainFrame().view();
         if (!frameView || !frameView->isScrollable())
             return Exception { INVALID_ACCESS_ERR };
         scrollableArea = frameView;
-        
+
     } else {
         if (!box.canBeScrolledAndHasScrollableArea())
             return Exception { INVALID_ACCESS_ERR };
@@ -3607,7 +3607,7 @@ ExceptionOr<String> Internals::scrollSnapOffsets(Element& element)
 
     if (!scrollableArea)
         return String();
-    
+
     StringBuilder result;
 
     if (auto* offsets = scrollableArea->horizontalSnapOffsets()) {
@@ -3696,7 +3696,7 @@ void Internals::setShowAllPlugins(bool show)
     Document* document = contextDocument();
     if (!document)
         return;
-    
+
     Page* page = document->page();
     if (!page)
         return;
@@ -3729,6 +3729,32 @@ bool Internals::isReadableStreamDisturbed(JSC::ExecState& state, JSValue stream)
     return returnedValue.asBoolean();
 }
 
+#if ENABLE(READABLE_BYTE_STREAM_API)
+
+JSValue Internals::cloneArrayBuffer(JSC::ExecState& state, JSValue buffer, JSValue srcByteOffset, JSValue srcLength)
+{
+    JSGlobalObject* globalObject = state.vmEntryGlobalObject();
+    JSVMClientData* clientData = static_cast<JSVMClientData*>(state.vm().clientData);
+    const Identifier& privateName = clientData->builtinNames().cloneArrayBufferPrivateName();
+    JSValue value;
+    PropertySlot propertySlot(value, PropertySlot::InternalMethodType::Get);
+    globalObject->methodTable()->getOwnPropertySlot(globalObject, &state, privateName, propertySlot);
+    value = propertySlot.getValue(&state, privateName);
+    ASSERT(value.isFunction());
+
+    JSObject* function = value.getObject();
+    CallData callData;
+    CallType callType = JSC::getCallData(function, callData);
+    ASSERT(callType != JSC::CallType::None);
+    MarkedArgumentBuffer arguments;
+    arguments.append(buffer);
+    arguments.append(srcByteOffset);
+    arguments.append(srcLength);
+
+    return JSC::call(&state, function, callType, callData, JSC::jsUndefined(), arguments);
+}
+
+#endif
 #endif
 
 String Internals::resourceLoadStatisticsForOrigin(const String& origin)
index 3443842..450fb42 100644 (file)
@@ -188,14 +188,14 @@ public:
 
     void invalidateFontCache();
     void setFontSmoothingEnabled(bool);
-    
+
     ExceptionOr<void> setLowPowerModeEnabled(bool);
 
     ExceptionOr<void> setScrollViewPosition(int x, int y);
-    
+
     ExceptionOr<Ref<ClientRect>> layoutViewportRect();
     ExceptionOr<Ref<ClientRect>> visualViewportRect();
-    
+
     ExceptionOr<void> setViewBaseBackgroundColor(const String& colorValue);
 
     ExceptionOr<void> setPagination(const String& mode, int gap, int pageLength);
@@ -368,7 +368,7 @@ public:
 
     ExceptionOr<void> startTrackingLayerFlushes();
     ExceptionOr<unsigned> layerFlushCount();
-    
+
     ExceptionOr<void> startTrackingStyleRecalcs();
     ExceptionOr<unsigned> styleRecalcCount();
     unsigned lastStyleUpdateSize() const;
@@ -523,10 +523,13 @@ public:
 
 #if ENABLE(READABLE_STREAM_API)
     bool isReadableStreamDisturbed(JSC::ExecState&, JSC::JSValue);
+#if ENABLE(READABLE_BYTE_STREAM_API)
+    JSC::JSValue cloneArrayBuffer(JSC::ExecState&, JSC::JSValue, JSC::JSValue, JSC::JSValue);
+#endif
 #endif
 
     String composedTreeAsText(Node&);
-    
+
     bool isProcessingUserGesture();
 
     RefPtr<GCObservation> observeGC(JSC::JSValue);
@@ -535,7 +538,7 @@ public:
     void setUserInterfaceLayoutDirection(UserInterfaceLayoutDirection);
 
     bool userPrefersReducedMotion() const;
-    
+
     void reportBacktrace();
 
     enum class BaseWritingDirection { Natural, Ltr, Rtl };
index d20bdbc..f85f625 100644 (file)
@@ -490,6 +490,7 @@ enum EventThrottlingBehavior {
 
     void setShowAllPlugins(boolean showAll);
 
+    [Conditional=READABLE_STREAM_API&READABLE_BYTE_STREAM_API, CallWith=ScriptState] any cloneArrayBuffer(any buffer, any srcByteOffset, any byteLength);
     [Conditional=READABLE_STREAM_API, CallWith=ScriptState] boolean isReadableStreamDisturbed(any stream);
 
     DOMString resourceLoadStatisticsForOrigin(DOMString domain);