Skip to content

Commit ef08833

Browse files
authored
gh-131999: Add support for tvOS, visionOS and watchOS. (#159944)
Add support for tvOS, visionOS and watchOS. This is mostly configuration updates and testbed projects to support deploying to the new platforms. Also includes a mimalloc change to support arm64_32 that has been contributed upstream.
1 parent 6854e79 commit ef08833

124 files changed

Lines changed: 3798 additions & 204 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎.gitignore‎

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -72,16 +72,19 @@ Lib/test/data/*
7272
/_bootstrap_python
7373
/Makefile
7474
/Makefile.pre
75-
/iOSTestbed.*
76-
Apple/iOS/Frameworks/
77-
Apple/iOS/Resources/Info.plist
78-
Apple/testbed/build
75+
/AppleTestbed.*
76+
Platforms/Apple/iOS/Frameworks/*
77+
Platforms/Apple/iOS/Resources/Info.plist
7978
Platforms/Apple/testbed/Python*.xcframework/*/bin
8079
Platforms/Apple/testbed/Python*.xcframework/*/include
8180
Platforms/Apple/testbed/Python*.xcframework/*/lib
8281
Platforms/Apple/testbed/Python*.xcframework/*/Python*.framework
83-
Apple/testbed/*Testbed.xcodeproj/project.xcworkspace
84-
Apple/testbed/*Testbed.xcodeproj/xcuserdata
82+
Platforms/Apple/tvOS/Frameworks/*
83+
Platforms/Apple/tvOS/Resources/Info.plist
84+
Platforms/Apple/visionOS/Frameworks/*
85+
Platforms/Apple/visionOS/Resources/Info.plist
86+
Platforms/Apple/watchOS/Frameworks/*
87+
Platforms/Apple/watchOS/Resources/Info.plist
8588
Mac/Makefile
8689
Mac/PythonLauncher/Info.plist
8790
Mac/PythonLauncher/Makefile

‎Include/cpython/object.h‎

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -469,8 +469,12 @@ _Py_ThreadId(void)
469469
#elif defined(__arm__) && __ARM_ARCH >= 7
470470
__asm__ ("mrc p15, 0, %0, c13, c0, 3\nbic %0, %0, #3" : "=r" (tid));
471471
#elif defined(__aarch64__) && defined(__APPLE__)
472-
__asm__ ("mrs %0, tpidrro_el0" : "=r" (tid));
473-
#elif defined(__aarch64__)
472+
// Use a 64-bit temporary: on arm64_32 (ILP32), uintptr_t is 32 bits
473+
// but system registers are 64 bits.
474+
uint64_t tp;
475+
__asm__ ("mrs %0, tpidrro_el0" : "=r" (tp));
476+
tid = (uintptr_t)tp;
477+
#elif defined (__aarch64__)
474478
__asm__ ("mrs %0, tpidr_el0" : "=r" (tid));
475479
#elif defined(__powerpc64__)
476480
#if defined(__clang__) && _Py__has_builtin(__builtin_thread_pointer)

‎Include/internal/mimalloc/mimalloc/prim.h‎

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -166,12 +166,17 @@ static inline void* mi_prim_tls_slot(size_t slot) mi_attr_noexcept {
166166
__asm__ volatile ("mrc p15, 0, %0, c13, c0, 3\nbic %0, %0, #3" : "=r" (tcb));
167167
res = tcb[slot];
168168
#elif defined(__aarch64__)
169-
void** tcb; MI_UNUSED(ofs);
169+
// CPython: patched for watchOS support.
170+
// Submitted upstream as microsoft/mimalloc#1444
171+
// Use a 64-bit temporary: on arm64_32 (ILP32), pointers are 32 bits
172+
// but system registers are 64 bits.
173+
uint64_t tp; MI_UNUSED(ofs);
170174
#if defined(__APPLE__) // M1, issue #343
171-
__asm__ volatile ("mrs %0, tpidrro_el0\nbic %0, %0, #7" : "=r" (tcb));
175+
__asm__ volatile ("mrs %0, tpidrro_el0\nbic %0, %0, #7" : "=r" (tp));
172176
#else
173-
__asm__ volatile ("mrs %0, tpidr_el0" : "=r" (tcb));
177+
__asm__ volatile ("mrs %0, tpidr_el0" : "=r" (tp));
174178
#endif
179+
void** tcb = (void**)(uintptr_t)tp;
175180
res = tcb[slot];
176181
#elif defined(__riscv)
177182
void** tcb; MI_UNUSED(ofs);
@@ -200,12 +205,15 @@ static inline void mi_prim_tls_slot_set(size_t slot, void* value) mi_attr_noexce
200205
__asm__ volatile ("mrc p15, 0, %0, c13, c0, 3\nbic %0, %0, #3" : "=r" (tcb));
201206
tcb[slot] = value;
202207
#elif defined(__aarch64__)
203-
void** tcb; MI_UNUSED(ofs);
208+
// Use a 64-bit temporary: on arm64_32 (ILP32), pointers are 32 bits
209+
// but system registers are 64 bits.
210+
uint64_t tp; MI_UNUSED(ofs);
204211
#if defined(__APPLE__) // M1, issue #343
205-
__asm__ volatile ("mrs %0, tpidrro_el0\nbic %0, %0, #7" : "=r" (tcb));
212+
__asm__ volatile ("mrs %0, tpidrro_el0\nbic %0, %0, #7" : "=r" (tp));
206213
#else
207-
__asm__ volatile ("mrs %0, tpidr_el0" : "=r" (tcb));
214+
__asm__ volatile ("mrs %0, tpidr_el0" : "=r" (tp));
208215
#endif
216+
void** tcb = (void**)(uintptr_t)tp;
209217
tcb[slot] = value;
210218
#elif defined(__riscv)
211219
void** tcb; MI_UNUSED(ofs);

‎Include/internal/pycore_pystate.h‎

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -342,7 +342,11 @@ _Py_get_machine_stack_pointer(void) {
342342
#elif defined(_MSC_VER) && (defined(_M_X64) || defined(_M_IX86))
343343
result = (uintptr_t)_AddressOfReturnAddress();
344344
#elif defined(__aarch64__)
345-
__asm__ ("mov %0, sp" : "=r" (result));
345+
// Use a 64-bit temporary: on arm64_32 (ILP32), uintptr_t is 32 bits
346+
// but sp is a 64-bit register.
347+
uint64_t sp;
348+
__asm__ ("mov %0, sp" : "=r" (sp));
349+
result = (uintptr_t)sp;
346350
#elif defined(__x86_64__)
347351
__asm__ ("{movq %%rsp, %0|mov %0, rsp}" : "=r" (result));
348352
#else

‎Lib/asyncio/unix_events.py‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -681,10 +681,10 @@ def __init__(self, loop, pipe, protocol, waiter=None, extra=None):
681681
# end polls as readable whenever unread data sits in the FIFO, and no
682682
# event is delivered when the read end is closed, so it can only
683683
# ever report a false disconnection (gh-145030). The same XNU
684-
# behaviour applies on iOS/tvOS/watchOS (sys.platform is not
684+
# behaviour applies on iOS/tvOS/visionOS/watchOS (sys.platform is not
685685
# "darwin" there).
686686
is_named_fifo_without_close_event = (
687-
sys.platform in {"darwin", "ios", "tvos", "watchos", "sunos5"}
687+
sys.platform in {"darwin", "ios", "tvos", "visionos", "watchos", "sunos5"}
688688
and is_fifo and pipe_stat.st_nlink > 0)
689689
if is_socket or (is_fifo
690690
and not sys.platform.startswith("aix")

‎Lib/ctypes/__init__.py‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -447,9 +447,9 @@ def _load_library(self, name, mode, handle, winmode):
447447

448448
else:
449449
def _load_library(self, name, mode, handle, winmode):
450-
# If the filename that has been provided is an iOS/tvOS/watchOS
451-
# .fwork file, dereference the location to the true origin of the
452-
# binary.
450+
# If the filename that has been provided is an iOS, tvOS, visionOS
451+
# or watchOS .fwork file, dereference the location to the true
452+
# origin of the binary.
453453
if name and name.endswith(".fwork"):
454454
with open(name) as f:
455455
name = _os.path.join(

‎Lib/ctypes/util.py‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ def dllist():
104104
if (name := _get_module_filename(h)) is not None]
105105
return libraries
106106

107-
elif os.name == "posix" and sys.platform in {"darwin", "ios", "tvos", "watchos"}:
107+
elif os.name == "posix" and sys.platform in {"darwin", "ios", "tvos", "visionos", "watchos"}:
108108
from ctypes.macholib.dyld import dyld_find as _dyld_find
109109
def find_library(name):
110110
possible = ['lib%s.dylib' % name,

‎Lib/importlib/_bootstrap_external.py‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@
5555

5656
# Bootstrap-related code ######################################################
5757
_CASE_INSENSITIVE_PLATFORMS_STR_KEY = 'win',
58-
_CASE_INSENSITIVE_PLATFORMS_BYTES_KEY = 'cygwin', 'darwin', 'ios', 'tvos', 'watchos'
58+
_CASE_INSENSITIVE_PLATFORMS_BYTES_KEY = 'cygwin', 'darwin', 'ios', 'tvos', 'visionos', 'watchos'
5959
_CASE_INSENSITIVE_PLATFORMS = (_CASE_INSENSITIVE_PLATFORMS_BYTES_KEY
6060
+ _CASE_INSENSITIVE_PLATFORMS_STR_KEY)
6161

@@ -1570,7 +1570,7 @@ def _get_supported_file_loaders():
15701570
"""
15711571
extension_loaders = []
15721572
if hasattr(_imp, 'create_dynamic'):
1573-
if sys.platform in {"ios", "tvos", "watchos"}:
1573+
if sys.platform in {"ios", "tvos", "visionos", "watchos"}:
15741574
extension_loaders = [(AppleFrameworkLoader, [
15751575
suffix.replace(".so", ".fwork")
15761576
for suffix in _imp.extension_suffixes()

‎Lib/platform.py‎

Lines changed: 26 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -526,13 +526,13 @@ def mac_ver(release='', versioninfo=('', '', ''), machine=''):
526526

527527

528528
def ios_ver(system="", release="", model="", is_simulator=False):
529-
"""Get iOS version information, and return it as a namedtuple:
530-
(system, release, model, is_simulator).
529+
"""Get iOS/tvOS/watchOS/visionOS version information, and return it as a
530+
namedtuple: (system, release, model, is_simulator).
531531
532532
If values can't be determined, they are set to values provided as
533533
parameters.
534534
"""
535-
if sys.platform == "ios":
535+
if sys.platform in {"ios", "tvos", "visionos", "watchos"}:
536536
import _ios_support
537537
result = _ios_support.get_platform_ios()
538538
if result is not None:
@@ -685,7 +685,7 @@ def _syscmd_file(target, default=''):
685685
default in case the command should fail.
686686
687687
"""
688-
if sys.platform in {'dos', 'win32', 'win16', 'ios', 'tvos', 'watchos'}:
688+
if sys.platform in {'dos', 'win32', 'win16', 'ios', 'tvos', 'visionos', 'watchos'}:
689689
# XXX Others too ?
690690
return default
691691

@@ -849,14 +849,30 @@ def get_OpenVMS():
849849
csid, cpu_number = vms_lib.getsyi('SYI$_CPU', 0)
850850
return 'Alpha' if cpu_number >= 128 else 'VAX'
851851

852-
# On the iOS simulator, os.uname returns the architecture as uname.machine.
853-
# On device it returns the model name for some reason; but there's only one
854-
# CPU architecture for iOS devices, so we know the right answer.
852+
# On the iOS/tvOS/visionOS/watchOS simulator, os.uname returns the
853+
# architecture as uname.machine. On device it returns the model name for
854+
# some reason; but there's only one CPU architecture for devices, so we know
855+
# the right answer.
855856
def get_ios():
856857
if sys.implementation._multiarch.endswith("simulator"):
857858
return os.uname().machine
858859
return 'arm64'
859860

861+
def get_tvos():
862+
if sys.implementation._multiarch.endswith("simulator"):
863+
return os.uname().machine
864+
return 'arm64'
865+
866+
def get_visionos():
867+
if sys.implementation._multiarch.endswith("simulator"):
868+
return os.uname().machine
869+
return 'arm64'
870+
871+
def get_watchos():
872+
if sys.implementation._multiarch.endswith("simulator"):
873+
return os.uname().machine
874+
return 'arm64_32'
875+
860876
def from_subprocess():
861877
"""
862878
Fall back to `uname -p`
@@ -1009,8 +1025,8 @@ def uname():
10091025
system = 'Android'
10101026
release = android_ver().release
10111027

1012-
# Normalize responses on iOS
1013-
if sys.platform == 'ios':
1028+
# Normalize responses on Apple mobile platforms
1029+
if sys.platform in {"ios", "tvos", "visionos", "watchos"}:
10141030
system, release, _, _ = ios_ver()
10151031

10161032
vals = system, node, release, version, machine
@@ -1299,7 +1315,7 @@ def platform(aliased=False, terse=False):
12991315

13001316
if system == 'Darwin':
13011317
# macOS and iOS both report as a "Darwin" kernel
1302-
if sys.platform == "ios":
1318+
if sys.platform in {"ios", "tvos", "visionos", "watchos"}:
13031319
system, release, _, _ = ios_ver()
13041320
else:
13051321
macos_release = mac_ver()[0]

‎Lib/site.py‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -653,8 +653,8 @@ def _getuserbase():
653653
if env_base:
654654
return env_base
655655

656-
# Emscripten, iOS, tvOS, VxWorks, WASI, and watchOS have no home directories
657-
if sys.platform in {"emscripten", "ios", "tvos", "vxworks", "wasi", "watchos"}:
656+
# Emscripten, iOS, tvOS, visionOS, VxWorks, WASI, and watchOS have no home directories
657+
if sys.platform in {"emscripten", "ios", "tvos", "vxworks", "visionos", "wasi", "watchos"}:
658658
return None
659659

660660
def joinuser(*args):

0 commit comments

Comments
 (0)