summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormark@chromium.org <mark@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-08-16 18:15:52 +0000
committermark@chromium.org <mark@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-08-16 18:15:52 +0000
commit3b1eb087df251521c8d96c64aa84613c18cc114c (patch)
treeb81c80ab0144a49ba609c7d25d2897fb05c5bf66
parentbd5ac7c4d26c4ffe645abf491780bbfa71a541d2 (diff)
downloadchromium_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.S20
-rw-r--r--chrome/browser/mac/closure_blocks_leopard_compat.h25
-rw-r--r--chrome/browser/mac/closure_blocks_leopard_compat_unittest.cc71
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);
}
}