Skip to content

Commit cf0191b

Browse files
authored
Update interpose to fix ShapeLayerHelper update issue (#777)
1 parent cb84f0a commit cf0191b

5 files changed

Lines changed: 69 additions & 44 deletions

File tree

Example/Example.xcodeproj/project.pbxproj

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -66,13 +66,6 @@
6666
/* End PBXFileReference section */
6767

6868
/* Begin PBXFileSystemSynchronizedBuildFileExceptionSet section */
69-
27240CFE2E8FFBC900E9DABD /* PBXFileSystemSynchronizedBuildFileExceptionSet */ = {
70-
isa = PBXFileSystemSynchronizedBuildFileExceptionSet;
71-
membershipExceptions = (
72-
kdebug_interpose.c,
73-
);
74-
target = 27CD0B482AFC8D37003665EB /* Example */;
75-
};
7669
275751CC2DEE136C003E467C /* PBXFileSystemSynchronizedBuildFileExceptionSet */ = {
7770
isa = PBXFileSystemSynchronizedBuildFileExceptionSet;
7871
membershipExceptions = (
@@ -93,6 +86,13 @@
9386
};
9487
target = 27D49DF72BA604FB00F6E2E2 /* HostingExample */;
9588
};
89+
275C29E52F389AE8008676C3 /* PBXFileSystemSynchronizedBuildFileExceptionSet */ = {
90+
isa = PBXFileSystemSynchronizedBuildFileExceptionSet;
91+
membershipExceptions = (
92+
interpose.c,
93+
);
94+
target = 275751E22DEE1441003E467C /* TestingHost */;
95+
};
9696
/* End PBXFileSystemSynchronizedBuildFileExceptionSet section */
9797

9898
/* Begin PBXFileSystemSynchronizedRootGroup section */
@@ -102,7 +102,7 @@
102102
275751F62DEE1456003E467C /* OpenSwiftUIUITests */ = {isa = PBXFileSystemSynchronizedRootGroup; explicitFileTypes = {}; explicitFolders = (); path = OpenSwiftUIUITests; sourceTree = "<group>"; };
103103
279FEC572DF450D200320390 /* ReferenceImages */ = {isa = PBXFileSystemSynchronizedRootGroup; explicitFileTypes = {}; explicitFolders = (); path = ReferenceImages; sourceTree = "<group>"; };
104104
27E6C4F62D2842D80010502F /* Configurations */ = {isa = PBXFileSystemSynchronizedRootGroup; explicitFileTypes = {}; explicitFolders = (); name = Configurations; path = ../Configurations; sourceTree = "<group>"; };
105-
27FFF0422E08850C0060A4DA /* SharedExample */ = {isa = PBXFileSystemSynchronizedRootGroup; exceptions = (27240CFE2E8FFBC900E9DABD /* PBXFileSystemSynchronizedBuildFileExceptionSet */, ); explicitFileTypes = {}; explicitFolders = (); path = SharedExample; sourceTree = "<group>"; };
105+
27FFF0422E08850C0060A4DA /* SharedExample */ = {isa = PBXFileSystemSynchronizedRootGroup; exceptions = (275C29E52F389AE8008676C3 /* PBXFileSystemSynchronizedBuildFileExceptionSet */, ); explicitFileTypes = {}; explicitFolders = (); path = SharedExample; sourceTree = "<group>"; };
106106
/* End PBXFileSystemSynchronizedRootGroup section */
107107

108108
/* Begin PBXFrameworksBuildPhase section */

Example/OpenSwiftUIUITests/Shape/ShapeUITests.swift

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,7 @@ struct ShapeUITests {
2929
.frame(width: 100, height: 100, alignment: .center)
3030
}
3131
}
32-
// FIXME
33-
openSwiftUIAssertSnapshot(of: ContentView(), perceptualPrecision: 0.8)
32+
openSwiftUIAssertSnapshot(of: ContentView())
3433
}
3534

3635
@Test
@@ -42,7 +41,6 @@ struct ShapeUITests {
4241
.frame(width: 100, height: 100, alignment: .center)
4342
}
4443
}
45-
// FIXME
46-
openSwiftUIAssertSnapshot(of: ContentView(), perceptualPrecision: 0.8)
44+
openSwiftUIAssertSnapshot(of: ContentView())
4745
}
4846
}

Example/SharedExample/interpose.c

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
//
2+
// interpose.c
3+
// SharedExample
4+
//
5+
// Created by Kyle on 2025/10/3.
6+
//
7+
8+
#include <stdbool.h>
9+
#include <stdint.h>
10+
#include <dlfcn.h>
11+
#include <AttributeGraph/AttributeGraph-umbrella.h>
12+
13+
// Forward declare the original
14+
extern bool kdebug_is_enabled(uint32_t debugid);
15+
16+
// Our replacement
17+
static bool my_kdebug_is_enabled(uint32_t debugid) {
18+
return true;
19+
}
20+
21+
extern const void *$s15OpenSwiftUICore5ColorV8ResolvedVN;
22+
23+
const void *_OpenSwiftUI_ColorResolvedNTD(void) {
24+
return &$s15OpenSwiftUICore5ColorV8ResolvedVN;
25+
}
26+
27+
extern bool swift_dynamicCast(void *dest, void *src,
28+
const void *srcType,
29+
const void *targetType,
30+
uint64_t flags);
31+
32+
static bool my_swift_dynamicCast(void *dest, void *src, const void *srcType, const void *targetType, uint64_t flags) {
33+
CFStringRef target_description = AGTypeDescription((AGTypeID)targetType);
34+
// Check if target_description contains "Color.Resolved"
35+
if (target_description != NULL) {
36+
CFRange range = CFStringFind(target_description, CFSTR("Color.Resolved"), 0);
37+
if (range.location != kCFNotFound) {
38+
// First try the original cast, if it fails try with OpenSwiftUI's Color.Resolved
39+
return swift_dynamicCast(dest, src, srcType, targetType, flags) ||
40+
swift_dynamicCast(dest, src, srcType, _OpenSwiftUI_ColorResolvedNTD(), flags);
41+
}
42+
}
43+
return swift_dynamicCast(dest, src, srcType, targetType, flags);
44+
}
45+
46+
// Interpose using Mach-O section
47+
typedef struct interpose_s {
48+
const void *replacement;
49+
const void *original;
50+
} interpose_t;
51+
52+
__attribute__((used)) static const interpose_t interposers[]
53+
__attribute__((section("__DATA, __interpose"))) = {
54+
// Interpose kdebug_is_enabled to always return true to perform Signpost testing with Instruments
55+
{ (const void *)my_kdebug_is_enabled, (const void *)kdebug_is_enabled },
56+
// Interpose swift_dynamicCast to handle casts to SwiftUI's internal Color.Resolved type to fix SwiftUI.ShapeLayerHelper visit check for Shape.fill API
57+
{ (const void *)my_swift_dynamicCast, (const void *)swift_dynamicCast },
58+
};

Example/SharedExample/kdebug_interpose.c

Lines changed: 0 additions & 31 deletions
This file was deleted.

Sources/OpenSwiftUICore/Graphic/Color/Paint.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ final package class _AnyResolvedPaint<P>: AnyResolvedPaint where P: ResolvedPain
9090
return paint == other.paint
9191
}
9292

93-
override package func visit<V>(_ visitor: inout V) where V : ResolvedPaintVisitor {
93+
override package func visit<V>(_ visitor: inout V) where V: ResolvedPaintVisitor {
9494
visitor.visitPaint(paint)
9595
}
9696

0 commit comments

Comments
 (0)