Upgrade to Pro — share decks privately, control downloads, hide ads and more …

ABI安定化とLibrary Evolution

Sponsored · Ship Features Fearlessly Turn features on and off without deploys. Used by thousands of Ruby developers.

ABI安定化とLibrary Evolution

Avatar for omochimetaru

omochimetaru

May 24, 2019
Tweet

More Decks by omochimetaru

Other Decks in Programming

Transcript

  1. • ΈΜͳେ޷͖Mangling • Calling Convention • (frozen)structͷϨΠΞ΢τ • Value Witness

    TableͷϨΠΞ΢τ • ... https://github.com/apple/swift/blob/master/ docs/ABIStabilityManifesto.md 8
  2. const uint16_t SWIFTMODULE_VERSION_MINOR = 491; // mangled class names as

    vtable keys https://github.com/apple/swift/blob/ cfc2dda69a7afe819ae245fbbd8f4501424c0644/ include/swift/Serialization/ModuleFormat.h#L55 18
  3. // a.swift public class Cat { public func nya1() {

    print(1) } internal func nya2() { print(2) } @inlinable public func nya3() { print(3) } @usableFromInline internal func nya4() { print(4) } } 20
  4. $ swiftc -enable-library-evolution - emit-module-interface a.swift // a.swiftinterface // swift-interface-format-version:

    1.0 // swift-tools-version: // Swift version 5.1-dev (LLVM 082dec2e22, Swift 60ee9527bb) // swift-module-flags: // -target x86_64-apple-darwin18.5.0 -enable-objc-interop // -enable-library-evolution -module-name a import Swift public class Cat { public func nya1() @inlinable public func nya3() { print(3) } @usableFromInline internal func nya4() @objc deinit } 21
  5. ϓϩϙʔβϧ SE-0260 Library Evolution for Stable ABIs https://github.com/apple/swift-evolution/blob/ master/proposals/0260-library-evolution.md ৹ٞεϨου

    https://forums.swift.org/t/se-0260-library- evolution-for-stable-abis/24260 5/21ʹ৹ٞऴྃͨ͠͹͔Γ Swift5.1΁ͷಋೖΛ༧ఆ 25
  6. ैདྷ(Cݴޠ) ϝϞϦྖҬͷ༧໿ struct Record { int id; const char *name;

    void *reserved[2]; }; • ඞཁʹͳΔ·Ͱ͸ແବ • ͸Έग़͢ͱ͍ۤ͠ 32
  7. ϙΠϯλʹୀආ struct Record { struct RecordImpl * impl }; //

    private struct RecordImpl { int id; const char *name; }; 33
  8. ૢ࡞༻ϝιου͕ͨ͘͞Μඞཁ void Record_init(Record * this); void Record_deinit(Record * this); int

    Record_id(const Record * this); const char * Record_name(const Record * this); void Record_copy(Record & dest, const Record & src); 34
  9. // b.swift public struct Record { public var id: Int

    = 0 public var name: String = "" public init() {} } // a.swift import b func main() { var x = Record() } 37
  10. define hidden swiftcc void @"$s1a4mainyyF"() local_unnamed_addr #1 { entry: %0

    = tail call swiftcc %swift.metadata_response @"$s1b6RecordVMa"(i64 0) #3 %1 = extractvalue %swift.metadata_response %0, 0 %2 = getelementptr inbounds %swift.type, %swift.type* %1, i64 -1 %3 = bitcast %swift.type* %2 to i8*** %.valueWitnesses = load i8**, i8*** %3, align 8, !invariant.load !13, !dereferenceable !14 %4 = getelementptr inbounds i8*, i8** %.valueWitnesses, i64 8 %5 = bitcast i8** %4 to i64* %size = load i64, i64* %5, align 8, !invariant.load !13 %x = alloca i8, i64 %size, align 16 call void @llvm.lifetime.start.p0i8(i64 -1, i8* nonnull %x) %6 = bitcast i8* %x to %swift.opaque* call swiftcc void @"$s1b6RecordVACycfC"(%swift.opaque* noalias nocapture nonnull sret %6) %7 = getelementptr inbounds i8*, i8** %.valueWitnesses, i64 1 %8 = bitcast i8** %7 to void (%swift.opaque*, %swift.type*)** %9 = load void (%swift.opaque*, %swift.type*)*, void (%swift.opaque*, %swift.type*)** %8, align 8, !invariant.load !13 call void %9(%swift.opaque* noalias nonnull %6, %swift.type* %1) #4 call void @llvm.lifetime.end.p0i8(i64 -1, i8* nonnull %x) ret void } 39
  11. • metadata accessor $s1b6RecordVMa Λݺͼग़ ͯ͠MetatypeΛऔಘ • getelementptrͷ-1ͰValue Witness TableΛ

    औಘ • VWTͷ8൪͔ΒܕͷαΠζΛऔಘ • allocaͰͦͷαΠζͰϝϞϦ֬อ 40