Indirectly calling functions through assembly


(Krishna Mannem) #1

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


(Joe Groff) #2

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

···

On Nov 26, 2016, at 5:20 PM, Krishna Mannem via swift-users <swift-users@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