Fix crash when we pass too few args to a builtin taking inout params and we interp...
commitcd7a7636ed3231f038556646446ab590d3114c9f
authorRick Lavoie <rlavoie@fb.com>
Fri, 10 Apr 2020 02:35:10 +0000 (9 19:35 -0700)
committerFacebook GitHub Bot <facebook-github-bot@users.noreply.github.com>
Fri, 10 Apr 2020 02:37:38 +0000 (9 19:37 -0700)
treea459324214fd7c3da08e4dc69d0f510fdc02fd9d
parent7b4dd5f66d73a33d73f4940f3a755b040cc8ffa9
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
hphp/runtime/ext/std/ext_std_intrinsics.cpp
hphp/runtime/ext/std/ext_std_intrinsics.php
hphp/runtime/vm/bytecode.cpp
hphp/runtime/vm/func.cpp
hphp/runtime/vm/func.h
hphp/runtime/vm/jit/unique-stubs.cpp
hphp/test/slow/inout/builtin-few-args-prologue.php [new file with mode: 0644]
hphp/test/slow/inout/builtin-few-args-prologue.php.expect [new file with mode: 0644]
hphp/test/slow/inout/builtin-few-args-prologue.php.opts [new file with mode: 0644]