Swift internals

35
let swift(16) º´ Internals LLVM, Type system, Swift Foundation OSXDEV.org j

Transcript of Swift internals

Page 1: Swift internals

let swift(16)

InternalsLLVM, Type system, Swift Foundation

OSXDEV.orgj�

Page 2: Swift internals

Agenda

Swift Compiler Swift Type System Swift Type Internals Swift Foundation Summary

Page 3: Swift internals

let swift(16)

Swift CompilerLLVM, Clang, Swiftc

Page 4: Swift internals
Page 5: Swift internals

A LoNG Time AGo,

in a galaxy far, far away...

Page 6: Swift internals

LLVMLow-Level Virtual Machine An Infrastructure for Multi-stage Optimization − by Chris Arthur Lattner @2002

Design and Implementation of a compiler infrastructure − support a unique multi-stage optimization system − support inter-procedural and profile-driven optimizations

LLVM virtual instruction (IR) − with high-level type information

Sponsored by APPLE

Page 7: Swift internals

Chris LattnerThe Father of LLVM

Page 8: Swift internals

LLVM CompilerGCC#4.2#

프론트엔드#

C"Tree*SSA#최적화기# 코드 생성기#C++"

Objec)ve+C"실행파일"

GCC"4.2"

GCC#4.2#프론트엔드#

C"LLVM#

최적화기#LLVM#

코드 생성기#C++"

Objec)ve+C"실행파일"

LLVM+GCC"4.2"

Clang#프론트엔드#

C"LLVM#

최적화기#LLVM#

코드 생성기#C++"

Objec)ve+C"실행파일"

LLVM"

Page 9: Swift internals
Page 10: Swift internals

Swift Compiler

yp�RVHES� � ��

− � 9 RHMF � DL MSH � M RHR �

− � %� � < OD� GD D �

� � p�

− � � d� S MREN L %�-: � %� DMD H �

> � :� � c�

k�ib � p�ib� y AHM �

.swift 기계코드

Page 11: Swift internals

let swift(16)

Swift Type SystemDuck Type vs. HM Type Inference

Page 12: Swift internals

Objective-C Type SystemStatic Type + Duck Type System − C-style static type − Smalltalk-style duck type

Duck Type History − a message to comp.lang.python Newsgroup (2000)

Don't check whether it IS-a duck: check whether it QUACKS-like-a duck, WALKS-like-a duck, etc, etc, depending on exactly what subset of duck-like behaviour you need to play your language-games with.

“”

Page 13: Swift internals

Swift Type System

Bi-directional type inference Constraint-based type checker − Based classical Hindley-Milner type system − Include polymorphic types & function overloading − Step : Generate ➔ Solve ➔ Solution Application

func foo(x: Double) -> Int { … }var doubleValue : Double = 3.141592var unknown = foo(doubleValue)

func bar<T>(x: T) -> T { return x }var floatValue: Float = -bar(1.414)

Page 14: Swift internals

“The Principal Type-Scheme of an Object in Combinatory Logic” Hindley, J. Roger (1969) − Describe what types an expression can have − Present an algorithm actually computing a type.

Deductive System

First implemented as part of the system of ML.

Hindley-Milner Type System

A, A ➔ BB (rule)

Page 15: Swift internals

Hindley-Milner Type SystemExpression e = x

| e1 e2 | !x . e | let x=e1 in e2

Types mono " = # | D "…" poly $ = " | ∀#.$

variable

application

abstraction

variableapplication

quantifier

Syntax Context % = & | %, x : # Typing = % ⊢e : $

Page 16: Swift internals

Hindley-Milner Algorithm W[Var]

[App]

[Abs]

[Let]

Page 17: Swift internals

Type Checker - Constraints0PT HS � �x� � � �

TAS OD� �r � � �

NMUD RHNM� �r � � � q � DPT HS � �RTAS OD ��

NMRS T SHNM� � s� � �r � � � q �

DLAD � � � � � c%�h� � � �

NMEN L M D� � � � p� �

GD DC� RS� � R� � � � q ��

-OO H A D�ETM SHNM� � d� � � �

UD N C�AHMCHMF� � � y� � � �

RR� � � �

NMITMSHNM� �/HRITM SHNM� �a i� p� i

Page 18: Swift internals

Constraint SolvingTake a given set of constraints

Determine the most specific type binding for each of the type variables

The Design of the solver − Simplification : Relational, Member constraints − Strategies : solver scope, overload selection − Comparing solutions : choose solution with smaller scores

“more specific” type

the super-type of overload binds

Page 19: Swift internals
Page 20: Swift internals

let swift(16)

Swift Type Internalsclass, enumeration, struct, protocol

Page 21: Swift internals

Native class typeclass NativePen { let id = 512 var sequence = 1024 }

// class.NativePen.__deallocating_deinit @_TFC5class9NativePenD : $@convention(method) (@owned NativePen) -> () { %0 : $NativePen, let, name "self", argno 1 %3 = class.NativePen.deinit(%0) %4 = unchecked_ref_cast(%3) // $Builtin.NativeObject to $NativePen dealloc_ref(%4) } // class.NativePen.deinit @_TFC5class9NativePend : $@convention(method) (@guaranteed NativePen) -> @owned Builtin.NativeObject { %0 : $NativePen, let, name "self", argno 1 %2 = unchecked_ref_cast(%0) // $NativePen to $Builtin.NativeObject return %2 // $Builtin.NativeObject }

deinit

Page 22: Swift internals

Native class type// class.NativePen.init () -> class.NativePen @_TFC5class9NativePencfT_S0_ : $@convention(method) (@owned NativePen) -> @owned NativePen { %0 : $NativePen, let, name "self" %2 = mark_uninitialized([rootself], %0) %4 = metatype(Int.Type) %5 = integer_literal($Builtin.Int2048, 512) %6 = Swift.Int.init(%5, %4) %7 = ref_element_addr(%2 : $NativePen, #NativePen.id) assign(%6 to %7) %10 = metatype(Int.Type) %11 = integer_literal($Builtin.Int2048, 1024) %12 = Swift.Int.init(%11, %10) %13 = ref_element_addr(%2 : $NativePen, #NativePen.sequence) assign (%12 to %13) return %2 // $NativePen } // class.NativePen.__allocating_init () -> class.NativePen @_TFC5class9NativePenCfT_S0_ : $@convention(thin) (@thick NativePen.Type) -> @owned NativePen { %1 = alloc_ref($NativePen) %3 = class.NativePen.init(%1) return %3 : $NativePen }

init

Page 23: Swift internals

enumeration type_ p� � �r � � � q ��

− � _l� u� q � p� �

RG A D�O NSN N �

0PT S A D�O NSN N

public protocol Hashable : Equatable { var hashValue: Int { get } }

public protocol Equatable { @warn_unused_result func == (lhs: Self, rhs: Self) -> Bool }

Page 24: Swift internals

enum type exampleenum PenModels { case BallPen case NamePen }// enum.PenModels.hashValue.getter : Swift.Int @_TFO4enum9PenModelsg9hashValueSi : $@convention(method) (PenModels) -> Int { %2 = alloc_box($Int, var, name "index") %3 = mark_uninitialized([var] %2#1 : $*Int) switch_enum %0 : $PenModels, case #PenModels.BallPen!enumelt: bb1, case #PenModels.NamePen!enumelt: bb2 bb1: %6 = metatype($@thin Int.Type) %7 = integer_literal($Builtin.Int2048, 0) %8 = Swift.Int.init(%7, %6) // (Builtin.Int2048, @thin Int.Type) -> Int assign(%8 to %3) br bb3 bb2: %12 = metatype($@thin Int.Type) %13 = integer_literal($Builtin.Int2048, 1) %14 = Swift.Int.init(%13, %12) // (Builtin.Int2048, @thin Int.Type) -> Int assign(%14 to %3) br bb3 bb3: %17 = load(%3 : $*Int) %19 = Swift.Int.hashValue.getter(%17) // $@convention(method) (Int) -> Int strong_release(%2#0) // $@box Int return %19 }

getter

Page 25: Swift internals

enum type example// protocol witness for static Swift.Equatable.== infix (A, A) -> Swift.Bool @_TTWO4enum9PenModelss9EquatableS_ZFS1_oi2eefTxx_Sb : $@convention(witness_method) (@in PenModels, @in PenModels, @thick PenModels.Type) -> Bool { %3 = load(%0 : $*PenModels) %4 = load(%1 : $*PenModels) %6 = enum.== infix(%3, %4) return %6 // $Bool } // protocol witness for Swift.Hashable.hashValue.getter : Swift.Int @_TTWO4enum9PenModelss8HashableS_FS1_g9hashValueSi : $@convention(witness_method) (@in_guaranteed PenModels) -> Int { %1 = alloc_stack($PenModels) copy_addr(%0 to [initialization] %1 : $*PenModels) %3 = load(%1 : $*PenModels) %5 = enum.PenModels.hashValue.getter(%3) dealloc_stack(%1 : $*PenModels) return %5 // $Int } sil_witness_table PenModels: Equatable module enum { method #Equatable."=="!1: @_TTWO4enum9PenModelss9EquatableS_ZFS1_oi2eefTxx_Sb } sil_witness_table PenModels: Hashable module enum { base_protocol Equatable: PenModels: Equatable module enum method #Hashable.hashValue!getter.1: @_TTWO4enum9PenModelss8HashableS_FS1_g9hashValueSi }

Protocol Witness Table

Page 26: Swift internals

struct type

� �i �wp� p� � �

− MS� � �- %� DS%�/H SHNM �t �)( �f �

i� HED D � c� �

− � � � � r�

n � � g �b r�

− DS HM� � D D RD�

Page 27: Swift internals

struct type - let examplestruct Car { let model = "apple" }

// struct.Car.init () -> struct.Car @_TFV6struct3CarCfT_S0_ : $@convention(thin) (@thin Car.Type) -> @owned Car { %1 = alloc_box($Car, var, name "self", argno 1) %2 = mark_uninitialized([rootself] %1#1 : $*Car) %4 = metatype($@thin String.Type) %5 = string_literal(utf8 "apple") %6 = integer_literal($Builtin.Word, 5) %7 = integer_literal($Builtin.Int1, -1) %8 = Swift.String.init(%5, %6, %7, %4) %9 = struct_element_addr(%2 : $*Car, #Car.model) assign(%8 to %9 : $*String) %11 = load(%2 : $*Car) retain_value(%11 : $Car) strong_release(%1#0 : $@box Car) return %11 } // struct.Car.model.getter : Swift.String @_TFV6struct3Carg5modelSS : $@convention(method) (@guaranteed Car) -> @owned String { %2 = struct_extract(%0 : $Car, #Car.model) retain_value(%2 : $String) return %2 }

Page 28: Swift internals

struct type - var examplestruct Car { var driver = "tim" }

// struct.Car.init (driver : Swift.String) -> struct.Car @_TFV6struct3CarCfT6driverSS_S0_ : $@convention(thin) (@owned String, @thin Car.Type) -> @owned Car { %2 = struct.$Car(%0 : $String) return %2 } // struct.Car.init () -> struct.Car @_TFV6struct3CarCfT_S0_ : $@convention(thin) (@thin Car.Type) -> @owned Car { %1 = alloc_box($Car, var, name "self", argno 1) %2 = mark_uninitialized([rootself] %1#1 : $*Car) %4 = metatype($@thin String.Type) %5 = string_literal(utf8 "tim") %6 = integer_literal($Builtin.Word, 3) %7 = integer_literal($Builtin.Int1, -1) %8 = Swift.String.init(%5, %6, %7, %4) %9 = struct_element_addr(%2 : $*Car, #Car.driver) assign(%8 to %9 : $*String) %11 = load(%2 : $*Car) retain_value(%11 : $Car) strong_release(%1#0 : $@box Car) return %11 }

init

Page 29: Swift internals

struct type - var example// struct.Car.driver.getter : Swift.String @_TFV6struct3Carg6driverSS : $@convention(method) (@guaranteed Car) -> @owned String { %2 = struct_extract(%0 : $Car, #Car.driver) retain_value(%2 : $String) return %2 } // struct.Car.driver.setter : Swift.String @_TFV6struct3Cars6driverSS : $@convention(method) (@owned String, @inout Car) -> () { %3 = alloc_box($Car, var, name "self", argno 2) copy_addr(%1 to [initialization] %3#1 : $*Car) retain_value(%0 : $String) %6 = struct_element_addr(%3#1 : $*Car, #Car.driver) assign(%0 to %6 : $*String) copy_addr(%3#1 to %1 : $*Car) strong_release(%3#0 : $@box Car) release_value(%0 : $String) %11 = tuple () return %11 } // struct.Car.driver.materializeForSet : Swift.String @_TFV6struct3Carm6driverSS : $@convention(method) (Builtin.RawPointer, @inout Builtin.UnsafeValueBuffer, @inout Car) -> (Builtin.RawPointer, Optional<@convention(thin) (Builtin.RawPointer, inout Builtin.UnsafeValueBuffer, inout Car, @thick Car.Type) -> ()>) { %3 = struct_element_addr(%2 : $*Car, #Car.driver) %4 = address_to_pointer(%3 : $*String to $Builtin.RawPointer) %5 = enum $Optional<@convention(thin) (Builtin.RawPointer, inout Builtin.UnsafeValueBuffer, inout Car, @thick Car.Type) -> ()>, #Optional.None!enumelt %6 = tuple (%4 : $Builtin.RawPointer, %5 : $Optional<@convention(thin) (Builtin.RawPointer, inout Builtin.UnsafeValueBuffer, inout Car, @thick Car.Type) -> ()>) return %6 : $(Builtin.RawPointer, Optional<@convention(thin) (Builtin.RawPointer, inout Builtin.UnsafeValueBuffer, inout Car, @thick Car.Type) -> ()>) }

getter/setter

Page 30: Swift internals

let swift(16)

Swift 3 Foundation

Page 31: Swift internals

Foundation SDK

source : WWDC 2016. Session207. Whats new in foundation for swift

Page 32: Swift internals

파일�구분 관련�타입들 설명

AffineTransform OTA H �RS T S�-EEHMD< MREN L -EEHMD< MREN L �v p�f �

CharacterSetHMSD M �EHM � RR�

VHES G SD DSG SD DS�d� TS A D G SD DS � p�n

� �

Data HMSD M �EHM � RR� VHES / S / S � TS A D/ S � p�n �

Date OTA H �RS T S�/ SD <HLD MSD U � � SHLD � m �b p�

DateComponents OTA H �RS T S�/ SD NLONMDMSR / SD NLONMDMSR � p�m � �

DateInterval OTA H �RS T S�/ SD MSD U / SD MSD U � p�m i � �o �

Decimal D SDMRHNM�/D HL� �t � � %� e� %� /D HL TLAD �

a � p�

FileManager OTA H � RR� H D M FD H D M FD � �

IndexPath OTA H �RS T S� MCD 9 SG MCD 9 SG �v p�o �f �

IndexSet OTA H �RS T S� MCD DS MCD DS �v p�o �f �

Measurement OTA H �RS T S� D RT DLDMS+ MHS< OD� �MHS,

D RT DLDMS �v p�o �f �

Notification OTA H �RS T S� NSHEH SHNM NSHEH SHNM �v p�o �f �

NSError D SDMRHNM� 0 N � �0 N 9 NSN N 0 N �o � � � � u �

URL OTA H �RS T S� : : � p�f �

URLComponents OTA H �RS T S� : NLONMDMSR : NLONMDMSR � p�f �

URLRequest OTA H �RS T S� : :DPTDRS TS A D : :DPTDRS � p�f �

Page 33: Swift internals

SummarySwift Compiler − LLVM + Chris Lattner, Talyer swift

Type System − HM Type System + W Algorithm

Type Internals − class, enumeration, struct, protocol Types

Swift Foundation − IndexPath, IndexSet, Measurement, Notification

Page 34: Swift internals

Referencesllvm.org

swift.org

https://github.com/apple/swift-evolution

https://github.com/apple/swift/tree/swift-3.0-preview-2-branch

https://en.wikipedia.org/wiki/Duck_typing

https://en.wikipedia.org/wiki/Hindley%E2%80%93Milner_type_system

http://akgupta.ca/blog/2013/05/14/so-you-still-dont-understand-hindley-milner/

https://developer.apple.com/videos/wwdc2016/

Page 35: Swift internals

let swift(16)