Title: [205313] trunk
Revision
205313
Author
[email protected]
Date
2016-09-01 13:40:23 -0700 (Thu, 01 Sep 2016)

Log Message

add BlockPtr::fromCallable
https://bugs.webkit.org/show_bug.cgi?id=161504

Reviewed by Tim Horton.

Source/WTF:

BlockPtr::fromCallable lets you create an Objective-C block from any callable object - including lambdas that contain move-only types.
The block will be allocated on the heap so it doesn't ever need to be copied (which is how it can work with move-only types).

* wtf/BlockPtr.h:

Tools:

Add a test.

* TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
* TestWebKitAPI/Tests/WTF/BlockPtr.mm: Added.
(TestWebKitAPI::TEST):

Modified Paths

Added Paths

Diff

Modified: trunk/Source/WTF/ChangeLog (205312 => 205313)


--- trunk/Source/WTF/ChangeLog	2016-09-01 20:33:31 UTC (rev 205312)
+++ trunk/Source/WTF/ChangeLog	2016-09-01 20:40:23 UTC (rev 205313)
@@ -1,3 +1,15 @@
+2016-09-01  Anders Carlsson  <[email protected]>
+
+        add BlockPtr::fromCallable
+        https://bugs.webkit.org/show_bug.cgi?id=161504
+
+        Reviewed by Tim Horton.
+
+        BlockPtr::fromCallable lets you create an Objective-C block from any callable object - including lambdas that contain move-only types.
+        The block will be allocated on the heap so it doesn't ever need to be copied (which is how it can work with move-only types).
+
+        * wtf/BlockPtr.h:
+
 2016-08-31  Keith Rollin  <[email protected]>
 
         WebKit should set a subsystem for os_log so it's easier to filter for WebKit log messages

Modified: trunk/Source/WTF/wtf/BlockPtr.h (205312 => 205313)


--- trunk/Source/WTF/wtf/BlockPtr.h	2016-09-01 20:33:31 UTC (rev 205312)
+++ trunk/Source/WTF/wtf/BlockPtr.h	2016-09-01 20:40:23 UTC (rev 205313)
@@ -23,8 +23,7 @@
  * THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-#ifndef BlockPtr_h
-#define BlockPtr_h
+#pragma once
 
 #include <Block.h>
 #include <wtf/Assertions.h>
@@ -31,17 +30,77 @@
 
 namespace WTF {
 
+extern "C" void* _NSConcreteMallocBlock[32];
+
 template<typename> class BlockPtr;
 
 template<typename R, typename... Args>
 class BlockPtr<R (Args...)> {
 public:
+    using BlockType = R (^)(Args...);
+
+    template<typename F>
+    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<Block*>(const_cast<void*>(ptr))->f.~F();
+            }
+        };
+
+        Block* block = static_cast<Block*>(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<Block*>(ptr)->f(std::forward<Args>(args)...);
+        };
+        block->descriptor = &descriptor;
+
+        new (&block->f) F { std::move(function) };
+
+        BlockPtr blockPtr;
+        blockPtr.m_block = static_cast<BlockType>(block);
+
+        return blockPtr;
+    }
+
     BlockPtr()
         : m_block(nullptr)
     {
     }
 
-    BlockPtr(R (^block)(Args...))
+    BlockPtr(BlockType block)
         : m_block(Block_copy(block))
     {
     }
@@ -81,6 +140,8 @@
         return *this;
     }
 
+    BlockType get() const { return m_block; }
+
     explicit operator bool() const { return m_block; }
     bool operator!() const { return !m_block; }
 
@@ -90,9 +151,9 @@
         
         return m_block(std::forward<Args>(arguments)...);
     }
-    
+
 private:
-    R (^m_block)(Args...);
+    BlockType m_block;
 };
 
 template<typename R, typename... Args>
@@ -106,4 +167,3 @@
 using WTF::BlockPtr;
 using WTF::makeBlockPtr;
 
-#endif // BlockPtr_h

Modified: trunk/Tools/ChangeLog (205312 => 205313)


--- trunk/Tools/ChangeLog	2016-09-01 20:33:31 UTC (rev 205312)
+++ trunk/Tools/ChangeLog	2016-09-01 20:40:23 UTC (rev 205313)
@@ -1,3 +1,16 @@
+2016-09-01  Anders Carlsson  <[email protected]>
+
+        add BlockPtr::fromCallable
+        https://bugs.webkit.org/show_bug.cgi?id=161504
+
+        Reviewed by Tim Horton.
+
+        Add a test.
+
+        * TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
+        * TestWebKitAPI/Tests/WTF/BlockPtr.mm: Added.
+        (TestWebKitAPI::TEST):
+
 2016-09-01  Alex Christensen  <[email protected]>
 
         URLParser should handle . and .. in URL paths

Modified: trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj (205312 => 205313)


--- trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj	2016-09-01 20:33:31 UTC (rev 205312)
+++ trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj	2016-09-01 20:40:23 UTC (rev 205313)
@@ -33,6 +33,7 @@
 		1A63479F183D72A4005B1707 /* all-content-in-one-iframe.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 93D3D19B17B1A7B000C7C415 /* all-content-in-one-iframe.html */; };
 		1A7E8B3618120B2F00AEB74A /* FragmentNavigation.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 1A7E8B351812093600AEB74A /* FragmentNavigation.html */; };
 		1A9E52C913E65EF4006917F5 /* 18-characters.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = C045F9461385C2F800C0F3CD /* 18-characters.html */; };
+		1ADAD1501D77A9F600212586 /* BlockPtr.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1ADAD14E1D77A9F600212586 /* BlockPtr.mm */; };
 		1ADBEFE3130C6AA100D61D19 /* simple-accelerated-compositing.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 1ADBEFBC130C6A0100D61D19 /* simple-accelerated-compositing.html */; };
 		1AEDE22613E5E7E700E62FE8 /* InjectedBundleControllerMac.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1AEDE22413E5E7A000E62FE8 /* InjectedBundleControllerMac.mm */; };
 		1AF7B21F1D6CD14D008C126C /* EnumTraits.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1AF7B21D1D6CD12E008C126C /* EnumTraits.cpp */; };
@@ -676,6 +677,7 @@
 		1A9FB6CC1CA34BE500966124 /* EarlyKVOCrash.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = EarlyKVOCrash.mm; sourceTree = "<group>"; };
 		1AAD19F51C7CE20300831E47 /* Coding.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = Coding.mm; sourceTree = "<group>"; };
 		1ABC3DED1899BE6D004F0626 /* Navigation.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = Navigation.mm; sourceTree = "<group>"; };
+		1ADAD14E1D77A9F600212586 /* BlockPtr.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = BlockPtr.mm; sourceTree = "<group>"; };
 		1ADBEFAD130C689C00D61D19 /* ForceRepaint.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ForceRepaint.cpp; sourceTree = "<group>"; };
 		1ADBEFBC130C6A0100D61D19 /* simple-accelerated-compositing.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "simple-accelerated-compositing.html"; sourceTree = "<group>"; };
 		1AE72F47173EB214006362F0 /* TerminateTwice.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TerminateTwice.cpp; sourceTree = "<group>"; };
@@ -1451,6 +1453,7 @@
 		BC029B1A1486B23800817DA9 /* ns */ = {
 			isa = PBXGroup;
 			children = (
+				1ADAD14E1D77A9F600212586 /* BlockPtr.mm */,
 				BC029B1B1486B25900817DA9 /* RetainPtr.mm */,
 			);
 			name = ns;
@@ -2122,6 +2125,7 @@
 				7C83DED21D0A590C00FEBCF3 /* HashMap.cpp in Sources */,
 				7C83DED41D0A590C00FEBCF3 /* HashSet.cpp in Sources */,
 				7C83DEE01D0A590C00FEBCF3 /* IntegerToStringConversion.cpp in Sources */,
+				1ADAD1501D77A9F600212586 /* BlockPtr.mm in Sources */,
 				7C83DEE81D0A590C00FEBCF3 /* ListHashSet.cpp in Sources */,
 				7C83DF1D1D0A590C00FEBCF3 /* Lock.cpp in Sources */,
 				7C83DEED1D0A590C00FEBCF3 /* MathExtras.cpp in Sources */,

Added: trunk/Tools/TestWebKitAPI/Tests/WTF/BlockPtr.mm (0 => 205313)


--- trunk/Tools/TestWebKitAPI/Tests/WTF/BlockPtr.mm	                        (rev 0)
+++ trunk/Tools/TestWebKitAPI/Tests/WTF/BlockPtr.mm	2016-09-01 20:40:23 UTC (rev 205313)
@@ -0,0 +1,52 @@
+/*
+ * 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.
+ */
+
+#import "config.h"
+
+#import "MoveOnly.h"
+#import <wtf/BlockPtr.h>
+
+namespace TestWebKitAPI {
+
+TEST(BlockPtr, FromBlock)
+{
+    BlockPtr<unsigned ()> block { ^{
+        return 10u;
+    } };
+
+    EXPECT_EQ(10u, block());
+}
+
+TEST(BlockPtr, FromLambda)
+{
+    MoveOnly moveOnly { 10 };
+    auto block = BlockPtr<unsigned ()>::fromCallable([moveOnly = WTFMove(moveOnly)] {
+        return moveOnly.value();
+    });
+
+    EXPECT_EQ(10u, block());
+}
+
+}
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to