Re: [perl #55842] [BUG] empty .const .String broken
chromatic a écrit : On Tuesday 08 July 2008 02:36:37 François PERRAD via RT wrote: This bug starts with r28354 (cache string). The cache don't handle empty string. Now, in Pipp (PHP), an empty string is used to stringify boolean False. // languages/pipp/src/pmc/phpboolean.pmc STRING* get_string() { if (PMC_int_val(SELF)) return const_string(INTERP, 1); else return const_string(INTERP, ); } Instead of an empty string, I obtain another cached string like MD2, PhpUndef, ... I can't reproduce that with this test case: .loadlib 'php_group' .sub 'main' :main .local pmc true, false true = new 'PhpBoolean' false = new 'PhpBoolean' true = 1 false = 0 $S0 = true say $S0 $S0 = false say $S0 .end On windows, r29191, with this test, I obtain : D:\fperrad\Parrot\trunk\languages\pippparrot bool.pir 1 Php D:\fperrad\Parrot\trunk\languages\pipp and with a Lua PMC test D:\fperrad\Parrot\trunk\languages\luaperl -I../../lib t/pmc/string.t 1..13 ok 1 - check inheritance ok 2 - check interface ok 3 - check name ok 4 - check get_bool ok 5 - check logical_not ok 6 - check embedded zero ok 7 - check HLL ok 8 - check HLL (autoboxing) ok 9 - check HLL .const not ok 10 - .const empty string # Failed test '.const empty string' # at t/pmc/string.t line 196. # got: '¤ # 1 # ' # expected: ' # 1 # ' ok 11 - check tostring ok 12 - check tonumber ok 13 - check tobase # Looks like you failed 1 test of 13. I shaw the same behavior on Xubuntu 8.04 (r29194). But I notice that this issue is random (disappear or re-appear after an update re-compilation). And when I revert all modifications in src/string.c since r28354, all is OK. François. Do you have PIR which demonstrates it? -- c
Re: [perl #55842] [BUG] empty .const .String broken
François Perrad schrieb: chromatic a écrit : On Tuesday 08 July 2008 02:36:37 François PERRAD via RT wrote: This bug starts with r28354 (cache string). The cache don't handle empty string. Now, in Pipp (PHP), an empty string is used to stringify boolean False. // languages/pipp/src/pmc/phpboolean.pmc STRING* get_string() { if (PMC_int_val(SELF)) return const_string(INTERP, 1); else return const_string(INTERP, ); } Instead of an empty string, I obtain another cached string like MD2, PhpUndef, ... I can't reproduce that with this test case: .loadlib 'php_group' .sub 'main' :main .local pmc true, false true = new 'PhpBoolean' false = new 'PhpBoolean' true = 1 false = 0 $S0 = true say $S0 $S0 = false say $S0 .end On windows, r29191, with this test, I obtain : D:\fperrad\Parrot\trunk\languages\pippparrot bool.pir 1 Php D:\fperrad\Parrot\trunk\languages\pipp and with a Lua PMC test D:\fperrad\Parrot\trunk\languages\luaperl -I../../lib t/pmc/string.t 1..13 ok 1 - check inheritance ok 2 - check interface ok 3 - check name ok 4 - check get_bool ok 5 - check logical_not ok 6 - check embedded zero ok 7 - check HLL ok 8 - check HLL (autoboxing) ok 9 - check HLL .const not ok 10 - .const empty string # Failed test '.const empty string' # at t/pmc/string.t line 196. # got: '¤ # 1 # ' # expected: ' # 1 # ' ok 11 - check tostring ok 12 - check tonumber ok 13 - check tobase # Looks like you failed 1 test of 13. I shaw the same behavior on Xubuntu 8.04 (r29194). But I notice that this issue is random (disappear or re-appear after an update re-compilation). I made the same experience under Linux. This misfeature appears and disappears after making arbitrary changes. Regards, Bernhard
Re: [perl #56398] [BUG] lexical inner scope always keeps first lexpad (or something)
On Wed, Jul 09, 2008 at 01:27:29AM -0400, Bob Rogers wrote: What foo should do is create a closure and call that: .const .Sub inner = 'inner' inner = newclosure inner inner() If I understand what you're saying, and then take it to what I see as its ultimate conclusion, you're basically claiming that every call to a subroutine involving lexicals requires a newclosure op. Consider: { my $x = 1; sub foo() { say $x; } foo(); } In effect this is little different from having 'foo' as an immediate block. If we now say that a newclosure op is required to invoke 'foo', then that means that the 'foo()' HLL subroutine has to be generated as: .local pmc $P0 $P0 = find_name_not_null 'foo' $P0 = newclosure $P0 $P0() Of course, for any given subroutine call like 'foo()', the compiler tools can't be certain at compile time that 'foo' is in fact a Closure PMC, so we really have to generate: $P0 = find_name_not_null 'foo' $I0 = isa $P0, 'Closure' unless $I0 goto xyz $P0 = newclosure $P0 xyz: $P0() That 'isa' step presents a bad design smell to me -- why should we have to test every sub for Closure-ness prior to invoking it? It all gets worse if I have something like: .sub 'abc' :multi('Integer') ... .end .sub 'abc' :multi('String') :outer('xyz') ... .end One of these is a Sub PMC, the other is a Closure PMC, and the thing that is stored under symbol 'abc' is neither -- that's a MultiSub PMC. I'm fairly certain I can't do newclosure on the MultiSub PMC. In fact, the caller doesn't have any way of knowing which sub is going to be invoked without actually invoking it, so we really can't do a 'newclosure' on it. Ultimately I think that Closure PMCs need to be smart enough to take a newclosure if they need one at the time they're invoked, rather than trying to place that burden on the caller. (Note that I'm not arguing that the current implementation is correct -- I'm just describing what I think a correct implementation will need to do.) I also think we probably still need to have a newclosure opcode available to allow PIR to explicitly say when to take a closure, but I don't think it should be required in the PIR generated for every HLL subroutine invocation. [...] It may be possible to rescue Patrick's desired behavior by keeping track of whether the outer_sub was initialized by newclosure or not. My 'desired behavior' is simply that we have something that works. :-) But I suspect that this means that closure PMCs will have to keep track of whether they've already been newclosured. Personally, I'd prefer if it were always an error to call a closure sub directly; implicitly initializing the outer context is bad enough, but re-initializing it is worse. (But we've had this discussion before [1], and I was not persuasive.) Given the examples I listed above, I think we _have_ to provide a way for Closure PMCs to be invoked directly from PIR, and then either the Closure PMC vtable_invoke method or IMCC performs whatever context initialization and/or fixups that are needed to have everything work. (Also, a reminder that whatever we do to fix this ticket has to keep RT #56184 working as well. :-) Pm
Re: [perl #56398] [BUG] lexical inner scope always keeps first lexpad (or something)
[typo clarification] On Wed, Jul 09, 2008 at 08:25:52AM -0500, Patrick R. Michaud wrote: [...] If we now say that a newclosure op is required to invoke 'foo', then that means that the 'foo()' HLL subroutine has to be generated as: .local pmc $P0 $P0 = find_name_not_null 'foo' $P0 = newclosure $P0 $P0() That should read ...that the 'foo()' HLL subroutine *call* has to be... Pm
[perl #56694] [PATCH] nullptr segfault in closure.pmc
Since the introduction of :lexid in PCT, the code generation in Lua is wrong (empty outer). For example : $ parrot luap.pir --target=pir Compiler Lua 5.1 on Parrot Copyright (C) 2005-2008, The Perl Foundation. print hello .include interpinfo.pasm .HLL Lua, lua_group .namespace .sub start :anon :main :lexid(11) .param pmc args :optional #print start\n load_bytecode languages/lua/lua.pbc lua_openlibs() .local pmc env env = get_hll_global _G .local pmc vararg vararg = argstolua(env, args) .const .Sub main = main_10 main.setfenv(env) ($I0, $P0) = docall(main, vararg :flat) unless $I0 goto L1 printerr luap: printerr $P0 L1: .end .namespace .sub main_10 :anon :lex :lexid(10) :outer() .param pmc vararg :slurpy .const .LuaString k_print = print .local pmc subr subr = interpinfo .INTERPINFO_CURRENT_SUB $P11 = subr.getfenv() set $P12, $P11[k_print] new $P13, LuaString set $P13, hello $P12($P13) .end Instead of : ... .sub start :anon :main :lexid(11) ... .sub main_10 :anon :lex :lexid(10) :outer(11) ... Fixed in r29184. François.
Re: [perl #56110] [PATCH] Warnings on Solaris
On Tuesday 08 July 2008 17:55:42 NotFound wrote: On Mon, Jun 23, 2008 at 4:37 PM, Andrew Johnson [EMAIL PROTECTED] wrote: Here is the patch. It avoids the warning both in C and C++ with gcc. Works fine for me, no warning. It might be worth adding a comment into parrot.h to clarify that PARROT_const_cast should *only* be used for c/v qualifier changes, and that additional casting may be necessary. Done in r29179, please confirm that gives no warning now. Confirmed, those warnings have gone. I'm still getting loads of warning: statement not reached but I'll work out how to suppress those and post a fix separately. - Andrew -- Talk is cheap. Show me the code. -- Linus Torvalds
[perl #56718] [BUG] Array PMC freeze/thaw/visit broken
# New Ticket Created by Christoph Otto # Please include the string: [perl #56718] # in the subject line of all future correspondence about this issue. # URL: http://rt.perl.org/rt3/Ticket/Display.html?id=56718 r29183 adds a test to t/pmc/array.t that exposes some brokenness in the Array PMC's freeze/thaw code path. I added the test because it looked like Array's freeze/thaw/visit code had no test coverage. It turns out that list_visit also never gets called (at least according to make cover). I don't have the tuits to fix this for now, hence the ticket and the failing test. To repo, just prove t/pmc/array.t. If everything passes, you win!
[perl #56716] speed up the configure tests
# New Ticket Created by Jerry Gay # Please include the string: [perl #56716] # in the subject line of all future correspondence about this issue. # URL: http://rt.perl.org/rt3/Ticket/Display.html?id=56716 the configure tests take too much time to run, and should be sped up by whatever means necessary so as to take a much smaller percentage of the overall time for the test suite. from the looks of it, there's a lot of setup and teardown in each step test file that requires the same code to be repeated. one example is that only a few lines of code differ between t/steps/inter_charset-01.t and t/steps/inter_charset-02.t, and mainly because there is one more test in the latter. why are all these tests being repeated? another example is that with so many files, perl is invoked many, many times. starting processes on windows is expensive, so every file (300 in t/steps and t/configure) is another invocation of perl. this adds up quickly to slow windows testing to a crawl. if instead these tests were data-driven, so the tests were in data format, and the configure system had a way to reset itself to a previous state between tests, then we could have many fewer invocations of perl--at least two orders of magnitude fewer invocations, i reckon. comments, suggestions, and questions welcome. ~jerry
Re: [perl #56110] [PATCH] Warnings on Solaris
On Wednesday 09 July 2008 08:27:35 Andrew Johnson wrote: Done in r29179, please confirm that gives no warning now. Confirmed, those warnings have gone. I'm still getting loads of warning: statement not reached but I'll work out how to suppress those and post a fix separately. Does your compiler have a function annotation which means This function does not return? If so, we can add a probe and a define for that. -- c
hackathon after OSCON
We're planning to meet Saturday after OSCON for a Perl 6/Parrot hackathon. Location still to be determined, but it will be somewhere close to the OSCON convention center. Allison
[perl #54384] [BUG] split opcode gives failed assertion when source string is null
Patch applied in r29201, keep ticket open for some days.
[perl #56110] [CAGE] Warnings on Solaris
Closing ticket
Re: [perl #56716] speed up the configure tests
On Tue, 8 Jul 2008, Jerry Gay wrote: # New Ticket Created by Jerry Gay # Please include the string: [perl #56716] # in the subject line of all future correspondence about this issue. # URL: http://rt.perl.org/rt3/Ticket/Display.html?id=56716 the configure tests take too much time to run, and should be sped up by whatever means necessary so as to take a much smaller percentage of the overall time for the test suite. from the looks of it, there's a lot of setup and teardown in each step test file that requires the same code to be repeated. To give some sense of scale: On my aging-but-busy Solaris 8/SPARC system, the configure tests take about 15 minutes to run, and account for about 1/4 of the total run time for 'make test'. -- Andy Dougherty [EMAIL PROTECTED]
Re: [perl #56398] [BUG] lexical inner scope always keeps first lexpad (or something)
From: Patrick R. Michaud [EMAIL PROTECTED] Date: Wed, 9 Jul 2008 08:25:52 -0500 On Wed, Jul 09, 2008 at 01:27:29AM -0400, Bob Rogers wrote: What foo should do is create a closure and call that: .const .Sub inner = 'inner' inner = newclosure inner inner() If I understand what you're saying, and then take it to what I see as its ultimate conclusion, you're basically claiming that every call to a subroutine involving lexicals requires a newclosure op. Yes; I believe that's a cleaner design. Doing otherwise relies on runtime heuristics to decide what context ought to have been closed over, which strikes me as much less reliable. Of course, I don't *need* the cleaner design, since I can just ignore the runtime heuristics -- as long as they don't break the newclosure case. Consider: { my $x = 1; sub foo() { say $x; } foo(); } In effect this is little different from having 'foo' as an immediate block. If we now say that a newclosure op is required to invoke 'foo', then that means that the 'foo()' HLL subroutine has to be generated as: .local pmc $P0 $P0 = find_name_not_null 'foo' $P0 = newclosure $P0 $P0() . . . Not true. The compiler always knows when it's compiling a closure. So if, at the point of definition, the emitted code does: foo_closure = newclosure foo_sub set_hll_global 'foo', foo_closure then the compiler doesn't have to treat calls to foo specially. Of course, this means that there is a different closure installed in the namespace after each call to the outer sub, which may have ramifications for threading. But IMHO this is a tad cleaner than the current situation (i.e. after Jonathan's fix) where the same closure is shared between threads, and could therefore leak the outer context from one to the other. (I also detect a design smell, but I am not certain it's coming from where you think it is. ;-) It all gets worse if I have something like: .sub 'abc' :multi('Integer') ... .end .sub 'abc' :multi('String') :outer('xyz') ... .end One of these is a Sub PMC, the other is a Closure PMC, and the thing that is stored under symbol 'abc' is neither -- that's a MultiSub PMC. I'm fairly certain I can't do newclosure on the MultiSub PMC . . . I think you're right, but that is probably for good reason; I don't think it makes sense. Instead, you should do newclosure on the method sub, and then define the closure as a method on the MultiSub. And if you can't do that, I claim that is a shortcoming of the Parrot MOP. I would like to see some HLL code for this. In Lisp, this winds up doing a newclosure on the method before stuffing it into the generic function, as outlined above -- and this particular method is not defined until then. IOW, there's no way to call this method that doesn't require having installed it via newclosure first. And the nature of the closure (i.e. what context is closed over) doesn't change unless the method is redefined explicitly. So the fact that you can say this in PIR doesn't necessary mean that it ought to be meaningful. In fact, if xyz is called in multiple threads, I suspect you need multiple MultiSub objects for abc anyway, which requires explicit runtime mangling to ensure that the right method closure is installed in the right context. (This is distinct from the case of lexically-scoped methods, which definitely require a new MultiSub object for each scope, and so the problem doesn't arise.) Ultimately I think that Closure PMCs need to be smart enough to take a newclosure if they need one at the time they're invoked, rather than trying to place that burden on the caller. (Note that I'm not arguing that the current implementation is correct -- I'm just describing what I think a correct implementation will need to do.) That's good; we semi-agree. But I'm arguing further that making parrot guess the right context is also broken, certainly in some if not all situations. I would like at least to persuade you that your badlex.pir case is incorrect (but will settle for only semi-agreeing. ;-) I also think we probably still need to have a newclosure opcode available to allow PIR to explicitly say when to take a closure . . . We *definitely* need newclosure; otherwise there can only ever be one closure at a time. Except perhaps by cloning the closure, and hoping that the runtime magic does the right thing. But I claim that compilers can always emit code that knows what the right context is; why should parrot *ever* have to guess? [...] It may be possible to rescue Patrick's desired behavior by keeping track of whether the outer_sub was initialized by newclosure or not. My 'desired behavior' is simply that we have something that works. :-) But I suspect that this
Re: [perl #56398] [BUG] lexical inner scope always keeps first lexpad (or something)
On Wednesday 09 July 2008 13:46:19 Bob Rogers wrote: From: Patrick R. Michaud [EMAIL PROTECTED] Date: Wed, 9 Jul 2008 08:25:52 -0500 If I understand what you're saying, and then take it to what I see as its ultimate conclusion, you're basically claiming that every call to a subroutine involving lexicals requires a newclosure op. Yes; I believe that's a cleaner design. Doing otherwise relies on runtime heuristics to decide what context ought to have been closed over, which strikes me as much less reliable. Of course, I don't *need* the cleaner design, since I can just ignore the runtime heuristics -- as long as they don't break the newclosure case. I read that in the lexicals PDD, and I think the current behavior is bizarre *without* the call to newclosure. How is it even possible to close over a lexical environment in an outer when that lexical environment was never even created? It's difficult to describe that as anything other than ridiculous. Consider Bob's example Perl 5 code: sub outer { my $x = shift; print outer foo $x\n; sub inner { print inner foo $x\n; } } # Note that it is not illegal to call inner before outer. inner(); There's a compile-time warning here, namely that $x will not stay shared. Even though it looks like inner() should close over outer()'s $x per Perl 5's scoping rules (ignoring that you can't nest subs in Perl 5), there is no $x available at the call to inner(). If you wrote this instead: sub outer { my $x = shift; print outer foo $x\n; return sub { print inner foo $x\n; } } my $inner = outer( 10 ); $inner-(); ... then Perl 5 effectively performs a newclosure action, attaching the active lexpad to the new instance of the subroutine reference. I suspect the motivation for the bizarreness of the specification is the desire to make code like this work in Parrot: { my $x; sub set_x { $x = shift } sub get_x { return $x } } ... except that there's no real way in Parrot right now to create an enclosing lexical block, activate it, and attach it as the outer to one or more Closures. -- c
Re: hackathon after OSCON
Allison Randal wrote: We're planning to meet Saturday after OSCON for a Perl 6/Parrot hackathon. Location still to be determined, but it will be somewhere close to the OSCON convention center. Location confirmed: Urban Grind East 2214 NE Oregon St. Portland, OR 97232 Saturday July 26th, 9am-5pm, in the back conference room. A few of us will be driving over from the OSCON convention center. Bus routes can be found on the local public transportation site http://trimet.org. Allison
Re: [perl #56398] [BUG] lexical inner scope always keeps first lexpad (or something)
From: chromatic [EMAIL PROTECTED] Date: Wed, 9 Jul 2008 13:59:16 -0700 I read that in the lexicals PDD, and I think the current behavior is bizarre *without* the call to newclosure. How is it even possible to close over a lexical environment in an outer when that lexical environment was never even created? It's difficult to describe that as anything other than ridiculous. That was my initial reaction, too . . . Consider Bob's example Perl 5 code: sub outer { my $x = shift; print outer foo $x\n; sub inner { print inner foo $x\n; } } # Note that it is not illegal to call inner before outer. inner(); There's a compile-time warning here, namely that $x will not stay shared. Even though it looks like inner() should close over outer()'s $x per Perl 5's scoping rules (ignoring that you can't nest subs in Perl 5), there is no $x available at the call to inner(). Yes. I would not want Perl 5 code like that in *my* repository. ;-} If you wrote this instead: sub outer { my $x = shift; print outer foo $x\n; return sub { print inner foo $x\n; } } my $inner = outer( 10 ); $inner-(); ... then Perl 5 effectively performs a newclosure action, attaching the active lexpad to the new instance of the subroutine reference. Yes. And if you want to preserve the external API, you could even do something like *inner = sub { print inner foo $x\n; }; which requires 'no strict', but (a) avoids the not stay shared warning and (b) updates inner() every time outer() is called, as Patrick wants in PIR. (IMHO, this is what your example *should* mean.) I suspect the motivation for the bizarreness of the specification is the desire to make code like this work in Parrot: { my $x; sub set_x { $x = shift } sub get_x { return $x } } ... except that there's no real way in Parrot right now to create an enclosing lexical block, activate it, and attach it as the outer to one or more Closures. -- c FWIW, I don't consider this bizarre; I've seen production code that does just this in order to share internal state between API functions. What would be bizarre is expecting set_x or get_x to be able to do anything meaningful before the outer block is executed. And it does work now, albeit with a little indirection; see bank-account.pir, attached. Or do you not consider this a real way? At any rate, Leo said [1] that autoclose was something Audrey wanted, so I assumed it was here to stay. I'd just like to keep it from spreading. ;-} -- Bob [1] http://groups.google.com/group/perl.perl6.internals/browse_thread/thread/41dbfee7b7b5bbe7 .namespace ['Foo'] .sub outer .local pmc x .lex '$x' ,x .const .Sub setter = 'raw_set_x' setter = newclosure setter set_hll_global ['Foo'], 'set_x', setter .const .Sub getter = 'raw_get_x' getter = newclosure getter set_hll_global ['Foo'], 'get_x', getter .end .sub raw_set_x :outer('outer') .param pmc new_x store_lex '$x', new_x .return (new_x) .end .sub raw_get_x :outer('outer') .local pmc new_x new_x = find_lex '$x' .return (new_x) .end .sub init :init outer() .end .sub main :main set_x(1) $P0 = get_x() print $P0 print \n set_x(9) $P0 = get_x() print $P0 print \n .end
Re: [perl #56398] [BUG] lexical inner scope always keeps first lexpad (or something)
On Wednesday 09 July 2008 15:37:51 Bob Rogers wrote: I suspect the motivation for the bizarreness of the specification is the desire to make code like this work in Parrot: { my $x; sub set_x { $x = shift } sub get_x { return $x } } ... except that there's no real way in Parrot right now to create an enclosing lexical block, activate it, and attach it as the outer to one or more Closures. -- c FWIW, I don't consider this bizarre; I've seen production code that does just this in order to share internal state between API functions. What would be bizarre is expecting set_x or get_x to be able to do anything meaningful before the outer block is executed. That's what I meant by bizarre. And it does work now, albeit with a little indirection; see bank-account.pir, attached. Or do you not consider this a real way? That example is fine with me. I almost deleted all of the hijinks necessary in Closure PMC to attach to a never-initialized outer lexical scope before I read the lexical spec again and realized that someone designed it that way. At any rate, Leo said [1] that autoclose was something Audrey wanted, so I assumed it was here to stay. I'd just like to keep it from spreading. ;-} Given the simplicity of the workaround (which actually works) and the difficulty of making the broken-as-designed feature work partially, I vote for removing the brokenness. -- c
Re: [perl #56398] [BUG] lexical inner scope always keeps first lexpad (or something)
On Wed, Jul 09, 2008 at 04:46:19PM -0400, Bob Rogers wrote: From: Patrick R. Michaud [EMAIL PROTECTED] ... If we now say that a newclosure op is required to invoke 'foo', then that means that the 'foo()' HLL subroutine has to be generated as: .local pmc $P0 $P0 = find_name_not_null 'foo' $P0 = newclosure $P0 $P0() . . . Not true. The compiler always knows when it's compiling a closure. So if, at the point of definition, the emitted code does: foo_closure = newclosure foo_sub set_hll_global 'foo', foo_closure then the compiler doesn't have to treat calls to foo specially. So, if I understand you correctly, for something like for 1..10 - $x { sub foo() { say $x; } foo(); } you're saying we should replace the 'foo' symbol ten times -- each time with a newclosure taken from whatever was previously stored there. Also, we can't do this exactly at the point of definition, because sub calls can lexically occur before the definition of the thing they're calling. So it has to be moved higher in the block somehow. It all gets worse if I have something like: .sub 'abc' :multi('Integer') ... .end .sub 'abc' :multi('String') :outer('xyz') ... .end One of these is a Sub PMC, the other is a Closure PMC, and the thing that is stored under symbol 'abc' is neither -- that's a MultiSub PMC. I'm fairly certain I can't do newclosure on the MultiSub PMC . . . I think you're right, but that is probably for good reason; I don't think it makes sense. Instead, you should do newclosure on the method sub, and then define the closure as a method on the MultiSub. And if you can't do that, I claim that is a shortcoming of the Parrot MOP. I don't know what you're meaning by method sub here, but I'm not sure it's important that I know. As I said earlier, I'm not at all arguing that Parrot's current model is correct, or that the way I've been trying to do things is the right one -- I'm merely asking What is the correct way to do this stuff in Parrot? So, if the correct answer is that a sub definition should rebind the sub's name to the result of a newclosure opcode, my response is okay, but that doesn't seem to work for MultiSubs. If the response to that is Parrot's MultiSub model is broken, I won't argue with that, but then someone (probably shouldn't be me, but I'll do it if there's no other option) needs to design and implement a model that isn't broken, or suggest how languages can work around it. Ultimately I think that Closure PMCs need to be smart enough to take a newclosure if they need one at the time they're invoked, rather than trying to place that burden on the caller. (Note that I'm not arguing that the current implementation is correct -- I'm just describing what I think a correct implementation will need to do.) That's good; we semi-agree. But I'm arguing further that making parrot guess the right context is also broken, certainly in some if not all situations. My feeling is that the some situations where guessing the context is wrong will be those where the HLL compiler inserts newclosure opcodes to get parrot to do the right thing. I don't think that guessing will be wrong in all (or even the majority) of situations-- immediate block/sub execution is *so* much more common than the need to take an explicit closure that it feels like Parrot ought to support that model by default. If that's not Parrot's default, that's fine, but I'd like someone or a PDD to officially say that every sub with :outer *must* have a newclosure op. I would like at least to persuade you that your badlex.pir case is incorrect (but will settle for only semi-agreeing. ;-) As I said above, I don't have to be persuaded that badlex.pir is incorrect -- I just need to be shown what correct is. As I've already noted, simply replacing the symbol with a newclosure PMC doesn't work in the case of MultiSubs. We *definitely* need newclosure; otherwise there can only ever be one closure at a time. Except perhaps by cloning the closure, and hoping that the runtime magic does the right thing. But I claim that compilers can always emit code that knows what the right context is; why should parrot *ever* have to guess? I somewhat disagree with the connotation of words here (runtime magic, guess) -- another name for guess is default. Parrot provides a default, and we override that default when it's not the correct value/behavior. I don't disagree that it's possible for a compiler to always know the context and emit code that knows the correct context. But in some sense that's what the compiler is already doing when it provides an :outer() flag to Parrot -- it's telling Parrot what the right context is. (By way of analogy, I think that one can equally argue that Parrot should not need to support :method flags or
[perl #56756] [BUG] t\pmc\pmc.t failure on win32
# New Ticket Created by Will Coleda # Please include the string: [perl #56756] # in the subject line of all future correspondence about this issue. # URL: http://rt.perl.org/rt3/Ticket/Display.html?id=56756 On a win32 build with AS perl and the MS tools, I get the following results: Failed Test Stat Wstat Total Fail Failed List of Failed --- t/pmc/pmc.t1 256191 5.26% 5 (1 subtest UNEXPECTEDLY SUCCEEDED), 34 tests and 615 subtests skipped. Failed 1/590 test scripts, 99.83% okay. 1/11410 subtests failed, 99.99% okay. NMAKE : fatal error U1077: 'c:\perl\bin\perl.exe' : return code '0xff' Stop. C:\research\parrotprove t/pmc/pmc.t t/pmc/pmcok 4/19 t/pmc/pmcNOK 5# Failed test 'PMC type check' # at t/pmc/pmc.t line 102. # Exited with error code: 255 # Received: # All names and ids ok. # # Expected: # /All names and ids ok/ # t/pmc/pmcok 19/19# Looks like you failed 1 test of 19. t/pmc/pmcdubious Test returned status 1 (wstat 256, 0x100) DIED. FAILED test 5 Failed 1/19 tests, 94.74% okay (less 1 skipped test: 17 okay, 89.47%) Failed Test Stat Wstat Total Fail Failed List of Failed --- t/pmc/pmc.t1 256191 5.26% 5 C:\research\parrot.\parrot t\pmc\pmc_5.pasm All names and ids ok. C:\research\parrotecho %ERRORLEVEL% -1073741819 Test passes on feather. -- Will Coke Coleda
Re: [perl #56398] [BUG] lexical inner scope always keeps first lexpad (or something)
On Wed, Jul 09, 2008 at 03:45:31PM -0700, chromatic wrote: That example is fine with me. I almost deleted all of the hijinks necessary in Closure PMC to attach to a never-initialized outer lexical scope before I read the lexical spec again and realized that someone designed it that way. ... Given the simplicity of the workaround (which actually works) and the difficulty of making the broken-as-designed feature work partially, I vote for removing the brokenness. FWIW, I don't have any problem with having Parrot throw an exception if someone invokes an inner lexical scope for which its outer lexical scope has not been invoked yet. Let's solve that problem when we come to it (and I don't know that Perl 6 will ever come to it -- again, I haven't worried about that case yet). Pm
Re: [perl #56398] [BUG] lexical inner scope always keeps first lexpad (or something)
On Wed, Jul 09, 2008 at 04:46:19PM -0400, Bob Rogers wrote: Content-Description: message body text In effect this is little different from having 'foo' as an immediate block. If we now say that a newclosure op is required to invoke 'foo', then that means that the 'foo()' HLL subroutine has to be generated as: .local pmc $P0 $P0 = find_name_not_null 'foo' $P0 = newclosure $P0 $P0() . . . Not true. The compiler always knows when it's compiling a closure. So if, at the point of definition, the emitted code does: foo_closure = newclosure foo_sub set_hll_global 'foo', foo_closure then the compiler doesn't have to treat calls to foo specially. ...would we also have to generate code to restore the previous value of 'foo' upon exiting the sub? (Think recursive calls here.) sub bar($x) { sub foo() { say $x; } if ($x 0) { bar($x-1); } foo(); } Pm
[perl #43310] [TODO] config/auto/readline.pm: Write unit tests
Since I closed this ticket in January, more code has been added. Tonight, while writing unit tests for internal subroutine _handle_ncurses_need(), I noticed the following lines: if ( $osname =~ /mswin32/i ) { if ( $cc =~ /^gcc/i ) { $conf-data-add( ' ', libs = '-lncuses' ); ### -- ??? } else { $conf-data-add( ' ', libs = 'ncurses.lib' ); } } else { $conf-data-add( ' ', libs = '-lncurses' ); } Based on code in other config steps, I would have expected the line marked ### to read: $conf-data-add( ' ', libs = '-lncurses' ); ... i.e., the same as the 'non-win32' branch seven lines farther down. Feature or bug? If the latter, we'll need to fix in config/auto/readline.pm and t/steps/auto_readline-02.t. Thank you very much. kid51
[perl #43322] [TODO] config/auto/pack.pm: Write unit tests
With additional unit tests added in r29216-29217, test coverage is now 100% in all major categories. Resolving ticket. kid51
[perl #43318] [TODO] config/auto/jit.pm: Write unit tests
On Tue Jul 08 20:01:11 2008, [EMAIL PROTECTED] wrote: Committed to trunk in r29181: http://www.parrotvm.org/svn/parrot/revision?rev=29181 kid51 Revisions appear to be passing smoke tests. Marking ticket resolved. kid51
[perl #56760] [TODO]: config/auto/opengl.pm: Write unit tests
# New Ticket Created by James Keenan # Please include the string: [perl #56760] # in the subject line of all future correspondence about this issue. # URL: http://rt.perl.org/rt3/Ticket/Display.html?id=56760 This configuration step class did not exist when I began to write tests for the steps in June 2007. So I'm opening a ticket now. Write unit tests for config/auto/opengl.pm, the module whose functionality executes Parrot configuration step auto::opengl. Since much of the code in this module has been refactored already, we should be able to add tests without disturbing its functionality or making future refactoring difficult. Thank you very much. kid51
Re: [perl #56398] [BUG] lexical inner scope always keeps first lexpad (or something)
From: Patrick R. Michaud [EMAIL PROTECTED] Date: Wed, 9 Jul 2008 18:49:53 -0500 On Wed, Jul 09, 2008 at 04:46:19PM -0400, Bob Rogers wrote: Not true. The compiler always knows when it's compiling a closure. So if, at the point of definition, the emitted code does: foo_closure = newclosure foo_sub set_hll_global 'foo', foo_closure then the compiler doesn't have to treat calls to foo specially. So, if I understand you correctly, for something like for 1..10 - $x { sub foo() { say $x; } foo(); } you're saying we should replace the 'foo' symbol ten times -- each time with a newclosure taken from whatever was previously stored there. Yes; because I think that is what the code means. Indeed, I think you yourself have already suggest that making closures in a loop requires newclosure anyway [0]. Or are you saying that this case is different? Shouldn't for 1..10 - $x { sub foo() { say $x; } push(@foos, \foo); } produce the same result as for 1..10 - $x { my $foo = sub { say $x; }; push(@foos, $foo); } modulo global namespace mangling (and broken Perl 6 syntax)? And if not, why not? Also, we can't do this exactly at the point of definition, because sub calls can lexically occur before the definition of the thing they're calling. So it has to be moved higher in the block somehow. Eh? Can't do what at the point of definition? Do you have an example? It all gets worse if I have something like: .sub 'abc' :multi('Integer') ... .end .sub 'abc' :multi('String') :outer('xyz') ... .end One of these is a Sub PMC, the other is a Closure PMC, and the thing that is stored under symbol 'abc' is neither -- that's a MultiSub PMC. I'm fairly certain I can't do newclosure on the MultiSub PMC . . . I think you're right, but that is probably for good reason; I don't think it makes sense. Instead, you should do newclosure on the method sub, and then define the closure as a method on the MultiSub. And if you can't do that, I claim that is a shortcoming of the Parrot MOP. I don't know what you're meaning by method sub here, but I'm not sure it's important that I know . . . I just mean the sub that implements the body of the method. I would define it as a normal sub, create a closure with newclosure, and do add_method (or equivalent) to tell the multi to dispatch to the closure on the appropriate classes. I alluded to the need for such a PIR API last December [1] in order to support anonymous classes, but this API is needed for closure methods as well. So, if the correct answer is that a sub definition should rebind the sub's name to the result of a newclosure opcode, my response is okay, but that doesn't seem to work for MultiSubs. If the response to that is Parrot's MultiSub model is broken, I won't argue with that, but then someone (probably shouldn't be me, but I'll do it if there's no other option) needs to design and implement a model that isn't broken, or suggest how languages can work around it. I have been itching to experiment along these lines in Kea-CL for more than a year now, but I've been too busy nailing down prerequisites (like having a working native compiler) even to get started. Sigh. In any case, IIUC, the current model doesn't support everything that will be needed for Perl 6, so something will have to be changed. I suspect it will look like the add_method API to which I alluded above. But I would rather be closer to having a practical compiler implementation before I try to propose anything. . . . I don't disagree that it's possible for a compiler to always know the context and emit code that knows the correct context. But in some sense that's what the compiler is already doing when it provides an :outer() flag to Parrot -- it's telling Parrot what the right context is. :outer tells Parrot what the *static* relationships are. newclosure tells Parrot the proper dynamic relationship. You may be correct that the static relationship sometimes implies enough about the dynamic one to get the right answer, but I am not convinced. I will continue to ignore autoclose -- except, of course, when it blows up in my face. (By way of analogy, I think that one can equally argue that Parrot should not need to support :method flags or automatically install subs as methods by default, because a compiler will know that something is a method and can emit code to install the sub as one.) :method flags are declaring purely static information, so the analogy doesn't fly. . . . Along those lines, it occurs to me that badlex.pir doesn't solve the general case for the Perl 6 example you posted. What should happen if I add inner() in main
Re: [perl #56398] [BUG] lexical inner scope always keeps first lexpad (or something)
On Thu, Jul 10, 2008 at 12:29:57AM -0400, Bob Rogers wrote: From: Patrick R. Michaud [EMAIL PROTECTED] Date: Wed, 9 Jul 2008 18:49:53 -0500 On Wed, Jul 09, 2008 at 04:46:19PM -0400, Bob Rogers wrote: Not true. The compiler always knows when it's compiling a closure. So if, at the point of definition, the emitted code does: foo_closure = newclosure foo_sub set_hll_global 'foo', foo_closure then the compiler doesn't have to treat calls to foo specially. Yes; because I think that is what the code means. Indeed, I think you yourself have already suggest that making closures in a loop requires newclosure anyway [0]. Or are you saying that this case is different? I think misread what you originally wrote, not seeing the difference between 'foo_sub' and the global 'foo'. Sorry about that. Shouldn't for 1..10 - $x { sub foo() { say $x; } push(@foos, \foo); } produce the same result as for 1..10 - $x { my $foo = sub { say $x; }; push(@foos, $foo); } modulo global namespace mangling (and broken Perl 6 syntax)? And if not, why not? Yes, the two examples above would be the effectively the same, but neither of them are the same as my original. Perl 6 recognizes taking a closure at the point where a sub is referenced (used as an rvalue), so in the first example we would do the newclosure at the foo reference inside the push() call, the second example we would do the newclosure as part of the my $foo assignment. But according to Synopsis 4 [1], if we simply define foo and call it directly (as opposed to taking a reference), we don't take that snapshot of its lexical scope. (I'm making the leap that takes a snapshot in the Synopsis means newclosure in Parrot.) Also, we can't do this exactly at the point of definition, because sub calls can lexically occur before the definition of the thing they're calling. So it has to be moved higher in the block somehow. Eh? Can't do what at the point of definition? Do you have an example? By this I meant take a newclosure and store it in the symbol table. The following is valid Perl 6: my $x = 'hello'; foo(); sub foo() { say $x; } At the point of the foo() call, we have to have already stored an entry in the symbol table for 'foo', thus if we wait until the sub declaration to do that, it's too late. So, we have to move the newclosure+store sequence to a point earlier in the block than where the sub declaration itself occurs. From: Patrick R. Michaud [EMAIL PROTECTED] ...would we also have to generate code to restore the previous value of 'foo' upon exiting the sub? (Think recursive calls here.) sub bar($x) { sub foo() { say $x; } if ($x 0) { bar($x-1); } foo(); } No. AFAIK, sub foo() { ... } always mangles the global definition of foo. So in Perl 5, the first call wins; in Perl 6, it might be the last call, but I don't really know. Okay, I wasn't aware of this for Perl 5, so perhaps Perl 6 has similar semantics. But in my head it doesn't seem to match what I read in Synopsis 4 at [1], particularly where S04 says my sub bar { print $x } # not cloned yet (Again I'm making the leap that 'cloning' in the synopsis is what we mean by 'newclosure' in Parrot.) To summarize, I am not arguing that relying on autoclose is necessarily wrong, and that we should therefore get rid of it. [...] I don't exactly understand what autoclose is (even after reading the other thread) -- my impression is that it refers to invoking or taking a snapshot of an inner sub's lexical environment even when its outer context hasn't been invoked yet. If this limited understanding of autoclose is correct, then I don't think my examples are relying on it; but if the examples I'm giving do make use of the autoclose feature you keep referring to, then I guess I need to learn more about autoclose to be able to talk intelligently about it. Pm [1] http://dev.perl.org/perl6/doc/design/syn/S04.html#When_is_a_closure_not_a_closure