From 1bf1084f2b10c3b47fd1a588d85d21ed0eb41d0c Mon Sep 17 00:00:00 2001 From: Lorry Tar Creator Date: Tue, 27 Jun 2017 06:07:23 +0000 Subject: webkitgtk-2.16.5 --- Source/WTF/wtf/BlockPtr.h | 169 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 169 insertions(+) create mode 100644 Source/WTF/wtf/BlockPtr.h (limited to 'Source/WTF/wtf/BlockPtr.h') diff --git a/Source/WTF/wtf/BlockPtr.h b/Source/WTF/wtf/BlockPtr.h new file mode 100644 index 000000000..1b79d4178 --- /dev/null +++ b/Source/WTF/wtf/BlockPtr.h @@ -0,0 +1,169 @@ +/* + * Copyright (C) 2016 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. 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 INC. 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 +#include + +namespace WTF { + +extern "C" void* _NSConcreteMallocBlock[32]; + +template class BlockPtr; + +template +class BlockPtr { +public: + using BlockType = R (^)(Args...); + + template + static BlockPtr fromCallable(F function) + { + struct Descriptor { + uintptr_t reserved; + uintptr_t size; + void (*copy)(void *dst, const void *src); + void (*dispose)(const void *); + }; + + struct Block { + void* isa; + int32_t flags; + int32_t reserved; + R (*invoke)(void *, Args...); + const struct Descriptor* descriptor; + F f; + }; + + static const Descriptor descriptor { + 0, + sizeof(Block), + + // We keep the copy function null - the block is already on the heap + // so it should never be copied. + nullptr, + + [](const void* ptr) { + static_cast(const_cast(ptr))->f.~F(); + } + }; + + Block* block = static_cast(malloc(sizeof(Block))); + block->isa = _NSConcreteMallocBlock; + + enum { + BLOCK_NEEDS_FREE = (1 << 24), + BLOCK_HAS_COPY_DISPOSE = (1 << 25), + }; + const unsigned retainCount = 1; + + block->flags = BLOCK_HAS_COPY_DISPOSE | BLOCK_NEEDS_FREE | (retainCount << 1); + block->reserved = 0; + block->invoke = [](void *ptr, Args... args) -> R { + return static_cast(ptr)->f(std::forward(args)...); + }; + block->descriptor = &descriptor; + + new (&block->f) F { std::move(function) }; + + BlockPtr blockPtr; + blockPtr.m_block = reinterpret_cast(block); + + return blockPtr; + } + + BlockPtr() + : m_block(nullptr) + { + } + + BlockPtr(BlockType block) + : m_block(Block_copy(block)) + { + } + + BlockPtr(const BlockPtr& other) + : m_block(Block_copy(other.m_block)) + { + } + + BlockPtr(BlockPtr&& other) + : m_block(std::exchange(other.m_block, nullptr)) + { + } + + ~BlockPtr() + { + Block_release(m_block); + } + + BlockPtr& operator=(const BlockPtr& other) + { + if (this != &other) { + Block_release(m_block); + m_block = Block_copy(other.m_block); + } + + return *this; + } + + BlockPtr& operator=(BlockPtr&& other) + { + ASSERT(this != &other); + + Block_release(m_block); + m_block = std::exchange(other.m_block, nullptr); + + return *this; + } + + BlockType get() const { return m_block; } + + explicit operator bool() const { return m_block; } + bool operator!() const { return !m_block; } + + R operator()(Args... arguments) const + { + ASSERT(m_block); + + return m_block(std::forward(arguments)...); + } + +private: + BlockType m_block; +}; + +template +inline BlockPtr makeBlockPtr(R (^block)(Args...)) +{ + return BlockPtr(block); +} + +} + +using WTF::BlockPtr; +using WTF::makeBlockPtr; + -- cgit v1.2.1