Refactor our Runtime implementations to allow replacement parts
This branch introduces a CompoundRuntime type, which can be used to build a runtime out of its constituent parts, and refactors our individual to use CompoundRuntime objects internally.
Making this change serves two purposes.
First, it makes it easier for other people to implement Runtimes that replace only part of another Runtime: it would decrease the boilerplate needed for #235 (closed), for example.
Second, it will make it easier for us to implement Runtimes with multiple TLS backends (#86 (closed)) without running into combinatorial explosion.
Closes #255 (closed).