diff options
author | mark@chromium.org <mark@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-08-16 18:15:52 +0000 |
---|---|---|
committer | mark@chromium.org <mark@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-08-16 18:15:52 +0000 |
commit | 3b1eb087df251521c8d96c64aa84613c18cc114c (patch) | |
tree | b81c80ab0144a49ba609c7d25d2897fb05c5bf66 | |
parent | bd5ac7c4d26c4ffe645abf491780bbfa71a541d2 (diff) | |
download | chromium_src-3b1eb087df251521c8d96c64aa84613c18cc114c.zip chromium_src-3b1eb087df251521c8d96c64aa84613c18cc114c.tar.gz chromium_src-3b1eb087df251521c8d96c64aa84613c18cc114c.tar.bz2 |
Weak-import more symbols in closure_blocks_leopard_compat:
__Block_copy, __Block_release, __Block_object_assign, and __Block_object_dispose
BUG=91978
TEST=Included
Review URL: http://codereview.chromium.org/7657014
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@96979 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | chrome/browser/mac/closure_blocks_leopard_compat.S | 20 | ||||
-rw-r--r-- | chrome/browser/mac/closure_blocks_leopard_compat.h | 25 | ||||
-rw-r--r-- | chrome/browser/mac/closure_blocks_leopard_compat_unittest.cc | 71 |
3 files changed, 110 insertions, 6 deletions
diff --git a/chrome/browser/mac/closure_blocks_leopard_compat.S b/chrome/browser/mac/closure_blocks_leopard_compat.S index cca9e83..88a63da 100644 --- a/chrome/browser/mac/closure_blocks_leopard_compat.S +++ b/chrome/browser/mac/closure_blocks_leopard_compat.S @@ -7,10 +7,11 @@ # # This file provides symbols for _NSConcreteGlobalBlock and # _NSConcreteStackBlock, normally present in libSystem.dylib and provided by -# by libclosure-38/data.c in Mac OS X 10.6 and later. When using the 10.5 SDK, -# the symbols are not present. This file's definition can be used with extreme -# care in an application that needs to use the 10.5 SDK in conjunction with -# blocks. +# by libclosure-38/data.c in Mac OS X 10.6 and later. It also provides symbols +# for various block runtime functions provided by libclosure-38/runtime.c. +# When using the 10.5 SDK, the symbols are not present. This file's definition +# can be used with extreme care in an application that needs to use the 10.5 +# SDK in conjunction with blocks. # # This file cooperates with the build system to produce a dynamic library # that, when linked against, causes dependents to look in libSystem for the @@ -36,8 +37,19 @@ .globl name ## ;\ name ## : +.text + +# Mac OS X 10.6.8 libclosure-38/runtime.c + +DEFINE_GLOBAL_SYMBOL(__Block_copy) +DEFINE_GLOBAL_SYMBOL(__Block_release) +DEFINE_GLOBAL_SYMBOL(__Block_object_assign) +DEFINE_GLOBAL_SYMBOL(__Block_object_dispose) + .section __DATA,__data +# Mac OS X 10.6.8 libclosure-38/data.c + DEFINE_GLOBAL_SYMBOL(__NSConcreteGlobalBlock) DEFINE_GLOBAL_SYMBOL(__NSConcreteStackBlock) diff --git a/chrome/browser/mac/closure_blocks_leopard_compat.h b/chrome/browser/mac/closure_blocks_leopard_compat.h index 9b6bf1a..516a18f 100644 --- a/chrome/browser/mac/closure_blocks_leopard_compat.h +++ b/chrome/browser/mac/closure_blocks_leopard_compat.h @@ -61,6 +61,13 @@ #include <AvailabilityMacros.h> +#if defined(MAC_OS_X_VERSION_10_6) && \ + MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6 // SDK >= 10.6 +// Get the system's own declarations of these things if using an SDK where +// they are present. +#include <Block.h> +#endif // SDK >= 10.6 + extern "C" { #if MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_5 // DT <= 10.5 @@ -69,6 +76,13 @@ extern "C" { #define MAYBE_WEAK_IMPORT #endif // DT <= 10.5 +MAYBE_WEAK_IMPORT extern void* _Block_copy(const void*); +MAYBE_WEAK_IMPORT extern void _Block_release(const void*); +MAYBE_WEAK_IMPORT extern void _Block_object_assign(void*, + const void*, + const int); +MAYBE_WEAK_IMPORT extern void _Block_object_dispose(const void*, const int); + MAYBE_WEAK_IMPORT extern void* _NSConcreteGlobalBlock[32]; MAYBE_WEAK_IMPORT extern void* _NSConcreteStackBlock[32]; @@ -76,4 +90,15 @@ MAYBE_WEAK_IMPORT extern void* _NSConcreteStackBlock[32]; } // extern "C" +// Macros from <Block.h>, in case <Block.h> is not present. + +#ifndef Block_copy +#define Block_copy(...) \ + ((__typeof(__VA_ARGS__))_Block_copy((const void *)(__VA_ARGS__))) +#endif + +#ifndef Block_release +#define Block_release(...) _Block_release((const void *)(__VA_ARGS__)) +#endif + #endif // CHROME_BROWSER_MAC_CLOSURE_BLOCKS_LEOPARD_COMPAT_H_ diff --git a/chrome/browser/mac/closure_blocks_leopard_compat_unittest.cc b/chrome/browser/mac/closure_blocks_leopard_compat_unittest.cc index 3e660f1..fa1717d 100644 --- a/chrome/browser/mac/closure_blocks_leopard_compat_unittest.cc +++ b/chrome/browser/mac/closure_blocks_leopard_compat_unittest.cc @@ -7,6 +7,14 @@ #include "base/mac/mac_util.h" #include "chrome/browser/mac/closure_blocks_leopard_compat.h" +// Used in ClosureBlocksLeopardCompatTest.Global. Putting a block at global +// scope results in a block structure whose isa field is set to +// NSConcreteGlobalBlock, ensuring that symbol is referenced. This test needs +// to be able to load on 10.5 where that symbol is not present at runtime, so +// the real test here is that the symbol is weakly imported. If not, the +// executable will fail to load. +void (^global_block)(bool*) = ^(bool* ran_pointer) { *ran_pointer = true; }; + namespace { // It should be possible to declare a block on OSes as early as Leopard @@ -14,9 +22,16 @@ namespace { // target, and runnable on 10.5. However, the block itself is not expected to // be runnable on 10.5. This test verfies that blocks are buildable on 10.5 // and runnable on Snow Leopard (10.6) and later. -TEST(ClosureBlocksLeopardCompatTest, Basic) { + +TEST(ClosureBlocksLeopardCompatTest, Stack) { bool ran = false; + // This should result in a block structure whose isa field is set to + // NSConcreteStackBlock, ensuring that symbol is referenced. This test + // needs to be able to load on 10.5 where that symbol is not present at + // runtime, so the real test here checks that the symbol is weakly imported. + // If not, the executable will fail to load. + void (^test_block)(bool*) = ^(bool* ran_pointer) { *ran_pointer = true; }; ASSERT_FALSE(ran); @@ -24,7 +39,59 @@ TEST(ClosureBlocksLeopardCompatTest, Basic) { if (base::mac::IsOSSnowLeopardOrLater()) { test_block(&ran); - ASSERT_TRUE(ran); + EXPECT_TRUE(ran); + } +} + +TEST(ClosureBlocksLeopardCompatTest, Global) { + bool ran = false; + + ASSERT_FALSE(ran); + + if (base::mac::IsOSSnowLeopardOrLater()) { + global_block(&ran); + + EXPECT_TRUE(ran); + } +} + +TEST(ClosureBlocksLeopardCompatTest, CopyRelease) { + if (base::mac::IsOSSnowLeopardOrLater()) { + // Protect the entire test in this conditional, because __block won't run + // on 10.5. + __block int value = 0; + + typedef int (^TestBlockType)(); + TestBlockType local_block = ^(void) { return ++value; }; + + ASSERT_EQ(0, value); + + int rv = local_block(); + EXPECT_EQ(1, rv); + EXPECT_EQ(rv, value); + + // Using Block_copy, Block_release, and these other operations ensures + // that _Block_copy, _Block_release, _Block_object_assign, and + // _Block_object_dispose are referenced. This test needs to be able to + // load on 10.5 where these symbols are not present at runtime, so the + // real test here is that the symbol is weakly imported. If not, the + // executable will fail to load. + + TestBlockType copied_block = Block_copy(local_block); + + rv = copied_block(); + EXPECT_EQ(2, rv); + EXPECT_EQ(rv, value); + + rv = copied_block(); + EXPECT_EQ(3, rv); + EXPECT_EQ(rv, value); + + Block_release(copied_block); + + rv = local_block(); + EXPECT_EQ(4, rv); + EXPECT_EQ(rv, value); } } |