Generate properly synced catch block for IterInit
commit71a66a999b0bc17a7cbd3a6b7ffc17e0fc221fce
authorJan Oravec <jan@fb.com>
Thu, 19 Mar 2020 04:22:37 +0000 (18 21:22 -0700)
committerFacebook GitHub Bot <facebook-github-bot@users.noreply.github.com>
Thu, 19 Mar 2020 04:26:18 +0000 (18 21:26 -0700)
tree98aade5cee9b8b6fe470a584b18b57aa17bb4f36
parent4040fd1f732728bf890bc4ccec29c2404defc2d7
Generate properly synced catch block for IterInit

Summary:
IterInit bytecode discards a stack value containing the iterable and then emits
an IterInit IR opcode that consumes it. The problem is that there was no
exception stack boundary between these two operations, so we emitted a catch
block with an incorrectly synced stack offsets. This forced us to preserve the
iterable across the opcode, so that the catch block can sync it to the stack.
This did not cause any real issues until now because of super hacky fixup logic
that synced the SP properly, so the unwindier did not attempt to decref this
extra value. However, oulgen's unwinder improvements experience this issue and
free the iterable twice.

Fix this by syncing the boundary and removing the hacky fixup logic. I will try
to improve the enforcement of this situation in the next diff, which is likely
to catch more instances of this bug.

Reviewed By: ricklavoie, oulgen

Differential Revision: D20524184

fbshipit-source-id: 7d571115fd1f6aad293aa6c2b6edabc173dc6cd8
hphp/runtime/vm/jit/extra-data.h
hphp/runtime/vm/jit/irgen-iter.cpp
hphp/runtime/vm/jit/irlower-internal.cpp
hphp/runtime/vm/jit/irlower-iter.cpp
hphp/runtime/vm/jit/irlower.h