diff options
author | Ayke van Laethem <[email protected]> | 2018-11-01 11:41:24 +0100 |
---|---|---|
committer | Ayke van Laethem <[email protected]> | 2018-11-01 11:41:24 +0100 |
commit | c7cf6f0e828258aed269b75840dfe111f71eef05 (patch) | |
tree | 544be00def416833237794708f045e842e8d2284 /docs | |
parent | 85d5fe7643107b67f57ced5928b6c59163072d48 (diff) | |
download | tinygo-c7cf6f0e828258aed269b75840dfe111f71eef05.tar.gz tinygo-c7cf6f0e828258aed269b75840dfe111f71eef05.zip |
docs: move calling convention documentation here
Diffstat (limited to 'docs')
-rw-r--r-- | docs/internals.rst | 72 |
1 files changed, 66 insertions, 6 deletions
diff --git a/docs/internals.rst b/docs/internals.rst index 836be2b26..e401465a0 100644 --- a/docs/internals.rst +++ b/docs/internals.rst @@ -79,12 +79,12 @@ interface function pointer A function pointer has two representations: a literal function pointer and a - tuple of ``{context, function pointer}``. Which representation is chosen - depends on the AnalyseFunctionPointers pass in `ir/passes.go - <https://github.com/aykevl/tinygo/blob/master/ir/passes.go>`_: it tries to - use a raw function pointer but will use a function pointer with context if - there is a closure or bound method somewhere in the program with the exact - same signature. + fat function pointer in the form of ``{context, function pointer}``. Which + representation is chosen depends on the AnalyseFunctionPointers pass in + `ir/passes.go <https://github.com/aykevl/tinygo/blob/master/ir/passes.go>`_: + it tries to use a raw function pointer but will use a fat function pointer + if there is a closure or bound method somewhere in the program with the + exact same signature. goroutine A goroutine is a linked list of `LLVM coroutines @@ -101,6 +101,66 @@ goroutine consumption. +Calling convention +------------------ + +Go uses a stack-based calling convention and passes a pointer to the argument +list as the first argument in the function. There were/are `plans to switch to a +register-based calling convention <https://github.com/golang/go/issues/18597>`_ +but they're now on hold. + +.. highlight:: llvm + +TinyGo, however, uses a register based calling convention. In fact it is +somewhat compatible with the C calling convention but with a few quirks: + + * Struct parameters are split into separate arguments, if the number of fields + (after flattening recursively) is 3 or lower. This is similar to the `Swift + calling convention + <https://github.com/apple/swift/blob/master/docs/CallingConvention.rst#physical-conventions>`_. + In the case of TinyGo, the size of each field does not matter, a field can + even be an array. :: + + {i8*, i32} -> i8*, i32 + {{i8*, i32}, i16} -> i8*, i32, i16 + {{i64}} -> i64 + {} -> + {i8*, i32, i8, i8} -> {i8*, i32, i8, i8} + {{i8*, i32, i8}, i8} -> {i8*, i32, i8, i8} + + Note that all native Go data types that are lowered to aggregate types in + LLVM are expanded this way: ``string``, slices, interfaces, and fat function + pointers. This avoids some overhead in the C calling convention and makes + the work of the LLVM optimizers easier. + + * Some functions have an extra context parameter appended at the end of the + argument list. This only happens when both of these conditions hold: + + * The address of the function is taken, for example when passing the + function as function pointer to another function or storing it in a + global variable. + + * This function or another function somewhere in the compiled code has the + exact same signature and is used in a closure or bound method. Signature + matching is very strict: it is based on Go types including named types + and return types, although parameter names or the function name itself + are not included in the match. + + Whether a function needs this is determined by `FunctionNeedsContext + <https://godoc.org/github.com/aykevl/tinygo/ir#Program.FunctionNeedsContext>`_, + which bases itself on analysis done by AnalyseFunctionPointers. + + * Blocking functions have a coroutine pointer prepended to the argument list, + see `src/runtime/scheduler.go + <https://github.com/aykevl/tinygo/blob/master/src/runtime/scheduler.go>`_ + for details. Whether a function is blocking is determined by the + AnalyseBlockingRecursive pass. + +This calling convention may change in the future. Changes will be documented +here. However, even though it may change, it is expected that function +signatures that only contain integers and pointers will remain stable. + + Pipeline -------- |