From e62c7dc9e5709b1ce54838aee30668a4c358a528 Mon Sep 17 00:00:00 2001 From: Jarred Sumner Date: Sun, 3 Apr 2022 00:09:45 -0700 Subject: [bun.js] Expose `ImageData` globally --- src/javascript/jsc/bindings/ZigGlobalObject.cpp | 15 + .../jsc/bindings/webcore/ArrayBufferView.cpp | 67 ++++ .../jsc/bindings/webcore/DOMClientIsoSubspaces.h | 2 +- .../jsc/bindings/webcore/DOMIsoSubspaces.h | 2 +- src/javascript/jsc/bindings/webcore/ImageData.cpp | 129 ++++++++ src/javascript/jsc/bindings/webcore/ImageData.h | 69 ++++ src/javascript/jsc/bindings/webcore/ImageData.idl | 41 +++ .../jsc/bindings/webcore/JSImageData.cpp | 359 +++++++++++++++++++++ .../jsc/bindings/webcore/JSImageData.dep | 1 + src/javascript/jsc/bindings/webcore/JSImageData.h | 94 ++++++ .../jsc/bindings/webcore/JSImageDataCustom.cpp | 59 ++++ 11 files changed, 836 insertions(+), 2 deletions(-) create mode 100644 src/javascript/jsc/bindings/webcore/ArrayBufferView.cpp create mode 100644 src/javascript/jsc/bindings/webcore/ImageData.cpp create mode 100644 src/javascript/jsc/bindings/webcore/ImageData.h create mode 100644 src/javascript/jsc/bindings/webcore/ImageData.idl create mode 100644 src/javascript/jsc/bindings/webcore/JSImageData.cpp create mode 100644 src/javascript/jsc/bindings/webcore/JSImageData.dep create mode 100644 src/javascript/jsc/bindings/webcore/JSImageData.h create mode 100644 src/javascript/jsc/bindings/webcore/JSImageDataCustom.cpp (limited to 'src') diff --git a/src/javascript/jsc/bindings/ZigGlobalObject.cpp b/src/javascript/jsc/bindings/ZigGlobalObject.cpp index 5fbf97fc9..ce73975c8 100644 --- a/src/javascript/jsc/bindings/ZigGlobalObject.cpp +++ b/src/javascript/jsc/bindings/ZigGlobalObject.cpp @@ -88,6 +88,7 @@ #include "JSEvent.h" #include "JSErrorEvent.h" #include "JSFetchHeaders.h" +#include "JSImageData.h" #include "Process.h" @@ -396,6 +397,17 @@ JSC_DEFINE_CUSTOM_GETTER(JSFetchHeaders_getter, WebCore::JSFetchHeaders::getConstructor(JSC::getVM(lexicalGlobalObject), thisObject)); } +JSC_DECLARE_CUSTOM_GETTER(JSImageData_getter); + +JSC_DEFINE_CUSTOM_GETTER(JSImageData_getter, + (JSC::JSGlobalObject * lexicalGlobalObject, JSC::EncodedJSValue thisValue, + JSC::PropertyName)) +{ + Zig::GlobalObject* thisObject = JSC::jsCast(lexicalGlobalObject); + return JSC::JSValue::encode( + WebCore::JSImageData::getConstructor(JSC::getVM(lexicalGlobalObject), thisObject)); +} + JSC_DECLARE_CUSTOM_GETTER(JSEventTarget_getter); JSC_DEFINE_CUSTOM_GETTER(JSEventTarget_getter, @@ -879,6 +891,9 @@ void GlobalObject::installAPIGlobals(JSClassRef* globals, int count, JSC::VM& vm putDirectCustomAccessor(vm, JSC::Identifier::fromString(vm, "ErrorEvent"_s), JSC::CustomGetterSetter::create(vm, JSErrorEvent_getter, nullptr), JSC::PropertyAttribute::DontDelete | JSC::PropertyAttribute::ReadOnly); + putDirectCustomAccessor(vm, JSC::Identifier::fromString(vm, "ImageData"_s), JSC::CustomGetterSetter::create(vm, JSImageData_getter, nullptr), + JSC::PropertyAttribute::DontDelete | JSC::PropertyAttribute::ReadOnly); + extraStaticGlobals.releaseBuffer(); this->setRemoteDebuggingEnabled(true); diff --git a/src/javascript/jsc/bindings/webcore/ArrayBufferView.cpp b/src/javascript/jsc/bindings/webcore/ArrayBufferView.cpp new file mode 100644 index 000000000..9bb609510 --- /dev/null +++ b/src/javascript/jsc/bindings/webcore/ArrayBufferView.cpp @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2009-2021 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "JavaScriptCore/ArrayBufferView.h" + +namespace JSC { + +ArrayBufferView::ArrayBufferView( + RefPtr&& buffer, size_t byteOffset, size_t byteLength) + : m_byteOffset(byteOffset) + , m_isDetachable(true) + , m_byteLength(byteLength) + , m_buffer(WTFMove(buffer)) +{ + Checked length(byteOffset); + length += byteLength; + RELEASE_ASSERT_WITH_SECURITY_IMPLICATION(length <= m_buffer->byteLength()); + if (m_buffer) + m_baseAddress = BaseAddress(static_cast(m_buffer->data()) + m_byteOffset, byteLength); +} + +ArrayBufferView::~ArrayBufferView() +{ + if (!m_isDetachable) + m_buffer->unpin(); +} + +void ArrayBufferView::setDetachable(bool flag) +{ + if (flag == m_isDetachable) + return; + + m_isDetachable = flag; + + if (!m_buffer) + return; + + if (flag) + m_buffer->unpin(); + else + m_buffer->pin(); +} + +} // namespace JSC diff --git a/src/javascript/jsc/bindings/webcore/DOMClientIsoSubspaces.h b/src/javascript/jsc/bindings/webcore/DOMClientIsoSubspaces.h index ad1b6a32b..6d779fccf 100644 --- a/src/javascript/jsc/bindings/webcore/DOMClientIsoSubspaces.h +++ b/src/javascript/jsc/bindings/webcore/DOMClientIsoSubspaces.h @@ -541,7 +541,7 @@ public: // std::unique_ptr m_clientSubspaceForHTMLUnknownElement; // std::unique_ptr m_clientSubspaceForHTMLVideoElement; // std::unique_ptr m_clientSubspaceForImageBitmap; - // std::unique_ptr m_clientSubspaceForImageData; + std::unique_ptr m_clientSubspaceForImageData; // std::unique_ptr m_clientSubspaceForMediaController; // std::unique_ptr m_clientSubspaceForMediaEncryptedEvent; // std::unique_ptr m_clientSubspaceForMediaError; diff --git a/src/javascript/jsc/bindings/webcore/DOMIsoSubspaces.h b/src/javascript/jsc/bindings/webcore/DOMIsoSubspaces.h index 75d91c0a2..3c064cab3 100644 --- a/src/javascript/jsc/bindings/webcore/DOMIsoSubspaces.h +++ b/src/javascript/jsc/bindings/webcore/DOMIsoSubspaces.h @@ -532,7 +532,7 @@ public: // std::unique_ptr m_subspaceForHTMLUnknownElement; // std::unique_ptr m_subspaceForHTMLVideoElement; // std::unique_ptr m_subspaceForImageBitmap; - // std::unique_ptr m_subspaceForImageData; + std::unique_ptr m_subspaceForImageData; // std::unique_ptr m_subspaceForMediaController; // std::unique_ptr m_subspaceForMediaEncryptedEvent; // std::unique_ptr m_subspaceForMediaError; diff --git a/src/javascript/jsc/bindings/webcore/ImageData.cpp b/src/javascript/jsc/bindings/webcore/ImageData.cpp new file mode 100644 index 000000000..2e6511bb4 --- /dev/null +++ b/src/javascript/jsc/bindings/webcore/ImageData.cpp @@ -0,0 +1,129 @@ +/* + * Copyright (C) 2008-2021 Apple Inc. All rights reserved. + * Copyright (C) 2014 Adobe Systems Incorporated. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Apple Inc. ("Apple") nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "ImageData.h" + +#include "JavaScriptCore/JSGenericTypedArrayViewInlines.h" +#include "JavaScriptCore/GenericTypedArrayViewInlines.h" + +#include "wtf/text/TextStream.h" + +namespace WebCore { +using namespace JSC; + +static CheckedUint32 computeDataSize(int width, int height) +{ + CheckedUint32 checkedDataSize = 4; + checkedDataSize *= static_cast(width); + checkedDataSize *= static_cast(height); + return checkedDataSize; +} + +// PredefinedColorSpace ImageData::computeColorSpace(std::optional settings, PredefinedColorSpace defaultColorSpace) +// { +// if (settings && settings->colorSpace) +// return *settings->colorSpace; +// return defaultColorSpace; +// } + +// Ref ImageData::create(PixelBuffer&& pixelBuffer) +// { +// auto colorSpace = toPredefinedColorSpace(pixelBuffer.format().colorSpace); +// return adoptRef(*new ImageData(pixelBuffer.size(), pixelBuffer.takeData(), *colorSpace)); +// } + +// RefPtr ImageData::create(std::optional&& pixelBuffer) +// { +// if (!pixelBuffer) +// return nullptr; +// return create(WTFMove(*pixelBuffer)); +// } + +ExceptionOr> ImageData::create(unsigned int sw, unsigned int sh) +{ + if (!sw || !sh) + return Exception { IndexSizeError }; + + auto dataSize = computeDataSize(static_cast(sw), static_cast(sh)); + if (dataSize.hasOverflowed()) + return Exception { RangeError, "Cannot allocate a buffer of this size"_s }; + + auto byteArray = Uint8ClampedArray::tryCreateUninitialized(dataSize); + if (!byteArray) { + // FIXME: Does this need to be a "real" out of memory error with setOutOfMemoryError called on it? + return Exception { RangeError, "Out of memory"_s }; + } + byteArray->zeroFill(); + + // auto colorSpace = computeColorSpace(settings); + return adoptRef(*new ImageData(sw, sh, byteArray.releaseNonNull())); +} + +ExceptionOr> ImageData::create(Ref&& byteArray, unsigned sw, std::optional sh) +{ + unsigned length = byteArray->length(); + if (!length || length % 4) + return Exception { InvalidStateError, "Length is not a non-zero multiple of 4"_s }; + + length /= 4; + if (!sw || length % sw) + return Exception { IndexSizeError, "Length is not a multiple of sw"_s }; + + unsigned height = length / sw; + if (sh && sh.value() != height) + return Exception { IndexSizeError, "sh value is not equal to height"_s }; + + int width = sw; + + auto dataSize = computeDataSize(width, height); + if (dataSize.hasOverflowed() || dataSize != byteArray->length()) + return Exception { RangeError }; + + // auto colorSpace = computeColorSpace(settings); + return adoptRef(*new ImageData(width, height, WTFMove(byteArray))); +} + +ImageData::ImageData(int width, int height, Ref&& data) + : m_data(WTFMove(data)) +// , m_colorSpace(colorSpace) +{ + m_width = width; + m_height = height; +} + +ImageData::~ImageData() = default; + +TextStream& operator<<(TextStream& ts, const ImageData& imageData) +{ + // Print out the address of the pixel data array + return ts << &imageData.data(); +} + +} diff --git a/src/javascript/jsc/bindings/webcore/ImageData.h b/src/javascript/jsc/bindings/webcore/ImageData.h new file mode 100644 index 000000000..1f3a7ae0b --- /dev/null +++ b/src/javascript/jsc/bindings/webcore/ImageData.h @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2008-2021 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Apple Inc. ("Apple") nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#pragma once + +#include "root.h" + +#include "ExceptionOr.h" +// #include "PixelBuffer.h" +#include +#include + +namespace WebCore { + +class ImageData : public RefCounted { +public: + WEBCORE_EXPORT static ExceptionOr> create(unsigned sw, unsigned sh); + WEBCORE_EXPORT static ExceptionOr> create(Ref&&, unsigned sw, std::optional sh); + + WEBCORE_EXPORT ~ImageData(); + + // static PredefinedColorSpace computeColorSpace(std::optional, PredefinedColorSpace defaultColorSpace = PredefinedColorSpace::SRGB); + + // const IntSize& size() const { return m_size; } + + int width() const { return m_width; } + int height() const { return m_height; } + Uint8ClampedArray& data() const { return m_data.get(); } + // PredefinedColorSpace colorSpace() const { return m_colorSpace; } + + // PixelBuffer pixelBuffer() const; + +private: + explicit ImageData(int width, int height, Ref&&); + + int m_width; + int m_height; + Ref m_data; + // PredefinedColorSpace m_colorSpace; +}; + +WEBCORE_EXPORT TextStream& operator<<(TextStream&, const ImageData&); + +} // namespace WebCore diff --git a/src/javascript/jsc/bindings/webcore/ImageData.idl b/src/javascript/jsc/bindings/webcore/ImageData.idl new file mode 100644 index 000000000..53713d6a0 --- /dev/null +++ b/src/javascript/jsc/bindings/webcore/ImageData.idl @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2008-2021 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Apple Inc. ("Apple") nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +[ + CustomToJSObject, + ExportMacro=WEBCORE_EXPORT, + Exposed=(Window,Worker), +] interface ImageData { + constructor(unsigned long sw, unsigned long sh, optional ImageDataSettings settings); + constructor(Uint8ClampedArray data, unsigned long sw, optional unsigned long sh, optional ImageDataSettings settings); + + readonly attribute unsigned long width; + readonly attribute unsigned long height; + readonly attribute Uint8ClampedArray data; + [EnabledBySetting=CanvasColorSpaceEnabled] readonly attribute PredefinedColorSpace colorSpace; +}; diff --git a/src/javascript/jsc/bindings/webcore/JSImageData.cpp b/src/javascript/jsc/bindings/webcore/JSImageData.cpp new file mode 100644 index 000000000..230558ef6 --- /dev/null +++ b/src/javascript/jsc/bindings/webcore/JSImageData.cpp @@ -0,0 +1,359 @@ +/* + This file is part of the WebKit open source project. + This file has been generated by generate-bindings.pl. DO NOT MODIFY! + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "config.h" +#include "JSImageData.h" + +#include "ActiveDOMObject.h" +#include "ExtendedDOMClientIsoSubspaces.h" +#include "ExtendedDOMIsoSubspaces.h" +#include "JSDOMAttribute.h" +#include "JSDOMBinding.h" +#include "JSDOMConstructor.h" +#include "JSDOMConvertBufferSource.h" +#include "JSDOMConvertDictionary.h" +#include "JSDOMConvertEnumeration.h" +#include "JSDOMConvertInterface.h" +#include "JSDOMConvertNumbers.h" +#include "JSDOMExceptionHandling.h" +#include "JSDOMGlobalObject.h" +#include "JSDOMGlobalObjectInlines.h" +#include "JSDOMWrapperCache.h" +// #include "JSImageDataSettings.h" +// #include "JSPredefinedColorSpace.h" + +#include "ScriptExecutionContext.h" +#include "WebCoreJSClientData.h" +#include "JavaScriptCore/FunctionPrototype.h" +#include "JavaScriptCore/HeapAnalyzer.h" +#include "JavaScriptCore/JSDestructibleObjectHeapCellType.h" +#include "JavaScriptCore/SlotVisitorMacros.h" +#include "JavaScriptCore/SubspaceInlines.h" +#include +#include +#include + +#include "JavaScriptCore/JSArrayBufferViewInlines.h" +#include "JavaScriptCore/JSGenericTypedArrayViewInlines.h" +#include "JavaScriptCore/ArrayBufferView.h" +#include "JavaScriptCore/JSCInlines.h" +#include "JSImageData.h" + +namespace WebCore { +using namespace JSC; + +// Attributes + +static JSC_DECLARE_CUSTOM_GETTER(jsImageDataConstructor); +static JSC_DECLARE_CUSTOM_GETTER(jsImageData_width); +static JSC_DECLARE_CUSTOM_GETTER(jsImageData_height); +static JSC_DECLARE_CUSTOM_GETTER(jsImageData_data); +// static JSC_DECLARE_CUSTOM_GETTER(jsImageData_colorSpace); + +class JSImageDataPrototype final : public JSC::JSNonFinalObject { +public: + using Base = JSC::JSNonFinalObject; + static JSImageDataPrototype* create(JSC::VM& vm, JSDOMGlobalObject* globalObject, JSC::Structure* structure) + { + JSImageDataPrototype* ptr = new (NotNull, JSC::allocateCell(vm)) JSImageDataPrototype(vm, globalObject, structure); + ptr->finishCreation(vm); + return ptr; + } + + DECLARE_INFO; + template + static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm) + { + STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(JSImageDataPrototype, Base); + return &vm.plainObjectSpace(); + } + static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype) + { + return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), info()); + } + +private: + JSImageDataPrototype(JSC::VM& vm, JSC::JSGlobalObject*, JSC::Structure* structure) + : JSC::JSNonFinalObject(vm, structure) + { + } + + void finishCreation(JSC::VM&); +}; +STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(JSImageDataPrototype, JSImageDataPrototype::Base); + +using JSImageDataDOMConstructor = JSDOMConstructor; + +static inline EncodedJSValue constructJSImageData1(JSGlobalObject* lexicalGlobalObject, CallFrame* callFrame) +{ + VM& vm = lexicalGlobalObject->vm(); + auto throwScope = DECLARE_THROW_SCOPE(vm); + auto* castedThis = jsCast(callFrame->jsCallee()); + ASSERT(castedThis); + EnsureStillAliveScope argument0 = callFrame->uncheckedArgument(0); + auto sw = convert(*lexicalGlobalObject, argument0.value()); + RETURN_IF_EXCEPTION(throwScope, encodedJSValue()); + EnsureStillAliveScope argument1 = callFrame->uncheckedArgument(1); + auto sh = convert(*lexicalGlobalObject, argument1.value()); + RETURN_IF_EXCEPTION(throwScope, encodedJSValue()); + // auto settings = convert>(*lexicalGlobalObject, argument2.value()); + // RETURN_IF_EXCEPTION(throwScope, encodedJSValue()); + auto object = ImageData::create(WTFMove(sw), WTFMove(sh)); + if constexpr (IsExceptionOr) + RETURN_IF_EXCEPTION(throwScope, {}); + static_assert(TypeOrExceptionOrUnderlyingType::isRef); + auto jsValue = toJSNewlyCreated>(*lexicalGlobalObject, *castedThis->globalObject(), throwScope, WTFMove(object)); + if constexpr (IsExceptionOr) + RETURN_IF_EXCEPTION(throwScope, {}); + setSubclassStructureIfNeeded(lexicalGlobalObject, callFrame, asObject(jsValue)); + RETURN_IF_EXCEPTION(throwScope, {}); + return JSValue::encode(jsValue); +} + +static inline EncodedJSValue constructJSImageData2(JSGlobalObject* lexicalGlobalObject, CallFrame* callFrame) +{ + VM& vm = lexicalGlobalObject->vm(); + auto throwScope = DECLARE_THROW_SCOPE(vm); + auto* castedThis = jsCast(callFrame->jsCallee()); + ASSERT(castedThis); + EnsureStillAliveScope argument0 = callFrame->uncheckedArgument(0); + auto data = convert(*lexicalGlobalObject, argument0.value(), [](JSC::JSGlobalObject& lexicalGlobalObject, JSC::ThrowScope& scope) { throwArgumentTypeError(lexicalGlobalObject, scope, 0, "data", "ImageData", nullptr, "Uint8ClampedArray"); }); + RETURN_IF_EXCEPTION(throwScope, encodedJSValue()); + EnsureStillAliveScope argument1 = callFrame->uncheckedArgument(1); + auto sw = convert(*lexicalGlobalObject, argument1.value()); + RETURN_IF_EXCEPTION(throwScope, encodedJSValue()); + EnsureStillAliveScope argument2 = callFrame->argument(2); + auto sh = argument2.value().isUndefined() ? std::optional::ReturnType>() : std::optional::ReturnType>(convert(*lexicalGlobalObject, argument2.value())); + RETURN_IF_EXCEPTION(throwScope, encodedJSValue()); + auto object = ImageData::create(data.releaseNonNull(), WTFMove(sw), WTFMove(sh)); + if constexpr (IsExceptionOr) + RETURN_IF_EXCEPTION(throwScope, {}); + static_assert(TypeOrExceptionOrUnderlyingType::isRef); + auto jsValue = toJSNewlyCreated>(*lexicalGlobalObject, *castedThis->globalObject(), throwScope, WTFMove(object)); + if constexpr (IsExceptionOr) + RETURN_IF_EXCEPTION(throwScope, {}); + setSubclassStructureIfNeeded(lexicalGlobalObject, callFrame, asObject(jsValue)); + RETURN_IF_EXCEPTION(throwScope, {}); + return JSValue::encode(jsValue); +} + +template<> EncodedJSValue JSC_HOST_CALL_ATTRIBUTES JSImageDataDOMConstructor::construct(JSGlobalObject* lexicalGlobalObject, CallFrame* callFrame) +{ + VM& vm = lexicalGlobalObject->vm(); + auto throwScope = DECLARE_THROW_SCOPE(vm); + UNUSED_PARAM(throwScope); + size_t argsCount = std::min(4, callFrame->argumentCount()); + if (argsCount == 2) { + JSValue distinguishingArg = callFrame->uncheckedArgument(0); + if (distinguishingArg.isObject() && asObject(distinguishingArg)->inherits(vm)) + RELEASE_AND_RETURN(throwScope, (constructJSImageData2(lexicalGlobalObject, callFrame))); + if (distinguishingArg.isNumber()) + RELEASE_AND_RETURN(throwScope, (constructJSImageData1(lexicalGlobalObject, callFrame))); + RELEASE_AND_RETURN(throwScope, (constructJSImageData1(lexicalGlobalObject, callFrame))); + } + if (argsCount == 3) { + JSValue distinguishingArg = callFrame->uncheckedArgument(0); + if (distinguishingArg.isObject() && asObject(distinguishingArg)->inherits(vm)) + RELEASE_AND_RETURN(throwScope, (constructJSImageData2(lexicalGlobalObject, callFrame))); + if (distinguishingArg.isNumber()) + RELEASE_AND_RETURN(throwScope, (constructJSImageData1(lexicalGlobalObject, callFrame))); + RELEASE_AND_RETURN(throwScope, (constructJSImageData1(lexicalGlobalObject, callFrame))); + } + if (argsCount == 4) { + RELEASE_AND_RETURN(throwScope, (constructJSImageData2(lexicalGlobalObject, callFrame))); + } + return argsCount < 2 ? throwVMError(lexicalGlobalObject, throwScope, createNotEnoughArgumentsError(lexicalGlobalObject)) : throwVMTypeError(lexicalGlobalObject, throwScope); +} +JSC_ANNOTATE_HOST_FUNCTION(JSImageDataConstructorConstruct, JSImageDataDOMConstructor::construct); + +template<> const ClassInfo JSImageDataDOMConstructor::s_info = { "ImageData"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSImageDataDOMConstructor) }; + +template<> JSValue JSImageDataDOMConstructor::prototypeForStructure(JSC::VM& vm, const JSDOMGlobalObject& globalObject) +{ + UNUSED_PARAM(vm); + return globalObject.functionPrototype(); +} + +template<> void JSImageDataDOMConstructor::initializeProperties(VM& vm, JSDOMGlobalObject& globalObject) +{ + putDirect(vm, vm.propertyNames->length, jsNumber(2), JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontEnum); + JSString* nameString = jsNontrivialString(vm, "ImageData"_s); + m_originalName.set(vm, this, nameString); + putDirect(vm, vm.propertyNames->name, nameString, JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontEnum); + putDirect(vm, vm.propertyNames->prototype, JSImageData::prototype(vm, globalObject), JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontEnum | JSC::PropertyAttribute::DontDelete); +} + +/* Hash table for prototype */ + +static const HashTableValue JSImageDataPrototypeTableValues[] = { + { "constructor", static_cast(JSC::PropertyAttribute::DontEnum), NoIntrinsic, { (intptr_t) static_cast(jsImageDataConstructor), (intptr_t) static_cast(0) } }, + { "width", static_cast(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute), NoIntrinsic, { (intptr_t) static_cast(jsImageData_width), (intptr_t) static_cast(0) } }, + { "height", static_cast(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute), NoIntrinsic, { (intptr_t) static_cast(jsImageData_height), (intptr_t) static_cast(0) } }, + { "data", static_cast(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute), NoIntrinsic, { (intptr_t) static_cast(jsImageData_data), (intptr_t) static_cast(0) } }, + // { "colorSpace", static_cast(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute), NoIntrinsic, { (intptr_t) static_cast(jsImageData_colorSpace), (intptr_t) static_cast(0) } }, +}; + +const ClassInfo JSImageDataPrototype::s_info = { "ImageData"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSImageDataPrototype) }; + +void JSImageDataPrototype::finishCreation(VM& vm) +{ + Base::finishCreation(vm); + reifyStaticProperties(vm, JSImageData::info(), JSImageDataPrototypeTableValues, *this); + JSC_TO_STRING_TAG_WITHOUT_TRANSITION(); +} + +const ClassInfo JSImageData::s_info = { "ImageData"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSImageData) }; + +JSImageData::JSImageData(Structure* structure, JSDOMGlobalObject& globalObject, Ref&& impl) + : JSDOMWrapper(structure, globalObject, WTFMove(impl)) +{ +} + +void JSImageData::finishCreation(VM& vm) +{ + Base::finishCreation(vm); + ASSERT(inherits(vm, info())); + + // static_assert(!std::is_base_of::value, "Interface is not marked as [ActiveDOMObject] even though implementation class subclasses ActiveDOMObject."); +} + +JSObject* JSImageData::createPrototype(VM& vm, JSDOMGlobalObject& globalObject) +{ + return JSImageDataPrototype::create(vm, &globalObject, JSImageDataPrototype::createStructure(vm, &globalObject, globalObject.objectPrototype())); +} + +JSObject* JSImageData::prototype(VM& vm, JSDOMGlobalObject& globalObject) +{ + return getDOMPrototype(vm, globalObject); +} + +JSValue JSImageData::getConstructor(VM& vm, const JSGlobalObject* globalObject) +{ + return getDOMConstructor(vm, *jsCast(globalObject)); +} + +void JSImageData::destroy(JSC::JSCell* cell) +{ + JSImageData* thisObject = static_cast(cell); + thisObject->JSImageData::~JSImageData(); +} + +JSC_DEFINE_CUSTOM_GETTER(jsImageDataConstructor, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, PropertyName)) +{ + VM& vm = JSC::getVM(lexicalGlobalObject); + auto throwScope = DECLARE_THROW_SCOPE(vm); + auto* prototype = jsDynamicCast(vm, JSValue::decode(thisValue)); + if (UNLIKELY(!prototype)) + return throwVMTypeError(lexicalGlobalObject, throwScope); + return JSValue::encode(JSImageData::getConstructor(JSC::getVM(lexicalGlobalObject), prototype->globalObject())); +} + +static inline JSValue jsImageData_widthGetter(JSGlobalObject& lexicalGlobalObject, JSImageData& thisObject) +{ + auto& vm = JSC::getVM(&lexicalGlobalObject); + auto throwScope = DECLARE_THROW_SCOPE(vm); + auto& impl = thisObject.wrapped(); + RELEASE_AND_RETURN(throwScope, (toJS(lexicalGlobalObject, throwScope, impl.width()))); +} + +JSC_DEFINE_CUSTOM_GETTER(jsImageData_width, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, PropertyName attributeName)) +{ + return IDLAttribute::get(*lexicalGlobalObject, thisValue, attributeName); +} + +static inline JSValue jsImageData_heightGetter(JSGlobalObject& lexicalGlobalObject, JSImageData& thisObject) +{ + auto& vm = JSC::getVM(&lexicalGlobalObject); + auto throwScope = DECLARE_THROW_SCOPE(vm); + auto& impl = thisObject.wrapped(); + RELEASE_AND_RETURN(throwScope, (toJS(lexicalGlobalObject, throwScope, impl.height()))); +} + +JSC_DEFINE_CUSTOM_GETTER(jsImageData_height, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, PropertyName attributeName)) +{ + return IDLAttribute::get(*lexicalGlobalObject, thisValue, attributeName); +} + +static inline JSValue jsImageData_dataGetter(JSGlobalObject& lexicalGlobalObject, JSImageData& thisObject) +{ + auto& vm = JSC::getVM(&lexicalGlobalObject); + auto throwScope = DECLARE_THROW_SCOPE(vm); + auto& impl = thisObject.wrapped(); + RELEASE_AND_RETURN(throwScope, (toJS(lexicalGlobalObject, *thisObject.globalObject(), throwScope, impl.data()))); +} + +JSC_DEFINE_CUSTOM_GETTER(jsImageData_data, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, PropertyName attributeName)) +{ + return IDLAttribute::get(*lexicalGlobalObject, thisValue, attributeName); +} + +// static inline JSValue jsImageData_colorSpaceGetter(JSGlobalObject& lexicalGlobalObject, JSImageData& thisObject) +// { +// return JSC::JSValue(JSC::jsString(lexicalGlobalObject.vm(), "srgb"_s)); +// } + +// JSC_DEFINE_CUSTOM_GETTER(jsImageData_colorSpace, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, PropertyName attributeName)) +// { +// return JSC::JSValue::encode( +// jsImageData_colorSpaceGetter(*lexicalGlobalObject, *jsCast(JSValue::decode(thisValue)))); +// } + +JSC::GCClient::IsoSubspace* JSImageData::subspaceForImpl(JSC::VM& vm) +{ + return WebCore::subspaceForImpl( + vm, + [](auto& spaces) { return spaces.m_clientSubspaceForImageData.get(); }, + [](auto& spaces, auto&& space) { spaces.m_clientSubspaceForImageData = WTFMove(space); }, + [](auto& spaces) { return spaces.m_subspaceForImageData.get(); }, + [](auto& spaces, auto&& space) { spaces.m_subspaceForImageData = WTFMove(space); }); +} + +void JSImageData::analyzeHeap(JSCell* cell, HeapAnalyzer& analyzer) +{ + auto* thisObject = jsCast(cell); + analyzer.setWrappedObjectForCell(cell, &thisObject->wrapped()); + if (thisObject->scriptExecutionContext()) + analyzer.setLabelForCell(cell, "url " + thisObject->scriptExecutionContext()->url().string()); + Base::analyzeHeap(cell, analyzer); +} + +bool JSImageDataOwner::isReachableFromOpaqueRoots(JSC::Handle handle, void*, AbstractSlotVisitor& visitor, const char** reason) +{ + UNUSED_PARAM(handle); + UNUSED_PARAM(visitor); + UNUSED_PARAM(reason); + return false; +} + +void JSImageDataOwner::finalize(JSC::Handle handle, void* context) +{ + auto* jsImageData = static_cast(handle.slot()->asCell()); + auto& world = *static_cast(context); + uncacheWrapper(world, &jsImageData->wrapped(), jsImageData); +} + +ImageData* JSImageData::toWrapped(JSC::VM& vm, JSC::JSValue value) +{ + if (auto* wrapper = jsDynamicCast(vm, value)) + return &wrapper->wrapped(); + return nullptr; +} + +} diff --git a/src/javascript/jsc/bindings/webcore/JSImageData.dep b/src/javascript/jsc/bindings/webcore/JSImageData.dep new file mode 100644 index 000000000..5c5941ed3 --- /dev/null +++ b/src/javascript/jsc/bindings/webcore/JSImageData.dep @@ -0,0 +1 @@ +JSImageData.h : diff --git a/src/javascript/jsc/bindings/webcore/JSImageData.h b/src/javascript/jsc/bindings/webcore/JSImageData.h new file mode 100644 index 000000000..29e7cc6ed --- /dev/null +++ b/src/javascript/jsc/bindings/webcore/JSImageData.h @@ -0,0 +1,94 @@ +/* + This file is part of the WebKit open source project. + This file has been generated by generate-bindings.pl. DO NOT MODIFY! + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#pragma once + +#include "ImageData.h" +#include "JSDOMWrapper.h" +#include + +namespace WebCore { + +class WEBCORE_EXPORT JSImageData : public JSDOMWrapper { +public: + using Base = JSDOMWrapper; + static JSImageData* create(JSC::Structure* structure, JSDOMGlobalObject* globalObject, Ref&& impl) + { + JSImageData* ptr = new (NotNull, JSC::allocateCell(globalObject->vm())) JSImageData(structure, *globalObject, WTFMove(impl)); + ptr->finishCreation(globalObject->vm()); + return ptr; + } + + static JSC::JSObject* createPrototype(JSC::VM&, JSDOMGlobalObject&); + static JSC::JSObject* prototype(JSC::VM&, JSDOMGlobalObject&); + static ImageData* toWrapped(JSC::VM&, JSC::JSValue); + static void destroy(JSC::JSCell*); + + DECLARE_INFO; + + static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype) + { + return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), info(), JSC::NonArray); + } + + static JSC::JSValue getConstructor(JSC::VM&, const JSC::JSGlobalObject*); + template static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm) + { + if constexpr (mode == JSC::SubspaceAccess::Concurrently) + return nullptr; + return subspaceForImpl(vm); + } + static JSC::GCClient::IsoSubspace* subspaceForImpl(JSC::VM& vm); + static void analyzeHeap(JSCell*, JSC::HeapAnalyzer&); + +protected: + JSImageData(JSC::Structure*, JSDOMGlobalObject&, Ref&&); + + void finishCreation(JSC::VM&); +}; + +class WEBCORE_EXPORT JSImageDataOwner final : public JSC::WeakHandleOwner { +public: + bool isReachableFromOpaqueRoots(JSC::Handle, void* context, JSC::AbstractSlotVisitor&, const char**) final; + void finalize(JSC::Handle, void* context) final; +}; + +inline JSC::WeakHandleOwner* wrapperOwner(DOMWrapperWorld&, ImageData*) +{ + static NeverDestroyed owner; + return &owner.get(); +} + +inline void* wrapperKey(ImageData* wrappableObject) +{ + return wrappableObject; +} + +WEBCORE_EXPORT JSC::JSValue toJS(JSC::JSGlobalObject*, JSDOMGlobalObject*, ImageData&); +inline JSC::JSValue toJS(JSC::JSGlobalObject* lexicalGlobalObject, JSDOMGlobalObject* globalObject, ImageData* impl) { return impl ? toJS(lexicalGlobalObject, globalObject, *impl) : JSC::jsNull(); } +JSC::JSValue toJSNewlyCreated(JSC::JSGlobalObject*, JSDOMGlobalObject*, Ref&&); +inline JSC::JSValue toJSNewlyCreated(JSC::JSGlobalObject* lexicalGlobalObject, JSDOMGlobalObject* globalObject, RefPtr&& impl) { return impl ? toJSNewlyCreated(lexicalGlobalObject, globalObject, impl.releaseNonNull()) : JSC::jsNull(); } + +template<> struct JSDOMWrapperConverterTraits { + using WrapperClass = JSImageData; + using ToWrappedReturnType = ImageData*; +}; + +} // namespace WebCore diff --git a/src/javascript/jsc/bindings/webcore/JSImageDataCustom.cpp b/src/javascript/jsc/bindings/webcore/JSImageDataCustom.cpp new file mode 100644 index 000000000..43c9871d6 --- /dev/null +++ b/src/javascript/jsc/bindings/webcore/JSImageDataCustom.cpp @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2008-2019 Apple Inc. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "JSImageData.h" + +#include "JSDOMConvert.h" +#include "JSDOMWrapperCache.h" +#include +#include +#include +#include +#include + +namespace WebCore { +using namespace JSC; + +JSValue toJSNewlyCreated(JSGlobalObject* lexicalGlobalObject, JSDOMGlobalObject* globalObject, Ref&& imageData) +{ + VM& vm = lexicalGlobalObject->vm(); + auto& data = imageData->data(); + auto* wrapper = createWrapper(globalObject, WTFMove(imageData)); + Identifier dataName = Identifier::fromString(vm, "data"); + wrapper->putDirect(vm, dataName, toJS(lexicalGlobalObject, globalObject, data), PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly); + // FIXME: Adopt reportExtraMemoryVisited, and switch to reportExtraMemoryAllocated. + // https://bugs.webkit.org/show_bug.cgi?id=142595 + vm.heap.deprecatedReportExtraMemory(data.length()); + + return wrapper; +} + +JSValue toJS(JSGlobalObject* lexicalGlobalObject, JSDOMGlobalObject* globalObject, ImageData& imageData) +{ + return wrap(lexicalGlobalObject, globalObject, imageData); +} + +} -- cgit v1.2.3