⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ch18_03.htm

📁 编程珍珠,里面很多好用的代码,大家可以参考学习呵呵,
💻 HTM
字号:
<html><head><title>Executing Your Code (Programming Perl)</title><!-- STYLESHEET --><link rel="stylesheet" type="text/css" href="../style/style1.css"><!-- METADATA --><!--Dublin Core Metadata--><meta name="DC.Creator" content=""><meta name="DC.Date" content=""><meta name="DC.Format" content="text/xml" scheme="MIME"><meta name="DC.Generator" content="XSLT stylesheet, xt by James Clark"><meta name="DC.Identifier" content=""><meta name="DC.Language" content="en-US"><meta name="DC.Publisher" content="O'Reilly &amp; Associates, Inc."><meta name="DC.Source" content="" scheme="ISBN"><meta name="DC.Subject.Keyword" content=""><meta name="DC.Title" content="Executing Your Code"><meta name="DC.Type" content="Text.Monograph"></head><body><!-- START OF BODY --><!-- TOP BANNER --><img src="gifs/smbanner.gif" usemap="#banner-map" border="0" alt="Book Home"><map name="banner-map"><AREA SHAPE="RECT" COORDS="0,0,466,71" HREF="index.htm" ALT="Programming Perl"><AREA SHAPE="RECT" COORDS="467,0,514,18" HREF="jobjects/fsearch.htm" ALT="Search this book"></map><!-- TOP NAV BAR --><div class="navbar"><table width="515" border="0"><tr><td align="left" valign="top" width="172"><a href="ch18_02.htm"><img src="../gifs/txtpreva.gif" alt="Previous" border="0"></a></td><td align="center" valign="top" width="171"><a href="ch18_01.htm">Chapter 18: Compiling</a></td><td align="right" valign="top" width="172"><a href="ch18_04.htm"><img src="../gifs/txtnexta.gif" alt="Next" border="0"></a></td></tr></table></div><hr width="515" align="left"><!-- SECTION BODY --><h2 class="sect1">18.3. Executing Your Code</h2><a name="INDEX-3254"></a><p><a name="INDEX-3255"></a>To the first approximation, Sparc programs only run on Sparcmachines, Intel programs only run on Intel machines, and Perlprograms only run on Perl machines.  A Perl machine possesses thoseattributes that a Perl program would find ideal in a computer: memory that is automatically allocated and deallocated, fundamentaldata types that are dynamic strings, arrays, and hashes, and have nosize limits, and systems that all behave pretty much the same way.  Thejob of the Perl interpreter is to make whatever computer it happens tobe running on appear to be one of these idealistic Perl machines.</p><p><a name="INDEX-3256"></a><a name="INDEX-3257"></a><a name="INDEX-3258"></a><a name="INDEX-3259"></a>This fictitious machine presents the illusion of a computer speciallydesigned to do nothing but run Perl programs.  Each opcode produced bythe compiler is a fundamental command in this emulated instructionset.  Instead of a hardware program counter, the interpreter justkeeps track of the current opcode to execute.  Instead of a hardwarestack pointer, the interpreter has its own virtual stack.  This stackis very important because the Perl virtual machine (which we refuse tocall a PVM) is a stack-based machine.  Perl opcodes are internallycalled <em class="emphasis">PP codes</em> (short for "push-pop codes")because they manipulate the interpreter's virtual stack to findall operands, process temporary values, and store all results.</p><p>If you've ever programmed in Forth or PostScript, or used an HPscientific calculator with RPN ("Reverse Polish Notation") entry, youknow how a stack machine works.  Even if you haven't, the concept issimple: to add 3 and 4, you do things in the order <tt class="literal">3 4 +</tt> instead ofthe more conventional <tt class="literal">3 + 4</tt>.  What this means in terms of the stackis that you push <tt class="literal">3</tt> and then <tt class="literal">4</tt> onto the stack, and <tt class="literal">+</tt> then popsboth arguments off the stack, adds them, and pushes <tt class="literal">7</tt> back onto thestack, where it will sit until you do something else with it.</p><p>Compared with the Perl compiler, the Perl interpreter is astraightforward, almost boring, program.  All it does is step throughthe compiled opcodes, one at a time, and dispatch them to the Perlrun-time environment, that is, the Perl virtual machine.  It's justa wad of C code, right?</p><p>Actually, it's not boring at all.  A Perl virtual machine keeps trackof a great deal of dynamic context on your behalf so that you don'thave to.  Perl maintains quite a few stacks, which you don't have tounderstand, but which we'll list here anyway just to impress you:<a name="INDEX-3260"></a></p><dl><dt><b>operand stack</b></dt><dd><p>That's the stack we already talked about.<a name="INDEX-"></a></p></dd><dt><b>save stack</b></dt><dd><p>Where localized values are saved pending restoration.  Manyinternal routines also localize values without your knowing it.<a name="INDEX-"></a><a name="INDEX-"></a></p></dd><dt><b>scope stack</b></dt><dd><p>The lightweight dynamic context that controls whenthe save stack should be "popped".<a name="INDEX-"></a></p></dd><dt><b>context stack</b></dt><dd><p> The heavyweight dynamiccontext; who called whom to get where you are now.  The<tt class="literal">caller</tt> function traverses this stack.  Loop-controlfunctions scan this stack to find out which loop to control. When youpeel back the context stack, the scope stack gets peeled backappropriately, which restores all your local variables from the savestack, even if you left the earlier context by nefarious methods suchas raising an exception and <em class="emphasis">longjmp</em>(3)ing out.<a name="INDEX-"></a></p></dd><dt><b>jumpenv stack</b></dt><dd><p>The stack of <em class="emphasis">longjmp</em>(3) contexts that allows us to raise exceptions orexit expeditiously.<a name="INDEX-"></a></p></dd><dt><b>return stack</b></dt><dd><p>Where we came from when we entered this subroutine.<a name="INDEX-"></a></p></dd><dt><b>mark stack</b></dt><dd><p>Where the current variadic argument list on the operand stack starts.<a name="INDEX-"></a></p></dd><dt><b>recursive lexical pad stacks</b></dt><dd><p>Where the lexical variables and other "scratch register" storage iskept when subroutines are called recursively.<a name="INDEX-"></a><a name="INDEX-"></a></p></dd></dl><p></p><p><a name="INDEX-3261"></a>And of course, there's the C stack on which all the C variables arestored.  Perl actually tries to avoid relying on C's stack for thestorage of saved values, since <em class="emphasis">longjmp</em>(3) bypasses the properrestoration of such values.</p><p>All this is to say that the usual view of an interpreter, a programthat interprets another program, is really woefully inadequate todescribe what's going on here.  Yes, there's some C code implementingsome opcodes, but when we say "interpreter", we mean something morethan that, in the same way that when we say "musician", we mean somethingmore than a set of DNA instructions for turning notes into sounds.Musicians are real, live organisms and have "state".  So do interpreters.</p><p><a name="INDEX-3262"></a>Specifically, all this dynamic and lexical context, along with theglobal symbol tables, plus the parse trees, plus a thread of execution,is what we call an interpreter.  As a context for execution, aninterpreter really starts its existence even before the compilerstarts, and can run in rudimentary form even as the compiler isbuilding up the interpreter's context.  In fact, that's preciselywhat's happening when the compiler calls into the interpreter toexecute <tt class="literal">BEGIN</tt> blocks and such.  And the interpreter can turn aroundand use the compiler to build itself up further.  Every time you defineanother subroutine or load another module, the particular virtual Perlmachine we call an interpreter is redefining itself.  You can't reallysay that either the compiler or the interpreter is in control, becausethey're cooperating to control the bootstrap process we commonly call"running a Perl script".  It's like bootstrapping a child's brain.  Is itthe DNA doing it or is it the neurons?  A little of both, we think,with some input from external programmers.<a name="INDEX-3263"></a></p><p>It's possible to run multiple interpreters in the sameprocess; they may or may not share parse trees, depending on whetherthey were started by cloning an existing interpreter or by building anew interpreter from scratch.  It's also possible to run multiplethreads in a single interpreter, in which case they share notonly parse trees but also global symbols--see <a href="ch17_01.htm">Chapter 17, "Threads"</a>.<a name="INDEX-3264"></a><a name="INDEX-3265"></a></p><p><a name="INDEX-3266"></a><a name="INDEX-3267"></a><a name="INDEX-3268"></a>But most Perl programs use only a single Perl interpreter to executetheir compiled code.  And while you can run multiple, independent Perlinterpreters within one process, the current API for this is onlyaccessible from C.<a href="#FOOTNOTE-5">[5]</a> Each individual Perl interpreter servesthe role of a completely separate process, but doesn't cost as much tocreate as a whole new process does.  That's how Apache's<tt class="literal">mod_perl</tt> extension gets such great performance:when you launch a CGI script under <tt class="literal">mod_perl</tt>, thatscript has already been compiled into Perl opcodes, eliminating theneed for recompilation--but more importantly, eliminating the need tostart a new process, which is the real bottleneck.  Apache initializesa new Perl interpreter in an existing process and hands thatinterpreter the previously compiled code to execute.  Of course,there's much more to it than that--there always is.  For moreabout <tt class="literal">mod_perl</tt>, see <em class="citetitle">WritingApache Modules with Perl and C</em> (O'Reilly, 1999).</p><blockquote class="footnote"><a name="FOOTNOTE-5"></a><p>[5] With one exception, so far:revision 5.6.0 of Perl can do cloned interpreters in support of<tt class="literal">fork</tt> emulation on Microsoft Windows.  There maywell be a Perl API to "ithreads", as they're called, by the time youread this.</p></blockquote><p><a name="INDEX-3269"></a>Many other applications such as <em class="emphasis">nvi</em>, <em class="emphasis">vim</em>, and <em class="emphasis">innd</em> can embedPerl interpreters; we can't hope to list them all here.  There are anumber of commercial products that don't even advertise that they haveembedded Perl engines.  They just use it internally because it getstheir job done in style.</p><a name="INDEX-3270"></a><!-- BOTTOM NAV BAR --><hr width="515" align="left"><div class="navbar"><table width="515" border="0"><tr><td align="left" valign="top" width="172"><a href="ch18_02.htm"><img src="../gifs/txtpreva.gif" alt="Previous" border="0"></a></td><td align="center" valign="top" width="171"><a href="index.htm"><img src="../gifs/txthome.gif" alt="Home" border="0"></a></td><td align="right" valign="top" width="172"><a href="ch18_04.htm"><img src="../gifs/txtnexta.gif" alt="Next" border="0"></a></td></tr><tr><td align="left" valign="top" width="172">18.2. Compiling Your Code</td><td align="center" valign="top" width="171"><a href="index/index.htm"><img src="../gifs/index.gif" alt="Book Index" border="0"></a></td><td align="right" valign="top" width="172">18.4. Compiler Backends</td></tr></table></div><hr width="515" align="left"><!-- LIBRARY NAV BAR --><img src="../gifs/smnavbar.gif" usemap="#library-map" border="0" alt="Library Navigation Links"><p><font size="-1"><a href="copyrght.htm">Copyright &copy; 2001</a> O'Reilly &amp; Associates. All rights reserved.</font></p><map name="library-map"> <area shape="rect" coords="2,-1,79,99" href="../index.htm"><area shape="rect" coords="84,1,157,108" href="../perlnut/index.htm"><area shape="rect" coords="162,2,248,125" href="../prog/index.htm"><area shape="rect" coords="253,2,326,130" href="../advprog/index.htm"><area shape="rect" coords="332,1,407,112" href="../cookbook/index.htm"><area shape="rect" coords="414,2,523,103" href="../sysadmin/index.htm"></map><!-- END OF BODY --></body></html>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -