From: Christophe R. <cs...@ca...> - 2007-07-01 10:20:27
|
Christopher Laux <chr...@we...> writes: > After a bit of experimenting, I've now managed to build a "demo" of the bug: > > (defun bug-demo-sub () (format t "test") nil) > (defun bug-demo-main () > (multiple-value-bind (a b c d e f g h) > (bug-demo-sub) > (if a (+ a b c d e f g h) t))) > > Note that returning seven values works just fine. It's also necessary to > have the format statement in there, (print "test") won't lead to the bug! > > I can't figure out what it means, but there are obviously many > work-arounds for me. Hopefully this is a tip-off to someone who knows > the relevant code. I for one am really looking forward to hearing an > explanation ;) Now we're cooking! This information is enough to identify the faulty code segment; it is in the backend definition for the x86-64 platform, for the operation of "defaulting unknown values": when multiple values are bound, as by your multiple-value-bind, if insufficient values are supplied by the calling function then the system must default the remaining bindings to NIL. Now, the clever x86-64 wizards have spent their time optimizing the section in question; take a look at src/compiler/x86-64/call.lisp, at the VOP definition for DEFAULT-UNKNOWN-VALUES. There are several different codepaths there, to optimize the generated code for space in various different circumstances. Unfortunately, it would appear that the code generated for the last branch (when there are more than seven values needed, as in your test case) is wonky in some fashion. (I wouldn't expect that fixing this is very hard, but first I need to page back in my understanding of x86 assembler and the sbcl calling convention. It's been a while... :-) Cheers, Christophe |