Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Swift NSObject subclass
import Foundation
class FooFun {
@objc
func bat() {
println("bat")
}
}
class Foo :NSObject {
var internal:FooFun = FooFun()
func bar() {
println("Swift Hello, World!")
}
@objc
func baz() {
println("baz")
}
override func doesNotRecognizeSelector(aSelector: Selector) {
println("NOPE!")
}
override func forwardingTargetForSelector(aSelector: Selector) -> AnyObject! {
return internal
}
// NSInvocation is un-available. Not sure why!
// override func forwardInvocation(anInvocation: NSInvocation!) {}
}
let f = Foo.init()
let a:AnyObject = f
a.bar() // This is done via objc_msgSend, since Foo is now a subclass of NSObject
a.bat() // Compiles, hits 'doesNotRecognizeSelector' and then forwards on to FooFun
// Comment out the @objc in FooFun, and the app will blow up.
a.baz() // Calls 'objc_msgSend'
a.bat?() // The optional cast does not detect bat and does not run. Note below
/* The interesting bit that I don't understand is what the dis-assembler is showing.
* I'd guess that this is swift creating an NSInvocation?
0x100001989: movq 0x4db0(%rip), %rsi ; "bat"
0x100001990: movq -0xd8(%rbp), %rdi
0x100001997: movq %rax, -0xe0(%rbp)
0x10000199e: callq 0x100004cb8 ; symbol stub for: swift_objcRespondsToSelector
0x1000019a3: testb $0x1, %al
0x1000019a5: jne 0x1000019ac ; top_level_code + 316 at main.swift:46
0x1000019a7: jmp 0x100001a9a ; top_level_code + 554 at main.swift:46
0x1000019ac: movq -0xd8(%rbp), %rdi
0x1000019b3: callq 0x100004dae ; symbol stub for: objc_retain
0x1000019b8: leaq 0x4951(%rip), %rdi ; metadata7
0x1000019bf: addq $0x10, %rdi
0x1000019c6: movabsq $0x18, %rsi
0x1000019d0: movabsq $0x7, %rdx
0x1000019da: movq %rax, -0xe8(%rbp)
0x1000019e1: callq 0x100004c8e ; symbol stub for: swift_allocObject
0x1000019e6: leaq 0x4943(%rip), %rdx ; metadata9
0x1000019ed: addq $0x10, %rdx
0x1000019f4: movabsq $0x20, %rsi
0x1000019fe: movabsq $0x7, %rdi
0x100001a08: movq -0xd8(%rbp), %rcx
0x100001a0f: movq %rcx, 0x10(%rax)
0x100001a13: movq %rdi, -0xf0(%rbp)
0x100001a1a: movq %rdx, %rdi
0x100001a1d: movq -0xf0(%rbp), %rdx
0x100001a24: movq %rax, -0xf8(%rbp)
0x100001a2b: callq 0x100004c8e ; symbol stub for: swift_allocObject
0x100001a30: movq 0x45f9(%rip), %rcx ; (void *)0x000000010016cc20: direct type metadata for ()
0x100001a37: addq $0x8, %rcx
0x100001a3e: leaq -0x90(%rbp), %rdx
0x100001a45: leaq 0xd74(%rip), %rsi ; partial apply forwarder for reabstraction thunk helper from @callee_owned () -> (@unowned ()) to @callee_owned (@in ()) -> (@out ()) with unmangled suffix "10" at main.swift
0x100001a4c: leaq 0xcfd(%rip), %rdi ; partial apply ObjC forwarder
0x100001a53: movq %rdi, 0x10(%rax)
0x100001a57: movq -0xf8(%rbp), %rdi
0x100001a5e: movq %rdi, 0x18(%rax)
0x100001a62: movq %rsi, -0x90(%rbp)
0x100001a69: movq %rax, -0x88(%rbp)
0x100001a70: movq %rcx, %rdi
0x100001a73: movq %rcx, %rsi
0x100001a76: movq %rdx, -0x100(%rbp)
0x100001a7d: callq 0x100004cac ; symbol stub for: swift_getFunctionTypeMetadata
0x100001a82: leaq -0x60(%rbp), %rcx
0x100001a86: movq %rcx, %rdi
0x100001a89: movq -0x100(%rbp), %rsi
0x100001a90: movq %rax, %rdx
0x100001a93: callq 0x100002820 ; Swift._injectValueIntoImplicitlyUnwrappedOptional <A>(A) -> Swift.ImplicitlyUnwrappedOptional<A>
0x100001a98: jmp 0x100001ac1 ; top_level_code + 593 at main.swift:46
0x100001a9a: movq 0x458f(%rip), %rax ; (void *)0x000000010016cc20: direct type metadata for ()
0x100001aa1: addq $0x8, %rax
0x100001aa7: movq %rax, %rdi
0x100001aaa: movq %rax, %rsi
0x100001aad: callq 0x100004cac ; symbol stub for: swift_getFunctionTypeMetadata
0x100001ab2: leaq -0x60(%rbp), %rsi
0x100001ab6: movq %rsi, %rdi
0x100001ab9: movq %rax, %rsi
0x100001abc: callq 0x100002960 ; Swift._injectNothingIntoImplicitlyUnwrappedOptional <A>() -> Swift.ImplicitlyUnwrappedOptional<A>
0x100001ac1: movq 0x4568(%rip), %rax ; (void *)0x000000010016cc20: direct type metadata for ()
0x100001ac8: addq $0x8, %rax
0x100001ace: leaq -0x48(%rbp), %rcx
0x100001ad2: movq -0x60(%rbp), %rdx
0x100001ad6: movq -0x58(%rbp), %rsi
0x100001ada: movb -0x50(%rbp), %dil
0x100001ade: movq %rsi, -0x40(%rbp)
0x100001ae2: movq %rdx, -0x48(%rbp)
0x100001ae6: andb $0x1, %dil
0x100001aea: movb %dil, -0x38(%rbp)
0x100001aee: movq %rax, %rdi
0x100001af1: movq %rax, %rsi
0x100001af4: movq %rcx, -0x108(%rbp)
0x100001afb: callq 0x100004cac ; symbol stub for: swift_getFunctionTypeMetadata
0x100001b00: movq 0x4509(%rip), %rdi ; (void *)0x00000001001725c0: direct generic type metadata pattern for Swift.ImplicitlyUnwrappedOptional
0x100001b07: movq %rax, %rsi
0x100001b0a: callq 0x100004cb2 ; symbol stub for: swift_getGenericMetadata1
0x100001b0f: movq -0x108(%rbp), %rdi
0x100001b16: movq %rax, %rsi
0x100001b19: callq 0x1000029f0 ; Swift._doesImplicitlyUnwrappedOptionalHaveValue <A>(@inout Swift.ImplicitlyUnwrappedOptional<A>) -> Builtin.Int1
0x100001b1e: testb $0x1, %al
0x100001b20: jne 0x100001b57 ; top_level_code + 743 at main.swift:46
0x100001b22: movq -0xd8(%rbp), %rdi
0x100001b29: callq 0x100004da8 ; symbol stub for: objc_release
0x100001b2e: leaq -0x48(%rbp), %rdi
0x100001b32: movb -0x38(%rbp), %al
0x100001b35: testb %al, %al
0x100001b37: movq %rdi, -0x110(%rbp)
0x100001b3e: jne 0x100001b52 ; top_level_code + 738 at main.swift:46
0x100001b40: jmp 0x100001b42 ; top_level_code + 722 at main.swift:46
0x100001b42: movq -0x110(%rbp), %rax
0x100001b49: movq 0x8(%rax), %rdi
0x100001b4d: callq 0x100004cbe ; symbol stub for: swift_release
0x100001b52: jmp 0x100001c83 ; top_level_code + 1043 at main.swift:46
0x100001b57: movq 0x44d2(%rip), %rax ; (void *)0x000000010016cc20: direct type metadata for ()
0x100001b5e: addq $0x8, %rax
0x100001b64: leaq -0x48(%rbp), %rcx
0x100001b68: movq %rax, %rdi
0x100001b6b: movq %rax, %rsi
0x100001b6e: movq %rcx, -0x118(%rbp)
0x100001b75: callq 0x100004cac ; symbol stub for: swift_getFunctionTypeMetadata
0x100001b7a: leaq -0x80(%rbp), %rcx
0x100001b7e: movq %rcx, %rdi
0x100001b81: movq -0x118(%rbp), %rsi
0x100001b88: movq %rax, %rdx
0x100001b8b: callq 0x100002a30 ; Swift._getImplicitlyUnwrappedOptionalValue <A>(Swift.ImplicitlyUnwrappedOptional<A>) -> A
0x100001b90: leaq 0x4739(%rip), %rax ; metadata2
0x100001b97: addq $0x10, %rax
0x100001b9d: movabsq $0x20, %rsi
0x100001ba7: movabsq $0x7, %rdx
0x100001bb1: movq -0x80(%rbp), %rcx
0x100001bb5: movq -0x78(%rbp), %rdi
0x100001bb9: movq %rdi, -0x120(%rbp)
0x100001bc0: movq %rax, %rdi
0x100001bc3: movq %rcx, -0x128(%rbp)
0x100001bca: callq 0x100004c8e ; symbol stub for: swift_allocObject
0x100001bcf: leaq 0x471a(%rip), %rcx ; metadata5
0x100001bd6: addq $0x10, %rcx
0x100001bdd: movabsq $0x20, %rsi
0x100001be7: movabsq $0x7, %rdx
0x100001bf1: movq -0x128(%rbp), %rdi
0x100001bf8: movq %rdi, 0x10(%rax)
0x100001bfc: movq -0x120(%rbp), %r8
0x100001c03: movq %r8, 0x18(%rax)
0x100001c07: movq %rcx, %rdi
0x100001c0a: movq %rax, -0x130(%rbp)
0x100001c11: callq 0x100004c8e ; symbol stub for: swift_allocObject
0x100001c16: movq 0x4413(%rip), %rcx ; (void *)0x000000010016cc20: direct type metadata for ()
0x100001c1d: addq $0x8, %rcx
0x100001c24: leaq -0x30(%rbp), %rdx
0x100001c28: leaq 0xa81(%rip), %rsi ; partial apply forwarder for reabstraction thunk helper from @callee_owned () -> (@unowned ()) to @callee_owned (@in ()) -> (@out ()) at main.swift
0x100001c2f: leaq 0x9fa(%rip), %rdi ; partial apply forwarder for reabstraction thunk helper from @callee_owned (@in ()) -> (@out ()) to @callee_owned () -> (@unowned ()) with unmangled suffix "3" at main.swift
0x100001c36: movq %rdi, 0x10(%rax)
0x100001c3a: movq -0x130(%rbp), %rdi
0x100001c41: movq %rdi, 0x18(%rax)
0x100001c45: movq %rsi, -0x30(%rbp)
0x100001c49: movq %rax, -0x28(%rbp)
0x100001c4d: movq %rcx, %rdi
0x100001c50: movq %rcx, %rsi
0x100001c53: movq %rdx, -0x138(%rbp)
0x100001c5a: callq 0x100004cac ; symbol stub for: swift_getFunctionTypeMetadata
0x100001c5f: leaq -0x20(%rbp), %rcx
0x100001c63: movq %rcx, %rdi
0x100001c66: movq -0x138(%rbp), %rsi
0x100001c6d: movq %rax, %rdx
0x100001c70: callq 0x100002c00 ; Swift._injectValueIntoOptional <A>(A) -> Swift.Optional<A>
0x100001c75: movq -0xd8(%rbp), %rdi
0x100001c7c: callq 0x100004da8 ; symbol stub for: objc_release
0x100001c81: jmp 0x100001caa ; top_level_code + 1082 at main.swift:46
0x100001c83: movq 0x43a6(%rip), %rax ; (void *)0x000000010016cc20: direct type metadata for ()
0x100001c8a: addq $0x8, %rax
0x100001c90: movq %rax, %rdi
0x100001c93: movq %rax, %rsi
0x100001c96: callq 0x100004cac ; symbol stub for: swift_getFunctionTypeMetadata
0x100001c9b: leaq -0x20(%rbp), %rsi
0x100001c9f: movq %rsi, %rdi
0x100001ca2: movq %rax, %rsi
0x100001ca5: callq 0x100002ca0 ; Swift._injectNothingIntoOptional <A>() -> Swift.Optional<A>
0x100001caa: movq 0x437f(%rip), %rax ; (void *)0x000000010016cc20: direct type metadata for ()
0x100001cb1: addq $0x8, %rax
0x100001cb7: leaq -0x20(%rbp), %rcx
0x100001cbb: movq %rax, %rdi
0x100001cbe: movq %rax, %rsi
0x100001cc1: movq %rcx, -0x140(%rbp)
0x100001cc8: callq 0x100004cac ; symbol stub for: swift_getFunctionTypeMetadata
0x100001ccd: movq 0x4344(%rip), %rdi ; (void *)0x0000000100172c60: direct generic type metadata pattern for Swift.Optional
0x100001cd4: movq %rax, %rsi
0x100001cd7: callq 0x100004cb2 ; symbol stub for: swift_getGenericMetadata1
0x100001cdc: movq -0x140(%rbp), %rdi
0x100001ce3: movq %rax, %rsi
0x100001ce6: callq 0x100002cd0 ; Swift._doesOptionalHaveValue <A>(@inout Swift.Optional<A>) -> Builtin.Int1
0x100001ceb: testb $0x1, %al
0x100001ced: jne 0x100001d06 ; top_level_code + 1174 at main.swift:46
0x100001cef: movb -0x10(%rbp), %al
0x100001cf2: testb %al, %al
0x100001cf4: jne 0x100001d01 ; top_level_code + 1169 at main.swift:46
0x100001cf6: jmp 0x100001cf8 ; top_level_code + 1160 at main.swift:46
0x100001cf8: movq -0x18(%rbp), %rdi
0x100001cfc: callq 0x100004cbe ; symbol stub for: swift_release
0x100001d01: jmp 0x100001dba ; top_level_code + 1354 at main.swift:46
0x100001d06: movq 0x4323(%rip), %rax ; (void *)0x000000010016cc20: direct type metadata for ()
0x100001d0d: addq $0x8, %rax
0x100001d13: leaq -0x20(%rbp), %rcx
0x100001d17: movq %rax, %rdi
0x100001d1a: movq %rax, %rsi
0x100001d1d: movq %rcx, -0x148(%rbp)
0x100001d24: callq 0x100004cac ; symbol stub for: swift_getFunctionTypeMetadata
0x100001d29: leaq -0x70(%rbp), %rcx
0x100001d2d: movq %rcx, %rdi
0x100001d30: movq -0x148(%rbp), %rsi
0x100001d37: movq %rax, %rdx
0x100001d3a: callq 0x100002de0 ; Swift._getOptionalValue <A>(Swift.Optional<A>) -> A
0x100001d3f: leaq 0x456a(%rip), %rax ; metadata
0x100001d46: addq $0x10, %rax
0x100001d4c: movabsq $0x20, %rsi
0x100001d56: movabsq $0x7, %rdx
0x100001d60: movq -0x70(%rbp), %rcx
0x100001d64: movq -0x68(%rbp), %rdi
0x100001d68: movq %rdi, -0x150(%rbp)
0x100001d6f: movq %rax, %rdi
0x100001d72: movq %rcx, -0x158(%rbp)
0x100001d79: callq 0x100004c8e ; symbol stub for: swift_allocObject
0x100001d7e: movq -0x158(%rbp), %rcx
0x100001d85: movq %rcx, 0x10(%rax)
0x100001d89: movq -0x150(%rbp), %rdx
0x100001d90: movq %rdx, 0x18(%rax)
0x100001d94: movq %rax, %rdi
0x100001d97: callq 0x1000025b0 ; partial apply forwarder for reabstraction thunk helper from @callee_owned (@in ()) -> (@out ()) to @callee_owned () -> (@unowned ()) at main.swift
0x100001d9c: movq 0x428d(%rip), %rax ; (void *)0x000000010016cc20: direct type metadata for ()
0x100001da3: addq $0x8, %rax
0x100001da9: leaq -0x8(%rbp), %rcx
0x100001dad: movq %rcx, %rdi
0x100001db0: movq %rax, %rdx
0x100001db3: callq 0x100002c00 ; Swift._injectValueIntoOptional <A>(A) -> Swift.Optional<A>
0x100001db8: jmp 0x100001dd6 ; top_level_code + 1382 at main.swift
0x100001dba: movq 0x426f(%rip), %rax ; (void *)0x000000010016cc20: direct type metadata for ()
0x100001dc1: addq $0x8, %rax
0x100001dc7: leaq -0x8(%rbp), %rcx
0x100001dcb: movq %rcx, %rdi
0x100001dce: movq %rax, %rsi
0x100001dd1: callq 0x100002ca0 ; Swift._injectNothingIntoOptional <A>() -> Swift.Optional<A>
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment