Skip to content

Commit a555f1f

Browse files
committed
---
yaml --- r: 347125 b: refs/heads/master c: 1f1fcb6 h: refs/heads/master i: 347123: 6ed5082
1 parent 45248fb commit a555f1f

File tree

19 files changed

+255
-11
lines changed

19 files changed

+255
-11
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
---
2-
refs/heads/master: d23a7ba5271300c2e743e42831c04a91debc3a1c
2+
refs/heads/master: 1f1fcb6ce57708a1f24eb34a5655276ca269eeca
33
refs/heads/master-next: 203b3026584ecad859eb328b2e12490099409cd5
44
refs/tags/osx-passed: b6b74147ef8a386f532cf9357a1bde006e552c54
55
refs/tags/swift-2.2-SNAPSHOT-2015-12-01-a: 6bb18e013c2284f2b45f5f84f2df2887dc0f7dea

trunk/CMakeLists.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -235,8 +235,8 @@ option(SWIFT_RUNTIME_CRASH_REPORTER_CLIENT
235235
FALSE)
236236

237237
option(SWIFT_DARWIN_ENABLE_STABLE_ABI_BIT
238-
"Enable the Swift stable ABI's class marker bit"
239-
FALSE)
238+
"Enable the Swift stable ABI's class marker bit for new deployment targets"
239+
TRUE)
240240

241241
set(SWIFT_DARWIN_XCRUN_TOOLCHAIN "XcodeDefault" CACHE STRING
242242
"The name of the toolchain to pass to 'xcrun'")

trunk/include/swift/ABI/Metadata.h

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1192,6 +1192,31 @@ struct TargetClassMetadata : public TargetAnyClassMetadata<Runtime> {
11921192
return bounds;
11931193
}
11941194

1195+
/// Given a statically-emitted metadata template, this sets the correct
1196+
/// "is Swift" bit for the current runtime. Depending on the deployment
1197+
/// target a binary was compiled for, statically emitted metadata templates
1198+
/// may have a different bit set from the one that this runtime canonically
1199+
/// considers the "is Swift" bit.
1200+
void setAsTypeMetadata() {
1201+
// If the wrong "is Swift" bit is set, set the correct one.
1202+
//
1203+
// Note that the only time we should see the "new" bit set while
1204+
// expecting the "old" one is when running a binary built for a
1205+
// new OS on an old OS, which is not supported, however we do
1206+
// have tests that exercise this scenario.
1207+
auto otherSwiftBit = (3ULL - SWIFT_CLASS_IS_SWIFT_MASK);
1208+
assert(otherSwiftBit == 1ULL || otherSwiftBit == 2ULL);
1209+
1210+
if ((this->Data & 3) == otherSwiftBit) {
1211+
this->Data ^= 3;
1212+
}
1213+
1214+
// Otherwise there should be nothing to do, since only the old "is
1215+
// Swift" bit is used for backward-deployed runtimes.
1216+
1217+
assert(isTypeMetadata());
1218+
}
1219+
11951220
static bool classof(const TargetMetadata<Runtime> *metadata) {
11961221
return metadata->getKind() == MetadataKind::Class;
11971222
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
//===--- BackDeployment.h - Support for running on older OS versions. -----===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2019 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
#ifndef SWIFT_STDLIB_BACKDEPLOYMENT_H
14+
#define SWIFT_STDLIB_BACKDEPLOYMENT_H
15+
16+
#if defined(__APPLE__) && defined(__MACH__)
17+
18+
#include "swift/Runtime/Config.h"
19+
#include "../../../stdlib/public/SwiftShims/Visibility.h"
20+
21+
#ifdef __cplusplus
22+
namespace swift { extern "C" {
23+
#endif
24+
25+
#if SWIFT_CLASS_IS_SWIFT_MASK_GLOBAL_VARIABLE
26+
# ifndef __cplusplus
27+
// This file gets included from some C/ObjC files and
28+
// SWIFT_RUNTIME_STDLIB_SPI doesn't imply extern in C.
29+
extern
30+
# endif
31+
SWIFT_RUNTIME_STDLIB_SPI unsigned long long _swift_classIsSwiftMask;
32+
#endif
33+
34+
/// Returns true if the current OS version, at runtime, is a back-deployment
35+
/// version.
36+
SWIFT_RUNTIME_STDLIB_INTERNAL
37+
int _swift_isBackDeploying();
38+
39+
#ifdef __cplusplus
40+
}} // extern "C", namespace swift
41+
#endif
42+
43+
#endif // defined(__APPLE__) && defined(__MACH__)
44+
45+
#endif // SWIFT_STDLIB_BACKDEPLOYMENT_H

trunk/include/swift/Runtime/CMakeConfig.h.in

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,7 @@
55
#define SWIFT_RUNTIME_CMAKECONFIG_H
66

77
#cmakedefine01 SWIFT_DARWIN_ENABLE_STABLE_ABI_BIT
8+
#cmakedefine01 SWIFT_BNI_OS_BUILD
9+
#cmakedefine01 SWIFT_BNI_XCODE_BUILD
810

911
#endif
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,13 @@
1+
# Detect B&I builds.
2+
set(SWIFT_BNI_OS_BUILD FALSE)
3+
set(SWIFT_BNI_XCODE_BUILD FALSE)
4+
if(DEFINED ENV{RC_XBS})
5+
if(NOT DEFINED ENV{RC_XCODE} OR NOT "$ENV{RC_XCODE}")
6+
set(SWIFT_BNI_OS_BUILD TRUE)
7+
else()
8+
set(SWIFT_BNI_XCODE_BUILD TRUE)
9+
endif()
10+
endif()
11+
112
configure_file(CMakeConfig.h.in ${CMAKE_CURRENT_BINARY_DIR}/CMakeConfig.h
213
ESCAPE_QUOTES @ONLY)

trunk/include/swift/Runtime/Config.h

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -141,10 +141,27 @@
141141
/// Which bits in the class metadata are used to distinguish Swift classes
142142
/// from ObjC classes?
143143
#ifndef SWIFT_CLASS_IS_SWIFT_MASK
144-
# if defined(__APPLE__) && SWIFT_OBJC_INTEROP && SWIFT_DARWIN_ENABLE_STABLE_ABI_BIT
144+
145+
// Non-Apple platforms always use 1.
146+
# if !defined(__APPLE__)
147+
# define SWIFT_CLASS_IS_SWIFT_MASK 1ULL
148+
149+
// Builds for Swift-in-the-OS always use 2.
150+
# elif SWIFT_BNI_OS_BUILD
145151
# define SWIFT_CLASS_IS_SWIFT_MASK 2ULL
146-
# else
152+
153+
// Builds for Xcode always use 1.
154+
# elif SWIFT_BNI_XCODE_BUILD
147155
# define SWIFT_CLASS_IS_SWIFT_MASK 1ULL
156+
157+
// Other builds (such as local builds on developers' computers)
158+
// dynamically choose the bit at runtime based on the current OS
159+
// version.
160+
# else
161+
# define SWIFT_CLASS_IS_SWIFT_MASK _swift_classIsSwiftMask
162+
# define SWIFT_CLASS_IS_SWIFT_MASK_GLOBAL_VARIABLE 1
163+
# include "BackDeployment.h"
164+
148165
# endif
149166
#endif
150167

trunk/include/swift/SwiftRemoteMirror/SwiftRemoteMirror.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@
3737
extern "C" {
3838
#endif
3939

40+
extern unsigned long long swift_reflection_classIsSwiftMask;
41+
4042
/// Get the metadata version supported by the Remote Mirror library.
4143
SWIFT_REMOTE_MIRROR_LINKAGE
4244
uint16_t swift_reflection_getSupportedMetadataVersion(void);

trunk/lib/Frontend/CompilerInvocation.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -429,7 +429,11 @@ static bool ParseLangArgs(LangOptions &Opts, ArgList &Args,
429429
Opts.EnableSILOpaqueValues |= Args.hasArg(OPT_enable_sil_opaque_values);
430430

431431
#if SWIFT_DARWIN_ENABLE_STABLE_ABI_BIT
432-
Opts.UseDarwinPreStableABIBit = false;
432+
Opts.UseDarwinPreStableABIBit =
433+
(Target.isMacOSX() && Target.isMacOSXVersionLT(10, 14, 4)) ||
434+
(Target.isiOS() && Target.isOSVersionLT(12, 2)) ||
435+
(Target.isTvOS() && Target.isOSVersionLT(12, 2)) ||
436+
(Target.isWatchOS() && Target.isOSVersionLT(5, 2));
433437
#else
434438
Opts.UseDarwinPreStableABIBit = true;
435439
#endif

trunk/stdlib/public/SwiftRemoteMirror/SwiftRemoteMirror.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@
1010
//
1111
//===----------------------------------------------------------------------===//
1212

13+
#define SWIFT_CLASS_IS_SWIFT_MASK swift_reflection_classIsSwiftMask
14+
extern "C" unsigned long long swift_reflection_classIsSwiftMask = 2;
15+
1316
#include "swift/Reflection/ReflectionContext.h"
1417
#include "swift/Reflection/TypeLowering.h"
1518
#include "swift/Remote/CMemoryReader.h"
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
//===--- BackDeployment.cpp - Support for running on older OS versions. ---===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2019 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
#include "swift/Runtime/BackDeployment.h"
14+
#include "swift/Runtime/Config.h"
15+
#include "../SwiftShims/FoundationShims.h"
16+
#include <stdlib.h>
17+
18+
#if defined(__APPLE__) && defined(__MACH__)
19+
20+
#if SWIFT_CLASS_IS_SWIFT_MASK_GLOBAL_VARIABLE
21+
static unsigned long long computeIsSwiftMask() {
22+
if (swift::_swift_isBackDeploying())
23+
return 1ULL;
24+
return 2ULL;
25+
}
26+
27+
SWIFT_ALLOWED_RUNTIME_GLOBAL_CTOR_BEGIN
28+
extern "C" unsigned long long
29+
_swift_classIsSwiftMask = computeIsSwiftMask();
30+
SWIFT_ALLOWED_RUNTIME_GLOBAL_CTOR_END
31+
#endif // SWIFT_CLASS_IS_SWIFT_MASK_GLOBAL_VARIABLE
32+
33+
static swift::_SwiftNSOperatingSystemVersion swiftInOSVersion = {
34+
#if __MAC_OS_X_VERSION_MIN_REQUIRED
35+
10, 14, 4
36+
// WatchOS also pretends to be iOS, so check it first.
37+
#elif __WATCH_OS_VERSION_MIN_REQUIRED
38+
5, 2, 0
39+
#elif __IPHONE_OS_VERSION_MIN_REQUIRED || __TV_OS_VERSION_MIN_REQUIRED
40+
12, 2, 0
41+
#else
42+
9999, 0, 0
43+
#endif
44+
};
45+
46+
static bool versionLessThan(swift::_SwiftNSOperatingSystemVersion lhs,
47+
swift::_SwiftNSOperatingSystemVersion rhs) {
48+
if (lhs.majorVersion < rhs.majorVersion) return true;
49+
if (lhs.majorVersion > rhs.majorVersion) return false;
50+
51+
if (lhs.minorVersion < rhs.minorVersion) return true;
52+
if (lhs.minorVersion > rhs.minorVersion) return false;
53+
54+
if (lhs.patchVersion < rhs.patchVersion) return true;
55+
56+
return false;
57+
}
58+
59+
SWIFT_RUNTIME_STDLIB_INTERNAL
60+
int _swift_isBackDeploying() {
61+
auto version = swift::_swift_stdlib_operatingSystemVersion();
62+
return versionLessThan(version, swiftInOSVersion);
63+
}
64+
#endif

trunk/stdlib/public/runtime/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ set(swift_runtime_objc_sources
3131
set(swift_runtime_sources
3232
AnyHashableSupport.cpp
3333
Array.cpp
34+
BackDeployment.cpp
3435
Casting.cpp
3536
CompatibilityOverride.cpp
3637
CygwinPort.cpp

trunk/stdlib/public/runtime/Metadata.cpp

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,15 @@ Metadata *TargetSingletonMetadataInitialization<InProcess>::allocate(
9696
// If this is a class, we have to initialize the value witness table early
9797
// so that two-phase initialization can proceed as if this metadata is
9898
// complete for layout purposes when it appears as part of an aggregate type.
99-
if (auto *classMetadata = dyn_cast<ClassMetadata>(metadata)) {
99+
//
100+
// Note that we can't use (dyn_)cast<ClassMetadata> here because the static
101+
// template may have the "wrong" isSwift bit set in its Data pointer, if the
102+
// binary was built to deploy back to pre-stable-Swift Objective-C runtimes.
103+
// Such a template will fail the `isTypeMetadata` test and we'll think that it
104+
// isn't Swift metadata but a plain old ObjC class instead.
105+
if (metadata->getKind() == MetadataKind::Class) {
106+
auto *classMetadata = static_cast<ClassMetadata*>(metadata);
107+
classMetadata->setAsTypeMetadata();
100108
auto *fullMetadata = asFullMetadata(metadata);
101109

102110
// Begin by initializing the value witness table; everything else is

trunk/stdlib/tools/swift-reflection-test/swift-reflection-test.c

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -551,6 +551,20 @@ int doDumpHeapInstance(const char *BinaryFilename) {
551551
return EXIT_SUCCESS;
552552
}
553553

554+
#if defined(__APPLE__) && defined(__MACH__)
555+
#include <dlfcn.h>
556+
static unsigned long long computeClassIsSwiftMask(void) {
557+
uintptr_t *objc_debug_swift_stable_abi_bit_ptr =
558+
(uintptr_t *)dlsym(RTLD_DEFAULT, "objc_debug_swift_stable_abi_bit");
559+
return objc_debug_swift_stable_abi_bit_ptr ?
560+
*objc_debug_swift_stable_abi_bit_ptr : 1;
561+
}
562+
#else
563+
static unsigned long long computeClassIsSwiftMask(void) {
564+
return 1;
565+
}
566+
#endif
567+
554568
void printUsageAndExit() {
555569
fprintf(stderr, "swift-reflection-test <binary filename>\n");
556570
exit(EXIT_FAILURE);
@@ -561,6 +575,8 @@ int main(int argc, char *argv[]) {
561575
printUsageAndExit();
562576

563577
const char *BinaryFilename = argv[1];
578+
579+
swift_reflection_classIsSwiftMask = computeClassIsSwiftMask();
564580

565581
uint16_t Version = swift_reflection_getSupportedMetadataVersion();
566582
printf("Metadata version: %u\n", Version);

trunk/test/IRGen/class.sil

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ sil_vtable C {}
4141
// CHECK-INDIRECT-SAME: %swift.type* null,
4242
// CHECK-SAME: [[OPAQUE]]* @_objc_empty_cache,
4343
// CHECK-SAME: [[OPAQUE]]* null,
44-
// CHECK-SAME: i64 add (i64 ptrtoint ({{.*}}* @_DATA__TtC5class1C to i64), i64 1)
44+
// CHECK-SAME: i64 add (i64 ptrtoint ({{.*}}* @_DATA__TtC5class1C to i64), i64 [[IS_SWIFT_BIT:1|2]])
4545
// CHECK-SAME: }>
4646

4747
// Destroying destructor

trunk/test/IRGen/class_resilience.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@
9292
// -- ivar destroyer:
9393
// CHECK-SAME: i32 0,
9494
// -- flags:
95-
// CHECK-SAME: i32 3,
95+
// CHECK-SAME: i32 2,
9696
// -- RO data:
9797
// CHECK-objc-SAME: @_DATA__TtC16class_resilience14ResilientChild
9898
// CHECK-native-SAME: i32 0,

trunk/test/IRGen/subclass.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
// CHECK-INDIRECT-SAME: [[TYPE]]* null,
2121
// CHECK-SAME: [[OPAQUE]]* @_objc_empty_cache,
2222
// CHECK-SAME: [[OPAQUE]]* null,
23-
// CHECK-SAME: i64 add (i64 ptrtoint ({ {{.*}} }* @_DATA__TtC8subclass1A to i64), i64 1),
23+
// CHECK-SAME: i64 add (i64 ptrtoint ({ {{.*}} }* @_DATA__TtC8subclass1A to i64), i64 [[IS_SWIFT_BIT:1|2]]),
2424
// CHECK-SAME: i64 ([[A]]*)* @"$s8subclass1AC1fSiyF",
2525
// CHECK-SAME: [[A]]* ([[TYPE]]*)* @"$s8subclass1AC1gACyFZ"
2626
// CHECK-SAME: }>
@@ -34,7 +34,7 @@
3434
// CHECK-INDIRECT-SAME: [[TYPE]]* null,
3535
// CHECK-SAME: [[OPAQUE]]* @_objc_empty_cache,
3636
// CHECK-SAME: [[OPAQUE]]* null,
37-
// CHECK-SAME: i64 add (i64 ptrtoint ({ {{.*}} }* @_DATA__TtC8subclass1B to i64), i64 1),
37+
// CHECK-SAME: i64 add (i64 ptrtoint ({ {{.*}} }* @_DATA__TtC8subclass1B to i64), i64 [[IS_SWIFT_BIT]]),
3838
// CHECK-SAME: i64 ([[B]]*)* @"$s8subclass1BC1fSiyF",
3939
// CHECK-SAME: [[A]]* ([[TYPE]]*)* @"$s8subclass1AC1gACyFZ"
4040
// CHECK-SAME: }>
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// RUN: %empty-directory(%t)
2+
// -- Deployment target is set to pre-10.14.4 so that we use the "old"
3+
// Swift runtime bit in compiler-emitted classes
4+
// RUN: %target-build-swift -target x86_64-apple-macosx10.9 %s -module-name main -o %t/a.out
5+
// RUN: %target-run %t/a.out | %FileCheck %s
6+
7+
// REQUIRES: executable_test
8+
// REQUIRES: OS=macosx
9+
10+
import Foundation
11+
12+
// A fixed-layout class should be considered Swift metadata by the OS runtime.
13+
class FixedLayout { }
14+
15+
debugPrint(FixedLayout.self) // CHECK: main.FixedLayout
16+
17+
// A generic class
18+
class GenericBase<T> { }
19+
debugPrint(GenericBase<Int>.self) // CHECK-NEXT: main.GenericBase<Swift.Int>
20+
21+
// A singleton-initialized class
22+
class SingletonInit: GenericBase<Int> { }
23+
debugPrint(SingletonInit.self) // CHECK-NEXT: main.SingletonInit
24+
25+
// A resilient-heritage class
26+
class ResilientSubInit: JSONEncoder {}
27+
debugPrint(ResilientSubInit.self) // CHECK-NEXT: main.ResilientSubInit
28+
29+
print("nailed it") // CHECK-NEXT: nailed it

trunk/tools/swift-remoteast-test/swift-remoteast-test.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,23 @@ using namespace swift;
3838
using namespace swift::remote;
3939
using namespace swift::remoteAST;
4040

41+
#if defined(__APPLE__) && defined(__MACH__)
42+
#include <dlfcn.h>
43+
static unsigned long long computeClassIsSwiftMask(void) {
44+
uintptr_t *objc_debug_swift_stable_abi_bit_ptr =
45+
(uintptr_t *)dlsym(RTLD_DEFAULT, "objc_debug_swift_stable_abi_bit");
46+
return objc_debug_swift_stable_abi_bit_ptr ?
47+
*objc_debug_swift_stable_abi_bit_ptr : 1;
48+
}
49+
#else
50+
static unsigned long long computeClassIsSwiftMask(void) {
51+
return 1;
52+
}
53+
#endif
54+
55+
extern "C" unsigned long long _swift_classIsSwiftMask =
56+
computeClassIsSwiftMask();
57+
4158
/// The context for the code we're running. Set by the observer.
4259
static ASTContext *context = nullptr;
4360

0 commit comments

Comments
 (0)