The suggestion I've always made is the addition of extra fields in the transaction structure; and isn't a million miles from what you've suggested.
Namely: an unsigned parameter array. Then you add a couple of script operators for fetching from that array, e.g. OP_FETCHPARAMETER1, and you're done.
The parameter block would mostly be holding the signature; and given that it's not included in the input to the signature generator would make all that crazy manipulation that goes on in OP_CHECKSIG unnecessary.
It would be equally capable of storing a script hash though. It would be pretty easy to introduce operators to do:
- OP_HASHOFSCRIPTSIG
- OP_HASHOFPUBKEYSCRIPT
Or possibly some more generic operators for pulling out arbitrary bytes.
For example:
- OP_PUSH(OP_CODESEPARATOR)
- OP_FINDLASTOFINPUBKEYSCRIPT
- OP_HASHFROMINDEX
- OP_FETCHPARAMETER1
- OP_EQUALVERIFY
(I've been a bit slapdash, but you get the idea).