|
From: Kevin K. <kev...@gm...> - 2018-01-10 16:21:43
|
I implemented last night (on the 'inline' branch) the 'initException'
sequence that Donal suggested, and found that it worked quite well
indeed (once I got rid of a misplaced close-brace that took forever to
track down). Right now, it's implemented only for 'invokeExpanded'
with wrong numbers of arguments, but I can do a fast follow-on for
'invoke'.
As I look at it, however, I am realizing that the approach I'm using
(generate terrible code and let optimization clean it up) is not
threading 'jumpMaybe' correctly, because the available type
information doesn't inform it that the result of the 'initException'
always fails. This winds up having a cascading effect in code quality,
I'm afraid.
Would it cause code generation tremendous heartburn if 'initException'
were to return a simple FAIL (rather than a FAIL STRING) if its return
code argument is {literal 1}? That would make life much easier for the
optimizer. I can generate just the 'initException', and code in a
subsequent pass
(https://core.tcl.tk/tclquadcode/artifact?ln=491-519&name=78060ce0e981c3c7)
will tidy up the 'jumpMaybe' and detect that the following 'jump' is
unreachable.
If this isn't feasible, I can still deal with it, by rewriting the
entire code burst
moveToCallFrame cf2 cr1 {literal name1} {var value11} ...
invoke res1 cf2 proc args...
retrieveResult res2 res1
extractCallFrame cf3 res1
moveFromCallFrame {var value12} cf3 {literal name1}
...
jumpMaybe {bb fail} res2
jump {bb ok}
rather than just the [invoke], but that's rather more work.
(We're also most likely going to have to come up with a type calculus
for break, continue, return, but that's not today's problem.)
|