Fix crash when we pass too few args to a builtin taking inout params and we interp the prologue
Summary:
If we have a builtin taking inout params and we pass too few
arguments, an exception will get thrown. However, if we fail to JIT
the prologue, we'll use fcallHelper to set up the frame and call into
the interpreter to finish. One of the things that fcallHelper does is
write uninits to the ActRec and inout stack slots (because the JIT may
have elided the normal stores to them).
The calculation it was doing for the inout slots was incorrect. It was
assuming that we were guaranteed to have the exact number of required
arguments at this point. However, this check is actually done later,
in the interpreter. So, we'll assume we have the correct number of
inout slots on the stack, even thought we might not. As a result,
we'll write uninit to random things on the stack, including locals or
the previous ActRec. This becomes more obvious when locals are
compacted.
Fix this by instead calculating the correct number of inout slots for
the given number of arguments. Add a helper function to do this, as it
comes up in a few places.
Add a new intrinsic builtin to allow for a unit test to test this
easily.
Reviewed By: jano
Differential Revision:
D20949528
fbshipit-source-id:
34173ea6b8dd244d23da6dc0a51cbfe09d3ef5dc