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

Swift fun(ctions)

Sponsored · Your Podcast. Everywhere. Effortlessly. Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.

Swift fun(ctions)

Lightning talk at dotSwift 2014. Shows how we can utilise knowledge of the memory layout for functions to dynamically call into C and call Swift from C.

Avatar for Boris Bügling

Boris Bügling

February 06, 2015
Tweet

More Decks by Boris Bügling

Other Decks in Technology

Transcript

  1. WHAT IS A FUNCTION? func add(a: Int, b: Int) ->

    Int { return a + b } let f = add f(1, 2) // $R0: Int = 3 println(f) // (Function)
  2. NAME MANGLING $ xcrun swiftc func.swift $ nm -g func

    0000000100000f10 T __TF4func3addFTSiSi_Si [...] $ xcrun swift-demangle __TF4func3addFTSiSi_Si _TF4func3addFTSiSi_Si ---> func.add (Swift.Int, Swift.Int) -> Swift.Int
  3. MEMORY LAYOUT ▸ 8 bytes => Pointer to _TPA__TTRXFo_dSidSi_dSi_XFo_iTSiSi__iSi_ ▸

    8 bytes => Pointer to struct _TPA__TTRXFo_dSidSi_dSi_XFo_iTSiSi__iSi_ ---> partial apply forwarder for reabstraction thunk helper [...]
  4. MEMORY LAYOUT ▸ 16 bytes => Swift object ▸ 8

    bytes => Pointer to _TF6memory3addFTSiSi_Si Function pointer !
  5. import Darwin @asmname("floor") func my_floor(dbl: Double) -> Double println(my_floor(6.7)) let

    handle = dlopen(nil, RTLD_NOW) let pointer = COpaquePointer(dlsym(handle, "ceil")) typealias FunctionType = (Double) -> Double
  6. struct f_trampoline { [...] } struct function_obj { [...] }

    let orig = unsafeBitCast(my_floor, f_trampoline.self) let new = f_trampoline(prototype: orig, new_fp: pointer) let my_ceil = unsafeBitCast(new, FunctionType.self) println(my_ceil(6.7))