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

ABI安定化とLibrary Evolution

ABI安定化とLibrary Evolution

3781f49ea2c76d6ecf0c6cda46096d49?s=128

omochimetaru

May 24, 2019
Tweet

More Decks by omochimetaru

Other Decks in Programming

Transcript

  1. ABI҆ఆԽͱLibrary Evolution omochimetaru Θ͍Θ͍swiftc #11 1

  2. Swift5ͱ͍͑͹ 2

  3. ABI҆ఆԽ 3

  4. ABI Stability and More https://swift.org/blog/abi-stability-and-more/ 4

  5. 3ͭͷػೳ • ABI Stability • Module Stability • Library Evolution

    5
  6. ABI Stability ίϯύΠϥͷόʔδϣϯʹΑΒͣɺ SwiftͷΠϯλʔϑΣʔε͕ಉ͡ͳΒ όΠφϦͷΠϯλʔϑΣʔε΋ಉ͡ 6

  7. ैདྷ ίϯύΠϥͷόʔδϣϯ͕มΘΔͱɺ SwiftͷΠϯλʔϑΣʔε͕ಉ͡Ͱ΋ɺ όΠφϦͷΠϯλʔϑΣʔε͕มΘͬͯͨ 7

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

    TableͷϨΠΞ΢τ • ... https://github.com/apple/swift/blob/master/ docs/ABIStabilityManifesto.md 8
  9. Ըܙ • ΞϓϦΛϏϧυͨ͠ޙͰϥΠϒϥϦΛࠩ͠ସ͑ Մೳ • ඪ४ϥΠϒϥϦͷOS΁ͷಉࠝ • Swift 5.0Ͱୡ੒ 9

  10. ஫ҙ ϏϧυޙͷϥΠϒϥϦͷࠩ͠ସ͑Ͱ͋ͬͯɺ ϏϧυલͰ͸ͳ͍ ΞϓϦͷϦϏϧυ͸Ͱ͖ͳ͍ ίϯύΠϧޙͷ࿩ 10

  11. Module Stability ίϯύΠϥͷόʔδϣϯʹΑΒͣɺ Ϗϧυͨ͠ϥΠϒϥϦΛ഑෍ͯ͠ɺ ΞϓϦʹ૊ΈࠐΜͰϏϧυͰ͖Δ 11

  12. Swift 5.1ͷ໨ۄػೳ(primary goal) https://swift.org/blog/5-1-release-process/ 12

  13. ৽͍͠ϥΠϒϥϦͱͱ΋ʹɺ ΞϓϦΛϦϏϧυ͢Δ࿩ ίϯύΠϧ͢Δ࣌ͷ࿩ 13

  14. Ϗϧυ͞ΕͨϥΠϒϥϦΛ૊ΈࠐΉͨΊʹ͸ɺ ϥΠϒϥϦͷΠϯλʔϑΣʔεͷ৘ใΛɺ ίϯύΠϥ͕நग़Ͱ͖Δඞཁ͕͋Δ 14

  15. ϥΠϒϥϦͷϔομ৘ใ XcodeͷCmd + Ctl + ↑ͱ͔Ͱݟ͑Δ΍ͭ(ࡶ) 15

  16. ैདྷ • .swiftmodule • όΠφϦܗࣜͷϥΠϒϥϦͷϔομ৘ใ • LLVM bitstream format http://llvm.org/docs/BitCodeFormat.html

    • https://github.com/omochi/BitcodeFormat 16
  17. • ޓ׵ੑΛ΋ͨͤʹ͍͘ • ίϯύΠϥͷόʔδϣϯ͕มΘΔͱϑΥʔϚο τ΋มΘͬͯͨ 17

  18. 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
  19. ղܾํ๏ • .swiftinterface • ςΩετܗࣜͷϥΠϒϥϦͷϔομ৘ใ https://forums.swift.org/t/plan-for-module- stability/14551 19

  20. // 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
  21. $ 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
  22. Library Evolution ৽͍͠όʔδϣϯͷϥΠϒϥϦΛɺ ϏϧυࡁΈͷΞϓϦʹରͯ͠ɺ ϦϏϧυ͢Δࣄͳࠩ͘͠ସ͑Δ͜ͱ͕Ͱ͖Δ 22

  23. ABI StabilityͰ͸ SwiftͷΠϯλʔϑΣʔε͸ಉҰͱ͍͏લఏ Library EvolutionͰ͸Ұఆͷ੍໿ͷݩͰɺ SwiftͷΠϯλʔϑΣʔεΛมߋͰ͖Δ 23

  24. ඪ४ϥΠϒϥϦ͕ΞοϓσʔτͰ͖Δͷ͸ɺ ͜ͷػೳΛઌߦͯ͠ར༻͍ͯ͠Δ͔Β ͜ΕΛҰൠ։์͢Δͷ͕Library Evolution 24

  25. ϓϩϙʔβϧ 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
  26. ϥΠϒϥϦΛόʔδϣϯΞοϓՄೳʹ͢Δͱ͍͏ ͜ͱ͸ɺ ίϯύΠϧ࣌ͱ࣮ߦ࣌Ͱத਎͕มΘΔͱ͍͏͜ͱ ࣮ߦ࣌ʹมߋʹରԠͰ͖Δॊೈੑ͕ඞཁʹͳΔ ίʔυ΋ͦΕʹ഑ྀͨ͠ରԠ͕ඞཁ 26

  27. Library EvolutionϞʔυ • ैདྷͷ௨ৗϞʔυʹՃ͑ɺ Library EvolutionϞʔυͰͷϏϧυ͕ಋೖ͞Ε Δ • ඪ४ϥΠϒϥϦ͸Ҏલ͔Β͜ͷϞʔυͩͬͨ •

    -enable-library-evolutionεΠον ҎԼɺLEϞʔυͰͷ࢓༷ͷ࿩ 27
  28. enum͕non-frozenʹͳΔ όʔδϣϯΞοϓͰcase͕૿΍ͤΔ Ϣʔβ͸switch-caseʹඞͣdefault:͕ඞཁʹͳ Δ Ϣʔβ͸@unknownͷ࢖͍ॴ 28

  29. struct͕resilientʹͳΔ όʔδϣϯΞοϓͰstored property͕૿΍ͤΔ 29

  30. struct΁ͷ@frozenࢦఆ @frozenΛࢦఆ͢Δͱɺͦͷstruct͚ͩ௨ৗϞʔ υʹͳΔ ͭ·ΓɺresiliencyΛࣦ͏୅ΘΓʹɺ࣮ߦ଎౓্͕ ͕Δ 30

  31. Resilientͳstruct 31

  32. ैདྷ(Cݴޠ) ϝϞϦྖҬͷ༧໿ struct Record { int id; const char *name;

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

    private struct RecordImpl { int id; const char *name; }; 33
  34. ૢ࡞༻ϝιου͕ͨ͘͞Μඞཁ 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
  35. ώʔϓར༻ίετ͕͔͔Δ ϝϞϦ֬อ/ղ์ॲཧͷඞཁ΍ɺ Ωϟογϡώοτ཰ͷ௿Լ͕ى͖Δ ಛʹ഑ྻʹͨ͠ͱ͖ʹɺ ίϯςϯπ͕ετϨʔδϝϞϦ্Ͱ࿈ଓ͠ͳ͘ ͳͬͯ͠·͏ 35

  36. ղܾํ๏ ࣮ߦ࣌ʹܕͷαΠζΛಈతʹऔಘ͢Δ ελοΫʹϝϞϦΛஔ͍ͨ··࣮ߦ࣌ՄมʹͰ͖ Δ 36

  37. // 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
  38. $ swiftc -enable-library-evolution -emit-module-interface b.swift $ swiftc -emit-ir -I .

    -O a.swift 38
  39. 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
  40. • metadata accessor $s1b6RecordVMa Λݺͼग़ ͯ͠MetatypeΛऔಘ • getelementptrͷ-1ͰValue Witness TableΛ

    औಘ • VWTͷ8൪͔ΒܕͷαΠζΛऔಘ • allocaͰͦͷαΠζͰϝϞϦ֬อ 40
  41. • Record.init($s1b6RecordVACycfC)Λݺͼग़ ͢ • VWTͷ1൪͔ΒdestroyΛऔಘ • ͦΕΛݺͼग़ͯ͠ΦϒδΣΫτΛഁغ 41