Skip to content

Commit ed7ab2a

Browse files
[Wasm][KeyPath] Resolve absolute function pointer as identity
Emit and resolve idValue of KeyPath as an absolute pointer if relative function pointer is turned-off on Wasm target. The existing ABI can't distinguish an idValue between function pointer or data pointer in use-site at compile-time and also at runtime. So this patch adds a new id resolution scheme `ResolvedAbsolute` to distinguish them at runtime properly.
1 parent ecf8a35 commit ed7ab2a

File tree

4 files changed

+32
-10
lines changed

4 files changed

+32
-10
lines changed

include/swift/ABI/KeyPath.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,7 @@ class KeyPathComponentHeader {
192192

193193
enum ComputedPropertyIDResolution {
194194
Resolved,
195+
ResolvedAbsolute,
195196
IndirectPointer,
196197
FunctionCall,
197198
};
@@ -214,6 +215,7 @@ class KeyPathComponentHeader {
214215
? _SwiftKeyPathComponentHeader_ComputedIDByVTableOffsetFlag : 0)
215216
| (hasArguments ? _SwiftKeyPathComponentHeader_ComputedHasArgumentsFlag : 0)
216217
| (resolution == Resolved ? _SwiftKeyPathComponentHeader_ComputedIDResolved
218+
: resolution == ResolvedAbsolute ? _SwiftKeyPathComponentHeader_ComputedIDResolvedAbsolute
217219
: resolution == IndirectPointer ? _SwiftKeyPathComponentHeader_ComputedIDUnresolvedIndirectPointer
218220
: resolution == FunctionCall ? _SwiftKeyPathComponentHeader_ComputedIDUnresolvedFunctionCall
219221
: (assert(false && "invalid resolution"), 0)));

lib/IRGen/GenKeyPath.cpp

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -954,7 +954,11 @@ emitKeyPathComponent(IRGenModule &IGM,
954954
// instantiation time.
955955
idResolution = idRef.isIndirect()
956956
? KeyPathComponentHeader::IndirectPointer
957-
: KeyPathComponentHeader::Resolved;
957+
// Compute absolute reference from relative reference if target supports it.
958+
// Otherwise, embed absolute reference directly.
959+
: (IGM.getOptions().CompactAbsoluteFunctionPointer
960+
? KeyPathComponentHeader::ResolvedAbsolute
961+
: KeyPathComponentHeader::Resolved);
958962
break;
959963
}
960964
case KeyPathPatternComponent::ComputedPropertyId::DeclRef: {
@@ -1089,8 +1093,12 @@ emitKeyPathComponent(IRGenModule &IGM,
10891093
fields.addInt32(header.getData());
10901094
switch (idKind) {
10911095
case KeyPathComponentHeader::Pointer:
1092-
// Use a relative offset to the referent.
1093-
fields.addRelativeAddress(idValue);
1096+
// Use a relative offset to the referent if value is not absolute.
1097+
if (idResolution == KeyPathComponentHeader::ResolvedAbsolute) {
1098+
fields.add(idValue);
1099+
} else {
1100+
fields.addRelativeAddress(idValue);
1101+
}
10941102
break;
10951103

10961104
case KeyPathComponentHeader::VTableOffset:

stdlib/public/SwiftShims/KeyPath.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,8 @@ static const __swift_uint32_t _SwiftKeyPathComponentHeader_ComputedIDResolutionM
104104
= 0x0000000FU;
105105
static const __swift_uint32_t _SwiftKeyPathComponentHeader_ComputedIDResolved
106106
= 0x00000000U;
107+
static const __swift_uint32_t _SwiftKeyPathComponentHeader_ComputedIDResolvedAbsolute
108+
= 0x00000003U;
107109
static const __swift_uint32_t _SwiftKeyPathComponentHeader_ComputedIDUnresolvedIndirectPointer
108110
= 0x00000002U;
109111
static const __swift_uint32_t _SwiftKeyPathComponentHeader_ComputedIDUnresolvedFunctionCall

stdlib/public/core/KeyPath.swift

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -874,6 +874,7 @@ internal enum KeyPathComputedIDKind {
874874

875875
internal enum KeyPathComputedIDResolution {
876876
case resolved
877+
case resolvedAbsolute
877878
case indirectPointer
878879
case functionCall
879880
}
@@ -1108,6 +1109,9 @@ internal struct RawKeyPathComponent {
11081109
internal static var computedIDResolved: UInt32 {
11091110
return _SwiftKeyPathComponentHeader_ComputedIDResolved
11101111
}
1112+
internal static var computedIDResolvedAbsolute: UInt32 {
1113+
return _SwiftKeyPathComponentHeader_ComputedIDResolvedAbsolute
1114+
}
11111115
internal static var computedIDUnresolvedIndirectPointer: UInt32 {
11121116
return _SwiftKeyPathComponentHeader_ComputedIDUnresolvedIndirectPointer
11131117
}
@@ -1118,6 +1122,8 @@ internal struct RawKeyPathComponent {
11181122
switch payload & Header.computedIDResolutionMask {
11191123
case Header.computedIDResolved:
11201124
return .resolved
1125+
case Header.computedIDResolvedAbsolute:
1126+
return .resolvedAbsolute
11211127
case Header.computedIDUnresolvedIndirectPointer:
11221128
return .indirectPointer
11231129
case Header.computedIDUnresolvedFunctionCall:
@@ -3381,35 +3387,39 @@ internal struct InstantiateKeyPathBuffer: KeyPathPatternVisitor {
33813387
resolvedID = UnsafeRawPointer(bitPattern: value)
33823388

33833389
case .pointer:
3384-
// Resolve the sign-extended relative reference.
3385-
var absoluteID: UnsafeRawPointer? = _resolveRelativeAddress(idValueBase, idValue)
3386-
33873390
// If the pointer ID is unresolved, then it needs work to get to
33883391
// the final value.
33893392
switch idResolution {
33903393
case .resolved:
3394+
resolvedID = _resolveRelativeAddress(idValueBase, idValue)
3395+
break
3396+
3397+
case .resolvedAbsolute:
3398+
let value = UInt(UInt32(bitPattern: idValue))
3399+
resolvedID = UnsafeRawPointer(bitPattern: value)
33913400
break
33923401

33933402
case .indirectPointer:
33943403
// The pointer in the pattern is an indirect pointer to the real
33953404
// identifier pointer.
3396-
absoluteID = absoluteID.unsafelyUnwrapped
3405+
let absoluteID = _resolveRelativeAddress(idValueBase, idValue)
3406+
resolvedID = absoluteID
33973407
.load(as: UnsafeRawPointer?.self)
33983408

33993409
case .functionCall:
34003410
// The pointer in the pattern is to a function that generates the
34013411
// identifier pointer.
34023412
typealias Resolver = @convention(c) (UnsafeRawPointer?) -> UnsafeRawPointer?
3413+
let absoluteID = _resolveCompactFunctionPointer(idValueBase, idValue)
34033414
let resolverSigned = _PtrAuth.sign(
3404-
pointer: absoluteID.unsafelyUnwrapped,
3415+
pointer: absoluteID,
34053416
key: .processIndependentCode,
34063417
discriminator: _PtrAuth.discriminator(for: Resolver.self))
34073418
let resolverFn = unsafeBitCast(resolverSigned,
34083419
to: Resolver.self)
34093420

3410-
absoluteID = resolverFn(patternArgs)
3421+
resolvedID = resolverFn(patternArgs)
34113422
}
3412-
resolvedID = absoluteID
34133423
}
34143424

34153425
// Bring over the header, getter, and setter.

0 commit comments

Comments
 (0)