compiler: Split out CondBranch codegen

This moves codegen support for conditional branches to its own
GenCondBranch object to reduce the size of the main GenPlanStep
function.
compiler: GC optimisations and fixes

- When flushing GC roots only flush values that will be GC rooted in
  both sides of the branch. This avoids a lot of useless rooting where a
  value will be discarded in both sides of the branch before the next GC
  barrier

- When building a conditional branch only the values that are live after
  *both* branches are valid. If a value is disposed of in only one branch
  it cannot be used as it may not have been properly GC rooted across a
  GC barrier. This prevents a crash where these invalid live temps
  persist after a branch and then end up in a GC slot later in execution
  and potentially cause a crash.

- If a value from outside a branch is used in only one side of the
  branch properly dispose of it on the other side of the branch. This
  reduces GC pressure in that branch due to values that are no longer
  used
compiler: More optimal (integer?) implementation

This directly tests for exact integers which allows us to use native
flonum comparisons in the else branch
stdlib: Implement asin, acos, atan, exp, log

These are just direct wrappers around the C standard library with simple
functional tests. This does not implement the two operand form of (log)
or (atan)