Set Exception Stack Boundary before failing StructDictMutation
commit6053764d301efe88ad7da5c2834788cb3ffd1a4c
authorKaty Voor <voork@fb.com>
Fri, 10 Dec 2021 10:45:50 +0000 (10 02:45 -0800)
committerFacebook GitHub Bot <facebook-github-bot@users.noreply.github.com>
Fri, 10 Dec 2021 10:47:27 +0000 (10 02:47 -0800)
tree249862910ad9346892f1d4ef8dbceeb62a170a54
parent23601fa25a38efe7b7ab769b71aad4b5f6b45d92
Set Exception Stack Boundary before failing StructDictMutation

Summary:
Previously we cored before we threw OOB errors for defining dim ops for StructDicts. This was because after we COW, we stored the copy to the MBR which could be a stack location, and this triggered the "catch block used after writing to stack" error.
```
-------------------------------Assertion Message--------------------------------
catch block used after writing to stack
     inst: ThrowOutOfBounds t186:CountedDict=StructDict<?"qe_disabled":Dict,?"qe_enabled":Dict>, "qe_disabled"

-------------------------------Assertion Failure--------------------------------
hphp/runtime/vm/jit/irgen.cpp:34: void HPHP::jit::irgen::{anonymous}::check_catch_stack_state(HPHP::jit::irgen::IRGS&, const HPHP::jit::IRInstruction*): assertion `!env.irb->fs().stackModified()' failed.
--------------------------------------IRGS--------------------------------------
+---------------------------------------- 2 stack element(s): -----------------------------------------+
|  0: (159) 1 = DefConst<Int<1>>                                                                       |
|  1: CountedDict=StructDict<?"qe_disabled":Dict,?"qe_enabled":Dict>                                   |
+------------------------------------------------------------------------------------------------------+

+--------------------------------------------- 5 local(s) ---------------------------------------------+
|  0: (584) t173:Dict=StructDict<?"normal":Dict,?"int":Dict,?"normvector":Dict,?"tags":Dict,?"denorm":Dict> = CheckType<ArrLike=StructDict<?"normal":Dict,?"int":Dict,?"normvector":Dict,?"tags":Dict,?"denorm":Dict>> t170:Dict -> B228<Unlikely> |
|  1: Cell                                                                                             |
|  2: Cell                                                                                             |
|  3: (26) Uninit = DefConst<Uninit>                                                                   |
|  4: Str                                                                                              |
+------------------------------------------------------------------------------------------------------+

```

Additionally, there was a bug in `emitSet()` where the `cond()` had lambdas that called `finish()->mfinalImpl()` which result in the stack offset going negative. I pulled the stack modifying operations out of the `cond()`.

Reviewed By: ricklavoie

Differential Revision: D32977588

fbshipit-source-id: f6e58efdec01c3e2d40dbfd1b1e176852edfb4c5
hphp/runtime/vm/jit/irgen-bespoke.cpp
hphp/test/slow/dict/struct-dict-mutate-bug.php [new file with mode: 0644]
hphp/test/slow/dict/struct-dict-mutate-bug.php.expectf [new file with mode: 0644]