Slide 1

Slide 1 text

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

Slide 2

Slide 2 text

Swift5ͱ͍͑͹ 2

Slide 3

Slide 3 text

ABI҆ఆԽ 3

Slide 4

Slide 4 text

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

Slide 5

Slide 5 text

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

Slide 6

Slide 6 text

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

Slide 7

Slide 7 text

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

Slide 8

Slide 8 text

• ΈΜͳେ޷͖Mangling • Calling Convention • (frozen)structͷϨΠΞ΢τ • Value Witness TableͷϨΠΞ΢τ • ... https://github.com/apple/swift/blob/master/ docs/ABIStabilityManifesto.md 8

Slide 9

Slide 9 text

Ըܙ • ΞϓϦΛϏϧυͨ͠ޙͰϥΠϒϥϦΛࠩ͠ସ͑ Մೳ • ඪ४ϥΠϒϥϦͷOS΁ͷಉࠝ • Swift 5.0Ͱୡ੒ 9

Slide 10

Slide 10 text

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

Slide 11

Slide 11 text

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

Slide 12

Slide 12 text

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

Slide 13

Slide 13 text

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

Slide 14

Slide 14 text

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

Slide 15

Slide 15 text

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

Slide 16

Slide 16 text

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

Slide 17

Slide 17 text

• ޓ׵ੑΛ΋ͨͤʹ͍͘ • ίϯύΠϥͷόʔδϣϯ͕มΘΔͱϑΥʔϚο τ΋มΘͬͯͨ 17

Slide 18

Slide 18 text

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

Slide 19

Slide 19 text

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

Slide 20

Slide 20 text

// 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

Slide 21

Slide 21 text

$ 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

Slide 22

Slide 22 text

Library Evolution ৽͍͠όʔδϣϯͷϥΠϒϥϦΛɺ ϏϧυࡁΈͷΞϓϦʹରͯ͠ɺ ϦϏϧυ͢Δࣄͳࠩ͘͠ସ͑Δ͜ͱ͕Ͱ͖Δ 22

Slide 23

Slide 23 text

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

Slide 24

Slide 24 text

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

Slide 25

Slide 25 text

ϓϩϙʔβϧ 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

Slide 26

Slide 26 text

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

Slide 27

Slide 27 text

Library EvolutionϞʔυ • ैདྷͷ௨ৗϞʔυʹՃ͑ɺ Library EvolutionϞʔυͰͷϏϧυ͕ಋೖ͞Ε Δ • ඪ४ϥΠϒϥϦ͸Ҏલ͔Β͜ͷϞʔυͩͬͨ • -enable-library-evolutionεΠον ҎԼɺLEϞʔυͰͷ࢓༷ͷ࿩ 27

Slide 28

Slide 28 text

enum͕non-frozenʹͳΔ όʔδϣϯΞοϓͰcase͕૿΍ͤΔ Ϣʔβ͸switch-caseʹඞͣdefault:͕ඞཁʹͳ Δ Ϣʔβ͸@unknownͷ࢖͍ॴ 28

Slide 29

Slide 29 text

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

Slide 30

Slide 30 text

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

Slide 31

Slide 31 text

Resilientͳstruct 31

Slide 32

Slide 32 text

ैདྷ(Cݴޠ) ϝϞϦྖҬͷ༧໿ struct Record { int id; const char *name; void *reserved[2]; }; • ඞཁʹͳΔ·Ͱ͸ແବ • ͸Έग़͢ͱ͍ۤ͠ 32

Slide 33

Slide 33 text

ϙΠϯλʹୀආ struct Record { struct RecordImpl * impl }; // private struct RecordImpl { int id; const char *name; }; 33

Slide 34

Slide 34 text

ૢ࡞༻ϝιου͕ͨ͘͞Μඞཁ 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

Slide 35

Slide 35 text

ώʔϓར༻ίετ͕͔͔Δ ϝϞϦ֬อ/ղ์ॲཧͷඞཁ΍ɺ Ωϟογϡώοτ཰ͷ௿Լ͕ى͖Δ ಛʹ഑ྻʹͨ͠ͱ͖ʹɺ ίϯςϯπ͕ετϨʔδϝϞϦ্Ͱ࿈ଓ͠ͳ͘ ͳͬͯ͠·͏ 35

Slide 36

Slide 36 text

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

Slide 37

Slide 37 text

// 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

Slide 38

Slide 38 text

$ swiftc -enable-library-evolution -emit-module-interface b.swift $ swiftc -emit-ir -I . -O a.swift 38

Slide 39

Slide 39 text

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

Slide 40

Slide 40 text

• metadata accessor $s1b6RecordVMa Λݺͼग़ ͯ͠MetatypeΛऔಘ • getelementptrͷ-1ͰValue Witness TableΛ औಘ • VWTͷ8൪͔ΒܕͷαΠζΛऔಘ • allocaͰͦͷαΠζͰϝϞϦ֬อ 40

Slide 41

Slide 41 text

• Record.init($s1b6RecordVACycfC)Λݺͼग़ ͢ • VWTͷ1൪͔ΒdestroyΛऔಘ • ͦΕΛݺͼग़ͯ͠ΦϒδΣΫτΛഁغ 41