We can't give you real feedback until you push.
But best guess based solely on what you wrote here, in_play() is too restrictive for what you're trying to check for - it'll either break cards that return permanents from the stack to their owners' hands, like
Remand and
Unsubstantiate, if you do it early, or not actually fix this, if you do it late.
You don't want to see if what you're bouncing is on the battlefield to see if an object can be returned to its owner's hand; you want to see if the object still exists - that is, card_instance_t::internal_card_id >= 0 - and return immediately if it doesn't. in_play() checks that and also that it's specifically on the battlefield. You
do want to check in_play() at other points in that function, too, before dispatching TRIGGER_LEAVE_PLAY and TRIGGER_BOUNCE_PERMANENT and the awful hacks at the end for specific cards.
You should also be aware that, like discard() and discard_card(), the executable version of bounce_permanent() was never overridden to use the C one, and no effort was made to ensure that all calls to it were replaced. Whimsy, at a minimum, still uses all three.