home *** CD-ROM | disk | FTP | other *** search
- Path: sparky!uunet!zaphod.mps.ohio-state.edu!sol.ctr.columbia.edu!usc!news!netlabs!lwall
- From: lwall@netlabs.com (Larry Wall)
- Newsgroups: comp.lang.perl
- Subject: Re: Bad label: _EVAL_, inconsistent behavior
- Keywords: eval, setuidness, etc.
- Message-ID: <1992Aug15.192751.10406@netlabs.com>
- Date: 15 Aug 92 19:27:51 GMT
- References: <1992Aug14.184402.25912@rayssd.ssd.ray.com>
- Sender: news@netlabs.com
- Distribution: usa
- Organization: NetLabs, Inc.
- Lines: 53
- Nntp-Posting-Host: scalpel.netlabs.com
-
- In article <1992Aug14.184402.25912@rayssd.ssd.ray.com> ras@rayssd.ssd.ray.com (Shaw) writes:
- : ...
- : Bad label: _EVAL_ at passutils.pl line 375, <STDIN> line 3.
- :
- : I've also tried:
- : eval "return \$answer if (\$answer =~ $test)";
- : and
- : eval qq:return $answer if (\$answer =~ $test):;
- : as well as a few other combnations. The "Bad label:" message
- : comes out on the next call to the subroutine after I've changed
- : something, and refers to <STDIN> line N, where N is the number of
- : times it's run the sub and gotten an answer.
- :
- : Any clues? I find no reference to _EVAL_ in the Book, and mysterious
- : references to the "qq" mechanism didn't seem to help either.
-
- You're basically confusing the heck out of the runtime system by
- returning from something that isn't a subroutine. The text of an eval
- is considered its own thing, like a parameterless subroutine. If
- return were to mean anything in an eval, it should probably mean to
- terminate the eval itself rather than the surrounding subroutine, if any.
-
- The gory details go like this: the subroutine, if it contains a return
- (and that means an ordinary return, not one embedded in an eval, which
- the parser can't see at compile time--your subroutine happens to have
- one, but your program would have blown up differently if it hadn't),
- pushes a mystical label _SUB_ on the label stack so the return will
- know where to longjmp() out to. The eval then sets the global Boolean
- variable in_eval and pushes a mystical label _EVAL_ onto the label
- stack so that fatal errors know they are being trapped and should
- longjmp() back to the eval code. When you do a return in an eval, it
- pops the _EVAL_ label, finds the _SUB_ label, and does a longjmp()
- around the eval "destructor" code that turns off the global in_eval
- flag, so the NEXT time you get a fatal error it tries to return to a
- no-longer existing _EVAL_ label. (Yes, I could just look for an _EVAL_
- label instead of testing in_eval, but in_eval is used other places
- too. Among other things, the tokener has to know whether it's reading
- from a string or from a file. I'm planning on doing away with
- longjmp() anyway, so it's not really an issue in Perl 5--the
- "destructor" code will presumably reset in_eval correctly.)
-
- Anyway, I'm not going to advertise a fix for it until I decide what
- "return" really should mean in an eval. I don't think it's reasonable
- to try to pretend that evaled code is inlined--for one thing, it would
- mean I'd have to turn off many of the optimizations that are done in a
- subroutine containing an eval. And it would be nice to have a way to
- short-circuit an eval or a require. There's no way to do that
- conveniently at the moment without faking a fatal error, which is
- useless in require and even in eval has the unwanted side effect of
- setting $@. If you expect return to terminate an eval in Perl 5,
- you're unlikely to be surprised... :-)
-
- Larry
-