Re: Compiled programs to keep BEGIN blocks? (was Re: [RFC] Switch to make Test::Builder output even if $^C ( for B::C ))
On Wed, Jan 16, 2002 at 11:39:05AM +0100, Mattia Barbon wrote: > >It seems that's wrong. That what perlcc/B::C does is 'freeze' the > >current state of the interpreter after compilation, including the > >values of variables, and then spit out appropriate C code for only > >the post-compile opcode tree. Is this right? > > Yes. That's what makes startup time faster ( but not run time, > as you surely know ) I always thought that was recouped because you didn't have to load the interpreter and wait for Perl to compile the program and libraries to bytecode. PS I got a huge number of these warnings from compiling 'use CGI' pccF6qox.c:14873: warning: decimal constant is so large that it is unsigned pccF6qox.c:14875: warning: decimal constant is so large that it is unsigned -- Michael G. Schwern <[EMAIL PROTECTED]>http://www.pobox.com/~schwern/ Perl Quality Assurance <[EMAIL PROTECTED]> Kwalitee Is Job One This is my sig file. Is it not nify? Worship the sig file. http://www.sluggy.com
Re: Compiled programs to keep BEGIN blocks? (was Re: [RFC] Switch to make Test::Builder output even if $^C ( for B::C ))
On Tue, Jan 15, 2002 at 05:30:09PM -0500, [EMAIL PROTECTED] wrote: > On Tue, Jan 15, 2002 at 08:51:06AM +, Piers Cawley wrote: > > > I don't understand. Why do we have to deal with them? Just translate > > > the Perl code in the BEGIN block to C , dump it and make > > > sure it gets run first. Right? > > > > > > I think I'm missing something very vital here. Yeah, I think so ;-) [snip] > Guess? Its a BEGIN block, it gets run once! Oh good, because you seemed to be suggesting otherwise. > Ok, there's some really fundemental breakdown of understanding here, > and I think its me. Let's step back a second. Why is anything > guessing when and how many times BEGIN blocks are run? Well, you seemed to be suggesting that some BEGIN blocks would be run at runtime. Some BEGIN blocks have to run at compile time. If they're only to be run once then you have to decide when that will be. My boss recently gave me a fairly tricky problem to solve. The Java boys weren't making much headway, so he asked if I could do it in PERL. After (a) little thought I came up with an elegant modular solution. Since the program contains proprietary intellectual property and also because it has to run as fast as C, I decided to run perlcc on it. Here's my program. Please don't break it. ONE.pm == package ONE; # I might obfuscate this eval statement later in case any of our # competitors ever see this code. sub import { eval '$main::ONE--' } 1 one.plx === #!/usr/bin/perl # Copyright Paul Johnson, 2002 # This program is mine. You can't have it. # Program to print 1 BEGIN { $ONE = 2 } # Initialisation. use ONE;# Abstracted away main logic. print $ONE # Output. __END__ The fundamental problem here is that BEGIN blocks have to run when they are compiled. This is documented. You can try to work out whether the BEGIN blocks can be rearranged and run at different times, but as Piers has pointed out, this is impossible in the general case. So if the BEGIN blocks are run at compile time, there's no point having them around at run time. This is the raison d'ĂȘtre of INIT blocks. This problem cannot be solved. But if you do solve it millions will rejoice. Well, thousands anyway. Still, I wonder whether you shouldn't work up to it by perhaps finding a polynomial time solution to the travelling salesman problem for example. PS. Parts of this message are moderated by :-) where required by law. -- Paul Johnson - [EMAIL PROTECTED]
Re: Compiled programs to keep BEGIN blocks? (was Re: [RFC] Switch to make Test::Builder output even if $^C ( for B::C ))
On Wed, Jan 16, 2002 at 08:45:26AM +0100, Paul Johnson wrote: > The fundamental problem here is that BEGIN blocks have to run when they > are compiled. This is documented. You can try to work out whether the > BEGIN blocks can be rearranged and run at different times, but as Piers > has pointed out, this is impossible in the general case. So if the > BEGIN blocks are run at compile time, there's no point having them > around at run time. This is the raison d'?tre of INIT blocks. Ok, lemme run this by you. Here's my conception of how perlcc/B::C works. The program is compiled, the opcode tree is scanned and the appropriate C code is written for each op in the program. Just like B::Deparse scans the opcode tree and writes out Perl code. Which is why I'm having so much conceptual trouble with why BEGIN blocks would be a problem. It seems that's wrong. That what perlcc/B::C does is 'freeze' the current state of the interpreter after compilation, including the values of variables, and then spit out appropriate C code for only the post-compile opcode tree. Is this right? In which case, yes, I can see how BEGIN blocks would be troublesome. :( -- Michael G. Schwern <[EMAIL PROTECTED]>http://www.pobox.com/~schwern/ Perl Quality Assurance <[EMAIL PROTECTED]> Kwalitee Is Job One Nature is pissed. http://www.unamerican.com/
Re: Compiled programs to keep BEGIN blocks? (was Re: [RFC] Switch to make Test::Builder output even if $^C ( for B::C ))
On Tue, Jan 15, 2002 at 08:51:06AM +, Piers Cawley wrote: > > I don't understand. Why do we have to deal with them? Just translate > > the Perl code in the BEGIN block to C , dump it and make > > sure it gets run first. Right? > > > > I think I'm missing something very vital here. > > Let's see if I can come up with a simple counterexample that will show > up the problem. > > #!perl > my($compile_time, $start_time); > BEGIN {$compile_time .= localtime(time)} > > # Later: > > print "Compiled at $compile_time\n"; > print "Started at $start_time\n"; > > ... > > BEGIN {$start_time .= localtime(time)} > __END__ > > How do you intend to distinguish between those two BEGIN blocks, one > of which must be run at script compile time, the other of which must > be run at (for want of a better description) INIT time? And neither of > which can be run twice (hence the .=). Wouldn't both of those BEGIN blocks be run at compile-time? The only ordering I'd see is that the first one declared (ie. $compile_time) is run before the second (ie. $start_time). > The only thing that can make that distinction is a human being. The > compiler can probably guess that the two blocks should only be run > once Guess? Its a BEGIN block, it gets run once! Ok, there's some really fundemental breakdown of understanding here, and I think its me. Let's step back a second. Why is anything guessing when and how many times BEGIN blocks are run? Is B::C literally dumping out the total state of the interpreter after compile-time, variables and everything?! -- Michael G. Schwern <[EMAIL PROTECTED]>http://www.pobox.com/~schwern/ Perl Quality Assurance <[EMAIL PROTECTED]> Kwalitee Is Job One Paste is a waste if you're chaste, but in this case dump a load of goo and poo by the case in your face, and place in your jawls like a juicy chaw, but don't spit that shit and enjoy it all. -- Ubergirl's beau
Re: Compiled programs to keep BEGIN blocks? (was Re: [RFC] Switch to make Test::Builder output even if $^C ( for B::C ))
On Mon, Jan 14, 2002 at 11:43:24PM +, Piers Cawley wrote: > > What's left? > > What about begin blocks with side effects. How do you propose > detecting the side effects. How do you deal with things that may > dispatch to different subroutines depending on when they are > evaluated? How do you deal with arrays getting initialised (and > possible extended) twice? How, in short do you solve the halting > problem? A scene from Perl: The Gathering. Piers has played the Halting Problem card your thread! Schwern counters by taping Hitler and playing two Befuddled Innocence cards! ;) I don't understand. Why do we have to deal with them? Just translate the Perl code in the BEGIN block to C , dump it and make sure it gets run first. Right? I think I'm missing something very vital here. > The point is that even B::Deparse, which tries very hard to get BEGIN > blocks right, can't do this and, according to the above extract, is > highly unlikely to do so in the forseeable future. Like I said, I don't expect perlcc to run perfectly Right Now, but I do expect this to be considered a bug, not a feature. The upshot of this is: don't prop up the perlcc tests to shield against this. That was the original point of this thread. Somebody will come along and fix it someday. That day might be tommorrow, dunno. Three weeks ago perlcc was declared indefinitely dead in the water, now its alive and kicking again. We do impossible things all the time. -- Michael G. Schwern <[EMAIL PROTECTED]>http://www.pobox.com/~schwern/ Perl Quality Assurance <[EMAIL PROTECTED]> Kwalitee Is Job One grep { ref and ref !~ /^[A-Z]+$/ } kill 9, @ARGV;
Re: Compiled programs to keep BEGIN blocks? (was Re: [RFC] Switch to make Test::Builder output even if $^C ( for B::C ))
On Mon, Jan 14, 2002 at 11:11:57PM +, Nicholas Clark wrote: > On Mon, Jan 14, 2002 at 10:38:36PM +, Piers Cawley wrote: > > Michael G Schwern <[EMAIL PROTECTED]> writes: > > > > > On Mon, Jan 14, 2002 at 04:16:49PM +, Piers Cawley wrote: > > >> Michael G Schwern <[EMAIL PROTECTED]> writes: > > > >> > Like it or not, people put lots of init code into BEGIN blocks, if > > >> > nothing else for backwards compatiblity with 5.005. perlcc has to > > >> > compile real world programs. > > > Meanwhile we *do* have INIT blocks will do what you want without doing > > the impossible. (Well, admittedly, educating programmers might well be > > nearly impossible too, but dammit the behaviour of BEGIN blocks has > > been *documented* since before there was a Perl compiler. And the > > behaviour of INIT and CHECK blocks have also been clearly documented > > since they were interested. > > > > This really is a case of 'READ THE FSCKING MANUAL'. > > I can't see that anything is going to solve what Schwern wants, becuse what > he wants is a solution backwards compatible to 5.00503 and preferably 5.004 I want 5.004_05 compatible code (or any syntacticly correct piece of Perl code) to be able to be compiled correctly (eventually) with the latest version of perlcc. If there's Perl->C translation issue as to why that's not possible, ok. But I know from a B standpoint all the information is there to handle BEGIN blocks. -- Michael G. Schwern <[EMAIL PROTECTED]>http://www.pobox.com/~schwern/ Perl Quality Assurance <[EMAIL PROTECTED]> Kwalitee Is Job One Now I fight for wisdom. http://sluggy.com/d/010204.html
Re: Compiled programs to keep BEGIN blocks? (was Re: [RFC] Switch to make Test::Builder output even if $^C ( for B::C ))
On Mon, Jan 14, 2002 at 10:38:36PM +, Piers Cawley wrote: > >> Deferring BEGIN blocks 'til runtime will break rather more realworld > >> program than it fixes I think. > > > > Where is deferring involved? > > Err... it goes like this: > > by the main program> > > > > > > The compiled file gets dumped out at CHECK time as I think we said > before. What you propose is to defer BEGIN processing to after the > CHECK phase. So, how do you decide whether > > BEGIN { > push @INC, 'bibble'; > } > > gets evaluated at compile time (which it should because it has far > reaching effects about where stuff gets included from during > compilation), or if it gets evaluated at runtime. Admittedly, this one > is rather straightforward. Oh, I think you misunderstand. Everything gets evaluated like normal. BEGIN blocks run, checks, whatever. Then its all compiled and dumped. The only difference I'm proposing is that any code in the BEGIN blocks (mod use statements and whatnot) is also dumped. So the resulting C code mirrors what the original was doing. You can get at the BEGIN code via B::save_BEGINs. You can figure out what's code and what's just a use statement. You can squelch any output with O.pm's -qq. What's left? > Meanwhile we *do* have INIT blocks will do what you want without doing > the impossible. (Well, admittedly, educating programmers might well be > nearly impossible too, but dammit the behaviour of BEGIN blocks has > been *documented* since before there was a Perl compiler. And the > behaviour of INIT and CHECK blocks have also been clearly documented > since they were interested. > > This really is a case of 'READ THE FSCKING MANUAL'. Its also a case of "I'd rather not break backwards compatibility [1] just to feed perlcc's neurosises". There's also the factor that for all intents and purposes, Joe Average Programmer really shouldn't have to care about the difference between BEGIN, INIT and CHECK. In fact, they should be able to get along just fine without ever knowing INIT and CHECK even exist. Sort of like *foo{HASH} and the finer points of the -D switch. Its perlcc's job to reproduce the actions of the original code to the best of its abilities. It might turn out that its not possible. This is, after all, an experiment. [1] I think they were in 5.005_XX, just not documented well until 5.6. -- Michael G. Schwern <[EMAIL PROTECTED]>http://www.pobox.com/~schwern/ Perl Quality Assurance <[EMAIL PROTECTED]> Kwalitee Is Job One Maybe they hooked you up with one of those ass-making magazines. -- brian d. foy as misheard by Michael G Schwern
Re: Compiled programs to keep BEGIN blocks? (was Re: [RFC] Switch to make Test::Builder output even if $^C ( for B::C ))
On Mon, Jan 14, 2002 at 11:20:43PM +0100, Rafael Garcia-Suarez wrote: > On 2002.01.14 22:27 Michael G Schwern wrote: > > B::Deparse has slowly gotten very good at figuring out BEGIN blocks > > from 'use' statements and putting them in the right places. Hard > > fought knowledge. Steal from it. > > There are still problems with pragmas. (As I was working on B::Deparse > the last few weeks, if you find new solutions, let me know.) I don't know if B::C has to worry about the same style of pragma problems as B::Deparse. ie. it doesn't have to worrying about reconstructing 'use strict' from a bunch of magic $^H twiddling opcodes. -- Michael G. Schwern <[EMAIL PROTECTED]>http://www.pobox.com/~schwern/ Perl Quality Assurance <[EMAIL PROTECTED]> Kwalitee Is Job One You can't control the universe with a jar of red pepper. http://www.goats.com/archive/981004.html
Re: Compiled programs to keep BEGIN blocks? (was Re: [RFC] Switch to make Test::Builder output even if $^C ( for B::C ))
On 2002.01.14 22:27 Michael G Schwern wrote: > B::Deparse has slowly gotten very good at figuring out BEGIN blocks > from 'use' statements and putting them in the right places. Hard > fought knowledge. Steal from it. There are still problems with pragmas. (As I was working on B::Deparse the last few weeks, if you find new solutions, let me know.) > I don't expect perlcc to magically become perfect overnight. What I > do expect is that the 'compiled programs won't run code in BEGIN > blocks' be treated as a bug and not a feature and to look around at > other bits of B which are taking a stab at solving these problems.
Re: Compiled programs to keep BEGIN blocks? (was Re: [RFC] Switch to make Test::Builder output even if $^C ( for B::C ))
On Mon, Jan 14, 2002 at 04:16:49PM +, Piers Cawley wrote: > Michael G Schwern <[EMAIL PROTECTED]> writes: > > > On Mon, Jan 14, 2002 at 10:23:46AM +, Piers Cawley wrote: > >> Um... You're wrong. If you do need 'startup time' initialization then > >> you should do it in an INIT block. If I may quote from the > >> documentation: > > > > Like it or not, people put lots of init code into BEGIN blocks, if > > nothing else for backwards compatiblity with 5.005. perlcc has to > > compile real world programs. > > Deferring BEGIN blocks 'til runtime will break rather more realworld > program than it fixes I think. Where is deferring involved? -- Michael G. Schwern <[EMAIL PROTECTED]>http://www.pobox.com/~schwern/ Perl Quality Assurance <[EMAIL PROTECTED]> Kwalitee Is Job One Lord of Kwalitee! Wearer of the CPANTS and Slayer of Pseudo-hashes!
Re: Compiled programs to keep BEGIN blocks? (was Re: [RFC] Switch to make Test::Builder output even if $^C ( for B::C ))
On Mon, Jan 14, 2002 at 04:16:49PM +, Piers Cawley wrote: > > Like I said, if B::Deparse can do it, B::C can. > > But it shouldn't. How do you distinguish between: > >use Foo; > > (needs to use 'Foo' before generating the compiled script, otherwise > what's the bloody point?) > > and > >BEGIN { ... } Using Deep Magic as demonstrated inside B::Deparse by begin_is_use(). Module::Info uses a rather simplified version for it's modules_used() method. Not easy, but definately a (mostly) solved problem. > Also, as the docs for B::Deparse points out: > > we can't guarantee to produce BEGIN blocks or "use" declarations > in exactly the right place. > > Which can become a big problem when you find that your compiled script > doesn't work and there's no easy way of debugging the program that it > thinks it's evaluating. So is the answer to just exclude them entirely? That's the wrong way out. B::Deparse has slowly gotten very good at figuring out BEGIN blocks from 'use' statements and putting them in the right places. Hard fought knowledge. Steal from it. I don't expect perlcc to magically become perfect overnight. What I do expect is that the 'compiled programs won't run code in BEGIN blocks' be treated as a bug and not a feature and to look around at other bits of B which are taking a stab at solving these problems. -- Michael G. Schwern <[EMAIL PROTECTED]>http://www.pobox.com/~schwern/ Perl Quality Assurance <[EMAIL PROTECTED]> Kwalitee Is Job One Well, my work here is done. If you need me again, just admit that you're screwed and die.
Re: Compiled programs to keep BEGIN blocks? (was Re: [RFC] Switch to make Test::Builder output even if $^C ( for B::C ))
> On Sun, Jan 13, 2002 at 10:04:58PM +0100, Mattia Barbon wrote: > > > $ bleadperl -MO=-qq,Deparse foo.plx > > > sub BEGIN { > > > print "foo\n"; > > > } > > > print "bar\n"; > > > > > > If B::Deparse can save BEGIN blocks, B::C can. > > > > I didn't mean that I can't write code to make B::C save BEGIN blocks > > ( it'd require <10 lines, probably ), I did mean that doing so would > > not be a god idea: _I am > > saving the state of the program after those blocks were ran_ and > > they will be run _another time_ at runtime, and this is not correct: > > ( for example use lib 'a'; would put 'a' into @INC twice, once > > ( correctly ) at compile time, and another time ( incorrectly ) at > > runtime ). In this > > case this is not harmful, but you get the idea. > > I don't understand. The compiled program should do exactly what the > original program did. Anything else, as difficult as it may be, is a > bug. Lots of programs and modules do important load-time checks and > logic inside BEGIN blocks. > > Why would this: > > BEGIN { > push @INC, 'foo'; > } > > put 'foo' into @INC twice if it were compiled? The compiled program > should not be storing the post-BEGIN value of @INC, it should store > the original value at startup. This isn't the way B::C ( I suspect B::Bytecode and B::CC work the same way ) works. It _by design_ saves the state _after_ the BEGIB blocks are run; the idea is to skip compilation time. Now, I know this is not going to always work, and the only ( always ) working solution I see ( and I'd like to be proved wrong here ), is something like B::Script ( which stores the source code of the program+modules in a single executable ). And yes, I realized that [ B::C is not always going to work ] just a coule days ago. Regards Mattia
Compiled programs to keep BEGIN blocks? (was Re: [RFC] Switch to make Test::Builder output even if $^C ( for B::C ))
On Sun, Jan 13, 2002 at 10:04:58PM +0100, Mattia Barbon wrote: > > $ bleadperl -MO=-qq,Deparse foo.plx > > sub BEGIN { > > print "foo\n"; > > } > > print "bar\n"; > > > > If B::Deparse can save BEGIN blocks, B::C can. > > I didn't mean that I can't write code to make B::C save BEGIN blocks > ( it'd require <10 lines, probably ), I did mean that doing so would > not be a god idea: _I am > saving the state of the program after those blocks were ran_ and > they will be run _another time_ at runtime, and this is not correct: > ( for example use lib 'a'; would put 'a' into @INC twice, once > ( correctly ) at compile time, and another time ( incorrectly ) at > runtime ). In this > case this is not harmful, but you get the idea. I don't understand. The compiled program should do exactly what the original program did. Anything else, as difficult as it may be, is a bug. Lots of programs and modules do important load-time checks and logic inside BEGIN blocks. Why would this: BEGIN { push @INC, 'foo'; } put 'foo' into @INC twice if it were compiled? The compiled program should not be storing the post-BEGIN value of @INC, it should store the original value at startup. -- Michael G. Schwern <[EMAIL PROTECTED]>http://www.pobox.com/~schwern/ Perl Quality Assurance <[EMAIL PROTECTED]> Kwalitee Is Job One Me? A robot? That's rediculous! For one thing, that doesn't compute at all!