[swift-users] Indirectly calling functions through assembly

Joe Groff jgroff at apple.com
Mon Nov 28 13:37:33 CST 2016


> On Nov 26, 2016, at 5:20 PM, Krishna Mannem via swift-users <swift-users at swift.org> wrote:
> 
> I’ve been messing around with swift and trying to figure out the internals for fun. I’ve been running into a seg fault while running this gist (https://gist.github.com/krishnamannem/032aa7b568f82297ba2f88041518085d), the seg fault happens in the print(). 
> 
> Going through the execution with lldb I know the error is inside print and the only difference between the disassembled versions is some retain release stuff which I don’t think is the issue. I have very little experience with swift so you’ll have to excuse me if I’m totally screwing/mixing something up. Does anyone know what extra magic testing(x: () -> ()) { x() }  does to ensure it doesn’t segfault. 
> 
> Side note: I have replaced the print with a plain var _ = 1 + 1 and this worked just fine.
> 
> I ran this using :
> 
> Llvm-g++ -c func.S -o func.o
> Swiftc -g func.swift func.o

It appears that something about the Swift source that built `using_asm.S` is making the Swift compiler try to call `testing` as if it were a C function. You can see in the disassembly there that it's emitting a `_TTo` thunk for `hello` that really shouldn't be necessary. It'd be worth filing a bug about this, since I don't see any reason why your assembly version wouldn't work in this specific case. In the more general case, where `_test` may be passed a closure with captures, your `_test` function would need to pass the closure parameter context through to the invocation function too, something like:

mov %rdi, %rax
mov %rsi, %rdi
call *%rax

though `hello` is a top-level function without captures, so this shouldn't matter in this case.

-Joe


More information about the swift-users mailing list