Unified · Split
| @@ -81,7 +81,7 @@ none: · 80 unmodified lines | ||
| 81 | 81 | @echo " $(PLATS)" |
| 82 | 82 | @echo "See doc/readme.html for complete instructions." |
| 83 | 83 | |
| 84 | −# make may get confused with test/ and install/ in a case-insensitive OS | |
| 84 | +# make may get confused with test/ and install/ | |
| 85 | 85 | dummy: |
| 86 | 86 | |
| 87 | 87 | # echo config parameters |
| @@ -1,4 +1,4 @@ | ||
| 1 | −This is Lua 5.2 (work2), released on 13 Jan 2010. | |
| 1 | +This is Lua 5.2 (work3), released on 18 May 2010. | |
| 2 | 2 | |
| 3 | 3 | For information about Lua, including installation instructions and |
| 4 | 4 | license details, see doc/readme.html. |
Binary file not shown.
| @@ -20,6 +20,11 @@ ul { · 19 unmodified lines | ||
| 20 | 20 | Lua 5.2 Reference Manual |
| 21 | 21 | </H1> |
| 22 | 22 | |
| 23 | +<IMG SRC="alert.png" ALIGN="absbottom"> | |
| 24 | +<EM>This is a work version of Lua 5.2. | |
| 25 | +Everything may change in the final version.</EM> | |
| 26 | +<P> | |
| 27 | + | |
| 23 | 28 | The reference manual is the official definition of the Lua language. |
| 24 | 29 | For a complete introduction to Lua programming, see the book |
| 25 | 30 | <A HREF="http://www.lua.org/docs.html#books">Programming in Lua</A>. |
| @@ -42,94 +47,95 @@ Freely available under the terms of the · 16 unmodified lines | ||
| 42 | 47 | <UL style="padding: 0"> |
| 43 | 48 | <LI><A HREF="manual.html">1 - Introduction</A> |
| 44 | 49 | <P> |
| 45 | −<LI><A HREF="manual.html#2">2 - The Language</A> | |
| 50 | +<LI><A HREF="manual.html#2">2 - Basic Concepts</A> | |
| 46 | 51 | <UL> |
| 47 | −<LI><A HREF="manual.html#2.1">2.1 - Lexical Conventions</A> | |
| 48 | −<LI><A HREF="manual.html#2.2">2.2 - Values and Types</A> | |
| 52 | +<LI><A HREF="manual.html#2.1">2.1 - Values and Types</A> | |
| 53 | +<LI><A HREF="manual.html#2.2">2.2 - Environments and the Global Environment</A> | |
| 54 | +<LI><A HREF="manual.html#2.3">2.3 - Error Handling</A> | |
| 55 | +<LI><A HREF="manual.html#2.4">2.4 - Metatables</A> | |
| 56 | +<LI><A HREF="manual.html#2.5">2.5 - Garbage Collection</A> | |
| 49 | 57 | <UL> |
| 50 | −<LI><A HREF="manual.html#2.2.1">2.2.1 - Coercion</A> | |
| 58 | +<LI><A HREF="manual.html#2.5.1">2.5.1 - Garbage-Collection Metamethods</A> | |
| 59 | +<LI><A HREF="manual.html#2.5.2">2.5.2 - Weak Tables</A> | |
| 51 | 60 | </UL> |
| 52 | −<LI><A HREF="manual.html#2.3">2.3 - Variables</A> | |
| 53 | −<LI><A HREF="manual.html#2.4">2.4 - Statements</A> | |
| 54 | −<UL> | |
| 55 | −<LI><A HREF="manual.html#2.4.1">2.4.1 - Chunks</A> | |
| 56 | −<LI><A HREF="manual.html#2.4.2">2.4.2 - Blocks</A> | |
| 57 | −<LI><A HREF="manual.html#2.4.3">2.4.3 - Assignment</A> | |
| 58 | −<LI><A HREF="manual.html#2.4.4">2.4.4 - Control Structures</A> | |
| 59 | −<LI><A HREF="manual.html#2.4.5">2.4.5 - For Statement</A> | |
| 60 | −<LI><A HREF="manual.html#2.4.6">2.4.6 - Function Calls as Statements</A> | |
| 61 | −<LI><A HREF="manual.html#2.4.7">2.4.7 - Local Declarations</A> | |
| 62 | −<LI><A HREF="manual.html#2.4.8">2.4.8 - Lexical Environments</A> | |
| 61 | +<LI><A HREF="manual.html#2.6">2.6 - Coroutines</A> | |
| 63 | 62 | </UL> |
| 64 | −<LI><A HREF="manual.html#2.5">2.5 - Expressions</A> | |
| 63 | +<P> | |
| 64 | +<LI><A HREF="manual.html#3">3 - The Language</A> | |
| 65 | +<UL> | |
| 66 | +<LI><A HREF="manual.html#3.1">3.1 - Lexical Conventions</A> | |
| 67 | +<LI><A HREF="manual.html#3.2">3.2 - Variables</A> | |
| 68 | +<LI><A HREF="manual.html#3.3">3.3 - Statements</A> | |
| 65 | 69 | <UL> |
| 66 | −<LI><A HREF="manual.html#2.5.1">2.5.1 - Arithmetic Operators</A> | |
| 67 | −<LI><A HREF="manual.html#2.5.2">2.5.2 - Relational Operators</A> | |
| 68 | −<LI><A HREF="manual.html#2.5.3">2.5.3 - Logical Operators</A> | |
| 69 | −<LI><A HREF="manual.html#2.5.4">2.5.4 - Concatenation</A> | |
| 70 | −<LI><A HREF="manual.html#2.5.5">2.5.5 - The Length Operator</A> | |
| 71 | −<LI><A HREF="manual.html#2.5.6">2.5.6 - Precedence</A> | |
| 72 | −<LI><A HREF="manual.html#2.5.7">2.5.7 - Table Constructors</A> | |
| 73 | −<LI><A HREF="manual.html#2.5.8">2.5.8 - Function Calls</A> | |
| 74 | −<LI><A HREF="manual.html#2.5.9">2.5.9 - Function Definitions</A> | |
| 70 | +<LI><A HREF="manual.html#3.3.1">3.3.1 - Chunks</A> | |
| 71 | +<LI><A HREF="manual.html#3.3.2">3.3.2 - Blocks</A> | |
| 72 | +<LI><A HREF="manual.html#3.3.3">3.3.3 - Assignment</A> | |
| 73 | +<LI><A HREF="manual.html#3.3.4">3.3.4 - Control Structures</A> | |
| 74 | +<LI><A HREF="manual.html#3.3.5">3.3.5 - For Statement</A> | |
| 75 | +<LI><A HREF="manual.html#3.3.6">3.3.6 - Function Calls as Statements</A> | |
| 76 | +<LI><A HREF="manual.html#3.3.7">3.3.7 - Local Declarations</A> | |
| 75 | 77 | </UL> |
| 76 | −<LI><A HREF="manual.html#2.6">2.6 - Visibility Rules</A> | |
| 77 | −<LI><A HREF="manual.html#2.7">2.7 - Error Handling</A> | |
| 78 | −<LI><A HREF="manual.html#2.8">2.8 - Metatables</A> | |
| 79 | −<LI><A HREF="manual.html#2.9">2.9 - Environments</A> | |
| 80 | −<LI><A HREF="manual.html#2.10">2.10 - Garbage Collection</A> | |
| 78 | +<LI><A HREF="manual.html#3.4">3.4 - Expressions</A> | |
| 81 | 79 | <UL> |
| 82 | −<LI><A HREF="manual.html#2.10.1">2.10.1 - Garbage-Collection Metamethods</A> | |
| 83 | −<LI><A HREF="manual.html#2.10.2">2.10.2 - Weak Tables</A> | |
| 80 | +<LI><A HREF="manual.html#3.4.1">3.4.1 - Arithmetic Operators</A> | |
| 81 | +<LI><A HREF="manual.html#3.4.2">3.4.2 - Coercion</A> | |
| 82 | +<LI><A HREF="manual.html#3.4.3">3.4.3 - Relational Operators</A> | |
| 83 | +<LI><A HREF="manual.html#3.4.4">3.4.4 - Logical Operators</A> | |
| 84 | +<LI><A HREF="manual.html#3.4.5">3.4.5 - Concatenation</A> | |
| 85 | +<LI><A HREF="manual.html#3.4.6">3.4.6 - The Length Operator</A> | |
| 86 | +<LI><A HREF="manual.html#3.4.7">3.4.7 - Precedence</A> | |
| 87 | +<LI><A HREF="manual.html#3.4.8">3.4.8 - Table Constructors</A> | |
| 88 | +<LI><A HREF="manual.html#3.4.9">3.4.9 - Function Calls</A> | |
| 89 | +<LI><A HREF="manual.html#3.4.10">3.4.10 - Function Definitions</A> | |
| 84 | 90 | </UL> |
| 85 | −<LI><A HREF="manual.html#2.11">2.11 - Coroutines</A> | |
| 91 | +<LI><A HREF="manual.html#3.5">3.5 - Visibility Rules</A> | |
| 86 | 92 | </UL> |
| 87 | 93 | <P> |
| 88 | −<LI><A HREF="manual.html#3">3 - The Application Program Interface</A> | |
| 94 | +<LI><A HREF="manual.html#4">4 - The Application Program Interface</A> | |
| 89 | 95 | <UL> |
| 90 | −<LI><A HREF="manual.html#3.1">3.1 - The Stack</A> | |
| 91 | −<LI><A HREF="manual.html#3.2">3.2 - Stack Size</A> | |
| 92 | −<LI><A HREF="manual.html#3.3">3.3 - Pseudo-Indices</A> | |
| 93 | −<LI><A HREF="manual.html#3.4">3.4 - C Closures</A> | |
| 94 | −<LI><A HREF="manual.html#3.5">3.5 - Registry</A> | |
| 95 | −<LI><A HREF="manual.html#3.6">3.6 - Error Handling in C</A> | |
| 96 | −<LI><A HREF="manual.html#3.7">3.7 - Handling Yields in C</A> | |
| 97 | −<LI><A HREF="manual.html#3.8">3.8 - Functions and Types</A> | |
| 98 | −<LI><A HREF="manual.html#3.9">3.9 - The Debug Interface</A> | |
| 96 | +<LI><A HREF="manual.html#4.1">4.1 - The Stack</A> | |
| 97 | +<LI><A HREF="manual.html#4.2">4.2 - Stack Size</A> | |
| 98 | +<LI><A HREF="manual.html#4.3">4.3 - Pseudo-Indices</A> | |
| 99 | +<LI><A HREF="manual.html#4.4">4.4 - C Closures</A> | |
| 100 | +<LI><A HREF="manual.html#4.5">4.5 - Registry</A> | |
| 101 | +<LI><A HREF="manual.html#4.6">4.6 - Error Handling in C</A> | |
| 102 | +<LI><A HREF="manual.html#4.7">4.7 - Handling Yields in C</A> | |
| 103 | +<LI><A HREF="manual.html#4.8">4.8 - Functions and Types</A> | |
| 104 | +<LI><A HREF="manual.html#4.9">4.9 - The Debug Interface</A> | |
| 99 | 105 | </UL> |
| 100 | 106 | <P> |
| 101 | −<LI><A HREF="manual.html#4">4 - The Auxiliary Library</A> | |
| 107 | +<LI><A HREF="manual.html#5">5 - The Auxiliary Library</A> | |
| 102 | 108 | <UL> |
| 103 | −<LI><A HREF="manual.html#4.1">4.1 - Functions and Types</A> | |
| 109 | +<LI><A HREF="manual.html#5.1">5.1 - Functions and Types</A> | |
| 104 | 110 | </UL> |
| 105 | 111 | <P> |
| 106 | −<LI><A HREF="manual.html#5">5 - Standard Libraries</A> | |
| 112 | +<LI><A HREF="manual.html#6">6 - Standard Libraries</A> | |
| 107 | 113 | <UL> |
| 108 | −<LI><A HREF="manual.html#5.1">5.1 - Basic Functions</A> | |
| 109 | −<LI><A HREF="manual.html#5.2">5.2 - Coroutine Manipulation</A> | |
| 110 | −<LI><A HREF="manual.html#5.3">5.3 - Modules</A> | |
| 111 | −<LI><A HREF="manual.html#5.4">5.4 - String Manipulation</A> | |
| 114 | +<LI><A HREF="manual.html#6.1">6.1 - Basic Functions</A> | |
| 115 | +<LI><A HREF="manual.html#6.2">6.2 - Coroutine Manipulation</A> | |
| 116 | +<LI><A HREF="manual.html#6.3">6.3 - Modules</A> | |
| 117 | +<LI><A HREF="manual.html#6.4">6.4 - String Manipulation</A> | |
| 112 | 118 | <UL> |
| 113 | −<LI><A HREF="manual.html#5.4.1">5.4.1 - Patterns</A> | |
| 119 | +<LI><A HREF="manual.html#6.4.1">6.4.1 - Patterns</A> | |
| 114 | 120 | </UL> |
| 115 | −<LI><A HREF="manual.html#5.5">5.5 - Table Manipulation</A> | |
| 116 | −<LI><A HREF="manual.html#5.6">5.6 - Mathematical Functions</A> | |
| 117 | −<LI><A HREF="manual.html#5.7">5.7 - Bitwise operations</A> | |
| 118 | −<LI><A HREF="manual.html#5.8">5.8 - Input and Output Facilities</A> | |
| 119 | −<LI><A HREF="manual.html#5.9">5.9 - Operating System Facilities</A> | |
| 120 | −<LI><A HREF="manual.html#5.10">5.10 - The Debug Library</A> | |
| 121 | +<LI><A HREF="manual.html#6.5">6.5 - Table Manipulation</A> | |
| 122 | +<LI><A HREF="manual.html#6.6">6.6 - Mathematical Functions</A> | |
| 123 | +<LI><A HREF="manual.html#6.7">6.7 - Bitwise operations</A> | |
| 124 | +<LI><A HREF="manual.html#6.8">6.8 - Input and Output Facilities</A> | |
| 125 | +<LI><A HREF="manual.html#6.9">6.9 - Operating System Facilities</A> | |
| 126 | +<LI><A HREF="manual.html#6.10">6.10 - The Debug Library</A> | |
| 121 | 127 | </UL> |
| 122 | 128 | <P> |
| 123 | −<LI><A HREF="manual.html#6">6 - Lua Stand-alone</A> | |
| 129 | +<LI><A HREF="manual.html#7">7 - Lua Stand-alone</A> | |
| 124 | 130 | <P> |
| 125 | −<LI><A HREF="manual.html#7">7 - Incompatibilities with the Previous Version</A> | |
| 131 | +<LI><A HREF="manual.html#8">8 - Incompatibilities with the Previous Version</A> | |
| 126 | 132 | <UL> |
| 127 | −<LI><A HREF="manual.html#7.1">7.1 - Changes in the Language</A> | |
| 128 | −<LI><A HREF="manual.html#7.2">7.2 - Changes in the Libraries</A> | |
| 129 | −<LI><A HREF="manual.html#7.3">7.3 - Changes in the API</A> | |
| 133 | +<LI><A HREF="manual.html#8.1">8.1 - Changes in the Language</A> | |
| 134 | +<LI><A HREF="manual.html#8.2">8.2 - Changes in the Libraries</A> | |
| 135 | +<LI><A HREF="manual.html#8.3">8.3 - Changes in the API</A> | |
| 130 | 136 | </UL> |
| 131 | 137 | <P> |
| 132 | −<LI><A HREF="manual.html#8">8 - The Complete Syntax of Lua</A> | |
| 138 | +<LI><A HREF="manual.html#9">9 - The Complete Syntax of Lua</A> | |
| 133 | 139 | </UL> |
| 134 | 140 | |
| 135 | 141 | <H2><A NAME="index">Index</A></H2> |
| @@ -144,7 +150,6 @@ Freely available under the terms of the · 8 unmodified lines | ||
| 144 | 150 | <A HREF="manual.html#pdf-dofile">dofile</A><BR> |
| 145 | 151 | <A HREF="manual.html#pdf-error">error</A><BR> |
| 146 | 152 | <A HREF="manual.html#pdf-getmetatable">getmetatable</A><BR> |
| 147 | −<A HREF="manual.html#pdf-ipairs">ipairs</A><BR> | |
| 148 | 153 | <A HREF="manual.html#pdf-load">load</A><BR> |
| 149 | 154 | <A HREF="manual.html#pdf-loadin">loadin</A><BR> |
| 150 | 155 | <A HREF="manual.html#pdf-loadfile">loadfile</A><BR> |
| @@ -169,10 +174,12 @@ Freely available under the terms of the · 18 unmodified lines | ||
| 169 | 174 | <A HREF="manual.html#pdf-bit.band">bit.band</A><BR> |
| 170 | 175 | <A HREF="manual.html#pdf-bit.bnot">bit.bnot</A><BR> |
| 171 | 176 | <A HREF="manual.html#pdf-bit.bor">bit.bor</A><BR> |
| 172 | −<A HREF="manual.html#pdf-bit.brotate">bit.brotate</A><BR> | |
| 173 | −<A HREF="manual.html#pdf-bit.bshift">bit.bshift</A><BR> | |
| 174 | 177 | <A HREF="manual.html#pdf-bit.btest">bit.btest</A><BR> |
| 175 | 178 | <A HREF="manual.html#pdf-bit.bxor">bit.bxor</A><BR> |
| 179 | +<A HREF="manual.html#pdf-bit.lshift">bit.lshift</A><BR> | |
| 180 | +<A HREF="manual.html#pdf-bit.rol">bit.rol</A><BR> | |
| 181 | +<A HREF="manual.html#pdf-bit.ror">bit.ror</A><BR> | |
| 182 | +<A HREF="manual.html#pdf-bit.rshift">bit.rshift</A><BR> | |
| 176 | 183 | <P> |
| 177 | 184 | |
| 178 | 185 | <A HREF="manual.html#pdf-coroutine.create">coroutine.create</A><BR> |
| @@ -199,10 +206,8 @@ Freely available under the terms of the · 20 unmodified lines | ||
| 199 | 206 | <A HREF="manual.html#pdf-debug.traceback">debug.traceback</A><BR> |
| 200 | 207 | <A HREF="manual.html#pdf-debug.upvalueid">debug.upvalueid</A><BR> |
| 201 | 208 | <A HREF="manual.html#pdf-debug.upvaluejoin">debug.upvaluejoin</A><BR> |
| 209 | +<P> | |
| 202 | 210 | |
| 203 | −</TD> | |
| 204 | −<TD> | |
| 205 | −<H3> </H3> | |
| 206 | 211 | <A HREF="manual.html#pdf-file:close">file:close</A><BR> |
| 207 | 212 | <A HREF="manual.html#pdf-file:flush">file:flush</A><BR> |
| 208 | 213 | <A HREF="manual.html#pdf-file:lines">file:lines</A><BR> |
| @@ -228,6 +233,9 @@ Freely available under the terms of the · 19 unmodified lines | ||
| 228 | 233 | <A HREF="manual.html#pdf-io.write">io.write</A><BR> |
| 229 | 234 | <P> |
| 230 | 235 | |
| 236 | +</TD> | |
| 237 | +<TD> | |
| 238 | +<H3> </H3> | |
| 231 | 239 | <A HREF="manual.html#pdf-math.abs">math.abs</A><BR> |
| 232 | 240 | <A HREF="manual.html#pdf-math.acos">math.acos</A><BR> |
| 233 | 241 | <A HREF="manual.html#pdf-math.asin">math.asin</A><BR> |
| @@ -320,6 +328,7 @@ Freely available under the terms of the · 86 unmodified lines | ||
| 320 | 328 | <A HREF="manual.html#lua_Writer">lua_Writer</A><BR> |
| 321 | 329 | <P> |
| 322 | 330 | |
| 331 | +<A HREF="manual.html#lua_absindex">lua_absindex</A><BR> | |
| 323 | 332 | <A HREF="manual.html#lua_atpanic">lua_atpanic</A><BR> |
| 324 | 333 | <A HREF="manual.html#lua_call">lua_call</A><BR> |
| 325 | 334 | <A HREF="manual.html#lua_callk">lua_callk</A><BR> |
| @@ -337,8 +346,8 @@ Freely available under the terms of the · 11 unmodified lines | ||
| 337 | 346 | <A HREF="manual.html#lua_getfenv">lua_getfenv</A><BR> |
| 338 | 347 | <A HREF="manual.html#lua_getfield">lua_getfield</A><BR> |
| 339 | 348 | <A HREF="manual.html#lua_getglobal">lua_getglobal</A><BR> |
| 340 | −<A HREF="manual.html#lua_gethookcount">lua_gethookcount</A><BR> | |
| 341 | 349 | <A HREF="manual.html#lua_gethook">lua_gethook</A><BR> |
| 350 | +<A HREF="manual.html#lua_gethookcount">lua_gethookcount</A><BR> | |
| 342 | 351 | <A HREF="manual.html#lua_gethookmask">lua_gethookmask</A><BR> |
| 343 | 352 | <A HREF="manual.html#lua_getinfo">lua_getinfo</A><BR> |
| 344 | 353 | <A HREF="manual.html#lua_getlocal">lua_getlocal</A><BR> |
| @@ -385,11 +394,11 @@ Freely available under the terms of the · 40 unmodified lines | ||
| 385 | 394 | <A HREF="manual.html#lua_pushvalue">lua_pushvalue</A><BR> |
| 386 | 395 | <A HREF="manual.html#lua_pushvfstring">lua_pushvfstring</A><BR> |
| 387 | 396 | <A HREF="manual.html#lua_rawequal">lua_rawequal</A><BR> |
| 388 | −<A HREF="manual.html#lua_rawgeti">lua_rawgeti</A><BR> | |
| 389 | 397 | <A HREF="manual.html#lua_rawget">lua_rawget</A><BR> |
| 398 | +<A HREF="manual.html#lua_rawgeti">lua_rawgeti</A><BR> | |
| 390 | 399 | <A HREF="manual.html#lua_rawlen">lua_rawlen</A><BR> |
| 391 | −<A HREF="manual.html#lua_rawseti">lua_rawseti</A><BR> | |
| 392 | 400 | <A HREF="manual.html#lua_rawset">lua_rawset</A><BR> |
| 401 | +<A HREF="manual.html#lua_rawseti">lua_rawseti</A><BR> | |
| 393 | 402 | <A HREF="manual.html#lua_register">lua_register</A><BR> |
| 394 | 403 | <A HREF="manual.html#lua_remove">lua_remove</A><BR> |
| 395 | 404 | <A HREF="manual.html#lua_replace">lua_replace</A><BR> |
| @@ -464,6 +473,7 @@ Freely available under the terms of the · 68 unmodified lines | ||
| 464 | 473 | <A HREF="manual.html#luaL_loadstring">luaL_loadstring</A><BR> |
| 465 | 474 | <A HREF="manual.html#luaL_newmetatable">luaL_newmetatable</A><BR> |
| 466 | 475 | <A HREF="manual.html#luaL_newstate">luaL_newstate</A><BR> |
| 476 | +<A HREF="manual.html#luaL_openlib">luaL_openlib</A><BR> | |
| 467 | 477 | <A HREF="manual.html#luaL_openlibs">luaL_openlibs</A><BR> |
| 468 | 478 | <A HREF="manual.html#luaL_optint">luaL_optint</A><BR> |
| 469 | 479 | <A HREF="manual.html#luaL_optinteger">luaL_optinteger</A><BR> |
| @@ -491,10 +501,10 @@ Freely available under the terms of the · 21 unmodified lines | ||
| 491 | 501 | <HR> |
| 492 | 502 | <SMALL> |
| 493 | 503 | Last update: |
| 494 | −Wed Jan 13 15:31:47 BRST 2010 | |
| 504 | +Mon May 17 16:58:54 BRT 2010 | |
| 495 | 505 | </SMALL> |
| 496 | 506 | <!-- |
| 497 | −Last change: revised for Lua 5.2.0 (work2) | |
| 507 | +Last change: revised for Lua 5.2.0 (work3) | |
| 498 | 508 | --> |
| 499 | 509 | |
| 500 | 510 | </BODY> |
Binary file not shown.
| @@ -16,6 +16,11 @@ · 15 unmodified lines | ||
| 16 | 16 | Lua 5.2 Reference Manual |
| 17 | 17 | </h1> |
| 18 | 18 | |
| 19 | +<IMG SRC="alert.png" ALIGN="absbottom"> | |
| 20 | +<EM>This is a work version of Lua 5.2. | |
| 21 | +Everything may change in the final version.</EM> | |
| 22 | +<P> | |
| 23 | + | |
| 19 | 24 | by Roberto Ierusalimschy, Luiz Henrique de Figueiredo, Waldemar Celes |
| 20 | 25 | <p> |
| 21 | 26 | <small> |
| @@ -33,7 +38,7 @@ Freely available under the terms of the · 11 unmodified lines | ||
| 33 | 38 | <!-- ====================================================================== --> |
| 34 | 39 | <p> |
| 35 | 40 | |
| 36 | −<!-- $Id: manual.of,v 1.54 2010/01/13 16:50:58 roberto Exp roberto $ --> | |
| 41 | +<!-- $Id: manual.of,v 1.56 2010/05/17 18:28:03 roberto Exp $ --> | |
| 37 | 42 | |
| 38 | 43 | |
| 39 | 44 | |
| @@ -84,179 +89,14 @@ see Roberto's book, <em>Programming in Lua (Second Edition)</em>. · 44 unmodified lines | ||
| 84 | 89 | |
| 85 | 90 | |
| 86 | 91 | |
| 87 | −<h1>2 - <a name="2">The Language</a></h1> | |
| 88 | − | |
| 89 | −<p> | |
| 90 | −This section describes the lexis, the syntax, and the semantics of Lua. | |
| 91 | −In other words, | |
| 92 | −this section describes | |
| 93 | −which tokens are valid, | |
| 94 | −how they can be combined, | |
| 95 | −and what their combinations mean. | |
| 96 | − | |
| 97 | − | |
| 98 | −<p> | |
| 99 | −The language constructs will be explained using the usual extended BNF notation, | |
| 100 | −in which | |
| 101 | −{<em>a</em>} means 0 or more <em>a</em>'s, and | |
| 102 | −[<em>a</em>] means an optional <em>a</em>. | |
| 103 | −Non-terminals are shown like non-terminal, | |
| 104 | −keywords are shown like <b>kword</b>, | |
| 105 | −and other terminal symbols are shown like `<b>=</b>´. | |
| 106 | −The complete syntax of Lua can be found in <a href="#8">§8</a> | |
| 107 | −at the end of this manual. | |
| 108 | − | |
| 109 | − | |
| 110 | − | |
| 111 | −<h2>2.1 - <a name="2.1">Lexical Conventions</a></h2> | |
| 112 | − | |
| 113 | −<p> | |
| 114 | −Lua is a free-form language. | |
| 115 | −It ignores spaces (including new lines) and comments | |
| 116 | −between lexical elements (tokens), | |
| 117 | −except as delimiters between names and keywords. | |
| 118 | − | |
| 119 | − | |
| 120 | −<p> | |
| 121 | −<em>Names</em> | |
| 122 | −(also called <em>identifiers</em>) | |
| 123 | −in Lua can be any string of letters, | |
| 124 | −digits, and underscores, | |
| 125 | −not beginning with a digit. | |
| 126 | −This coincides with the definition of names in most languages. | |
| 127 | −Identifiers are used to name variables and table fields. | |
| 128 | − | |
| 129 | − | |
| 130 | −<p> | |
| 131 | −The following <em>keywords</em> are reserved | |
| 132 | −and cannot be used as names: | |
| 133 | − | |
| 134 | − | |
| 135 | −<pre> | |
| 136 | − and break do else elseif | |
| 137 | − end false for function if | |
| 138 | − in local nil not or | |
| 139 | − repeat return then true until while | |
| 140 | −</pre> | |
| 141 | − | |
| 142 | −<p> | |
| 143 | −Lua is a case-sensitive language: | |
| 144 | −<code>and</code> is a reserved word, but <code>And</code> and <code>AND</code> | |
| 145 | −are two different, valid names. | |
| 146 | −As a convention, names starting with an underscore followed by | |
| 147 | −uppercase letters (such as <a href="#pdf-_VERSION"><code>_VERSION</code></a>) | |
| 148 | −are reserved for internal global variables used by Lua. | |
| 149 | − | |
| 150 | − | |
| 151 | −<p> | |
| 152 | −The following strings denote other tokens: | |
| 153 | − | |
| 154 | −<pre> | |
| 155 | − + - * / % ^ # | |
| 156 | − == ~= <= >= < > = | |
| 157 | − ( ) { } [ ] | |
| 158 | − ; : , . .. ... | |
| 159 | −</pre> | |
| 160 | − | |
| 161 | −<p> | |
| 162 | −<em>Literal strings</em> | |
| 163 | −can be delimited by matching single or double quotes, | |
| 164 | −and can contain the following C-like escape sequences: | |
| 165 | −'<code>\a</code>' (bell), | |
| 166 | −'<code>\b</code>' (backspace), | |
| 167 | −'<code>\f</code>' (form feed), | |
| 168 | −'<code>\n</code>' (newline), | |
| 169 | −'<code>\r</code>' (carriage return), | |
| 170 | −'<code>\t</code>' (horizontal tab), | |
| 171 | −'<code>\v</code>' (vertical tab), | |
| 172 | −'<code>\\</code>' (backslash), | |
| 173 | −'<code>\"</code>' (quotation mark [double quote]), | |
| 174 | −and '<code>\'</code>' (apostrophe [single quote]). | |
| 175 | −Moreover, a backslash followed by a real newline | |
| 176 | −results in a newline in the string. | |
| 177 | −A character in a string can also be specified by its numerical value. | |
| 178 | −This can be done with the escape sequence <code>\x<em>XX</em></code>, | |
| 179 | −where <em>XX</em> is a sequence of exactly two hexadecimal digits, | |
| 180 | −and with the escape sequence <code>\<em>ddd</em></code>, | |
| 181 | −where <em>ddd</em> is a sequence of up to three decimal digits. | |
| 182 | −(Note that if a decimal escape is to be followed by a digit, | |
| 183 | −it must be expressed using exactly three digits.) | |
| 184 | −Strings in Lua can contain any 8-bit value, including embedded zeros, | |
| 185 | −which can be specified as '<code>\0</code>'. | |
| 186 | − | |
| 187 | − | |
| 188 | −<p> | |
| 189 | −Literal strings can also be defined using a long format | |
| 190 | −enclosed by <em>long brackets</em>. | |
| 191 | −We define an <em>opening long bracket of level <em>n</em></em> as an opening | |
| 192 | −square bracket followed by <em>n</em> equal signs followed by another | |
| 193 | −opening square bracket. | |
| 194 | −So, an opening long bracket of level 0 is written as <code>[[</code>, | |
| 195 | −an opening long bracket of level 1 is written as <code>[=[</code>, | |
| 196 | −and so on. | |
| 197 | −A <em>closing long bracket</em> is defined similarly; | |
| 198 | −for instance, a closing long bracket of level 4 is written as <code>]====]</code>. | |
| 199 | −A long string starts with an opening long bracket of any level and | |
| 200 | −ends at the first closing long bracket of the same level. | |
| 201 | −It can contain any text except a closing bracket of the proper level. | |
| 202 | −Literals in this bracketed form can run for several lines, | |
| 203 | −do not interpret any escape sequences, | |
| 204 | −and ignore long brackets of any other level. | |
| 205 | −Any kind of end-of-line sequence | |
| 206 | −(carriage return, newline, carriage return followed by newline, | |
| 207 | −or newline followed by carriage return) | |
| 208 | −is converted to a simple newline. | |
| 209 | −You should not use long strings for non-text data; | |
| 210 | −Use instead a regular quoted literal with explicit escape sequences | |
| 211 | −for control characters. | |
| 212 | − | |
| 213 | − | |
| 214 | −<p> | |
| 215 | −For convenience, | |
| 216 | −when the opening long bracket is immediately followed by a newline, | |
| 217 | −the newline is not included in the string. | |
| 218 | −As an example, in a system using ASCII | |
| 219 | −(in which '<code>a</code>' is coded as 97, | |
| 220 | −newline is coded as 10, and '<code>1</code>' is coded as 49), | |
| 221 | −the five literal strings below denote the same string: | |
| 222 | − | |
| 223 | −<pre> | |
| 224 | − a = 'alo\n123"' | |
| 225 | − a = "alo\n123\"" | |
| 226 | − a = '\97lo\10\04923"' | |
| 227 | − a = [[alo | |
| 228 | − 123"]] | |
| 229 | − a = [==[ | |
| 230 | − alo | |
| 231 | − 123"]==] | |
| 232 | −</pre> | |
| 233 | − | |
| 234 | −<p> | |
| 235 | −A <em>numerical constant</em> can be written with an optional decimal part | |
| 236 | −and an optional decimal exponent. | |
| 237 | −Lua also accepts integer hexadecimal constants, | |
| 238 | −by prefixing them with <code>0x</code>. | |
| 239 | −Examples of valid numerical constants are | |
| 240 | − | |
| 241 | −<pre> | |
| 242 | − 3 3.0 3.1416 314.16e-2 0.31416E1 0xff 0x56 | |
| 243 | −</pre> | |
| 92 | +<h1>2 - <a name="2">Basic Concepts</a></h1> | |
| 244 | 93 | |
| 245 | 94 | <p> |
| 246 | −A <em>comment</em> starts with a double hyphen (<code>--</code>) | |
| 247 | −anywhere outside a string. | |
| 248 | −If the text immediately after <code>--</code> is not an opening long bracket, | |
| 249 | −the comment is a <em>short comment</em>, | |
| 250 | −which runs until the end of the line. | |
| 251 | −Otherwise, it is a <em>long comment</em>, | |
| 252 | −which runs until the corresponding closing long bracket. | |
| 253 | −Long comments are frequently used to disable code temporarily. | |
| 254 | − | |
| 255 | − | |
| 95 | +This section describes some basic concepts of the language. | |
| 256 | 96 | |
| 257 | 97 | |
| 258 | 98 | |
| 259 | −<h2>2.2 - <a name="2.2">Values and Types</a></h2> | |
| 99 | +<h2>2.1 - <a name="2.1">Values and Types</a></h2> | |
| 260 | 100 | |
| 261 | 101 | <p> |
| 262 | 102 | Lua is a <em>dynamically typed language</em>. |
| @@ -291,14 +131,14 @@ see file <code>luaconf.h</code>.) · 28 unmodified lines | ||
| 291 | 131 | <em>String</em> represents arrays of characters. |
| 292 | 132 | |
| 293 | 133 | Lua is 8-bit clean: |
| 294 | −strings can contain any 8-bit character, | |
| 295 | −including embedded zeros ('<code>\0</code>') (see <a href="#2.1">§2.1</a>). | |
| 134 | +strings can contain any 8-bit value, | |
| 135 | +including embedded zeros ('<code>\0</code>'). | |
| 296 | 136 | |
| 297 | 137 | |
| 298 | 138 | <p> |
| 299 | 139 | Lua can call (and manipulate) functions written in Lua and |
| 300 | 140 | functions written in C |
| 301 | −(see <a href="#2.5.8">§2.5.8</a>). | |
| 141 | +(see <a href="#3.4.9">§3.4.9</a>). | |
| 302 | 142 | |
| 303 | 143 | |
| 304 | 144 | <p> |
| @@ -309,7 +149,7 @@ and has no pre-defined operations in Lua, · 4 unmodified lines | ||
| 309 | 149 | except assignment and identity test. |
| 310 | 150 | However, by using <em>metatables</em>, |
| 311 | 151 | the programmer can define operations for userdata values |
| 312 | −(see <a href="#2.8">§2.8</a>). | |
| 152 | +(see <a href="#2.4">§2.4</a>). | |
| 313 | 153 | Userdata values cannot be created or modified in Lua, |
| 314 | 154 | only through the C API. |
| 315 | 155 | This guarantees the integrity of data owned by the host program. |
| @@ -317,7 +157,7 @@ This guarantees the integrity of data owned by the host program. · 1 unmodified line | ||
| 317 | 157 | |
| 318 | 158 | <p> |
| 319 | 159 | The type <em>thread</em> represents independent threads of execution |
| 320 | −and it is used to implement coroutines (see <a href="#2.11">§2.11</a>). | |
| 160 | +and it is used to implement coroutines (see <a href="#2.6">§2.6</a>). | |
| 321 | 161 | Do not confuse Lua threads with operating-system threads. |
| 322 | 162 | Lua supports coroutines on all systems, |
| 323 | 163 | even those that do not support threads. |
| @@ -336,7 +176,7 @@ To represent records, Lua uses the field name as an index. · 12 unmodified lines | ||
| 336 | 176 | The language supports this representation by |
| 337 | 177 | providing <code>a.name</code> as syntactic sugar for <code>a["name"]</code>. |
| 338 | 178 | There are several convenient ways to create tables in Lua |
| 339 | −(see <a href="#2.5.7">§2.5.7</a>). | |
| 179 | +(see <a href="#3.4.8">§3.4.8</a>). | |
| 340 | 180 | |
| 341 | 181 | |
| 342 | 182 | <p> |
| @@ -345,7 +185,7 @@ the value of a table field can be of any type (except <b>nil</b>). · 2 unmodified lines | ||
| 345 | 185 | In particular, |
| 346 | 186 | because functions are first-class values, |
| 347 | 187 | table fields can contain functions. |
| 348 | −Thus tables can also carry <em>methods</em> (see <a href="#2.5.9">§2.5.9</a>). | |
| 188 | +Thus tables can also carry <em>methods</em> (see <a href="#3.4.10">§3.4.10</a>). | |
| 349 | 189 | |
| 350 | 190 | |
| 351 | 191 | <p> |
| @@ -363,458 +203,480 @@ of a given value. · 11 unmodified lines | ||
| 363 | 203 | |
| 364 | 204 | |
| 365 | 205 | |
| 366 | −<h3>2.2.1 - <a name="2.2.1">Coercion</a></h3> | |
| 367 | 206 | |
| 368 | −<p> | |
| 369 | −Lua provides automatic conversion between | |
| 370 | −string and number values at run time. | |
| 371 | −Any arithmetic operation applied to a string tries to convert | |
| 372 | −this string to a number, following the usual conversion rules. | |
| 373 | −Conversely, whenever a number is used where a string is expected, | |
| 374 | −the number is converted to a string, in a reasonable format. | |
| 375 | −For complete control over how numbers are converted to strings, | |
| 376 | −use the <code>format</code> function from the string library | |
| 377 | −(see <a href="#pdf-string.format"><code>string.format</code></a>). | |
| 378 | 207 | |
| 208 | +<h2>2.2 - <a name="2.2">Environments and the Global Environment</a></h2> | |
| 379 | 209 | |
| 210 | +<p> | |
| 211 | +As discussed in <a href="#3.2">§3.2</a> and <a href="#3.3.3">§3.3.3</a>, | |
| 212 | +any reference to a global name <code>var</code> is syntactically translated | |
| 213 | +to <code>_ENV.var</code>. | |
| 214 | +Moreover, any chunk is compiled in the scope of an external | |
| 215 | +variable called <code>_ENV</code> (see <a href="#3.3.1">§3.3.1</a>). | |
| 216 | +Any table used as the value of <code>_ENV</code> is usually called | |
| 217 | +an <em>environment</em>. | |
| 380 | 218 | |
| 381 | 219 | |
| 220 | +<p> | |
| 221 | +Lua keeps a distinguished environment called the <em>global environment</em>. | |
| 222 | +This value is kept at a special index in the C registry (see <a href="#4.5">§4.5</a>). | |
| 223 | +In Lua, the variable <a href="#pdf-_G"><code>_G</code></a> is initialized with this same value. | |
| 382 | 224 | |
| 383 | 225 | |
| 226 | +<p> | |
| 227 | +When Lua compiles a chunk, | |
| 228 | +it initializes the value of its <code>_ENV</code> variable | |
| 229 | +with the global environment (see <a href="#pdf-load"><code>load</code></a>). | |
| 230 | +Therefore, by default, | |
| 231 | +global variables in Lua code refer to entries in the global environment. | |
| 232 | +Moreover, all standard libraries are loaded in the global environment, | |
| 233 | +and several functions there operate on that environment. | |
| 234 | +You can use <a href="#pdf-loadin"><code>loadin</code></a> to load a chunk with a different environment. | |
| 235 | +(In C, you have to load the chunk and then change the value | |
| 236 | +of its first upvalue.) | |
| 384 | 237 | |
| 385 | −<h2>2.3 - <a name="2.3">Variables</a></h2> | |
| 386 | 238 | |
| 387 | 239 | <p> |
| 388 | −Variables are places that store values. | |
| 240 | +If you change the global environment in the registry | |
| 241 | +(through C code or the debug library), | |
| 242 | +all chunks loaded after the change will get the new environment. | |
| 243 | +Previously loaded chunks are not affected, however, | |
| 244 | +as each has its own copy of the environment in its <code>_ENV</code> variable. | |
| 245 | +Moreover, the variable <a href="#pdf-_G"><code>_G</code></a> | |
| 246 | +(which is stored in the original global environment) | |
| 247 | +is never updated by Lua. | |
| 389 | 248 | |
| 390 | −There are three kinds of variables in Lua: | |
| 391 | −global variables, local variables, and table fields. | |
| 392 | 249 | |
| 393 | 250 | |
| 394 | −<p> | |
| 395 | −A single name can denote a global variable or a local variable | |
| 396 | −(or a function's formal parameter, | |
| 397 | −which is a particular kind of local variable): | |
| 398 | 251 | |
| 399 | −<pre> | |
| 400 | − var ::= Name | |
| 401 | −</pre><p> | |
| 402 | −Name denotes identifiers, as defined in <a href="#2.1">§2.1</a>. | |
| 403 | 252 | |
| 253 | +<h2>2.3 - <a name="2.3">Error Handling</a></h2> | |
| 404 | 254 | |
| 405 | 255 | <p> |
| 406 | −Any variable is assumed to be global unless explicitly declared | |
| 407 | −as a local (see <a href="#2.4.7">§2.4.7</a>). | |
| 408 | −Local variables are <em>lexically scoped</em>: | |
| 409 | −local variables can be freely accessed by functions | |
| 410 | −defined inside their scope (see <a href="#2.6">§2.6</a>). | |
| 256 | +Because Lua is an embedded extension language, | |
| 257 | +all Lua actions start from C code in the host program | |
| 258 | +calling a function from the Lua library (see <a href="#lua_pcall"><code>lua_pcall</code></a>). | |
| 259 | +Whenever an error occurs during Lua compilation or execution, | |
| 260 | +control returns to C, | |
| 261 | +which can take appropriate measures | |
| 262 | +(such as printing an error message). | |
| 411 | 263 | |
| 412 | 264 | |
| 413 | 265 | <p> |
| 414 | −Before the first assignment to a variable, its value is <b>nil</b>. | |
| 415 | − | |
| 266 | +Lua code can explicitly generate an error by calling the | |
| 267 | +<a href="#pdf-error"><code>error</code></a> function. | |
| 268 | +If you need to catch errors in Lua, | |
| 269 | +you can use the <a href="#pdf-pcall"><code>pcall</code></a> function. | |
| 416 | 270 | |
| 417 | −<p> | |
| 418 | −Square brackets are used to index a table: | |
| 419 | 271 | |
| 420 | −<pre> | |
| 421 | − var ::= prefixexp `<b>[</b>´ exp `<b>]</b>´ | |
| 422 | −</pre><p> | |
| 423 | −The meaning of accesses to global variables | |
| 424 | −and table fields can be changed via metatables. | |
| 425 | −An access to an indexed variable <code>t[i]</code> is equivalent to | |
| 426 | −a call <code>gettable_event(t,i)</code>. | |
| 427 | −(See <a href="#2.8">§2.8</a> for a complete description of the | |
| 428 | −<code>gettable_event</code> function. | |
| 429 | −This function is not defined or callable in Lua. | |
| 430 | −We use it here only for explanatory purposes.) | |
| 431 | 272 | |
| 432 | 273 | |
| 433 | −<p> | |
| 434 | −The syntax <code>var.Name</code> is just syntactic sugar for | |
| 435 | −<code>var["Name"]</code>: | |
| 436 | 274 | |
| 437 | −<pre> | |
| 438 | − var ::= prefixexp `<b>.</b>´ Name | |
| 439 | −</pre> | |
| 275 | +<h2>2.4 - <a name="2.4">Metatables</a></h2> | |
| 440 | 276 | |
| 441 | 277 | <p> |
| 442 | −All global variables live as fields in ordinary Lua tables, | |
| 443 | −called <em>environment tables</em> or simply | |
| 444 | −<em>environments</em> (see <a href="#2.9">§2.9</a>). | |
| 445 | −An access to a global variable <code>x</code> | |
| 446 | −is equivalent to <code>_env.x</code>, | |
| 447 | −which in turn is equivalent to | |
| 448 | − | |
| 449 | −<pre> | |
| 450 | − gettable_event(_env, "x") | |
| 451 | −</pre><p> | |
| 452 | −where <code>_env</code> is the current environment (see <a href="#2.9">§2.9</a>). | |
| 453 | −(See <a href="#2.8">§2.8</a> for a complete description of the | |
| 454 | −<code>gettable_event</code> function. | |
| 455 | −This function is not defined or callable in Lua. | |
| 456 | −Similarly, the <code>_env</code> variable is not defined in Lua. | |
| 457 | −We use them here only for explanatory purposes.) | |
| 278 | +Every value in Lua can have a <em>metatable</em>. | |
| 279 | +This <em>metatable</em> is an ordinary Lua table | |
| 280 | +that defines the behavior of the original value | |
| 281 | +under certain special operations. | |
| 282 | +You can change several aspects of the behavior | |
| 283 | +of operations over a value by setting specific fields in its metatable. | |
| 284 | +For instance, when a non-numeric value is the operand of an addition, | |
| 285 | +Lua checks for a function in the field <code>"__add"</code> in its metatable. | |
| 286 | +If it finds one, | |
| 287 | +Lua calls this function to perform the addition. | |
| 458 | 288 | |
| 459 | 289 | |
| 290 | +<p> | |
| 291 | +We call the keys in a metatable <em>events</em> | |
| 292 | +and the values <em>metamethods</em>. | |
| 293 | +In the previous example, the event is <code>"add"</code> | |
| 294 | +and the metamethod is the function that performs the addition. | |
| 460 | 295 | |
| 461 | 296 | |
| 297 | +<p> | |
| 298 | +You can query the metatable of any value | |
| 299 | +through the <a href="#pdf-getmetatable"><code>getmetatable</code></a> function. | |
| 462 | 300 | |
| 463 | −<h2>2.4 - <a name="2.4">Statements</a></h2> | |
| 464 | 301 | |
| 465 | 302 | <p> |
| 466 | −Lua supports an almost conventional set of statements, | |
| 467 | −similar to those in Pascal or C. | |
| 468 | −This set includes | |
| 469 | −assignments, control structures, function calls, | |
| 470 | −and variable declarations. | |
| 303 | +You can replace the metatable of tables | |
| 304 | +through the <a href="#pdf-setmetatable"><code>setmetatable</code></a> | |
| 305 | +function. | |
| 306 | +You cannot change the metatable of other types from Lua | |
| 307 | +(except by using the debug library); | |
| 308 | +you must use the C API for that. | |
| 471 | 309 | |
| 472 | 310 | |
| 311 | +<p> | |
| 312 | +Tables and full userdata have individual metatables | |
| 313 | +(although multiple tables and userdata can share their metatables). | |
| 314 | +Values of all other types share one single metatable per type; | |
| 315 | +that is, there is one single metatable for all numbers, | |
| 316 | +one for all strings, etc. | |
| 317 | +By default, a value has no metatable, | |
| 318 | +but the string library sets a metatable for the string type (see <a href="#6.4">§6.4</a>). | |
| 473 | 319 | |
| 474 | −<h3>2.4.1 - <a name="2.4.1">Chunks</a></h3> | |
| 475 | 320 | |
| 476 | 321 | <p> |
| 477 | −The unit of execution of Lua is called a <em>chunk</em>. | |
| 478 | −A chunk is simply a sequence of statements, | |
| 479 | −which are executed sequentially. | |
| 480 | −Each statement can be optionally followed by a semicolon: | |
| 481 | − | |
| 482 | −<pre> | |
| 483 | − chunk ::= {stat [`<b>;</b>´]} | |
| 484 | −</pre><p> | |
| 485 | −There are no empty statements and thus '<code>;;</code>' is not legal. | |
| 486 | − | |
| 487 | − | |
| 488 | −<p> | |
| 489 | −Lua handles a chunk as the body of an anonymous function | |
| 490 | −with a variable number of arguments | |
| 491 | −(see <a href="#2.5.9">§2.5.9</a>). | |
| 492 | −As such, chunks can define local variables, | |
| 493 | −receive arguments, and return values. | |
| 322 | +A metatable controls how an object behaves in arithmetic operations, | |
| 323 | +order comparisons, concatenation, length operation, and indexing. | |
| 324 | +A metatable also can define a function to be called when a userdata | |
| 325 | +is garbage collected. | |
| 326 | +For each of these operations Lua associates a specific key | |
| 327 | +called an <em>event</em>. | |
| 328 | +When Lua performs one of these operations over a value, | |
| 329 | +it checks whether this value has a metatable with the corresponding event. | |
| 330 | +If so, the value associated with that key (the metamethod) | |
| 331 | +controls how Lua will perform the operation. | |
| 494 | 332 | |
| 495 | 333 | |
| 496 | 334 | <p> |
| 497 | −A chunk can be stored in a file or in a string inside the host program. | |
| 498 | −To execute a chunk, | |
| 499 | −Lua first pre-compiles the chunk into instructions for a virtual machine, | |
| 500 | −and then it executes the compiled code | |
| 501 | −with an interpreter for the virtual machine. | |
| 335 | +Metatables control the operations listed next. | |
| 336 | +Each operation is identified by its corresponding name. | |
| 337 | +The key for each operation is a string with its name prefixed by | |
| 338 | +two underscores, '<code>__</code>'; | |
| 339 | +for instance, the key for operation "add" is the | |
| 340 | +string <code>"__add"</code>. | |
| 341 | +The semantics of these operations is better explained by a Lua function | |
| 342 | +describing how the interpreter executes the operation. | |
| 502 | 343 | |
| 503 | 344 | |
| 504 | 345 | <p> |
| 505 | −Chunks can also be pre-compiled into binary form; | |
| 506 | −see program <code>luac</code> for details. | |
| 507 | −Programs in source and compiled forms are interchangeable; | |
| 508 | −Lua automatically detects the file type and acts accordingly. | |
| 509 | − | |
| 510 | − | |
| 511 | − | |
| 512 | − | |
| 513 | − | |
| 514 | − | |
| 515 | −<h3>2.4.2 - <a name="2.4.2">Blocks</a></h3><p> | |
| 516 | −A block is a list of statements; | |
| 517 | −syntactically, a block is the same as a chunk: | |
| 346 | +The code shown here in Lua is only illustrative; | |
| 347 | +the real behavior is hard coded in the interpreter | |
| 348 | +and it is much more efficient than this simulation. | |
| 349 | +All functions used in these descriptions | |
| 350 | +(<a href="#pdf-rawget"><code>rawget</code></a>, <a href="#pdf-tonumber"><code>tonumber</code></a>, etc.) | |
| 351 | +are described in <a href="#6.1">§6.1</a>. | |
| 352 | +In particular, to retrieve the metamethod of a given object, | |
| 353 | +we use the expression | |
| 518 | 354 | |
| 519 | 355 | <pre> |
| 520 | − block ::= chunk | |
| 521 | −</pre> | |
| 522 | − | |
| 523 | −<p> | |
| 524 | −A block can be explicitly delimited to produce a single statement: | |
| 356 | + metatable(obj)[event] | |
| 357 | +</pre><p> | |
| 358 | +This should be read as | |
| 525 | 359 | |
| 526 | 360 | <pre> |
| 527 | − stat ::= <b>do</b> block <b>end</b> | |
| 361 | + rawget(getmetatable(obj) or {}, event) | |
| 528 | 362 | </pre><p> |
| 529 | −Explicit blocks are useful | |
| 530 | −to control the scope of variable declarations. | |
| 531 | −Explicit blocks are also sometimes used to | |
| 532 | −add a <b>return</b> or <b>break</b> statement in the middle | |
| 533 | −of another block (see <a href="#2.4.4">§2.4.4</a>). | |
| 534 | − | |
| 535 | 363 | |
| 364 | +That is, the access to a metamethod does not invoke other metamethods, | |
| 365 | +and the access to objects with no metatables does not fail | |
| 366 | +(it simply results in <b>nil</b>). | |
| 536 | 367 | |
| 537 | 368 | |
| 369 | +<p> | |
| 370 | +For the unary <code>-</code> and <code>#</code> operators, | |
| 371 | +the metamethod is called repeating the first argument as a second argument. | |
| 372 | +This extra argument is only to simplify Lua's internals; | |
| 373 | +it may be removed in future versions and therefore it is not present | |
| 374 | +in the following code. | |
| 375 | +(For most uses this extra argument is irrelevant.) | |
| 538 | 376 | |
| 539 | −<h3>2.4.3 - <a name="2.4.3">Assignment</a></h3> | |
| 540 | 377 | |
| 541 | −<p> | |
| 542 | −Lua allows multiple assignments. | |
| 543 | −Therefore, the syntax for assignment | |
| 544 | −defines a list of variables on the left side | |
| 545 | −and a list of expressions on the right side. | |
| 546 | −The elements in both lists are separated by commas: | |
| 547 | 378 | |
| 548 | −<pre> | |
| 549 | − stat ::= varlist `<b>=</b>´ explist | |
| 550 | − varlist ::= var {`<b>,</b>´ var} | |
| 551 | − explist ::= exp {`<b>,</b>´ exp} | |
| 552 | −</pre><p> | |
| 553 | −Expressions are discussed in <a href="#2.5">§2.5</a>. | |
| 379 | +<ul> | |
| 554 | 380 | |
| 381 | +<li><b>"add":</b> | |
| 382 | +the <code>+</code> operation. | |
| 555 | 383 | |
| 556 | −<p> | |
| 557 | −Before the assignment, | |
| 558 | −the list of values is <em>adjusted</em> to the length of | |
| 559 | −the list of variables. | |
| 560 | −If there are more values than needed, | |
| 561 | −the excess values are thrown away. | |
| 562 | −If there are fewer values than needed, | |
| 563 | −the list is extended with as many <b>nil</b>'s as needed. | |
| 564 | −If the list of expressions ends with a function call, | |
| 565 | −then all values returned by that call enter the list of values, | |
| 566 | −before the adjustment | |
| 567 | −(except when the call is enclosed in parentheses; see <a href="#2.5">§2.5</a>). | |
| 568 | 384 | |
| 569 | 385 | |
| 570 | 386 | <p> |
| 571 | −The assignment statement first evaluates all its expressions | |
| 572 | −and only then are the assignments performed. | |
| 573 | −Thus the code | |
| 574 | − | |
| 575 | −<pre> | |
| 576 | − i = 3 | |
| 577 | − i, a[i] = i+1, 20 | |
| 578 | −</pre><p> | |
| 579 | −sets <code>a[3]</code> to 20, without affecting <code>a[4]</code> | |
| 580 | −because the <code>i</code> in <code>a[i]</code> is evaluated (to 3) | |
| 581 | −before it is assigned 4. | |
| 582 | −Similarly, the line | |
| 387 | +The function <code>getbinhandler</code> below defines how Lua chooses a handler | |
| 388 | +for a binary operation. | |
| 389 | +First, Lua tries the first operand. | |
| 390 | +If its type does not define a handler for the operation, | |
| 391 | +then Lua tries the second operand. | |
| 583 | 392 | |
| 584 | 393 | <pre> |
| 585 | − x, y = y, x | |
| 394 | + function getbinhandler (op1, op2, event) | |
| 395 | + return metatable(op1)[event] or metatable(op2)[event] | |
| 396 | + end | |
| 586 | 397 | </pre><p> |
| 587 | −exchanges the values of <code>x</code> and <code>y</code>, | |
| 588 | −and | |
| 398 | +By using this function, | |
| 399 | +the behavior of the <code>op1 + op2</code> is | |
| 589 | 400 | |
| 590 | 401 | <pre> |
| 591 | − x, y, z = y, z, x | |
| 402 | + function add_event (op1, op2) | |
| 403 | + local o1, o2 = tonumber(op1), tonumber(op2) | |
| 404 | + if o1 and o2 then -- both operands are numeric? | |
| 405 | + return o1 + o2 -- '+' here is the primitive 'add' | |
| 406 | + else -- at least one of the operands is not numeric | |
| 407 | + local h = getbinhandler(op1, op2, "__add") | |
| 408 | + if h then | |
| 409 | + -- call the handler with both operands | |
| 410 | + return (h(op1, op2)) | |
| 411 | + else -- no handler available: default behavior | |
| 412 | + error(···) | |
| 413 | + end | |
| 414 | + end | |
| 415 | + end | |
| 592 | 416 | </pre><p> |
| 593 | −cyclically permutes the values of <code>x</code>, <code>y</code>, and <code>z</code>. | |
| 594 | − | |
| 417 | +</li> | |
| 595 | 418 | |
| 596 | −<p> | |
| 597 | −The meaning of assignments to global variables | |
| 598 | −and table fields can be changed via metatables. | |
| 599 | −An assignment to an indexed variable <code>t[i] = val</code> is equivalent to | |
| 600 | −<code>settable_event(t,i,val)</code>. | |
| 601 | −(See <a href="#2.8">§2.8</a> for a complete description of the | |
| 602 | −<code>settable_event</code> function. | |
| 603 | −This function is not defined or callable in Lua. | |
| 604 | −We use it here only for explanatory purposes.) | |
| 419 | +<li><b>"sub":</b> | |
| 420 | +the <code>-</code> operation. | |
| 605 | 421 | |
| 422 | +Behavior similar to the "add" operation. | |
| 423 | +</li> | |
| 606 | 424 | |
| 607 | −<p> | |
| 608 | −An assignment to a global variable <code>x = val</code> | |
| 609 | −is equivalent to the assignment | |
| 610 | −<code>_env.x = val</code>, | |
| 611 | −which in turn is equivalent to | |
| 425 | +<li><b>"mul":</b> | |
| 426 | +the <code>*</code> operation. | |
| 612 | 427 | |
| 613 | −<pre> | |
| 614 | − settable_event(_env, "x", val) | |
| 615 | −</pre><p> | |
| 616 | −where <code>_env</code> is the environment of the running function. | |
| 617 | −(The <code>_env</code> variable is not defined in Lua. | |
| 618 | −We use it here only for explanatory purposes.) | |
| 428 | +Behavior similar to the "add" operation. | |
| 429 | +</li> | |
| 619 | 430 | |
| 431 | +<li><b>"div":</b> | |
| 432 | +the <code>/</code> operation. | |
| 620 | 433 | |
| 434 | +Behavior similar to the "add" operation. | |
| 435 | +</li> | |
| 621 | 436 | |
| 437 | +<li><b>"mod":</b> | |
| 438 | +the <code>%</code> operation. | |
| 622 | 439 | |
| 440 | +Behavior similar to the "add" operation, | |
| 441 | +with the operation | |
| 442 | +<code>o1 - floor(o1/o2)*o2</code> as the primitive operation. | |
| 443 | +</li> | |
| 623 | 444 | |
| 624 | −<h3>2.4.4 - <a name="2.4.4">Control Structures</a></h3><p> | |
| 625 | −The control structures | |
| 626 | −<b>if</b>, <b>while</b>, and <b>repeat</b> have the usual meaning and | |
| 627 | −familiar syntax: | |
| 445 | +<li><b>"pow":</b> | |
| 446 | +the <code>^</code> (exponentiation) operation. | |
| 628 | 447 | |
| 448 | +Behavior similar to the "add" operation, | |
| 449 | +with the function <code>pow</code> (from the C math library) | |
| 450 | +as the primitive operation. | |
| 451 | +</li> | |
| 629 | 452 | |
| 453 | +<li><b>"unm":</b> | |
| 454 | +the unary <code>-</code> operation. | |
| 630 | 455 | |
| 631 | 456 | |
| 632 | 457 | <pre> |
| 633 | − stat ::= <b>while</b> exp <b>do</b> block <b>end</b> | |
| 634 | − stat ::= <b>repeat</b> block <b>until</b> exp | |
| 635 | − stat ::= <b>if</b> exp <b>then</b> block {<b>elseif</b> exp <b>then</b> block} [<b>else</b> block] <b>end</b> | |
| 458 | + function unm_event (op) | |
| 459 | + local o = tonumber(op) | |
| 460 | + if o then -- operand is numeric? | |
| 461 | + return -o -- '-' here is the primitive 'unm' | |
| 462 | + else -- the operand is not numeric. | |
| 463 | + -- Try to get a handler from the operand | |
| 464 | + local h = metatable(op).__unm | |
| 465 | + if h then | |
| 466 | + -- call the handler with the operand | |
| 467 | + return (h(op)) | |
| 468 | + else -- no handler available: default behavior | |
| 469 | + error(···) | |
| 470 | + end | |
| 471 | + end | |
| 472 | + end | |
| 636 | 473 | </pre><p> |
| 637 | −Lua also has a <b>for</b> statement, in two flavors (see <a href="#2.4.5">§2.4.5</a>). | |
| 474 | +</li> | |
| 638 | 475 | |
| 476 | +<li><b>"concat":</b> | |
| 477 | +the <code>..</code> (concatenation) operation. | |
| 639 | 478 | |
| 640 | −<p> | |
| 641 | −The condition expression of a | |
| 642 | −control structure can return any value. | |
| 643 | −Both <b>false</b> and <b>nil</b> are considered false. | |
| 644 | −All values different from <b>nil</b> and <b>false</b> are considered true | |
| 645 | −(in particular, the number 0 and the empty string are also true). | |
| 646 | 479 | |
| 480 | +<pre> | |
| 481 | + function concat_event (op1, op2) | |
| 482 | + if (type(op1) == "string" or type(op1) == "number") and | |
| 483 | + (type(op2) == "string" or type(op2) == "number") then | |
| 484 | + return op1 .. op2 -- primitive string concatenation | |
| 485 | + else | |
| 486 | + local h = getbinhandler(op1, op2, "__concat") | |
| 487 | + if h then | |
| 488 | + return (h(op1, op2)) | |
| 489 | + else | |
| 490 | + error(···) | |
| 491 | + end | |
| 492 | + end | |
| 493 | + end | |
| 494 | +</pre><p> | |
| 495 | +</li> | |
| 496 | + | |
| 497 | +<li><b>"len":</b> | |
| 498 | +the <code>#</code> operation. | |
| 647 | 499 | |
| 648 | −<p> | |
| 649 | −In the <b>repeat</b>–<b>until</b> loop, | |
| 650 | −the inner block does not end at the <b>until</b> keyword, | |
| 651 | −but only after the condition. | |
| 652 | −So, the condition can refer to local variables | |
| 653 | −declared inside the loop block. | |
| 654 | 500 | |
| 501 | +<pre> | |
| 502 | + function len_event (op) | |
| 503 | + if type(op) == "string" then | |
| 504 | + return strlen(op) -- primitive string length | |
| 505 | + else | |
| 506 | + local h = metatable(op).__len | |
| 507 | + if h then | |
| 508 | + return (h(op)) -- call handler with the operand | |
| 509 | + elseif type(op) == "table" then | |
| 510 | + return #op -- primitive table length | |
| 511 | + else -- no handler available: error | |
| 512 | + error(···) | |
| 513 | + end | |
| 514 | + end | |
| 515 | + end | |
| 516 | +</pre><p> | |
| 517 | +See <a href="#3.4.6">§3.4.6</a> for a description of the length of a table. | |
| 518 | +</li> | |
| 655 | 519 | |
| 656 | −<p> | |
| 657 | −The <b>return</b> statement is used to return values | |
| 658 | −from a function or a chunk (which is just a function). | |
| 520 | +<li><b>"eq":</b> | |
| 521 | +the <code>==</code> operation. | |
| 659 | 522 | |
| 660 | −Functions and chunks can return more than one value, | |
| 661 | −and so the syntax for the <b>return</b> statement is | |
| 523 | +The function <code>getequalhandler</code> defines how Lua chooses a metamethod | |
| 524 | +for equality. | |
| 525 | +A metamethod is selected only when both values | |
| 526 | +being compared have the same type | |
| 527 | +and the same metamethod for the selected operation. | |
| 662 | 528 | |
| 663 | 529 | <pre> |
| 664 | − stat ::= <b>return</b> [explist] | |
| 665 | −</pre> | |
| 666 | − | |
| 667 | −<p> | |
| 668 | −The <b>break</b> statement is used to terminate the execution of a | |
| 669 | −<b>while</b>, <b>repeat</b>, or <b>for</b> loop, | |
| 670 | −skipping to the next statement after the loop: | |
| 671 | − | |
| 672 | − | |
| 673 | −<pre> | |
| 674 | − stat ::= <b>break</b> | |
| 530 | + function getequalhandler (op1, op2, event) | |
| 531 | + if type(op1) ~= type(op2) then return nil end | |
| 532 | + local mm1 = metatable(op1)[event] | |
| 533 | + local mm2 = metatable(op2)[event] | |
| 534 | + if mm1 == mm2 then return mm1 else return nil end | |
| 535 | + end | |
| 675 | 536 | </pre><p> |
| 676 | −A <b>break</b> ends the innermost enclosing loop. | |
| 677 | − | |
| 678 | − | |
| 679 | −<p> | |
| 680 | −The <b>return</b> and <b>break</b> | |
| 681 | −statements can only be written as the <em>last</em> statement of a block. | |
| 682 | −If it is really necessary to <b>return</b> or <b>break</b> in the | |
| 683 | −middle of a block, | |
| 684 | −then an explicit inner block can be used, | |
| 685 | −as in the idioms | |
| 686 | −<code>do return end</code> and <code>do break end</code>, | |
| 687 | −because now <b>return</b> and <b>break</b> are the last statements in | |
| 688 | −their (inner) blocks. | |
| 689 | − | |
| 690 | − | |
| 691 | − | |
| 692 | − | |
| 693 | − | |
| 694 | −<h3>2.4.5 - <a name="2.4.5">For Statement</a></h3> | |
| 695 | − | |
| 696 | −<p> | |
| 697 | − | |
| 698 | −The <b>for</b> statement has two forms: | |
| 699 | −one numeric and one generic. | |
| 700 | − | |
| 701 | − | |
| 702 | −<p> | |
| 703 | −The numeric <b>for</b> loop repeats a block of code while a | |
| 704 | −control variable runs through an arithmetic progression. | |
| 705 | −It has the following syntax: | |
| 537 | +The "eq" event is defined as follows: | |
| 706 | 538 | |
| 707 | 539 | <pre> |
| 708 | − stat ::= <b>for</b> Name `<b>=</b>´ exp `<b>,</b>´ exp [`<b>,</b>´ exp] <b>do</b> block <b>end</b> | |
| 540 | + function eq_event (op1, op2) | |
| 541 | + if type(op1) ~= type(op2) then -- different types? | |
| 542 | + return false -- different values | |
| 543 | + end | |
| 544 | + if op1 == op2 then -- primitive equal? | |
| 545 | + return true -- values are equal | |
| 546 | + end | |
| 547 | + -- try metamethod | |
| 548 | + local h = getequalhandler(op1, op2, "__eq") | |
| 549 | + if h then | |
| 550 | + return (h(op1, op2)) | |
| 551 | + else | |
| 552 | + return false | |
| 553 | + end | |
| 554 | + end | |
| 709 | 555 | </pre><p> |
| 710 | −The <em>block</em> is repeated for <em>name</em> starting at the value of | |
| 711 | −the first <em>exp</em>, until it passes the second <em>exp</em> by steps of the | |
| 712 | −third <em>exp</em>. | |
| 713 | −More precisely, a <b>for</b> statement like | |
| 556 | +</li> | |
| 557 | + | |
| 558 | +<li><b>"lt":</b> | |
| 559 | +the <code><</code> operation. | |
| 714 | 560 | |
| 715 | −<pre> | |
| 716 | − for v = <em>e1</em>, <em>e2</em>, <em>e3</em> do <em>block</em> end | |
| 717 | −</pre><p> | |
| 718 | −is equivalent to the code: | |
| 719 | 561 | |
| 720 | 562 | <pre> |
| 721 | − do | |
| 722 | − local <em>var</em>, <em>limit</em>, <em>step</em> = tonumber(<em>e1</em>), tonumber(<em>e2</em>), tonumber(<em>e3</em>) | |
| 723 | − if not (<em>var</em> and <em>limit</em> and <em>step</em>) then error() end | |
| 724 | − while (<em>step</em> > 0 and <em>var</em> <= <em>limit</em>) or (<em>step</em> <= 0 and <em>var</em> >= <em>limit</em>) do | |
| 725 | − local v = <em>var</em> | |
| 726 | − <em>block</em> | |
| 727 | − <em>var</em> = <em>var</em> + <em>step</em> | |
| 563 | + function lt_event (op1, op2) | |
| 564 | + if type(op1) == "number" and type(op2) == "number" then | |
| 565 | + return op1 < op2 -- numeric comparison | |
| 566 | + elseif type(op1) == "string" and type(op2) == "string" then | |
| 567 | + return op1 < op2 -- lexicographic comparison | |
| 568 | + else | |
| 569 | + local h = getbinhandler(op1, op2, "__lt") | |
| 570 | + if h then | |
| 571 | + return (h(op1, op2)) | |
| 572 | + else | |
| 573 | + error(···) | |
| 574 | + end | |
| 728 | 575 | end |
| 729 | 576 | end |
| 730 | 577 | </pre><p> |
| 731 | −Note the following: | |
| 732 | − | |
| 733 | −<ul> | |
| 734 | − | |
| 735 | −<li> | |
| 736 | −All three control expressions are evaluated only once, | |
| 737 | −before the loop starts. | |
| 738 | −They must all result in numbers. | |
| 739 | −</li> | |
| 740 | − | |
| 741 | −<li> | |
| 742 | −<code><em>var</em></code>, <code><em>limit</em></code>, and <code><em>step</em></code> are invisible variables. | |
| 743 | −The names shown here are for explanatory purposes only. | |
| 744 | 578 | </li> |
| 745 | 579 | |
| 746 | −<li> | |
| 747 | −If the third expression (the step) is absent, | |
| 748 | −then a step of 1 is used. | |
| 749 | −</li> | |
| 580 | +<li><b>"le":</b> | |
| 581 | +the <code><=</code> operation. | |
| 750 | 582 | |
| 751 | −<li> | |
| 752 | −You can use <b>break</b> to exit a <b>for</b> loop. | |
| 753 | −</li> | |
| 754 | 583 | |
| 755 | −<li> | |
| 756 | −The loop variable <code>v</code> is local to the loop; | |
| 757 | −you cannot use its value after the <b>for</b> ends or is broken. | |
| 758 | −If you need this value, | |
| 759 | −assign it to another variable before breaking or exiting the loop. | |
| 584 | +<pre> | |
| 585 | + function le_event (op1, op2) | |
| 586 | + if type(op1) == "number" and type(op2) == "number" then | |
| 587 | + return op1 <= op2 -- numeric comparison | |
| 588 | + elseif type(op1) == "string" and type(op2) == "string" then | |
| 589 | + return op1 <= op2 -- lexicographic comparison | |
| 590 | + else | |
| 591 | + local h = getbinhandler(op1, op2, "__le") | |
| 592 | + if h then | |
| 593 | + return (h(op1, op2)) | |
| 594 | + else | |
| 595 | + h = getbinhandler(op1, op2, "__lt") | |
| 596 | + if h then | |
| 597 | + return not h(op2, op1) | |
| 598 | + else | |
| 599 | + error(···) | |
| 600 | + end | |
| 601 | + end | |
| 602 | + end | |
| 603 | + end | |
| 604 | +</pre><p> | |
| 605 | +Note that, in the absence of a "le" metamethod, | |
| 606 | +Lua tries the "lt", assuming that <code>a <= b</code> is | |
| 607 | +equivalent to <code>not (b < a)</code>. | |
| 760 | 608 | </li> |
| 761 | 609 | |
| 762 | −</ul> | |
| 610 | +<li><b>"index":</b> | |
| 611 | +The indexing access <code>table[key]</code>. | |
| 763 | 612 | |
| 764 | −<p> | |
| 765 | −The generic <b>for</b> statement works over functions, | |
| 766 | −called <em>iterators</em>. | |
| 767 | −On each iteration, the iterator function is called to produce a new value, | |
| 768 | −stopping when this new value is <b>nil</b>. | |
| 769 | −The generic <b>for</b> loop has the following syntax: | |
| 770 | 613 | |
| 771 | 614 | <pre> |
| 772 | − stat ::= <b>for</b> namelist <b>in</b> explist <b>do</b> block <b>end</b> | |
| 773 | − namelist ::= Name {`<b>,</b>´ Name} | |
| 615 | + function gettable_event (table, key) | |
| 616 | + local h | |
| 617 | + if type(table) == "table" then | |
| 618 | + local v = rawget(table, key) | |
| 619 | + if v ~= nil then return v end | |
| 620 | + h = metatable(table).__index | |
| 621 | + if h == nil then return nil end | |
| 622 | + else | |
| 623 | + h = metatable(table).__index | |
| 624 | + if h == nil then | |
| 625 | + error(···) | |
| 626 | + end | |
| 627 | + end | |
| 628 | + if type(h) == "function" then | |
| 629 | + return (h(table, key)) -- call the handler | |
| 630 | + else return h[key] -- or repeat operation on it | |
| 631 | + end | |
| 632 | + end | |
| 774 | 633 | </pre><p> |
| 775 | −A <b>for</b> statement like | |
| 634 | +</li> | |
| 635 | + | |
| 636 | +<li><b>"newindex":</b> | |
| 637 | +The indexing assignment <code>table[key] = value</code>. | |
| 776 | 638 | |
| 777 | −<pre> | |
| 778 | − for <em>var_1</em>, ···, <em>var_n</em> in <em>explist</em> do <em>block</em> end | |
| 779 | −</pre><p> | |
| 780 | −is equivalent to the code: | |
| 781 | 639 | |
| 782 | 640 | <pre> |
| 783 | − do | |
| 784 | − local <em>f</em>, <em>s</em>, <em>var</em> = <em>explist</em> | |
| 785 | − while true do | |
| 786 | − local <em>var_1</em>, ···, <em>var_n</em> = <em>f</em>(<em>s</em>, <em>var</em>) | |
| 787 | − <em>var</em> = <em>var_1</em> | |
| 788 | − if <em>var</em> == nil then break end | |
| 789 | − <em>block</em> | |
| 641 | + function settable_event (table, key, value) | |
| 642 | + local h | |
| 643 | + if type(table) == "table" then | |
| 644 | + local v = rawget(table, key) | |
| 645 | + if v ~= nil then rawset(table, key, value); return end | |
| 646 | + h = metatable(table).__newindex | |
| 647 | + if h == nil then rawset(table, key, value); return end | |
| 648 | + else | |
| 649 | + h = metatable(table).__newindex | |
| 650 | + if h == nil then | |
| 651 | + error(···) | |
| 652 | + end | |
| 653 | + end | |
| 654 | + if type(h) == "function" then | |
| 655 | + h(table, key,value) -- call the handler | |
| 656 | + else h[key] = value -- or repeat operation on it | |
| 790 | 657 | end |
| 791 | 658 | end |
| 792 | 659 | </pre><p> |
| 793 | −Note the following: | |
| 794 | − | |
| 795 | −<ul> | |
| 796 | − | |
| 797 | −<li> | |
| 798 | −<code><em>explist</em></code> is evaluated only once. | |
| 799 | −Its results are an <em>iterator</em> function, | |
| 800 | −a <em>state</em>, | |
| 801 | −and an initial value for the first <em>iterator variable</em>. | |
| 802 | 660 | </li> |
| 803 | 661 | |
| 804 | −<li> | |
| 805 | −<code><em>f</em></code>, <code><em>s</em></code>, and <code><em>var</em></code> are invisible variables. | |
| 806 | −The names are here for explanatory purposes only. | |
| 807 | −</li> | |
| 662 | +<li><b>"call":</b> | |
| 663 | +called when Lua calls a value. | |
| 808 | 664 | |
| 809 | −<li> | |
| 810 | −You can use <b>break</b> to exit a <b>for</b> loop. | |
| 811 | −</li> | |
| 812 | 665 | |
| 813 | −<li> | |
| 814 | −The loop variables <code><em>var_i</em></code> are local to the loop; | |
| 815 | −you cannot use their values after the <b>for</b> ends. | |
| 816 | −If you need these values, | |
| 817 | −then assign them to other variables before breaking or exiting the loop. | |
| 666 | +<pre> | |
| 667 | + function function_event (func, ...) | |
| 668 | + if type(func) == "function" then | |
| 669 | + return func(...) -- primitive call | |
| 670 | + else | |
| 671 | + local h = metatable(func).__call | |
| 672 | + if h then | |
| 673 | + return h(func, ...) | |
| 674 | + else | |
| 675 | + error(···) | |
| 676 | + end | |
| 677 | + end | |
| 678 | + end | |
| 679 | +</pre><p> | |
| 818 | 680 | </li> |
| 819 | 681 | |
| 820 | 682 | </ul> |
| @@ -822,1481 +684,1581 @@ then assign them to other variables before breaking or exiting the loop. · 1 unmodified line | ||
| 822 | 684 | |
| 823 | 685 | |
| 824 | 686 | |
| 825 | −<h3>2.4.6 - <a name="2.4.6">Function Calls as Statements</a></h3><p> | |
| 826 | −To allow possible side-effects, | |
| 827 | −function calls can be executed as statements: | |
| 828 | − | |
| 829 | −<pre> | |
| 830 | − stat ::= functioncall | |
| 831 | −</pre><p> | |
| 832 | −In this case, all returned values are thrown away. | |
| 833 | −Function calls are explained in <a href="#2.5.8">§2.5.8</a>. | |
| 687 | +<h2>2.5 - <a name="2.5">Garbage Collection</a></h2> | |
| 834 | 688 | |
| 689 | +<p> | |
| 690 | +Lua performs automatic memory management. | |
| 691 | +This means that | |
| 692 | +you have to worry neither about allocating memory for new objects | |
| 693 | +nor about freeing it when the objects are no longer needed. | |
| 694 | +Lua manages memory automatically by running | |
| 695 | +a <em>garbage collector</em> to collect all <em>dead objects</em> | |
| 696 | +(that is, objects that are no longer accessible from Lua). | |
| 697 | +All memory used by Lua is subject to automatic management: | |
| 698 | +tables, userdata, functions, threads, strings, etc. | |
| 835 | 699 | |
| 836 | 700 | |
| 701 | +<p> | |
| 702 | +Lua implements an incremental mark-and-sweep collector. | |
| 703 | +It uses two numbers to control its garbage-collection cycles: | |
| 704 | +the <em>garbage-collector pause</em> and | |
| 705 | +the <em>garbage-collector step multiplier</em>. | |
| 706 | +Both use percentage points as units | |
| 707 | +(so that a value of 100 means an internal value of 1). | |
| 837 | 708 | |
| 838 | 709 | |
| 839 | −<h3>2.4.7 - <a name="2.4.7">Local Declarations</a></h3><p> | |
| 840 | −Local variables can be declared anywhere inside a block. | |
| 841 | −The declaration can include an initial assignment: | |
| 842 | − | |
| 843 | −<pre> | |
| 844 | − stat ::= <b>local</b> namelist [`<b>=</b>´ explist] | |
| 845 | −</pre><p> | |
| 846 | −If present, an initial assignment has the same semantics | |
| 847 | −of a multiple assignment (see <a href="#2.4.3">§2.4.3</a>). | |
| 848 | −Otherwise, all variables are initialized with <b>nil</b>. | |
| 710 | +<p> | |
| 711 | +The garbage-collector pause | |
| 712 | +controls how long the collector waits before starting a new cycle. | |
| 713 | +Larger values make the collector less aggressive. | |
| 714 | +Values smaller than 100 mean the collector will not wait to | |
| 715 | +start a new cycle. | |
| 716 | +A value of 200 means that the collector waits for the total memory in use | |
| 717 | +to double before starting a new cycle. | |
| 849 | 718 | |
| 850 | 719 | |
| 851 | 720 | <p> |
| 852 | −A chunk is also a block (see <a href="#2.4.1">§2.4.1</a>), | |
| 853 | −and so local variables can be declared in a chunk outside any explicit block. | |
| 854 | −The scope of such local variables extends until the end of the chunk. | |
| 721 | +The step multiplier | |
| 722 | +controls the relative speed of the collector relative to | |
| 723 | +memory allocation. | |
| 724 | +Larger values make the collector more aggressive but also increase | |
| 725 | +the size of each incremental step. | |
| 726 | +Values smaller than 100 make the collector too slow and | |
| 727 | +can result in the collector never finishing a cycle. | |
| 728 | +The default, 200, means that the collector runs at "twice" | |
| 729 | +the speed of memory allocation. | |
| 855 | 730 | |
| 856 | 731 | |
| 857 | 732 | <p> |
| 858 | −The visibility rules for local variables are explained in <a href="#2.6">§2.6</a>. | |
| 733 | +If you set the step multiplier to a very large number | |
| 734 | +(larger than 10% of the maximum number of | |
| 735 | +bytes that the program may use), | |
| 736 | +the collector behaves like a stop-the-world collector. | |
| 737 | +If you then set the pause to 200, | |
| 738 | +the collector behaves as in old Lua versions, | |
| 739 | +doing a complete collection every time Lua doubles its | |
| 740 | +memory usage. | |
| 859 | 741 | |
| 860 | 742 | |
| 743 | +<p> | |
| 744 | +You can change these numbers by calling <a href="#lua_gc"><code>lua_gc</code></a> in C | |
| 745 | +or <a href="#pdf-collectgarbage"><code>collectgarbage</code></a> in Lua. | |
| 746 | +With these functions you can also control | |
| 747 | +the collector directly (e.g., stop and restart it). | |
| 861 | 748 | |
| 862 | 749 | |
| 863 | 750 | |
| 864 | −<h3>2.4.8 - <a name="2.4.8">Lexical Environments</a></h3> | |
| 751 | +<h3>2.5.1 - <a name="2.5.1">Garbage-Collection Metamethods</a></h3> | |
| 865 | 752 | |
| 866 | 753 | <p> |
| 867 | −A lexical environment defines a new current environment (see <a href="#2.9">§2.9</a>) | |
| 868 | −for the code inside its block: | |
| 869 | − | |
| 870 | −<pre> | |
| 871 | − stat ::= <b>in</b> exp <b>do</b> block <b>end</b> | |
| 872 | −</pre><p> | |
| 873 | −That is, a lexical environment changes the | |
| 874 | −table used to resolve all accesses | |
| 875 | −to global (free) variables inside a block. | |
| 754 | +Using the C API, | |
| 755 | +you can set garbage-collector metamethods for userdata (see <a href="#2.4">§2.4</a>). | |
| 756 | +These metamethods are also called <em>finalizers</em>. | |
| 757 | +Finalizers allow you to coordinate Lua's garbage collection | |
| 758 | +with external resource management | |
| 759 | +(such as closing files, network or database connections, | |
| 760 | +or freeing your own memory). | |
| 876 | 761 | |
| 877 | 762 | |
| 878 | 763 | <p> |
| 879 | −Inside a lexical environment, | |
| 880 | −the result of <code><em>exp</em></code> becomes the current environment. | |
| 881 | −Expression <code><em>exp</em></code> is evaluated only once in the beginning of | |
| 882 | −the statement and it is stored in a hidden local variable named | |
| 883 | −<a name="pdf-(environment)"><code>(environment)</code></a>. | |
| 884 | −Then, any global variable | |
| 885 | −(that is, a variable not declared as a local) | |
| 886 | −<code>var</code> inside <code><em>block</em></code> is accessed as | |
| 887 | −<code>(environment).<em>var</em></code>. | |
| 888 | −Moreover, functions defined inside the block also use the | |
| 889 | −current environment as their environments (see <a href="#2.9">§2.9</a>). | |
| 764 | +Garbage userdata with a field <code>__gc</code> in their metatables are not | |
| 765 | +collected immediately by the garbage collector. | |
| 766 | +Instead, Lua puts them in a list. | |
| 767 | +After the collection, | |
| 768 | +Lua does the equivalent of the following function | |
| 769 | +for each userdata in that list: | |
| 890 | 770 | |
| 771 | +<pre> | |
| 772 | + function gc_event (udata) | |
| 773 | + local h = metatable(udata).__gc | |
| 774 | + if h then | |
| 775 | + h(udata) | |
| 776 | + end | |
| 777 | + end | |
| 778 | +</pre> | |
| 891 | 779 | |
| 892 | 780 | <p> |
| 893 | −A lexical environment does not shadow local declarations. | |
| 894 | −That is, any local variable that is visible just before | |
| 895 | −a lexical environment is still visible inside the environment. | |
| 896 | − | |
| 897 | − | |
| 781 | +At the end of each garbage-collection cycle, | |
| 782 | +the finalizers for userdata are called in <em>reverse</em> | |
| 783 | +order of their creation, | |
| 784 | +among those collected in that cycle. | |
| 785 | +That is, the first finalizer to be called is the one associated | |
| 786 | +with the userdata created last in the program. | |
| 787 | +The userdata itself is freed only in the next garbage-collection cycle. | |
| 898 | 788 | |
| 899 | 789 | |
| 900 | 790 | |
| 901 | 791 | |
| 902 | 792 | |
| 903 | −<h2>2.5 - <a name="2.5">Expressions</a></h2> | |
| 793 | +<h3>2.5.2 - <a name="2.5.2">Weak Tables</a></h3> | |
| 904 | 794 | |
| 905 | 795 | <p> |
| 906 | −The basic expressions in Lua are the following: | |
| 796 | +A <em>weak table</em> is a table whose elements are | |
| 797 | +<em>weak references</em>. | |
| 798 | +A weak reference is ignored by the garbage collector. | |
| 799 | +In other words, | |
| 800 | +if the only references to an object are weak references, | |
| 801 | +then the garbage collector will collect this object. | |
| 907 | 802 | |
| 908 | −<pre> | |
| 909 | − exp ::= prefixexp | |
| 910 | − exp ::= <b>nil</b> | <b>false</b> | <b>true</b> | |
| 911 | − exp ::= Number | |
| 912 | − exp ::= String | |
| 913 | − exp ::= function | |
| 914 | − exp ::= tableconstructor | |
| 915 | − exp ::= `<b>...</b>´ | |
| 916 | − exp ::= exp binop exp | |
| 917 | − exp ::= unop exp | |
| 918 | − prefixexp ::= var | functioncall | `<b>(</b>´ exp `<b>)</b>´ | |
| 919 | −</pre> | |
| 920 | 803 | |
| 921 | 804 | <p> |
| 922 | −Numbers and literal strings are explained in <a href="#2.1">§2.1</a>; | |
| 923 | −variables are explained in <a href="#2.3">§2.3</a>; | |
| 924 | −function definitions are explained in <a href="#2.5.9">§2.5.9</a>; | |
| 925 | −function calls are explained in <a href="#2.5.8">§2.5.8</a>; | |
| 926 | −table constructors are explained in <a href="#2.5.7">§2.5.7</a>. | |
| 927 | −Vararg expressions, | |
| 928 | −denoted by three dots ('<code>...</code>'), can only be used when | |
| 929 | −directly inside a vararg function; | |
| 930 | −they are explained in <a href="#2.5.9">§2.5.9</a>. | |
| 805 | +A weak table can have weak keys, weak values, or both. | |
| 806 | +A table with weak keys allows the collection of its keys, | |
| 807 | +but prevents the collection of its values. | |
| 808 | +A table with both weak keys and weak values allows the collection of | |
| 809 | +both keys and values. | |
| 810 | +In any case, if either the key or the value is collected, | |
| 811 | +the whole pair is removed from the table. | |
| 812 | +The weakness of a table is controlled by the | |
| 813 | +<code>__mode</code> field of its metatable. | |
| 814 | +If the <code>__mode</code> field is a string containing the character '<code>k</code>', | |
| 815 | +the keys in the table are weak. | |
| 816 | +If <code>__mode</code> contains '<code>v</code>', | |
| 817 | +the values in the table are weak. | |
| 931 | 818 | |
| 932 | 819 | |
| 933 | 820 | <p> |
| 934 | −Binary operators comprise arithmetic operators (see <a href="#2.5.1">§2.5.1</a>), | |
| 935 | −relational operators (see <a href="#2.5.2">§2.5.2</a>), logical operators (see <a href="#2.5.3">§2.5.3</a>), | |
| 936 | −and the concatenation operator (see <a href="#2.5.4">§2.5.4</a>). | |
| 937 | −Unary operators comprise the unary minus (see <a href="#2.5.1">§2.5.1</a>), | |
| 938 | −the unary <b>not</b> (see <a href="#2.5.3">§2.5.3</a>), | |
| 939 | −and the unary <em>length operator</em> (see <a href="#2.5.5">§2.5.5</a>). | |
| 821 | +A table with weak keys and strong values | |
| 822 | +is also called an <em>ephemeron table</em>. | |
| 823 | +In an ephemeron table, | |
| 824 | +a value is considered reachable only if its key is reachable. | |
| 825 | +In particular, | |
| 826 | +if the only reference to a key comes from its value, | |
| 827 | +the pair is removed. | |
| 940 | 828 | |
| 941 | 829 | |
| 942 | 830 | <p> |
| 943 | −Both function calls and vararg expressions can result in multiple values. | |
| 944 | −If an expression is used as a statement | |
| 945 | −(only possible for function calls (see <a href="#2.4.6">§2.4.6</a>)), | |
| 946 | −then its return list is adjusted to zero elements, | |
| 947 | −thus discarding all returned values. | |
| 948 | −If an expression is used as the last (or the only) element | |
| 949 | −of a list of expressions, | |
| 950 | −then no adjustment is made | |
| 951 | −(unless the call is enclosed in parentheses). | |
| 952 | −In all other contexts, | |
| 953 | −Lua adjusts the result list to one element, | |
| 954 | −discarding all values except the first one. | |
| 831 | +After you use a table as a metatable, | |
| 832 | +you should not change the value of its <code>__mode</code> field. | |
| 833 | +Otherwise, the weak behavior of the tables controlled by this | |
| 834 | +metatable is undefined. | |
| 955 | 835 | |
| 956 | 836 | |
| 957 | 837 | <p> |
| 958 | −Here are some examples: | |
| 838 | +Only objects that have an explicit construction | |
| 839 | +can be removed from weak tables. | |
| 840 | +Values, such as numbers and booleans, | |
| 841 | +are not subject to garbage collection, | |
| 842 | +and therefore are not removed from weak tables | |
| 843 | +(unless its associated value is collected). | |
| 844 | +Lua treats strings and light C functions as non-object values. | |
| 959 | 845 | |
| 960 | −<pre> | |
| 961 | − f() -- adjusted to 0 results | |
| 962 | − g(f(), x) -- f() is adjusted to 1 result | |
| 963 | − g(x, f()) -- g gets x plus all results from f() | |
| 964 | − a,b,c = f(), x -- f() is adjusted to 1 result (c gets nil) | |
| 965 | − a,b = ... -- a gets the first vararg parameter, b gets | |
| 966 | − -- the second (both a and b can get nil if there | |
| 967 | − -- is no corresponding vararg parameter) | |
| 968 | − | |
| 969 | − a,b,c = x, f() -- f() is adjusted to 2 results | |
| 970 | − a,b,c = f() -- f() is adjusted to 3 results | |
| 971 | − return f() -- returns all results from f() | |
| 972 | − return ... -- returns all received vararg parameters | |
| 973 | − return x,y,f() -- returns x, y, and all results from f() | |
| 974 | − {f()} -- creates a list with all results from f() | |
| 975 | − {...} -- creates a list with all vararg parameters | |
| 976 | − {f(), nil} -- f() is adjusted to 1 result | |
| 977 | −</pre> | |
| 978 | 846 | |
| 979 | 847 | <p> |
| 980 | −Any expression enclosed in parentheses always results in only one value. | |
| 981 | −Thus, | |
| 982 | −<code>(f(x,y,z))</code> is always a single value, | |
| 983 | −even if <code>f</code> returns several values. | |
| 984 | −(The value of <code>(f(x,y,z))</code> is the first value returned by <code>f</code> | |
| 985 | −or <b>nil</b> if <code>f</code> does not return any values.) | |
| 848 | +Userdata with finalizers has a special behavior in weak tables. | |
| 849 | +When a userdata is a value in a weak table, | |
| 850 | +it is removed from the table the first time it is collected, | |
| 851 | +before running its finalizer. | |
| 852 | +When it is a key, however, | |
| 853 | +it is removed from the table only when it is really freed, | |
| 854 | +after running its finalizer. | |
| 855 | +This behavior allows the finalizer to access values | |
| 856 | +associated with the userdata through weak tables. | |
| 986 | 857 | |
| 987 | 858 | |
| 988 | 859 | |
| 989 | −<h3>2.5.1 - <a name="2.5.1">Arithmetic Operators</a></h3><p> | |
| 990 | −Lua supports the usual arithmetic operators: | |
| 991 | −the binary <code>+</code> (addition), | |
| 992 | −<code>-</code> (subtraction), <code>*</code> (multiplication), | |
| 993 | −<code>/</code> (division), <code>%</code> (modulo), and <code>^</code> (exponentiation); | |
| 994 | −and unary <code>-</code> (negation). | |
| 995 | −If the operands are numbers, or strings that can be converted to | |
| 996 | −numbers (see <a href="#2.2.1">§2.2.1</a>), | |
| 997 | −then all operations have the usual meaning. | |
| 998 | −Exponentiation works for any exponent. | |
| 999 | −For instance, <code>x^(-0.5)</code> computes the inverse of the square root of <code>x</code>. | |
| 1000 | −Modulo is defined as | |
| 1001 | 860 | |
| 1002 | −<pre> | |
| 1003 | − a % b == a - math.floor(a/b)*b | |
| 1004 | −</pre><p> | |
| 1005 | −That is, it is the remainder of a division that rounds | |
| 1006 | −the quotient towards minus infinity. | |
| 1007 | 861 | |
| 1008 | 862 | |
| 1009 | 863 | |
| 864 | +<h2>2.6 - <a name="2.6">Coroutines</a></h2> | |
| 1010 | 865 | |
| 866 | +<p> | |
| 867 | +Lua supports coroutines, | |
| 868 | +also called <em>collaborative multithreading</em>. | |
| 869 | +A coroutine in Lua represents an independent thread of execution. | |
| 870 | +Unlike threads in multithread systems, however, | |
| 871 | +a coroutine only suspends its execution by explicitly calling | |
| 872 | +a yield function. | |
| 1011 | 873 | |
| 1012 | −<h3>2.5.2 - <a name="2.5.2">Relational Operators</a></h3><p> | |
| 1013 | −The relational operators in Lua are | |
| 1014 | 874 | |
| 1015 | −<pre> | |
| 1016 | − == ~= < > <= >= | |
| 1017 | −</pre><p> | |
| 1018 | −These operators always result in <b>false</b> or <b>true</b>. | |
| 875 | +<p> | |
| 876 | +You create a coroutine with a call to <a href="#pdf-coroutine.create"><code>coroutine.create</code></a>. | |
| 877 | +Its sole argument is a function | |
| 878 | +that is the main function of the coroutine. | |
| 879 | +The <code>create</code> function only creates a new coroutine and | |
| 880 | +returns a handle to it (an object of type <em>thread</em>); | |
| 881 | +it does not start the coroutine execution. | |
| 1019 | 882 | |
| 1020 | 883 | |
| 1021 | 884 | <p> |
| 1022 | −Equality (<code>==</code>) first compares the type of its operands. | |
| 1023 | −If the types are different, then the result is <b>false</b>. | |
| 1024 | −Otherwise, the values of the operands are compared. | |
| 1025 | −Numbers and strings are compared in the usual way. | |
| 1026 | −Objects (tables, userdata, threads, and functions) | |
| 1027 | −are compared by <em>reference</em>: | |
| 1028 | −two objects are considered equal only if they are the <em>same</em> object. | |
| 1029 | −Every time you create a new object | |
| 1030 | −(a table, userdata, thread, or function), | |
| 1031 | −this new object is different from any previously existing object. | |
| 885 | +When you first call <a href="#pdf-coroutine.resume"><code>coroutine.resume</code></a>, | |
| 886 | +passing as its first argument | |
| 887 | +a thread returned by <a href="#pdf-coroutine.create"><code>coroutine.create</code></a>, | |
| 888 | +the coroutine starts its execution, | |
| 889 | +at the first line of its main function. | |
| 890 | +Extra arguments passed to <a href="#pdf-coroutine.resume"><code>coroutine.resume</code></a> are passed on | |
| 891 | +to the coroutine main function. | |
| 892 | +After the coroutine starts running, | |
| 893 | +it runs until it terminates or <em>yields</em>. | |
| 1032 | 894 | |
| 1033 | 895 | |
| 1034 | 896 | <p> |
| 1035 | −You can change the way that Lua compares tables and userdata | |
| 1036 | −by using the "eq" metamethod (see <a href="#2.8">§2.8</a>). | |
| 897 | +A coroutine can terminate its execution in two ways: | |
| 898 | +normally, when its main function returns | |
| 899 | +(explicitly or implicitly, after the last instruction); | |
| 900 | +and abnormally, if there is an unprotected error. | |
| 901 | +In the first case, <a href="#pdf-coroutine.resume"><code>coroutine.resume</code></a> returns <b>true</b>, | |
| 902 | +plus any values returned by the coroutine main function. | |
| 903 | +In case of errors, <a href="#pdf-coroutine.resume"><code>coroutine.resume</code></a> returns <b>false</b> | |
| 904 | +plus an error message. | |
| 1037 | 905 | |
| 1038 | 906 | |
| 1039 | 907 | <p> |
| 1040 | −The conversion rules of <a href="#2.2.1">§2.2.1</a> | |
| 1041 | −<em>do not</em> apply to equality comparisons. | |
| 1042 | −Thus, <code>"0"==0</code> evaluates to <b>false</b>, | |
| 1043 | −and <code>t[0]</code> and <code>t["0"]</code> denote different | |
| 1044 | −entries in a table. | |
| 908 | +A coroutine yields by calling <a href="#pdf-coroutine.yield"><code>coroutine.yield</code></a>. | |
| 909 | +When a coroutine yields, | |
| 910 | +the corresponding <a href="#pdf-coroutine.resume"><code>coroutine.resume</code></a> returns immediately, | |
| 911 | +even if the yield happens inside nested function calls | |
| 912 | +(that is, not in the main function, | |
| 913 | +but in a function directly or indirectly called by the main function). | |
| 914 | +In the case of a yield, <a href="#pdf-coroutine.resume"><code>coroutine.resume</code></a> also returns <b>true</b>, | |
| 915 | +plus any values passed to <a href="#pdf-coroutine.yield"><code>coroutine.yield</code></a>. | |
| 916 | +The next time you resume the same coroutine, | |
| 917 | +it continues its execution from the point where it yielded, | |
| 918 | +with the call to <a href="#pdf-coroutine.yield"><code>coroutine.yield</code></a> returning any extra | |
| 919 | +arguments passed to <a href="#pdf-coroutine.resume"><code>coroutine.resume</code></a>. | |
| 1045 | 920 | |
| 1046 | 921 | |
| 1047 | 922 | <p> |
| 1048 | −The operator <code>~=</code> is exactly the negation of equality (<code>==</code>). | |
| 923 | +Like <a href="#pdf-coroutine.create"><code>coroutine.create</code></a>, | |
| 924 | +the <a href="#pdf-coroutine.wrap"><code>coroutine.wrap</code></a> function also creates a coroutine, | |
| 925 | +but instead of returning the coroutine itself, | |
| 926 | +it returns a function that, when called, resumes the coroutine. | |
| 927 | +Any arguments passed to this function | |
| 928 | +go as extra arguments to <a href="#pdf-coroutine.resume"><code>coroutine.resume</code></a>. | |
| 929 | +<a href="#pdf-coroutine.wrap"><code>coroutine.wrap</code></a> returns all the values returned by <a href="#pdf-coroutine.resume"><code>coroutine.resume</code></a>, | |
| 930 | +except the first one (the boolean error code). | |
| 931 | +Unlike <a href="#pdf-coroutine.resume"><code>coroutine.resume</code></a>, | |
| 932 | +<a href="#pdf-coroutine.wrap"><code>coroutine.wrap</code></a> does not catch errors; | |
| 933 | +any error is propagated to the caller. | |
| 1049 | 934 | |
| 1050 | 935 | |
| 1051 | 936 | <p> |
| 1052 | −The order operators work as follows. | |
| 1053 | −If both arguments are numbers, then they are compared as such. | |
| 1054 | −Otherwise, if both arguments are strings, | |
| 1055 | −then their values are compared according to the current locale. | |
| 1056 | −Otherwise, Lua tries to call the "lt" or the "le" | |
| 1057 | −metamethod (see <a href="#2.8">§2.8</a>). | |
| 1058 | −A comparison <code>a > b</code> is translated to <code>b < a</code> | |
| 1059 | −and <code>a >= b</code> is translated to <code>b <= a</code>. | |
| 937 | +As an example, | |
| 938 | +consider the following code: | |
| 1060 | 939 | |
| 940 | +<pre> | |
| 941 | + function foo (a) | |
| 942 | + print("foo", a) | |
| 943 | + return coroutine.yield(2*a) | |
| 944 | + end | |
| 945 | + | |
| 946 | + co = coroutine.create(function (a,b) | |
| 947 | + print("co-body", a, b) | |
| 948 | + local r = foo(a+1) | |
| 949 | + print("co-body", r) | |
| 950 | + local r, s = coroutine.yield(a+b, a-b) | |
| 951 | + print("co-body", r, s) | |
| 952 | + return b, "end" | |
| 953 | + end) | |
| 954 | + | |
| 955 | + print("main", coroutine.resume(co, 1, 10)) | |
| 956 | + print("main", coroutine.resume(co, "r")) | |
| 957 | + print("main", coroutine.resume(co, "x", "y")) | |
| 958 | + print("main", coroutine.resume(co, "x", "y")) | |
| 959 | +</pre><p> | |
| 960 | +When you run it, it produces the following output: | |
| 1061 | 961 | |
| 962 | +<pre> | |
| 963 | + co-body 1 10 | |
| 964 | + foo 2 | |
| 965 | + | |
| 966 | + main true 4 | |
| 967 | + co-body r | |
| 968 | + main true 11 -9 | |
| 969 | + co-body x y | |
| 970 | + main true 10 end | |
| 971 | + main false cannot resume dead coroutine | |
| 972 | +</pre> | |
| 1062 | 973 | |
| 1063 | 974 | |
| 1064 | 975 | |
| 1065 | −<h3>2.5.3 - <a name="2.5.3">Logical Operators</a></h3><p> | |
| 1066 | −The logical operators in Lua are | |
| 1067 | −<b>and</b>, <b>or</b>, and <b>not</b>. | |
| 1068 | −Like the control structures (see <a href="#2.4.4">§2.4.4</a>), | |
| 1069 | −all logical operators consider both <b>false</b> and <b>nil</b> as false | |
| 1070 | −and anything else as true. | |
| 1071 | 976 | |
| 977 | +<h1>3 - <a name="3">The Language</a></h1> | |
| 1072 | 978 | |
| 1073 | 979 | <p> |
| 1074 | −The negation operator <b>not</b> always returns <b>false</b> or <b>true</b>. | |
| 1075 | −The conjunction operator <b>and</b> returns its first argument | |
| 1076 | −if this value is <b>false</b> or <b>nil</b>; | |
| 1077 | −otherwise, <b>and</b> returns its second argument. | |
| 1078 | −The disjunction operator <b>or</b> returns its first argument | |
| 1079 | −if this value is different from <b>nil</b> and <b>false</b>; | |
| 1080 | −otherwise, <b>or</b> returns its second argument. | |
| 1081 | −Both <b>and</b> and <b>or</b> use short-cut evaluation; | |
| 1082 | −that is, | |
| 1083 | −the second operand is evaluated only if necessary. | |
| 1084 | −Here are some examples: | |
| 980 | +This section describes the lexis, the syntax, and the semantics of Lua. | |
| 981 | +In other words, | |
| 982 | +this section describes | |
| 983 | +which tokens are valid, | |
| 984 | +how they can be combined, | |
| 985 | +and what their combinations mean. | |
| 1085 | 986 | |
| 1086 | −<pre> | |
| 1087 | − 10 or 20 --> 10 | |
| 1088 | − 10 or error() --> 10 | |
| 1089 | − nil or "a" --> "a" | |
| 1090 | − nil and 10 --> nil | |
| 1091 | − false and error() --> false | |
| 1092 | − false and nil --> false | |
| 1093 | − false or nil --> nil | |
| 1094 | − 10 and 20 --> 20 | |
| 1095 | −</pre><p> | |
| 1096 | −(In this manual, | |
| 1097 | −<code>--></code> indicates the result of the preceding expression.) | |
| 1098 | 987 | |
| 988 | +<p> | |
| 989 | +The language constructs will be explained using the usual extended BNF notation, | |
| 990 | +in which | |
| 991 | +{<em>a</em>} means 0 or more <em>a</em>'s, and | |
| 992 | +[<em>a</em>] means an optional <em>a</em>. | |
| 993 | +Non-terminals are shown like non-terminal, | |
| 994 | +keywords are shown like <b>kword</b>, | |
| 995 | +and other terminal symbols are shown like &lsquo<b>=</b>’. | |
| 996 | +The complete syntax of Lua can be found in <a href="#9">§9</a> | |
| 997 | +at the end of this manual. | |
| 1099 | 998 | |
| 1100 | 999 | |
| 1101 | 1000 | |
| 1001 | +<h2>3.1 - <a name="3.1">Lexical Conventions</a></h2> | |
| 1002 | + | |
| 1003 | +<p> | |
| 1004 | +Lua is a free-form language. | |
| 1005 | +It ignores spaces (including new lines) and comments | |
| 1006 | +between lexical elements (tokens), | |
| 1007 | +except as delimiters between names and keywords. | |
| 1102 | 1008 | |
| 1103 | −<h3>2.5.4 - <a name="2.5.4">Concatenation</a></h3><p> | |
| 1104 | −The string concatenation operator in Lua is | |
| 1105 | −denoted by two dots ('<code>..</code>'). | |
| 1106 | −If both operands are strings or numbers, then they are converted to | |
| 1107 | −strings according to the rules mentioned in <a href="#2.2.1">§2.2.1</a>. | |
| 1108 | −Otherwise, the "concat" metamethod is called (see <a href="#2.8">§2.8</a>). | |
| 1109 | 1009 | |
| 1010 | +<p> | |
| 1011 | +<em>Names</em> | |
| 1012 | +(also called <em>identifiers</em>) | |
| 1013 | +in Lua can be any string of letters, | |
| 1014 | +digits, and underscores, | |
| 1015 | +not beginning with a digit. | |
| 1016 | +This coincides with the definition of names in most languages. | |
| 1017 | +Identifiers are used to name variables and table fields. | |
| 1110 | 1018 | |
| 1111 | 1019 | |
| 1020 | +<p> | |
| 1021 | +The following <em>keywords</em> are reserved | |
| 1022 | +and cannot be used as names: | |
| 1112 | 1023 | |
| 1113 | 1024 | |
| 1114 | −<h3>2.5.5 - <a name="2.5.5">The Length Operator</a></h3> | |
| 1025 | +<pre> | |
| 1026 | + and break do else elseif | |
| 1027 | + end false for function if | |
| 1028 | + in local nil not or | |
| 1029 | + repeat return then true until while | |
| 1030 | +</pre> | |
| 1115 | 1031 | |
| 1116 | 1032 | <p> |
| 1117 | −The length operator is denoted by the unary prefix operator <code>#</code>. | |
| 1118 | −The length of a string is its number of bytes | |
| 1119 | −(that is, the usual meaning of string length when each | |
| 1120 | −character is one byte). | |
| 1033 | +Lua is a case-sensitive language: | |
| 1034 | +<code>and</code> is a reserved word, but <code>And</code> and <code>AND</code> | |
| 1035 | +are two different, valid names. | |
| 1036 | +As a convention, names starting with an underscore followed by | |
| 1037 | +uppercase letters (such as <a href="#pdf-_VERSION"><code>_VERSION</code></a>) | |
| 1038 | +are reserved for variables used by Lua. | |
| 1121 | 1039 | |
| 1122 | 1040 | |
| 1123 | 1041 | <p> |
| 1124 | −The length of a table <code>t</code> is defined to be any | |
| 1125 | −integer index <code>n</code> | |
| 1126 | −such that <code>t[n]</code> is not <b>nil</b> and <code>t[n+1]</code> is <b>nil</b>; | |
| 1127 | −moreover, if <code>t[1]</code> is <b>nil</b>, <code>n</code> can be zero. | |
| 1128 | −For a regular array, where all non-nil values | |
| 1129 | −have keys from 1 to a given <code>n</code>, | |
| 1130 | −its length is exactly that <code>n</code>, | |
| 1131 | −the index of its last value. | |
| 1132 | −If the array has "holes" | |
| 1133 | −(that is, <b>nil</b> values between other non-nil values), | |
| 1134 | −then <code>#t</code> can be any of the indices that | |
| 1135 | −directly precedes a <b>nil</b> value | |
| 1136 | −(that is, it may consider any such <b>nil</b> value as the end of | |
| 1137 | −the array). | |
| 1042 | +The following strings denote other tokens: | |
| 1043 | + | |
| 1044 | +<pre> | |
| 1045 | + + - * / % ^ # | |
| 1046 | + == ~= <= >= < > = | |
| 1047 | + ( ) { } [ ] | |
| 1048 | + ; : , . .. ... | |
| 1049 | +</pre> | |
| 1050 | + | |
| 1051 | +<p> | |
| 1052 | +<em>Literal strings</em> | |
| 1053 | +can be delimited by matching single or double quotes, | |
| 1054 | +and can contain the following C-like escape sequences: | |
| 1055 | +'<code>\a</code>' (bell), | |
| 1056 | +'<code>\b</code>' (backspace), | |
| 1057 | +'<code>\f</code>' (form feed), | |
| 1058 | +'<code>\n</code>' (newline), | |
| 1059 | +'<code>\r</code>' (carriage return), | |
| 1060 | +'<code>\t</code>' (horizontal tab), | |
| 1061 | +'<code>\v</code>' (vertical tab), | |
| 1062 | +'<code>\\</code>' (backslash), | |
| 1063 | +'<code>\"</code>' (quotation mark [double quote]), | |
| 1064 | +and '<code>\'</code>' (apostrophe [single quote]). | |
| 1065 | +A backslash followed by a real newline | |
| 1066 | +results in a newline in the string. | |
| 1067 | +The escape sequence '<code>\*</code>' skips the following span | |
| 1068 | +of white-space characters, | |
| 1069 | +including line breaks; | |
| 1070 | +it is particularly useful to break and ident a string | |
| 1071 | +into multiple lines without adding the newlines and spaces | |
| 1072 | +into the string contents. | |
| 1138 | 1073 | |
| 1139 | 1074 | |
| 1140 | 1075 | <p> |
| 1141 | −A program can modify the behavior of the length operator for | |
| 1142 | −any value but strings through metamethods (see <a href="#2.8">§2.8</a>). | |
| 1076 | +A character in a literal string can also be specified by its numerical value. | |
| 1077 | +This can be done with the escape sequence <code>\x<em>XX</em></code>, | |
| 1078 | +where <em>XX</em> is a sequence of exactly two hexadecimal digits, | |
| 1079 | +or with the escape sequence <code>\<em>ddd</em></code>, | |
| 1080 | +where <em>ddd</em> is a sequence of up to three decimal digits. | |
| 1081 | +(Note that if a decimal escape is to be followed by a digit, | |
| 1082 | +it must be expressed using exactly three digits.) | |
| 1083 | +Strings in Lua can contain any 8-bit value, including embedded zeros, | |
| 1084 | +which can be specified as '<code>\0</code>'. | |
| 1143 | 1085 | |
| 1144 | 1086 | |
| 1087 | +<p> | |
| 1088 | +Literal strings can also be defined using a long format | |
| 1089 | +enclosed by <em>long brackets</em>. | |
| 1090 | +We define an <em>opening long bracket of level <em>n</em></em> as an opening | |
| 1091 | +square bracket followed by <em>n</em> equal signs followed by another | |
| 1092 | +opening square bracket. | |
| 1093 | +So, an opening long bracket of level 0 is written as <code>[[</code>, | |
| 1094 | +an opening long bracket of level 1 is written as <code>[=[</code>, | |
| 1095 | +and so on. | |
| 1096 | +A <em>closing long bracket</em> is defined similarly; | |
| 1097 | +for instance, a closing long bracket of level 4 is written as <code>]====]</code>. | |
| 1098 | +A long string starts with an opening long bracket of any level and | |
| 1099 | +ends at the first closing long bracket of the same level. | |
| 1100 | +It can contain any text except a closing bracket of the proper level. | |
| 1101 | +Literals in this bracketed form can run for several lines, | |
| 1102 | +do not interpret any escape sequences, | |
| 1103 | +and ignore long brackets of any other level. | |
| 1104 | +Any kind of end-of-line sequence | |
| 1105 | +(carriage return, newline, carriage return followed by newline, | |
| 1106 | +or newline followed by carriage return) | |
| 1107 | +is converted to a simple newline. | |
| 1108 | +You should not use long strings for non-text data; | |
| 1109 | +Use instead a regular quoted literal with explicit escape sequences | |
| 1110 | +for control characters. | |
| 1145 | 1111 | |
| 1146 | 1112 | |
| 1113 | +<p> | |
| 1114 | +For convenience, | |
| 1115 | +when the opening long bracket is immediately followed by a newline, | |
| 1116 | +the newline is not included in the string. | |
| 1117 | +As an example, in a system using ASCII | |
| 1118 | +(in which '<code>a</code>' is coded as 97, | |
| 1119 | +newline is coded as 10, and '<code>1</code>' is coded as 49), | |
| 1120 | +the five literal strings below denote the same string: | |
| 1147 | 1121 | |
| 1148 | −<h3>2.5.6 - <a name="2.5.6">Precedence</a></h3><p> | |
| 1149 | −Operator precedence in Lua follows the table below, | |
| 1150 | −from lower to higher priority: | |
| 1122 | +<pre> | |
| 1123 | + a = 'alo\n123"' | |
| 1124 | + a = "alo\n123\"" | |
| 1125 | + a = '\97lo\10\04923"' | |
| 1126 | + a = [[alo | |
| 1127 | + 123"]] | |
| 1128 | + a = [==[ | |
| 1129 | + alo | |
| 1130 | + 123"]==] | |
| 1131 | +</pre> | |
| 1132 | + | |
| 1133 | +<p> | |
| 1134 | +A <em>numerical constant</em> can be written with an optional decimal part | |
| 1135 | +and an optional decimal exponent. | |
| 1136 | +Lua also accepts integer hexadecimal constants, | |
| 1137 | +by prefixing them with <code>0x</code>. | |
| 1138 | +Examples of valid numerical constants are | |
| 1151 | 1139 | |
| 1152 | 1140 | <pre> |
| 1153 | − or | |
| 1154 | − and | |
| 1155 | − < > <= >= ~= == | |
| 1156 | − .. | |
| 1157 | − + - | |
| 1158 | − * / % | |
| 1159 | − not # - (unary) | |
| 1160 | − ^ | |
| 1161 | −</pre><p> | |
| 1162 | −As usual, | |
| 1163 | −you can use parentheses to change the precedences of an expression. | |
| 1164 | −The concatenation ('<code>..</code>') and exponentiation ('<code>^</code>') | |
| 1165 | −operators are right associative. | |
| 1166 | −All other binary operators are left associative. | |
| 1141 | + 3 3.0 3.1416 314.16e-2 0.31416E1 0xff 0x56 | |
| 1142 | +</pre> | |
| 1167 | 1143 | |
| 1144 | +<p> | |
| 1145 | +A <em>comment</em> starts with a double hyphen (<code>--</code>) | |
| 1146 | +anywhere outside a string. | |
| 1147 | +If the text immediately after <code>--</code> is not an opening long bracket, | |
| 1148 | +the comment is a <em>short comment</em>, | |
| 1149 | +which runs until the end of the line. | |
| 1150 | +Otherwise, it is a <em>long comment</em>, | |
| 1151 | +which runs until the corresponding closing long bracket. | |
| 1152 | +Long comments are frequently used to disable code temporarily. | |
| 1168 | 1153 | |
| 1169 | 1154 | |
| 1170 | 1155 | |
| 1171 | 1156 | |
| 1172 | −<h3>2.5.7 - <a name="2.5.7">Table Constructors</a></h3><p> | |
| 1173 | −Table constructors are expressions that create tables. | |
| 1174 | −Every time a constructor is evaluated, a new table is created. | |
| 1175 | −A constructor can be used to create an empty table | |
| 1176 | −or to create a table and initialize some of its fields. | |
| 1177 | −The general syntax for constructors is | |
| 1178 | 1157 | |
| 1179 | −<pre> | |
| 1180 | − tableconstructor ::= `<b>{</b>´ [fieldlist] `<b>}</b>´ | |
| 1181 | − fieldlist ::= field {fieldsep field} [fieldsep] | |
| 1182 | − field ::= `<b>[</b>´ exp `<b>]</b>´ `<b>=</b>´ exp | Name `<b>=</b>´ exp | exp | |
| 1183 | − fieldsep ::= `<b>,</b>´ | `<b>;</b>´ | |
| 1184 | −</pre> | |
| 1158 | +<h2>3.2 - <a name="3.2">Variables</a></h2> | |
| 1185 | 1159 | |
| 1186 | 1160 | <p> |
| 1187 | −Each field of the form <code>[exp1] = exp2</code> adds to the new table an entry | |
| 1188 | −with key <code>exp1</code> and value <code>exp2</code>. | |
| 1189 | −A field of the form <code>name = exp</code> is equivalent to | |
| 1190 | −<code>["name"] = exp</code>. | |
| 1191 | −Finally, fields of the form <code>exp</code> are equivalent to | |
| 1192 | −<code>[i] = exp</code>, where <code>i</code> are consecutive numerical integers, | |
| 1193 | −starting with 1. | |
| 1194 | −Fields in the other formats do not affect this counting. | |
| 1195 | −For example, | |
| 1161 | +Variables are places that store values. | |
| 1196 | 1162 | |
| 1197 | −<pre> | |
| 1198 | − a = { [f(1)] = g; "x", "y"; x = 1, f(x), [30] = 23; 45 } | |
| 1199 | −</pre><p> | |
| 1200 | −is equivalent to | |
| 1163 | +There are three kinds of variables in Lua: | |
| 1164 | +global variables, local variables, and table fields. | |
| 1201 | 1165 | |
| 1202 | −<pre> | |
| 1203 | − do | |
| 1204 | − local t = {} | |
| 1205 | − t[f(1)] = g | |
| 1206 | − t[1] = "x" -- 1st exp | |
| 1207 | − t[2] = "y" -- 2nd exp | |
| 1208 | − t.x = 1 -- t["x"] = 1 | |
| 1209 | − t[3] = f(x) -- 3rd exp | |
| 1210 | − t[30] = 23 | |
| 1211 | − t[4] = 45 -- 4th exp | |
| 1212 | − a = t | |
| 1213 | − end | |
| 1214 | −</pre> | |
| 1215 | 1166 | |
| 1216 | 1167 | <p> |
| 1217 | −If the last field in the list has the form <code>exp</code> | |
| 1218 | −and the expression is a function call or a vararg expression, | |
| 1219 | −then all values returned by this expression enter the list consecutively | |
| 1220 | −(see <a href="#2.5.8">§2.5.8</a>). | |
| 1221 | −To avoid this, | |
| 1222 | −enclose the function call or the vararg expression | |
| 1223 | −in parentheses (see <a href="#2.5">§2.5</a>). | |
| 1168 | +A single name can denote a global variable or a local variable | |
| 1169 | +(or a function's formal parameter, | |
| 1170 | +which is a particular kind of local variable): | |
| 1171 | + | |
| 1172 | +<pre> | |
| 1173 | + var ::= Name | |
| 1174 | +</pre><p> | |
| 1175 | +Name denotes identifiers, as defined in <a href="#3.1">§3.1</a>. | |
| 1224 | 1176 | |
| 1225 | 1177 | |
| 1226 | 1178 | <p> |
| 1227 | −The field list can have an optional trailing separator, | |
| 1228 | −as a convenience for machine-generated code. | |
| 1229 | − | |
| 1179 | +Any variable name is assumed to be global unless explicitly declared | |
| 1180 | +as a local (see <a href="#3.3.7">§3.3.7</a>). | |
| 1181 | +Local variables are <em>lexically scoped</em>: | |
| 1182 | +local variables can be freely accessed by functions | |
| 1183 | +defined inside their scope (see <a href="#3.5">§3.5</a>). | |
| 1230 | 1184 | |
| 1231 | 1185 | |
| 1186 | +<p> | |
| 1187 | +Before the first assignment to a variable, its value is <b>nil</b>. | |
| 1232 | 1188 | |
| 1233 | 1189 | |
| 1234 | −<h3>2.5.8 - <a name="2.5.8">Function Calls</a></h3><p> | |
| 1235 | −A function call in Lua has the following syntax: | |
| 1190 | +<p> | |
| 1191 | +Square brackets are used to index a table: | |
| 1236 | 1192 | |
| 1237 | 1193 | <pre> |
| 1238 | − functioncall ::= prefixexp args | |
| 1194 | + var ::= prefixexp &lsquo<b>[</b>’ exp &lsquo<b>]</b>’ | |
| 1239 | 1195 | </pre><p> |
| 1240 | −In a function call, | |
| 1241 | −first prefixexp and args are evaluated. | |
| 1242 | −If the value of prefixexp has type <em>function</em>, | |
| 1243 | −then this function is called | |
| 1244 | −with the given arguments. | |
| 1245 | −Otherwise, the prefixexp "call" metamethod is called, | |
| 1246 | −having as first parameter the value of prefixexp, | |
| 1247 | −followed by the original call arguments | |
| 1248 | −(see <a href="#2.8">§2.8</a>). | |
| 1196 | +The meaning of accesses to table fields can be changed via metatables. | |
| 1197 | +An access to an indexed variable <code>t[i]</code> is equivalent to | |
| 1198 | +a call <code>gettable_event(t,i)</code>. | |
| 1199 | +(See <a href="#2.4">§2.4</a> for a complete description of the | |
| 1200 | +<code>gettable_event</code> function. | |
| 1201 | +This function is not defined or callable in Lua. | |
| 1202 | +We use it here only for explanatory purposes.) | |
| 1249 | 1203 | |
| 1250 | 1204 | |
| 1251 | 1205 | <p> |
| 1252 | −The form | |
| 1206 | +The syntax <code>var.Name</code> is just syntactic sugar for | |
| 1207 | +<code>var["Name"]</code>: | |
| 1253 | 1208 | |
| 1254 | 1209 | <pre> |
| 1255 | − functioncall ::= prefixexp `<b>:</b>´ Name args | |
| 1256 | −</pre><p> | |
| 1257 | −can be used to call "methods". | |
| 1258 | −A call <code>v:name(<em>args</em>)</code> | |
| 1259 | −is syntactic sugar for <code>v.name(v,<em>args</em>)</code>, | |
| 1260 | −except that <code>v</code> is evaluated only once. | |
| 1261 | − | |
| 1210 | + var ::= prefixexp &lsquo<b>.</b>’ Name | |
| 1211 | +</pre> | |
| 1262 | 1212 | |
| 1263 | 1213 | <p> |
| 1264 | −Arguments have the following syntax: | |
| 1214 | +An access to a global variable <code>x</code> | |
| 1215 | +is equivalent to <code>_ENV.x</code>. | |
| 1216 | +Due to the way that chunks are compiled, | |
| 1217 | +<code>_ENV</code> is never a global name (see <a href="#2.2">§2.2</a>). | |
| 1218 | + | |
| 1219 | + | |
| 1220 | + | |
| 1265 | 1221 | |
| 1266 | −<pre> | |
| 1267 | − args ::= `<b>(</b>´ [explist] `<b>)</b>´ | |
| 1268 | − args ::= tableconstructor | |
| 1269 | − args ::= String | |
| 1270 | −</pre><p> | |
| 1271 | −All argument expressions are evaluated before the call. | |
| 1272 | −A call of the form <code>f{<em>fields</em>}</code> is | |
| 1273 | −syntactic sugar for <code>f({<em>fields</em>})</code>; | |
| 1274 | −that is, the argument list is a single new table. | |
| 1275 | −A call of the form <code>f'<em>string</em>'</code> | |
| 1276 | −(or <code>f"<em>string</em>"</code> or <code>f[[<em>string</em>]]</code>) | |
| 1277 | −is syntactic sugar for <code>f('<em>string</em>')</code>; | |
| 1278 | −that is, the argument list is a single literal string. | |
| 1279 | 1222 | |
| 1223 | +<h2>3.3 - <a name="3.3">Statements</a></h2> | |
| 1280 | 1224 | |
| 1281 | 1225 | <p> |
| 1282 | −As an exception to the free-form character of Lua, | |
| 1283 | −you cannot put a line break before the '<code>(</code>' in a function call. | |
| 1284 | −This restriction avoids some ambiguities in the language. | |
| 1285 | −If you write | |
| 1226 | +Lua supports an almost conventional set of statements, | |
| 1227 | +similar to those in Pascal or C. | |
| 1228 | +This set includes | |
| 1229 | +assignments, control structures, function calls, | |
| 1230 | +and variable declarations. | |
| 1231 | + | |
| 1286 | 1232 | |
| 1287 | −<pre> | |
| 1288 | − a = f | |
| 1289 | − (g).x(a) | |
| 1290 | −</pre><p> | |
| 1291 | −Lua would see that as a single statement, <code>a = f(g).x(a)</code>. | |
| 1292 | −In this case, if you want two statements, | |
| 1293 | −you must add a semi-colon between them. | |
| 1294 | −If you actually want to call <code>f</code>, | |
| 1295 | −you must remove the line break before <code>(g)</code>. | |
| 1296 | 1233 | |
| 1234 | +<h3>3.3.1 - <a name="3.3.1">Chunks</a></h3> | |
| 1297 | 1235 | |
| 1298 | 1236 | <p> |
| 1299 | −A call of the form <code>return</code> <em>functioncall</em> is called | |
| 1300 | −a <em>tail call</em>. | |
| 1301 | −Lua implements <em>proper tail calls</em> | |
| 1302 | −(or <em>proper tail recursion</em>): | |
| 1303 | −in a tail call, | |
| 1304 | −the called function reuses the stack entry of the calling function. | |
| 1305 | −Therefore, there is no limit on the number of nested tail calls that | |
| 1306 | −a program can execute. | |
| 1307 | −However, a tail call erases any debug information about the | |
| 1308 | −calling function. | |
| 1309 | −Note that a tail call only happens with a particular syntax, | |
| 1310 | −where the <b>return</b> has one single function call as argument; | |
| 1311 | −this syntax makes the calling function return exactly | |
| 1312 | −the returns of the called function. | |
| 1313 | −So, none of the following examples are tail calls: | |
| 1237 | +The unit of execution of Lua is called a <em>chunk</em>. | |
| 1238 | +A chunk is simply a sequence of statements, | |
| 1239 | +which are executed sequentially. | |
| 1314 | 1240 | |
| 1315 | 1241 | <pre> |
| 1316 | − return (f(x)) -- results adjusted to 1 | |
| 1317 | − return 2 * f(x) | |
| 1318 | − return x, f(x) -- additional results | |
| 1319 | − f(x); return -- results discarded | |
| 1320 | − return x or f(x) -- results adjusted to 1 | |
| 1242 | + chunk ::= {stat } | |
| 1243 | +</pre><p> | |
| 1244 | +Lua has <em>empty statements</em> | |
| 1245 | +that allow you to separate statements with semicolons, | |
| 1246 | +start a chunk with a semicolon | |
| 1247 | +or write two semicolons in sequence: | |
| 1248 | + | |
| 1249 | +<pre> | |
| 1250 | + stat ::= &lsquo<b>;</b>’ | |
| 1321 | 1251 | </pre> |
| 1322 | 1252 | |
| 1253 | +<p> | |
| 1254 | +Lua handles a chunk as the body of an anonymous function | |
| 1255 | +with a variable number of arguments | |
| 1256 | +(see <a href="#3.4.10">§3.4.10</a>). | |
| 1257 | +As such, chunks can define local variables, | |
| 1258 | +receive arguments, and return values. | |
| 1259 | +Moreover, such anonymous function is compiled as in the | |
| 1260 | +scope of an external local variable called <code>_ENV</code> (see <a href="#2.2">§2.2</a>). | |
| 1323 | 1261 | |
| 1324 | 1262 | |
| 1263 | +<p> | |
| 1264 | +A chunk can be stored in a file or in a string inside the host program. | |
| 1265 | +To execute a chunk, | |
| 1266 | +Lua first pre-compiles the chunk into instructions for a virtual machine, | |
| 1267 | +and then it executes the compiled code | |
| 1268 | +with an interpreter for the virtual machine. | |
| 1325 | 1269 | |
| 1326 | −<h3>2.5.9 - <a name="2.5.9">Function Definitions</a></h3> | |
| 1327 | 1270 | |
| 1328 | 1271 | <p> |
| 1329 | −The syntax for function definition is | |
| 1272 | +Chunks can also be pre-compiled into binary form; | |
| 1273 | +see program <code>luac</code> for details. | |
| 1274 | +Programs in source and compiled forms are interchangeable; | |
| 1275 | +Lua automatically detects the file type and acts accordingly. | |
| 1276 | + | |
| 1277 | + | |
| 1278 | + | |
| 1279 | + | |
| 1280 | + | |
| 1281 | + | |
| 1282 | +<h3>3.3.2 - <a name="3.3.2">Blocks</a></h3><p> | |
| 1283 | +A block is a list of statements; | |
| 1284 | +syntactically, a block is the same as a chunk: | |
| 1330 | 1285 | |
| 1331 | 1286 | <pre> |
| 1332 | − function ::= <b>function</b> funcbody | |
| 1333 | − funcbody ::= `<b>(</b>´ [parlist] `<b>)</b>´ block <b>end</b> | |
| 1287 | + block ::= chunk | |
| 1334 | 1288 | </pre> |
| 1335 | 1289 | |
| 1336 | 1290 | <p> |
| 1337 | −The following syntactic sugar simplifies function definitions: | |
| 1291 | +A block can be explicitly delimited to produce a single statement: | |
| 1338 | 1292 | |
| 1339 | 1293 | <pre> |
| 1340 | − stat ::= <b>function</b> funcname funcbody | |
| 1341 | − stat ::= <b>local</b> <b>function</b> Name funcbody | |
| 1342 | − funcname ::= Name {`<b>.</b>´ Name} [`<b>:</b>´ Name] | |
| 1294 | + stat ::= <b>do</b> block <b>end</b> | |
| 1343 | 1295 | </pre><p> |
| 1344 | −The statement | |
| 1296 | +Explicit blocks are useful | |
| 1297 | +to control the scope of variable declarations. | |
| 1298 | +Explicit blocks are also sometimes used to | |
| 1299 | +add a <b>return</b> or <b>break</b> statement in the middle | |
| 1300 | +of another block (see <a href="#3.3.4">§3.3.4</a>). | |
| 1345 | 1301 | |
| 1346 | −<pre> | |
| 1347 | − function f () <em>body</em> end | |
| 1348 | −</pre><p> | |
| 1349 | −translates to | |
| 1350 | 1302 | |
| 1351 | −<pre> | |
| 1352 | − f = function () <em>body</em> end | |
| 1353 | −</pre><p> | |
| 1354 | −The statement | |
| 1355 | 1303 | |
| 1356 | −<pre> | |
| 1357 | − function t.a.b.c.f () <em>body</em> end | |
| 1358 | −</pre><p> | |
| 1359 | −translates to | |
| 1304 | + | |
| 1305 | + | |
| 1306 | +<h3>3.3.3 - <a name="3.3.3">Assignment</a></h3> | |
| 1307 | + | |
| 1308 | +<p> | |
| 1309 | +Lua allows multiple assignments. | |
| 1310 | +Therefore, the syntax for assignment | |
| 1311 | +defines a list of variables on the left side | |
| 1312 | +and a list of expressions on the right side. | |
| 1313 | +The elements in both lists are separated by commas: | |
| 1360 | 1314 | |
| 1361 | 1315 | <pre> |
| 1362 | − t.a.b.c.f = function () <em>body</em> end | |
| 1316 | + stat ::= varlist &lsquo<b>=</b>’ explist | |
| 1317 | + varlist ::= var {&lsquo<b>,</b>’ var} | |
| 1318 | + explist ::= exp {&lsquo<b>,</b>’ exp} | |
| 1363 | 1319 | </pre><p> |
| 1364 | −The statement | |
| 1320 | +Expressions are discussed in <a href="#3.4">§3.4</a>. | |
| 1321 | + | |
| 1322 | + | |
| 1323 | +<p> | |
| 1324 | +Before the assignment, | |
| 1325 | +the list of values is <em>adjusted</em> to the length of | |
| 1326 | +the list of variables. | |
| 1327 | +If there are more values than needed, | |
| 1328 | +the excess values are thrown away. | |
| 1329 | +If there are fewer values than needed, | |
| 1330 | +the list is extended with as many <b>nil</b>'s as needed. | |
| 1331 | +If the list of expressions ends with a function call, | |
| 1332 | +then all values returned by that call enter the list of values, | |
| 1333 | +before the adjustment | |
| 1334 | +(except when the call is enclosed in parentheses; see <a href="#3.4">§3.4</a>). | |
| 1335 | + | |
| 1336 | + | |
| 1337 | +<p> | |
| 1338 | +The assignment statement first evaluates all its expressions | |
| 1339 | +and only then are the assignments performed. | |
| 1340 | +Thus the code | |
| 1365 | 1341 | |
| 1366 | 1342 | <pre> |
| 1367 | − local function f () <em>body</em> end | |
| 1343 | + i = 3 | |
| 1344 | + i, a[i] = i+1, 20 | |
| 1368 | 1345 | </pre><p> |
| 1369 | −translates to | |
| 1346 | +sets <code>a[3]</code> to 20, without affecting <code>a[4]</code> | |
| 1347 | +because the <code>i</code> in <code>a[i]</code> is evaluated (to 3) | |
| 1348 | +before it is assigned 4. | |
| 1349 | +Similarly, the line | |
| 1370 | 1350 | |
| 1371 | 1351 | <pre> |
| 1372 | − local f; f = function () <em>body</em> end | |
| 1352 | + x, y = y, x | |
| 1373 | 1353 | </pre><p> |
| 1374 | −<em>not</em> to | |
| 1354 | +exchanges the values of <code>x</code> and <code>y</code>, | |
| 1355 | +and | |
| 1375 | 1356 | |
| 1376 | 1357 | <pre> |
| 1377 | − local f = function () <em>body</em> end | |
| 1358 | + x, y, z = y, z, x | |
| 1378 | 1359 | </pre><p> |
| 1379 | −(This only makes a difference when the body of the function | |
| 1380 | −contains references to <code>f</code>.) | |
| 1360 | +cyclically permutes the values of <code>x</code>, <code>y</code>, and <code>z</code>. | |
| 1381 | 1361 | |
| 1382 | 1362 | |
| 1383 | 1363 | <p> |
| 1384 | −A function definition is an executable expression, | |
| 1385 | −whose value has type <em>function</em>. | |
| 1386 | −When Lua pre-compiles a chunk, | |
| 1387 | −all its function bodies are pre-compiled too. | |
| 1388 | −Then, whenever Lua executes the function definition, | |
| 1389 | −the function is <em>instantiated</em> (or <em>closed</em>). | |
| 1390 | −This function instance (or <em>closure</em>) | |
| 1391 | −is the final value of the expression. | |
| 1392 | −Different instances of the same function | |
| 1393 | −can refer to different external local variables | |
| 1394 | −and can have different environment tables. | |
| 1364 | +The meaning of assignments to global variables | |
| 1365 | +and table fields can be changed via metatables. | |
| 1366 | +An assignment to an indexed variable <code>t[i] = val</code> is equivalent to | |
| 1367 | +<code>settable_event(t,i,val)</code>. | |
| 1368 | +(See <a href="#2.4">§2.4</a> for a complete description of the | |
| 1369 | +<code>settable_event</code> function. | |
| 1370 | +This function is not defined or callable in Lua. | |
| 1371 | +We use it here only for explanatory purposes.) | |
| 1395 | 1372 | |
| 1396 | 1373 | |
| 1397 | 1374 | <p> |
| 1398 | −Parameters act as local variables that are | |
| 1399 | −initialized with the argument values: | |
| 1375 | +An assignment to a global variable <code>x = val</code> | |
| 1376 | +is equivalent to the assignment | |
| 1377 | +<code>_ENV.x = val</code> (see <a href="#2.2">§2.2</a>). | |
| 1400 | 1378 | |
| 1401 | −<pre> | |
| 1402 | − parlist ::= namelist [`<b>,</b>´ `<b>...</b>´] | `<b>...</b>´ | |
| 1403 | −</pre><p> | |
| 1404 | −When a function is called, | |
| 1405 | −the list of arguments is adjusted to | |
| 1406 | −the length of the list of parameters, | |
| 1407 | −unless the function is a variadic or <em>vararg function</em>, | |
| 1408 | −which is | |
| 1409 | −indicated by three dots ('<code>...</code>') at the end of its parameter list. | |
| 1410 | −A vararg function does not adjust its argument list; | |
| 1411 | −instead, it collects all extra arguments and supplies them | |
| 1412 | −to the function through a <em>vararg expression</em>, | |
| 1413 | −which is also written as three dots. | |
| 1414 | −The value of this expression is a list of all actual extra arguments, | |
| 1415 | −similar to a function with multiple results. | |
| 1416 | −If a vararg expression is used inside another expression | |
| 1417 | −or in the middle of a list of expressions, | |
| 1418 | −then its return list is adjusted to one element. | |
| 1419 | −If the expression is used as the last element of a list of expressions, | |
| 1420 | −then no adjustment is made | |
| 1421 | −(unless that last expression is enclosed in parentheses). | |
| 1422 | 1379 | |
| 1423 | 1380 | |
| 1424 | −<p> | |
| 1425 | −As an example, consider the following definitions: | |
| 1426 | 1381 | |
| 1427 | −<pre> | |
| 1428 | − function f(a, b) end | |
| 1429 | − function g(a, b, ...) end | |
| 1430 | − function r() return 1,2,3 end | |
| 1431 | −</pre><p> | |
| 1432 | −Then, we have the following mapping from arguments to parameters and | |
| 1433 | −to the vararg expression: | |
| 1434 | 1382 | |
| 1435 | −<pre> | |
| 1436 | − CALL PARAMETERS | |
| 1437 | − | |
| 1438 | − f(3) a=3, b=nil | |
| 1439 | − f(3, 4) a=3, b=4 | |
| 1440 | − f(3, 4, 5) a=3, b=4 | |
| 1441 | − f(r(), 10) a=1, b=10 | |
| 1442 | − f(r()) a=1, b=2 | |
| 1443 | − | |
| 1444 | − g(3) a=3, b=nil, ... --> (nothing) | |
| 1445 | − g(3, 4) a=3, b=4, ... --> (nothing) | |
| 1446 | − g(3, 4, 5, 8) a=3, b=4, ... --> 5 8 | |
| 1447 | − g(5, r()) a=5, b=1, ... --> 2 3 | |
| 1448 | −</pre> | |
| 1383 | +<h3>3.3.4 - <a name="3.3.4">Control Structures</a></h3><p> | |
| 1384 | +The control structures | |
| 1385 | +<b>if</b>, <b>while</b>, and <b>repeat</b> have the usual meaning and | |
| 1386 | +familiar syntax: | |
| 1449 | 1387 | |
| 1450 | −<p> | |
| 1451 | −Results are returned using the <b>return</b> statement (see <a href="#2.4.4">§2.4.4</a>). | |
| 1452 | −If control reaches the end of a function | |
| 1453 | −without encountering a <b>return</b> statement, | |
| 1454 | −then the function returns with no results. | |
| 1455 | 1388 | |
| 1456 | 1389 | |
| 1457 | −<p> | |
| 1458 | −The <em>colon</em> syntax | |
| 1459 | −is used for defining <em>methods</em>, | |
| 1460 | −that is, functions that have an implicit extra parameter <code>self</code>. | |
| 1461 | −Thus, the statement | |
| 1462 | 1390 | |
| 1463 | 1391 | <pre> |
| 1464 | − function t.a.b.c:f (<em>params</em>) <em>body</em> end | |
| 1392 | + stat ::= <b>while</b> exp <b>do</b> block <b>end</b> | |
| 1393 | + stat ::= <b>repeat</b> block <b>until</b> exp | |
| 1394 | + stat ::= <b>if</b> exp <b>then</b> block {<b>elseif</b> exp <b>then</b> block} [<b>else</b> block] <b>end</b> | |
| 1465 | 1395 | </pre><p> |
| 1466 | −is syntactic sugar for | |
| 1467 | − | |
| 1468 | −<pre> | |
| 1469 | − t.a.b.c.f = function (self, <em>params</em>) <em>body</em> end | |
| 1470 | −</pre> | |
| 1471 | − | |
| 1396 | +Lua also has a <b>for</b> statement, in two flavors (see <a href="#3.3.5">§3.3.5</a>). | |
| 1472 | 1397 | |
| 1473 | 1398 | |
| 1399 | +<p> | |
| 1400 | +The condition expression of a | |
| 1401 | +control structure can return any value. | |
| 1402 | +Both <b>false</b> and <b>nil</b> are considered false. | |
| 1403 | +All values different from <b>nil</b> and <b>false</b> are considered true | |
| 1404 | +(in particular, the number 0 and the empty string are also true). | |
| 1474 | 1405 | |
| 1475 | 1406 | |
| 1407 | +<p> | |
| 1408 | +In the <b>repeat</b>–<b>until</b> loop, | |
| 1409 | +the inner block does not end at the <b>until</b> keyword, | |
| 1410 | +but only after the condition. | |
| 1411 | +So, the condition can refer to local variables | |
| 1412 | +declared inside the loop block. | |
| 1476 | 1413 | |
| 1477 | −<h2>2.6 - <a name="2.6">Visibility Rules</a></h2> | |
| 1478 | 1414 | |
| 1479 | 1415 | <p> |
| 1416 | +The <b>return</b> statement is used to return values | |
| 1417 | +from a function or a chunk (which is just a function). | |
| 1480 | 1418 | |
| 1481 | −Lua is a lexically scoped language. | |
| 1482 | −The scope of variables begins at the first statement <em>after</em> | |
| 1483 | −their declaration and lasts until the end of the innermost block that | |
| 1484 | −includes the declaration. | |
| 1485 | −Consider the following example: | |
| 1419 | +Functions and chunks can return more than one value, | |
| 1420 | +and so the syntax for the <b>return</b> statement is | |
| 1486 | 1421 | |
| 1487 | 1422 | <pre> |
| 1488 | − x = 10 -- global variable | |
| 1489 | − do -- new block | |
| 1490 | − local x = x -- new 'x', with value 10 | |
| 1491 | − print(x) --> 10 | |
| 1492 | − x = x+1 | |
| 1493 | − do -- another block | |
| 1494 | − local x = x+1 -- another 'x' | |
| 1495 | − print(x) --> 12 | |
| 1496 | − end | |
| 1497 | − print(x) --> 11 | |
| 1498 | − end | |
| 1499 | − print(x) --> 10 (the global one) | |
| 1423 | + stat ::= <b>return</b> [explist] [&lsquo<b>;</b>’] | |
| 1500 | 1424 | </pre> |
| 1501 | 1425 | |
| 1502 | 1426 | <p> |
| 1503 | −Notice that, in a declaration like <code>local x = x</code>, | |
| 1504 | −the new <code>x</code> being declared is not in scope yet, | |
| 1505 | −and so the second <code>x</code> refers to the outside variable. | |
| 1506 | − | |
| 1507 | − | |
| 1508 | −<p> | |
| 1509 | −Because of the lexical scoping rules, | |
| 1510 | −local variables can be freely accessed by functions | |
| 1511 | −defined inside their scope. | |
| 1512 | −A local variable used by an inner function is called | |
| 1513 | −an <em>upvalue</em>, or <em>external local variable</em>, | |
| 1514 | −inside the inner function. | |
| 1515 | − | |
| 1427 | +The <b>break</b> statement is used to terminate the execution of a | |
| 1428 | +<b>while</b>, <b>repeat</b>, or <b>for</b> loop, | |
| 1429 | +skipping to the next statement after the loop: | |
| 1516 | 1430 | |
| 1517 | −<p> | |
| 1518 | −Notice that each execution of a <b>local</b> statement | |
| 1519 | −defines new local variables. | |
| 1520 | −Consider the following example: | |
| 1521 | 1431 | |
| 1522 | 1432 | <pre> |
| 1523 | − a = {} | |
| 1524 | − local x = 20 | |
| 1525 | − for i=1,10 do | |
| 1526 | − local y = 0 | |
| 1527 | − a[i] = function () y=y+1; return x+y end | |
| 1528 | − end | |
| 1433 | + stat ::= <b>break</b> [&lsquo<b>;</b>’] | |
| 1529 | 1434 | </pre><p> |
| 1530 | −The loop creates ten closures | |
| 1531 | −(that is, ten instances of the anonymous function). | |
| 1532 | −Each of these closures uses a different <code>y</code> variable, | |
| 1533 | −while all of them share the same <code>x</code>. | |
| 1534 | − | |
| 1535 | − | |
| 1536 | − | |
| 1537 | − | |
| 1538 | − | |
| 1539 | −<h2>2.7 - <a name="2.7">Error Handling</a></h2> | |
| 1540 | − | |
| 1541 | −<p> | |
| 1542 | −Because Lua is an embedded extension language, | |
| 1543 | −all Lua actions start from C code in the host program | |
| 1544 | −calling a function from the Lua library (see <a href="#lua_pcall"><code>lua_pcall</code></a>). | |
| 1545 | −Whenever an error occurs during Lua compilation or execution, | |
| 1546 | −control returns to C, | |
| 1547 | −which can take appropriate measures | |
| 1548 | −(such as printing an error message). | |
| 1435 | +A <b>break</b> ends the innermost enclosing loop. | |
| 1549 | 1436 | |
| 1550 | 1437 | |
| 1551 | 1438 | <p> |
| 1552 | −Lua code can explicitly generate an error by calling the | |
| 1553 | −<a href="#pdf-error"><code>error</code></a> function. | |
| 1554 | −If you need to catch errors in Lua, | |
| 1555 | −you can use the <a href="#pdf-pcall"><code>pcall</code></a> function. | |
| 1439 | +The <b>return</b> and <b>break</b> | |
| 1440 | +statements can only be written as the <em>last</em> statement of a block. | |
| 1441 | +If it is really necessary to <b>return</b> or <b>break</b> in the | |
| 1442 | +middle of a block, | |
| 1443 | +then an explicit inner block can be used, | |
| 1444 | +as in the idioms | |
| 1445 | +<code>do return end</code> and <code>do break end</code>, | |
| 1446 | +because now <b>return</b> and <b>break</b> are the last statements in | |
| 1447 | +their (inner) blocks. | |
| 1556 | 1448 | |
| 1557 | 1449 | |
| 1558 | 1450 | |
| 1559 | 1451 | |
| 1560 | 1452 | |
| 1561 | −<h2>2.8 - <a name="2.8">Metatables</a></h2> | |
| 1453 | +<h3>3.3.5 - <a name="3.3.5">For Statement</a></h3> | |
| 1562 | 1454 | |
| 1563 | 1455 | <p> |
| 1564 | −Every value in Lua can have a <em>metatable</em>. | |
| 1565 | −This <em>metatable</em> is an ordinary Lua table | |
| 1566 | −that defines the behavior of the original value | |
| 1567 | −under certain special operations. | |
| 1568 | −You can change several aspects of the behavior | |
| 1569 | −of operations over a value by setting specific fields in its metatable. | |
| 1570 | −For instance, when a non-numeric value is the operand of an addition, | |
| 1571 | −Lua checks for a function in the field <code>"__add"</code> in its metatable. | |
| 1572 | −If it finds one, | |
| 1573 | −Lua calls this function to perform the addition. | |
| 1574 | 1456 | |
| 1575 | − | |
| 1576 | −<p> | |
| 1577 | −We call the keys in a metatable <em>events</em> | |
| 1578 | −and the values <em>metamethods</em>. | |
| 1579 | −In the previous example, the event is <code>"add"</code> | |
| 1580 | −and the metamethod is the function that performs the addition. | |
| 1457 | +The <b>for</b> statement has two forms: | |
| 1458 | +one numeric and one generic. | |
| 1581 | 1459 | |
| 1582 | 1460 | |
| 1583 | 1461 | <p> |
| 1584 | −You can query the metatable of any value | |
| 1585 | −through the <a href="#pdf-getmetatable"><code>getmetatable</code></a> function. | |
| 1462 | +The numeric <b>for</b> loop repeats a block of code while a | |
| 1463 | +control variable runs through an arithmetic progression. | |
| 1464 | +It has the following syntax: | |
| 1586 | 1465 | |
| 1466 | +<pre> | |
| 1467 | + stat ::= <b>for</b> Name &lsquo<b>=</b>’ exp &lsquo<b>,</b>’ exp [&lsquo<b>,</b>’ exp] <b>do</b> block <b>end</b> | |
| 1468 | +</pre><p> | |
| 1469 | +The <em>block</em> is repeated for <em>name</em> starting at the value of | |
| 1470 | +the first <em>exp</em>, until it passes the second <em>exp</em> by steps of the | |
| 1471 | +third <em>exp</em>. | |
| 1472 | +More precisely, a <b>for</b> statement like | |
| 1587 | 1473 | |
| 1588 | −<p> | |
| 1589 | −You can replace the metatable of tables | |
| 1590 | −through the <a href="#pdf-setmetatable"><code>setmetatable</code></a> | |
| 1591 | −function. | |
| 1592 | −You cannot change the metatable of other types from Lua | |
| 1593 | −(except by using the debug library); | |
| 1594 | −you must use the C API for that. | |
| 1474 | +<pre> | |
| 1475 | + for v = <em>e1</em>, <em>e2</em>, <em>e3</em> do <em>block</em> end | |
| 1476 | +</pre><p> | |
| 1477 | +is equivalent to the code: | |
| 1478 | + | |
| 1479 | +<pre> | |
| 1480 | + do | |
| 1481 | + local <em>var</em>, <em>limit</em>, <em>step</em> = tonumber(<em>e1</em>), tonumber(<em>e2</em>), tonumber(<em>e3</em>) | |
| 1482 | + if not (<em>var</em> and <em>limit</em> and <em>step</em>) then error() end | |
| 1483 | + while (<em>step</em> > 0 and <em>var</em> <= <em>limit</em>) or (<em>step</em> <= 0 and <em>var</em> >= <em>limit</em>) do | |
| 1484 | + local v = <em>var</em> | |
| 1485 | + <em>block</em> | |
| 1486 | + <em>var</em> = <em>var</em> + <em>step</em> | |
| 1487 | + end | |
| 1488 | + end | |
| 1489 | +</pre><p> | |
| 1490 | +Note the following: | |
| 1595 | 1491 | |
| 1492 | +<ul> | |
| 1596 | 1493 | |
| 1597 | −<p> | |
| 1598 | −Tables and full userdata have individual metatables | |
| 1599 | −(although multiple tables and userdata can share their metatables). | |
| 1600 | −Values of all other types share one single metatable per type; | |
| 1601 | −that is, there is one single metatable for all numbers, | |
| 1602 | −one for all strings, etc. | |
| 1603 | −By default, a value has no metatable, | |
| 1604 | −but the string library sets a metatable for the string type (see <a href="#5.4">§5.4</a>). | |
| 1494 | +<li> | |
| 1495 | +All three control expressions are evaluated only once, | |
| 1496 | +before the loop starts. | |
| 1497 | +They must all result in numbers. | |
| 1498 | +</li> | |
| 1605 | 1499 | |
| 1500 | +<li> | |
| 1501 | +<code><em>var</em></code>, <code><em>limit</em></code>, and <code><em>step</em></code> are invisible variables. | |
| 1502 | +The names shown here are for explanatory purposes only. | |
| 1503 | +</li> | |
| 1606 | 1504 | |
| 1607 | −<p> | |
| 1608 | −A metatable controls how an object behaves in arithmetic operations, | |
| 1609 | −order comparisons, concatenation, length operation, and indexing. | |
| 1610 | −A metatable also can define a function to be called when a userdata | |
| 1611 | −is garbage collected. | |
| 1612 | −For each of these operations Lua associates a specific key | |
| 1613 | −called an <em>event</em>. | |
| 1614 | −When Lua performs one of these operations over a value, | |
| 1615 | −it checks whether this value has a metatable with the corresponding event. | |
| 1616 | −If so, the value associated with that key (the metamethod) | |
| 1617 | −controls how Lua will perform the operation. | |
| 1505 | +<li> | |
| 1506 | +If the third expression (the step) is absent, | |
| 1507 | +then a step of 1 is used. | |
| 1508 | +</li> | |
| 1618 | 1509 | |
| 1510 | +<li> | |
| 1511 | +You can use <b>break</b> to exit a <b>for</b> loop. | |
| 1512 | +</li> | |
| 1619 | 1513 | |
| 1620 | −<p> | |
| 1621 | −Metatables control the operations listed next. | |
| 1622 | −Each operation is identified by its corresponding name. | |
| 1623 | −The key for each operation is a string with its name prefixed by | |
| 1624 | −two underscores, '<code>__</code>'; | |
| 1625 | −for instance, the key for operation "add" is the | |
| 1626 | −string <code>"__add"</code>. | |
| 1627 | −The semantics of these operations is better explained by a Lua function | |
| 1628 | −describing how the interpreter executes the operation. | |
| 1514 | +<li> | |
| 1515 | +The loop variable <code>v</code> is local to the loop; | |
| 1516 | +you cannot use its value after the <b>for</b> ends or is broken. | |
| 1517 | +If you need this value, | |
| 1518 | +assign it to another variable before breaking or exiting the loop. | |
| 1519 | +</li> | |
| 1629 | 1520 | |
| 1521 | +</ul> | |
| 1630 | 1522 | |
| 1631 | 1523 | <p> |
| 1632 | −The code shown here in Lua is only illustrative; | |
| 1633 | −the real behavior is hard coded in the interpreter | |
| 1634 | −and it is much more efficient than this simulation. | |
| 1635 | −All functions used in these descriptions | |
| 1636 | −(<a href="#pdf-rawget"><code>rawget</code></a>, <a href="#pdf-tonumber"><code>tonumber</code></a>, etc.) | |
| 1637 | −are described in <a href="#5.1">§5.1</a>. | |
| 1638 | −In particular, to retrieve the metamethod of a given object, | |
| 1639 | −we use the expression | |
| 1524 | +The generic <b>for</b> statement works over functions, | |
| 1525 | +called <em>iterators</em>. | |
| 1526 | +On each iteration, the iterator function is called to produce a new value, | |
| 1527 | +stopping when this new value is <b>nil</b>. | |
| 1528 | +The generic <b>for</b> loop has the following syntax: | |
| 1640 | 1529 | |
| 1641 | 1530 | <pre> |
| 1642 | − metatable(obj)[event] | |
| 1531 | + stat ::= <b>for</b> namelist <b>in</b> explist <b>do</b> block <b>end</b> | |
| 1532 | + namelist ::= Name {&lsquo<b>,</b>’ Name} | |
| 1643 | 1533 | </pre><p> |
| 1644 | −This should be read as | |
| 1534 | +A <b>for</b> statement like | |
| 1645 | 1535 | |
| 1646 | 1536 | <pre> |
| 1647 | − rawget(getmetatable(obj) or {}, event) | |
| 1537 | + for <em>var_1</em>, ···, <em>var_n</em> in <em>explist</em> do <em>block</em> end | |
| 1648 | 1538 | </pre><p> |
| 1539 | +is equivalent to the code: | |
| 1649 | 1540 | |
| 1650 | −That is, the access to a metamethod does not invoke other metamethods, | |
| 1651 | −and the access to objects with no metatables does not fail | |
| 1652 | −(it simply results in <b>nil</b>). | |
| 1653 | − | |
| 1654 | − | |
| 1541 | +<pre> | |
| 1542 | + do | |
| 1543 | + local <em>f</em>, <em>s</em>, <em>var</em> = <em>explist</em> | |
| 1544 | + while true do | |
| 1545 | + local <em>var_1</em>, ···, <em>var_n</em> = <em>f</em>(<em>s</em>, <em>var</em>) | |
| 1546 | + <em>var</em> = <em>var_1</em> | |
| 1547 | + if <em>var</em> == nil then break end | |
| 1548 | + <em>block</em> | |
| 1549 | + end | |
| 1550 | + end | |
| 1551 | +</pre><p> | |
| 1552 | +Note the following: | |
| 1655 | 1553 | |
| 1656 | 1554 | <ul> |
| 1657 | 1555 | |
| 1658 | −<li><b>"add":</b> | |
| 1659 | −the <code>+</code> operation. | |
| 1556 | +<li> | |
| 1557 | +<code><em>explist</em></code> is evaluated only once. | |
| 1558 | +Its results are an <em>iterator</em> function, | |
| 1559 | +a <em>state</em>, | |
| 1560 | +and an initial value for the first <em>iterator variable</em>. | |
| 1561 | +</li> | |
| 1660 | 1562 | |
| 1563 | +<li> | |
| 1564 | +<code><em>f</em></code>, <code><em>s</em></code>, and <code><em>var</em></code> are invisible variables. | |
| 1565 | +The names are here for explanatory purposes only. | |
| 1566 | +</li> | |
| 1567 | + | |
| 1568 | +<li> | |
| 1569 | +You can use <b>break</b> to exit a <b>for</b> loop. | |
| 1570 | +</li> | |
| 1571 | + | |
| 1572 | +<li> | |
| 1573 | +The loop variables <code><em>var_i</em></code> are local to the loop; | |
| 1574 | +you cannot use their values after the <b>for</b> ends. | |
| 1575 | +If you need these values, | |
| 1576 | +then assign them to other variables before breaking or exiting the loop. | |
| 1577 | +</li> | |
| 1578 | + | |
| 1579 | +</ul> | |
| 1661 | 1580 | |
| 1662 | 1581 | |
| 1663 | −<p> | |
| 1664 | −The function <code>getbinhandler</code> below defines how Lua chooses a handler | |
| 1665 | −for a binary operation. | |
| 1666 | −First, Lua tries the first operand. | |
| 1667 | −If its type does not define a handler for the operation, | |
| 1668 | −then Lua tries the second operand. | |
| 1582 | + | |
| 1583 | + | |
| 1584 | +<h3>3.3.6 - <a name="3.3.6">Function Calls as Statements</a></h3><p> | |
| 1585 | +To allow possible side-effects, | |
| 1586 | +function calls can be executed as statements: | |
| 1669 | 1587 | |
| 1670 | 1588 | <pre> |
| 1671 | − function getbinhandler (op1, op2, event) | |
| 1672 | − return metatable(op1)[event] or metatable(op2)[event] | |
| 1673 | − end | |
| 1589 | + stat ::= functioncall | |
| 1674 | 1590 | </pre><p> |
| 1675 | −By using this function, | |
| 1676 | −the behavior of the <code>op1 + op2</code> is | |
| 1591 | +In this case, all returned values are thrown away. | |
| 1592 | +Function calls are explained in <a href="#3.4.9">§3.4.9</a>. | |
| 1593 | + | |
| 1594 | + | |
| 1595 | + | |
| 1596 | + | |
| 1597 | + | |
| 1598 | +<h3>3.3.7 - <a name="3.3.7">Local Declarations</a></h3><p> | |
| 1599 | +Local variables can be declared anywhere inside a block. | |
| 1600 | +The declaration can include an initial assignment: | |
| 1677 | 1601 | |
| 1678 | 1602 | <pre> |
| 1679 | − function add_event (op1, op2) | |
| 1680 | − local o1, o2 = tonumber(op1), tonumber(op2) | |
| 1681 | − if o1 and o2 then -- both operands are numeric? | |
| 1682 | − return o1 + o2 -- '+' here is the primitive 'add' | |
| 1683 | − else -- at least one of the operands is not numeric | |
| 1684 | − local h = getbinhandler(op1, op2, "__add") | |
| 1685 | − if h then | |
| 1686 | − -- call the handler with both operands | |
| 1687 | − return (h(op1, op2)) | |
| 1688 | − else -- no handler available: default behavior | |
| 1689 | − error(···) | |
| 1690 | − end | |
| 1691 | − end | |
| 1692 | − end | |
| 1603 | + stat ::= <b>local</b> namelist [&lsquo<b>=</b>’ explist] | |
| 1693 | 1604 | </pre><p> |
| 1694 | −</li> | |
| 1605 | +If present, an initial assignment has the same semantics | |
| 1606 | +of a multiple assignment (see <a href="#3.3.3">§3.3.3</a>). | |
| 1607 | +Otherwise, all variables are initialized with <b>nil</b>. | |
| 1695 | 1608 | |
| 1696 | −<li><b>"sub":</b> | |
| 1697 | −the <code>-</code> operation. | |
| 1698 | 1609 | |
| 1699 | −Behavior similar to the "add" operation. | |
| 1700 | −</li> | |
| 1610 | +<p> | |
| 1611 | +A chunk is also a block (see <a href="#3.3.1">§3.3.1</a>), | |
| 1612 | +and so local variables can be declared in a chunk outside any explicit block. | |
| 1613 | +The scope of such local variables extends until the end of the chunk. | |
| 1701 | 1614 | |
| 1702 | −<li><b>"mul":</b> | |
| 1703 | −the <code>*</code> operation. | |
| 1704 | 1615 | |
| 1705 | −Behavior similar to the "add" operation. | |
| 1706 | −</li> | |
| 1616 | +<p> | |
| 1617 | +The visibility rules for local variables are explained in <a href="#3.5">§3.5</a>. | |
| 1707 | 1618 | |
| 1708 | −<li><b>"div":</b> | |
| 1709 | −the <code>/</code> operation. | |
| 1710 | 1619 | |
| 1711 | −Behavior similar to the "add" operation. | |
| 1712 | −</li> | |
| 1713 | 1620 | |
| 1714 | −<li><b>"mod":</b> | |
| 1715 | −the <code>%</code> operation. | |
| 1716 | 1621 | |
| 1717 | −Behavior similar to the "add" operation, | |
| 1718 | −with the operation | |
| 1719 | −<code>o1 - floor(o1/o2)*o2</code> as the primitive operation. | |
| 1720 | −</li> | |
| 1721 | 1622 | |
| 1722 | −<li><b>"pow":</b> | |
| 1723 | −the <code>^</code> (exponentiation) operation. | |
| 1724 | 1623 | |
| 1725 | −Behavior similar to the "add" operation, | |
| 1726 | −with the function <code>pow</code> (from the C math library) | |
| 1727 | −as the primitive operation. | |
| 1728 | −</li> | |
| 1729 | 1624 | |
| 1730 | −<li><b>"unm":</b> | |
| 1731 | −the unary <code>-</code> operation. | |
| 1625 | +<h2>3.4 - <a name="3.4">Expressions</a></h2> | |
| 1732 | 1626 | |
| 1627 | +<p> | |
| 1628 | +The basic expressions in Lua are the following: | |
| 1733 | 1629 | |
| 1734 | 1630 | <pre> |
| 1735 | − function unm_event (op) | |
| 1736 | − local o = tonumber(op) | |
| 1737 | − if o then -- operand is numeric? | |
| 1738 | − return -o -- '-' here is the primitive 'unm' | |
| 1739 | − else -- the operand is not numeric. | |
| 1740 | − -- Try to get a handler from the operand | |
| 1741 | − local h = metatable(op).__unm | |
| 1742 | − if h then | |
| 1743 | − -- call the handler with the operand | |
| 1744 | − return (h(op)) | |
| 1745 | − else -- no handler available: default behavior | |
| 1746 | − error(···) | |
| 1747 | − end | |
| 1748 | − end | |
| 1749 | − end | |
| 1750 | −</pre><p> | |
| 1751 | −</li> | |
| 1631 | + exp ::= prefixexp | |
| 1632 | + exp ::= <b>nil</b> | <b>false</b> | <b>true</b> | |
| 1633 | + exp ::= Number | |
| 1634 | + exp ::= String | |
| 1635 | + exp ::= function | |
| 1636 | + exp ::= tableconstructor | |
| 1637 | + exp ::= &lsquo<b>...</b>’ | |
| 1638 | + exp ::= exp binop exp | |
| 1639 | + exp ::= unop exp | |
| 1640 | + prefixexp ::= var | functioncall | &lsquo<b>(</b>’ exp &lsquo<b>)</b>’ | |
| 1641 | +</pre> | |
| 1752 | 1642 | |
| 1753 | −<li><b>"concat":</b> | |
| 1754 | −the <code>..</code> (concatenation) operation. | |
| 1643 | +<p> | |
| 1644 | +Numbers and literal strings are explained in <a href="#3.1">§3.1</a>; | |
| 1645 | +variables are explained in <a href="#3.2">§3.2</a>; | |
| 1646 | +function definitions are explained in <a href="#3.4.10">§3.4.10</a>; | |
| 1647 | +function calls are explained in <a href="#3.4.9">§3.4.9</a>; | |
| 1648 | +table constructors are explained in <a href="#3.4.8">§3.4.8</a>. | |
| 1649 | +Vararg expressions, | |
| 1650 | +denoted by three dots ('<code>...</code>'), can only be used when | |
| 1651 | +directly inside a vararg function; | |
| 1652 | +they are explained in <a href="#3.4.10">§3.4.10</a>. | |
| 1755 | 1653 | |
| 1756 | 1654 | |
| 1757 | −<pre> | |
| 1758 | − function concat_event (op1, op2) | |
| 1759 | − if (type(op1) == "string" or type(op1) == "number") and | |
| 1760 | − (type(op2) == "string" or type(op2) == "number") then | |
| 1761 | − return op1 .. op2 -- primitive string concatenation | |
| 1762 | − else | |
| 1763 | − local h = getbinhandler(op1, op2, "__concat") | |
| 1764 | − if h then | |
| 1765 | − return (h(op1, op2)) | |
| 1766 | − else | |
| 1767 | − error(···) | |
| 1768 | − end | |
| 1769 | − end | |
| 1770 | − end | |
| 1771 | −</pre><p> | |
| 1772 | −</li> | |
| 1655 | +<p> | |
| 1656 | +Binary operators comprise arithmetic operators (see <a href="#3.4.1">§3.4.1</a>), | |
| 1657 | +relational operators (see <a href="#3.4.3">§3.4.3</a>), logical operators (see <a href="#3.4.4">§3.4.4</a>), | |
| 1658 | +and the concatenation operator (see <a href="#3.4.5">§3.4.5</a>). | |
| 1659 | +Unary operators comprise the unary minus (see <a href="#3.4.1">§3.4.1</a>), | |
| 1660 | +the unary <b>not</b> (see <a href="#3.4.4">§3.4.4</a>), | |
| 1661 | +and the unary <em>length operator</em> (see <a href="#3.4.6">§3.4.6</a>). | |
| 1662 | + | |
| 1663 | + | |
| 1664 | +<p> | |
| 1665 | +Both function calls and vararg expressions can result in multiple values. | |
| 1666 | +If an expression is used as a statement | |
| 1667 | +(only possible for function calls (see <a href="#3.3.6">§3.3.6</a>)), | |
| 1668 | +then its return list is adjusted to zero elements, | |
| 1669 | +thus discarding all returned values. | |
| 1670 | +If an expression is used as the last (or the only) element | |
| 1671 | +of a list of expressions, | |
| 1672 | +then no adjustment is made | |
| 1673 | +(unless the call is enclosed in parentheses). | |
| 1674 | +In all other contexts, | |
| 1675 | +Lua adjusts the result list to one element, | |
| 1676 | +discarding all values except the first one. | |
| 1773 | 1677 | |
| 1774 | −<li><b>"len":</b> | |
| 1775 | −the <code>#</code> operation. | |
| 1776 | 1678 | |
| 1679 | +<p> | |
| 1680 | +Here are some examples: | |
| 1777 | 1681 | |
| 1778 | 1682 | <pre> |
| 1779 | − function len_event (op) | |
| 1780 | − if type(op) == "string" then | |
| 1781 | − return strlen(op) -- primitive string length | |
| 1782 | − else | |
| 1783 | − local h = metatable(op).__len | |
| 1784 | − if h then | |
| 1785 | − return (h(op)) -- call handler with the operand | |
| 1786 | − elseif type(op) == "table" then | |
| 1787 | − return #op -- primitive table length | |
| 1788 | − else -- no handler available: error | |
| 1789 | − error(···) | |
| 1790 | − end | |
| 1791 | − end | |
| 1792 | − end | |
| 1793 | −</pre><p> | |
| 1794 | −See <a href="#2.5.5">§2.5.5</a> for a description of the length of a table. | |
| 1795 | −</li> | |
| 1683 | + f() -- adjusted to 0 results | |
| 1684 | + g(f(), x) -- f() is adjusted to 1 result | |
| 1685 | + g(x, f()) -- g gets x plus all results from f() | |
| 1686 | + a,b,c = f(), x -- f() is adjusted to 1 result (c gets nil) | |
| 1687 | + a,b = ... -- a gets the first vararg parameter, b gets | |
| 1688 | + -- the second (both a and b can get nil if there | |
| 1689 | + -- is no corresponding vararg parameter) | |
| 1690 | + | |
| 1691 | + a,b,c = x, f() -- f() is adjusted to 2 results | |
| 1692 | + a,b,c = f() -- f() is adjusted to 3 results | |
| 1693 | + return f() -- returns all results from f() | |
| 1694 | + return ... -- returns all received vararg parameters | |
| 1695 | + return x,y,f() -- returns x, y, and all results from f() | |
| 1696 | + {f()} -- creates a list with all results from f() | |
| 1697 | + {...} -- creates a list with all vararg parameters | |
| 1698 | + {f(), nil} -- f() is adjusted to 1 result | |
| 1699 | +</pre> | |
| 1796 | 1700 | |
| 1797 | −<li><b>"eq":</b> | |
| 1798 | −the <code>==</code> operation. | |
| 1701 | +<p> | |
| 1702 | +Any expression enclosed in parentheses always results in only one value. | |
| 1703 | +Thus, | |
| 1704 | +<code>(f(x,y,z))</code> is always a single value, | |
| 1705 | +even if <code>f</code> returns several values. | |
| 1706 | +(The value of <code>(f(x,y,z))</code> is the first value returned by <code>f</code> | |
| 1707 | +or <b>nil</b> if <code>f</code> does not return any values.) | |
| 1799 | 1708 | |
| 1800 | −The function <code>getcomphandler</code> defines how Lua chooses a metamethod | |
| 1801 | −for comparison operators. | |
| 1802 | −A metamethod only is selected when both objects | |
| 1803 | −being compared have the same type | |
| 1804 | −and the same metamethod for the selected operation. | |
| 1805 | 1709 | |
| 1806 | −<pre> | |
| 1807 | − function getcomphandler (op1, op2, event) | |
| 1808 | − if type(op1) ~= type(op2) then return nil end | |
| 1809 | − local mm1 = metatable(op1)[event] | |
| 1810 | − local mm2 = metatable(op2)[event] | |
| 1811 | − if mm1 == mm2 then return mm1 else return nil end | |
| 1812 | − end | |
| 1813 | −</pre><p> | |
| 1814 | −The "eq" event is defined as follows: | |
| 1710 | + | |
| 1711 | +<h3>3.4.1 - <a name="3.4.1">Arithmetic Operators</a></h3><p> | |
| 1712 | +Lua supports the usual arithmetic operators: | |
| 1713 | +the binary <code>+</code> (addition), | |
| 1714 | +<code>-</code> (subtraction), <code>*</code> (multiplication), | |
| 1715 | +<code>/</code> (division), <code>%</code> (modulo), and <code>^</code> (exponentiation); | |
| 1716 | +and unary <code>-</code> (negation). | |
| 1717 | +If the operands are numbers, or strings that can be converted to | |
| 1718 | +numbers (see <a href="#3.4.2">§3.4.2</a>), | |
| 1719 | +then all operations have the usual meaning. | |
| 1720 | +Exponentiation works for any exponent. | |
| 1721 | +For instance, <code>x^(-0.5)</code> computes the inverse of the square root of <code>x</code>. | |
| 1722 | +Modulo is defined as | |
| 1815 | 1723 | |
| 1816 | 1724 | <pre> |
| 1817 | − function eq_event (op1, op2) | |
| 1818 | − if type(op1) ~= type(op2) then -- different types? | |
| 1819 | − return false -- different objects | |
| 1820 | − end | |
| 1821 | − if op1 == op2 then -- primitive equal? | |
| 1822 | − return true -- objects are equal | |
| 1823 | − end | |
| 1824 | − -- try metamethod | |
| 1825 | − local h = getcomphandler(op1, op2, "__eq") | |
| 1826 | − if h then | |
| 1827 | − return (h(op1, op2)) | |
| 1828 | − else | |
| 1829 | − return false | |
| 1830 | − end | |
| 1831 | − end | |
| 1725 | + a % b == a - math.floor(a/b)*b | |
| 1832 | 1726 | </pre><p> |
| 1833 | −<code>a ~= b</code> is equivalent to <code>not (a == b)</code>. | |
| 1834 | −</li> | |
| 1727 | +That is, it is the remainder of a division that rounds | |
| 1728 | +the quotient towards minus infinity. | |
| 1835 | 1729 | |
| 1836 | −<li><b>"lt":</b> | |
| 1837 | −the <code><</code> operation. | |
| 1838 | 1730 | |
| 1839 | 1731 | |
| 1840 | −<pre> | |
| 1841 | − function lt_event (op1, op2) | |
| 1842 | − if type(op1) == "number" and type(op2) == "number" then | |
| 1843 | − return op1 < op2 -- numeric comparison | |
| 1844 | − elseif type(op1) == "string" and type(op2) == "string" then | |
| 1845 | − return op1 < op2 -- lexicographic comparison | |
| 1846 | − else | |
| 1847 | − local h = getcomphandler(op1, op2, "__lt") | |
| 1848 | − if h then | |
| 1849 | − return (h(op1, op2)) | |
| 1850 | − else | |
| 1851 | − error(···) | |
| 1852 | − end | |
| 1853 | − end | |
| 1854 | − end | |
| 1855 | −</pre><p> | |
| 1856 | −<code>a > b</code> is equivalent to <code>b < a</code>. | |
| 1857 | −</li> | |
| 1858 | 1732 | |
| 1859 | −<li><b>"le":</b> | |
| 1860 | −the <code><=</code> operation. | |
| 1733 | + | |
| 1734 | +<h3>3.4.2 - <a name="3.4.2">Coercion</a></h3> | |
| 1735 | + | |
| 1736 | +<p> | |
| 1737 | +Lua provides automatic conversion between | |
| 1738 | +string and number values at run time. | |
| 1739 | +Any arithmetic operation applied to a string tries to convert | |
| 1740 | +this string to a number, following the usual conversion rules. | |
| 1741 | +Conversely, whenever a number is used where a string is expected, | |
| 1742 | +the number is converted to a string, in a reasonable format. | |
| 1743 | +For complete control over how numbers are converted to strings, | |
| 1744 | +use the <code>format</code> function from the string library | |
| 1745 | +(see <a href="#pdf-string.format"><code>string.format</code></a>). | |
| 1861 | 1746 | |
| 1862 | 1747 | |
| 1863 | −<pre> | |
| 1864 | − function le_event (op1, op2) | |
| 1865 | − if type(op1) == "number" and type(op2) == "number" then | |
| 1866 | − return op1 <= op2 -- numeric comparison | |
| 1867 | − elseif type(op1) == "string" and type(op2) == "string" then | |
| 1868 | − return op1 <= op2 -- lexicographic comparison | |
| 1869 | − else | |
| 1870 | − local h = getcomphandler(op1, op2, "__le") | |
| 1871 | − if h then | |
| 1872 | − return (h(op1, op2)) | |
| 1873 | − else | |
| 1874 | − h = getcomphandler(op1, op2, "__lt") | |
| 1875 | − if h then | |
| 1876 | − return not h(op2, op1) | |
| 1877 | − else | |
| 1878 | − error(···) | |
| 1879 | − end | |
| 1880 | − end | |
| 1881 | − end | |
| 1882 | − end | |
| 1883 | −</pre><p> | |
| 1884 | −<code>a >= b</code> is equivalent to <code>b <= a</code>. | |
| 1885 | −Note that, in the absence of a "le" metamethod, | |
| 1886 | −Lua tries the "lt", assuming that <code>a <= b</code> is | |
| 1887 | −equivalent to <code>not (b < a)</code>. | |
| 1888 | −</li> | |
| 1889 | 1748 | |
| 1890 | −<li><b>"index":</b> | |
| 1891 | −The indexing access <code>table[key]</code>. | |
| 1892 | 1749 | |
| 1893 | 1750 | |
| 1751 | +<h3>3.4.3 - <a name="3.4.3">Relational Operators</a></h3><p> | |
| 1752 | +The relational operators in Lua are | |
| 1753 | + | |
| 1894 | 1754 | <pre> |
| 1895 | − function gettable_event (table, key) | |
| 1896 | − local h | |
| 1897 | − if type(table) == "table" then | |
| 1898 | − local v = rawget(table, key) | |
| 1899 | − if v ~= nil then return v end | |
| 1900 | − h = metatable(table).__index | |
| 1901 | − if h == nil then return nil end | |
| 1902 | − else | |
| 1903 | − h = metatable(table).__index | |
| 1904 | − if h == nil then | |
| 1905 | − error(···) | |
| 1906 | − end | |
| 1907 | − end | |
| 1908 | − if type(h) == "function" then | |
| 1909 | − return (h(table, key)) -- call the handler | |
| 1910 | − else return h[key] -- or repeat operation on it | |
| 1911 | − end | |
| 1912 | − end | |
| 1755 | + == ~= < > <= >= | |
| 1913 | 1756 | </pre><p> |
| 1914 | −</li> | |
| 1757 | +These operators always result in <b>false</b> or <b>true</b>. | |
| 1758 | + | |
| 1759 | + | |
| 1760 | +<p> | |
| 1761 | +Equality (<code>==</code>) first compares the type of its operands. | |
| 1762 | +If the types are different, then the result is <b>false</b>. | |
| 1763 | +Otherwise, the values of the operands are compared. | |
| 1764 | +Numbers and strings are compared in the usual way. | |
| 1765 | +Objects (tables, userdata, threads, and functions) | |
| 1766 | +are compared by <em>reference</em>: | |
| 1767 | +two objects are considered equal only if they are the <em>same</em> object. | |
| 1768 | +Every time you create a new object | |
| 1769 | +(a table, userdata, thread, or function), | |
| 1770 | +this new object is different from any previously existing object. | |
| 1771 | + | |
| 1772 | + | |
| 1773 | +<p> | |
| 1774 | +You can change the way that Lua compares tables and userdata | |
| 1775 | +by using the "eq" metamethod (see <a href="#2.4">§2.4</a>). | |
| 1776 | + | |
| 1777 | + | |
| 1778 | +<p> | |
| 1779 | +The conversion rules of <a href="#3.4.2">§3.4.2</a> | |
| 1780 | +<em>do not</em> apply to equality comparisons. | |
| 1781 | +Thus, <code>"0"==0</code> evaluates to <b>false</b>, | |
| 1782 | +and <code>t[0]</code> and <code>t["0"]</code> denote different | |
| 1783 | +entries in a table. | |
| 1784 | + | |
| 1785 | + | |
| 1786 | +<p> | |
| 1787 | +The operator <code>~=</code> is exactly the negation of equality (<code>==</code>). | |
| 1788 | + | |
| 1789 | + | |
| 1790 | +<p> | |
| 1791 | +The order operators work as follows. | |
| 1792 | +If both arguments are numbers, then they are compared as such. | |
| 1793 | +Otherwise, if both arguments are strings, | |
| 1794 | +then their values are compared according to the current locale. | |
| 1795 | +Otherwise, Lua tries to call the "lt" or the "le" | |
| 1796 | +metamethod (see <a href="#2.4">§2.4</a>). | |
| 1797 | +A comparison <code>a > b</code> is translated to <code>b < a</code> | |
| 1798 | +and <code>a >= b</code> is translated to <code>b <= a</code>. | |
| 1915 | 1799 | |
| 1916 | −<li><b>"newindex":</b> | |
| 1917 | −The indexing assignment <code>table[key] = value</code>. | |
| 1918 | 1800 | |
| 1919 | 1801 | |
| 1802 | + | |
| 1803 | + | |
| 1804 | +<h3>3.4.4 - <a name="3.4.4">Logical Operators</a></h3><p> | |
| 1805 | +The logical operators in Lua are | |
| 1806 | +<b>and</b>, <b>or</b>, and <b>not</b>. | |
| 1807 | +Like the control structures (see <a href="#3.3.4">§3.3.4</a>), | |
| 1808 | +all logical operators consider both <b>false</b> and <b>nil</b> as false | |
| 1809 | +and anything else as true. | |
| 1810 | + | |
| 1811 | + | |
| 1812 | +<p> | |
| 1813 | +The negation operator <b>not</b> always returns <b>false</b> or <b>true</b>. | |
| 1814 | +The conjunction operator <b>and</b> returns its first argument | |
| 1815 | +if this value is <b>false</b> or <b>nil</b>; | |
| 1816 | +otherwise, <b>and</b> returns its second argument. | |
| 1817 | +The disjunction operator <b>or</b> returns its first argument | |
| 1818 | +if this value is different from <b>nil</b> and <b>false</b>; | |
| 1819 | +otherwise, <b>or</b> returns its second argument. | |
| 1820 | +Both <b>and</b> and <b>or</b> use short-cut evaluation; | |
| 1821 | +that is, | |
| 1822 | +the second operand is evaluated only if necessary. | |
| 1823 | +Here are some examples: | |
| 1824 | + | |
| 1920 | 1825 | <pre> |
| 1921 | − function settable_event (table, key, value) | |
| 1922 | − local h | |
| 1923 | − if type(table) == "table" then | |
| 1924 | − local v = rawget(table, key) | |
| 1925 | − if v ~= nil then rawset(table, key, value); return end | |
| 1926 | − h = metatable(table).__newindex | |
| 1927 | − if h == nil then rawset(table, key, value); return end | |
| 1928 | − else | |
| 1929 | − h = metatable(table).__newindex | |
| 1930 | − if h == nil then | |
| 1931 | − error(···) | |
| 1932 | − end | |
| 1933 | − end | |
| 1934 | − if type(h) == "function" then | |
| 1935 | − h(table, key,value) -- call the handler | |
| 1936 | − else h[key] = value -- or repeat operation on it | |
| 1937 | − end | |
| 1938 | − end | |
| 1826 | + 10 or 20 --> 10 | |
| 1827 | + 10 or error() --> 10 | |
| 1828 | + nil or "a" --> "a" | |
| 1829 | + nil and 10 --> nil | |
| 1830 | + false and error() --> false | |
| 1831 | + false and nil --> false | |
| 1832 | + false or nil --> nil | |
| 1833 | + 10 and 20 --> 20 | |
| 1939 | 1834 | </pre><p> |
| 1940 | −</li> | |
| 1835 | +(In this manual, | |
| 1836 | +<code>--></code> indicates the result of the preceding expression.) | |
| 1941 | 1837 | |
| 1942 | −<li><b>"call":</b> | |
| 1943 | −called when Lua calls a value. | |
| 1944 | 1838 | |
| 1945 | 1839 | |
| 1946 | −<pre> | |
| 1947 | − function function_event (func, ...) | |
| 1948 | − if type(func) == "function" then | |
| 1949 | − return func(...) -- primitive call | |
| 1950 | − else | |
| 1951 | − local h = metatable(func).__call | |
| 1952 | − if h then | |
| 1953 | − return h(func, ...) | |
| 1954 | − else | |
| 1955 | − error(···) | |
| 1956 | − end | |
| 1957 | − end | |
| 1958 | − end | |
| 1959 | −</pre><p> | |
| 1960 | −</li> | |
| 1961 | 1840 | |
| 1962 | −</ul> | |
| 1963 | 1841 | |
| 1842 | +<h3>3.4.5 - <a name="3.4.5">Concatenation</a></h3><p> | |
| 1843 | +The string concatenation operator in Lua is | |
| 1844 | +denoted by two dots ('<code>..</code>'). | |
| 1845 | +If both operands are strings or numbers, then they are converted to | |
| 1846 | +strings according to the rules mentioned in <a href="#3.4.2">§3.4.2</a>. | |
| 1847 | +Otherwise, the "concat" metamethod is called (see <a href="#2.4">§2.4</a>). | |
| 1964 | 1848 | |
| 1965 | 1849 | |
| 1966 | 1850 | |
| 1967 | −<h2>2.9 - <a name="2.9">Environments</a></h2> | |
| 1968 | 1851 | |
| 1969 | −<p> | |
| 1970 | −Each function and userdata in Lua | |
| 1971 | −has a table associated with it, | |
| 1972 | −called its <em>environment</em>. | |
| 1973 | −Like metatables, environments are regular tables and | |
| 1974 | −multiple objects can share the same environment. | |
| 1975 | −>From Lua, | |
| 1976 | −you can manipulate the environment of an object | |
| 1977 | −only through the debug library (see <a href="#5.10">§5.10</a>). | |
| 1978 | 1852 | |
| 1853 | +<h3>3.4.6 - <a name="3.4.6">The Length Operator</a></h3> | |
| 1979 | 1854 | |
| 1980 | 1855 | <p> |
| 1981 | −Userdata and C functions are created sharing the environment | |
| 1982 | −of the creating C function. | |
| 1983 | −Non-nested Lua functions | |
| 1984 | −(created by <a href="#pdf-loadfile"><code>loadfile</code></a>, <a href="#pdf-loadstring"><code>loadstring</code></a> or <a href="#pdf-load"><code>load</code></a>) | |
| 1985 | −are created sharing the global environment. | |
| 1986 | −Nested Lua functions are created sharing the current environment | |
| 1987 | −of where it is defined. | |
| 1856 | +The length operator is denoted by the unary prefix operator <code>#</code>. | |
| 1857 | +The length of a string is its number of bytes | |
| 1858 | +(that is, the usual meaning of string length when each | |
| 1859 | +character is one byte). | |
| 1988 | 1860 | |
| 1989 | 1861 | |
| 1990 | 1862 | <p> |
| 1991 | −Environments associated with userdata have no meaning for Lua. | |
| 1992 | −It is only a convenience feature for programmers to associate a table to | |
| 1993 | −a userdata. | |
| 1863 | +The length of a table <code>t</code> is defined to be any | |
| 1864 | +integer index <code>n</code> | |
| 1865 | +such that <code>t[n]</code> is not <b>nil</b> and <code>t[n+1]</code> is <b>nil</b>; | |
| 1866 | +moreover, if <code>t[1]</code> is <b>nil</b>, <code>n</code> can be zero. | |
| 1867 | +For a regular array, where all non-nil values | |
| 1868 | +have keys from 1 to a given <code>n</code>, | |
| 1869 | +its length is exactly that <code>n</code>, | |
| 1870 | +the index of its last value. | |
| 1871 | +If the array has "holes" | |
| 1872 | +(that is, <b>nil</b> values between other non-nil values), | |
| 1873 | +then <code>#t</code> can be any of the indices that | |
| 1874 | +directly precedes a <b>nil</b> value | |
| 1875 | +(that is, it may consider any such <b>nil</b> value as the end of | |
| 1876 | +the array). | |
| 1994 | 1877 | |
| 1995 | 1878 | |
| 1996 | 1879 | <p> |
| 1997 | −The environment associated with a C function can be directly | |
| 1998 | −accessed by C code (see <a href="#3.3">§3.3</a>). | |
| 1999 | −It is used as the default environment for other C functions | |
| 2000 | −and userdata created by the function. | |
| 1880 | +A program can modify the behavior of the length operator for | |
| 1881 | +any value but strings through metamethods (see <a href="#2.4">§2.4</a>). | |
| 2001 | 1882 | |
| 2002 | 1883 | |
| 2003 | −<p> | |
| 2004 | −The environment associated with a Lua function is used as the | |
| 2005 | −current environment of all code in the function outside | |
| 2006 | −a lexical environment (see <a href="#2.4.8">§2.4.8</a>). | |
| 2007 | −A lexical environment changes the | |
| 2008 | −current environment inside its scope. | |
| 2009 | −In any case, | |
| 2010 | −the <em>current environment</em> is the table | |
| 2011 | −Lua uses to resolve global variables and to initialize | |
| 2012 | −the environment of nested functions. | |
| 2013 | 1884 | |
| 2014 | 1885 | |
| 2015 | 1886 | |
| 1887 | +<h3>3.4.7 - <a name="3.4.7">Precedence</a></h3><p> | |
| 1888 | +Operator precedence in Lua follows the table below, | |
| 1889 | +from lower to higher priority: | |
| 1890 | + | |
| 1891 | +<pre> | |
| 1892 | + or | |
| 1893 | + and | |
| 1894 | + < > <= >= ~= == | |
| 1895 | + .. | |
| 1896 | + + - | |
| 1897 | + * / % | |
| 1898 | + not # - (unary) | |
| 1899 | + ^ | |
| 1900 | +</pre><p> | |
| 1901 | +As usual, | |
| 1902 | +you can use parentheses to change the precedences of an expression. | |
| 1903 | +The concatenation ('<code>..</code>') and exponentiation ('<code>^</code>') | |
| 1904 | +operators are right associative. | |
| 1905 | +All other binary operators are left associative. | |
| 2016 | 1906 | |
| 2017 | 1907 | |
| 2018 | −<h2>2.10 - <a name="2.10">Garbage Collection</a></h2> | |
| 2019 | 1908 | |
| 2020 | −<p> | |
| 2021 | −Lua performs automatic memory management. | |
| 2022 | −This means that | |
| 2023 | −you have to worry neither about allocating memory for new objects | |
| 2024 | −nor about freeing it when the objects are no longer needed. | |
| 2025 | −Lua manages memory automatically by running | |
| 2026 | −a <em>garbage collector</em> from time to time | |
| 2027 | −to collect all <em>dead objects</em> | |
| 2028 | −(that is, objects that are no longer accessible from Lua). | |
| 2029 | −All memory used by Lua is subject to automatic management: | |
| 2030 | −tables, userdata, functions, threads, strings, etc. | |
| 2031 | 1909 | |
| 2032 | 1910 | |
| 2033 | −<p> | |
| 2034 | −Lua implements an incremental mark-and-sweep collector. | |
| 2035 | −It uses two numbers to control its garbage-collection cycles: | |
| 2036 | −the <em>garbage-collector pause</em> and | |
| 2037 | −the <em>garbage-collector step multiplier</em>. | |
| 2038 | −Both use percentage points as units | |
| 2039 | −(so that a value of 100 means an internal value of 1). | |
| 1911 | +<h3>3.4.8 - <a name="3.4.8">Table Constructors</a></h3><p> | |
| 1912 | +Table constructors are expressions that create tables. | |
| 1913 | +Every time a constructor is evaluated, a new table is created. | |
| 1914 | +A constructor can be used to create an empty table | |
| 1915 | +or to create a table and initialize some of its fields. | |
| 1916 | +The general syntax for constructors is | |
| 2040 | 1917 | |
| 1918 | +<pre> | |
| 1919 | + tableconstructor ::= &lsquo<b>{</b>’ [fieldlist] &lsquo<b>}</b>’ | |
| 1920 | + fieldlist ::= field {fieldsep field} [fieldsep] | |
| 1921 | + field ::= &lsquo<b>[</b>’ exp &lsquo<b>]</b>’ &lsquo<b>=</b>’ exp | Name &lsquo<b>=</b>’ exp | exp | |
| 1922 | + fieldsep ::= &lsquo<b>,</b>’ | &lsquo<b>;</b>’ | |
| 1923 | +</pre> | |
| 2041 | 1924 | |
| 2042 | 1925 | <p> |
| 2043 | −The garbage-collector pause | |
| 2044 | −controls how long the collector waits before starting a new cycle. | |
| 2045 | −Larger values make the collector less aggressive. | |
| 2046 | −Values smaller than 100 mean the collector will not wait to | |
| 2047 | −start a new cycle. | |
| 2048 | −A value of 200 means that the collector waits for the total memory in use | |
| 2049 | −to double before starting a new cycle. | |
| 1926 | +Each field of the form <code>[exp1] = exp2</code> adds to the new table an entry | |
| 1927 | +with key <code>exp1</code> and value <code>exp2</code>. | |
| 1928 | +A field of the form <code>name = exp</code> is equivalent to | |
| 1929 | +<code>["name"] = exp</code>. | |
| 1930 | +Finally, fields of the form <code>exp</code> are equivalent to | |
| 1931 | +<code>[i] = exp</code>, where <code>i</code> are consecutive numerical integers, | |
| 1932 | +starting with 1. | |
| 1933 | +Fields in the other formats do not affect this counting. | |
| 1934 | +For example, | |
| 1935 | + | |
| 1936 | +<pre> | |
| 1937 | + a = { [f(1)] = g; "x", "y"; x = 1, f(x), [30] = 23; 45 } | |
| 1938 | +</pre><p> | |
| 1939 | +is equivalent to | |
| 2050 | 1940 | |
| 1941 | +<pre> | |
| 1942 | + do | |
| 1943 | + local t = {} | |
| 1944 | + t[f(1)] = g | |
| 1945 | + t[1] = "x" -- 1st exp | |
| 1946 | + t[2] = "y" -- 2nd exp | |
| 1947 | + t.x = 1 -- t["x"] = 1 | |
| 1948 | + t[3] = f(x) -- 3rd exp | |
| 1949 | + t[30] = 23 | |
| 1950 | + t[4] = 45 -- 4th exp | |
| 1951 | + a = t | |
| 1952 | + end | |
| 1953 | +</pre> | |
| 2051 | 1954 | |
| 2052 | 1955 | <p> |
| 2053 | −The step multiplier | |
| 2054 | −controls the relative speed of the collector relative to | |
| 2055 | −memory allocation. | |
| 2056 | −Larger values make the collector more aggressive but also increase | |
| 2057 | −the size of each incremental step. | |
| 2058 | −Values smaller than 100 make the collector too slow and | |
| 2059 | −can result in the collector never finishing a cycle. | |
| 2060 | −The default, 200, means that the collector runs at "twice" | |
| 2061 | −the speed of memory allocation. | |
| 1956 | +If the last field in the list has the form <code>exp</code> | |
| 1957 | +and the expression is a function call or a vararg expression, | |
| 1958 | +then all values returned by this expression enter the list consecutively | |
| 1959 | +(see <a href="#3.4.9">§3.4.9</a>). | |
| 1960 | +To avoid this, | |
| 1961 | +enclose the function call or the vararg expression | |
| 1962 | +in parentheses (see <a href="#3.4">§3.4</a>). | |
| 2062 | 1963 | |
| 2063 | 1964 | |
| 2064 | 1965 | <p> |
| 2065 | −If you set the step multiplier to a very large number | |
| 2066 | −(larger than 10% of the maximum number of | |
| 2067 | −bytes that the program may use), | |
| 2068 | −the collector behaves like a stop-the-world collector. | |
| 2069 | −If you then set the pause to 200, | |
| 2070 | −the collector behaves as in old Lua versions, | |
| 2071 | −doing a complete collection every time Lua doubles its | |
| 2072 | −memory usage. | |
| 1966 | +The field list can have an optional trailing separator, | |
| 1967 | +as a convenience for machine-generated code. | |
| 1968 | + | |
| 1969 | + | |
| 1970 | + | |
| 1971 | + | |
| 1972 | + | |
| 1973 | +<h3>3.4.9 - <a name="3.4.9">Function Calls</a></h3><p> | |
| 1974 | +A function call in Lua has the following syntax: | |
| 1975 | + | |
| 1976 | +<pre> | |
| 1977 | + functioncall ::= prefixexp args | |
| 1978 | +</pre><p> | |
| 1979 | +In a function call, | |
| 1980 | +first prefixexp and args are evaluated. | |
| 1981 | +If the value of prefixexp has type <em>function</em>, | |
| 1982 | +then this function is called | |
| 1983 | +with the given arguments. | |
| 1984 | +Otherwise, the prefixexp "call" metamethod is called, | |
| 1985 | +having as first parameter the value of prefixexp, | |
| 1986 | +followed by the original call arguments | |
| 1987 | +(see <a href="#2.4">§2.4</a>). | |
| 2073 | 1988 | |
| 2074 | 1989 | |
| 2075 | 1990 | <p> |
| 2076 | −You can change these numbers by calling <a href="#lua_gc"><code>lua_gc</code></a> in C | |
| 2077 | −or <a href="#pdf-collectgarbage"><code>collectgarbage</code></a> in Lua. | |
| 2078 | −With these functions you can also control | |
| 2079 | −the collector directly (e.g., stop and restart it). | |
| 1991 | +The form | |
| 1992 | + | |
| 1993 | +<pre> | |
| 1994 | + functioncall ::= prefixexp &lsquo<b>:</b>’ Name args | |
| 1995 | +</pre><p> | |
| 1996 | +can be used to call "methods". | |
| 1997 | +A call <code>v:name(<em>args</em>)</code> | |
| 1998 | +is syntactic sugar for <code>v.name(v,<em>args</em>)</code>, | |
| 1999 | +except that <code>v</code> is evaluated only once. | |
| 2080 | 2000 | |
| 2081 | 2001 | |
| 2002 | +<p> | |
| 2003 | +Arguments have the following syntax: | |
| 2004 | + | |
| 2005 | +<pre> | |
| 2006 | + args ::= &lsquo<b>(</b>’ [explist] &lsquo<b>)</b>’ | |
| 2007 | + args ::= tableconstructor | |
| 2008 | + args ::= String | |
| 2009 | +</pre><p> | |
| 2010 | +All argument expressions are evaluated before the call. | |
| 2011 | +A call of the form <code>f{<em>fields</em>}</code> is | |
| 2012 | +syntactic sugar for <code>f({<em>fields</em>})</code>; | |
| 2013 | +that is, the argument list is a single new table. | |
| 2014 | +A call of the form <code>f'<em>string</em>'</code> | |
| 2015 | +(or <code>f"<em>string</em>"</code> or <code>f[[<em>string</em>]]</code>) | |
| 2016 | +is syntactic sugar for <code>f('<em>string</em>')</code>; | |
| 2017 | +that is, the argument list is a single literal string. | |
| 2082 | 2018 | |
| 2083 | −<h3>2.10.1 - <a name="2.10.1">Garbage-Collection Metamethods</a></h3> | |
| 2084 | 2019 | |
| 2085 | 2020 | <p> |
| 2086 | −Using the C API, | |
| 2087 | −you can set garbage-collector metamethods for userdata (see <a href="#2.8">§2.8</a>). | |
| 2088 | −These metamethods are also called <em>finalizers</em>. | |
| 2089 | −Finalizers allow you to coordinate Lua's garbage collection | |
| 2090 | −with external resource management | |
| 2091 | −(such as closing files, network or database connections, | |
| 2092 | −or freeing your own memory). | |
| 2021 | +A call of the form <code>return</code> <em>functioncall</em> is called | |
| 2022 | +a <em>tail call</em>. | |
| 2023 | +Lua implements <em>proper tail calls</em> | |
| 2024 | +(or <em>proper tail recursion</em>): | |
| 2025 | +in a tail call, | |
| 2026 | +the called function reuses the stack entry of the calling function. | |
| 2027 | +Therefore, there is no limit on the number of nested tail calls that | |
| 2028 | +a program can execute. | |
| 2029 | +However, a tail call erases any debug information about the | |
| 2030 | +calling function. | |
| 2031 | +Note that a tail call only happens with a particular syntax, | |
| 2032 | +where the <b>return</b> has one single function call as argument; | |
| 2033 | +this syntax makes the calling function return exactly | |
| 2034 | +the returns of the called function. | |
| 2035 | +So, none of the following examples are tail calls: | |
| 2036 | + | |
| 2037 | +<pre> | |
| 2038 | + return (f(x)) -- results adjusted to 1 | |
| 2039 | + return 2 * f(x) | |
| 2040 | + return x, f(x) -- additional results | |
| 2041 | + f(x); return -- results discarded | |
| 2042 | + return x or f(x) -- results adjusted to 1 | |
| 2043 | +</pre> | |
| 2044 | + | |
| 2045 | + | |
| 2093 | 2046 | |
| 2094 | 2047 | |
| 2048 | +<h3>3.4.10 - <a name="3.4.10">Function Definitions</a></h3> | |
| 2049 | + | |
| 2095 | 2050 | <p> |
| 2096 | −Garbage userdata with a field <code>__gc</code> in their metatables are not | |
| 2097 | −collected immediately by the garbage collector. | |
| 2098 | −Instead, Lua puts them in a list. | |
| 2099 | −After the collection, | |
| 2100 | −Lua does the equivalent of the following function | |
| 2101 | −for each userdata in that list: | |
| 2051 | +The syntax for function definition is | |
| 2102 | 2052 | |
| 2103 | 2053 | <pre> |
| 2104 | − function gc_event (udata) | |
| 2105 | − local h = metatable(udata).__gc | |
| 2106 | − if h then | |
| 2107 | − h(udata) | |
| 2108 | − end | |
| 2109 | − end | |
| 2054 | + function ::= <b>function</b> funcbody | |
| 2055 | + funcbody ::= &lsquo<b>(</b>’ [parlist] &lsquo<b>)</b>’ block <b>end</b> | |
| 2110 | 2056 | </pre> |
| 2111 | 2057 | |
| 2112 | 2058 | <p> |
| 2113 | −At the end of each garbage-collection cycle, | |
| 2114 | −the finalizers for userdata are called in <em>reverse</em> | |
| 2115 | −order of their creation, | |
| 2116 | −among those collected in that cycle. | |
| 2117 | −That is, the first finalizer to be called is the one associated | |
| 2118 | −with the userdata created last in the program. | |
| 2119 | −The userdata itself is freed only in the next garbage-collection cycle. | |
| 2059 | +The following syntactic sugar simplifies function definitions: | |
| 2120 | 2060 | |
| 2061 | +<pre> | |
| 2062 | + stat ::= <b>function</b> funcname funcbody | |
| 2063 | + stat ::= <b>local</b> <b>function</b> Name funcbody | |
| 2064 | + funcname ::= Name {&lsquo<b>.</b>’ Name} [&lsquo<b>:</b>’ Name] | |
| 2065 | +</pre><p> | |
| 2066 | +The statement | |
| 2121 | 2067 | |
| 2068 | +<pre> | |
| 2069 | + function f () <em>body</em> end | |
| 2070 | +</pre><p> | |
| 2071 | +translates to | |
| 2122 | 2072 | |
| 2073 | +<pre> | |
| 2074 | + f = function () <em>body</em> end | |
| 2075 | +</pre><p> | |
| 2076 | +The statement | |
| 2123 | 2077 | |
| 2078 | +<pre> | |
| 2079 | + function t.a.b.c.f () <em>body</em> end | |
| 2080 | +</pre><p> | |
| 2081 | +translates to | |
| 2124 | 2082 | |
| 2125 | −<h3>2.10.2 - <a name="2.10.2">Weak Tables</a></h3> | |
| 2083 | +<pre> | |
| 2084 | + t.a.b.c.f = function () <em>body</em> end | |
| 2085 | +</pre><p> | |
| 2086 | +The statement | |
| 2126 | 2087 | |
| 2127 | −<p> | |
| 2128 | −A <em>weak table</em> is a table whose elements are | |
| 2129 | −<em>weak references</em>. | |
| 2130 | −A weak reference is ignored by the garbage collector. | |
| 2131 | −In other words, | |
| 2132 | −if the only references to an object are weak references, | |
| 2133 | −then the garbage collector will collect this object. | |
| 2088 | +<pre> | |
| 2089 | + local function f () <em>body</em> end | |
| 2090 | +</pre><p> | |
| 2091 | +translates to | |
| 2134 | 2092 | |
| 2093 | +<pre> | |
| 2094 | + local f; f = function () <em>body</em> end | |
| 2095 | +</pre><p> | |
| 2096 | +<em>not</em> to | |
| 2135 | 2097 | |
| 2136 | −<p> | |
| 2137 | −A weak table can have weak keys, weak values, or both. | |
| 2138 | −A table with weak keys allows the collection of its keys, | |
| 2139 | −but prevents the collection of its values. | |
| 2140 | −A table with both weak keys and weak values allows the collection of | |
| 2141 | −both keys and values. | |
| 2142 | −In any case, if either the key or the value is collected, | |
| 2143 | −the whole pair is removed from the table. | |
| 2144 | −The weakness of a table is controlled by the | |
| 2145 | −<code>__mode</code> field of its metatable. | |
| 2146 | −If the <code>__mode</code> field is a string containing the character '<code>k</code>', | |
| 2147 | −the keys in the table are weak. | |
| 2148 | −If <code>__mode</code> contains '<code>v</code>', | |
| 2149 | −the values in the table are weak. | |
| 2098 | +<pre> | |
| 2099 | + local f = function () <em>body</em> end | |
| 2100 | +</pre><p> | |
| 2101 | +(This only makes a difference when the body of the function | |
| 2102 | +contains references to <code>f</code>.) | |
| 2150 | 2103 | |
| 2151 | 2104 | |
| 2152 | 2105 | <p> |
| 2153 | −Userdata with finalizers has a special behavior in weak tables. | |
| 2154 | −When a userdata is a value in a weak table, | |
| 2155 | −it is removed from the table the first time it is collected, | |
| 2156 | −before running its finalizer. | |
| 2157 | −When it is a key, however, | |
| 2158 | −it is removed from the table only when it is really freed, | |
| 2159 | −after running its finalizer. | |
| 2160 | −This behavior allows the finalizer to access values | |
| 2161 | −associated with the userdata through weak tables. | |
| 2106 | +A function definition is an executable expression, | |
| 2107 | +whose value has type <em>function</em>. | |
| 2108 | +When Lua pre-compiles a chunk, | |
| 2109 | +all its function bodies are pre-compiled too. | |
| 2110 | +Then, whenever Lua executes the function definition, | |
| 2111 | +the function is <em>instantiated</em> (or <em>closed</em>). | |
| 2112 | +This function instance (or <em>closure</em>) | |
| 2113 | +is the final value of the expression. | |
| 2114 | +Different instances of the same function | |
| 2115 | +can refer to different external local variables | |
| 2116 | +and can have different environment tables. | |
| 2162 | 2117 | |
| 2163 | 2118 | |
| 2164 | 2119 | <p> |
| 2165 | −A table with weak keys and strong values | |
| 2166 | −is also called an <em>ephemeron table</em>. | |
| 2167 | −In an ephemeron table, | |
| 2168 | −a value is considered reachable only if its key is reachable. | |
| 2169 | −In particular, | |
| 2170 | −if the only reference to a key comes from its value, | |
| 2171 | −the pair is removed. | |
| 2120 | +Parameters act as local variables that are | |
| 2121 | +initialized with the argument values: | |
| 2122 | + | |
| 2123 | +<pre> | |
| 2124 | + parlist ::= namelist [&lsquo<b>,</b>’ &lsquo<b>...</b>’] | &lsquo<b>...</b>’ | |
| 2125 | +</pre><p> | |
| 2126 | +When a function is called, | |
| 2127 | +the list of arguments is adjusted to | |
| 2128 | +the length of the list of parameters, | |
| 2129 | +unless the function is a variadic or <em>vararg function</em>, | |
| 2130 | +which is | |
| 2131 | +indicated by three dots ('<code>...</code>') at the end of its parameter list. | |
| 2132 | +A vararg function does not adjust its argument list; | |
| 2133 | +instead, it collects all extra arguments and supplies them | |
| 2134 | +to the function through a <em>vararg expression</em>, | |
| 2135 | +which is also written as three dots. | |
| 2136 | +The value of this expression is a list of all actual extra arguments, | |
| 2137 | +similar to a function with multiple results. | |
| 2138 | +If a vararg expression is used inside another expression | |
| 2139 | +or in the middle of a list of expressions, | |
| 2140 | +then its return list is adjusted to one element. | |
| 2141 | +If the expression is used as the last element of a list of expressions, | |
| 2142 | +then no adjustment is made | |
| 2143 | +(unless that last expression is enclosed in parentheses). | |
| 2172 | 2144 | |
| 2173 | 2145 | |
| 2174 | 2146 | <p> |
| 2175 | −After you use a table as a metatable, | |
| 2176 | −you should not change the value of its <code>__mode</code> field. | |
| 2177 | −Otherwise, the weak behavior of the tables controlled by this | |
| 2178 | −metatable is undefined. | |
| 2147 | +As an example, consider the following definitions: | |
| 2179 | 2148 | |
| 2149 | +<pre> | |
| 2150 | + function f(a, b) end | |
| 2151 | + function g(a, b, ...) end | |
| 2152 | + function r() return 1,2,3 end | |
| 2153 | +</pre><p> | |
| 2154 | +Then, we have the following mapping from arguments to parameters and | |
| 2155 | +to the vararg expression: | |
| 2180 | 2156 | |
| 2157 | +<pre> | |
| 2158 | + CALL PARAMETERS | |
| 2159 | + | |
| 2160 | + f(3) a=3, b=nil | |
| 2161 | + f(3, 4) a=3, b=4 | |
| 2162 | + f(3, 4, 5) a=3, b=4 | |
| 2163 | + f(r(), 10) a=1, b=10 | |
| 2164 | + f(r()) a=1, b=2 | |
| 2165 | + | |
| 2166 | + g(3) a=3, b=nil, ... --> (nothing) | |
| 2167 | + g(3, 4) a=3, b=4, ... --> (nothing) | |
| 2168 | + g(3, 4, 5, 8) a=3, b=4, ... --> 5 8 | |
| 2169 | + g(5, r()) a=5, b=1, ... --> 2 3 | |
| 2170 | +</pre> | |
| 2181 | 2171 | |
| 2172 | +<p> | |
| 2173 | +Results are returned using the <b>return</b> statement (see <a href="#3.3.4">§3.3.4</a>). | |
| 2174 | +If control reaches the end of a function | |
| 2175 | +without encountering a <b>return</b> statement, | |
| 2176 | +then the function returns with no results. | |
| 2182 | 2177 | |
| 2183 | 2178 | |
| 2179 | +<p> | |
| 2180 | +The <em>colon</em> syntax | |
| 2181 | +is used for defining <em>methods</em>, | |
| 2182 | +that is, functions that have an implicit extra parameter <code>self</code>. | |
| 2183 | +Thus, the statement | |
| 2184 | 2184 | |
| 2185 | +<pre> | |
| 2186 | + function t.a.b.c:f (<em>params</em>) <em>body</em> end | |
| 2187 | +</pre><p> | |
| 2188 | +is syntactic sugar for | |
| 2185 | 2189 | |
| 2186 | −<h2>2.11 - <a name="2.11">Coroutines</a></h2> | |
| 2190 | +<pre> | |
| 2191 | + t.a.b.c.f = function (self, <em>params</em>) <em>body</em> end | |
| 2192 | +</pre> | |
| 2187 | 2193 | |
| 2188 | −<p> | |
| 2189 | −Lua supports coroutines, | |
| 2190 | −also called <em>collaborative multithreading</em>. | |
| 2191 | −A coroutine in Lua represents an independent thread of execution. | |
| 2192 | −Unlike threads in multithread systems, however, | |
| 2193 | −a coroutine only suspends its execution by explicitly calling | |
| 2194 | −a yield function. | |
| 2195 | 2194 | |
| 2196 | 2195 | |
| 2197 | −<p> | |
| 2198 | −You create a coroutine with a call to <a href="#pdf-coroutine.create"><code>coroutine.create</code></a>. | |
| 2199 | −Its sole argument is a function | |
| 2200 | −that is the main function of the coroutine. | |
| 2201 | −The <code>create</code> function only creates a new coroutine and | |
| 2202 | −returns a handle to it (an object of type <em>thread</em>); | |
| 2203 | −it does not start the coroutine execution. | |
| 2204 | 2196 | |
| 2205 | 2197 | |
| 2206 | −<p> | |
| 2207 | −When you first call <a href="#pdf-coroutine.resume"><code>coroutine.resume</code></a>, | |
| 2208 | −passing as its first argument | |
| 2209 | −a thread returned by <a href="#pdf-coroutine.create"><code>coroutine.create</code></a>, | |
| 2210 | −the coroutine starts its execution, | |
| 2211 | −at the first line of its main function. | |
| 2212 | −Extra arguments passed to <a href="#pdf-coroutine.resume"><code>coroutine.resume</code></a> are passed on | |
| 2213 | −to the coroutine main function. | |
| 2214 | −After the coroutine starts running, | |
| 2215 | −it runs until it terminates or <em>yields</em>. | |
| 2216 | 2198 | |
| 2199 | +<h2>3.5 - <a name="3.5">Visibility Rules</a></h2> | |
| 2217 | 2200 | |
| 2218 | 2201 | <p> |
| 2219 | −A coroutine can terminate its execution in two ways: | |
| 2220 | −normally, when its main function returns | |
| 2221 | −(explicitly or implicitly, after the last instruction); | |
| 2222 | −and abnormally, if there is an unprotected error. | |
| 2223 | −In the first case, <a href="#pdf-coroutine.resume"><code>coroutine.resume</code></a> returns <b>true</b>, | |
| 2224 | −plus any values returned by the coroutine main function. | |
| 2225 | −In case of errors, <a href="#pdf-coroutine.resume"><code>coroutine.resume</code></a> returns <b>false</b> | |
| 2226 | −plus an error message. | |
| 2227 | 2202 | |
| 2203 | +Lua is a lexically scoped language. | |
| 2204 | +The scope of variables begins at the first statement <em>after</em> | |
| 2205 | +their declaration and lasts until the end of the innermost block that | |
| 2206 | +includes the declaration. | |
| 2207 | +Consider the following example: | |
| 2208 | + | |
| 2209 | +<pre> | |
| 2210 | + x = 10 -- global variable | |
| 2211 | + do -- new block | |
| 2212 | + local x = x -- new 'x', with value 10 | |
| 2213 | + print(x) --> 10 | |
| 2214 | + x = x+1 | |
| 2215 | + do -- another block | |
| 2216 | + local x = x+1 -- another 'x' | |
| 2217 | + print(x) --> 12 | |
| 2218 | + end | |
| 2219 | + print(x) --> 11 | |
| 2220 | + end | |
| 2221 | + print(x) --> 10 (the global one) | |
| 2222 | +</pre> | |
| 2228 | 2223 | |
| 2229 | 2224 | <p> |
| 2230 | −A coroutine yields by calling <a href="#pdf-coroutine.yield"><code>coroutine.yield</code></a>. | |
| 2231 | −When a coroutine yields, | |
| 2232 | −the corresponding <a href="#pdf-coroutine.resume"><code>coroutine.resume</code></a> returns immediately, | |
| 2233 | −even if the yield happens inside nested function calls | |
| 2234 | −(that is, not in the main function, | |
| 2235 | −but in a function directly or indirectly called by the main function). | |
| 2236 | −In the case of a yield, <a href="#pdf-coroutine.resume"><code>coroutine.resume</code></a> also returns <b>true</b>, | |
| 2237 | −plus any values passed to <a href="#pdf-coroutine.yield"><code>coroutine.yield</code></a>. | |
| 2238 | −The next time you resume the same coroutine, | |
| 2239 | −it continues its execution from the point where it yielded, | |
| 2240 | −with the call to <a href="#pdf-coroutine.yield"><code>coroutine.yield</code></a> returning any extra | |
| 2241 | −arguments passed to <a href="#pdf-coroutine.resume"><code>coroutine.resume</code></a>. | |
| 2225 | +Notice that, in a declaration like <code>local x = x</code>, | |
| 2226 | +the new <code>x</code> being declared is not in scope yet, | |
| 2227 | +and so the second <code>x</code> refers to the outside variable. | |
| 2242 | 2228 | |
| 2243 | 2229 | |
| 2244 | 2230 | <p> |
| 2245 | −Like <a href="#pdf-coroutine.create"><code>coroutine.create</code></a>, | |
| 2246 | −the <a href="#pdf-coroutine.wrap"><code>coroutine.wrap</code></a> function also creates a coroutine, | |
| 2247 | −but instead of returning the coroutine itself, | |
| 2248 | −it returns a function that, when called, resumes the coroutine. | |
| 2249 | −Any arguments passed to this function | |
| 2250 | −go as extra arguments to <a href="#pdf-coroutine.resume"><code>coroutine.resume</code></a>. | |
| 2251 | −<a href="#pdf-coroutine.wrap"><code>coroutine.wrap</code></a> returns all the values returned by <a href="#pdf-coroutine.resume"><code>coroutine.resume</code></a>, | |
| 2252 | −except the first one (the boolean error code). | |
| 2253 | −Unlike <a href="#pdf-coroutine.resume"><code>coroutine.resume</code></a>, | |
| 2254 | −<a href="#pdf-coroutine.wrap"><code>coroutine.wrap</code></a> does not catch errors; | |
| 2255 | −any error is propagated to the caller. | |
| 2231 | +Because of the lexical scoping rules, | |
| 2232 | +local variables can be freely accessed by functions | |
| 2233 | +defined inside their scope. | |
| 2234 | +A local variable used by an inner function is called | |
| 2235 | +an <em>upvalue</em>, or <em>external local variable</em>, | |
| 2236 | +inside the inner function. | |
| 2256 | 2237 | |
| 2257 | 2238 | |
| 2258 | 2239 | <p> |
| 2259 | −As an example, | |
| 2260 | −consider the following code: | |
| 2240 | +Notice that each execution of a <b>local</b> statement | |
| 2241 | +defines new local variables. | |
| 2242 | +Consider the following example: | |
| 2261 | 2243 | |
| 2262 | 2244 | <pre> |
| 2263 | − function foo (a) | |
| 2264 | − print("foo", a) | |
| 2265 | − return coroutine.yield(2*a) | |
| 2245 | + a = {} | |
| 2246 | + local x = 20 | |
| 2247 | + for i=1,10 do | |
| 2248 | + local y = 0 | |
| 2249 | + a[i] = function () y=y+1; return x+y end | |
| 2266 | 2250 | end |
| 2267 | − | |
| 2268 | − co = coroutine.create(function (a,b) | |
| 2269 | − print("co-body", a, b) | |
| 2270 | − local r = foo(a+1) | |
| 2271 | − print("co-body", r) | |
| 2272 | − local r, s = coroutine.yield(a+b, a-b) | |
| 2273 | − print("co-body", r, s) | |
| 2274 | − return b, "end" | |
| 2275 | − end) | |
| 2276 | − | |
| 2277 | − print("main", coroutine.resume(co, 1, 10)) | |
| 2278 | − print("main", coroutine.resume(co, "r")) | |
| 2279 | − print("main", coroutine.resume(co, "x", "y")) | |
| 2280 | − print("main", coroutine.resume(co, "x", "y")) | |
| 2281 | 2251 | </pre><p> |
| 2282 | −When you run it, it produces the following output: | |
| 2252 | +The loop creates ten closures | |
| 2253 | +(that is, ten instances of the anonymous function). | |
| 2254 | +Each of these closures uses a different <code>y</code> variable, | |
| 2255 | +while all of them share the same <code>x</code>. | |
| 2283 | 2256 | |
| 2284 | −<pre> | |
| 2285 | − co-body 1 10 | |
| 2286 | − foo 2 | |
| 2287 | − | |
| 2288 | − main true 4 | |
| 2289 | − co-body r | |
| 2290 | − main true 11 -9 | |
| 2291 | − co-body x y | |
| 2292 | − main true 10 end | |
| 2293 | − main false cannot resume dead coroutine | |
| 2294 | −</pre> | |
| 2295 | 2257 | |
| 2296 | 2258 | |
| 2297 | 2259 | |
| 2298 | 2260 | |
| 2299 | −<h1>3 - <a name="3">The Application Program Interface</a></h1> | |
| 2261 | +<h1>4 - <a name="4">The Application Program Interface</a></h1> | |
| 2300 | 2262 | |
| 2301 | 2263 | <p> |
| 2302 | 2264 | |
| @@ -2324,7 +2286,7 @@ in file <code>luaconf.h</code>. · 21 unmodified lines | ||
| 2324 | 2286 | |
| 2325 | 2287 | |
| 2326 | 2288 | |
| 2327 | −<h2>3.1 - <a name="3.1">The Stack</a></h2> | |
| 2289 | +<h2>4.1 - <a name="4.1">The Stack</a></h2> | |
| 2328 | 2290 | |
| 2329 | 2291 | <p> |
| 2330 | 2292 | Lua uses a <em>virtual stack</em> to pass values to and from C. |
| @@ -2366,7 +2328,7 @@ if it lies between 1 and the stack top · 35 unmodified lines | ||
| 2366 | 2328 | |
| 2367 | 2329 | |
| 2368 | 2330 | |
| 2369 | −<h2>3.2 - <a name="3.2">Stack Size</a></h2> | |
| 2331 | +<h2>4.2 - <a name="4.2">Stack Size</a></h2> | |
| 2370 | 2332 | |
| 2371 | 2333 | <p> |
| 2372 | 2334 | When you interact with Lua API, |
| @@ -2412,37 +2374,22 @@ Note that 0 is never an acceptable index. · 39 unmodified lines | ||
| 2412 | 2374 | |
| 2413 | 2375 | |
| 2414 | 2376 | |
| 2415 | −<h2>3.3 - <a name="3.3">Pseudo-Indices</a></h2> | |
| 2377 | +<h2>4.3 - <a name="4.3">Pseudo-Indices</a></h2> | |
| 2416 | 2378 | |
| 2417 | 2379 | <p> |
| 2418 | 2380 | Unless otherwise noted, |
| 2419 | 2381 | any function that accepts valid indices also accepts <em>pseudo-indices</em>, |
| 2420 | 2382 | which represent some Lua values that are accessible to C code |
| 2421 | 2383 | but which are not in the stack. |
| 2422 | −Pseudo-indices are used to access the thread environment, | |
| 2423 | −the function environment, | |
| 2424 | −the registry, | |
| 2425 | −and the upvalues of a C function (see <a href="#3.4">§3.4</a>). | |
| 2426 | − | |
| 2427 | − | |
| 2428 | −<p> | |
| 2429 | −The environment of the running C function is always | |
| 2430 | −at pseudo-index <a name="pdf-LUA_ENVIRONINDEX"><code>LUA_ENVIRONINDEX</code></a>. | |
| 2384 | +Pseudo-indices are used to access | |
| 2385 | +the registry | |
| 2386 | +and the upvalues of a C function (see <a href="#4.4">§4.4</a>). | |
| 2431 | 2387 | |
| 2432 | 2388 | |
| 2433 | −<p> | |
| 2434 | −To access and change the value of global variables, | |
| 2435 | −you can use regular table operations over an environment table. | |
| 2436 | −For instance, to access the value of a global variable, do | |
| 2437 | − | |
| 2438 | −<pre> | |
| 2439 | − lua_getfield(L, LUA_ENVIRONINDEX, varname); | |
| 2440 | −</pre> | |
| 2441 | − | |
| 2442 | 2389 | |
| 2443 | 2390 | |
| 2444 | 2391 | |
| 2445 | −<h2>3.4 - <a name="3.4">C Closures</a></h2> | |
| 2392 | +<h2>4.4 - <a name="4.4">C Closures</a></h2> | |
| 2446 | 2393 | |
| 2447 | 2394 | <p> |
| 2448 | 2395 | When a C function is created, |
| @@ -2469,7 +2416,7 @@ produces an acceptable (but invalid) index. · 20 unmodified lines | ||
| 2469 | 2416 | |
| 2470 | 2417 | |
| 2471 | 2418 | |
| 2472 | −<h2>3.5 - <a name="3.5">Registry</a></h2> | |
| 2419 | +<h2>4.5 - <a name="4.5">Registry</a></h2> | |
| 2473 | 2420 | |
| 2474 | 2421 | <p> |
| 2475 | 2422 | Lua provides a <em>registry</em>, |
| @@ -2503,29 +2450,6 @@ The following constants are defined: · 27 unmodified lines | ||
| 2503 | 2450 | the main thread of the state. |
| 2504 | 2451 | (The main thread is the one created together with the state.) |
| 2505 | 2452 | </li> |
| 2506 | −<li><b>LUA_RIDX_CPCALL:</b> At this index the registry has | |
| 2507 | −the <a name="pdf-cpcall"><code>cpcall</code></a> function. | |
| 2508 | −This function allows you to call any | |
| 2509 | −<a href="#lua_CFunction"><code>lua_CFunction</code></a> without creating a closure for it, | |
| 2510 | −therefore preventing an unprotected memory allocation error. | |
| 2511 | − | |
| 2512 | − | |
| 2513 | −<p> | |
| 2514 | −The address of the function to be called must be stored in a variable, | |
| 2515 | −whose address is passed as the first argument to <code>cpcall</code>, | |
| 2516 | −as a light userdata. | |
| 2517 | −Note that the light userdata in the first argument should not | |
| 2518 | −point to the function to be called, | |
| 2519 | −but to a variable containing the pointer to the function. | |
| 2520 | −ANSI C does not allow the direct assignment of a function address to | |
| 2521 | −the <code>void*</code> in a light userdata. | |
| 2522 | − | |
| 2523 | − | |
| 2524 | −<p> | |
| 2525 | −Other arguments to <code>cpcall</code> are passed to the called function. | |
| 2526 | −The <code>cpcall</code> function itself should be called with <a href="#lua_pcall"><code>lua_pcall</code></a>, | |
| 2527 | −like any C function. | |
| 2528 | −</li> | |
| 2529 | 2453 | |
| 2530 | 2454 | <li><b>LUA_RIDX_GLOBALS:</b> At this index the registry has |
| 2531 | 2455 | the global environment. |
| @@ -2536,7 +2460,7 @@ This is the C equivalent to the <a href="#pdf-_G"><code>_G</code></a> globa · 4 unmodified lines | ||
| 2536 | 2460 | |
| 2537 | 2461 | |
| 2538 | 2462 | |
| 2539 | −<h2>3.6 - <a name="3.6">Error Handling in C</a></h2> | |
| 2463 | +<h2>4.6 - <a name="4.6">Error Handling in C</a></h2> | |
| 2540 | 2464 | |
| 2541 | 2465 | <p> |
| 2542 | 2466 | Internally, Lua uses the C <code>longjmp</code> facility to handle errors. |
| @@ -2575,7 +2499,7 @@ Inside a C function you can throw an error by calling <a href="#lua_error"> · 32 unmodified lines | ||
| 2575 | 2499 | |
| 2576 | 2500 | |
| 2577 | 2501 | |
| 2578 | −<h2>3.7 - <a name="3.7">Handling Yields in C</a></h2> | |
| 2502 | +<h2>4.7 - <a name="4.7">Handling Yields in C</a></h2> | |
| 2579 | 2503 | |
| 2580 | 2504 | <p> |
| 2581 | 2505 | Internally, Lua uses the C <code>longjmp</code> facility to yield a coroutine. |
| @@ -2600,10 +2524,10 @@ To explain continuations, · 18 unmodified lines | ||
| 2600 | 2524 | let us set some terminology. |
| 2601 | 2525 | We have a C function called from Lua which we will call |
| 2602 | 2526 | the <em>original function</em>. |
| 2603 | −This original function may call one of those three functions in the C API, | |
| 2527 | +This original function then calls one of those three functions in the C API, | |
| 2604 | 2528 | which we will call the <em>callee function</em>, |
| 2605 | −that may yield the current thread. | |
| 2606 | −(This will happen when the callee function is <a href="#lua_yieldk"><code>lua_yieldk</code></a>, | |
| 2529 | +that then yields the current thread. | |
| 2530 | +(This can happen when the callee function is <a href="#lua_yieldk"><code>lua_yieldk</code></a>, | |
| 2607 | 2531 | or when the callee function is either <a href="#lua_callk"><code>lua_callk</code></a> or <a href="#lua_pcallk"><code>lua_pcallk</code></a> |
| 2608 | 2532 | and the function called by them yields.) |
| 2609 | 2533 | |
| @@ -2643,7 +2567,7 @@ and its continuation is the result of a call to <a href="#lua_getctx"><code>lua_ · 33 unmodified lines | ||
| 2643 | 2567 | |
| 2644 | 2568 | |
| 2645 | 2569 | |
| 2646 | −<h2>3.8 - <a name="3.8">Functions and Types</a></h2> | |
| 2570 | +<h2>4.8 - <a name="4.8">Functions and Types</a></h2> | |
| 2647 | 2571 | |
| 2648 | 2572 | <p> |
| 2649 | 2573 | Here we list all functions and types from the C API in |
| @@ -2675,6 +2599,18 @@ only due to not enough memory; · 25 unmodified lines | ||
| 2675 | 2599 | |
| 2676 | 2600 | |
| 2677 | 2601 | |
| 2602 | +<hr><h3><a name="lua_absindex"><code>lua_absindex</code></a></h3><p> | |
| 2603 | +<span class="apii">[-0, +0, <em>-</em>]</span> | |
| 2604 | +<pre>void lua_absindex (lua_State *L, int idx);</pre> | |
| 2605 | + | |
| 2606 | +<p> | |
| 2607 | +Converts the acceptable index <code>idx</code> into an absolute index | |
| 2608 | +(that is, one that does not depend on the stack top). | |
| 2609 | + | |
| 2610 | + | |
| 2611 | + | |
| 2612 | + | |
| 2613 | + | |
| 2678 | 2614 | <hr><h3><a name="lua_Alloc"><code>lua_Alloc</code></a></h3> |
| 2679 | 2615 | <pre>typedef void * (*lua_Alloc) (void *ud, |
| 2680 | 2616 | void *ptr, |
| @@ -2768,12 +2704,12 @@ but it seems a safe assumption.) · 87 unmodified lines | ||
| 2768 | 2704 | <pre>lua_CFunction lua_atpanic (lua_State *L, lua_CFunction panicf);</pre> |
| 2769 | 2705 | |
| 2770 | 2706 | <p> |
| 2771 | −Sets a new panic function and returns the old one (see <a href="#3.6">§3.6</a>). | |
| 2707 | +Sets a new panic function and returns the old one (see <a href="#4.6">§4.6</a>). | |
| 2772 | 2708 | |
| 2773 | 2709 | |
| 2774 | 2710 | <p> |
| 2775 | 2711 | The panic function should not try to run anything on the failed Lua state. |
| 2776 | −However, it can still use the debug API (see <a href="#3.9">§3.9</a>) | |
| 2712 | +However, it can still use the debug API (see <a href="#4.9">§4.9</a>) | |
| 2777 | 2713 | to gather information about the state. |
| 2778 | 2714 | In particular, the error message is at the top of the stack. |
| 2779 | 2715 | |
| @@ -2824,14 +2760,14 @@ equivalent to this Lua code: · 44 unmodified lines | ||
| 2824 | 2760 | Here it is in C: |
| 2825 | 2761 | |
| 2826 | 2762 | <pre> |
| 2827 | − lua_getfield(L, LUA_ENVIRONINDEX, "f"); /* function to be called */ | |
| 2763 | + lua_getglobal(L, "f"); /* function to be called */ | |
| 2828 | 2764 | lua_pushstring(L, "how"); /* 1st argument */ |
| 2829 | − lua_getfield(L, LUA_ENVIRONINDEX, "t"); /* table to be indexed */ | |
| 2765 | + lua_getglobal(L, "t"); /* table to be indexed */ | |
| 2830 | 2766 | lua_getfield(L, -1, "x"); /* push result of t.x (2nd arg) */ |
| 2831 | 2767 | lua_remove(L, -2); /* remove 't' from the stack */ |
| 2832 | 2768 | lua_pushinteger(L, 14); /* 3rd argument */ |
| 2833 | 2769 | lua_call(L, 3, 1); /* call 'f' with 3 arguments and 1 result */ |
| 2834 | − lua_setfield(L, LUA_ENVIRONINDEX, "a"); /* set global 'a' */ | |
| 2770 | + lua_setglobal(L, "a"); /* set global 'a' */ | |
| 2835 | 2771 | </pre><p> |
| 2836 | 2772 | Note that the code above is "balanced": |
| 2837 | 2773 | at its end, the stack is back to its original configuration. |
| @@ -2848,7 +2784,7 @@ This is considered good programming practice. · 10 unmodified lines | ||
| 2848 | 2784 | |
| 2849 | 2785 | <p> |
| 2850 | 2786 | This function behaves exactly like <a href="#lua_call"><code>lua_call</code></a>, |
| 2851 | −but allows the called function to yield (see <a href="#3.7">§3.7</a>). | |
| 2787 | +but allows the called function to yield (see <a href="#4.7">§4.7</a>). | |
| 2852 | 2788 | |
| 2853 | 2789 | |
| 2854 | 2790 | |
| @@ -2980,7 +2916,7 @@ If <code>n</code> is 1, the result is the single value on the stack · 125 unmodified lines | ||
| 2980 | 2916 | (that is, the function does nothing); |
| 2981 | 2917 | if <code>n</code> is 0, the result is the empty string. |
| 2982 | 2918 | Concatenation is performed following the usual semantics of Lua |
| 2983 | −(see <a href="#2.5.4">§2.5.4</a>). | |
| 2919 | +(see <a href="#3.4.5">§3.4.5</a>). | |
| 2984 | 2920 | |
| 2985 | 2921 | |
| 2986 | 2922 | |
| @@ -3108,13 +3044,13 @@ garbage-collection cycle. · 121 unmodified lines | ||
| 3108 | 3044 | |
| 3109 | 3045 | <li><b><code>LUA_GCSETPAUSE</code>:</b> |
| 3110 | 3046 | sets <code>data</code> as the new value |
| 3111 | −for the <em>pause</em> of the collector (see <a href="#2.10">§2.10</a>). | |
| 3047 | +for the <em>pause</em> of the collector (see <a href="#2.5">§2.5</a>). | |
| 3112 | 3048 | The function returns the previous value of the pause. |
| 3113 | 3049 | </li> |
| 3114 | 3050 | |
| 3115 | 3051 | <li><b><code>LUA_GCSETSTEPMUL</code>:</b> |
| 3116 | 3052 | sets <code>data</code> as the new value for the <em>step multiplier</em> of |
| 3117 | −the collector (see <a href="#2.10">§2.10</a>). | |
| 3053 | +the collector (see <a href="#2.5">§2.5</a>). | |
| 3118 | 3054 | The function returns the previous value of the step multiplier. |
| 3119 | 3055 | </li> |
| 3120 | 3056 | |
| @@ -3146,7 +3082,7 @@ opaque pointer passed to <a href="#lua_newstate"><code>lua_newstate</code></a>. · 25 unmodified lines | ||
| 3146 | 3082 | <pre>int lua_getctx (lua_State *L, int *ctx);</pre> |
| 3147 | 3083 | |
| 3148 | 3084 | <p> |
| 3149 | −This function is called by a continuation function (see <a href="#3.7">§3.7</a>) | |
| 3085 | +This function is called by a continuation function (see <a href="#4.7">§4.7</a>) | |
| 3150 | 3086 | to retrieve the status of the thread and a context information. |
| 3151 | 3087 | |
| 3152 | 3088 | |
| @@ -3197,7 +3133,7 @@ the value at the given index. · 44 unmodified lines | ||
| 3197 | 3133 | Pushes onto the stack the value <code>t[k]</code>, |
| 3198 | 3134 | where <code>t</code> is the value at the given valid index. |
| 3199 | 3135 | As in Lua, this function may trigger a metamethod |
| 3200 | −for the "index" event (see <a href="#2.8">§2.8</a>). | |
| 3136 | +for the "index" event (see <a href="#2.4">§2.4</a>). | |
| 3201 | 3137 | |
| 3202 | 3138 | |
| 3203 | 3139 | |
| @@ -3209,11 +3145,8 @@ for the "index" event (see <a href="#2.8">§2.8</a>). · 5 unmodified lines | ||
| 3209 | 3145 | |
| 3210 | 3146 | <p> |
| 3211 | 3147 | Pushes onto the stack the value of the global <code>name</code>. |
| 3212 | −It is defined as a macro: | |
| 3148 | +It is defined as a macro. | |
| 3213 | 3149 | |
| 3214 | −<pre> | |
| 3215 | − #define lua_getglobal(L,s) lua_getfield(L, LUA_ENVIRONINDEX, s) | |
| 3216 | −</pre> | |
| 3217 | 3150 | |
| 3218 | 3151 | |
| 3219 | 3152 | |
| @@ -3247,7 +3180,7 @@ and <code>k</code> is the value at the top of the stack. · 27 unmodified lines | ||
| 3247 | 3180 | This function pops the key from the stack |
| 3248 | 3181 | (putting the resulting value in its place). |
| 3249 | 3182 | As in Lua, this function may trigger a metamethod |
| 3250 | −for the "index" event (see <a href="#2.8">§2.8</a>). | |
| 3183 | +for the "index" event (see <a href="#2.4">§2.4</a>). | |
| 3251 | 3184 | |
| 3252 | 3185 | |
| 3253 | 3186 | |
| @@ -3452,7 +3385,7 @@ Returns 1 if the value at the given acceptable index is a userdata · 198 unmodified lines | ||
| 3452 | 3385 | |
| 3453 | 3386 | <p> |
| 3454 | 3387 | Returns the "length" of the value at the given acceptable index; |
| 3455 | −it is equivalent to the '<code>#</code>' operator in Lua (see <a href="#2.5.5">§2.5.5</a>). | |
| 3388 | +it is equivalent to the '<code>#</code>' operator in Lua (see <a href="#3.4.6">§3.4.6</a>). | |
| 3456 | 3389 | The result is pushed on the stack. |
| 3457 | 3390 | |
| 3458 | 3391 | |
| @@ -3510,7 +3443,15 @@ The <code>data</code> argument is an opaque value passed to the reader function. · 51 unmodified lines | ||
| 3510 | 3443 | |
| 3511 | 3444 | <p> |
| 3512 | 3445 | The <code>source</code> argument gives a name to the chunk, |
| 3513 | −which is used for error messages and in debug information (see <a href="#3.9">§3.9</a>). | |
| 3446 | +which is used for error messages and in debug information (see <a href="#4.9">§4.9</a>). | |
| 3447 | + | |
| 3448 | + | |
| 3449 | +<p> | |
| 3450 | +If the resulting function has upvalues, | |
| 3451 | +the first upvalue is set to the value of the global environment | |
| 3452 | +stored at index <code>LUA_RIDX_GLOBALS</code> in the registry (see <a href="#4.5">§4.5</a>). | |
| 3453 | +(When loading main chunks, | |
| 3454 | +this upvalue will be the <code>_ENV</code> variable (see <a href="#2.2">§2.2</a>).) | |
| 3514 | 3455 | |
| 3515 | 3456 | |
| 3516 | 3457 | |
| @@ -3729,7 +3670,7 @@ It is generated by the garbage collector.) · 212 unmodified lines | ||
| 3729 | 3670 | |
| 3730 | 3671 | <p> |
| 3731 | 3672 | This function behaves exactly like <a href="#lua_pcall"><code>lua_pcall</code></a>, |
| 3732 | −but allows the called function to yield (see <a href="#3.7">§3.7</a>). | |
| 3673 | +but allows the called function to yield (see <a href="#4.7">§4.7</a>). | |
| 3733 | 3674 | |
| 3734 | 3675 | |
| 3735 | 3676 | |
| @@ -3768,7 +3709,7 @@ Pushes a new C closure onto the stack. · 32 unmodified lines | ||
| 3768 | 3709 | <p> |
| 3769 | 3710 | When a C function is created, |
| 3770 | 3711 | it is possible to associate some values with it, |
| 3771 | −thus creating a C closure (see <a href="#3.4">§3.4</a>); | |
| 3712 | +thus creating a C closure (see <a href="#4.4">§4.4</a>); | |
| 3772 | 3713 | these values are then accessible to the function whenever it is called. |
| 3773 | 3714 | To associate values with a C function, |
| 3774 | 3715 | first these values should be pushed onto the stack |
| @@ -3784,11 +3725,18 @@ associated with the function. · 9 unmodified lines | ||
| 3784 | 3725 | The maximum value for <code>n</code> is 255. |
| 3785 | 3726 | |
| 3786 | 3727 | |
| 3728 | +<p> | |
| 3729 | +When <code>n</code> is zero, | |
| 3730 | +this function creates a <em>light C function</em>, | |
| 3731 | +which is just a pointer to the C function. | |
| 3732 | +In that case, it cannot throw a memory error. | |
| 3733 | + | |
| 3734 | + | |
| 3787 | 3735 | |
| 3788 | 3736 | |
| 3789 | 3737 | |
| 3790 | 3738 | <hr><h3><a name="lua_pushcfunction"><code>lua_pushcfunction</code></a></h3><p> |
| 3791 | −<span class="apii">[-0, +1, <em>m</em>]</span> | |
| 3739 | +<span class="apii">[-0, +1, <em>-</em>]</span> | |
| 3792 | 3740 | <pre>void lua_pushcfunction (lua_State *L, lua_CFunction f);</pre> |
| 3793 | 3741 | |
| 3794 | 3742 | <p> |
| @@ -3946,7 +3894,7 @@ onto the stack. · 151 unmodified lines | ||
| 3946 | 3894 | Lua makes (or reuses) an internal copy of the given string, |
| 3947 | 3895 | so the memory at <code>s</code> can be freed or reused immediately after |
| 3948 | 3896 | the function returns. |
| 3949 | −The string cannot contain embedded zeros; | |
| 3897 | +The string should not contain embedded zeros; | |
| 3950 | 3898 | it is assumed to end at the first zero. |
| 3951 | 3899 | |
| 3952 | 3900 | |
| @@ -3954,6 +3902,10 @@ it is assumed to end at the first zero. · 1 unmodified line | ||
| 3954 | 3902 | Returns a pointer to the internal copy of the string. |
| 3955 | 3903 | |
| 3956 | 3904 | |
| 3905 | +<p> | |
| 3906 | +If <code>s</code> is <code>NULL</code>, pushes <b>nil</b> and returns <code>NULL</code>. | |
| 3907 | + | |
| 3908 | + | |
| 3957 | 3909 | |
| 3958 | 3910 | |
| 3959 | 3911 | |
| @@ -4232,7 +4184,7 @@ and <code>v</code> is the value at the top of the stack. · 272 unmodified lines | ||
| 4232 | 4184 | <p> |
| 4233 | 4185 | This function pops the value from the stack. |
| 4234 | 4186 | As in Lua, this function may trigger a metamethod |
| 4235 | −for the "newindex" event (see <a href="#2.8">§2.8</a>). | |
| 4187 | +for the "newindex" event (see <a href="#2.4">§2.4</a>). | |
| 4236 | 4188 | |
| 4237 | 4189 | |
| 4238 | 4190 | |
| @@ -4245,11 +4197,8 @@ for the "newindex" event (see <a href="#2.8">§2.8</a>). · 6 unmodified lines | ||
| 4245 | 4197 | <p> |
| 4246 | 4198 | Pops a value from the stack and |
| 4247 | 4199 | sets it as the new value of global <code>name</code>. |
| 4248 | −It is defined as a macro: | |
| 4200 | +It is defined as a macro. | |
| 4249 | 4201 | |
| 4250 | −<pre> | |
| 4251 | − #define lua_setglobal(L,s) lua_setfield(L, LUA_ENVIRONINDEX, s) | |
| 4252 | −</pre> | |
| 4253 | 4202 | |
| 4254 | 4203 | |
| 4255 | 4204 | |
| @@ -4281,7 +4230,7 @@ and <code>k</code> is the value just below the top. · 25 unmodified lines | ||
| 4281 | 4230 | <p> |
| 4282 | 4231 | This function pops both the key and the value from the stack. |
| 4283 | 4232 | As in Lua, this function may trigger a metamethod |
| 4284 | −for the "newindex" event (see <a href="#2.8">§2.8</a>). | |
| 4233 | +for the "newindex" event (see <a href="#2.4">§2.4</a>). | |
| 4285 | 4234 | |
| 4286 | 4235 | |
| 4287 | 4236 | |
| @@ -4379,7 +4328,7 @@ otherwise, returns <code>NULL</code>. · 91 unmodified lines | ||
| 4379 | 4328 | Converts the Lua value at the given acceptable index |
| 4380 | 4329 | to the signed integral type <a href="#lua_Integer"><code>lua_Integer</code></a>. |
| 4381 | 4330 | The Lua value must be a number or a string convertible to a number |
| 4382 | −(see <a href="#2.2.1">§2.2.1</a>); | |
| 4331 | +(see <a href="#3.4.2">§3.4.2</a>); | |
| 4383 | 4332 | otherwise, <a href="#lua_tointeger"><code>lua_tointeger</code></a> returns 0. |
| 4384 | 4333 | |
| 4385 | 4334 | |
| @@ -4430,7 +4379,7 @@ will be valid after the corresponding value is removed from the stack. · 44 unmodified lines | ||
| 4430 | 4379 | Converts the Lua value at the given acceptable index |
| 4431 | 4380 | to the C type <a href="#lua_Number"><code>lua_Number</code></a> (see <a href="#lua_Number"><code>lua_Number</code></a>). |
| 4432 | 4381 | The Lua value must be a number or a string convertible to a number |
| 4433 | −(see <a href="#2.2.1">§2.2.1</a>); | |
| 4382 | +(see <a href="#3.4.2">§3.4.2</a>); | |
| 4434 | 4383 | otherwise, <a href="#lua_tonumber"><code>lua_tonumber</code></a> returns 0. |
| 4435 | 4384 | |
| 4436 | 4385 | |
| @@ -4596,7 +4545,7 @@ and pushes them onto the stack <code>to</code>. · 159 unmodified lines | ||
| 4596 | 4545 | |
| 4597 | 4546 | <p> |
| 4598 | 4547 | This function is equivalent to <a href="#lua_yieldk"><code>lua_yieldk</code></a>, |
| 4599 | −but it has no continuation (see <a href="#3.7">§3.7</a>). | |
| 4548 | +but it has no continuation (see <a href="#4.7">§4.7</a>). | |
| 4600 | 4549 | Therefore, when the thread resumes, |
| 4601 | 4550 | it returns to the function that called |
| 4602 | 4551 | the function calling <code>lua_yield</code>. |
| @@ -4631,7 +4580,7 @@ that are passed as results to <a href="#lua_resume"><code>lua_resume</code></a>. · 28 unmodified lines | ||
| 4631 | 4580 | <p> |
| 4632 | 4581 | When the coroutine is resumed again, |
| 4633 | 4582 | Lua calls the given continuation function <code>k</code> to continue |
| 4634 | −the execution of the C function that yielded (see <a href="#3.7">§3.7</a>). | |
| 4583 | +the execution of the C function that yielded (see <a href="#4.7">§4.7</a>). | |
| 4635 | 4584 | This continuation function receives the same stack |
| 4636 | 4585 | from the previous function, |
| 4637 | 4586 | with the results removed and |
| @@ -4646,7 +4595,7 @@ by calling <a href="#lua_getctx"><code>lua_getctx</code></a>. · 8 unmodified lines | ||
| 4646 | 4595 | |
| 4647 | 4596 | |
| 4648 | 4597 | |
| 4649 | −<h2>3.9 - <a name="3.9">The Debug Interface</a></h2> | |
| 4598 | +<h2>4.9 - <a name="4.9">The Debug Interface</a></h2> | |
| 4650 | 4599 | |
| 4651 | 4600 | <p> |
| 4652 | 4601 | Lua has no built-in debugging facilities. |
| @@ -4830,7 +4779,7 @@ you can write the following code: · 177 unmodified lines | ||
| 4830 | 4779 | |
| 4831 | 4780 | <pre> |
| 4832 | 4781 | lua_Debug ar; |
| 4833 | − lua_getfield(L, LUA_ENVIRONINDEX, "f"); /* get global 'f' */ | |
| 4782 | + lua_getglobal(L, "f"); /* get global 'f' */ | |
| 4834 | 4783 | lua_getinfo(L, ">S", &ar); |
| 4835 | 4784 | printf("%d\n", ar.linedefined); |
| 4836 | 4785 | </pre> |
| @@ -5126,7 +5075,7 @@ TO BE DONE!! · 289 unmodified lines | ||
| 5126 | 5075 | |
| 5127 | 5076 | |
| 5128 | 5077 | |
| 5129 | −<h1>4 - <a name="4">The Auxiliary Library</a></h1> | |
| 5078 | +<h1>5 - <a name="5">The Auxiliary Library</a></h1> | |
| 5130 | 5079 | |
| 5131 | 5080 | <p> |
| 5132 | 5081 | |
| @@ -5150,6 +5099,14 @@ top of the basic API, · 17 unmodified lines | ||
| 5150 | 5099 | and so they provide nothing that cannot be done with that API. |
| 5151 | 5100 | |
| 5152 | 5101 | |
| 5102 | +<p> | |
| 5103 | +Several functions in the auxiliary library use internally some | |
| 5104 | +extra stack slots. | |
| 5105 | +When a function in the auxiliary library uses less than five slots, | |
| 5106 | +it does not check the stack size; | |
| 5107 | +it simply assumes that there are enough slots. | |
| 5108 | + | |
| 5109 | + | |
| 5153 | 5110 | <p> |
| 5154 | 5111 | Several functions in the auxiliary library are used to |
| 5155 | 5112 | check C function arguments. |
| @@ -5164,7 +5121,7 @@ always throw an error if the check is not satisfied. · 8 unmodified lines | ||
| 5164 | 5121 | |
| 5165 | 5122 | |
| 5166 | 5123 | |
| 5167 | −<h2>4.1 - <a name="4.1">Functions and Types</a></h2> | |
| 5124 | +<h2>5.1 - <a name="5.1">Functions and Types</a></h2> | |
| 5168 | 5125 | |
| 5169 | 5126 | <p> |
| 5170 | 5127 | Here we list all functions and types from the auxiliary library |
| @@ -5192,7 +5149,7 @@ Adds the character <code>c</code> to the buffer <code>B</code> · 21 unmodified lines | ||
| 5192 | 5149 | Adds the string pointed to by <code>s</code> with length <code>l</code> to |
| 5193 | 5150 | the buffer <code>B</code> |
| 5194 | 5151 | (see <a href="#luaL_Buffer"><code>luaL_Buffer</code></a>). |
| 5195 | −The string may contain embedded zeros. | |
| 5152 | +The string can contain embedded zeros. | |
| 5196 | 5153 | |
| 5197 | 5154 | |
| 5198 | 5155 | |
| @@ -5219,7 +5176,7 @@ buffer area (see <a href="#luaL_prepbuffer"><code>luaL_prepbuffer</code></a>). · 20 unmodified lines | ||
| 5219 | 5176 | Adds the zero-terminated string pointed to by <code>s</code> |
| 5220 | 5177 | to the buffer <code>B</code> |
| 5221 | 5178 | (see <a href="#luaL_Buffer"><code>luaL_Buffer</code></a>). |
| 5222 | −The string may not contain embedded zeros. | |
| 5179 | +The string should not contain embedded zeros. | |
| 5223 | 5180 | |
| 5224 | 5181 | |
| 5225 | 5182 | |
| @@ -5661,9 +5618,9 @@ Pushes the resulting string on the stack and returns it. · 435 unmodified lines | ||
| 5661 | 5618 | <p> |
| 5662 | 5619 | Returns the "length" of the value at the given acceptable index |
| 5663 | 5620 | as a number; |
| 5664 | −it is equivalent to the '<code>#</code>' operator in Lua (see <a href="#2.5.5">§2.5.5</a>). | |
| 5621 | +it is equivalent to the '<code>#</code>' operator in Lua (see <a href="#3.4.6">§3.4.6</a>). | |
| 5665 | 5622 | Raises an error if the result of the operation is not a number. |
| 5666 | −(This only may happen through metamethods.) | |
| 5623 | +(This only can happen through metamethods.) | |
| 5667 | 5624 | |
| 5668 | 5625 | |
| 5669 | 5626 | |
| @@ -5769,7 +5726,7 @@ with <code>tname</code> in the registry. · 99 unmodified lines | ||
| 5769 | 5726 | Creates a new Lua state. |
| 5770 | 5727 | It calls <a href="#lua_newstate"><code>lua_newstate</code></a> with an |
| 5771 | 5728 | allocator based on the standard C <code>realloc</code> function |
| 5772 | −and then sets a panic function (see <a href="#3.6">§3.6</a>) that prints | |
| 5729 | +and then sets a panic function (see <a href="#4.6">§4.6</a>) that prints | |
| 5773 | 5730 | an error message to the standard error output in case of fatal |
| 5774 | 5731 | errors. |
| 5775 | 5732 | |
| @@ -5782,8 +5739,54 @@ or <code>NULL</code> if there is a memory allocation error. · 6 unmodified lines | ||
| 5782 | 5739 | |
| 5783 | 5740 | |
| 5784 | 5741 | |
| 5742 | +<hr><h3><a name="luaL_openlib"><code>luaL_openlib</code></a></h3><p> | |
| 5743 | +<span class="apii">[-(nup + (0|1)), +1, <em>e</em>]</span> | |
| 5744 | +<pre>void luaL_openlib (lua_State *L, | |
| 5745 | + const char *libname, | |
| 5746 | + const luaL_Reg *l, | |
| 5747 | + int nup);</pre> | |
| 5748 | + | |
| 5749 | +<p> | |
| 5750 | +Opens a library. | |
| 5751 | + | |
| 5752 | + | |
| 5753 | +<p> | |
| 5754 | +When called with <code>libname</code> equal to <code>NULL</code>, | |
| 5755 | +it simply registers all functions in the array <code>l</code> | |
| 5756 | +(see <a href="#luaL_Reg"><code>luaL_Reg</code></a>) into the table on the top of the stack. | |
| 5757 | +The pointer <code>l</code> may be <code>NULL</code>, | |
| 5758 | +representing an empty list. | |
| 5759 | + | |
| 5760 | + | |
| 5761 | +<p> | |
| 5762 | +When called with a non-null <code>libname</code>, | |
| 5763 | +<code>luaL_openlib</code> creates a new table <code>t</code>, | |
| 5764 | +sets it as the value of the global variable <code>libname</code>, | |
| 5765 | +sets it as the value of <code>package.loaded[libname]</code>, | |
| 5766 | +and registers on it all functions in the list <code>l</code>. | |
| 5767 | +If there is a table in <code>package.loaded[libname]</code> or | |
| 5768 | +in global variable <code>libname</code>, | |
| 5769 | +reuses this table instead of creating a new one. | |
| 5770 | + | |
| 5771 | + | |
| 5772 | +<p> | |
| 5773 | +In any case the function leaves the table | |
| 5774 | +on the top of the stack. | |
| 5775 | + | |
| 5776 | + | |
| 5777 | +<p> | |
| 5778 | +When <code>nup</code> is not zero, | |
| 5779 | +all functions are created sharing <code>nup</code> upvalues, | |
| 5780 | +which must be previously pushed on the stack | |
| 5781 | +(on top of the library table, if present). | |
| 5782 | +These values are popped from the stack after the registration. | |
| 5783 | + | |
| 5784 | + | |
| 5785 | + | |
| 5786 | + | |
| 5787 | + | |
| 5785 | 5788 | <hr><h3><a name="luaL_openlibs"><code>luaL_openlibs</code></a></h3><p> |
| 5786 | −<span class="apii">[-0, +0, <em>m</em>]</span> | |
| 5789 | +<span class="apii">[-0, +0, <em>e</em>]</span> | |
| 5787 | 5790 | <pre>void luaL_openlibs (lua_State *L);</pre> |
| 5788 | 5791 | |
| 5789 | 5792 | <p> |
| @@ -5960,7 +5963,7 @@ from any reference returned by <a href="#luaL_ref"><code>luaL_ref</code></a>. · 170 unmodified lines | ||
| 5960 | 5963 | |
| 5961 | 5964 | <p> |
| 5962 | 5965 | Type for arrays of functions to be registered by |
| 5963 | −<a href="#luaL_register"><code>luaL_register</code></a>. | |
| 5966 | +<a href="#luaL_openlib"><code>luaL_openlib</code></a>. | |
| 5964 | 5967 | <code>name</code> is the function name and <code>func</code> is a pointer to |
| 5965 | 5968 | the function. |
| 5966 | 5969 | Any array of <a href="#luaL_Reg"><code>luaL_Reg</code></a> must end with an sentinel entry |
| @@ -5977,31 +5980,8 @@ in which both <code>name</code> and <code>func</code> are <code>NULL</code>. · 10 unmodified lines | ||
| 5977 | 5980 | const luaL_Reg *l);</pre> |
| 5978 | 5981 | |
| 5979 | 5982 | <p> |
| 5980 | −Opens a library. | |
| 5981 | − | |
| 5982 | − | |
| 5983 | −<p> | |
| 5984 | −When called with <code>libname</code> equal to <code>NULL</code>, | |
| 5985 | −it simply registers all functions in the array <code>l</code> | |
| 5986 | −(see <a href="#luaL_Reg"><code>luaL_Reg</code></a>) into the table on the top of the stack. | |
| 5987 | −The pointer <code>l</code> may be <code>NULL</code>, | |
| 5988 | −representing an empty list. | |
| 5989 | − | |
| 5990 | − | |
| 5991 | −<p> | |
| 5992 | −When called with a non-null <code>libname</code>, | |
| 5993 | −<code>luaL_register</code> creates a new table <code>t</code>, | |
| 5994 | −sets it as the value of the global variable <code>libname</code>, | |
| 5995 | −sets it as the value of <code>package.loaded[libname]</code>, | |
| 5996 | −and registers on it all functions in the list <code>l</code>. | |
| 5997 | −If there is a table in <code>package.loaded[libname]</code> or in | |
| 5998 | −variable <code>libname</code>, | |
| 5999 | −reuses this table instead of creating a new one. | |
| 6000 | − | |
| 6001 | − | |
| 6002 | −<p> | |
| 6003 | −In any case the function leaves the table | |
| 6004 | −on the top of the stack. | |
| 5983 | +This macro is equivalent to calling <a href="#luaL_openlib"><code>luaL_openlib</code></a> | |
| 5984 | +with no upvalues. | |
| 6005 | 5985 | |
| 6006 | 5986 | |
| 6007 | 5987 | |
| @@ -6134,7 +6114,7 @@ This function is used to build a prefix for error messages. · 126 unmodified lines | ||
| 6134 | 6114 | |
| 6135 | 6115 | |
| 6136 | 6116 | |
| 6137 | −<h1>5 - <a name="5">Standard Libraries</a></h1> | |
| 6117 | +<h1>6 - <a name="6">Standard Libraries</a></h1> | |
| 6138 | 6118 | |
| 6139 | 6119 | <p> |
| 6140 | 6120 | The standard Lua libraries provide useful functions |
| @@ -6200,7 +6180,7 @@ e.g., by using <a href="#lua_call"><code>lua_call</code></a>. · 59 unmodified lines | ||
| 6200 | 6180 | |
| 6201 | 6181 | |
| 6202 | 6182 | |
| 6203 | −<h2>5.1 - <a name="5.1">Basic Functions</a></h2> | |
| 6183 | +<h2>6.1 - <a name="6.1">Basic Functions</a></h2> | |
| 6204 | 6184 | |
| 6205 | 6185 | <p> |
| 6206 | 6186 | The basic library provides some core functions to Lua. |
| @@ -6266,13 +6246,13 @@ Returns <b>true</b> if the step finished a collection cycle. · 59 unmodified lines | ||
| 6266 | 6246 | |
| 6267 | 6247 | <li><b>"setpause":</b> |
| 6268 | 6248 | sets <code>arg</code> as the new value for the <em>pause</em> of |
| 6269 | −the collector (see <a href="#2.10">§2.10</a>). | |
| 6249 | +the collector (see <a href="#2.5">§2.5</a>). | |
| 6270 | 6250 | Returns the previous value for <em>pause</em>. |
| 6271 | 6251 | </li> |
| 6272 | 6252 | |
| 6273 | 6253 | <li><b>"setstepmul":</b> |
| 6274 | 6254 | sets <code>arg</code> as the new value for the <em>step multiplier</em> of |
| 6275 | −the collector (see <a href="#2.10">§2.10</a>). | |
| 6255 | +the collector (see <a href="#2.5">§2.5</a>). | |
| 6276 | 6256 | Returns the previous value for <em>step</em>. |
| 6277 | 6257 | </li> |
| 6278 | 6258 | |
| @@ -6321,7 +6301,7 @@ to the message. · 42 unmodified lines | ||
| 6321 | 6301 | <p> |
| 6322 | 6302 | <hr><h3><a name="pdf-_G"><code>_G</code></a></h3> |
| 6323 | 6303 | A global variable (not a function) that |
| 6324 | −holds the global environment (so that <code>_G._G = _G</code>). | |
| 6304 | +holds the global environment (see <a href="#2.2">§2.2</a>). | |
| 6325 | 6305 | Lua itself does not use this variable; |
| 6326 | 6306 | changing its value does not affect any environment, |
| 6327 | 6307 | nor vice-versa. |
| @@ -6343,31 +6323,6 @@ Otherwise, returns the metatable of the given object. · 15 unmodified lines | ||
| 6343 | 6323 | |
| 6344 | 6324 | |
| 6345 | 6325 | |
| 6346 | −<p> | |
| 6347 | −<hr><h3><a name="pdf-ipairs"><code>ipairs (t)</code></a></h3> | |
| 6348 | − | |
| 6349 | − | |
| 6350 | −<p> | |
| 6351 | −If <code>t</code> has a metamethod <code>__ipairs</code>, | |
| 6352 | −calls it with <code>t</code> as argument and returns the first three | |
| 6353 | −results from the call. | |
| 6354 | − | |
| 6355 | − | |
| 6356 | −<p> | |
| 6357 | −Otherwise, | |
| 6358 | −returns three values: an iterator function, the table <code>t</code>, and 0, | |
| 6359 | −so that the construction | |
| 6360 | − | |
| 6361 | −<pre> | |
| 6362 | − for i,v in ipairs(t) do <em>body</em> end | |
| 6363 | −</pre><p> | |
| 6364 | −will iterate over the pairs (<code>1,t[1]</code>), (<code>2,t[2]</code>), ···, | |
| 6365 | −up to the length of the table, | |
| 6366 | −as defined by the length operator (see <a href="#2.5.5">§2.5.5</a>). | |
| 6367 | − | |
| 6368 | − | |
| 6369 | − | |
| 6370 | − | |
| 6371 | 6326 | <p> |
| 6372 | 6327 | <hr><h3><a name="pdf-load"><code>load (ld [, source [, mode]])</code></a></h3> |
| 6373 | 6328 | |
| @@ -6392,12 +6347,15 @@ If <code>ld</code> is a string, the chunk is this string. · 18 unmodified lines | ||
| 6392 | 6347 | If there are no errors, |
| 6393 | 6348 | returns the compiled chunk as a function; |
| 6394 | 6349 | otherwise, returns <b>nil</b> plus the error message. |
| 6395 | −The environment of the returned function is the global environment. | |
| 6350 | +If the resulting function has upvalues, | |
| 6351 | +the first upvalue is set to the value of the global environment | |
| 6352 | +(When loading main chunks, | |
| 6353 | +this upvalue will be the <code>_ENV</code> variable (see <a href="#2.2">§2.2</a>).) | |
| 6396 | 6354 | |
| 6397 | 6355 | |
| 6398 | 6356 | <p> |
| 6399 | 6357 | <code>source</code> is used as the source of the chunk for error messages |
| 6400 | −and debug information (see <a href="#3.9">§3.9</a>). | |
| 6358 | +and debug information (see <a href="#4.9">§4.9</a>). | |
| 6401 | 6359 | When absent, |
| 6402 | 6360 | it defaults to "<code>=(load)</code>". |
| 6403 | 6361 | |
| @@ -6418,8 +6376,9 @@ The default is "<code>bt</code>". · 14 unmodified lines | ||
| 6418 | 6376 | |
| 6419 | 6377 | <p> |
| 6420 | 6378 | This function is similar to <a href="#pdf-load"><code>load</code></a>, |
| 6421 | −but sets <code>env</code> as the environment | |
| 6379 | +but sets <code>env</code> as the value of the first upvalue | |
| 6422 | 6380 | of the created function in case of success. |
| 6381 | +(Usually this first upvalue will be <code>_ENV</code> (see <a href="#2.2">§2.2</a>).) | |
| 6423 | 6382 | The parameters after <code>env</code> are similar to those of <a href="#pdf-load"><code>load</code></a>, too. |
| 6424 | 6383 | |
| 6425 | 6384 | |
| @@ -6486,7 +6445,7 @@ you can use <code>next(t)</code> to check whether a table is empty. · 60 unmodified lines | ||
| 6486 | 6445 | The order in which the indices are enumerated is not specified, |
| 6487 | 6446 | <em>even for numeric indices</em>. |
| 6488 | 6447 | (To traverse a table in numeric order, |
| 6489 | −use a numerical <b>for</b> or the <a href="#pdf-ipairs"><code>ipairs</code></a> function.) | |
| 6448 | +use a numerical <b>for</b>.) | |
| 6490 | 6449 | |
| 6491 | 6450 | |
| 6492 | 6451 | <p> |
| @@ -6641,7 +6600,7 @@ In bases above 10, the letter '<code>A</code>' (in either upper or lower ca · 148 unmodified lines | ||
| 6641 | 6600 | represents 10, '<code>B</code>' represents 11, and so forth, |
| 6642 | 6601 | with '<code>Z</code>' representing 35. |
| 6643 | 6602 | In base 10 (the default), the number can have a decimal part, |
| 6644 | −as well as an optional exponent part (see <a href="#2.1">§2.1</a>). | |
| 6603 | +as well as an optional exponent part (see <a href="#3.1">§3.1</a>). | |
| 6645 | 6604 | In other bases, only unsigned integers are accepted. |
| 6646 | 6605 | |
| 6647 | 6606 | |
| @@ -6703,12 +6662,12 @@ except that it sets a new error handler <code>err</code>. · 55 unmodified lines | ||
| 6703 | 6662 | |
| 6704 | 6663 | |
| 6705 | 6664 | |
| 6706 | −<h2>5.2 - <a name="5.2">Coroutine Manipulation</a></h2> | |
| 6665 | +<h2>6.2 - <a name="6.2">Coroutine Manipulation</a></h2> | |
| 6707 | 6666 | |
| 6708 | 6667 | <p> |
| 6709 | 6668 | The operations related to coroutines comprise a sub-library of |
| 6710 | 6669 | the basic library and come inside the table <a name="pdf-coroutine"><code>coroutine</code></a>. |
| 6711 | −See <a href="#2.11">§2.11</a> for a general description of coroutines. | |
| 6670 | +See <a href="#2.6">§2.6</a> for a general description of coroutines. | |
| 6712 | 6671 | |
| 6713 | 6672 | |
| 6714 | 6673 | <p> |
| @@ -6813,7 +6772,7 @@ Any arguments to <code>yield</code> are passed as extra results to <code>resume< · 98 unmodified lines | ||
| 6813 | 6772 | |
| 6814 | 6773 | |
| 6815 | 6774 | |
| 6816 | −<h2>5.3 - <a name="5.3">Modules</a></h2> | |
| 6775 | +<h2>6.3 - <a name="6.3">Modules</a></h2> | |
| 6817 | 6776 | |
| 6818 | 6777 | <p> |
| 6819 | 6778 | The package library provides basic |
| @@ -7194,7 +7153,7 @@ To be used as an option to function <a href="#pdf-module"><code>module</code></a · 374 unmodified lines | ||
| 7194 | 7153 | |
| 7195 | 7154 | |
| 7196 | 7155 | |
| 7197 | −<h2>5.4 - <a name="5.4">String Manipulation</a></h2> | |
| 7156 | +<h2>6.4 - <a name="6.4">String Manipulation</a></h2> | |
| 7198 | 7157 | |
| 7199 | 7158 | <p> |
| 7200 | 7159 | This library provides generic functions for string manipulation, |
| @@ -7377,6 +7336,7 @@ replaced by a replacement string specified by <code>repl</code>, · 176 unmodified lines | ||
| 7377 | 7336 | which can be a string, a table, or a function. |
| 7378 | 7337 | <code>gsub</code> also returns, as its second value, |
| 7379 | 7338 | the total number of matches that occurred. |
| 7339 | +The name <code>gsub</code> comes from <em>Global SUBstitution</em>. | |
| 7380 | 7340 | |
| 7381 | 7341 | |
| 7382 | 7342 | <p> |
| @@ -7517,7 +7477,7 @@ The definition of what a lowercase letter is depends on the current locale. · 134 unmodified lines | ||
| 7517 | 7477 | |
| 7518 | 7478 | |
| 7519 | 7479 | |
| 7520 | −<h3>5.4.1 - <a name="5.4.1">Patterns</a></h3> | |
| 7480 | +<h3>6.4.1 - <a name="6.4.1">Patterns</a></h3> | |
| 7521 | 7481 | |
| 7522 | 7482 | |
| 7523 | 7483 | <h4>Character Class:</h4><p> |
| @@ -7552,8 +7512,6 @@ represents the character <em>x</em> itself. · 28 unmodified lines | ||
| 7552 | 7512 | |
| 7553 | 7513 | <li><b><code>%x</code>:</b> represents all hexadecimal digits.</li> |
| 7554 | 7514 | |
| 7555 | −<li><b><code>%z</code>:</b> represents the character with representation 0.</li> | |
| 7556 | − | |
| 7557 | 7515 | <li><b><code>%<em>x</em></code>:</b> (where <em>x</em> is any non-alphanumeric character) |
| 7558 | 7516 | represents the character <em>x</em>. |
| 7559 | 7517 | This is the standard way to escape the magic characters. |
| @@ -7702,9 +7660,6 @@ For instance, if we apply the pattern <code>"()aa()"</code> on the · 142 unmodified lines | ||
| 7702 | 7660 | string <code>"flaaap"</code>, there will be two captures: 3 and 5. |
| 7703 | 7661 | |
| 7704 | 7662 | |
| 7705 | −<p> | |
| 7706 | −A pattern cannot contain embedded zeros. Use <code>%z</code> instead. | |
| 7707 | − | |
| 7708 | 7663 | |
| 7709 | 7664 | |
| 7710 | 7665 | |
| @@ -7714,8 +7669,7 @@ A pattern cannot contain embedded zeros. Use <code>%z</code> instead. · 3 unmodified lines | ||
| 7714 | 7669 | |
| 7715 | 7670 | |
| 7716 | 7671 | |
| 7717 | − | |
| 7718 | −<h2>5.5 - <a name="5.5">Table Manipulation</a></h2><p> | |
| 7672 | +<h2>6.5 - <a name="6.5">Table Manipulation</a></h2><p> | |
| 7719 | 7673 | This library provides generic functions for table manipulation. |
| 7720 | 7674 | It provides all its functions inside the table <a name="pdf-table"><code>table</code></a>. |
| 7721 | 7675 | |
| @@ -7747,7 +7701,7 @@ If <code>i</code> is greater than <code>j</code>, returns the empty string. · 25 unmodified lines | ||
| 7747 | 7701 | Inserts element <code>value</code> at position <code>pos</code> in <code>table</code>, |
| 7748 | 7702 | shifting up other elements to open space, if necessary. |
| 7749 | 7703 | The default value for <code>pos</code> is <code>n+1</code>, |
| 7750 | −where <code>n</code> is the length of the table (see <a href="#2.5.5">§2.5.5</a>), | |
| 7704 | +where <code>n</code> is the length of the table (see <a href="#3.4.6">§3.4.6</a>), | |
| 7751 | 7705 | so that a call <code>table.insert(t,x)</code> inserts <code>x</code> at the end |
| 7752 | 7706 | of table <code>t</code>. |
| 7753 | 7707 | |
| @@ -7788,9 +7742,9 @@ Sorts table elements in a given order, <em>in-place</em>, · 34 unmodified lines | ||
| 7788 | 7742 | from <code>table[1]</code> to <code>table[n]</code>, |
| 7789 | 7743 | where <code>n</code> is the length of the table. |
| 7790 | 7744 | If <code>comp</code> is given, |
| 7791 | −then it must be a function that receives two table elements, | |
| 7792 | −and returns true | |
| 7793 | −when the first is less than the second | |
| 7745 | +then it must be a function that receives two table elements | |
| 7746 | +and returns true when the first element must come | |
| 7747 | +before the second in the final order | |
| 7794 | 7748 | (so that <code>not comp(a[i+1],a[i])</code> will be true after the sort). |
| 7795 | 7749 | If <code>comp</code> is not given, |
| 7796 | 7750 | then the standard Lua operator <code><</code> is used instead. |
| @@ -7815,7 +7769,7 @@ This function is equivalent to · 18 unmodified lines | ||
| 7815 | 7769 | except that the above code can be written only for a fixed number |
| 7816 | 7770 | of elements. |
| 7817 | 7771 | By default, <code>i</code> is 1 and <code>j</code> is the length of the list, |
| 7818 | −as defined by the length operator (see <a href="#2.5.5">§2.5.5</a>). | |
| 7772 | +as defined by the length operator (see <a href="#3.4.6">§3.4.6</a>). | |
| 7819 | 7773 | |
| 7820 | 7774 | |
| 7821 | 7775 | |
| @@ -7823,7 +7777,7 @@ as defined by the length operator (see <a href="#2.5.5">§2.5.5</a>). · 1 unmodified line | ||
| 7823 | 7777 | |
| 7824 | 7778 | |
| 7825 | 7779 | |
| 7826 | −<h2>5.6 - <a name="5.6">Mathematical Functions</a></h2> | |
| 7780 | +<h2>6.6 - <a name="6.6">Mathematical Functions</a></h2> | |
| 7827 | 7781 | |
| 7828 | 7782 | <p> |
| 7829 | 7783 | This library is an interface to the standard C math library. |
| @@ -8036,7 +7990,7 @@ the integral part of <code>x</code> and the fractional part of <code>x</code>. · 206 unmodified lines | ||
| 8036 | 7990 | |
| 8037 | 7991 | |
| 8038 | 7992 | <p> |
| 8039 | −The value of <em>pi</em>. | |
| 7993 | +The value of <em>π</em>. | |
| 8040 | 7994 | |
| 8041 | 7995 | |
| 8042 | 7996 | |
| @@ -8152,7 +8106,7 @@ Returns the hyperbolic tangent of <code>x</code>. · 109 unmodified lines | ||
| 8152 | 8106 | |
| 8153 | 8107 | |
| 8154 | 8108 | |
| 8155 | −<h2>5.7 - <a name="5.7">Bitwise operations</a></h2> | |
| 8109 | +<h2>6.7 - <a name="6.7">Bitwise operations</a></h2> | |
| 8156 | 8110 | |
| 8157 | 8111 | <p> |
| 8158 | 8112 | This library provides bitwise operations. |
| @@ -8202,29 +8156,28 @@ Returns the bitwise or of its operands. · 43 unmodified lines | ||
| 8202 | 8156 | |
| 8203 | 8157 | |
| 8204 | 8158 | <p> |
| 8205 | −<hr><h3><a name="pdf-bit.brotate"><code>bit.brotate (x, disp)</code></a></h3> | |
| 8159 | +<hr><h3><a name="pdf-bit.btest"><code>bit.btest (···)</code></a></h3> | |
| 8206 | 8160 | |
| 8207 | 8161 | |
| 8208 | 8162 | <p> |
| 8209 | −Returns the number <code>x</code> rotated <code>disp</code> bits to the left. | |
| 8210 | −The number <code>disp</code> may be any representable integer. | |
| 8163 | +Returns a boolean signaling | |
| 8164 | +whether the bitwise and of its operands is different from zero. | |
| 8165 | + | |
| 8166 | + | |
| 8211 | 8167 | |
| 8212 | 8168 | |
| 8213 | 8169 | <p> |
| 8214 | −For any valid displacement, | |
| 8215 | −the following identity holds: | |
| 8170 | +<hr><h3><a name="pdf-bit.bxor"><code>bit.bxor (···)</code></a></h3> | |
| 8216 | 8171 | |
| 8217 | −<pre> | |
| 8218 | − assert(bit.rotate(x, disp) == bit.rotate(x, disp % 32)) | |
| 8219 | −</pre><p> | |
| 8220 | −This allows you to consider that | |
| 8221 | −negative displacements rotate to the right. | |
| 8172 | + | |
| 8173 | +<p> | |
| 8174 | +Returns the bitwise exclusive or of its operands. | |
| 8222 | 8175 | |
| 8223 | 8176 | |
| 8224 | 8177 | |
| 8225 | 8178 | |
| 8226 | 8179 | <p> |
| 8227 | −<hr><h3><a name="pdf-bit.bshift"><code>bit.bshift (x, disp)</code></a></h3> | |
| 8180 | +<hr><h3><a name="pdf-bit.lshift"><code>bit.lshift (x, disp)</code></a></h3> | |
| 8228 | 8181 | |
| 8229 | 8182 | |
| 8230 | 8183 | <p> |
| @@ -8243,42 +8196,82 @@ For positive displacements, · 12 unmodified lines | ||
| 8243 | 8196 | the following equality holds: |
| 8244 | 8197 | |
| 8245 | 8198 | <pre> |
| 8246 | − assert(bit.bshift(b, disp) == (b * 2^disp) % 2^32) | |
| 8199 | + assert(bit.lshift(b, disp) == (b * 2^disp) % 2^32) | |
| 8247 | 8200 | </pre> |
| 8248 | 8201 | |
| 8202 | + | |
| 8203 | + | |
| 8249 | 8204 | <p> |
| 8250 | −For negative displacements, | |
| 8251 | −the following equality holds: | |
| 8205 | +<hr><h3><a name="pdf-bit.rol"><code>bit.rol (x, disp)</code></a></h3> | |
| 8206 | + | |
| 8207 | + | |
| 8208 | +<p> | |
| 8209 | +Returns the number <code>x</code> rotated <code>disp</code> bits to the left. | |
| 8210 | +The number <code>disp</code> may be any representable integer. | |
| 8211 | + | |
| 8212 | + | |
| 8213 | +<p> | |
| 8214 | +For any valid displacement, | |
| 8215 | +the following identity holds: | |
| 8252 | 8216 | |
| 8253 | 8217 | <pre> |
| 8254 | − assert(bit.bshift(b, disp) == math.floor(b * 2^disp)) | |
| 8255 | −</pre> | |
| 8218 | + assert(bit.rol(x, disp) == bit.rol(x, disp % 32)) | |
| 8219 | +</pre><p> | |
| 8220 | +In particular, | |
| 8221 | +negative displacements rotate to the right. | |
| 8222 | + | |
| 8223 | + | |
| 8224 | + | |
| 8256 | 8225 | |
| 8257 | 8226 | <p> |
| 8258 | −This shift operation is what is called logical shift. | |
| 8259 | −For an arithmetic shift, | |
| 8260 | −you should use the arithmetic operators. | |
| 8227 | +<hr><h3><a name="pdf-bit.ror"><code>bit.ror (x, disp)</code></a></h3> | |
| 8261 | 8228 | |
| 8262 | 8229 | |
| 8230 | +<p> | |
| 8231 | +Returns the number <code>x</code> rotated <code>disp</code> bits to the right. | |
| 8232 | +The number <code>disp</code> may be any representable integer. | |
| 8263 | 8233 | |
| 8264 | 8234 | |
| 8265 | 8235 | <p> |
| 8266 | −<hr><h3><a name="pdf-bit.btest"><code>bit.btest (···)</code></a></h3> | |
| 8236 | +For any valid displacement, | |
| 8237 | +the following identity holds: | |
| 8238 | + | |
| 8239 | +<pre> | |
| 8240 | + assert(bit.ror(x, disp) == bit.ror(x, disp % 32)) | |
| 8241 | +</pre><p> | |
| 8242 | +In particular, | |
| 8243 | +negative displacements rotate to the left. | |
| 8244 | + | |
| 8245 | + | |
| 8267 | 8246 | |
| 8268 | 8247 | |
| 8269 | 8248 | <p> |
| 8270 | −Returns a boolean signaling | |
| 8271 | −whether the bitwise and of its operands is different from zero. | |
| 8249 | +<hr><h3><a name="pdf-bit.rshift"><code>bit.rshift (x, disp)</code></a></h3> | |
| 8272 | 8250 | |
| 8273 | 8251 | |
| 8252 | +<p> | |
| 8253 | +Returns the number <code>x</code> shifted <code>disp</code> bits to the right. | |
| 8254 | +The number <code>disp</code> may be any representable integer. | |
| 8255 | +Negative displacements shift to the left. | |
| 8256 | +In any direction, vacant bits are filled with zeros. | |
| 8257 | +In particular, | |
| 8258 | +displacements with absolute values higher than | |
| 8259 | +the total number of bits in the representation of <code>x</code> | |
| 8260 | +result in zero (all bits are shifted out). | |
| 8274 | 8261 | |
| 8275 | 8262 | |
| 8276 | 8263 | <p> |
| 8277 | −<hr><h3><a name="pdf-bit.bxor"><code>bit.bxor (···)</code></a></h3> | |
| 8264 | +For positive displacements, | |
| 8265 | +the following equality holds: | |
| 8278 | 8266 | |
| 8267 | +<pre> | |
| 8268 | + assert(bit.rshift(b, disp) == math.floor(b * 2^-disp)) | |
| 8269 | +</pre> | |
| 8279 | 8270 | |
| 8280 | 8271 | <p> |
| 8281 | −Returns the bitwise exclusive or of its operands. | |
| 8272 | +This shift operation is what is called logical shift. | |
| 8273 | +For an arithmetic shift, | |
| 8274 | +you should use the arithmetic operators. | |
| 8282 | 8275 | |
| 8283 | 8276 | |
| 8284 | 8277 | |
| @@ -8286,7 +8279,7 @@ Returns the bitwise exclusive or of its operands. · 1 unmodified line | ||
| 8286 | 8279 | |
| 8287 | 8280 | |
| 8288 | 8281 | |
| 8289 | −<h2>5.8 - <a name="5.8">Input and Output Facilities</a></h2> | |
| 8282 | +<h2>6.8 - <a name="6.8">Input and Output Facilities</a></h2> | |
| 8290 | 8283 | |
| 8291 | 8284 | <p> |
| 8292 | 8285 | The I/O library provides two different styles for file manipulation. |
| @@ -8362,7 +8355,7 @@ instead of returning an error code. · 69 unmodified lines | ||
| 8362 | 8355 | |
| 8363 | 8356 | |
| 8364 | 8357 | <p> |
| 8365 | −<hr><h3><a name="pdf-io.lines"><code>io.lines ([filename])</code></a></h3> | |
| 8358 | +<hr><h3><a name="pdf-io.lines"><code>io.lines ([filename] [, keepNL])</code></a></h3> | |
| 8366 | 8359 | |
| 8367 | 8360 | |
| 8368 | 8361 | <p> |
| @@ -8387,6 +8380,11 @@ that is, it iterates over the lines of the default input file. · 18 unmodified lines | ||
| 8387 | 8380 | In this case it does not close the file when the loop ends. |
| 8388 | 8381 | |
| 8389 | 8382 | |
| 8383 | +<p> | |
| 8384 | +By default, <code>lines</code> removes the newline at the end of each line. | |
| 8385 | +If <code>keepNL</code> is <b>true</b>, it will keep the newlines. | |
| 8386 | + | |
| 8387 | + | |
| 8390 | 8388 | |
| 8391 | 8389 | |
| 8392 | 8390 | <p> |
| @@ -8521,7 +8519,7 @@ Saves any written data to <code>file</code>. · 128 unmodified lines | ||
| 8521 | 8519 | |
| 8522 | 8520 | |
| 8523 | 8521 | <p> |
| 8524 | −<hr><h3><a name="pdf-file:lines"><code>file:lines ()</code></a></h3> | |
| 8522 | +<hr><h3><a name="pdf-file:lines"><code>file:lines ([keepNL])</code></a></h3> | |
| 8525 | 8523 | |
| 8526 | 8524 | |
| 8527 | 8525 | <p> |
| @@ -8533,11 +8531,17 @@ Therefore, the construction · 5 unmodified lines | ||
| 8533 | 8531 | <pre> |
| 8534 | 8532 | for line in file:lines() do <em>body</em> end |
| 8535 | 8533 | </pre><p> |
| 8536 | −will iterate over all lines of the file. | |
| 8534 | +will iterate over all lines of the file, | |
| 8535 | +starting at the current position. | |
| 8537 | 8536 | (Unlike <a href="#pdf-io.lines"><code>io.lines</code></a>, this function does not close the file |
| 8538 | 8537 | when the loop ends.) |
| 8539 | 8538 | |
| 8540 | 8539 | |
| 8540 | +<p> | |
| 8541 | +By default, <code>lines</code> removes the newline at the end of each line. | |
| 8542 | +If <code>keepNL</code> is <b>true</b>, it will keep the newlines. | |
| 8543 | + | |
| 8544 | + | |
| 8541 | 8545 | |
| 8542 | 8546 | |
| 8543 | 8547 | <p> |
| @@ -8551,7 +8555,7 @@ For each format, · 7 unmodified lines | ||
| 8551 | 8555 | the function returns a string (or a number) with the characters read, |
| 8552 | 8556 | or <b>nil</b> if it cannot read data with the specified format. |
| 8553 | 8557 | When called without formats, |
| 8554 | −it uses a default format that reads the entire next line | |
| 8558 | +it uses a default format that reads the next line | |
| 8555 | 8559 | (see below). |
| 8556 | 8560 | |
| 8557 | 8561 | |
| @@ -8571,11 +8575,16 @@ On end of file, it returns the empty string. · 13 unmodified lines | ||
| 8571 | 8575 | </li> |
| 8572 | 8576 | |
| 8573 | 8577 | <li><b>"*l":</b> |
| 8574 | −reads the next line (skipping the end of line), | |
| 8578 | +reads the next line skipping the end of line, | |
| 8575 | 8579 | returning <b>nil</b> on end of file. |
| 8576 | 8580 | This is the default format. |
| 8577 | 8581 | </li> |
| 8578 | 8582 | |
| 8583 | +<li><b>"*L":</b> | |
| 8584 | +reads the next line keeping the end of line (if present), | |
| 8585 | +returning <b>nil</b> on end of file. | |
| 8586 | +</li> | |
| 8587 | + | |
| 8579 | 8588 | <li><b><em>number</em>:</b> |
| 8580 | 8589 | reads a string with up to this number of characters, |
| 8581 | 8590 | returning <b>nil</b> on end of file. |
| @@ -8678,7 +8687,7 @@ Otherwise it returns <b>nil</b> plus a string describing the error. · 96 unmodified lines | ||
| 8678 | 8687 | |
| 8679 | 8688 | |
| 8680 | 8689 | |
| 8681 | −<h2>5.9 - <a name="5.9">Operating System Facilities</a></h2> | |
| 8690 | +<h2>6.9 - <a name="6.9">Operating System Facilities</a></h2> | |
| 8682 | 8691 | |
| 8683 | 8692 | <p> |
| 8684 | 8693 | This library is implemented through table <a name="pdf-os"><code>os</code></a>. |
| @@ -8904,23 +8913,20 @@ which automatically removes the file when the program ends. · 219 unmodified lines | ||
| 8904 | 8913 | |
| 8905 | 8914 | |
| 8906 | 8915 | |
| 8907 | −<h2>5.10 - <a name="5.10">The Debug Library</a></h2> | |
| 8916 | +<h2>6.10 - <a name="6.10">The Debug Library</a></h2> | |
| 8908 | 8917 | |
| 8909 | 8918 | <p> |
| 8910 | 8919 | This library provides |
| 8911 | 8920 | the functionality of the debug interface to Lua programs. |
| 8912 | 8921 | You should exert care when using this library. |
| 8913 | −The functions provided here should be used exclusively for debugging | |
| 8914 | −and similar tasks, such as profiling. | |
| 8915 | −Please resist the temptation to use them as a | |
| 8916 | −usual programming tool: | |
| 8917 | −they can be very slow. | |
| 8918 | −Moreover, several of these functions | |
| 8919 | −violate some assumptions about Lua code | |
| 8922 | +Several of these functions | |
| 8923 | +violate basic assumptions about Lua code | |
| 8920 | 8924 | (e.g., that variables local to a function |
| 8921 | −cannot be accessed from outside or | |
| 8922 | −that userdata metatables cannot be changed by Lua code) | |
| 8925 | +cannot be accessed from outside; | |
| 8926 | +that userdata metatables cannot be changed by Lua code; | |
| 8927 | +that Lua programs do not crash) | |
| 8923 | 8928 | and therefore can compromise otherwise secure code. |
| 8929 | +Moreover, some functions in this library may be slow. | |
| 8924 | 8930 | |
| 8925 | 8931 | |
| 8926 | 8932 | <p> |
| @@ -9055,7 +9061,7 @@ or <b>nil</b> if it does not have a metatable. · 128 unmodified lines | ||
| 9055 | 9061 | |
| 9056 | 9062 | |
| 9057 | 9063 | <p> |
| 9058 | −Returns the registry table (see <a href="#3.5">§3.5</a>). | |
| 9064 | +Returns the registry table (see <a href="#4.5">§4.5</a>). | |
| 9059 | 9065 | |
| 9060 | 9066 | |
| 9061 | 9067 | |
| @@ -9217,7 +9223,7 @@ TO BE DONE!! · 155 unmodified lines | ||
| 9217 | 9223 | |
| 9218 | 9224 | |
| 9219 | 9225 | |
| 9220 | −<h1>6 - <a name="6">Lua Stand-alone</a></h1> | |
| 9226 | +<h1>7 - <a name="7">Lua Stand-alone</a></h1> | |
| 9221 | 9227 | |
| 9222 | 9228 | <p> |
| 9223 | 9229 | Although Lua has been designed as an extension language, |
| @@ -9268,7 +9274,7 @@ For instance, an invocation like · 44 unmodified lines | ||
| 9268 | 9274 | </pre><p> |
| 9269 | 9275 | will first set <code>a</code> to 1, then print the value of <code>a</code> (which is '<code>1</code>'), |
| 9270 | 9276 | and finally run the file <code>script.lua</code> with no arguments. |
| 9271 | −(Here <code>$</code> is the shell prompt. Your prompt may be different.) | |
| 9277 | +(Here <code>$</code> is the shell prompt. Your prompt can be different.) | |
| 9272 | 9278 | |
| 9273 | 9279 | |
| 9274 | 9280 | <p> |
| @@ -9352,7 +9358,7 @@ as in · 77 unmodified lines | ||
| 9352 | 9358 | #!/usr/local/bin/lua |
| 9353 | 9359 | </pre><p> |
| 9354 | 9360 | (Of course, |
| 9355 | −the location of the Lua interpreter may be different in your machine. | |
| 9361 | +the location of the Lua interpreter can be different in your machine. | |
| 9356 | 9362 | If <code>lua</code> is in your <code>PATH</code>, |
| 9357 | 9363 | then |
| 9358 | 9364 | |
| @@ -9363,10 +9369,10 @@ is a more portable solution.) · 4 unmodified lines | ||
| 9363 | 9369 | |
| 9364 | 9370 | |
| 9365 | 9371 | |
| 9366 | −<h1>7 - <a name="7">Incompatibilities with the Previous Version</a></h1> | |
| 9372 | +<h1>8 - <a name="8">Incompatibilities with the Previous Version</a></h1> | |
| 9367 | 9373 | |
| 9368 | 9374 | <p> |
| 9369 | −Here we list the incompatibilities that you may find when moving a program | |
| 9375 | +Here we list the incompatibilities that you can find when moving a program | |
| 9370 | 9376 | from Lua 5.1 to Lua 5.2. |
| 9371 | 9377 | You can avoid some incompatibilities compiling Lua with |
| 9372 | 9378 | appropriate options (see file <code>luaconf.h</code>). |
| @@ -9375,7 +9381,7 @@ all these compatibility options will be removed in the next version of Lua. · 2 unmodified lines | ||
| 9375 | 9381 | |
| 9376 | 9382 | |
| 9377 | 9383 | |
| 9378 | −<h2>7.1 - <a name="7.1">Changes in the Language</a></h2> | |
| 9384 | +<h2>8.1 - <a name="8.1">Changes in the Language</a></h2> | |
| 9379 | 9385 | <ul> |
| 9380 | 9386 | |
| 9381 | 9387 | <li> |
| @@ -9396,12 +9402,19 @@ Threads do not have individual environments. · 14 unmodified lines | ||
| 9396 | 9402 | All threads share a single fixed environment. |
| 9397 | 9403 | </li> |
| 9398 | 9404 | |
| 9405 | +<li> | |
| 9406 | +The event <em>tail return</em> in debug hooks was removed. | |
| 9407 | +Instead, tail calls generate a special new event, | |
| 9408 | +<em>tail call</em>, so that the debuger can know there will | |
| 9409 | +not be a corresponding return event. | |
| 9410 | +</li> | |
| 9411 | + | |
| 9399 | 9412 | </ul> |
| 9400 | 9413 | |
| 9401 | 9414 | |
| 9402 | 9415 | |
| 9403 | 9416 | |
| 9404 | −<h2>7.2 - <a name="7.2">Changes in the Libraries</a></h2> | |
| 9417 | +<h2>8.2 - <a name="8.2">Changes in the Libraries</a></h2> | |
| 9405 | 9418 | <ul> |
| 9406 | 9419 | |
| 9407 | 9420 | <li> |
| @@ -9412,9 +9425,13 @@ You must explicitly require it. · 4 unmodified lines | ||
| 9412 | 9425 | <li> |
| 9413 | 9426 | Functions <code>setfenv</code> and <code>getfenv</code> are deprecated. |
| 9414 | 9427 | To set the environment of a Lua function, |
| 9415 | −use lexical environments or the new function <a href="#pdf-loadin"><code>loadin</code></a>. | |
| 9416 | −(If you really need them, | |
| 9417 | −you may use their equivalents in the debug library.) | |
| 9428 | +use the variable <code>_ENV</code> or the new function <a href="#pdf-loadin"><code>loadin</code></a>. | |
| 9429 | +</li> | |
| 9430 | + | |
| 9431 | +<li> | |
| 9432 | +Function <code>ipairs</code> is deprecated. | |
| 9433 | +Use a numerical for loop instead, | |
| 9434 | +or write it in Lua. | |
| 9418 | 9435 | </li> |
| 9419 | 9436 | |
| 9420 | 9437 | <li> |
| @@ -9432,20 +9449,44 @@ Function <code>unpack</code> was moved into the table library · 11 unmodified lines | ||
| 9432 | 9449 | and therefore must be called as <a href="#pdf-table.unpack"><code>table.unpack</code></a>. |
| 9433 | 9450 | </li> |
| 9434 | 9451 | |
| 9452 | +<li> | |
| 9453 | +Character class <code>%z</code> in patterns is deprecated, | |
| 9454 | +as now patterns may contain '<code>\0</code>' as a regular character. | |
| 9455 | +</li> | |
| 9456 | + | |
| 9457 | +<li> | |
| 9458 | +Lua does not have bytecode verification anymore. | |
| 9459 | +So, all functions that load code | |
| 9460 | +(<a href="#pdf-load"><code>load</code></a>, <a href="#pdf-loadfile"><code>loadfile</code></a>, <a href="#pdf-loadstring"><code>loadstring</code></a>) | |
| 9461 | +are potentially insecure when loading untrusted binary data. | |
| 9462 | +(Actually, those functions were already insecure because | |
| 9463 | +of bugs in the verification algorithm.) | |
| 9464 | +When in doubt, | |
| 9465 | +use the <code>mode</code> argument in function <a href="#pdf-load"><code>load</code></a> | |
| 9466 | +to restrict it to loading textual chunks. | |
| 9467 | +</li> | |
| 9468 | + | |
| 9435 | 9469 | </ul> |
| 9436 | 9470 | |
| 9437 | 9471 | |
| 9438 | 9472 | |
| 9439 | 9473 | |
| 9440 | −<h2>7.3 - <a name="7.3">Changes in the API</a></h2> | |
| 9474 | +<h2>8.3 - <a name="8.3">Changes in the API</a></h2> | |
| 9441 | 9475 | <ul> |
| 9442 | 9476 | |
| 9443 | 9477 | <li> |
| 9444 | 9478 | Pseudoindex <code>LUA_GLOBALSINDEX</code> was removed. |
| 9445 | −You may use the pseudoindex <a href="#pdf-LUA_ENVIRONINDEX"><code>LUA_ENVIRONINDEX</code></a> instead, | |
| 9446 | −if the C function does not change its standard environment. | |
| 9447 | −Otherwise, you should get the global environment from the registry | |
| 9448 | −(see <a href="#3.5">§3.5</a>). | |
| 9479 | +You must get the global environment from the registry | |
| 9480 | +(see <a href="#4.5">§4.5</a>). | |
| 9481 | +</li> | |
| 9482 | + | |
| 9483 | +<li> | |
| 9484 | +Pseudoindex <code>LUA_ENVIRONINDEX</code> was removed. | |
| 9485 | +C functions do not have environments any more. | |
| 9486 | +Use an upvalue with a shared table if you need to keep | |
| 9487 | +shared state among several C functions. | |
| 9488 | +(You may use <a href="#luaL_openlib"><code>luaL_openlib</code></a> to open a C library | |
| 9489 | +with all functions sharing a common upvalue.) | |
| 9449 | 9490 | </li> |
121 more lines aren’t shown here.
| @@ -9,25 +9,31 @@ blockquote, .display { · 8 unmodified lines | ||
| 9 | 9 | color: black ; |
| 10 | 10 | padding: 8px ; |
| 11 | 11 | border: solid #a0a0a0 2px ; |
| 12 | − background-color: #EFEFFF ; | |
| 12 | + xbackground-color: #EFEFFF ; | |
| 13 | 13 | margin-left: 0px ; |
| 14 | 14 | } |
| 15 | 15 | |
| 16 | −.review { | |
| 17 | − color: red ; | |
| 18 | −} | |
| 19 | − | |
| 20 | 16 | .external { |
| 21 | 17 | padding-right: 15px; |
| 22 | 18 | background: transparent url(external.png) no-repeat center right; |
| 23 | 19 | } |
| 24 | 20 | |
| 25 | −tt, kbd { | |
| 21 | +tt, kbd, code { | |
| 26 | 22 | font-size: 120% ; |
| 27 | 23 | xcolor: black ; |
| 28 | 24 | xpadding: 4px ; |
| 29 | 25 | xbackground-color: #E0E0E0 ; |
| 30 | 26 | } |
| 27 | + | |
| 28 | +kbd { | |
| 29 | + color: black ; | |
| 30 | + background-color: #E8E8E8 ; | |
| 31 | +} | |
| 32 | + | |
| 33 | +.review { | |
| 34 | + color: red ; | |
| 35 | +} | |
| 36 | + | |
| 31 | 37 | </STYLE> |
| 32 | 38 | </HEAD> |
| 33 | 39 | |
| @@ -39,6 +45,11 @@ tt, kbd { · 5 unmodified lines | ||
| 39 | 45 | Welcome to Lua 5.2 |
| 40 | 46 | </H1> |
| 41 | 47 | |
| 48 | +<IMG SRC="alert.png" ALIGN="absbottom"> | |
| 49 | +<EM>This is a work version of Lua 5.2. | |
| 50 | +Everything may change in the final version.</EM> | |
| 51 | +<P> | |
| 52 | + | |
| 42 | 53 | <A HREF="#about">about</A> |
| 43 | 54 | · |
| 44 | 55 | <A HREF="#install">installation</A> |
| @@ -51,11 +62,6 @@ Welcome to Lua 5.2 · 6 unmodified lines | ||
| 51 | 62 | <HR> |
| 52 | 63 | <P> |
| 53 | 64 | |
| 54 | −<P> | |
| 55 | −<IMG SRC="alert.png" ALIGN="absbottom"> | |
| 56 | −<EM>This is a work version of Lua 5.2. | |
| 57 | −All details may change in the final version.</EM> | |
| 58 | − | |
| 59 | 65 | <H2><A NAME="about">About Lua</A></H2> |
| 60 | 66 | |
| 61 | 67 | Lua is a powerful, fast, lightweight, embeddable scripting language |
| @@ -270,6 +276,24 @@ compiler: · 208 unmodified lines | ||
| 270 | 276 | |
| 271 | 277 | <H2><A NAME="changes">Changes since Lua 5.1</A></H2> |
| 272 | 278 | |
| 279 | +<IMG SRC="alert.png" ALIGN="absbottom"> | |
| 280 | +<EM>Everything may change in the final version.</EM> | |
| 281 | +<P> | |
| 282 | + | |
| 283 | +Here are the main changes since the previous work version: | |
| 284 | +<UL> | |
| 285 | +<LI> new <CODE>_ENV</CODE> proposal | |
| 286 | +<LI> generational collector (very experimental) | |
| 287 | +<LI> light C functions | |
| 288 | + | |
| 289 | +<LI> order tag methods follow the same rules of other binary operators | |
| 290 | +<LI> <CODE>lua_absindex</CODE> | |
| 291 | +<LI> \0 in patterns | |
| 292 | +<LI> empty statement | |
| 293 | +<LI> options in <CODE>io.lines</CODE> | |
| 294 | +</UL> | |
| 295 | +<P> | |
| 296 | + | |
| 273 | 297 | Here are the main changes in Lua since its last release. |
| 274 | 298 | The |
| 275 | 299 | <A HREF="contents.html">reference manual</A> |
| @@ -281,13 +305,13 @@ lists the · 5 unmodified lines | ||
| 281 | 305 | <UL> |
| 282 | 306 | <LI> new lexical environments. |
| 283 | 307 | <LI> no more fenv for threads. |
| 284 | −<LI> ephemeron tables. | |
| 285 | −<LI> yieldable pcall/metamethods. | |
| 308 | +<LI> ephemeron tables | |
| 309 | + (tables with weak keys only visit value when key is accessible). | |
| 310 | +<LI> yieldable pcall and metamethods. | |
| 286 | 311 | <LI> tables honor the <CODE>__len</CODE> metamethod. |
| 287 | 312 | <LI> max constants per function raised to 2^26. |
| 288 | 313 | <LI> hex escapes in strings. |
| 289 | 314 | <LI> no more verification of opcode consistency. |
| 290 | − | |
| 291 | 315 | </UL> |
| 292 | 316 | |
| 293 | 317 | <H3>Libraries</H3> |
| @@ -299,27 +323,39 @@ lists the · 5 unmodified lines | ||
| 299 | 323 | <LI> <CODE>loadlib</CODE> may load libraries with global names (RTLD_GLOBAL). |
| 300 | 324 | <LI> new function <CODE>package.searchpath</CODE>. |
| 301 | 325 | <LI> optional base in <CODE>math.log</CODE>. |
| 302 | −<LI> <CODE>file:write</CODE> returns file. | |
| 326 | +<LI> <CODE>file:write</CODE> returns <CODE>file</CODE>. | |
| 303 | 327 | <LI> closing a pipe returns exit status. |
| 304 | 328 | <LI> <CODE>os.exit</CODE> may close state. |
| 305 | 329 | <LI> new option 'isrunning' for <CODE>collectgarbage</CODE> and <CODE>lua_gc</CODE>. |
| 306 | 330 | <LI> frontier patterns. |
| 307 | 331 | <LI> <CODE>ipairs</CODE> now goes until #t. |
| 332 | +</UL> | |
| 308 | 333 | |
| 334 | +<H3>C API</H3> | |
| 335 | +<UL> | |
| 336 | +<LI> mainthread predefined in the registry. | |
| 337 | +<LI> <CODE>lua_cpcall</CODE> changed to a predefined function in the registry. | |
| 338 | +<LI> new constants <CODE>LUA_OK</CODE> and <CODE>LUA_ERRGCMM</CODE>. | |
| 339 | +<LI> new <CODE>lua_compare</CODE>, <CODE>lua_arith</CODE>, and <CODE>lua_len</CODE>. | |
| 340 | +<LI> new <CODE>lua_version</CODE> and <CODE>luaL_version</CODE>. | |
| 341 | +<LI> <CODE>lua_pushstring</CODE> and <CODE>pushlstring</CODE> return string. | |
| 342 | +<LI> new <CODE>luaL_testudata</CODE>. | |
| 343 | +<LI> new <CODE>luaL_tolstring</CODE>. | |
| 344 | +<LI> new <CODE>lua_copy</CODE>. | |
| 345 | +<LI> new <CODE>lua_upvalueid</CODE> and <CODE>lua_upvaluejoin</CODE>. | |
| 346 | +<LI> <CODE>nparams</CODE> and <CODE>isvarag</CODE> available in debug API. | |
| 309 | 347 | </UL> |
| 310 | 348 | |
| 311 | 349 | <H3>Implementation</H3> |
| 312 | 350 | <UL> |
| 313 | 351 | <LI> emergency garbage collector |
| 314 | 352 | (core forces a full collection when allocation fails). |
| 315 | −<LI> ephemeron tables | |
| 316 | − (tables with weak keys only visit value when key is accessible) | |
| 317 | −<LI> handling of non-string error messages in the standalone interpreter. | |
| 318 | 353 | <LI> udata with finalizers are kept in a separated list for the GC. |
| 319 | 354 | <LI> CallInfo stack now is a linked list. |
| 320 | 355 | <LI> internal (immutable) version of ctypes. |
| 321 | 356 | <LI> parser uses much less C-stack space (no more auto arrays). |
| 322 | 357 | <LI> new hash for floats. |
| 358 | +<LI> handling of non-string error messages in the standalone interpreter. | |
| 323 | 359 | </UL> |
| 324 | 360 | |
| 325 | 361 | |
| @@ -372,10 +408,10 @@ THE SOFTWARE. · 46 unmodified lines | ||
| 372 | 408 | <HR> |
| 373 | 409 | <SMALL> |
| 374 | 410 | Last update: |
| 375 | −Wed Jan 13 15:35:05 BRST 2010 | |
| 411 | +Tue May 18 13:59:06 BRT 2010 | |
| 376 | 412 | </SMALL> |
| 377 | 413 | <!-- |
| 378 | −Last change: revised for Lua 5.2.0 (work2) | |
| 414 | +Last change: revised for Lua 5.2.0 (work3) | |
| 379 | 415 | --> |
| 380 | 416 | |
| 381 | 417 | </BODY> |
| @@ -7,32 +7,48 @@ BIN= $(TOP)/src · 6 unmodified lines | ||
| 7 | 7 | SRC= $(TOP)/src |
| 8 | 8 | TST= $(TOP)/test |
| 9 | 9 | |
| 10 | +T= test | |
| 10 | 11 | CC= gcc |
| 11 | 12 | CFLAGS= -O2 -Wall -I$(INC) $(MYCFLAGS) |
| 12 | 13 | MYCFLAGS= |
| 13 | −MYLDFLAGS= -Wl,-E | |
| 14 | −MYLIBS= -lm | |
| 15 | −#MYLIBS= -lm -Wl,-E -ldl -lreadline -lhistory -lncurses | |
| 14 | +MYLIBS= -lm # -ldl -lreadline -lncurses -Wl,-E | |
| 16 | 15 | RM= rm -f |
| 17 | 16 | |
| 17 | + | |
| 18 | 18 | default: |
| 19 | − @echo 'Please choose a target: min noparser one strict clean' | |
| 19 | + @echo 'Please choose a target: min noparser one one-lua one-lib one-luac so strict clean' | |
| 20 | 20 | |
| 21 | 21 | min: min.c |
| 22 | − $(CC) $(CFLAGS) $@.c -L$(LIB) -llua $(MYLIBS) | |
| 23 | − echo 'print"Hello there!"' | ./a.out | |
| 24 | − ./a.out $(TST)/hello.lua | |
| 25 | − echo 'print("Hello world, from",_VERSION,"!")' | ./a.out | |
| 22 | + $(CC) $(CFLAGS) -o $T min.c -L$(LIB) -llua $(MYLIBS) | |
| 23 | + echo 'print"Hello there!"' | ./$T | |
| 24 | + ./$T $(TST)/hello.lua | |
| 25 | + echo 'print("Hello world, from",_VERSION,"!")' | ./$T | |
| 26 | 26 | |
| 27 | 27 | noparser: noparser.o |
| 28 | − $(CC) noparser.o $(SRC)/lua.o -L$(LIB) -llua $(MYLIBS) | |
| 28 | + $(CC) -o $T noparser.o $(SRC)/lua.o -L$(LIB) -llua $(MYLIBS) | |
| 29 | 29 | $(BIN)/luac $(TST)/hello.lua |
| 30 | − -./a.out luac.out | |
| 31 | − -./a.out -e'a=1' | |
| 30 | + -./$T luac.out | |
| 31 | + -./$T -e'a=1' | |
| 32 | + | |
| 33 | +one: one-lua one-lib one-luac | |
| 34 | + | |
| 35 | +one-lua: | |
| 36 | + $(CC) $(CFLAGS) -o $T one.c $(MYLIBS) | |
| 37 | + ./$T $(TST)/hello.lua | |
| 38 | + | |
| 39 | +one-lib: | |
| 40 | + $(CC) $(CFLAGS) -DMAKE_LIB -o liblua.o -c one.c | |
| 41 | + $(CC) $(CFLAGS) -o $T min.c liblua.o $(MYLIBS) | |
| 42 | + ./$T $(TST)/hello.lua | |
| 43 | + | |
| 44 | +one-luac: | |
| 45 | + $(CC) $(CFLAGS) -o $T -DMAKE_LUAC one.c $(MYLIBS) | |
| 46 | + ./$T -l $(TST)/hello.lua | |
| 32 | 47 | |
| 33 | −one: | |
| 34 | − $(CC) $(CFLAGS) one.c $(MYLIBS) | |
| 35 | − ./a.out $(TST)/hello.lua | |
| 48 | +so: | |
| 49 | + $(CC) $(CFLAGS) -shared -o dummy.so dummy.c | |
| 50 | + @#env MACOSX_DEPLOYMENT_TARGET=10.3 $(CC) $(CFLAGS) -bundle -undefined dynamic_lookup -o dummy.so dummy.c | |
| 51 | + $(BIN)/lua -v -ldummy | |
| 36 | 52 | |
| 37 | 53 | strict: |
| 38 | 54 | -$(BIN)/lua -e 'print(a);b=2' |
| @@ -41,6 +57,6 @@ strict: · 2 unmodified lines | ||
| 41 | 57 | -$(BIN)/lua -lstrict -e 'function f() b=2 end f()' |
| 42 | 58 | |
| 43 | 59 | clean: |
| 44 | − $(RM) a.out core core.* *.o luac.out | |
| 60 | + $(RM) $T a.out core core.* *.o luac.out dummy.so | |
| 45 | 61 | |
| 46 | −.PHONY: default min noparser one strict clean | |
| 62 | +.PHONY: default min noparser one one-lua one-lib one-luac so strict clean | |
| @@ -4,23 +4,26 @@ Unlike the code in ../src, everything here is in the public domain. · 3 unmodified lines | ||
| 4 | 4 | If any of the makes fail, you're probably not using the same libraries used |
| 5 | 5 | to build Lua. Set MYLIBS in Makefile or in the command line accordingly. |
| 6 | 6 | |
| 7 | −one.c | |
| 8 | − Full Lua interpreter in a single file. | |
| 9 | − Do "make one" for a demo. | |
| 7 | +dummy.c: | |
| 8 | + A minimal Lua library for testing dynamic loading. | |
| 9 | + Do "make so" for a demo. | |
| 10 | 10 | |
| 11 | 11 | luavs.bat |
| 12 | 12 | Script to build Lua under "Visual Studio .NET Command Prompt". |
| 13 | 13 | Run it from the toplevel as etc\luavs.bat. |
| 14 | 14 | |
| 15 | 15 | min.c |
| 16 | − A minimal Lua interpreter. | |
| 17 | − Good for learning and for starting your own. | |
| 16 | + A minimal Lua interpreter for learning and for starting your own. | |
| 18 | 17 | Do "make min" for a demo. |
| 19 | 18 | |
| 20 | 19 | noparser.c |
| 21 | 20 | Linking with noparser.o avoids loading the parsing modules in lualib.a. |
| 22 | 21 | Do "make noparser" for a demo. |
| 23 | 22 | |
| 23 | +one.c | |
| 24 | + Full Lua interpreter in a single file. Also library and compiler. | |
| 25 | + Do "make one" for a demo. | |
| 26 | + | |
| 24 | 27 | strict.lua |
| 25 | 28 | Traps uses of undeclared global variables. |
| 26 | 29 | Do "make strict" for a demo. |
| @@ -0,0 +1,11 @@ | ||
| 1 | +/* | |
| 2 | +* dummy.c -- a minimal Lua library for testing dynamic loading | |
| 3 | +*/ | |
| 4 | + | |
| 5 | +#include <stdio.h> | |
| 6 | +#include "lua.h" | |
| 7 | + | |
| 8 | +int luaopen_dummy (lua_State *L) { | |
| 9 | + puts("Hello from dummy"); | |
| 10 | + return 0; | |
| 11 | +} | |
| @@ -5,10 +5,11 @@ · 4 unmodified lines | ||
| 5 | 5 | /* default is to build the full interpreter */ |
| 6 | 6 | #ifndef MAKE_LIB |
| 7 | 7 | #ifndef MAKE_LUAC |
| 8 | −#undef MAKE_LUA | |
| 8 | +#ifndef MAKE_LUA | |
| 9 | 9 | #define MAKE_LUA |
| 10 | 10 | #endif |
| 11 | 11 | #endif |
| 12 | +#endif | |
| 12 | 13 | |
| 13 | 14 | /* choose suitable platform-specific features */ |
| 14 | 15 | /* some of these may need extra libraries such as -ldl -lreadline -lncurses */ |
| @@ -16,7 +17,6 @@ · 1 unmodified line | ||
| 16 | 17 | #define LUA_USE_LINUX |
| 17 | 18 | #define LUA_USE_MACOSX |
| 18 | 19 | #define LUA_USE_POSIX |
| 19 | −#define LUA_USE_DLOPEN | |
| 20 | 20 | #define LUA_ANSI |
| 21 | 21 | #endif |
| 22 | 22 | |
| @@ -58,11 +58,11 @@ · 35 unmodified lines | ||
| 58 | 58 | #include "loslib.c" |
| 59 | 59 | #include "lstrlib.c" |
| 60 | 60 | #include "ltablib.c" |
| 61 | +#include "linit.c" | |
| 61 | 62 | #endif |
| 62 | 63 | |
| 63 | 64 | /* lua */ |
| 64 | 65 | #ifdef MAKE_LUA |
| 65 | −#include "linit.c" | |
| 66 | 66 | #include "lua.c" |
| 67 | 67 | #endif |
| 68 | 68 | |
| @@ -27,7 +27,7 @@ CORE_O= lapi.o lcode.o lctype.o ldebug.o ldo.o ldump.o lfunc.o lgc.o llex.o \ · 26 unmodified lines | ||
| 27 | 27 | lmem.o lobject.o lopcodes.o lparser.o lstate.o lstring.o ltable.o \ |
| 28 | 28 | ltm.o lundump.o lvm.o lzio.o |
| 29 | 29 | LIB_O= lauxlib.o lbaselib.o lbitlib.o ldblib.o liolib.o lmathlib.o loslib.o \ |
| 30 | − ltablib.o lstrlib.o loadlib.o linit.o | |
| 30 | + lstrlib.o ltablib.o loadlib.o linit.o | |
| 31 | 31 | |
| 32 | 32 | LUA_T= lua |
| 33 | 33 | LUA_O= lua.o |
| @@ -103,7 +103,7 @@ macosx: · 69 unmodified lines | ||
| 103 | 103 | $(MAKE) $(ALL) MYCFLAGS="-DLUA_USE_MACOSX" MYLIBS="-lreadline" |
| 104 | 104 | |
| 105 | 105 | mingw: |
| 106 | − $(MAKE) "LUA_A=lua51.dll" "LUA_T=lua.exe" \ | |
| 106 | + $(MAKE) "LUA_A=lua52.dll" "LUA_T=lua.exe" \ | |
| 107 | 107 | "AR=$(CC) -shared -o" "RANLIB=strip --strip-unneeded" \ |
| 108 | 108 | "MYCFLAGS=-DLUA_BUILD_AS_DLL" "MYLIBS=" "MYLDFLAGS=-s" lua.exe |
| 109 | 109 | |
| @@ -137,8 +137,8 @@ ldo.o: ldo.c lua.h luaconf.h lapi.h llimits.h lstate.h lobject.h ltm.h \ · 27 unmodified lines | ||
| 137 | 137 | lstring.h ltable.h lundump.h lvm.h |
| 138 | 138 | ldump.o: ldump.c lua.h luaconf.h lobject.h llimits.h lstate.h ltm.h \ |
| 139 | 139 | lzio.h lmem.h lundump.h |
| 140 | −lfunc.o: lfunc.c lua.h luaconf.h lfunc.h lobject.h llimits.h lgc.h lmem.h \ | |
| 141 | − lopcodes.h lstate.h ltm.h lzio.h | |
| 140 | +lfunc.o: lfunc.c lua.h luaconf.h lfunc.h lobject.h llimits.h lgc.h \ | |
| 141 | + lstate.h ltm.h lzio.h lmem.h lopcodes.h | |
| 142 | 142 | lgc.o: lgc.c lua.h luaconf.h ldebug.h lstate.h lobject.h llimits.h ltm.h \ |
| 143 | 143 | lzio.h lmem.h ldo.h lfunc.h lgc.h lstring.h ltable.h |
| 144 | 144 | linit.o: linit.c lua.h luaconf.h lualib.h lauxlib.h |
| @@ -163,7 +163,7 @@ lstring.o: lstring.c lua.h luaconf.h lmem.h llimits.h lobject.h lstate.h \ · 18 unmodified lines | ||
| 163 | 163 | ltm.h lzio.h lstring.h lgc.h |
| 164 | 164 | lstrlib.o: lstrlib.c lua.h luaconf.h lauxlib.h lualib.h |
| 165 | 165 | ltable.o: ltable.c lua.h luaconf.h ldebug.h lstate.h lobject.h llimits.h \ |
| 166 | − ltm.h lzio.h lmem.h ldo.h lgc.h ltable.h | |
| 166 | + ltm.h lzio.h lmem.h ldo.h lgc.h lstring.h ltable.h | |
| 167 | 167 | ltablib.o: ltablib.c lua.h luaconf.h lauxlib.h lualib.h |
| 168 | 168 | ltm.o: ltm.c lua.h luaconf.h lobject.h llimits.h lstate.h ltm.h lzio.h \ |
| 169 | 169 | lmem.h lstring.h lgc.h ltable.h |
| @@ -1,5 +1,5 @@ | ||
| 1 | 1 | /* |
| 2 | −** $Id: lapi.c,v 2.111 2010/01/13 16:18:25 roberto Exp $ | |
| 2 | +** $Id: lapi.c,v 2.129 2010/05/14 13:15:26 roberto Exp $ | |
| 3 | 3 | ** Lua API |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| @@ -39,16 +39,6 @@ const char lua_ident[] = · 33 unmodified lines | ||
| 39 | 39 | "invalid index") |
| 40 | 40 | |
| 41 | 41 | |
| 42 | −static Table *getcurrenv (lua_State *L) { | |
| 43 | − if (L->ci->previous == NULL) /* no enclosing function? */ | |
| 44 | − return G(L)->l_gt; /* use global table as environment */ | |
| 45 | − else { | |
| 46 | − Closure *func = curr_func(L); | |
| 47 | − return func->c.env; | |
| 48 | − } | |
| 49 | −} | |
| 50 | − | |
| 51 | − | |
| 52 | 42 | static TValue *index2addr (lua_State *L, int idx) { |
| 53 | 43 | CallInfo *ci = L->ci; |
| 54 | 44 | if (idx > 0) { |
| @@ -61,26 +51,25 @@ static TValue *index2addr (lua_State *L, int idx) { · 6 unmodified lines | ||
| 61 | 51 | api_check(L, idx != 0 && -idx <= L->top - (ci->func + 1), "invalid index"); |
| 62 | 52 | return L->top + idx; |
| 63 | 53 | } |
| 64 | − else switch (idx) { /* pseudo-indices */ | |
| 65 | − case LUA_REGISTRYINDEX: return &G(L)->l_registry; | |
| 66 | − case LUA_ENVIRONINDEX: { | |
| 67 | − sethvalue(L, &L->env, getcurrenv(L)); | |
| 68 | − return &L->env; | |
| 69 | − } | |
| 70 | − default: { | |
| 71 | − Closure *func = curr_func(L); | |
| 72 | − idx = LUA_ENVIRONINDEX - idx; | |
| 73 | − api_check(L, idx <= UCHAR_MAX + 1, "upvalue index too large"); | |
| 54 | + else if (idx == LUA_REGISTRYINDEX) | |
| 55 | + return &G(L)->l_registry; | |
| 56 | + else { /* upvalues */ | |
| 57 | + idx = LUA_REGISTRYINDEX - idx; | |
| 58 | + api_check(L, idx <= UCHAR_MAX + 1, "upvalue index too large"); | |
| 59 | + if (ttislcf(ci->func)) /* light C function? */ | |
| 60 | + return cast(TValue *, luaO_nilobject); /* it has no upvalues */ | |
| 61 | + else { | |
| 62 | + Closure *func = clvalue(ci->func); | |
| 74 | 63 | return (idx <= func->c.nupvalues) |
| 75 | − ? &func->c.upvalue[idx-1] | |
| 76 | − : cast(TValue *, luaO_nilobject); | |
| 64 | + ? &func->c.upvalue[idx-1] | |
| 65 | + : cast(TValue *, luaO_nilobject); | |
| 77 | 66 | } |
| 78 | 67 | } |
| 79 | 68 | } |
| 80 | 69 | |
| 81 | 70 | |
| 82 | 71 | /* |
| 83 | −** to be caled by 'lua_checkstack' in protected mode, to grow stack | |
| 72 | +** to be called by 'lua_checkstack' in protected mode, to grow stack | |
| 84 | 73 | ** capturing memory errors |
| 85 | 74 | */ |
| 86 | 75 | static void growstack (lua_State *L, void *ud) { |
| @@ -147,6 +136,16 @@ LUA_API const lua_Number *lua_version (lua_State *L) { · 60 unmodified lines | ||
| 147 | 136 | */ |
| 148 | 137 | |
| 149 | 138 | |
| 139 | +/* | |
| 140 | +** convert an acceptable stack index into an absolute index | |
| 141 | +*/ | |
| 142 | +LUA_API int lua_absindex (lua_State *L, int idx) { | |
| 143 | + return (idx > 0 || idx <= LUA_REGISTRYINDEX) | |
| 144 | + ? idx | |
| 145 | + : cast_int(L->top - L->ci->func + idx); | |
| 146 | +} | |
| 147 | + | |
| 148 | + | |
| 150 | 149 | LUA_API int lua_gettop (lua_State *L) { |
| 151 | 150 | return cast_int(L->top - (L->ci->func + 1)); |
| 152 | 151 | } |
| @@ -195,16 +194,10 @@ LUA_API void lua_insert (lua_State *L, int idx) { · 42 unmodified lines | ||
| 195 | 194 | static void moveto (lua_State *L, TValue *fr, int idx) { |
| 196 | 195 | TValue *to = index2addr(L, idx); |
| 197 | 196 | api_checkvalidindex(L, to); |
| 198 | − if (idx == LUA_ENVIRONINDEX) { | |
| 199 | − Closure *func = curr_func(L); | |
| 200 | − api_check(L, ttistable(fr), "table expected"); | |
| 201 | − func->c.env = hvalue(fr); | |
| 202 | − luaC_barrier(L, func, fr); | |
| 203 | − } | |
| 204 | − else { | |
| 205 | − setobj(L, to, fr); | |
| 206 | − if (idx < LUA_ENVIRONINDEX) /* function upvalue? */ | |
| 207 | − luaC_barrier(L, curr_func(L), fr); | |
| 197 | + setobj(L, to, fr); | |
| 198 | + if (idx < LUA_REGISTRYINDEX) { /* function upvalue? */ | |
| 199 | + lua_assert(ttisclosure(L->ci->func)); | |
| 200 | + luaC_barrier(L, clvalue(L->ci->func), fr); | |
| 208 | 201 | } |
| 209 | 202 | /* LUA_REGISTRYINDEX does not need gc barrier |
| 210 | 203 | (collector revisits it before finishing collection) */ |
| @@ -213,9 +206,6 @@ static void moveto (lua_State *L, TValue *fr, int idx) { · 2 unmodified lines | ||
| 213 | 206 | |
| 214 | 207 | LUA_API void lua_replace (lua_State *L, int idx) { |
| 215 | 208 | lua_lock(L); |
| 216 | − /* explicit test for incompatible code */ | |
| 217 | − if (idx == LUA_ENVIRONINDEX && L->ci->previous == NULL) | |
| 218 | − luaG_runerror(L, "no calling environment"); | |
| 219 | 209 | api_checknelems(L, 1); |
| 220 | 210 | moveto(L, L->top - 1, idx); |
| 221 | 211 | L->top--; |
| @@ -249,19 +239,19 @@ LUA_API void lua_pushvalue (lua_State *L, int idx) { · 27 unmodified lines | ||
| 249 | 239 | |
| 250 | 240 | LUA_API int lua_type (lua_State *L, int idx) { |
| 251 | 241 | StkId o = index2addr(L, idx); |
| 252 | − return (o == luaO_nilobject) ? LUA_TNONE : ttype(o); | |
| 242 | + return (o == luaO_nilobject) ? LUA_TNONE : ttypenv(o); | |
| 253 | 243 | } |
| 254 | 244 | |
| 255 | 245 | |
| 256 | 246 | LUA_API const char *lua_typename (lua_State *L, int t) { |
| 257 | 247 | UNUSED(L); |
| 258 | − return typename(t); | |
| 248 | + return ttypename(t); | |
| 259 | 249 | } |
| 260 | 250 | |
| 261 | 251 | |
| 262 | 252 | LUA_API int lua_iscfunction (lua_State *L, int idx) { |
| 263 | 253 | StkId o = index2addr(L, idx); |
| 264 | − return iscfunction(o); | |
| 254 | + return (ttislcf(o) || (ttisclosure(o) && clvalue(o)->c.isC)); | |
| 265 | 255 | } |
| 266 | 256 | |
| 267 | 257 | |
| @@ -387,7 +377,10 @@ LUA_API size_t lua_rawlen (lua_State *L, int idx) { · 119 unmodified lines | ||
| 387 | 377 | |
| 388 | 378 | LUA_API lua_CFunction lua_tocfunction (lua_State *L, int idx) { |
| 389 | 379 | StkId o = index2addr(L, idx); |
| 390 | − return (!iscfunction(o)) ? NULL : clvalue(o)->c.f; | |
| 380 | + if (ttislcf(o)) return fvalue(o); | |
| 381 | + else if (ttisclosure(o) && clvalue(o)->c.isC) | |
| 382 | + return clvalue(o)->c.f; | |
| 383 | + else return NULL; /* not a C function */ | |
| 391 | 384 | } |
| 392 | 385 | |
| 393 | 386 | |
| @@ -412,6 +405,7 @@ LUA_API const void *lua_topointer (lua_State *L, int idx) { · 18 unmodified lines | ||
| 412 | 405 | switch (ttype(o)) { |
| 413 | 406 | case LUA_TTABLE: return hvalue(o); |
| 414 | 407 | case LUA_TFUNCTION: return clvalue(o); |
| 408 | + case LUA_TLCF: return cast(void *, cast(size_t, fvalue(o))); | |
| 415 | 409 | case LUA_TTHREAD: return thvalue(o); |
| 416 | 410 | case LUA_TUSERDATA: |
| 417 | 411 | case LUA_TLIGHTUSERDATA: |
| @@ -468,8 +462,16 @@ LUA_API const char *lua_pushstring (lua_State *L, const char *s) { · 50 unmodified lines | ||
| 468 | 462 | lua_pushnil(L); |
| 469 | 463 | return NULL; |
| 470 | 464 | } |
| 471 | − else | |
| 472 | − return lua_pushlstring(L, s, strlen(s)); | |
| 465 | + else { | |
| 466 | + TString *ts; | |
| 467 | + lua_lock(L); | |
| 468 | + luaC_checkGC(L); | |
| 469 | + ts = luaS_new(L, s); | |
| 470 | + setsvalue2s(L, L->top, ts); | |
| 471 | + api_incr_top(L); | |
| 472 | + lua_unlock(L); | |
| 473 | + return getstr(ts); | |
| 474 | + } | |
| 473 | 475 | } |
| 474 | 476 | |
| 475 | 477 | |
| @@ -498,18 +500,22 @@ LUA_API const char *lua_pushfstring (lua_State *L, const char *fmt, ...) { · 22 unmodified lines | ||
| 498 | 500 | |
| 499 | 501 | |
| 500 | 502 | LUA_API void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n) { |
| 501 | − Closure *cl; | |
| 502 | 503 | lua_lock(L); |
| 503 | − api_checknelems(L, n); | |
| 504 | − api_check(L, n <= UCHAR_MAX, "upvalue index too large"); | |
| 505 | − luaC_checkGC(L); | |
| 506 | − cl = luaF_newCclosure(L, n, getcurrenv(L)); | |
| 507 | − cl->c.f = fn; | |
| 508 | − L->top -= n; | |
| 509 | − while (n--) | |
| 510 | − setobj2n(L, &cl->c.upvalue[n], L->top+n); | |
| 511 | − setclvalue(L, L->top, cl); | |
| 512 | − lua_assert(iswhite(obj2gco(cl))); | |
| 504 | + if (n == 0) { | |
| 505 | + setfvalue(L->top, fn); | |
| 506 | + } | |
| 507 | + else { | |
| 508 | + Closure *cl; | |
| 509 | + api_checknelems(L, n); | |
| 510 | + api_check(L, n <= UCHAR_MAX, "upvalue index too large"); | |
| 511 | + luaC_checkGC(L); | |
| 512 | + cl = luaF_newCclosure(L, n); | |
| 513 | + cl->c.f = fn; | |
| 514 | + L->top -= n; | |
| 515 | + while (n--) | |
| 516 | + setobj2n(L, &cl->c.upvalue[n], L->top + n); | |
| 517 | + setclvalue(L, L->top, cl); | |
| 518 | + } | |
| 513 | 519 | api_incr_top(L); |
| 514 | 520 | lua_unlock(L); |
| 515 | 521 | } |
| @@ -616,7 +622,7 @@ LUA_API int lua_getmetatable (lua_State *L, int objindex) { · 100 unmodified lines | ||
| 616 | 622 | mt = uvalue(obj)->metatable; |
| 617 | 623 | break; |
| 618 | 624 | default: |
| 619 | − mt = G(L)->mt[ttype(obj)]; | |
| 625 | + mt = G(L)->mt[ttypenv(obj)]; | |
| 620 | 626 | break; |
| 621 | 627 | } |
| 622 | 628 | if (mt == NULL) |
| @@ -631,22 +637,16 @@ LUA_API int lua_getmetatable (lua_State *L, int objindex) { · 8 unmodified lines | ||
| 631 | 637 | } |
| 632 | 638 | |
| 633 | 639 | |
| 634 | −LUA_API void lua_getfenv (lua_State *L, int idx) { | |
| 640 | +LUA_API void lua_getenv (lua_State *L, int idx) { | |
| 635 | 641 | StkId o; |
| 636 | 642 | lua_lock(L); |
| 637 | 643 | o = index2addr(L, idx); |
| 638 | 644 | api_checkvalidindex(L, o); |
| 639 | − switch (ttype(o)) { | |
| 640 | − case LUA_TFUNCTION: | |
| 641 | − sethvalue(L, L->top, clvalue(o)->c.env); | |
| 642 | − break; | |
| 643 | − case LUA_TUSERDATA: | |
| 644 | − sethvalue(L, L->top, uvalue(o)->env); | |
| 645 | − break; | |
| 646 | − default: | |
| 647 | − setnilvalue(L->top); | |
| 648 | − break; | |
| 649 | − } | |
| 645 | + api_check(L, ttisuserdata(o), "userdata expected"); | |
| 646 | + if (uvalue(o)->env) { | |
| 647 | + sethvalue(L, L->top, uvalue(o)->env); | |
| 648 | + } else | |
| 649 | + setnilvalue(L->top); | |
| 650 | 650 | api_incr_top(L); |
| 651 | 651 | lua_unlock(L); |
| 652 | 652 | } |
| @@ -737,7 +737,7 @@ LUA_API int lua_setmetatable (lua_State *L, int objindex) { · 84 unmodified lines | ||
| 737 | 737 | break; |
| 738 | 738 | } |
| 739 | 739 | default: { |
| 740 | − G(L)->mt[ttype(obj)] = mt; | |
| 740 | + G(L)->mt[ttypenv(obj)] = mt; | |
| 741 | 741 | break; |
| 742 | 742 | } |
| 743 | 743 | } |
| @@ -747,29 +747,22 @@ LUA_API int lua_setmetatable (lua_State *L, int objindex) { · 3 unmodified lines | ||
| 747 | 747 | } |
| 748 | 748 | |
| 749 | 749 | |
| 750 | −LUA_API int lua_setfenv (lua_State *L, int idx) { | |
| 750 | +LUA_API void lua_setenv (lua_State *L, int idx) { | |
| 751 | 751 | StkId o; |
| 752 | − int res = 1; | |
| 753 | 752 | lua_lock(L); |
| 754 | 753 | api_checknelems(L, 1); |
| 755 | 754 | o = index2addr(L, idx); |
| 756 | 755 | api_checkvalidindex(L, o); |
| 757 | − api_check(L, ttistable(L->top - 1), "table expected"); | |
| 758 | − switch (ttype(o)) { | |
| 759 | − case LUA_TFUNCTION: | |
| 760 | − clvalue(o)->c.env = hvalue(L->top - 1); | |
| 761 | − break; | |
| 762 | − case LUA_TUSERDATA: | |
| 763 | − uvalue(o)->env = hvalue(L->top - 1); | |
| 764 | − break; | |
| 765 | − default: | |
| 766 | − res = 0; | |
| 767 | − break; | |
| 756 | + api_check(L, ttisuserdata(o), "userdata expected"); | |
| 757 | + if (ttisnil(L->top - 1)) | |
| 758 | + uvalue(o)->env = NULL; | |
| 759 | + else { | |
| 760 | + api_check(L, ttistable(L->top - 1), "table expected"); | |
| 761 | + uvalue(o)->env = hvalue(L->top - 1); | |
| 762 | + luaC_objbarrier(L, gcvalue(o), hvalue(L->top - 1)); | |
| 768 | 763 | } |
| 769 | − if (res) luaC_objbarrier(L, gcvalue(o), hvalue(L->top - 1)); | |
| 770 | 764 | L->top--; |
| 771 | 765 | lua_unlock(L); |
| 772 | − return res; | |
| 773 | 766 | } |
| 774 | 767 | |
| 775 | 768 | |
| @@ -857,7 +850,7 @@ LUA_API int lua_pcallk (lua_State *L, int nargs, int nresults, int errfunc, · 81 unmodified lines | ||
| 857 | 850 | ci->u.c.k = k; /* save continuation */ |
| 858 | 851 | ci->u.c.ctx = ctx; /* save context */ |
| 859 | 852 | /* save information for error recovery */ |
| 860 | − ci->u.c.oldtop = savestack(L, c.func); | |
| 853 | + ci->u.c.extra = savestack(L, c.func); | |
| 861 | 854 | ci->u.c.old_allowhook = L->allowhook; |
| 862 | 855 | ci->u.c.old_errfunc = L->errfunc; |
| 863 | 856 | L->errfunc = func; |
| @@ -882,6 +875,18 @@ LUA_API int lua_load (lua_State *L, lua_Reader reader, void *data, · 18 unmodified lines | ||
| 882 | 875 | if (!chunkname) chunkname = "?"; |
| 883 | 876 | luaZ_init(L, &z, reader, data); |
| 884 | 877 | status = luaD_protectedparser(L, &z, chunkname); |
| 878 | + if (status == LUA_OK) { /* no errors? */ | |
| 879 | + Closure *f = clvalue(L->top - 1); /* get newly created function */ | |
| 880 | + lua_assert(!f->c.isC); | |
| 881 | + if (f->l.nupvalues == 1) { /* does it have one upvalue? */ | |
| 882 | + /* get global table from registry */ | |
| 883 | + Table *reg = hvalue(&G(L)->l_registry); | |
| 884 | + const TValue *gt = luaH_getint(reg, LUA_RIDX_GLOBALS); | |
| 885 | + /* set global table as 1st upvalue of 'f' (may be _ENV) */ | |
| 886 | + setobj(L, f->l.upvals[0]->v, gt); | |
| 887 | + luaC_barrier(L, f->l.upvals[0], gt); | |
| 888 | + } | |
| 889 | + } | |
| 885 | 890 | lua_unlock(L); |
| 886 | 891 | return status; |
| 887 | 892 | } |
| @@ -918,11 +923,11 @@ LUA_API int lua_gc (lua_State *L, int what, int data) { · 30 unmodified lines | ||
| 918 | 923 | g = G(L); |
| 919 | 924 | switch (what) { |
| 920 | 925 | case LUA_GCSTOP: { |
| 921 | − g->GCthreshold = MAX_LUMEM; | |
| 926 | + stopgc(g); | |
| 922 | 927 | break; |
| 923 | 928 | } |
| 924 | 929 | case LUA_GCRESTART: { |
| 925 | − g->GCthreshold = g->totalbytes; | |
| 930 | + g->GCdebt = 0; | |
| 926 | 931 | break; |
| 927 | 932 | } |
| 928 | 933 | case LUA_GCCOLLECT: { |
| @@ -939,18 +944,22 @@ LUA_API int lua_gc (lua_State *L, int what, int data) { · 10 unmodified lines | ||
| 939 | 944 | break; |
| 940 | 945 | } |
| 941 | 946 | case LUA_GCSTEP: { |
| 942 | − lu_mem oldts = g->GCthreshold; | |
| 943 | − lu_mem a = (cast(lu_mem, data) << 10); | |
| 944 | − g->GCthreshold = (a <= g->totalbytes) ? g->totalbytes - a : 0; | |
| 945 | − while (g->GCthreshold <= g->totalbytes) { | |
| 946 | − luaC_step(L); | |
| 947 | − if (g->gcstate == GCSpause) { /* end of cycle? */ | |
| 948 | − res = 1; /* signal it */ | |
| 949 | − break; | |
| 947 | + int stopped = gcstopped(g); | |
| 948 | + if (g->gckind == KGC_GEN) { /* generational mode? */ | |
| 949 | + res = (g->lastmajormem == 0); /* 1 if will do major collection */ | |
| 950 | + luaC_step(L); /* do a single step */ | |
| 951 | + } | |
| 952 | + else { | |
| 953 | + while (data-- >= 0) { | |
| 954 | + luaC_step(L); | |
| 955 | + if (g->gcstate == GCSpause) { /* end of cycle? */ | |
| 956 | + res = 1; /* signal it */ | |
| 957 | + break; | |
| 958 | + } | |
| 950 | 959 | } |
| 951 | 960 | } |
| 952 | − if (oldts == MAX_LUMEM) /* collector was stopped? */ | |
| 953 | − g->GCthreshold = oldts; /* keep it that way */ | |
| 961 | + if (stopped) /* collector was stopped? */ | |
| 962 | + stopgc(g); /* keep it that way */ | |
| 954 | 963 | break; |
| 955 | 964 | } |
| 956 | 965 | case LUA_GCSETPAUSE: { |
| @@ -964,7 +973,15 @@ LUA_API int lua_gc (lua_State *L, int what, int data) { · 7 unmodified lines | ||
| 964 | 973 | break; |
| 965 | 974 | } |
| 966 | 975 | case LUA_GCISRUNNING: { |
| 967 | − res = (g->GCthreshold != MAX_LUMEM); | |
| 976 | + res = !gcstopped(g); | |
| 977 | + break; | |
| 978 | + } | |
| 979 | + case LUA_GCGEN: { /* change collector to generational mode */ | |
| 980 | + luaC_changemode(L, KGC_GEN); | |
| 981 | + break; | |
| 982 | + } | |
| 983 | + case LUA_GCINC: { /* change collector to incremental mode */ | |
| 984 | + luaC_changemode(L, KGC_NORMAL); | |
| 968 | 985 | break; |
| 969 | 986 | } |
| 970 | 987 | default: res = -1; /* invalid option */ |
| @@ -1054,7 +1071,7 @@ LUA_API void *lua_newuserdata (lua_State *L, size_t size) { · 83 unmodified lines | ||
| 1054 | 1071 | Udata *u; |
| 1055 | 1072 | lua_lock(L); |
| 1056 | 1073 | luaC_checkGC(L); |
| 1057 | − u = luaS_newudata(L, size, getcurrenv(L)); | |
| 1074 | + u = luaS_newudata(L, size, NULL); | |
| 1058 | 1075 | setuvalue(L, L->top, u); |
| 1059 | 1076 | api_incr_top(L); |
| 1060 | 1077 | lua_unlock(L); |
| @@ -1064,19 +1081,22 @@ LUA_API void *lua_newuserdata (lua_State *L, size_t size) { · 3 unmodified lines | ||
| 1064 | 1081 | |
| 1065 | 1082 | |
| 1066 | 1083 | |
| 1067 | −static const char *aux_upvalue (StkId fi, int n, TValue **val) { | |
| 1084 | +static const char *aux_upvalue (StkId fi, int n, TValue **val, | |
| 1085 | + GCObject **owner) { | |
| 1068 | 1086 | Closure *f; |
| 1069 | − if (!ttisfunction(fi)) return NULL; | |
| 1087 | + if (!ttisclosure(fi)) return NULL; | |
| 1070 | 1088 | f = clvalue(fi); |
| 1071 | 1089 | if (f->c.isC) { |
| 1072 | 1090 | if (!(1 <= n && n <= f->c.nupvalues)) return NULL; |
| 1073 | 1091 | *val = &f->c.upvalue[n-1]; |
| 1092 | + if (owner) *owner = obj2gco(f); | |
| 1074 | 1093 | return ""; |
| 1075 | 1094 | } |
| 1076 | 1095 | else { |
| 1077 | 1096 | Proto *p = f->l.p; |
| 1078 | 1097 | if (!(1 <= n && n <= p->sizeupvalues)) return NULL; |
| 1079 | 1098 | *val = f->l.upvals[n-1]->v; |
| 1099 | + if (owner) *owner = obj2gco(f->l.upvals[n - 1]); | |
| 1080 | 1100 | return getstr(p->upvalues[n-1].name); |
| 1081 | 1101 | } |
| 1082 | 1102 | } |
| @@ -1086,7 +1106,7 @@ LUA_API const char *lua_getupvalue (lua_State *L, int funcindex, int n) { · 3 unmodified lines | ||
| 1086 | 1106 | const char *name; |
| 1087 | 1107 | TValue *val; |
| 1088 | 1108 | lua_lock(L); |
| 1089 | − name = aux_upvalue(index2addr(L, funcindex), n, &val); | |
| 1109 | + name = aux_upvalue(index2addr(L, funcindex), n, &val, NULL); | |
| 1090 | 1110 | if (name) { |
| 1091 | 1111 | setobj2s(L, L->top, val); |
| 1092 | 1112 | api_incr_top(L); |
| @@ -1099,15 +1119,16 @@ LUA_API const char *lua_getupvalue (lua_State *L, int funcindex, int n) { · 6 unmodified lines | ||
| 1099 | 1119 | LUA_API const char *lua_setupvalue (lua_State *L, int funcindex, int n) { |
| 1100 | 1120 | const char *name; |
| 1101 | 1121 | TValue *val; |
| 1122 | + GCObject *owner; | |
| 1102 | 1123 | StkId fi; |
| 1103 | 1124 | lua_lock(L); |
| 1104 | 1125 | fi = index2addr(L, funcindex); |
| 1105 | 1126 | api_checknelems(L, 1); |
| 1106 | − name = aux_upvalue(fi, n, &val); | |
| 1127 | + name = aux_upvalue(fi, n, &val, &owner); | |
| 1107 | 1128 | if (name) { |
| 1108 | 1129 | L->top--; |
| 1109 | 1130 | setobj(L, val, L->top); |
| 1110 | − luaC_barrier(L, clvalue(fi), L->top); | |
| 1131 | + luaC_barrier(L, owner, L->top); | |
| 1111 | 1132 | } |
| 1112 | 1133 | lua_unlock(L); |
| 1113 | 1134 | return name; |
| @@ -1118,7 +1139,7 @@ static UpVal **getupvalref (lua_State *L, int fidx, int n, Closure **pf) { · 4 unmodified lines | ||
| 1118 | 1139 | Closure *f; |
| 1119 | 1140 | Proto *p; |
| 1120 | 1141 | StkId fi = index2addr(L, fidx); |
| 1121 | − api_check(L, ttisfunction(fi), "function expected"); | |
| 1142 | + api_check(L, ttisclosure(fi), "Lua function expected"); | |
| 1122 | 1143 | f = clvalue(fi); |
| 1123 | 1144 | api_check(L, !f->c.isC, "Lua function expected"); |
| 1124 | 1145 | p = f->l.p; |
| @@ -1131,7 +1152,7 @@ static UpVal **getupvalref (lua_State *L, int fidx, int n, Closure **pf) { · 6 unmodified lines | ||
| 1131 | 1152 | LUA_API void *lua_upvalueid (lua_State *L, int fidx, int n) { |
| 1132 | 1153 | Closure *f; |
| 1133 | 1154 | StkId fi = index2addr(L, fidx); |
| 1134 | − api_check(L, ttisfunction(fi), "function expected"); | |
| 1155 | + api_check(L, ttisclosure(fi), "function expected"); | |
| 1135 | 1156 | f = clvalue(fi); |
| 1136 | 1157 | if (f->c.isC) { |
| 1137 | 1158 | api_check(L, 1 <= n && n <= f->c.nupvalues, "invalid upvalue index"); |
| @@ -1150,12 +1171,3 @@ LUA_API void lua_upvaluejoin (lua_State *L, int fidx1, int n1, · 12 unmodified lines | ||
| 1150 | 1171 | luaC_objbarrier(L, f1, *up2); |
| 1151 | 1172 | } |
| 1152 | 1173 | |
| 1153 | − | |
| 1154 | −#if defined(LUA_COMPAT_CPCALL) | |
| 1155 | −LUA_API int lua_cpcall (lua_State *L, lua_CFunction func, void *ud) { | |
| 1156 | − lua_rawgeti(L, LUA_REGISTRYINDEX, LUA_RIDX_CPCALL); | |
| 1157 | − lua_pushlightuserdata(L, &func); | |
| 1158 | − lua_pushlightuserdata(L, ud); | |
| 1159 | − return lua_pcall(L, 2, 0, 0); | |
| 1160 | −} | |
| 1161 | −#endif | |
| @@ -1,5 +1,5 @@ | ||
| 1 | 1 | /* |
| 2 | −** $Id: lauxlib.c,v 1.196 2009/12/22 15:32:50 roberto Exp $ | |
| 2 | +** $Id: lauxlib.c,v 1.212 2010/05/18 17:21:24 roberto Exp $ | |
| 3 | 3 | ** Auxiliary functions for building Lua libraries |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| @@ -24,11 +24,6 @@ · 18 unmodified lines | ||
| 24 | 24 | #include "lauxlib.h" |
| 25 | 25 | |
| 26 | 26 | |
| 27 | −/* convert a stack index to positive */ | |
| 28 | −#define abs_index(L, i) ((i) > 0 || (i) <= LUA_REGISTRYINDEX ? (i) : \ | |
| 29 | − lua_gettop(L) + (i) + 1) | |
| 30 | − | |
| 31 | − | |
| 32 | 27 | /* |
| 33 | 28 | ** {====================================================== |
| 34 | 29 | ** Traceback |
| @@ -347,54 +342,40 @@ LUALIB_API lua_Integer luaL_optinteger (lua_State *L, int narg, · 312 unmodified lines | ||
| 347 | 342 | ** ======================================================= |
| 348 | 343 | */ |
| 349 | 344 | |
| 350 | − | |
| 351 | −#define bufflen(B) ((B)->p - (B)->buffer) | |
| 352 | −#define bufffree(B) ((size_t)(LUAL_BUFFERSIZE - bufflen(B))) | |
| 353 | − | |
| 354 | −#define LIMIT (LUA_MINSTACK/2) | |
| 355 | − | |
| 356 | − | |
| 357 | −static int emptybuffer (luaL_Buffer *B) { | |
| 358 | − size_t l = bufflen(B); | |
| 359 | − if (l == 0) return 0; /* put nothing on stack */ | |
| 360 | − else { | |
| 361 | − lua_pushlstring(B->L, B->buffer, l); | |
| 362 | − B->p = B->buffer; | |
| 363 | − B->lvl++; | |
| 364 | − return 1; | |
| 365 | − } | |
| 366 | −} | |
| 345 | +/* | |
| 346 | +** check whether buffer is using a userdata on the stack as a temporary | |
| 347 | +** buffer | |
| 348 | +*/ | |
| 349 | +#define buffonstack(B) ((B)->b != (B)->initb) | |
| 367 | 350 | |
| 368 | 351 | |
| 369 | −static void adjuststack (luaL_Buffer *B) { | |
| 370 | − if (B->lvl > 1) { | |
| 371 | − lua_State *L = B->L; | |
| 372 | − int toget = 1; /* number of levels to concat */ | |
| 373 | − size_t toplen = lua_rawlen(L, -1); | |
| 374 | − do { | |
| 375 | − size_t l = lua_rawlen(L, -(toget+1)); | |
| 376 | − if (B->lvl - toget + 1 >= LIMIT || toplen > l) { | |
| 377 | − toplen += l; | |
| 378 | − toget++; | |
| 379 | − } | |
| 380 | − else break; | |
| 381 | − } while (toget < B->lvl); | |
| 382 | − lua_concat(L, toget); | |
| 383 | − B->lvl = B->lvl - toget + 1; | |
| 352 | +/* | |
| 353 | +** returns a pointer to a free area with at least 'sz' bytes | |
| 354 | +*/ | |
| 355 | +LUALIB_API char *luaL_prepbuffsize (luaL_Buffer *B, size_t sz) { | |
| 356 | + lua_State *L = B->L; | |
| 357 | + if (B->size - B->n < sz) { /* not enough space? */ | |
| 358 | + char *newbuff; | |
| 359 | + size_t newsize = B->size * 2; /* double buffer size */ | |
| 360 | + if (newsize - B->n < sz) /* not bit enough? */ | |
| 361 | + newsize = B->n + sz; | |
| 362 | + if (newsize < B->n || newsize - B->n < sz) | |
| 363 | + luaL_error(L, "string too large"); | |
| 364 | + newbuff = (char *)lua_newuserdata(L, newsize); /* create larger buffer */ | |
| 365 | + memcpy(newbuff, B->b, B->n); /* move content to new buffer */ | |
| 366 | + if (buffonstack(B)) | |
| 367 | + lua_remove(L, -2); /* remove old buffer */ | |
| 368 | + B->b = newbuff; | |
| 369 | + B->size = newsize; | |
| 384 | 370 | } |
| 385 | −} | |
| 386 | − | |
| 387 | − | |
| 388 | −LUALIB_API char *luaL_prepbuffer (luaL_Buffer *B) { | |
| 389 | − if (emptybuffer(B)) | |
| 390 | − adjuststack(B); | |
| 391 | − return B->buffer; | |
| 371 | + return &B->b[B->n]; | |
| 392 | 372 | } |
| 393 | 373 | |
| 394 | 374 | |
| 395 | 375 | LUALIB_API void luaL_addlstring (luaL_Buffer *B, const char *s, size_t l) { |
| 396 | − while (l--) | |
| 397 | − luaL_addchar(B, *s++); | |
| 376 | + char *b = luaL_prepbuffsize(B, l); | |
| 377 | + memcpy(b, s, l); | |
| 378 | + luaL_addsize(B, l); | |
| 398 | 379 | } |
| 399 | 380 | |
| 400 | 381 | |
| @@ -404,35 +385,41 @@ LUALIB_API void luaL_addstring (luaL_Buffer *B, const char *s) { · 3 unmodified lines | ||
| 404 | 385 | |
| 405 | 386 | |
| 406 | 387 | LUALIB_API void luaL_pushresult (luaL_Buffer *B) { |
| 407 | − emptybuffer(B); | |
| 408 | − lua_concat(B->L, B->lvl); | |
| 409 | − B->lvl = 1; | |
| 388 | + lua_State *L = B->L; | |
| 389 | + lua_pushlstring(L, B->b, B->n); | |
| 390 | + if (buffonstack(B)) | |
| 391 | + lua_remove(L, -2); /* remove old buffer */ | |
| 392 | +} | |
| 393 | + | |
| 394 | + | |
| 395 | +LUALIB_API void luaL_pushresultsize (luaL_Buffer *B, size_t sz) { | |
| 396 | + luaL_addsize(B, sz); | |
| 397 | + luaL_pushresult(B); | |
| 410 | 398 | } |
| 411 | 399 | |
| 412 | 400 | |
| 413 | 401 | LUALIB_API void luaL_addvalue (luaL_Buffer *B) { |
| 414 | 402 | lua_State *L = B->L; |
| 415 | − size_t vl; | |
| 416 | − const char *s = lua_tolstring(L, -1, &vl); | |
| 417 | − if (vl <= bufffree(B)) { /* fit into buffer? */ | |
| 418 | − memcpy(B->p, s, vl); /* put it there */ | |
| 419 | − B->p += vl; | |
| 420 | − lua_pop(L, 1); /* remove from stack */ | |
| 421 | − } | |
| 422 | − else { | |
| 423 | − if (emptybuffer(B)) | |
| 424 | − lua_insert(L, -2); /* put buffer before new value */ | |
| 425 | − B->lvl++; /* add new value into B stack */ | |
| 426 | − adjuststack(B); | |
| 427 | − } | |
| 403 | + size_t l; | |
| 404 | + const char *s = lua_tolstring(L, -1, &l); | |
| 405 | + if (buffonstack(B)) | |
| 406 | + lua_insert(L, -2); /* put value below buffer */ | |
| 407 | + luaL_addlstring(B, s, l); | |
| 408 | + lua_remove(L, (buffonstack(B)) ? -2 : -1); /* remove value */ | |
| 428 | 409 | } |
| 429 | 410 | |
| 430 | 411 | |
| 431 | 412 | LUALIB_API void luaL_buffinit (lua_State *L, luaL_Buffer *B) { |
| 432 | − luaL_checkstack(L, LIMIT + LUA_MINSTACK, "no space for new buffer"); | |
| 433 | 413 | B->L = L; |
| 434 | − B->p = B->buffer; | |
| 435 | − B->lvl = 0; | |
| 414 | + B->b = B->initb; | |
| 415 | + B->n = 0; | |
| 416 | + B->size = LUAL_BUFFERSIZE; | |
| 417 | +} | |
| 418 | + | |
| 419 | + | |
| 420 | +LUALIB_API char *luaL_buffinitsize (lua_State *L, luaL_Buffer *B, size_t sz) { | |
| 421 | + luaL_buffinit(L, B); | |
| 422 | + return luaL_prepbuffsize(B, sz); | |
| 436 | 423 | } |
| 437 | 424 | |
| 438 | 425 | /* }====================================================== */ |
| @@ -444,32 +431,26 @@ LUALIB_API void luaL_buffinit (lua_State *L, luaL_Buffer *B) { · 5 unmodified lines | ||
| 444 | 431 | ** ======================================================= |
| 445 | 432 | */ |
| 446 | 433 | |
| 447 | −/* number of prereserved references (for internal use) */ | |
| 448 | −#define FREELIST_REF (LUA_RIDX_LAST + 1) /* free list of references */ | |
| 434 | +/* index of free-list header */ | |
| 435 | +#define freelist "lua-freelist" | |
| 449 | 436 | |
| 450 | 437 | |
| 451 | 438 | LUALIB_API int luaL_ref (lua_State *L, int t) { |
| 452 | 439 | int ref; |
| 453 | − t = abs_index(L, t); | |
| 440 | + t = lua_absindex(L, t); | |
| 454 | 441 | if (lua_isnil(L, -1)) { |
| 455 | 442 | lua_pop(L, 1); /* remove from stack */ |
| 456 | 443 | return LUA_REFNIL; /* `nil' has a unique fixed reference */ |
| 457 | 444 | } |
| 458 | − lua_rawgeti(L, t, FREELIST_REF); /* get first free element */ | |
| 445 | + lua_getfield(L, t, freelist); /* get first free element */ | |
| 459 | 446 | ref = (int)lua_tointeger(L, -1); /* ref = t[FREELIST_REF] */ |
| 460 | 447 | lua_pop(L, 1); /* remove it from stack */ |
| 461 | 448 | if (ref != 0) { /* any free element? */ |
| 462 | 449 | lua_rawgeti(L, t, ref); /* remove it from list */ |
| 463 | − lua_rawseti(L, t, FREELIST_REF); /* (t[FREELIST_REF] = t[ref]) */ | |
| 450 | + lua_setfield(L, t, freelist); /* (t[freelist] = t[ref]) */ | |
| 464 | 451 | } |
| 465 | − else { /* no free elements */ | |
| 452 | + else /* no free elements */ | |
| 466 | 453 | ref = (int)lua_rawlen(L, t) + 1; /* get a new reference */ |
| 467 | − if (ref == FREELIST_REF) { /* FREELIST_REF not initialized? */ | |
| 468 | − lua_pushinteger(L, 0); | |
| 469 | − lua_rawseti(L, t, FREELIST_REF); | |
| 470 | − ref = FREELIST_REF + 1; | |
| 471 | − } | |
| 472 | − } | |
| 473 | 454 | lua_rawseti(L, t, ref); |
| 474 | 455 | return ref; |
| 475 | 456 | } |
| @@ -477,11 +458,11 @@ LUALIB_API int luaL_ref (lua_State *L, int t) { · 1 unmodified line | ||
| 477 | 458 | |
| 478 | 459 | LUALIB_API void luaL_unref (lua_State *L, int t, int ref) { |
| 479 | 460 | if (ref >= 0) { |
| 480 | − t = abs_index(L, t); | |
| 481 | − lua_rawgeti(L, t, FREELIST_REF); | |
| 482 | − lua_rawseti(L, t, ref); /* t[ref] = t[FREELIST_REF] */ | |
| 461 | + t = lua_absindex(L, t); | |
| 462 | + lua_getfield(L, t, freelist); | |
| 463 | + lua_rawseti(L, t, ref); /* t[ref] = t[freelist] */ | |
| 483 | 464 | lua_pushinteger(L, ref); |
| 484 | − lua_rawseti(L, t, FREELIST_REF); /* t[FREELIST_REF] = ref */ | |
| 465 | + lua_setfield(L, t, freelist); /* t[freelist] = ref */ | |
| 485 | 466 | } |
| 486 | 467 | } |
| 487 | 468 | |
| @@ -495,7 +476,7 @@ LUALIB_API void luaL_unref (lua_State *L, int t, int ref) { · 7 unmodified lines | ||
| 495 | 476 | */ |
| 496 | 477 | |
| 497 | 478 | typedef struct LoadF { |
| 498 | − int extraline; | |
| 479 | + int first; | |
| 499 | 480 | FILE *f; |
| 500 | 481 | char buff[LUAL_BUFFERSIZE]; |
| 501 | 482 | } LoadF; |
| @@ -504,17 +485,19 @@ typedef struct LoadF { · 2 unmodified lines | ||
| 504 | 485 | static const char *getF (lua_State *L, void *ud, size_t *size) { |
| 505 | 486 | LoadF *lf = (LoadF *)ud; |
| 506 | 487 | (void)L; |
| 507 | − if (lf->extraline) { | |
| 508 | − lf->extraline = 0; | |
| 488 | + if (lf->first != EOF) { | |
| 509 | 489 | *size = 1; |
| 510 | − return "\n"; | |
| 490 | + lf->buff[0] = (char)lf->first; | |
| 491 | + lf->first = EOF; | |
| 492 | + } | |
| 493 | + else { | |
| 494 | + /* 'fread' can return > 0 *and* set the EOF flag. If next call to | |
| 495 | + 'getF' called 'fread', it might still wait for user input. | |
| 496 | + The next check avoids this problem. */ | |
| 497 | + if (feof(lf->f)) return NULL; | |
| 498 | + *size = fread(lf->buff, 1, sizeof(lf->buff), lf->f); | |
| 511 | 499 | } |
| 512 | − /* 'fread' can return > 0 *and* set the EOF flag. If next call to | |
| 513 | − 'getF' calls 'fread', terminal may still wait for user input. | |
| 514 | − The next check avoids this problem. */ | |
| 515 | − if (feof(lf->f)) return NULL; | |
| 516 | − *size = fread(lf->buff, 1, sizeof(lf->buff), lf->f); | |
| 517 | − return (*size > 0) ? lf->buff : NULL; | |
| 500 | + return lf->buff; | |
| 518 | 501 | } |
| 519 | 502 | |
| 520 | 503 | |
| @@ -532,7 +515,6 @@ LUALIB_API int luaL_loadfile (lua_State *L, const char *filename) { · 11 unmodified lines | ||
| 532 | 515 | int status, readstatus; |
| 533 | 516 | int c; |
| 534 | 517 | int fnameindex = lua_gettop(L) + 1; /* index of filename on the stack */ |
| 535 | − lf.extraline = 0; | |
| 536 | 518 | if (filename == NULL) { |
| 537 | 519 | lua_pushliteral(L, "=stdin"); |
| 538 | 520 | lf.f = stdin; |
| @@ -544,18 +526,14 @@ LUALIB_API int luaL_loadfile (lua_State *L, const char *filename) { · 5 unmodified lines | ||
| 544 | 526 | } |
| 545 | 527 | c = getc(lf.f); |
| 546 | 528 | if (c == '#') { /* Unix exec. file? */ |
| 547 | − lf.extraline = 1; | |
| 548 | 529 | while ((c = getc(lf.f)) != EOF && c != '\n') ; /* skip first line */ |
| 549 | − if (c == '\n') c = getc(lf.f); | |
| 550 | 530 | } |
| 551 | − if (c == LUA_SIGNATURE[0] && filename) { /* binary file? */ | |
| 531 | + else if (c == LUA_SIGNATURE[0] && filename) { /* binary file? */ | |
| 552 | 532 | lf.f = freopen(filename, "rb", lf.f); /* reopen in binary mode */ |
| 553 | 533 | if (lf.f == NULL) return errfile(L, "reopen", fnameindex); |
| 554 | − /* skip eventual `#!...' */ | |
| 555 | − while ((c = getc(lf.f)) != EOF && c != LUA_SIGNATURE[0]) ; | |
| 556 | − lf.extraline = 0; | |
| 534 | + c = getc(lf.f); /* re-read first character */ | |
| 557 | 535 | } |
| 558 | − ungetc(c, lf.f); | |
| 536 | + lf.first = c; /* 'c' is the first character of the stream */ | |
| 559 | 537 | status = lua_load(L, getF, &lf, lua_tostring(L, -1)); |
| 560 | 538 | readstatus = ferror(lf.f); |
| 561 | 539 | if (filename) fclose(lf.f); /* close file (even in case of errors) */ |
| @@ -618,7 +596,7 @@ LUALIB_API int luaL_getmetafield (lua_State *L, int obj, const char *event) { · 56 unmodified lines | ||
| 618 | 596 | |
| 619 | 597 | |
| 620 | 598 | LUALIB_API int luaL_callmeta (lua_State *L, int obj, const char *event) { |
| 621 | − obj = abs_index(L, obj); | |
| 599 | + obj = lua_absindex(L, obj); | |
| 622 | 600 | if (!luaL_getmetafield(L, obj, event)) /* no metafield? */ |
| 623 | 601 | return 0; |
| 624 | 602 | lua_pushvalue(L, obj); |
| @@ -663,13 +641,13 @@ LUALIB_API const char *luaL_tolstring (lua_State *L, int idx, size_t *len) { · 38 unmodified lines | ||
| 663 | 641 | |
| 664 | 642 | static int libsize (const luaL_Reg *l) { |
| 665 | 643 | int size = 0; |
| 666 | − for (; l->name; l++) size++; | |
| 644 | + for (; l && l->name; l++) size++; | |
| 667 | 645 | return size; |
| 668 | 646 | } |
| 669 | 647 | |
| 670 | 648 | |
| 671 | −LUALIB_API void luaL_register (lua_State *L, const char *libname, | |
| 672 | − const luaL_Reg *l) { | |
| 649 | +LUALIB_API void luaL_openlib (lua_State *L, const char *libname, | |
| 650 | + const luaL_Reg *l, int nup) { | |
| 673 | 651 | luaL_checkversion(L); |
| 674 | 652 | if (libname) { |
| 675 | 653 | /* check whether lib already exists */ |
| @@ -685,12 +663,17 @@ LUALIB_API void luaL_register (lua_State *L, const char *libname, · 9 unmodified lines | ||
| 685 | 663 | lua_setfield(L, -3, libname); /* _LOADED[libname] = new table */ |
| 686 | 664 | } |
| 687 | 665 | lua_remove(L, -2); /* remove _LOADED table */ |
| 666 | + lua_insert(L, -(nup + 1)); /* move library table to below upvalues */ | |
| 688 | 667 | } |
| 689 | − if (l == NULL) return; /* nothing to register? */ | |
| 690 | − for (; l->name; l++) { /* else fill the table with given functions */ | |
| 691 | − lua_pushcfunction(L, l->func); | |
| 692 | − lua_setfield(L, -2, l->name); | |
| 668 | + luaL_checkstack(L, nup, "too many upvalues"); | |
| 669 | + for (; l && l->name; l++) { /* fill the table with given functions */ | |
| 670 | + int i; | |
| 671 | + for (i = 0; i < nup; i++) /* copy upvalues to the top */ | |
| 672 | + lua_pushvalue(L, -nup); | |
| 673 | + lua_pushcclosure(L, l->func, nup); | |
| 674 | + lua_setfield(L, -(nup + 2), l->name); | |
| 693 | 675 | } |
| 676 | + lua_pop(L, nup); /* remove upvalues */ | |
| 694 | 677 | } |
| 695 | 678 | |
| 696 | 679 | |
| @@ -751,7 +734,7 @@ static void *l_alloc (void *ud, void *ptr, size_t osize, size_t nsize) { · 54 unmodified lines | ||
| 751 | 734 | |
| 752 | 735 | |
| 753 | 736 | static int panic (lua_State *L) { |
| 754 | − fprintf(stderr, "PANIC: unprotected error in call to Lua API (%s)\n", | |
| 737 | + luai_writestringerror("PANIC: unprotected error in call to Lua API (%s)\n", | |
| 755 | 738 | lua_tostring(L, -1)); |
| 756 | 739 | return 0; /* return to Lua to abort */ |
| 757 | 740 | } |
| @@ -1,5 +1,5 @@ | ||
| 1 | 1 | /* |
| 2 | −** $Id: lauxlib.h,v 1.99 2010/01/11 16:00:45 roberto Exp $ | |
| 2 | +** $Id: lauxlib.h,v 1.105 2010/05/04 17:21:08 roberto Exp $ | |
| 3 | 3 | ** Auxiliary functions for building Lua libraries |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| @@ -29,11 +29,11 @@ typedef struct luaL_Reg { · 23 unmodified lines | ||
| 29 | 29 | LUALIB_API void (luaL_checkversion_) (lua_State *L, lua_Number ver); |
| 30 | 30 | #define luaL_checkversion(L) luaL_checkversion_(L, LUA_VERSION_NUM) |
| 31 | 31 | |
| 32 | −LUALIB_API void (luaL_register) (lua_State *L, const char *libname, | |
| 33 | − const luaL_Reg *l); | |
| 32 | +LUALIB_API void (luaL_openlib) (lua_State *L, const char *libname, | |
| 33 | + const luaL_Reg *l, int nup); | |
| 34 | 34 | LUALIB_API int (luaL_getmetafield) (lua_State *L, int obj, const char *e); |
| 35 | 35 | LUALIB_API int (luaL_callmeta) (lua_State *L, int obj, const char *e); |
| 36 | −LUALIB_API const char *luaL_tolstring (lua_State *L, int idx, size_t *len); | |
| 36 | +LUALIB_API const char *(luaL_tolstring) (lua_State *L, int idx, size_t *len); | |
| 37 | 37 | LUALIB_API int (luaL_typeerror) (lua_State *L, int narg, const char *tname); |
| 38 | 38 | LUALIB_API int (luaL_argerror) (lua_State *L, int numarg, const char *extramsg); |
| 39 | 39 | LUALIB_API const char *(luaL_checklstring) (lua_State *L, int numArg, |
| @@ -71,7 +71,7 @@ LUALIB_API int (luaL_loadstring) (lua_State *L, const char *s); · 31 unmodified lines | ||
| 71 | 71 | |
| 72 | 72 | LUALIB_API lua_State *(luaL_newstate) (void); |
| 73 | 73 | |
| 74 | −LUALIB_API int luaL_len (lua_State *L, int idx); | |
| 74 | +LUALIB_API int (luaL_len) (lua_State *L, int idx); | |
| 75 | 75 | |
| 76 | 76 | LUALIB_API const char *(luaL_gsub) (lua_State *L, const char *s, const char *p, |
| 77 | 77 | const char *r); |
| @@ -79,9 +79,8 @@ LUALIB_API const char *(luaL_gsub) (lua_State *L, const char *s, const char *p, · 1 unmodified line | ||
| 79 | 79 | LUALIB_API const char *(luaL_findtable) (lua_State *L, int idx, |
| 80 | 80 | const char *fname, int szhint); |
| 81 | 81 | |
| 82 | −LUALIB_API void luaL_traceback (lua_State *L, lua_State *L1, | |
| 83 | − const char *msg, int level); | |
| 84 | − | |
| 82 | +LUALIB_API void (luaL_traceback) (lua_State *L, lua_State *L1, | |
| 83 | + const char *msg, int level); | |
| 85 | 84 | |
| 86 | 85 | |
| 87 | 86 | /* |
| @@ -111,34 +110,40 @@ LUALIB_API void luaL_traceback (lua_State *L, lua_State *L1, · 23 unmodified lines | ||
| 111 | 110 | |
| 112 | 111 | #define luaL_opt(L,f,n,d) (lua_isnoneornil(L,(n)) ? (d) : f(L,(n))) |
| 113 | 112 | |
| 113 | +#define luaL_register(L,n,l) (luaL_openlib(L,(n),(l),0)) | |
| 114 | + | |
| 115 | + | |
| 114 | 116 | /* |
| 115 | 117 | ** {====================================================== |
| 116 | 118 | ** Generic Buffer manipulation |
| 117 | 119 | ** ======================================================= |
| 118 | 120 | */ |
| 119 | 121 | |
| 120 | − | |
| 121 | − | |
| 122 | 122 | typedef struct luaL_Buffer { |
| 123 | − char *p; /* current position in buffer */ | |
| 124 | − int lvl; /* number of strings in the stack (level) */ | |
| 123 | + char *b; /* buffer address */ | |
| 124 | + size_t size; /* buffer size */ | |
| 125 | + size_t n; /* number of characters in buffer */ | |
| 125 | 126 | lua_State *L; |
| 126 | − char buffer[LUAL_BUFFERSIZE]; | |
| 127 | + char initb[LUAL_BUFFERSIZE]; /* initial buffer */ | |
| 127 | 128 | } luaL_Buffer; |
| 128 | 129 | |
| 130 | + | |
| 129 | 131 | #define luaL_addchar(B,c) \ |
| 130 | − ((void)((B)->p < ((B)->buffer+LUAL_BUFFERSIZE) || luaL_prepbuffer(B)), \ | |
| 131 | − (*(B)->p++ = (char)(c))) | |
| 132 | + ((void)((B)->n < (B)->size || luaL_prepbuffsize((B), 1)), \ | |
| 133 | + ((B)->b[(B)->n++] = (c))) | |
| 132 | 134 | |
| 133 | −#define luaL_addsize(B,n) ((B)->p += (n)) | |
| 135 | +#define luaL_addsize(B,s) ((B)->n += (s)) | |
| 134 | 136 | |
| 135 | 137 | LUALIB_API void (luaL_buffinit) (lua_State *L, luaL_Buffer *B); |
| 136 | −LUALIB_API char *(luaL_prepbuffer) (luaL_Buffer *B); | |
| 138 | +LUALIB_API char *(luaL_prepbuffsize) (luaL_Buffer *B, size_t sz); | |
| 137 | 139 | LUALIB_API void (luaL_addlstring) (luaL_Buffer *B, const char *s, size_t l); |
| 138 | 140 | LUALIB_API void (luaL_addstring) (luaL_Buffer *B, const char *s); |
| 139 | 141 | LUALIB_API void (luaL_addvalue) (luaL_Buffer *B); |
| 140 | 142 | LUALIB_API void (luaL_pushresult) (luaL_Buffer *B); |
| 143 | +LUALIB_API void (luaL_pushresultsize) (luaL_Buffer *B, size_t sz); | |
| 144 | +LUALIB_API char *(luaL_buffinitsize) (lua_State *L, luaL_Buffer *B, size_t sz); | |
| 141 | 145 | |
| 146 | +#define luaL_prepbuffer(B) luaL_prepbuffsize(B, LUAL_BUFFERSIZE) | |
| 142 | 147 | |
| 143 | 148 | /* }====================================================== */ |
| 144 | 149 | |
| @@ -1,5 +1,5 @@ | ||
| 1 | 1 | /* |
| 2 | −** $Id: lbaselib.c,v 1.235 2009/12/28 16:30:31 roberto Exp $ | |
| 2 | +** $Id: lbaselib.c,v 1.243 2010/04/19 17:02:02 roberto Exp $ | |
| 3 | 3 | ** Basic library |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| @@ -23,7 +23,7 @@ · 17 unmodified lines | ||
| 23 | 23 | static int luaB_print (lua_State *L) { |
| 24 | 24 | int n = lua_gettop(L); /* number of arguments */ |
| 25 | 25 | int i; |
| 26 | − lua_getfield(L, LUA_ENVIRONINDEX, "tostring"); | |
| 26 | + lua_getglobal(L, "tostring"); | |
| 27 | 27 | for (i=1; i<=n; i++) { |
| 28 | 28 | const char *s; |
| 29 | 29 | size_t l; |
| @@ -107,50 +107,12 @@ static int luaB_setmetatable (lua_State *L) { · 77 unmodified lines | ||
| 107 | 107 | } |
| 108 | 108 | |
| 109 | 109 | |
| 110 | − | |
| 111 | −#if defined(LUA_COMPAT_FENV) | |
| 112 | − | |
| 113 | −static void getfunc (lua_State *L, int opt) { | |
| 114 | − if (lua_isfunction(L, 1)) lua_pushvalue(L, 1); | |
| 115 | − else { | |
| 116 | − lua_Debug ar; | |
| 117 | − int level = opt ? luaL_optint(L, 1, 1) : luaL_checkint(L, 1); | |
| 118 | − luaL_argcheck(L, level >= 0, 1, "level must be non-negative"); | |
| 119 | − if (lua_getstack(L, level, &ar) == 0) | |
| 120 | − luaL_argerror(L, 1, "invalid level"); | |
| 121 | − lua_getinfo(L, "f", &ar); | |
| 122 | − } | |
| 123 | −} | |
| 124 | − | |
| 125 | −static int luaB_getfenv (lua_State *L) { | |
| 126 | − getfunc(L, 1); | |
| 127 | − if (lua_iscfunction(L, -1)) /* is a C function? */ | |
| 128 | − lua_pushglobaltable(L); /* return the global env. */ | |
| 129 | − else | |
| 130 | − lua_getfenv(L, -1); | |
| 131 | − return 1; | |
| 132 | −} | |
| 133 | − | |
| 134 | −static int luaB_setfenv (lua_State *L) { | |
| 135 | − luaL_checktype(L, 2, LUA_TTABLE); | |
| 136 | − getfunc(L, 0); | |
| 137 | − lua_pushvalue(L, 2); | |
| 138 | − if (lua_iscfunction(L, -2) || lua_setfenv(L, -2) == 0) | |
| 139 | − return luaL_error(L, | |
| 140 | − LUA_QL("setfenv") " cannot change environment of given object"); | |
| 141 | − return 1; | |
| 142 | −} | |
| 143 | − | |
| 144 | −#else | |
| 145 | − | |
| 146 | 110 | static int luaB_getfenv (lua_State *L) { |
| 147 | 111 | return luaL_error(L, "getfenv/setfenv deprecated"); |
| 148 | 112 | } |
| 149 | 113 | |
| 150 | 114 | #define luaB_setfenv luaB_getfenv |
| 151 | 115 | |
| 152 | −#endif | |
| 153 | − | |
| 154 | 116 | |
| 155 | 117 | static int luaB_rawequal (lua_State *L) { |
| 156 | 118 | luaL_checkany(L, 1); |
| @@ -178,18 +140,13 @@ static int luaB_rawset (lua_State *L) { · 21 unmodified lines | ||
| 178 | 140 | } |
| 179 | 141 | |
| 180 | 142 | |
| 181 | −static int luaB_gcinfo (lua_State *L) { | |
| 182 | − lua_pushinteger(L, lua_gc(L, LUA_GCCOUNT, 0)); | |
| 183 | − return 1; | |
| 184 | −} | |
| 185 | − | |
| 186 | − | |
| 187 | 143 | static int luaB_collectgarbage (lua_State *L) { |
| 188 | 144 | static const char *const opts[] = {"stop", "restart", "collect", |
| 189 | − "count", "step", "setpause", "setstepmul", "isrunning", NULL}; | |
| 145 | + "count", "step", "setpause", "setstepmul", "isrunning", | |
| 146 | + "gen", "inc", NULL}; | |
| 190 | 147 | static const int optsnum[] = {LUA_GCSTOP, LUA_GCRESTART, LUA_GCCOLLECT, |
| 191 | 148 | LUA_GCCOUNT, LUA_GCSTEP, LUA_GCSETPAUSE, LUA_GCSETSTEPMUL, |
| 192 | − LUA_GCISRUNNING}; | |
| 149 | + LUA_GCISRUNNING, LUA_GCGEN, LUA_GCINC}; | |
| 193 | 150 | int o = optsnum[luaL_checkoption(L, 1, "collect", opts)]; |
| 194 | 151 | int ex = luaL_optint(L, 2, 0); |
| 195 | 152 | int res = lua_gc(L, o, ex); |
| @@ -219,10 +176,11 @@ static int luaB_type (lua_State *L) { · 23 unmodified lines | ||
| 219 | 176 | } |
| 220 | 177 | |
| 221 | 178 | |
| 222 | −static int pairsmeta (lua_State *L, const char *method, int iszero) { | |
| 179 | +static int pairsmeta (lua_State *L, const char *method, int iszero, | |
| 180 | + lua_CFunction iter) { | |
| 223 | 181 | if (!luaL_getmetafield(L, 1, method)) { /* no metamethod? */ |
| 224 | 182 | luaL_checktype(L, 1, LUA_TTABLE); /* argument must be a table */ |
| 225 | − lua_pushvalue(L, lua_upvalueindex(1)); /* will return generator, */ | |
| 183 | + lua_pushcfunction(L, iter); /* will return generator, */ | |
| 226 | 184 | lua_pushvalue(L, 1); /* state, */ |
| 227 | 185 | if (iszero) lua_pushinteger(L, 0); /* and initial value */ |
| 228 | 186 | else lua_pushnil(L); |
| @@ -248,10 +206,12 @@ static int luaB_next (lua_State *L) { · 19 unmodified lines | ||
| 248 | 206 | |
| 249 | 207 | |
| 250 | 208 | static int luaB_pairs (lua_State *L) { |
| 251 | − return pairsmeta(L, "__pairs", 0); | |
| 209 | + return pairsmeta(L, "__pairs", 0, luaB_next); | |
| 252 | 210 | } |
| 253 | 211 | |
| 254 | 212 | |
| 213 | +#if defined(LUA_COMPAT_IPAIRS) | |
| 214 | + | |
| 255 | 215 | static int ipairsaux (lua_State *L) { |
| 256 | 216 | int i = luaL_checkint(L, 2); |
| 257 | 217 | luaL_checktype(L, 1, LUA_TTABLE); |
| @@ -263,9 +223,17 @@ static int ipairsaux (lua_State *L) { · 5 unmodified lines | ||
| 263 | 223 | |
| 264 | 224 | |
| 265 | 225 | static int luaB_ipairs (lua_State *L) { |
| 266 | − return pairsmeta(L, "__ipairs", 1); | |
| 226 | + return pairsmeta(L, "__ipairs", 1, ipairsaux); | |
| 227 | +} | |
| 228 | + | |
| 229 | +#else | |
| 230 | + | |
| 231 | +static int luaB_ipairs (lua_State *L) { | |
| 232 | + return luaL_error(L, "'ipairs' deprecated"); | |
| 267 | 233 | } |
| 268 | 234 | |
| 235 | +#endif | |
| 236 | + | |
| 269 | 237 | |
| 270 | 238 | static int load_aux (lua_State *L, int status) { |
| 271 | 239 | if (status == LUA_OK) |
| @@ -376,7 +344,7 @@ static int luaB_loadin (lua_State *L) { · 104 unmodified lines | ||
| 376 | 344 | n = luaB_load_aux(L, 2); |
| 377 | 345 | if (n == 1) { /* success? */ |
| 378 | 346 | lua_pushvalue(L, 1); /* environment for loaded function */ |
| 379 | − lua_setfenv(L, -2); | |
| 347 | + lua_setupvalue(L, -2, 1); | |
| 380 | 348 | } |
| 381 | 349 | return n; |
| 382 | 350 | } |
| @@ -507,14 +475,15 @@ static const luaL_Reg base_funcs[] = { · 124 unmodified lines | ||
| 507 | 475 | {"collectgarbage", luaB_collectgarbage}, |
| 508 | 476 | {"dofile", luaB_dofile}, |
| 509 | 477 | {"error", luaB_error}, |
| 510 | − {"gcinfo", luaB_gcinfo}, | |
| 511 | 478 | {"getfenv", luaB_getfenv}, |
| 512 | 479 | {"getmetatable", luaB_getmetatable}, |
| 480 | + {"ipairs", luaB_ipairs}, | |
| 513 | 481 | {"loadfile", luaB_loadfile}, |
| 514 | 482 | {"load", luaB_load}, |
| 515 | 483 | {"loadin", luaB_loadin}, |
| 516 | 484 | {"loadstring", luaB_loadstring}, |
| 517 | 485 | {"next", luaB_next}, |
| 486 | + {"pairs", luaB_pairs}, | |
| 518 | 487 | {"pcall", luaB_pcall}, |
| 519 | 488 | {"print", luaB_print}, |
| 520 | 489 | {"rawequal", luaB_rawequal}, |
| @@ -668,25 +637,15 @@ static const luaL_Reg co_funcs[] = { · 147 unmodified lines | ||
| 668 | 637 | /* }====================================================== */ |
| 669 | 638 | |
| 670 | 639 | |
| 671 | −static void auxopen (lua_State *L, const char *name, | |
| 672 | − lua_CFunction f, lua_CFunction u) { | |
| 673 | − lua_pushcfunction(L, u); | |
| 674 | − lua_pushcclosure(L, f, 1); | |
| 675 | − lua_setfield(L, -2, name); | |
| 676 | −} | |
| 677 | − | |
| 678 | − | |
| 679 | 640 | static void base_open (lua_State *L) { |
| 680 | 641 | /* set global _G */ |
| 681 | 642 | lua_pushglobaltable(L); |
| 682 | − lua_setfield(L, LUA_ENVIRONINDEX, "_G"); | |
| 643 | + lua_pushglobaltable(L); | |
| 644 | + lua_setfield(L, -2, "_G"); | |
| 683 | 645 | /* open lib into global table */ |
| 684 | 646 | luaL_register(L, "_G", base_funcs); |
| 685 | 647 | lua_pushliteral(L, LUA_VERSION); |
| 686 | − lua_setfield(L, LUA_ENVIRONINDEX, "_VERSION"); /* set global _VERSION */ | |
| 687 | − /* `ipairs' and `pairs' need auxiliary functions as upvalues */ | |
| 688 | − auxopen(L, "ipairs", luaB_ipairs, ipairsaux); | |
| 689 | − auxopen(L, "pairs", luaB_pairs, luaB_next); | |
| 648 | + lua_setfield(L, -2, "_VERSION"); /* set global _VERSION */ | |
| 690 | 649 | /* `newproxy' needs a weaktable as upvalue */ |
| 691 | 650 | lua_createtable(L, 0, 1); /* new table `w' */ |
| 692 | 651 | lua_pushvalue(L, -1); /* `w' will be its own metatable */ |
| @@ -694,7 +653,7 @@ static void base_open (lua_State *L) { · 1 unmodified line | ||
| 694 | 653 | lua_pushliteral(L, "kv"); |
| 695 | 654 | lua_setfield(L, -2, "__mode"); /* metatable(w).__mode = "kv" */ |
| 696 | 655 | lua_pushcclosure(L, luaB_newproxy, 1); |
| 697 | − lua_setfield(L, LUA_ENVIRONINDEX, "newproxy"); /* set global `newproxy' */ | |
| 656 | + lua_setfield(L, -2, "newproxy"); /* set global `newproxy' */ | |
| 698 | 657 | } |
| 699 | 658 | |
| 700 | 659 | |
| @@ -1,5 +1,5 @@ | ||
| 1 | 1 | /* |
| 2 | −** $Id: lbitlib.c,v 1.3 2010/01/12 19:40:02 roberto Exp $ | |
| 2 | +** $Id: lbitlib.c,v 1.4 2010/02/11 15:55:29 roberto Exp $ | |
| 3 | 3 | ** Standard library for bitwise operations |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| @@ -80,9 +80,8 @@ static int b_not (lua_State *L) { · 74 unmodified lines | ||
| 80 | 80 | } |
| 81 | 81 | |
| 82 | 82 | |
| 83 | −static int b_shift (lua_State *L) { | |
| 83 | +static int b_shift (lua_State *L, int i) { | |
| 84 | 84 | b_uint r = getuintarg(L, 1); |
| 85 | − lua_Integer i = luaL_checkinteger(L, 2); | |
| 86 | 85 | if (i < 0) { /* shift right? */ |
| 87 | 86 | i = -i; |
| 88 | 87 | if (i >= NBITS) r = 0; |
| @@ -97,9 +96,18 @@ static int b_shift (lua_State *L) { · 8 unmodified lines | ||
| 97 | 96 | } |
| 98 | 97 | |
| 99 | 98 | |
| 100 | −static int b_rotate (lua_State *L) { | |
| 99 | +static int b_lshift (lua_State *L) { | |
| 100 | + return b_shift(L, luaL_checkint(L, 2)); | |
| 101 | +} | |
| 102 | + | |
| 103 | + | |
| 104 | +static int b_rshift (lua_State *L) { | |
| 105 | + return b_shift(L, -luaL_checkint(L, 2)); | |
| 106 | +} | |
| 107 | + | |
| 108 | + | |
| 109 | +static int b_rot (lua_State *L, int i) { | |
| 101 | 110 | b_uint r = getuintarg(L, 1); |
| 102 | − lua_Integer i = luaL_checkinteger(L, 2); | |
| 103 | 111 | i &= (NBITS - 1); /* i = i % NBITS */ |
| 104 | 112 | r = (r << i) | (r >> (NBITS - i)); |
| 105 | 113 | lua_pushnumber(L, lua_uint2number(r)); |
| @@ -107,14 +115,26 @@ static int b_rotate (lua_State *L) { · 1 unmodified line | ||
| 107 | 115 | } |
| 108 | 116 | |
| 109 | 117 | |
| 118 | +static int b_rol (lua_State *L) { | |
| 119 | + return b_rot(L, luaL_checkint(L, 2)); | |
| 120 | +} | |
| 121 | + | |
| 122 | + | |
| 123 | +static int b_ror (lua_State *L) { | |
| 124 | + return b_rot(L, -luaL_checkint(L, 2)); | |
| 125 | +} | |
| 126 | + | |
| 127 | + | |
| 110 | 128 | static const luaL_Reg bitlib[] = { |
| 111 | 129 | {"band", b_and}, |
| 112 | 130 | {"btest", b_test}, |
| 113 | 131 | {"bor", b_or}, |
| 114 | 132 | {"bxor", b_xor}, |
| 115 | 133 | {"bnot", b_not}, |
| 116 | − {"bshift", b_shift}, | |
| 117 | − {"brotate", b_rotate}, | |
| 134 | + {"lshift", b_lshift}, | |
| 135 | + {"rshift", b_rshift}, | |
| 136 | + {"rol", b_rol}, | |
| 137 | + {"ror", b_ror}, | |
| 118 | 138 | {NULL, NULL} |
| 119 | 139 | }; |
| 120 | 140 | |
| @@ -1,5 +1,5 @@ | ||
| 1 | 1 | /* |
| 2 | −** $Id: lcode.c,v 2.43 2010/01/11 17:38:30 roberto Exp $ | |
| 2 | +** $Id: lcode.c,v 2.46 2010/04/17 12:46:32 roberto Exp $ | |
| 3 | 3 | ** Code generator for Lua |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| @@ -372,11 +372,6 @@ void luaK_dischargevars (FuncState *fs, expdesc *e) { · 366 unmodified lines | ||
| 372 | 372 | e->k = VRELOCABLE; |
| 373 | 373 | break; |
| 374 | 374 | } |
| 375 | − case VGLOBAL: { | |
| 376 | − e->u.s.info = luaK_codeABxX(fs, OP_GETGLOBAL, 0, e->u.s.info); | |
| 377 | − e->k = VRELOCABLE; | |
| 378 | − break; | |
| 379 | − } | |
| 380 | 375 | case VINDEXED: { |
| 381 | 376 | freereg(fs, e->u.s.aux); |
| 382 | 377 | freereg(fs, e->u.s.info); |
| @@ -384,6 +379,12 @@ void luaK_dischargevars (FuncState *fs, expdesc *e) { · 1 unmodified line | ||
| 384 | 379 | e->k = VRELOCABLE; |
| 385 | 380 | break; |
| 386 | 381 | } |
| 382 | + case VINDEXEDUP: { | |
| 383 | + freereg(fs, e->u.s.aux); | |
| 384 | + e->u.s.info = luaK_codeABC(fs, OP_GETTABUP, 0, e->u.s.info, e->u.s.aux); | |
| 385 | + e->k = VRELOCABLE; | |
| 386 | + break; | |
| 387 | + } | |
| 387 | 388 | case VVARARG: |
| 388 | 389 | case VCALL: { |
| 389 | 390 | luaK_setoneret(fs, e); |
| @@ -493,6 +494,12 @@ int luaK_exp2anyreg (FuncState *fs, expdesc *e) { · 103 unmodified lines | ||
| 493 | 494 | } |
| 494 | 495 | |
| 495 | 496 | |
| 497 | +void luaK_exp2anyregup (FuncState *fs, expdesc *e) { | |
| 498 | + if (e->k != VUPVAL || hasjumps(e)) | |
| 499 | + luaK_exp2anyreg(fs, e); | |
| 500 | +} | |
| 501 | + | |
| 502 | + | |
| 496 | 503 | void luaK_exp2val (FuncState *fs, expdesc *e) { |
| 497 | 504 | if (hasjumps(e)) |
| 498 | 505 | luaK_exp2anyreg(fs, e); |
| @@ -543,16 +550,16 @@ void luaK_storevar (FuncState *fs, expdesc *var, expdesc *ex) { · 44 unmodified lines | ||
| 543 | 550 | luaK_codeABC(fs, OP_SETUPVAL, e, var->u.s.info, 0); |
| 544 | 551 | break; |
| 545 | 552 | } |
| 546 | − case VGLOBAL: { | |
| 547 | − int e = luaK_exp2anyreg(fs, ex); | |
| 548 | − luaK_codeABxX(fs, OP_SETGLOBAL, e, var->u.s.info); | |
| 549 | − break; | |
| 550 | − } | |
| 551 | 553 | case VINDEXED: { |
| 552 | 554 | int e = luaK_exp2RK(fs, ex); |
| 553 | 555 | luaK_codeABC(fs, OP_SETTABLE, var->u.s.info, var->u.s.aux, e); |
| 554 | 556 | break; |
| 555 | 557 | } |
| 558 | + case VINDEXEDUP: { | |
| 559 | + int e = luaK_exp2RK(fs, ex); | |
| 560 | + luaK_codeABC(fs, OP_SETTABUP, var->u.s.info, var->u.s.aux, e); | |
| 561 | + break; | |
| 562 | + } | |
| 556 | 563 | default: { |
| 557 | 564 | lua_assert(0); /* invalid var kind to store */ |
| 558 | 565 | break; |
| @@ -567,9 +574,9 @@ void luaK_self (FuncState *fs, expdesc *e, expdesc *key) { · 8 unmodified lines | ||
| 567 | 574 | luaK_exp2anyreg(fs, e); |
| 568 | 575 | freeexp(fs, e); |
| 569 | 576 | func = fs->freereg; |
| 570 | − luaK_reserveregs(fs, 2); | |
| 571 | 577 | luaK_codeABC(fs, OP_SELF, func, e->u.s.info, luaK_exp2RK(fs, key)); |
| 572 | 578 | freeexp(fs, key); |
| 579 | + luaK_reserveregs(fs, 2); | |
| 573 | 580 | e->u.s.info = func; |
| 574 | 581 | e->k = VNONRELOC; |
| 575 | 582 | } |
| @@ -695,8 +702,9 @@ static void codenot (FuncState *fs, expdesc *e) { · 119 unmodified lines | ||
| 695 | 702 | |
| 696 | 703 | |
| 697 | 704 | void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k) { |
| 705 | + lua_assert(!hasjumps(t)); | |
| 698 | 706 | t->u.s.aux = luaK_exp2RK(fs, k); |
| 699 | − t->k = VINDEXED; | |
| 707 | + t->k = (t->k == VUPVAL) ? VINDEXEDUP : VINDEXED; | |
| 700 | 708 | } |
| 701 | 709 | |
| 702 | 710 | |
| @@ -711,7 +719,8 @@ static int constfolding (OpCode op, expdesc *e1, expdesc *e2) { · 8 unmodified lines | ||
| 711 | 719 | } |
| 712 | 720 | |
| 713 | 721 | |
| 714 | −static void codearith (FuncState *fs, OpCode op, expdesc *e1, expdesc *e2) { | |
| 722 | +static void codearith (FuncState *fs, OpCode op, | |
| 723 | + expdesc *e1, expdesc *e2, int line) { | |
| 715 | 724 | if (constfolding(op, e1, e2)) |
| 716 | 725 | return; |
| 717 | 726 | else { |
| @@ -727,6 +736,7 @@ static void codearith (FuncState *fs, OpCode op, expdesc *e1, expdesc *e2) { · 9 unmodified lines | ||
| 727 | 736 | } |
| 728 | 737 | e1->u.s.info = luaK_codeABC(fs, op, 0, o1, o2); |
| 729 | 738 | e1->k = VRELOCABLE; |
| 739 | + luaK_fixline(fs, line); | |
| 730 | 740 | } |
| 731 | 741 | } |
| 732 | 742 | |
| @@ -747,7 +757,7 @@ static void codecomp (FuncState *fs, OpCode op, int cond, expdesc *e1, · 14 unmodified lines | ||
| 747 | 757 | } |
| 748 | 758 | |
| 749 | 759 | |
| 750 | −void luaK_prefix (FuncState *fs, UnOpr op, expdesc *e) { | |
| 760 | +void luaK_prefix (FuncState *fs, UnOpr op, expdesc *e, int line) { | |
| 751 | 761 | expdesc e2; |
| 752 | 762 | e2.t = e2.f = NO_JUMP; e2.k = VKNUM; e2.u.nval = 0; |
| 753 | 763 | switch (op) { |
| @@ -756,14 +766,14 @@ void luaK_prefix (FuncState *fs, UnOpr op, expdesc *e) { · 2 unmodified lines | ||
| 756 | 766 | e->u.nval = luai_numunm(NULL, e->u.nval); /* fold it */ |
| 757 | 767 | else { |
| 758 | 768 | luaK_exp2anyreg(fs, e); |
| 759 | − codearith(fs, OP_UNM, e, &e2); | |
| 769 | + codearith(fs, OP_UNM, e, &e2, line); | |
| 760 | 770 | } |
| 761 | 771 | break; |
| 762 | 772 | } |
| 763 | 773 | case OPR_NOT: codenot(fs, e); break; |
| 764 | 774 | case OPR_LEN: { |
| 765 | 775 | luaK_exp2anyreg(fs, e); /* cannot operate on constants */ |
| 766 | − codearith(fs, OP_LEN, e, &e2); | |
| 776 | + codearith(fs, OP_LEN, e, &e2, line); | |
| 767 | 777 | break; |
| 768 | 778 | } |
| 769 | 779 | default: lua_assert(0); |
| @@ -798,7 +808,8 @@ void luaK_infix (FuncState *fs, BinOpr op, expdesc *v) { · 28 unmodified lines | ||
| 798 | 808 | } |
| 799 | 809 | |
| 800 | 810 | |
| 801 | −void luaK_posfix (FuncState *fs, BinOpr op, expdesc *e1, expdesc *e2) { | |
| 811 | +void luaK_posfix (FuncState *fs, BinOpr op, | |
| 812 | + expdesc *e1, expdesc *e2, int line) { | |
| 802 | 813 | switch (op) { |
| 803 | 814 | case OPR_AND: { |
| 804 | 815 | lua_assert(e1->t == NO_JUMP); /* list must be closed */ |
| @@ -824,13 +835,13 @@ void luaK_posfix (FuncState *fs, BinOpr op, expdesc *e1, expdesc *e2) { · 19 unmodified lines | ||
| 824 | 835 | } |
| 825 | 836 | else { |
| 826 | 837 | luaK_exp2nextreg(fs, e2); /* operand must be on the 'stack' */ |
| 827 | − codearith(fs, OP_CONCAT, e1, e2); | |
| 838 | + codearith(fs, OP_CONCAT, e1, e2, line); | |
| 828 | 839 | } |
| 829 | 840 | break; |
| 830 | 841 | } |
| 831 | 842 | case OPR_ADD: case OPR_SUB: case OPR_MUL: case OPR_DIV: |
| 832 | 843 | case OPR_MOD: case OPR_POW: { |
| 833 | − codearith(fs, cast(OpCode, op - OPR_ADD + OP_ADD), e1, e2); | |
| 844 | + codearith(fs, cast(OpCode, op - OPR_ADD + OP_ADD), e1, e2, line); | |
| 834 | 845 | break; |
| 835 | 846 | } |
| 836 | 847 | case OPR_EQ: case OPR_LT: case OPR_LE: { |
| @@ -1,5 +1,5 @@ | ||
| 1 | 1 | /* |
| 2 | −** $Id: lcode.h,v 1.52 2009/09/23 20:33:05 roberto Exp $ | |
| 2 | +** $Id: lcode.h,v 1.54 2010/04/17 12:46:32 roberto Exp $ | |
| 3 | 3 | ** Code generator for Lua |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| @@ -57,6 +57,7 @@ LUAI_FUNC int luaK_stringK (FuncState *fs, TString *s); · 51 unmodified lines | ||
| 57 | 57 | LUAI_FUNC int luaK_numberK (FuncState *fs, lua_Number r); |
| 58 | 58 | LUAI_FUNC void luaK_dischargevars (FuncState *fs, expdesc *e); |
| 59 | 59 | LUAI_FUNC int luaK_exp2anyreg (FuncState *fs, expdesc *e); |
| 60 | +LUAI_FUNC void luaK_exp2anyregup (FuncState *fs, expdesc *e); | |
| 60 | 61 | LUAI_FUNC void luaK_exp2nextreg (FuncState *fs, expdesc *e); |
| 61 | 62 | LUAI_FUNC void luaK_exp2val (FuncState *fs, expdesc *e); |
| 62 | 63 | LUAI_FUNC int luaK_exp2RK (FuncState *fs, expdesc *e); |
| @@ -72,9 +73,10 @@ LUAI_FUNC void luaK_patchlist (FuncState *fs, int list, int target); · 9 unmodified lines | ||
| 72 | 73 | LUAI_FUNC void luaK_patchtohere (FuncState *fs, int list); |
| 73 | 74 | LUAI_FUNC void luaK_concat (FuncState *fs, int *l1, int l2); |
| 74 | 75 | LUAI_FUNC int luaK_getlabel (FuncState *fs); |
| 75 | −LUAI_FUNC void luaK_prefix (FuncState *fs, UnOpr op, expdesc *v); | |
| 76 | +LUAI_FUNC void luaK_prefix (FuncState *fs, UnOpr op, expdesc *v, int line); | |
| 76 | 77 | LUAI_FUNC void luaK_infix (FuncState *fs, BinOpr op, expdesc *v); |
| 77 | −LUAI_FUNC void luaK_posfix (FuncState *fs, BinOpr op, expdesc *v1, expdesc *v2); | |
| 78 | +LUAI_FUNC void luaK_posfix (FuncState *fs, BinOpr op, expdesc *v1, | |
| 79 | + expdesc *v2, int line); | |
| 78 | 80 | LUAI_FUNC void luaK_setlist (FuncState *fs, int base, int nelems, int tostore); |
| 79 | 81 | |
| 80 | 82 | |
| @@ -1,5 +1,5 @@ | ||
| 1 | 1 | /* |
| 2 | −** $Id: ldblib.c,v 1.119 2010/01/06 14:42:35 roberto Exp $ | |
| 2 | +** $Id: ldblib.c,v 1.121 2010/03/26 20:58:11 roberto Exp $ | |
| 3 | 3 | ** Interface from Lua to its debug API |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| @@ -44,19 +44,19 @@ static int db_setmetatable (lua_State *L) { · 38 unmodified lines | ||
| 44 | 44 | } |
| 45 | 45 | |
| 46 | 46 | |
| 47 | −static int db_getfenv (lua_State *L) { | |
| 48 | − luaL_checkany(L, 1); | |
| 49 | − lua_getfenv(L, 1); | |
| 47 | +static int db_getenv (lua_State *L) { | |
| 48 | + luaL_checktype(L, 1, LUA_TUSERDATA); | |
| 49 | + lua_getenv(L, 1); | |
| 50 | 50 | return 1; |
| 51 | 51 | } |
| 52 | 52 | |
| 53 | 53 | |
| 54 | −static int db_setfenv (lua_State *L) { | |
| 55 | − luaL_checktype(L, 2, LUA_TTABLE); | |
| 54 | +static int db_setenv (lua_State *L) { | |
| 55 | + luaL_checktype(L, 1, LUA_TUSERDATA); | |
| 56 | + if (!lua_isnoneornil(L, 2)) | |
| 57 | + luaL_checktype(L, 2, LUA_TTABLE); | |
| 56 | 58 | lua_settop(L, 2); |
| 57 | − if (lua_setfenv(L, 1) == 0) | |
| 58 | − luaL_error(L, LUA_QL("setfenv") | |
| 59 | − " cannot change environment of given object"); | |
| 59 | + lua_setenv(L, 1); | |
| 60 | 60 | return 1; |
| 61 | 61 | } |
| 62 | 62 | |
| @@ -339,15 +339,13 @@ static int db_gethook (lua_State *L) { · 276 unmodified lines | ||
| 339 | 339 | static int db_debug (lua_State *L) { |
| 340 | 340 | for (;;) { |
| 341 | 341 | char buffer[250]; |
| 342 | − fputs("lua_debug> ", stderr); | |
| 342 | + luai_writestringerror("%s", "lua_debug> "); | |
| 343 | 343 | if (fgets(buffer, sizeof(buffer), stdin) == 0 || |
| 344 | 344 | strcmp(buffer, "cont\n") == 0) |
| 345 | 345 | return 0; |
| 346 | 346 | if (luaL_loadbuffer(L, buffer, strlen(buffer), "=(debug command)") || |
| 347 | − lua_pcall(L, 0, 0, 0)) { | |
| 348 | − fputs(lua_tostring(L, -1), stderr); | |
| 349 | − fputs("\n", stderr); | |
| 350 | − } | |
| 347 | + lua_pcall(L, 0, 0, 0)) | |
| 348 | + luai_writestringerror("%s\n", lua_tostring(L, -1)); | |
| 351 | 349 | lua_settop(L, 0); /* remove eventual returns */ |
| 352 | 350 | } |
| 353 | 351 | } |
| @@ -369,7 +367,7 @@ static int db_traceback (lua_State *L) { · 15 unmodified lines | ||
| 369 | 367 | |
| 370 | 368 | static const luaL_Reg dblib[] = { |
| 371 | 369 | {"debug", db_debug}, |
| 372 | − {"getfenv", db_getfenv}, | |
| 370 | + {"getenv", db_getenv}, | |
| 373 | 371 | {"gethook", db_gethook}, |
| 374 | 372 | {"getinfo", db_getinfo}, |
| 375 | 373 | {"getlocal", db_getlocal}, |
| @@ -378,7 +376,7 @@ static const luaL_Reg dblib[] = { · 2 unmodified lines | ||
| 378 | 376 | {"getupvalue", db_getupvalue}, |
| 379 | 377 | {"upvaluejoin", db_upvaluejoin}, |
| 380 | 378 | {"upvalueid", db_upvalueid}, |
| 381 | − {"setfenv", db_setfenv}, | |
| 379 | + {"setenv", db_setenv}, | |
| 382 | 380 | {"sethook", db_sethook}, |
| 383 | 381 | {"setlocal", db_setlocal}, |
| 384 | 382 | {"setmetatable", db_setmetatable}, |
| @@ -1,5 +1,5 @@ | ||
| 1 | 1 | /* |
| 2 | −** $Id: ldebug.c,v 2.63 2010/01/13 16:18:25 roberto Exp $ | |
| 2 | +** $Id: ldebug.c,v 2.70 2010/04/13 20:48:12 roberto Exp $ | |
| 3 | 3 | ** Debug Interface |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| @@ -144,7 +144,7 @@ LUA_API const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int n) { · 138 unmodified lines | ||
| 144 | 144 | |
| 145 | 145 | |
| 146 | 146 | static void funcinfo (lua_Debug *ar, Closure *cl) { |
| 147 | − if (cl->c.isC) { | |
| 147 | + if (cl == NULL || cl->c.isC) { | |
| 148 | 148 | ar->source = "=[C]"; |
| 149 | 149 | ar->linedefined = -1; |
| 150 | 150 | ar->lastlinedefined = -1; |
| @@ -191,8 +191,8 @@ static int auxgetinfo (lua_State *L, const char *what, lua_Debug *ar, · 40 unmodified lines | ||
| 191 | 191 | break; |
| 192 | 192 | } |
| 193 | 193 | case 'u': { |
| 194 | − ar->nups = f->c.nupvalues; | |
| 195 | − if (f->c.isC) { | |
| 194 | + ar->nups = (f == NULL) ? 0 : f->c.nupvalues; | |
| 195 | + if (f == NULL || f->c.isC) { | |
| 196 | 196 | ar->isvararg = 1; |
| 197 | 197 | ar->nparams = 0; |
| 198 | 198 | } |
| @@ -226,28 +226,30 @@ static int auxgetinfo (lua_State *L, const char *what, lua_Debug *ar, · 27 unmodified lines | ||
| 226 | 226 | |
| 227 | 227 | LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar) { |
| 228 | 228 | int status; |
| 229 | − Closure *f = NULL; | |
| 230 | − CallInfo *ci = NULL; | |
| 229 | + Closure *cl; | |
| 230 | + CallInfo *ci; | |
| 231 | + StkId func; | |
| 231 | 232 | lua_lock(L); |
| 232 | 233 | if (*what == '>') { |
| 233 | − StkId func = L->top - 1; | |
| 234 | + ci = NULL; | |
| 235 | + func = L->top - 1; | |
| 234 | 236 | luai_apicheck(L, ttisfunction(func)); |
| 235 | 237 | what++; /* skip the '>' */ |
| 236 | − f = clvalue(func); | |
| 237 | 238 | L->top--; /* pop function */ |
| 238 | 239 | } |
| 239 | 240 | else { |
| 240 | 241 | ci = ar->i_ci; |
| 242 | + func = ci->func; | |
| 241 | 243 | lua_assert(ttisfunction(ci->func)); |
| 242 | − f = clvalue(ci->func); | |
| 243 | 244 | } |
| 244 | − status = auxgetinfo(L, what, ar, f, ci); | |
| 245 | + cl = ttisclosure(func) ? clvalue(func) : NULL; | |
| 246 | + status = auxgetinfo(L, what, ar, cl, ci); | |
| 245 | 247 | if (strchr(what, 'f')) { |
| 246 | − setclvalue(L, L->top, f); | |
| 248 | + setobjs2s(L, L->top, func); | |
| 247 | 249 | incr_top(L); |
| 248 | 250 | } |
| 249 | 251 | if (strchr(what, 'L')) |
| 250 | − collectvalidlines(L, f); | |
| 252 | + collectvalidlines(L, cl); | |
| 251 | 253 | lua_unlock(L); |
| 252 | 254 | return status; |
| 253 | 255 | } |
| @@ -260,22 +262,23 @@ LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar) { · 6 unmodified lines | ||
| 260 | 262 | */ |
| 261 | 263 | |
| 262 | 264 | |
| 263 | −static const char *kname (Proto *p, int c) { | |
| 264 | − if (ISK(c) && ttisstring(&p->k[INDEXK(c)])) | |
| 265 | − return svalue(&p->k[INDEXK(c)]); | |
| 265 | +static void kname (Proto *p, int c, int reg, const char *what, | |
| 266 | + const char **name) { | |
| 267 | + if (c == reg && *what == 'c') | |
| 268 | + return; /* index is a constant; name already correct */ | |
| 269 | + else if (ISK(c) && ttisstring(&p->k[INDEXK(c)])) | |
| 270 | + *name = svalue(&p->k[INDEXK(c)]); | |
| 266 | 271 | else |
| 267 | − return "?"; | |
| 272 | + *name = "?"; | |
| 268 | 273 | } |
| 269 | 274 | |
| 270 | 275 | |
| 271 | 276 | static const char *getobjname (lua_State *L, CallInfo *ci, int reg, |
| 272 | 277 | const char **name) { |
| 273 | − Proto *p; | |
| 274 | − int lastpc, pc; | |
| 278 | + Proto *p = ci_func(ci)->l.p; | |
| 275 | 279 | const char *what = NULL; |
| 276 | − lua_assert(isLua(ci)); | |
| 277 | − p = ci_func(ci)->l.p; | |
| 278 | − lastpc = currentpc(ci); | |
| 280 | + int lastpc = currentpc(ci); | |
| 281 | + int pc; | |
| 279 | 282 | *name = luaF_getlocalname(p, reg + 1, lastpc); |
| 280 | 283 | if (*name) /* is a local? */ |
| 281 | 284 | return "local"; |
| @@ -285,17 +288,6 @@ static const char *getobjname (lua_State *L, CallInfo *ci, int reg, · 3 unmodified lines | ||
| 285 | 288 | OpCode op = GET_OPCODE(i); |
| 286 | 289 | int a = GETARG_A(i); |
| 287 | 290 | switch (op) { |
| 288 | − case OP_GETGLOBAL: { | |
| 289 | − if (reg == a) { | |
| 290 | − int g = GETARG_Bx(i); | |
| 291 | − if (g != 0) g--; | |
| 292 | − else g = GETARG_Ax(p->code[++pc]); | |
| 293 | − lua_assert(ttisstring(&p->k[g])); | |
| 294 | − *name = svalue(&p->k[g]); | |
| 295 | − what = "global"; | |
| 296 | − } | |
| 297 | − break; | |
| 298 | − } | |
| 299 | 291 | case OP_MOVE: { |
| 300 | 292 | if (reg == a) { |
| 301 | 293 | int b = GETARG_B(i); /* move from 'b' to 'a' */ |
| @@ -305,11 +297,16 @@ static const char *getobjname (lua_State *L, CallInfo *ci, int reg, · 3 unmodified lines | ||
| 305 | 297 | } |
| 306 | 298 | break; |
| 307 | 299 | } |
| 300 | + case OP_GETTABUP: | |
| 308 | 301 | case OP_GETTABLE: { |
| 309 | 302 | if (reg == a) { |
| 310 | 303 | int k = GETARG_C(i); /* key index */ |
| 311 | − *name = kname(p, k); | |
| 312 | − what = "field"; | |
| 304 | + int t = GETARG_B(i); | |
| 305 | + const char *vn = (op == OP_GETTABLE) /* name of indexed variable */ | |
| 306 | + ? luaF_getlocalname(p, t + 1, pc) | |
| 307 | + : getstr(p->upvalues[t].name); | |
| 308 | + kname(p, k, a, what, name); | |
| 309 | + what = (vn && strcmp(vn, "_ENV") == 0) ? "global" : "field"; | |
| 313 | 310 | } |
| 314 | 311 | break; |
| 315 | 312 | } |
| @@ -322,6 +319,17 @@ static const char *getobjname (lua_State *L, CallInfo *ci, int reg, · 6 unmodified lines | ||
| 322 | 319 | } |
| 323 | 320 | break; |
| 324 | 321 | } |
| 322 | + case OP_LOADK: { | |
| 323 | + if (reg == a) { | |
| 324 | + int b = GETARG_Bx(i); | |
| 325 | + b = (b > 0) ? b - 1 : GETARG_Ax(p->code[pc + 1]); | |
| 326 | + if (ttisstring(&p->k[b])) { | |
| 327 | + what = "constant"; | |
| 328 | + *name = svalue(&p->k[b]); | |
| 329 | + } | |
| 330 | + } | |
| 331 | + break; | |
| 332 | + } | |
| 325 | 333 | case OP_LOADNIL: { |
| 326 | 334 | int b = GETARG_B(i); /* move from 'b' to 'a' */ |
| 327 | 335 | if (a <= reg && reg <= b) /* set registers from 'a' to 'b' */ |
| @@ -331,7 +339,7 @@ static const char *getobjname (lua_State *L, CallInfo *ci, int reg, · 3 unmodified lines | ||
| 331 | 339 | case OP_SELF: { |
| 332 | 340 | if (reg == a) { |
| 333 | 341 | int k = GETARG_C(i); /* key index */ |
| 334 | − *name = kname(p, k); | |
| 342 | + kname(p, k, a, what, name); | |
| 335 | 343 | what = "method"; |
| 336 | 344 | } |
| 337 | 345 | break; |
| @@ -374,12 +382,15 @@ static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name) { · 36 unmodified lines | ||
| 374 | 382 | switch (GET_OPCODE(i)) { |
| 375 | 383 | case OP_CALL: |
| 376 | 384 | case OP_TAILCALL: |
| 377 | − case OP_TFORLOOP: | |
| 378 | 385 | return getobjname(L, ci, GETARG_A(i), name); |
| 379 | − case OP_GETGLOBAL: | |
| 386 | + case OP_TFORCALL: { | |
| 387 | + *name = "for iterator"; | |
| 388 | + return "for iterator"; | |
| 389 | + } | |
| 380 | 390 | case OP_SELF: |
| 391 | + case OP_GETTABUP: | |
| 381 | 392 | case OP_GETTABLE: tm = TM_INDEX; break; |
| 382 | − case OP_SETGLOBAL: | |
| 393 | + case OP_SETTABUP: | |
| 383 | 394 | case OP_SETTABLE: tm = TM_NEWINDEX; break; |
| 384 | 395 | case OP_EQ: tm = TM_EQ; break; |
| 385 | 396 | case OP_ADD: tm = TM_ADD; break; |
| @@ -413,13 +424,30 @@ static int isinstack (CallInfo *ci, const TValue *o) { · 27 unmodified lines | ||
| 413 | 424 | } |
| 414 | 425 | |
| 415 | 426 | |
| 427 | +static const char *getupvalname (CallInfo *ci, const TValue *o, | |
| 428 | + const char **name) { | |
| 429 | + LClosure *c = &ci_func(ci)->l; | |
| 430 | + int i; | |
| 431 | + for (i = 0; i < c->nupvalues; i++) { | |
| 432 | + if (c->upvals[i]->v == o) { | |
| 433 | + *name = getstr(c->p->upvalues[i].name); | |
| 434 | + return "upvalue"; | |
| 435 | + } | |
| 436 | + } | |
| 437 | + return NULL; | |
| 438 | +} | |
| 439 | + | |
| 440 | + | |
| 416 | 441 | void luaG_typeerror (lua_State *L, const TValue *o, const char *op) { |
| 417 | 442 | CallInfo *ci = L->ci; |
| 418 | 443 | const char *name = NULL; |
| 419 | − const char *t = typename(ttype(o)); | |
| 420 | − const char *kind = (isLua(ci) && isinstack(ci, o)) ? | |
| 421 | − getobjname(L, ci, cast_int(o - ci->u.l.base), &name) : | |
| 422 | − NULL; | |
| 444 | + const char *t = objtypename(o); | |
| 445 | + const char *kind = NULL; | |
| 446 | + if (isLua(ci)) { | |
| 447 | + kind = getupvalname(ci, o, &name); /* check whether 'o' is an upvalue */ | |
| 448 | + if (!kind && isinstack(ci, o)) /* no? try a register */ | |
| 449 | + kind = getobjname(L, ci, cast_int(o - ci->u.l.base), &name); | |
| 450 | + } | |
| 423 | 451 | if (kind) |
| 424 | 452 | luaG_runerror(L, "attempt to %s %s " LUA_QS " (a %s value)", |
| 425 | 453 | op, kind, name, t); |
| @@ -444,8 +472,8 @@ void luaG_aritherror (lua_State *L, const TValue *p1, const TValue *p2) { · 18 unmodified lines | ||
| 444 | 472 | |
| 445 | 473 | |
| 446 | 474 | int luaG_ordererror (lua_State *L, const TValue *p1, const TValue *p2) { |
| 447 | − const char *t1 = typename(ttype(p1)); | |
| 448 | − const char *t2 = typename(ttype(p2)); | |
| 475 | + const char *t1 = objtypename(p1); | |
| 476 | + const char *t2 = objtypename(p2); | |
| 449 | 477 | if (t1 == t2) |
| 450 | 478 | luaG_runerror(L, "attempt to compare two %s values", t1); |
| 451 | 479 | else |
| @@ -1,5 +1,5 @@ | ||
| 1 | 1 | /* |
| 2 | −** $Id: ldo.c,v 2.80 2010/01/13 16:17:32 roberto Exp $ | |
| 2 | +** $Id: ldo.c,v 2.87 2010/05/05 18:49:56 roberto Exp $ | |
| 3 | 3 | ** Stack and Call structure of Lua |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| @@ -48,7 +48,7 @@ · 42 unmodified lines | ||
| 48 | 48 | */ |
| 49 | 49 | #if !defined(LUAI_THROW) |
| 50 | 50 | |
| 51 | −#if defined(__cplusplus) | |
| 51 | +#if defined(__cplusplus) && !defined(LUA_USE_LONGJMP) | |
| 52 | 52 | /* C++ exceptions */ |
| 53 | 53 | #define LUAI_THROW(L,c) throw(c) |
| 54 | 54 | #define LUAI_TRY(L,c,a) \ |
| @@ -83,8 +83,8 @@ struct lua_longjmp { · 28 unmodified lines | ||
| 83 | 83 | |
| 84 | 84 | static void seterrorobj (lua_State *L, int errcode, StkId oldtop) { |
| 85 | 85 | switch (errcode) { |
| 86 | − case LUA_ERRMEM: { | |
| 87 | − setsvalue2s(L, oldtop, luaS_newliteral(L, MEMERRMSG)); | |
| 86 | + case LUA_ERRMEM: { /* memory error? */ | |
| 87 | + setsvalue2s(L, oldtop, G(L)->memerrmsg); /* reuse preregistered msg. */ | |
| 88 | 88 | break; |
| 89 | 89 | } |
| 90 | 90 | case LUA_ERRERR: { |
| @@ -293,18 +293,43 @@ static StkId tryfuncTM (lua_State *L, StkId func) { · 202 unmodified lines | ||
| 293 | 293 | ** returns true if function has been executed (C function) |
| 294 | 294 | */ |
| 295 | 295 | int luaD_precall (lua_State *L, StkId func, int nresults) { |
| 296 | − LClosure *cl; | |
| 296 | + Closure *cl; | |
| 297 | + lua_CFunction f; | |
| 297 | 298 | ptrdiff_t funcr; |
| 298 | 299 | if (!ttisfunction(func)) /* `func' is not a function? */ |
| 299 | 300 | func = tryfuncTM(L, func); /* check the `function' tag method */ |
| 300 | 301 | funcr = savestack(L, func); |
| 301 | − cl = &clvalue(func)->l; | |
| 302 | 302 | L->ci->nresults = nresults; |
| 303 | − if (!cl->isC) { /* Lua function? prepare its call */ | |
| 303 | + if (ttislcf(func)) { /* light C function? */ | |
| 304 | + f = fvalue(func); /* get it */ | |
| 305 | + goto isCfunc; /* go to call it */ | |
| 306 | + } | |
| 307 | + cl = clvalue(func); | |
| 308 | + if (cl->c.isC) { /* C closure? */ | |
| 309 | + CallInfo *ci; | |
| 310 | + int n; | |
| 311 | + f = cl->c.f; | |
| 312 | + isCfunc: /* call C function 'f' */ | |
| 313 | + luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */ | |
| 314 | + ci = next_ci(L); /* now 'enter' new function */ | |
| 315 | + ci->func = restorestack(L, funcr); | |
| 316 | + ci->top = L->top + LUA_MINSTACK; | |
| 317 | + lua_assert(ci->top <= L->stack_last); | |
| 318 | + ci->callstatus = 0; | |
| 319 | + if (L->hookmask & LUA_MASKCALL) | |
| 320 | + luaD_hook(L, LUA_HOOKCALL, -1); | |
| 321 | + lua_unlock(L); | |
| 322 | + n = (*f)(L); /* do the actual call */ | |
| 323 | + lua_lock(L); | |
| 324 | + api_checknelems(L, n); | |
| 325 | + luaD_poscall(L, L->top - n); | |
| 326 | + return 1; | |
| 327 | + } | |
| 328 | + else { /* Lua function: prepare its call */ | |
| 304 | 329 | CallInfo *ci; |
| 305 | 330 | int nparams, nargs; |
| 306 | 331 | StkId base; |
| 307 | − Proto *p = cl->p; | |
| 332 | + Proto *p = cl->l.p; | |
| 308 | 333 | luaD_checkstack(L, p->maxstacksize); |
| 309 | 334 | func = restorestack(L, funcr); |
| 310 | 335 | nargs = cast_int(L->top - func) - 1; /* number of real arguments */ |
| @@ -327,24 +352,6 @@ int luaD_precall (lua_State *L, StkId func, int nresults) { · 16 unmodified lines | ||
| 327 | 352 | callhook(L, ci); |
| 328 | 353 | return 0; |
| 329 | 354 | } |
| 330 | − else { /* if is a C function, call it */ | |
| 331 | − CallInfo *ci; | |
| 332 | − int n; | |
| 333 | − luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */ | |
| 334 | − ci = next_ci(L); /* now 'enter' new function */ | |
| 335 | − ci->func = restorestack(L, funcr); | |
| 336 | − ci->top = L->top + LUA_MINSTACK; | |
| 337 | − lua_assert(ci->top <= L->stack_last); | |
| 338 | − ci->callstatus = 0; | |
| 339 | − if (L->hookmask & LUA_MASKCALL) | |
| 340 | − luaD_hook(L, LUA_HOOKCALL, -1); | |
| 341 | − lua_unlock(L); | |
| 342 | − n = (*curr_func(L)->c.f)(L); /* do the actual call */ | |
| 343 | − lua_lock(L); | |
| 344 | − api_checknelems(L, n); | |
| 345 | − luaD_poscall(L, L->top - n); | |
| 346 | − return 1; | |
| 347 | − } | |
| 348 | 355 | } |
| 349 | 356 | |
| 350 | 357 | |
| @@ -452,7 +459,7 @@ static int recover (lua_State *L, int status) { · 101 unmodified lines | ||
| 452 | 459 | CallInfo *ci = findpcall(L); |
| 453 | 460 | if (ci == NULL) return 0; /* no recovery point */ |
| 454 | 461 | /* "finish" luaD_pcall */ |
| 455 | − oldtop = restorestack(L, ci->u.c.oldtop); | |
| 462 | + oldtop = restorestack(L, ci->u.c.extra); | |
| 456 | 463 | luaF_close(L, oldtop); |
| 457 | 464 | seterrorobj(L, status, oldtop); |
| 458 | 465 | L->ci = ci; |
| @@ -469,7 +476,7 @@ static int recover (lua_State *L, int status) { · 10 unmodified lines | ||
| 469 | 476 | /* |
| 470 | 477 | ** signal an error in the call to 'resume', not in the execution of the |
| 471 | 478 | ** coroutine itself. (Such errors should not be handled by any coroutine |
| 472 | −** error hanlder and should not kill the coroutine.) | |
| 479 | +** error handler and should not kill the coroutine.) | |
| 473 | 480 | */ |
| 474 | 481 | static void resume_error (lua_State *L, const char *msg, StkId firstArg) { |
| 475 | 482 | L->top = firstArg; /* remove args from the stack */ |
| @@ -501,11 +508,11 @@ static void resume (lua_State *L, void *ud) { · 25 unmodified lines | ||
| 501 | 508 | if (isLua(ci)) /* yielded inside a hook? */ |
| 502 | 509 | luaV_execute(L); /* just continue running Lua code */ |
| 503 | 510 | else { /* 'common' yield */ |
| 511 | + ci->func = restorestack(L, ci->u.c.extra); | |
| 504 | 512 | if (ci->u.c.k != NULL) { /* does it have a continuation? */ |
| 505 | 513 | int n; |
| 506 | 514 | ci->u.c.status = LUA_YIELD; /* 'default' status */ |
| 507 | 515 | ci->callstatus |= CIST_YIELDED; |
| 508 | − ci->func = restorestack(L, ci->u.c.oldtop); | |
| 509 | 516 | lua_unlock(L); |
| 510 | 517 | n = (*ci->u.c.k)(L); /* call continuation */ |
| 511 | 518 | lua_lock(L); |
| @@ -526,6 +533,7 @@ LUA_API int lua_resume (lua_State *L, int nargs) { · 14 unmodified lines | ||
| 526 | 533 | luai_userstateresume(L, nargs); |
| 527 | 534 | ++G(L)->nCcalls; /* count resume */ |
| 528 | 535 | L->nny = 0; /* allow yields */ |
| 536 | + api_checknelems(L, (L->status == LUA_OK) ? nargs + 1 : nargs); | |
| 529 | 537 | status = luaD_rawrunprotected(L, resume, L->top - nargs); |
| 530 | 538 | if (status == -1) /* error calling 'lua_resume'? */ |
| 531 | 539 | status = LUA_ERRRUN; |
| @@ -565,11 +573,10 @@ LUA_API int lua_yieldk (lua_State *L, int nresults, int ctx, lua_CFunction k) { · 33 unmodified lines | ||
| 565 | 573 | api_check(L, k == NULL, "hooks cannot continue after yielding"); |
| 566 | 574 | } |
| 567 | 575 | else { |
| 568 | − if ((ci->u.c.k = k) != NULL) { /* is there a continuation? */ | |
| 576 | + if ((ci->u.c.k = k) != NULL) /* is there a continuation? */ | |
| 569 | 577 | ci->u.c.ctx = ctx; /* save context */ |
| 570 | − ci->u.c.oldtop = savestack(L, ci->func); /* save current 'func' */ | |
| 571 | − } | |
| 572 | − ci->func = L->top - nresults - 1; /* protect stack slots below */ | |
| 578 | + ci->u.c.extra = savestack(L, ci->func); /* save current 'func' */ | |
| 579 | + ci->func = L->top - nresults - 1; /* protect stack below results */ | |
| 573 | 580 | luaD_throw(L, LUA_YIELD); |
| 574 | 581 | } |
| 575 | 582 | lua_assert(ci->callstatus & CIST_HOOKED); /* must be inside a hook */ |
| @@ -623,7 +630,7 @@ static void f_parser (lua_State *L, void *ud) { · 47 unmodified lines | ||
| 623 | 630 | : luaY_parser(L, p->z, &p->buff, &p->varl, p->name); |
| 624 | 631 | setptvalue2s(L, L->top, tf); |
| 625 | 632 | incr_top(L); |
| 626 | − cl = luaF_newLclosure(L, tf->sizeupvalues, G(L)->l_gt); | |
| 633 | + cl = luaF_newLclosure(L, tf->sizeupvalues); | |
| 627 | 634 | cl->l.p = tf; |
| 628 | 635 | setclvalue(L, L->top - 1, cl); |
| 629 | 636 | for (i = 0; i < tf->sizeupvalues; i++) /* initialize upvalues */ |
| @@ -1,5 +1,5 @@ | ||
| 1 | 1 | /* |
| 2 | −** $Id: ldump.c,v 2.12 2009/09/30 15:38:37 roberto Exp $ | |
| 2 | +** $Id: ldump.c,v 2.13 2010/03/12 19:14:06 roberto Exp $ | |
| 3 | 3 | ** save precompiled Lua chunks |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| @@ -145,7 +145,6 @@ static void DumpFunction(const Proto* f, const TString* p, DumpState* D) · 139 unmodified lines | ||
| 145 | 145 | DumpChar(f->numparams,D); |
| 146 | 146 | DumpChar(f->is_vararg,D); |
| 147 | 147 | DumpChar(f->maxstacksize,D); |
| 148 | − DumpChar(f->envreg,D); | |
| 149 | 148 | DumpCode(f,D); |
| 150 | 149 | DumpConstants(f,D); |
| 151 | 150 | DumpUpvalues(f,D); |
| @@ -1,5 +1,5 @@ | ||
| 1 | 1 | /* |
| 2 | −** $Id: lfunc.c,v 2.19 2009/12/16 16:42:58 roberto Exp $ | |
| 2 | +** $Id: lfunc.c,v 2.24 2010/05/10 18:23:45 roberto Exp $ | |
| 3 | 3 | ** Auxiliary functions to manipulate prototypes and closures |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| @@ -21,19 +21,17 @@ · 15 unmodified lines | ||
| 21 | 21 | |
| 22 | 22 | |
| 23 | 23 | |
| 24 | −Closure *luaF_newCclosure (lua_State *L, int n, Table *e) { | |
| 24 | +Closure *luaF_newCclosure (lua_State *L, int n) { | |
| 25 | 25 | Closure *c = &luaC_newobj(L, LUA_TFUNCTION, sizeCclosure(n), NULL, 0)->cl; |
| 26 | 26 | c->c.isC = 1; |
| 27 | − c->c.env = e; | |
| 28 | 27 | c->c.nupvalues = cast_byte(n); |
| 29 | 28 | return c; |
| 30 | 29 | } |
| 31 | 30 | |
| 32 | 31 | |
| 33 | −Closure *luaF_newLclosure (lua_State *L, int n, Table *e) { | |
| 32 | +Closure *luaF_newLclosure (lua_State *L, int n) { | |
| 34 | 33 | Closure *c = &luaC_newobj(L, LUA_TFUNCTION, sizeLclosure(n), NULL, 0)->cl; |
| 35 | 34 | c->l.isC = 0; |
| 36 | − c->l.env = e; | |
| 37 | 35 | c->l.nupvalues = cast_byte(n); |
| 38 | 36 | while (n--) c->l.upvals[n] = NULL; |
| 39 | 37 | return c; |
| @@ -54,12 +52,14 @@ UpVal *luaF_findupval (lua_State *L, StkId level) { · 14 unmodified lines | ||
| 54 | 52 | UpVal *p; |
| 55 | 53 | UpVal *uv; |
| 56 | 54 | while (*pp != NULL && (p = gco2uv(*pp))->v >= level) { |
| 55 | + GCObject *o = obj2gco(p); | |
| 57 | 56 | lua_assert(p->v != &p->u.value); |
| 58 | 57 | if (p->v == level) { /* found a corresponding upvalue? */ |
| 59 | − if (isdead(g, obj2gco(p))) /* is it dead? */ | |
| 60 | − changewhite(obj2gco(p)); /* ressurrect it */ | |
| 58 | + if (isdead(g, o)) /* is it dead? */ | |
| 59 | + changewhite(o); /* ressurrect it */ | |
| 61 | 60 | return p; |
| 62 | 61 | } |
| 62 | + resetoldbit(o); /* may create a newer upval after this one */ | |
| 63 | 63 | pp = &p->next; |
| 64 | 64 | } |
| 65 | 65 | /* not found: create a new one */ |
| @@ -98,10 +98,12 @@ void luaF_close (lua_State *L, StkId level) { · 32 unmodified lines | ||
| 98 | 98 | if (isdead(g, o)) |
| 99 | 99 | luaF_freeupval(L, uv); /* free upvalue */ |
| 100 | 100 | else { |
| 101 | − unlinkupval(uv); | |
| 102 | − setobj(L, &uv->u.value, uv->v); | |
| 101 | + unlinkupval(uv); /* remove upvalue from 'uvhead' list */ | |
| 102 | + setobj(L, &uv->u.value, uv->v); /* move value to upvalue slot */ | |
| 103 | 103 | uv->v = &uv->u.value; /* now current value lives here */ |
| 104 | − luaC_linkupval(L, uv); /* link upvalue into `gcroot' list */ | |
| 104 | + gch(o)->next = g->allgc; /* link upvalue into 'allgc' list */ | |
| 105 | + g->allgc = o; | |
| 106 | + luaC_checkupvalcolor(g, uv); | |
| 105 | 107 | } |
| 106 | 108 | } |
| 107 | 109 | } |
| @@ -127,7 +129,6 @@ Proto *luaF_newproto (lua_State *L) { · 19 unmodified lines | ||
| 127 | 129 | f->linedefined = 0; |
| 128 | 130 | f->lastlinedefined = 0; |
| 129 | 131 | f->source = NULL; |
| 130 | − f->envreg = NO_REG; | |
| 131 | 132 | return f; |
| 132 | 133 | } |
| 133 | 134 | |
| @@ -1,5 +1,5 @@ | ||
| 1 | 1 | /* |
| 2 | −** $Id: lfunc.h,v 2.4 2005/04/25 19:24:10 roberto Exp $ | |
| 2 | +** $Id: lfunc.h,v 2.5 2010/03/26 20:58:11 roberto Exp $ | |
| 3 | 3 | ** Auxiliary functions to manipulate prototypes and closures |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| @@ -19,8 +19,8 @@ · 13 unmodified lines | ||
| 19 | 19 | |
| 20 | 20 | |
| 21 | 21 | LUAI_FUNC Proto *luaF_newproto (lua_State *L); |
| 22 | −LUAI_FUNC Closure *luaF_newCclosure (lua_State *L, int nelems, Table *e); | |
| 23 | −LUAI_FUNC Closure *luaF_newLclosure (lua_State *L, int nelems, Table *e); | |
| 22 | +LUAI_FUNC Closure *luaF_newCclosure (lua_State *L, int nelems); | |
| 23 | +LUAI_FUNC Closure *luaF_newLclosure (lua_State *L, int nelems); | |
| 24 | 24 | LUAI_FUNC UpVal *luaF_newupval (lua_State *L); |
| 25 | 25 | LUAI_FUNC UpVal *luaF_findupval (lua_State *L, StkId level); |
| 26 | 26 | LUAI_FUNC void luaF_close (lua_State *L, StkId level); |
| @@ -1,5 +1,5 @@ | ||
| 1 | 1 | /* |
| 2 | −** $Id: lgc.c,v 2.67 2009/12/22 15:32:50 roberto Exp $ | |
| 2 | +** $Id: lgc.c,v 2.96 2010/05/17 20:39:31 roberto Exp $ | |
| 3 | 3 | ** Garbage Collector |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| @@ -23,21 +23,49 @@ · 17 unmodified lines | ||
| 23 | 23 | #include "ltm.h" |
| 24 | 24 | |
| 25 | 25 | |
| 26 | −#define GCSTEPSIZE 1024u | |
| 26 | + | |
| 27 | +/* how much to allocate before next GC step */ | |
| 28 | +#define GCSTEPSIZE 1024 | |
| 29 | + | |
| 30 | +/* maximum numer of elements to sweep in each single step */ | |
| 27 | 31 | #define GCSWEEPMAX 40 |
| 28 | −#define GCSWEEPCOST 10 | |
| 29 | −#define GCFINALIZECOST 100 | |
| 30 | 32 | |
| 33 | +/* cost of sweeping one element */ | |
| 34 | +#define GCSWEEPCOST 1 | |
| 35 | + | |
| 36 | +/* maximum number of finalizers to call in each GC step */ | |
| 37 | +#define GCFINALIZENUM 4 | |
| 38 | + | |
| 39 | +/* cost of marking the root set */ | |
| 40 | +#define GCROOTCOST 10 | |
| 41 | + | |
| 42 | +/* cost of atomic step */ | |
| 43 | +#define GCATOMICCOST 1000 | |
| 44 | + | |
| 45 | +/* basic cost to traverse one object (to be added to the links the | |
| 46 | + object may have) */ | |
| 47 | +#define TRAVCOST 5 | |
| 31 | 48 | |
| 32 | −#define maskcolors cast_byte(~(bitmask(BLACKBIT)|WHITEBITS)) | |
| 33 | 49 | |
| 50 | +/* | |
| 51 | +** standard negative debt for GC; a reasonable "time" to wait before | |
| 52 | +** starting a new cycle | |
| 53 | +*/ | |
| 54 | +#define stddebt(g) (-cast(l_mem, g->totalbytes/100) * g->gcpause) | |
| 55 | + | |
| 56 | + | |
| 57 | +/* | |
| 58 | +** 'makewhite' erases all color bits plus the old bit and then | |
| 59 | +** sets only the current white bit | |
| 60 | +*/ | |
| 61 | +#define maskcolors (~(bit2mask(BLACKBIT, OLDBIT) | WHITEBITS)) | |
| 34 | 62 | #define makewhite(g,x) \ |
| 35 | 63 | (gch(x)->marked = cast_byte((gch(x)->marked & maskcolors) | luaC_white(g))) |
| 36 | 64 | |
| 37 | 65 | #define white2gray(x) resetbits(gch(x)->marked, WHITEBITS) |
| 38 | 66 | #define black2gray(x) resetbit(gch(x)->marked, BLACKBIT) |
| 39 | 67 | |
| 40 | −#define stringmark(s) resetbits((s)->tsv.marked, WHITEBITS) | |
| 68 | +#define stringmark(s) ((void)((s) && resetbits((s)->tsv.marked, WHITEBITS))) | |
| 41 | 69 | |
| 42 | 70 | |
| 43 | 71 | #define isfinalized(u) testbit((u)->marked, FINALIZEDBIT) |
| @@ -51,7 +79,6 @@ · 7 unmodified lines | ||
| 51 | 79 | #define markobject(g,t) { if ((t) && iswhite(obj2gco(t))) \ |
| 52 | 80 | reallymarkobject(g, obj2gco(t)); } |
| 53 | 81 | |
| 54 | − | |
| 55 | 82 | static void reallymarkobject (global_State *g, GCObject *o); |
| 56 | 83 | |
| 57 | 84 | |
| @@ -61,12 +88,16 @@ static void reallymarkobject (global_State *g, GCObject *o); · 3 unmodified lines | ||
| 61 | 88 | ** ======================================================= |
| 62 | 89 | */ |
| 63 | 90 | |
| 64 | −static void linktable (Table *h, GCObject **p) { | |
| 65 | − h->gclist = *p; | |
| 66 | − *p = obj2gco(h); | |
| 67 | −} | |
| 91 | + | |
| 92 | +/* | |
| 93 | +** link table 'h' into list pointed by 'p' | |
| 94 | +*/ | |
| 95 | +#define linktable(h,p) ((h)->gclist = *(p), *(p) = obj2gco(h)) | |
| 68 | 96 | |
| 69 | 97 | |
| 98 | +/* | |
| 99 | +** mark a table entry as dead (therefore removing it from the table) | |
| 100 | +*/ | |
| 70 | 101 | static void removeentry (Node *n) { |
| 71 | 102 | lua_assert(ttisnil(gval(n))); |
| 72 | 103 | if (iscollectable(gkey(n))) |
| @@ -75,8 +106,8 @@ static void removeentry (Node *n) { · 2 unmodified lines | ||
| 75 | 106 | |
| 76 | 107 | |
| 77 | 108 | /* |
| 78 | −** The next function tells whether a key or value can be cleared from | |
| 79 | −** a weak table. Non-collectable objects are never removed from weak | |
| 109 | +** tells whether a key or value can be cleared from a weak | |
| 110 | +** table. Non-collectable objects are never removed from weak | |
| 80 | 111 | ** tables. Strings behave as `values', so are never removed too. for |
| 81 | 112 | ** other objects: if really collected, cannot keep them; for objects |
| 82 | 113 | ** being finalized, keep them in keys, but not in values |
| @@ -92,24 +123,32 @@ static int iscleared (const TValue *o, int iskey) { · 9 unmodified lines | ||
| 92 | 123 | } |
| 93 | 124 | |
| 94 | 125 | |
| 126 | +/* | |
| 127 | +** barrier that moves collector forward, that is, mark the white object | |
| 128 | +** being pointed by a black object. | |
| 129 | +*/ | |
| 95 | 130 | void luaC_barrierf (lua_State *L, GCObject *o, GCObject *v) { |
| 96 | 131 | global_State *g = G(L); |
| 97 | 132 | lua_assert(isblack(o) && iswhite(v) && !isdead(g, v) && !isdead(g, o)); |
| 98 | − lua_assert(g->gcstate != GCSfinalize && g->gcstate != GCSpause); | |
| 133 | + lua_assert(isgenerational(g) || g->gcstate != GCSpause); | |
| 99 | 134 | lua_assert(gch(o)->tt != LUA_TTABLE); |
| 100 | − /* must keep invariant? */ | |
| 101 | − if (g->gcstate == GCSpropagate) | |
| 135 | + if (keepinvariant(g)) /* must keep invariant? */ | |
| 102 | 136 | reallymarkobject(g, v); /* restore invariant */ |
| 103 | − else /* don't mind */ | |
| 104 | − makewhite(g, o); /* mark as white just to avoid other barriers */ | |
| 137 | + else { /* sweep phase */ | |
| 138 | + lua_assert(issweepphase(g)); | |
| 139 | + makewhite(g, o); /* mark main obj. as white to avoid other barriers */ | |
| 140 | + } | |
| 105 | 141 | } |
| 106 | 142 | |
| 107 | 143 | |
| 144 | +/* | |
| 145 | +** barrier that moves collector backward, that is, mark the black object | |
| 146 | +** pointing to a white object as gray again. | |
| 147 | +*/ | |
| 108 | 148 | void luaC_barrierback (lua_State *L, Table *t) { |
| 109 | 149 | global_State *g = G(L); |
| 110 | 150 | GCObject *o = obj2gco(t); |
| 111 | 151 | lua_assert(isblack(o) && !isdead(g, o)); |
| 112 | − lua_assert(g->gcstate != GCSfinalize && g->gcstate != GCSpause); | |
| 113 | 152 | black2gray(o); /* make table gray (again) */ |
| 114 | 153 | t->gclist = g->grayagain; |
| 115 | 154 | g->grayagain = o; |
| @@ -117,14 +156,37 @@ void luaC_barrierback (lua_State *L, Table *t) { · 1 unmodified line | ||
| 117 | 156 | |
| 118 | 157 | |
| 119 | 158 | /* |
| 120 | −** create a new collectable object and link it to '*list' | |
| 159 | +** check color (and invariants) for an upvalue that was closed, | |
| 160 | +** i.e., moved into the 'allgc' list | |
| 161 | +*/ | |
| 162 | +void luaC_checkupvalcolor (global_State *g, UpVal *uv) { | |
| 163 | + GCObject *o = obj2gco(uv); | |
| 164 | + lua_assert(!isblack(o)); /* open upvalues are never black */ | |
| 165 | + if (isgray(o)) { | |
| 166 | + if (keepinvariant(g)) { | |
| 167 | + resetoldbit(o); /* see MOVE OLD rule */ | |
| 168 | + gray2black(o); /* it is being visited now */ | |
| 169 | + markvalue(g, uv->v); | |
| 170 | + } | |
| 171 | + else { | |
| 172 | + lua_assert(issweepphase(g)); | |
| 173 | + makewhite(g, o); | |
| 174 | + } | |
| 175 | + } | |
| 176 | +} | |
| 177 | + | |
| 178 | + | |
| 179 | +/* | |
| 180 | +** create a new collectable object (with given type and size) and link | |
| 181 | +** it to '*list'. 'offset' tells how many bytes to allocate before the | |
| 182 | +** object itself (used only by states). | |
| 121 | 183 | */ |
| 122 | 184 | GCObject *luaC_newobj (lua_State *L, int tt, size_t sz, GCObject **list, |
| 123 | 185 | int offset) { |
| 124 | 186 | global_State *g = G(L); |
| 125 | 187 | GCObject *o = obj2gco(cast(char *, luaM_newobject(L, tt, sz)) + offset); |
| 126 | 188 | if (list == NULL) |
| 127 | − list = &g->rootgc; /* standard list for collectable objects */ | |
| 189 | + list = &g->allgc; /* standard list for collectable objects */ | |
| 128 | 190 | gch(o)->marked = luaC_white(g); |
| 129 | 191 | gch(o)->tt = tt; |
| 130 | 192 | gch(o)->next = *list; |
| @@ -132,24 +194,6 @@ GCObject *luaC_newobj (lua_State *L, int tt, size_t sz, GCObject **list, · 1 unmodified line | ||
| 132 | 194 | return o; |
| 133 | 195 | } |
| 134 | 196 | |
| 135 | − | |
| 136 | −void luaC_linkupval (lua_State *L, UpVal *uv) { | |
| 137 | − global_State *g = G(L); | |
| 138 | − GCObject *o = obj2gco(uv); | |
| 139 | − gch(o)->next = g->rootgc; /* link upvalue into `rootgc' list */ | |
| 140 | − g->rootgc = o; | |
| 141 | − if (isgray(o)) { | |
| 142 | − if (g->gcstate == GCSpropagate) { | |
| 143 | − gray2black(o); /* closed upvalues need barrier */ | |
| 144 | − luaC_barrier(L, uv, uv->v); | |
| 145 | − } | |
| 146 | − else { /* sweep phase: sweep it (turning it into white) */ | |
| 147 | − makewhite(g, o); | |
| 148 | − lua_assert(g->gcstate != GCSfinalize && g->gcstate != GCSpause); | |
| 149 | − } | |
| 150 | − } | |
| 151 | −} | |
| 152 | − | |
| 153 | 197 | /* }====================================================== */ |
| 154 | 198 | |
| 155 | 199 | |
| @@ -160,25 +204,33 @@ void luaC_linkupval (lua_State *L, UpVal *uv) { · 4 unmodified lines | ||
| 160 | 204 | ** ======================================================= |
| 161 | 205 | */ |
| 162 | 206 | |
| 207 | + | |
| 208 | +/* | |
| 209 | +** mark an object. Userdata and closed upvalues are visited and turned | |
| 210 | +** black here. Strings remain gray (it is the same as making them | |
| 211 | +** black). Other objects are marked gray and added to appropriate list | |
| 212 | +** to be visited (and turned black) later. (Open upvalues are already | |
| 213 | +** linked in 'headuv' list.) | |
| 214 | +*/ | |
| 163 | 215 | static void reallymarkobject (global_State *g, GCObject *o) { |
| 164 | 216 | lua_assert(iswhite(o) && !isdead(g, o)); |
| 165 | 217 | white2gray(o); |
| 166 | 218 | switch (gch(o)->tt) { |
| 167 | 219 | case LUA_TSTRING: { |
| 168 | − return; | |
| 220 | + return; /* for strings, gray is as good as black */ | |
| 169 | 221 | } |
| 170 | 222 | case LUA_TUSERDATA: { |
| 171 | 223 | Table *mt = gco2u(o)->metatable; |
| 172 | − gray2black(o); /* udata are never gray */ | |
| 173 | 224 | markobject(g, mt); |
| 174 | 225 | markobject(g, gco2u(o)->env); |
| 226 | + gray2black(o); /* all pointers marked */ | |
| 175 | 227 | return; |
| 176 | 228 | } |
| 177 | 229 | case LUA_TUPVAL: { |
| 178 | 230 | UpVal *uv = gco2uv(o); |
| 179 | 231 | markvalue(g, uv->v); |
| 180 | − if (uv->v == &uv->u.value) /* closed? */ | |
| 181 | − gray2black(o); /* open upvalues are never black */ | |
| 232 | + if (uv->v == &uv->u.value) /* closed? (open upvalues remain gray) */ | |
| 233 | + gray2black(o); /* make it black */ | |
| 182 | 234 | return; |
| 183 | 235 | } |
| 184 | 236 | case LUA_TFUNCTION: { |
| @@ -205,48 +257,55 @@ static void reallymarkobject (global_State *g, GCObject *o) { · 20 unmodified lines | ||
| 205 | 257 | } |
| 206 | 258 | |
| 207 | 259 | |
| 260 | +/* | |
| 261 | +** mark tag methods for basic types | |
| 262 | +*/ | |
| 208 | 263 | static void markmt (global_State *g) { |
| 209 | 264 | int i; |
| 210 | − for (i=0; i<NUM_TAGS; i++) | |
| 265 | + for (i=0; i < LUA_NUMTAGS; i++) | |
| 211 | 266 | markobject(g, g->mt[i]); |
| 212 | 267 | } |
| 213 | 268 | |
| 214 | 269 | |
| 270 | +/* | |
| 271 | +** mark all objects in list of being-finalized | |
| 272 | +*/ | |
| 215 | 273 | static void markbeingfnz (global_State *g) { |
| 216 | 274 | GCObject *o; |
| 217 | 275 | for (o = g->tobefnz; o != NULL; o = gch(o)->next) { |
| 218 | − lua_assert(testbit(gch(o)->marked, SEPARATED)); | |
| 219 | 276 | makewhite(g, o); |
| 220 | 277 | reallymarkobject(g, o); |
| 221 | 278 | } |
| 222 | 279 | } |
| 223 | 280 | |
| 224 | 281 | |
| 225 | −/* mark root set */ | |
| 226 | −static void markroot (lua_State *L) { | |
| 227 | − global_State *g = G(L); | |
| 228 | − g->gray = NULL; | |
| 229 | − g->grayagain = NULL; | |
| 230 | − g->weak = g->ephemeron = g->allweak = NULL; | |
| 231 | − markobject(g, g->mainthread); | |
| 232 | − /* make global table and registry to be traversed before main stack */ | |
| 233 | − markobject(g, g->l_gt); | |
| 234 | − markvalue(g, &g->l_registry); | |
| 235 | − markmt(g); | |
| 236 | − markbeingfnz(g); /* mark any finalizing object left from previous cycle */ | |
| 237 | − g->gcstate = GCSpropagate; | |
| 238 | −} | |
| 239 | − | |
| 240 | − | |
| 282 | +/* | |
| 283 | +** mark all values stored in marked open upvalues. (See comment in | |
| 284 | +** 'lstate.h'.) | |
| 285 | +*/ | |
| 241 | 286 | static void remarkupvals (global_State *g) { |
| 242 | 287 | UpVal *uv; |
| 243 | 288 | for (uv = g->uvhead.u.l.next; uv != &g->uvhead; uv = uv->u.l.next) { |
| 244 | − lua_assert(uv->u.l.next->u.l.prev == uv && uv->u.l.prev->u.l.next == uv); | |
| 245 | 289 | if (isgray(obj2gco(uv))) |
| 246 | 290 | markvalue(g, uv->v); |
| 247 | 291 | } |
| 248 | 292 | } |
| 249 | 293 | |
| 294 | + | |
| 295 | +/* | |
| 296 | +** mark root set and reset all gray lists, to start a new | |
| 297 | +** incremental (or full) collection | |
| 298 | +*/ | |
| 299 | +static void markroot (lua_State *L) { | |
| 300 | + global_State *g = G(L); | |
| 301 | + g->gray = g->grayagain = NULL; | |
| 302 | + g->weak = g->allweak = g->ephemeron = NULL; | |
| 303 | + markobject(g, g->mainthread); | |
| 304 | + markvalue(g, &g->l_registry); | |
| 305 | + markmt(g); | |
| 306 | + markbeingfnz(g); /* mark any finalizing object left from previous cycle */ | |
| 307 | +} | |
| 308 | + | |
| 250 | 309 | /* }====================================================== */ |
| 251 | 310 | |
| 252 | 311 | |
| @@ -257,49 +316,48 @@ static void remarkupvals (global_State *g) { · 4 unmodified lines | ||
| 257 | 316 | */ |
| 258 | 317 | |
| 259 | 318 | static void traverseweakvalue (global_State *g, Table *h) { |
| 260 | − int i = sizenode(h); | |
| 261 | − while (i--) { | |
| 262 | − Node *n = gnode(h, i); | |
| 319 | + Node *n, *limit = gnode(h, sizenode(h)); | |
| 320 | + for (n = gnode(h, 0); n < limit; n++) { | |
| 263 | 321 | checkdeadkey(n); |
| 264 | − if (ttisnil(gval(n))) | |
| 265 | − removeentry(n); /* remove empty entries */ | |
| 322 | + if (ttisnil(gval(n))) /* entry is empty? */ | |
| 323 | + removeentry(n); /* remove it */ | |
| 266 | 324 | else { |
| 267 | 325 | lua_assert(!ttisnil(gkey(n))); |
| 268 | − markvalue(g, gkey(n)); | |
| 326 | + markvalue(g, gkey(n)); /* mark key */ | |
| 269 | 327 | } |
| 270 | 328 | } |
| 271 | − linktable(h, &g->weak); | |
| 329 | + linktable(h, &g->weak); /* link into appropriate list */ | |
| 272 | 330 | } |
| 273 | 331 | |
| 274 | 332 | |
| 275 | 333 | static int traverseephemeron (global_State *g, Table *h) { |
| 276 | − int marked = 0; | |
| 277 | − int hasclears = 0; | |
| 278 | − int i = h->sizearray; | |
| 279 | − while (i--) { /* mark array part (numeric keys are 'strong') */ | |
| 334 | + int marked = 0; /* true if an object is marked in this traversal */ | |
| 335 | + int hasclears = 0; /* true if table has unmarked pairs */ | |
| 336 | + Node *n, *limit = gnode(h, sizenode(h)); | |
| 337 | + int i; | |
| 338 | + /* traverse array part (numeric keys are 'strong') */ | |
| 339 | + for (i = 0; i < h->sizearray; i++) { | |
| 280 | 340 | if (valiswhite(&h->array[i])) { |
| 281 | 341 | marked = 1; |
| 282 | 342 | reallymarkobject(g, gcvalue(&h->array[i])); |
| 283 | 343 | } |
| 284 | 344 | } |
| 285 | − i = sizenode(h); | |
| 286 | − while (i--) { | |
| 287 | − Node *n = gnode(h, i); | |
| 345 | + /* traverse hash part */ | |
| 346 | + for (n = gnode(h, 0); n < limit; n++) { | |
| 288 | 347 | checkdeadkey(n); |
| 289 | 348 | if (ttisnil(gval(n))) /* entry is empty? */ |
| 290 | 349 | removeentry(n); /* remove it */ |
| 291 | − else if (valiswhite(gval(n))) { | |
| 292 | − /* value is not marked yet */ | |
| 350 | + else if (valiswhite(gval(n))) { /* value not marked yet? */ | |
| 293 | 351 | if (iscleared(key2tval(n), 1)) /* key is not marked (yet)? */ |
| 294 | 352 | hasclears = 1; /* may have to propagate mark from key to value */ |
| 295 | − else { /* mark value only if key is marked */ | |
| 296 | − marked = 1; /* some mark changed status */ | |
| 353 | + else { /* key is marked, so mark value */ | |
| 354 | + marked = 1; /* value was not marked */ | |
| 297 | 355 | reallymarkobject(g, gcvalue(gval(n))); |
| 298 | 356 | } |
| 299 | 357 | } |
| 300 | 358 | } |
| 301 | − if (hasclears) | |
| 302 | − linktable(h, &g->ephemeron); | |
| 359 | + if (hasclears) /* does table have unmarked pairs? */ | |
| 360 | + linktable(h, &g->ephemeron); /* will have to propagate again */ | |
| 303 | 361 | else /* nothing to propagate */ |
| 304 | 362 | linktable(h, &g->weak); /* avoid convergence phase */ |
| 305 | 363 | return marked; |
| @@ -307,26 +365,24 @@ static int traverseephemeron (global_State *g, Table *h) { · 1 unmodified line | ||
| 307 | 365 | |
| 308 | 366 | |
| 309 | 367 | static void traversestrongtable (global_State *g, Table *h) { |
| 368 | + Node *n, *limit = gnode(h, sizenode(h)); | |
| 310 | 369 | int i; |
| 311 | − i = h->sizearray; | |
| 312 | − while (i--) | |
| 370 | + for (i = 0; i < h->sizearray; i++) /* traverse array part */ | |
| 313 | 371 | markvalue(g, &h->array[i]); |
| 314 | − i = sizenode(h); | |
| 315 | − while (i--) { | |
| 316 | − Node *n = gnode(h, i); | |
| 372 | + for (n = gnode(h, 0); n < limit; n++) { /* traverse hash part */ | |
| 317 | 373 | checkdeadkey(n); |
| 318 | − if (ttisnil(gval(n))) | |
| 319 | − removeentry(n); /* remove empty entries */ | |
| 374 | + if (ttisnil(gval(n))) /* entry is empty? */ | |
| 375 | + removeentry(n); /* remove it */ | |
| 320 | 376 | else { |
| 321 | 377 | lua_assert(!ttisnil(gkey(n))); |
| 322 | − markvalue(g, gkey(n)); | |
| 323 | − markvalue(g, gval(n)); | |
| 378 | + markvalue(g, gkey(n)); /* mark key */ | |
| 379 | + markvalue(g, gval(n)); /* mark value */ | |
| 324 | 380 | } |
| 325 | 381 | } |
| 326 | 382 | } |
| 327 | 383 | |
| 328 | 384 | |
| 329 | −static void traversetable (global_State *g, Table *h) { | |
| 385 | +static int traversetable (global_State *g, Table *h) { | |
| 330 | 386 | const TValue *mode = gfasttm(g, h->metatable, TM_MODE); |
| 331 | 387 | markobject(g, h->metatable); |
| 332 | 388 | if (mode && ttisstring(mode)) { /* is there a weak mode? */ |
| @@ -334,43 +390,41 @@ static void traversetable (global_State *g, Table *h) { · 1 unmodified line | ||
| 334 | 390 | int weakvalue = (strchr(svalue(mode), 'v') != NULL); |
| 335 | 391 | if (weakkey || weakvalue) { /* is really weak? */ |
| 336 | 392 | black2gray(obj2gco(h)); /* keep table gray */ |
| 337 | − if (!weakkey) /* strong keys? */ | |
| 393 | + if (!weakkey) { /* strong keys? */ | |
| 338 | 394 | traverseweakvalue(g, h); |
| 339 | − else if (!weakvalue) /* strong values? */ | |
| 395 | + return TRAVCOST + sizenode(h); | |
| 396 | + } | |
| 397 | + else if (!weakvalue) { /* strong values? */ | |
| 340 | 398 | traverseephemeron(g, h); |
| 341 | − else | |
| 399 | + return TRAVCOST + h->sizearray + sizenode(h); | |
| 400 | + } | |
| 401 | + else { | |
| 342 | 402 | linktable(h, &g->allweak); /* nothing to traverse now */ |
| 343 | − return; | |
| 403 | + return TRAVCOST; | |
| 404 | + } | |
| 344 | 405 | } /* else go through */ |
| 345 | 406 | } |
| 346 | 407 | traversestrongtable(g, h); |
| 408 | + return TRAVCOST + h->sizearray + (2 * sizenode(h)); | |
| 347 | 409 | } |
| 348 | 410 | |
| 349 | 411 | |
| 350 | −/* | |
| 351 | −** All marks are conditional because a GC may happen while the | |
| 352 | −** prototype is still being created | |
| 353 | −*/ | |
| 354 | −static void traverseproto (global_State *g, Proto *f) { | |
| 412 | +static int traverseproto (global_State *g, Proto *f) { | |
| 355 | 413 | int i; |
| 356 | − if (f->source) stringmark(f->source); | |
| 357 | − for (i=0; i<f->sizek; i++) /* mark literals */ | |
| 414 | + stringmark(f->source); | |
| 415 | + for (i = 0; i < f->sizek; i++) /* mark literals */ | |
| 358 | 416 | markvalue(g, &f->k[i]); |
| 359 | − for (i=0; i<f->sizeupvalues; i++) { /* mark upvalue names */ | |
| 360 | − if (f->upvalues[i].name) | |
| 361 | − stringmark(f->upvalues[i].name); | |
| 362 | − } | |
| 363 | − for (i=0; i<f->sizep; i++) /* mark nested protos */ | |
| 417 | + for (i = 0; i < f->sizeupvalues; i++) /* mark upvalue names */ | |
| 418 | + stringmark(f->upvalues[i].name); | |
| 419 | + for (i = 0; i < f->sizep; i++) /* mark nested protos */ | |
| 364 | 420 | markobject(g, f->p[i]); |
| 365 | − for (i=0; i<f->sizelocvars; i++) { /* mark local-variable names */ | |
| 366 | − if (f->locvars[i].varname) | |
| 367 | − stringmark(f->locvars[i].varname); | |
| 368 | − } | |
| 421 | + for (i = 0; i < f->sizelocvars; i++) /* mark local-variable names */ | |
| 422 | + stringmark(f->locvars[i].varname); | |
| 423 | + return TRAVCOST + f->sizek + f->sizeupvalues + f->sizep + f->sizelocvars; | |
| 369 | 424 | } |
| 370 | 425 | |
| 371 | 426 | |
| 372 | −static void traverseclosure (global_State *g, Closure *cl) { | |
| 373 | − markobject(g, cl->c.env); | |
| 427 | +static l_mem traverseclosure (global_State *g, Closure *cl) { | |
| 374 | 428 | if (cl->c.isC) { |
| 375 | 429 | int i; |
| 376 | 430 | for (i=0; i<cl->c.nupvalues; i++) /* mark its upvalues */ |
| @@ -379,32 +433,35 @@ static void traverseclosure (global_State *g, Closure *cl) { · 2 unmodified lines | ||
| 379 | 433 | else { |
| 380 | 434 | int i; |
| 381 | 435 | lua_assert(cl->l.nupvalues == cl->l.p->sizeupvalues); |
| 382 | − markobject(g, cl->l.p); | |
| 436 | + markobject(g, cl->l.p); /* mark its prototype */ | |
| 383 | 437 | for (i=0; i<cl->l.nupvalues; i++) /* mark its upvalues */ |
| 384 | 438 | markobject(g, cl->l.upvals[i]); |
| 385 | 439 | } |
| 440 | + return TRAVCOST + cl->c.nupvalues; | |
| 386 | 441 | } |
| 387 | 442 | |
| 388 | 443 | |
| 389 | −static void traversestack (global_State *g, lua_State *L) { | |
| 390 | − StkId o; | |
| 391 | − if (L->stack == NULL) | |
| 392 | − return; /* stack not completely built yet */ | |
| 393 | − for (o = L->stack; o < L->top; o++) | |
| 444 | +static int traversestack (global_State *g, lua_State *L) { | |
| 445 | + StkId o = L->stack; | |
| 446 | + if (o == NULL) | |
| 447 | + return 1; /* stack not completely built yet */ | |
| 448 | + for (; o < L->top; o++) | |
| 394 | 449 | markvalue(g, o); |
| 395 | 450 | if (g->gcstate == GCSatomic) { /* final traversal? */ |
| 396 | 451 | StkId lim = L->stack + L->stacksize; /* real end of stack */ |
| 397 | 452 | for (; o < lim; o++) /* clear not-marked stack slice */ |
| 398 | 453 | setnilvalue(o); |
| 399 | 454 | } |
| 455 | + return TRAVCOST + cast_int(o - L->stack); | |
| 400 | 456 | } |
| 401 | 457 | |
| 402 | 458 | |
| 403 | 459 | /* |
| 404 | −** traverse one gray object, turning it to black. | |
| 405 | −** Returns `quantity' traversed. | |
| 460 | +** traverse one gray object, turning it to black (except for threads, | |
| 461 | +** which are always gray). | |
| 462 | +** Returns number of values traversed. | |
| 406 | 463 | */ |
| 407 | −static l_mem propagatemark (global_State *g) { | |
| 464 | +static int propagatemark (global_State *g) { | |
| 408 | 465 | GCObject *o = g->gray; |
| 409 | 466 | lua_assert(isgray(o)); |
| 410 | 467 | gray2black(o); |
| @@ -412,16 +469,12 @@ static l_mem propagatemark (global_State *g) { · 1 unmodified line | ||
| 412 | 469 | case LUA_TTABLE: { |
| 413 | 470 | Table *h = gco2t(o); |
| 414 | 471 | g->gray = h->gclist; |
| 415 | − traversetable(g, h); | |
| 416 | − return sizeof(Table) + sizeof(TValue) * h->sizearray + | |
| 417 | − sizeof(Node) * sizenode(h); | |
| 472 | + return traversetable(g, h); | |
| 418 | 473 | } |
| 419 | 474 | case LUA_TFUNCTION: { |
| 420 | 475 | Closure *cl = gco2cl(o); |
| 421 | 476 | g->gray = cl->c.gclist; |
| 422 | − traverseclosure(g, cl); | |
| 423 | − return (cl->c.isC) ? sizeCclosure(cl->c.nupvalues) : | |
| 424 | − sizeLclosure(cl->l.nupvalues); | |
| 477 | + return traverseclosure(g, cl); | |
| 425 | 478 | } |
| 426 | 479 | case LUA_TTHREAD: { |
| 427 | 480 | lua_State *th = gco2th(o); |
| @@ -429,19 +482,12 @@ static l_mem propagatemark (global_State *g) { · 1 unmodified line | ||
| 429 | 482 | th->gclist = g->grayagain; |
| 430 | 483 | g->grayagain = o; |
| 431 | 484 | black2gray(o); |
| 432 | − traversestack(g, th); | |
| 433 | − return sizeof(lua_State) + sizeof(TValue) * th->stacksize; | |
| 485 | + return traversestack(g, th); | |
| 434 | 486 | } |
| 435 | 487 | case LUA_TPROTO: { |
| 436 | 488 | Proto *p = gco2p(o); |
| 437 | 489 | g->gray = p->gclist; |
| 438 | − traverseproto(g, p); | |
| 439 | − return sizeof(Proto) + sizeof(Instruction) * p->sizecode + | |
| 440 | − sizeof(Proto *) * p->sizep + | |
| 441 | − sizeof(TValue) * p->sizek + | |
| 442 | − sizeof(int) * p->sizelineinfo + | |
| 443 | − sizeof(LocVar) * p->sizelocvars + | |
| 444 | − sizeof(TString *) * p->sizeupvalues; | |
| 490 | + return traverseproto(g, p); | |
| 445 | 491 | } |
| 446 | 492 | default: lua_assert(0); return 0; |
| 447 | 493 | } |
| @@ -465,14 +511,14 @@ static void convergeephemerons (global_State *g) { · 17 unmodified lines | ||
| 465 | 511 | int changed; |
| 466 | 512 | do { |
| 467 | 513 | GCObject *w; |
| 468 | − GCObject *next = g->ephemeron; | |
| 469 | − g->ephemeron = NULL; | |
| 514 | + GCObject *next = g->ephemeron; /* get ephemeron list */ | |
| 515 | + g->ephemeron = NULL; /* tables will return to this list when traversed */ | |
| 470 | 516 | changed = 0; |
| 471 | 517 | while ((w = next) != NULL) { |
| 472 | 518 | next = gco2t(w)->gclist; |
| 473 | − if (traverseephemeron(g, gco2t(w))) { | |
| 474 | − changed = 1; | |
| 475 | − propagateall(g); | |
| 519 | + if (traverseephemeron(g, gco2t(w))) { /* traverse marked some value? */ | |
| 520 | + propagateall(g); /* propagate changes */ | |
| 521 | + changed = 1; /* will have to revisit all ephemeron tables */ | |
| 476 | 522 | } |
| 477 | 523 | } |
| 478 | 524 | } while (changed); |
| @@ -487,26 +533,26 @@ static void convergeephemerons (global_State *g) { · 8 unmodified lines | ||
| 487 | 533 | ** ======================================================= |
| 488 | 534 | */ |
| 489 | 535 | |
| 490 | −/* clear collected entries from weaktables */ | |
| 536 | +/* | |
| 537 | +** clear collected entries from all weaktables in list 'l' | |
| 538 | +*/ | |
| 491 | 539 | static void cleartable (GCObject *l) { |
| 492 | − while (l) { | |
| 540 | + for (; l != NULL; l = gco2t(l)->gclist) { | |
| 493 | 541 | Table *h = gco2t(l); |
| 494 | − int i = h->sizearray; | |
| 495 | − while (i--) { | |
| 542 | + Node *n, *limit = gnode(h, sizenode(h)); | |
| 543 | + int i; | |
| 544 | + for (i = 0; i < h->sizearray; i++) { | |
| 496 | 545 | TValue *o = &h->array[i]; |
| 497 | 546 | if (iscleared(o, 0)) /* value was collected? */ |
| 498 | 547 | setnilvalue(o); /* remove value */ |
| 499 | 548 | } |
| 500 | − i = sizenode(h); | |
| 501 | − while (i--) { | |
| 502 | − Node *n = gnode(h, i); | |
| 549 | + for (n = gnode(h, 0); n < limit; n++) { | |
| 503 | 550 | if (!ttisnil(gval(n)) && /* non-empty entry? */ |
| 504 | 551 | (iscleared(key2tval(n), 1) || iscleared(gval(n), 0))) { |
| 505 | 552 | setnilvalue(gval(n)); /* remove value ... */ |
| 506 | − removeentry(n); /* remove entry from table */ | |
| 553 | + removeentry(n); /* and remove entry from table */ | |
| 507 | 554 | } |
| 508 | 555 | } |
| 509 | − l = h->gclist; | |
| 510 | 556 | } |
| 511 | 557 | } |
| 512 | 558 | |
| @@ -533,33 +579,63 @@ static void freeobj (lua_State *L, GCObject *o) { · 20 unmodified lines | ||
| 533 | 579 | static GCObject **sweeplist (lua_State *L, GCObject **p, lu_mem count); |
| 534 | 580 | |
| 535 | 581 | |
| 536 | −static void sweepthread (lua_State *L, lua_State *L1, int alive) { | |
| 582 | +/* | |
| 583 | +** sweep the (open) upvalues of a thread and resize its stack and | |
| 584 | +** list of call-info structures. | |
| 585 | +*/ | |
| 586 | +static void sweepthread (lua_State *L, lua_State *L1) { | |
| 537 | 587 | if (L1->stack == NULL) return; /* stack not completely built yet */ |
| 538 | 588 | sweepwholelist(L, &L1->openupval); /* sweep open upvalues */ |
| 539 | 589 | luaE_freeCI(L1); /* free extra CallInfo slots */ |
| 540 | 590 | /* should not change the stack during an emergency gc cycle */ |
| 541 | − if (alive && G(L)->gckind != KGC_EMERGENCY) | |
| 591 | + if (G(L)->gckind != KGC_EMERGENCY) | |
| 542 | 592 | luaD_shrinkstack(L1); |
| 543 | 593 | } |
| 544 | 594 | |
| 545 | 595 | |
| 596 | +/* | |
| 597 | +** sweep at most 'count' elements from a list of GCObjects erasing dead | |
| 598 | +** objects, where a dead (not alive) object is one marked with the "old" | |
| 599 | +** (non current) white and not fixed. | |
| 600 | +** In non-generational mode, change all non-dead objects back to white, | |
| 601 | +** preparing for next collection cycle. | |
| 602 | +** In generational mode, keep black objects black, and also mark them as | |
| 603 | +** old; stop when hitting an old object, as all objects after that | |
| 604 | +** one will be old too. | |
| 605 | +** When object is a thread, sweep its list of open upvalues too. | |
| 606 | +*/ | |
| 546 | 607 | static GCObject **sweeplist (lua_State *L, GCObject **p, lu_mem count) { |
| 547 | − GCObject *curr; | |
| 548 | 608 | global_State *g = G(L); |
| 549 | − int deadmask = otherwhite(g); | |
| 550 | − while ((curr = *p) != NULL && count-- > 0) { | |
| 551 | − int alive = (gch(curr)->marked ^ WHITEBITS) & deadmask; | |
| 552 | − if (gch(curr)->tt == LUA_TTHREAD) | |
| 553 | − sweepthread(L, gco2th(curr), alive); | |
| 554 | − if (alive) { | |
| 555 | − lua_assert(!isdead(g, curr) || testbit(gch(curr)->marked, FIXEDBIT)); | |
| 556 | − makewhite(g, curr); /* make it white (for next cycle) */ | |
| 557 | − p = &gch(curr)->next; | |
| 558 | − } | |
| 559 | − else { /* must erase `curr' */ | |
| 560 | − lua_assert(isdead(g, curr) || deadmask == bitmask(SFIXEDBIT)); | |
| 609 | + int ow = otherwhite(g); | |
| 610 | + int toclear, toset; /* bits to clear and to set in all live objects */ | |
| 611 | + int tostop; /* stop sweep when this is true */ | |
| 612 | + if (isgenerational(g)) { /* generational mode? */ | |
| 613 | + toclear = ~0; /* clear nothing */ | |
| 614 | + toset = bitmask(OLDBIT); /* set the old bit of all surviving objects */ | |
| 615 | + tostop = bitmask(OLDBIT); /* do not sweep old generation */ | |
| 616 | + } | |
| 617 | + else { /* normal mode */ | |
| 618 | + toclear = maskcolors; /* clear all color bits + old bit */ | |
| 619 | + toset = luaC_white(g); /* make object white */ | |
| 620 | + tostop = 0; /* do not stop */ | |
| 621 | + } | |
| 622 | + while (*p != NULL && count-- > 0) { | |
| 623 | + GCObject *curr = *p; | |
| 624 | + int marked = gch(curr)->marked; | |
| 625 | + if (isdeadm(ow, marked)) { /* is 'curr' dead? */ | |
| 561 | 626 | *p = gch(curr)->next; /* remove 'curr' from list */ |
| 562 | − freeobj(L, curr); | |
| 627 | + freeobj(L, curr); /* erase 'curr' */ | |
| 628 | + } | |
| 629 | + else { | |
| 630 | + if (gch(curr)->tt == LUA_TTHREAD) | |
| 631 | + sweepthread(L, gco2th(curr)); /* sweep thread's upvalues */ | |
| 632 | + if (testbits(marked, tostop)) { | |
| 633 | + static GCObject *nullp = NULL; | |
| 634 | + return &nullp; /* stop sweeping this list */ | |
| 635 | + } | |
| 636 | + /* update marks */ | |
| 637 | + gch(curr)->marked = cast_byte((marked & toclear) | toset); | |
| 638 | + p = &gch(curr)->next; /* go to next element */ | |
| 563 | 639 | } |
| 564 | 640 | } |
| 565 | 641 | return p; |
| @@ -576,25 +652,28 @@ static GCObject **sweeplist (lua_State *L, GCObject **p, lu_mem count) { · 10 unmodified lines | ||
| 576 | 652 | |
| 577 | 653 | static void checkSizes (lua_State *L) { |
| 578 | 654 | global_State *g = G(L); |
| 579 | − if (g->strt.nuse < cast(lu_int32, g->strt.size)) { | |
| 580 | − /* string-table size could be the smaller power of 2 larger than 'nuse' */ | |
| 581 | − int size = 1 << luaO_ceillog2(g->strt.nuse); | |
| 582 | − if (size < g->strt.size) /* current table too large? */ | |
| 583 | − luaS_resize(L, size); /* shrink it */ | |
| 655 | + if (g->gckind != KGC_EMERGENCY) { /* do not change sizes in emergency */ | |
| 656 | + int hs = g->strt.size / 2; /* half the size of the string table */ | |
| 657 | + if (g->strt.nuse < cast(lu_int32, hs)) /* using less than that half? */ | |
| 658 | + luaS_resize(L, hs); /* halve its size */ | |
| 659 | + luaZ_freebuffer(L, &g->buff); /* free concatenation buffer */ | |
| 584 | 660 | } |
| 585 | − luaZ_freebuffer(L, &g->buff); | |
| 586 | 661 | } |
| 587 | 662 | |
| 588 | 663 | |
| 589 | 664 | static Udata *udata2finalize (global_State *g) { |
| 590 | 665 | GCObject *o = g->tobefnz; /* get first element */ |
| 591 | − g->tobefnz = gch(o)->next; /* remove it from 'tobefnz' list */ | |
| 592 | − gch(o)->next = g->rootgc; /* return it to `root' list */ | |
| 593 | − g->rootgc = o; | |
| 594 | − lua_assert(isfinalized(gch(o))); | |
| 595 | − resetbit(gch(o)->marked, SEPARATED); /* mark it as such */ | |
| 596 | − makewhite(g, o); | |
| 597 | − return rawgco2u(o); | |
| 666 | + Udata *u = rawgco2u(o); | |
| 667 | + lua_assert(isfinalized(&u->uv)); | |
| 668 | + lua_assert(!isold(o)); | |
| 669 | + g->tobefnz = u->uv.next; /* remove it from 'tobefnz' list */ | |
| 670 | + u->uv.next = g->allgc; /* return it to 'allgc' list */ | |
| 671 | + g->allgc = o; | |
| 672 | + resetbit(u->uv.marked, SEPARATED); /* mark that it is not in 'tobefnz' */ | |
| 673 | + resetoldbit(o); /* see MOVE OLD rule */ | |
| 674 | + if (!keepinvariant(g)) /* not keeping invariant? */ | |
| 675 | + makewhite(g, o); /* "sweep" object */ | |
| 676 | + return u; | |
| 598 | 677 | } |
| 599 | 678 | |
| 600 | 679 | |
| @@ -608,18 +687,18 @@ static void GCTM (lua_State *L, int propagateerrors) { · 7 unmodified lines | ||
| 608 | 687 | global_State *g = G(L); |
| 609 | 688 | Udata *udata = udata2finalize(g); |
| 610 | 689 | const TValue *tm = gfasttm(g, udata->uv.metatable, TM_GC); |
| 611 | − if (tm != NULL && ttisfunction(tm)) { | |
| 690 | + if (tm != NULL && ttisfunction(tm)) { /* is there a finalizer? */ | |
| 612 | 691 | int status; |
| 613 | 692 | lu_byte oldah = L->allowhook; |
| 614 | − lu_mem oldt = g->GCthreshold; | |
| 693 | + lu_mem oldd = g->GCdebt; | |
| 615 | 694 | L->allowhook = 0; /* stop debug hooks during GC tag method */ |
| 616 | − g->GCthreshold = 2*g->totalbytes; /* avoid GC steps */ | |
| 617 | − setobj2s(L, L->top, tm); | |
| 618 | − setuvalue(L, L->top+1, udata); | |
| 619 | − L->top += 2; | |
| 695 | + stopgc(g); /* avoid GC steps */ | |
| 696 | + setobj2s(L, L->top, tm); /* push finalizer... */ | |
| 697 | + setuvalue(L, L->top+1, udata); /* ... and its argument */ | |
| 698 | + L->top += 2; /* and (next line) call the finalizer */ | |
| 620 | 699 | status = luaD_pcall(L, dothecall, NULL, savestack(L, L->top - 2), 0); |
| 621 | 700 | L->allowhook = oldah; /* restore hooks */ |
| 622 | − g->GCthreshold = oldt; /* restore threshold */ | |
| 701 | + g->GCdebt = oldd; /* restore threshold */ | |
| 623 | 702 | if (status != LUA_OK && propagateerrors) { /* error while running __gc? */ |
| 624 | 703 | if (status == LUA_ERRRUN) { /* is there an error msg.? */ |
| 625 | 704 | luaO_pushfstring(L, "error in __gc tag method (%s)", |
| @@ -632,14 +711,18 @@ static void GCTM (lua_State *L, int propagateerrors) { · 6 unmodified lines | ||
| 632 | 711 | } |
| 633 | 712 | |
| 634 | 713 | |
| 635 | −/* move 'dead' udata that need finalization to list 'tobefnz' */ | |
| 714 | +/* | |
| 715 | +** move all unreachable udata that need finalization from list 'udgc' to | |
| 716 | +** list 'tobefnz' | |
| 717 | +*/ | |
| 636 | 718 | void luaC_separateudata (lua_State *L, int all) { |
| 637 | 719 | global_State *g = G(L); |
| 638 | − GCObject **p = &g->mainthread->next; | |
| 720 | + GCObject **p = &g->udgc; | |
| 639 | 721 | GCObject *curr; |
| 640 | 722 | GCObject **lastnext = &g->tobefnz; |
| 641 | − /* find last 'next' field in 'tobefnz' list (to insert elements in its end) */ | |
| 642 | − while (*lastnext != NULL) lastnext = &gch(*lastnext)->next; | |
| 723 | + /* find last 'next' field in 'tobefnz' list (to add elements in its end) */ | |
| 724 | + while (*lastnext != NULL) | |
| 725 | + lastnext = &gch(*lastnext)->next; | |
| 643 | 726 | while ((curr = *p) != NULL) { /* traverse all finalizable objects */ |
| 644 | 727 | lua_assert(gch(curr)->tt == LUA_TUSERDATA && !isfinalized(gco2u(curr))); |
| 645 | 728 | lua_assert(testbit(gch(curr)->marked, SEPARATED)); |
| @@ -647,9 +730,8 @@ void luaC_separateudata (lua_State *L, int all) { · 1 unmodified line | ||
| 647 | 730 | p = &gch(curr)->next; /* don't bother with it */ |
| 648 | 731 | else { |
| 649 | 732 | l_setbit(gch(curr)->marked, FINALIZEDBIT); /* won't be finalized again */ |
| 650 | − *p = gch(curr)->next; /* remove 'curr' from 'rootgc' list */ | |
| 651 | − /* link 'curr' at the end of 'tobefnz' list */ | |
| 652 | − gch(curr)->next = *lastnext; | |
| 733 | + *p = gch(curr)->next; /* remove 'curr' from 'udgc' list */ | |
| 734 | + gch(curr)->next = *lastnext; /* link at the end of 'tobefnz' list */ | |
| 653 | 735 | *lastnext = curr; |
| 654 | 736 | lastnext = &gch(curr)->next; |
| 655 | 737 | } |
| @@ -657,20 +739,24 @@ void luaC_separateudata (lua_State *L, int all) { · 1 unmodified line | ||
| 657 | 739 | } |
| 658 | 740 | |
| 659 | 741 | |
| 742 | +/* | |
| 743 | +** if userdata 'u' has a finalizer, remove it from 'allgc' list (must | |
| 744 | +** search the list to find it) and link it in 'udgc' list. | |
| 745 | +*/ | |
| 660 | 746 | void luaC_checkfinalizer (lua_State *L, Udata *u) { |
| 661 | 747 | global_State *g = G(L); |
| 662 | − if (testbit(u->uv.marked, SEPARATED) || /* userdata is already separated... */ | |
| 663 | − isfinalized(&u->uv) || /* ... or is finalized... */ | |
| 664 | − gfasttm(g, u->uv.metatable, TM_GC) == NULL) /* or has no finalization? */ | |
| 748 | + if (testbit(u->uv.marked, SEPARATED) || /* udata is already separated... */ | |
| 749 | + isfinalized(&u->uv) || /* ... or is finalized... */ | |
| 750 | + gfasttm(g, u->uv.metatable, TM_GC) == NULL) /* or has no finalizer? */ | |
| 665 | 751 | return; /* nothing to be done */ |
| 666 | − else { /* move 'u' to 2nd part of root list */ | |
| 752 | + else { /* move 'u' to 'udgc' list */ | |
| 667 | 753 | GCObject **p; |
| 668 | − for (p = &g->rootgc; *p != obj2gco(u); p = &gch(*p)->next) | |
| 669 | − lua_assert(*p != obj2gco(g->mainthread)); /* 'u' must be in this list */ | |
| 754 | + for (p = &g->allgc; *p != obj2gco(u); p = &gch(*p)->next) ; | |
| 670 | 755 | *p = u->uv.next; /* remove 'u' from root list */ |
| 671 | − u->uv.next = g->mainthread->next; /* re-link it in list */ | |
| 672 | − g->mainthread->next = obj2gco(u); | |
| 756 | + u->uv.next = g->udgc; /* link it in list 'udgc' */ | |
| 757 | + g->udgc = obj2gco(u); | |
| 673 | 758 | l_setbit(u->uv.marked, SEPARATED); /* mark it as such */ |
| 759 | + resetoldbit(obj2gco(u)); /* see MOVE OLD rule */ | |
| 674 | 760 | } |
| 675 | 761 | } |
| 676 | 762 | |
| @@ -683,15 +769,52 @@ void luaC_checkfinalizer (lua_State *L, Udata *u) { · 6 unmodified lines | ||
| 683 | 769 | ** ======================================================= |
| 684 | 770 | */ |
| 685 | 771 | |
| 772 | + | |
| 773 | +#define sweepphases \ | |
| 774 | + (bitmask(GCSsweepstring) | bitmask(GCSsweepudata) | bitmask(GCSsweep)) | |
| 775 | + | |
| 776 | +/* | |
| 777 | +** change GC mode | |
| 778 | +*/ | |
| 779 | +void luaC_changemode (lua_State *L, int mode) { | |
| 780 | + global_State *g = G(L); | |
| 781 | + if (mode == g->gckind) return; /* nothing to change */ | |
| 782 | + if (mode == KGC_GEN) { /* change to generational mode */ | |
| 783 | + /* make sure gray lists are consistent */ | |
| 784 | + luaC_runtilstate(L, bitmask(GCSpropagate)); | |
| 785 | + g->lastmajormem = g->totalbytes; | |
| 786 | + g->gckind = KGC_GEN; | |
| 787 | + } | |
| 788 | + else { /* change to incremental mode */ | |
| 789 | + /* sweep all objects to turn them back to white | |
| 790 | + (as white has not changed, nothing extra will be collected) */ | |
| 791 | + g->sweepstrgc = 0; | |
| 792 | + g->gcstate = GCSsweepstring; | |
| 793 | + g->gckind = KGC_NORMAL; | |
| 794 | + luaC_runtilstate(L, ~sweepphases); | |
| 795 | + } | |
| 796 | +} | |
| 797 | + | |
| 798 | + | |
| 799 | +/* | |
| 800 | +** call all pending finalizers */ | |
| 801 | +static void callallpendingfinalizers (lua_State *L, int propagateerrors) { | |
| 802 | + global_State *g = G(L); | |
| 803 | + while (g->tobefnz) GCTM(L, propagateerrors); | |
| 804 | +} | |
| 805 | + | |
| 806 | + | |
| 686 | 807 | void luaC_freeallobjects (lua_State *L) { |
| 687 | 808 | global_State *g = G(L); |
| 688 | 809 | int i; |
| 689 | − while (g->tobefnz) GCTM(L, 0); /* Call all pending finalizers */ | |
| 810 | + callallpendingfinalizers(L, 0); | |
| 690 | 811 | /* following "white" makes all objects look dead */ |
| 691 | − g->currentwhite = WHITEBITS | bitmask(SFIXEDBIT); | |
| 692 | − sweepwholelist(L, &g->rootgc); | |
| 693 | − lua_assert(g->rootgc == obj2gco(g->mainthread) && | |
| 694 | − g->mainthread->next == NULL); | |
| 812 | + g->currentwhite = WHITEBITS; | |
| 813 | + g->gckind = KGC_NORMAL; | |
| 814 | + sweepwholelist(L, &g->udgc); | |
| 815 | + lua_assert(g->udgc == NULL); | |
| 816 | + sweepwholelist(L, &g->allgc); | |
| 817 | + lua_assert(g->allgc == NULL); | |
| 695 | 818 | for (i = 0; i < g->strt.size; i++) /* free all string lists */ |
| 696 | 819 | sweepwholelist(L, &g->strt.hash[i]); |
| 697 | 820 | lua_assert(g->strt.nuse == 0); |
| @@ -700,7 +823,6 @@ void luaC_freeallobjects (lua_State *L) { · 2 unmodified lines | ||
| 700 | 823 | |
| 701 | 824 | static void atomic (lua_State *L) { |
| 702 | 825 | global_State *g = G(L); |
| 703 | − g->gcstate = GCSatomic; | |
| 704 | 826 | lua_assert(!iswhite(obj2gco(g->mainthread))); |
| 705 | 827 | markobject(g, L); /* mark running thread */ |
| 706 | 828 | /* registry and global metatables may be changed by API */ |
| @@ -710,12 +832,11 @@ static void atomic (lua_State *L) { · 3 unmodified lines | ||
| 710 | 832 | remarkupvals(g); |
| 711 | 833 | /* traverse objects caught by write barrier and by 'remarkupvals' */ |
| 712 | 834 | propagateall(g); |
| 713 | − /* at this point, all strongly accessible objects are marked. | |
| 714 | − Start marking weakly accessible objects. */ | |
| 715 | 835 | traverselistofgrays(g, &g->weak); /* remark weak tables */ |
| 716 | 836 | traverselistofgrays(g, &g->ephemeron); /* remark ephemeron tables */ |
| 717 | 837 | traverselistofgrays(g, &g->grayagain); /* remark gray again */ |
| 718 | 838 | convergeephemerons(g); |
| 839 | + /* at this point, all strongly accessible objects are marked. */ | |
| 719 | 840 | luaC_separateudata(L, 0); /* separate userdata to be finalized */ |
| 720 | 841 | markbeingfnz(g); /* mark userdata that will be finalized */ |
| 721 | 842 | propagateall(g); /* remark, to propagate `preserveness' */ |
| @@ -724,51 +845,68 @@ static void atomic (lua_State *L) { · 2 unmodified lines | ||
| 724 | 845 | cleartable(g->weak); |
| 725 | 846 | cleartable(g->ephemeron); |
| 726 | 847 | cleartable(g->allweak); |
| 727 | − g->currentwhite = cast_byte(otherwhite(g)); /* flip current white */ | |
| 728 | − g->sweepstrgc = 0; /* go to sweep phase */ | |
| 848 | + g->sweepstrgc = 0; /* prepare to sweep strings */ | |
| 729 | 849 | g->gcstate = GCSsweepstring; |
| 850 | + g->currentwhite = cast_byte(otherwhite(g)); /* flip current white */ | |
| 851 | + /*lua_checkmemory(L);*/ | |
| 730 | 852 | } |
| 731 | 853 | |
| 732 | 854 | |
| 733 | 855 | static l_mem singlestep (lua_State *L) { |
| 734 | 856 | global_State *g = G(L); |
| 735 | − /*lua_checkmemory(L);*/ | |
| 736 | 857 | switch (g->gcstate) { |
| 737 | 858 | case GCSpause: { |
| 738 | − markroot(L); /* start a new collection */ | |
| 739 | − return 0; | |
| 859 | + if (!isgenerational(g)) | |
| 860 | + markroot(L); /* start a new collection */ | |
| 861 | + /* in any case, root must be marked */ | |
| 862 | + lua_assert(!iswhite(obj2gco(g->mainthread)) | |
| 863 | + && !iswhite(gcvalue(&g->l_registry))); | |
| 864 | + g->gcstate = GCSpropagate; | |
| 865 | + return GCROOTCOST; | |
| 740 | 866 | } |
| 741 | 867 | case GCSpropagate: { |
| 742 | 868 | if (g->gray) |
| 743 | 869 | return propagatemark(g); |
| 744 | 870 | else { /* no more `gray' objects */ |
| 745 | − atomic(L); /* finish mark phase */ | |
| 746 | − return 0; | |
| 871 | + g->gcstate = GCSatomic; /* finish mark phase */ | |
| 872 | + atomic(L); | |
| 873 | + return GCATOMICCOST; | |
| 747 | 874 | } |
| 748 | 875 | } |
| 749 | 876 | case GCSsweepstring: { |
| 750 | − sweepwholelist(L, &g->strt.hash[g->sweepstrgc++]); | |
| 751 | − if (g->sweepstrgc >= g->strt.size) { /* nothing more to sweep? */ | |
| 752 | − g->sweepgc = &g->rootgc; | |
| 753 | − g->gcstate = GCSsweep; /* sweep all other objects */ | |
| 877 | + if (g->sweepstrgc < g->strt.size) { | |
| 878 | + sweepwholelist(L, &g->strt.hash[g->sweepstrgc++]); | |
| 879 | + return GCSWEEPCOST; | |
| 880 | + } | |
| 881 | + else { /* no more strings to sweep */ | |
| 882 | + g->sweepgc = &g->udgc; /* prepare to sweep userdata */ | |
| 883 | + g->gcstate = GCSsweepudata; | |
| 884 | + return 0; | |
| 754 | 885 | } |
| 755 | − return GCSWEEPCOST; | |
| 756 | 886 | } |
| 757 | − case GCSsweep: { | |
| 758 | − g->sweepgc = sweeplist(L, g->sweepgc, GCSWEEPMAX); | |
| 759 | − if (*g->sweepgc == NULL) /* nothing more to sweep? */ | |
| 760 | − g->gcstate = GCSfinalize; /* end sweep phase */ | |
| 761 | − return GCSWEEPMAX*GCSWEEPCOST; | |
| 887 | + case GCSsweepudata: { | |
| 888 | + if (*g->sweepgc) { | |
| 889 | + g->sweepgc = sweeplist(L, g->sweepgc, GCSWEEPMAX); | |
| 890 | + return GCSWEEPMAX*GCSWEEPCOST; | |
| 891 | + } | |
| 892 | + else { | |
| 893 | + g->sweepgc = &g->allgc; /* go to next phase */ | |
| 894 | + g->gcstate = GCSsweep; | |
| 895 | + return GCSWEEPCOST; | |
| 896 | + } | |
| 762 | 897 | } |
| 763 | − case GCSfinalize: { | |
| 764 | − if (g->tobefnz) { | |
| 765 | − GCTM(L, 1); | |
| 766 | − return GCFINALIZECOST; | |
| 898 | + case GCSsweep: { | |
| 899 | + if (*g->sweepgc) { | |
| 900 | + g->sweepgc = sweeplist(L, g->sweepgc, GCSWEEPMAX); | |
| 901 | + return GCSWEEPMAX*GCSWEEPCOST; | |
| 767 | 902 | } |
| 768 | 903 | else { |
| 904 | + /* sweep main thread */ | |
| 905 | + GCObject *mt = obj2gco(g->mainthread); | |
| 906 | + sweeplist(L, &mt, 1); | |
| 769 | 907 | checkSizes(L); |
| 770 | − g->gcstate = GCSpause; /* end collection */ | |
| 771 | − return 0; | |
| 908 | + g->gcstate = GCSpause; /* finish collection */ | |
| 909 | + return GCSWEEPCOST; | |
| 772 | 910 | } |
| 773 | 911 | } |
| 774 | 912 | default: lua_assert(0); return 0; |
| @@ -776,22 +914,6 @@ static l_mem singlestep (lua_State *L) { · 1 unmodified line | ||
| 776 | 914 | } |
| 777 | 915 | |
| 778 | 916 | |
| 779 | −void luaC_step (lua_State *L) { | |
| 780 | − global_State *g = G(L); | |
| 781 | − l_mem lim = (GCSTEPSIZE/100) * g->gcstepmul; /* how much to work */ | |
| 782 | − lu_mem debt = g->totalbytes - g->GCthreshold; | |
| 783 | − lua_assert(g->gckind == KGC_NORMAL); | |
| 784 | − do { /* always perform at least one single step */ | |
| 785 | − lim -= singlestep(L); | |
| 786 | − } while (lim > 0 && g->gcstate != GCSpause); | |
| 787 | − g->GCthreshold = (g->gcstate != GCSpause) | |
| 788 | − ? g->totalbytes + GCSTEPSIZE | |
| 789 | − : (g->totalbytes/100) * g->gcpause; | |
| 790 | − /* compensate if GC is "behind schedule" (has some debt to pay) */ | |
| 791 | − if (g->GCthreshold > debt) g->GCthreshold -= debt; | |
| 792 | −} | |
| 793 | − | |
| 794 | − | |
| 795 | 917 | /* |
| 796 | 918 | ** advances the garbage collector until it reaches a state allowed |
| 797 | 919 | ** by 'statemask' |
| @@ -803,29 +925,73 @@ void luaC_runtilstate (lua_State *L, int statesmask) { · 5 unmodified lines | ||
| 803 | 925 | } |
| 804 | 926 | |
| 805 | 927 | |
| 928 | +static void generationalcollection (lua_State *L) { | |
| 929 | + global_State *g = G(L); | |
| 930 | + if (g->lastmajormem == 0) { /* signal for another major collection? */ | |
| 931 | + luaC_fullgc(L, 0); /* perform a full regular collection */ | |
| 932 | + g->lastmajormem = g->totalbytes; /* update control */ | |
| 933 | + } | |
| 934 | + else { | |
| 935 | + luaC_runtilstate(L, bitmask(GCSpause)); /* run collection */ | |
| 936 | + if (g->totalbytes > g->lastmajormem/100 * g->gcpause) | |
| 937 | + g->lastmajormem = 0; /* signal for a major collection */ | |
| 938 | + } | |
| 939 | + g->GCdebt = stddebt(g); | |
| 940 | +} | |
| 941 | + | |
| 942 | + | |
| 943 | +static void step (lua_State *L) { | |
| 944 | + global_State *g = G(L); | |
| 945 | + l_mem lim = g->gcstepmul; /* how much to work */ | |
| 946 | + do { /* always perform at least one single step */ | |
| 947 | + lim -= singlestep(L); | |
| 948 | + } while (lim > 0 && g->gcstate != GCSpause); | |
| 949 | + if (g->gcstate != GCSpause) | |
| 950 | + g->GCdebt -= GCSTEPSIZE; | |
| 951 | + else | |
| 952 | + g->GCdebt = stddebt(g); | |
| 953 | +} | |
| 954 | + | |
| 955 | + | |
| 956 | +void luaC_step (lua_State *L) { | |
| 957 | + int i; | |
| 958 | + if (isgenerational(G(L))) generationalcollection(L); | |
| 959 | + else step(L); | |
| 960 | + for (i = 0; i < GCFINALIZENUM && G(L)->tobefnz; i++) | |
| 961 | + GCTM(L, 1); /* Call a few pending finalizers */ | |
| 962 | +} | |
| 963 | + | |
| 964 | + | |
| 806 | 965 | /* |
| 807 | −** performs a full GC cycle; if "isememrgency", does not call | |
| 966 | +** performs a full GC cycle; if "isemergency", does not call | |
| 808 | 967 | ** finalizers (which could change stack positions) |
| 809 | 968 | */ |
| 810 | 969 | void luaC_fullgc (lua_State *L, int isemergency) { |
| 811 | 970 | global_State *g = G(L); |
| 812 | − lua_assert(g->gckind == KGC_NORMAL); | |
| 813 | − g->gckind = isemergency ? KGC_EMERGENCY : KGC_FORCED; | |
| 814 | − if (g->gcstate == GCSpropagate) { /* marking phase? */ | |
| 971 | + int origkind = g->gckind; | |
| 972 | + lua_assert(origkind != KGC_EMERGENCY); | |
| 973 | + if (!isemergency) /* do not run finalizers during emergency GC */ | |
| 974 | + callallpendingfinalizers(L, 1); | |
| 975 | + if (keepinvariant(g)) { /* marking phase? */ | |
| 815 | 976 | /* must sweep all objects to turn them back to white |
| 816 | − (as white does not change, nothing will be collected) */ | |
| 977 | + (as white has not changed, nothing will be collected) */ | |
| 817 | 978 | g->sweepstrgc = 0; |
| 818 | 979 | g->gcstate = GCSsweepstring; |
| 819 | 980 | } |
| 820 | − /* finish any pending sweep phase */ | |
| 821 | − luaC_runtilstate(L, ~bit2mask(GCSsweepstring, GCSsweep)); | |
| 822 | − markroot(L); /* start a new collection */ | |
| 823 | − /* run collector up to finalizers */ | |
| 824 | − luaC_runtilstate(L, bitmask(GCSfinalize)); | |
| 825 | − g->gckind = KGC_NORMAL; | |
| 981 | + g->gckind = isemergency ? KGC_EMERGENCY : KGC_NORMAL; | |
| 982 | + /* finish any pending sweep phase to start a new cycle */ | |
| 983 | + luaC_runtilstate(L, bitmask(GCSpause)); | |
| 984 | + /* run entire collector */ | |
| 985 | + luaC_runtilstate(L, ~bitmask(GCSpause)); | |
| 986 | + luaC_runtilstate(L, bitmask(GCSpause)); | |
| 987 | + if (origkind == KGC_GEN) { /* generational mode? */ | |
| 988 | + /* generational mode must always start in propagate phase */ | |
| 989 | + luaC_runtilstate(L, bitmask(GCSpropagate)); | |
| 990 | + } | |
| 991 | + g->gckind = origkind; | |
| 992 | + g->GCdebt = stddebt(g); | |
| 826 | 993 | if (!isemergency) /* do not run finalizers during emergency GC */ |
| 827 | − luaC_runtilstate(L, ~bitmask(GCSfinalize)); | |
| 828 | − g->GCthreshold = (g->totalbytes/100) * g->gcpause; | |
| 994 | + callallpendingfinalizers(L, 1); | |
| 829 | 995 | } |
| 830 | 996 | |
| 831 | 997 | /* }====================================================== */ |
| @@ -1,5 +1,5 @@ | ||
| 1 | 1 | /* |
| 2 | −** $Id: lgc.h,v 2.27 2009/12/16 16:42:58 roberto Exp $ | |
| 2 | +** $Id: lgc.h,v 2.41 2010/05/10 18:23:45 roberto Exp $ | |
| 3 | 3 | ** Garbage Collector |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| @@ -9,18 +9,51 @@ · 3 unmodified lines | ||
| 9 | 9 | |
| 10 | 10 | |
| 11 | 11 | #include "lobject.h" |
| 12 | +#include "lstate.h" | |
| 13 | + | |
| 14 | +/* | |
| 15 | +** Collectable objects may have one of three colors: white, which | |
| 16 | +** means the object is not marked; gray, which means the | |
| 17 | +** object is marked, but its references may be not marked; and | |
| 18 | +** black, which means that the object and all its references are marked. | |
| 19 | +** The main invariant of the garbage collector, while marking objects, | |
| 20 | +** is that a black object can never point to a white one. Moreover, | |
| 21 | +** any gray object must be in a "gray list" (gray, grayagain, weak, | |
| 22 | +** allweak, ephemeron) so that it can be visited again before finishing | |
| 23 | +** the collection cycle. These lists have no meaning when the invariant | |
| 24 | +** is not being enforced (e.g., sweep phase). | |
| 25 | +*/ | |
| 12 | 26 | |
| 13 | 27 | |
| 14 | 28 | /* |
| 15 | 29 | ** Possible states of the Garbage Collector |
| 16 | 30 | */ |
| 17 | −#define GCSpause 0 | |
| 18 | −#define GCSpropagate 1 | |
| 19 | −#define GCSatomic 2 | |
| 20 | −#define GCSsweepstring 3 | |
| 31 | +#define GCSpropagate 0 | |
| 32 | +#define GCSatomic 1 | |
| 33 | +#define GCSsweepstring 2 | |
| 34 | +#define GCSsweepudata 3 | |
| 21 | 35 | #define GCSsweep 4 |
| 22 | −#define GCSfinalize 5 | |
| 36 | +#define GCSpause 5 | |
| 37 | + | |
| 38 | + | |
| 39 | +#define issweepphase(g) \ | |
| 40 | + (GCSsweepstring <= (g)->gcstate && (g)->gcstate <= GCSsweep) | |
| 41 | + | |
| 42 | +#define isgenerational(g) ((g)->gckind == KGC_GEN) | |
| 43 | + | |
| 44 | +/* | |
| 45 | +** macro to tell when main invariant (white objects cannot point to black | |
| 46 | +** ones) must be kept. During a non-generational collection, the sweep | |
| 47 | +** phase may brak the invariant, as objects turned white may point to | |
| 48 | +** still-black objects. The invariant is restored when sweep ends and | |
| 49 | +** all objects are white again. During a generational collection, the | |
| 50 | +** invariant must be kept all times. | |
| 51 | +*/ | |
| 52 | +#define keepinvariant(g) (isgenerational(g) || g->gcstate <= GCSatomic) | |
| 53 | + | |
| 23 | 54 | |
| 55 | +#define gcstopped(g) ((g)->GCdebt == MIN_LMEM) | |
| 56 | +#define stopgc(g) ((g)->GCdebt = MIN_LMEM) | |
| 24 | 57 | |
| 25 | 58 | |
| 26 | 59 | /* |
| @@ -39,34 +72,33 @@ · 12 unmodified lines | ||
| 39 | 72 | |
| 40 | 73 | |
| 41 | 74 | |
| 42 | −/* | |
| 43 | −** Layout for bit use in `marked' field: | |
| 44 | −** bit 0 - object is white (type 0) | |
| 45 | −** bit 1 - object is white (type 1) | |
| 46 | −** bit 2 - object is black | |
| 47 | −** bit 3 - for userdata: has been finalized | |
| 48 | −** bit 4 - for userdata: it's in 2nd part of rootgc list or in tobefnz | |
| 49 | −** bit 5 - object is fixed (should not be collected) | |
| 50 | −** bit 6 - object is "super" fixed (only the main thread) | |
| 51 | −*/ | |
| 52 | − | |
| 75 | +/* Layout for bit use in `marked' field: */ | |
| 76 | +#define WHITE0BIT 0 /* object is white (type 0) */ | |
| 77 | +#define WHITE1BIT 1 /* object is white (type 1) */ | |
| 78 | +#define BLACKBIT 2 /* object is black */ | |
| 79 | +#define FINALIZEDBIT 3 /* for userdata: has been finalized */ | |
| 80 | +#define SEPARATED 4 /* " ": it's in 'udgc' list or in 'tobefnz' */ | |
| 81 | +#define FIXEDBIT 5 /* object is fixed (should not be collected) */ | |
| 82 | +#define OLDBIT 6 /* object is old (only in generational mode) */ | |
| 83 | +/* bit 7 is currently used by tests (luaL_checkmemory) */ | |
| 53 | 84 | |
| 54 | −#define WHITE0BIT 0 | |
| 55 | −#define WHITE1BIT 1 | |
| 56 | −#define BLACKBIT 2 | |
| 57 | −#define FINALIZEDBIT 3 | |
| 58 | −#define SEPARATED 4 | |
| 59 | −#define FIXEDBIT 5 | |
| 60 | −#define SFIXEDBIT 6 | |
| 61 | 85 | #define WHITEBITS bit2mask(WHITE0BIT, WHITE1BIT) |
| 62 | 86 | |
| 63 | 87 | |
| 64 | 88 | #define iswhite(x) testbits((x)->gch.marked, WHITEBITS) |
| 65 | 89 | #define isblack(x) testbit((x)->gch.marked, BLACKBIT) |
| 66 | −#define isgray(x) (!isblack(x) && !iswhite(x)) | |
| 90 | +#define isgray(x) /* neither white nor black */ \ | |
| 91 | + (!testbits((x)->gch.marked, WHITEBITS | bitmask(BLACKBIT))) | |
| 92 | + | |
| 93 | +#define isold(x) testbit((x)->gch.marked, OLDBIT) | |
| 94 | + | |
| 95 | +/* MOVE OLD rule: whenever an object is moved to the beginning of | |
| 96 | + a GC list, its old bit must be cleared */ | |
| 97 | +#define resetoldbit(o) resetbit((o)->gch.marked, OLDBIT) | |
| 67 | 98 | |
| 68 | 99 | #define otherwhite(g) (g->currentwhite ^ WHITEBITS) |
| 69 | −#define isdead(g,v) ((v)->gch.marked & otherwhite(g) & WHITEBITS) | |
| 100 | +#define isdeadm(ow,m) (!(((m) ^ WHITEBITS) & (ow))) | |
| 101 | +#define isdead(g,v) isdeadm(otherwhite(g), (v)->gch.marked) | |
| 70 | 102 | |
| 71 | 103 | #define changewhite(x) ((x)->gch.marked ^= WHITEBITS) |
| 72 | 104 | #define gray2black(x) l_setbit((x)->gch.marked, BLACKBIT) |
| @@ -76,8 +108,7 @@ · 3 unmodified lines | ||
| 76 | 108 | #define luaC_white(g) cast(lu_byte, (g)->currentwhite & WHITEBITS) |
| 77 | 109 | |
| 78 | 110 | |
| 79 | −#define luaC_checkGC(L) \ | |
| 80 | − {condchangemem(L); if (G(L)->totalbytes >= G(L)->GCthreshold) luaC_step(L);} | |
| 111 | +#define luaC_checkGC(L) {condchangemem(L); if (G(L)->GCdebt > 0) luaC_step(L);} | |
| 81 | 112 | |
| 82 | 113 | |
| 83 | 114 | #define luaC_barrier(L,p,v) { if (valiswhite(v) && isblack(obj2gco(p))) \ |
| @@ -100,10 +131,10 @@ LUAI_FUNC void luaC_runtilstate (lua_State *L, int statesmask); · 16 unmodified lines | ||
| 100 | 131 | LUAI_FUNC void luaC_fullgc (lua_State *L, int isemergency); |
| 101 | 132 | LUAI_FUNC GCObject *luaC_newobj (lua_State *L, int tt, size_t sz, |
| 102 | 133 | GCObject **list, int offset); |
| 103 | −LUAI_FUNC void luaC_linkupval (lua_State *L, UpVal *uv); | |
| 104 | 134 | LUAI_FUNC void luaC_barrierf (lua_State *L, GCObject *o, GCObject *v); |
| 105 | 135 | LUAI_FUNC void luaC_barrierback (lua_State *L, Table *t); |
| 106 | 136 | LUAI_FUNC void luaC_checkfinalizer (lua_State *L, Udata *u); |
| 107 | − | |
| 137 | +LUAI_FUNC void luaC_checkupvalcolor (global_State *g, UpVal *uv); | |
| 138 | +LUAI_FUNC void luaC_changemode (lua_State *L, int mode); | |
| 108 | 139 | |
| 109 | 140 | #endif |
| @@ -1,5 +1,5 @@ | ||
| 1 | 1 | /* |
| 2 | −** $Id: linit.c,v 1.23 2009/12/22 15:32:50 roberto Exp $ | |
| 2 | +** $Id: linit.c,v 1.24 2010/03/26 20:58:11 roberto Exp $ | |
| 3 | 3 | ** Initialization of libraries for lua.c and other clients |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| @@ -52,9 +52,9 @@ LUALIB_API void luaL_openlibs (lua_State *L) { · 46 unmodified lines | ||
| 52 | 52 | const luaL_Reg *lib; |
| 53 | 53 | /* call open functions from 'loadedlibs' */ |
| 54 | 54 | for (lib = loadedlibs; lib->func; lib++) { |
| 55 | − lua_pushcfunction(L, lib->func); | |
| 55 | + lua_settop(L, 0); | |
| 56 | 56 | lua_pushstring(L, lib->name); |
| 57 | − lua_call(L, 1, 0); | |
| 57 | + (lib->func)(L); | |
| 58 | 58 | } |
| 59 | 59 | /* add open functions from 'preloadedlibs' into 'package.preload' table */ |
| 60 | 60 | lua_pushglobaltable(L); |
| @@ -65,8 +65,7 @@ LUALIB_API void luaL_openlibs (lua_State *L) { · 4 unmodified lines | ||
| 65 | 65 | } |
| 66 | 66 | lua_pop(L, 1); /* remove package.preload table */ |
| 67 | 67 | #if defined(LUA_COMPAT_DEBUGLIB) |
| 68 | − lua_pushglobaltable(L); | |
| 69 | − lua_getfield(L, -1, "require"); | |
| 68 | + lua_getglobal(L, "require"); | |
| 70 | 69 | lua_pushliteral(L, LUA_DBLIBNAME); |
| 71 | 70 | lua_call(L, 1, 0); /* call 'require"debug"' */ |
| 72 | 71 | lua_pop(L, 1); /* remove global table */ |
| @@ -1,5 +1,5 @@ | ||
| 1 | 1 | /* |
| 2 | −** $Id: liolib.c,v 2.85 2009/12/17 16:20:01 roberto Exp $ | |
| 2 | +** $Id: liolib.c,v 2.88 2010/03/26 20:58:11 roberto Exp $ | |
| 3 | 3 | ** Standard I/O (and system) library |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| @@ -103,13 +103,12 @@ static FILE *tofile (lua_State *L) { · 97 unmodified lines | ||
| 103 | 103 | } |
| 104 | 104 | |
| 105 | 105 | |
| 106 | − | |
| 107 | 106 | /* |
| 108 | 107 | ** When creating file handles, always creates a `closed' file handle |
| 109 | 108 | ** before opening the actual file; so, if there is a memory error, the |
| 110 | 109 | ** file is not left opened. |
| 111 | 110 | */ |
| 112 | −static FILE **newfile (lua_State *L) { | |
| 111 | +static FILE **newprefile (lua_State *L) { | |
| 113 | 112 | FILE **pf = (FILE **)lua_newuserdata(L, sizeof(FILE *)); |
| 114 | 113 | *pf = NULL; /* file handle is currently `closed' */ |
| 115 | 114 | luaL_getmetatable(L, LUA_FILEHANDLE); |
| @@ -118,6 +117,14 @@ static FILE **newfile (lua_State *L) { · 2 unmodified lines | ||
| 118 | 117 | } |
| 119 | 118 | |
| 120 | 119 | |
| 120 | +static FILE **newfile (lua_State *L) { | |
| 121 | + FILE **pf = newprefile(L); | |
| 122 | + lua_pushvalue(L, lua_upvalueindex(1)); /* set upvalue... */ | |
| 123 | + lua_setenv(L, -2); /* ... as environment for new file */ | |
| 124 | + return pf; | |
| 125 | +} | |
| 126 | + | |
| 127 | + | |
| 121 | 128 | /* |
| 122 | 129 | ** function to (not) close the standard files stdin, stdout, and stderr |
| 123 | 130 | */ |
| @@ -156,7 +163,7 @@ static int io_fclose (lua_State *L) { · 32 unmodified lines | ||
| 156 | 163 | |
| 157 | 164 | |
| 158 | 165 | static int aux_close (lua_State *L) { |
| 159 | − lua_getfenv(L, 1); | |
| 166 | + lua_getenv(L, 1); | |
| 160 | 167 | lua_getfield(L, -1, "__close"); |
| 161 | 168 | return (lua_tocfunction(L, -1))(L); |
| 162 | 169 | } |
| @@ -164,7 +171,7 @@ static int aux_close (lua_State *L) { · 1 unmodified line | ||
| 164 | 171 | |
| 165 | 172 | static int io_close (lua_State *L) { |
| 166 | 173 | if (lua_isnone(L, 1)) |
| 167 | − lua_rawgeti(L, LUA_ENVIRONINDEX, IO_OUTPUT); | |
| 174 | + lua_rawgeti(L, lua_upvalueindex(1), IO_OUTPUT); | |
| 168 | 175 | tofile(L); /* make sure argument is a file */ |
| 169 | 176 | return aux_close(L); |
| 170 | 177 | } |
| @@ -229,7 +236,7 @@ static int io_tmpfile (lua_State *L) { · 58 unmodified lines | ||
| 229 | 236 | |
| 230 | 237 | static FILE *getiofile (lua_State *L, int findex) { |
| 231 | 238 | FILE *f; |
| 232 | − lua_rawgeti(L, LUA_ENVIRONINDEX, findex); | |
| 239 | + lua_rawgeti(L, lua_upvalueindex(1), findex); | |
| 233 | 240 | f = *(FILE **)lua_touserdata(L, -1); |
| 234 | 241 | if (f == NULL) |
| 235 | 242 | luaL_error(L, "standard %s file is closed", fnames[findex - 1]); |
| @@ -250,10 +257,10 @@ static int g_iofile (lua_State *L, int f, const char *mode) { · 14 unmodified lines | ||
| 250 | 257 | tofile(L); /* check that it's a valid file handle */ |
| 251 | 258 | lua_pushvalue(L, 1); |
| 252 | 259 | } |
| 253 | − lua_rawseti(L, LUA_ENVIRONINDEX, f); | |
| 260 | + lua_rawseti(L, lua_upvalueindex(1), f); | |
| 254 | 261 | } |
| 255 | 262 | /* return current value */ |
| 256 | − lua_rawgeti(L, LUA_ENVIRONINDEX, f); | |
| 263 | + lua_rawgeti(L, lua_upvalueindex(1), f); | |
| 257 | 264 | return 1; |
| 258 | 265 | } |
| 259 | 266 | |
| @@ -271,35 +278,46 @@ static int io_output (lua_State *L) { · 11 unmodified lines | ||
| 271 | 278 | static int io_readline (lua_State *L); |
| 272 | 279 | |
| 273 | 280 | |
| 274 | −static void aux_lines (lua_State *L, int idx, int toclose) { | |
| 275 | − lua_pushvalue(L, idx); | |
| 281 | +static void aux_lines (lua_State *L, int toclose) { | |
| 282 | + int i; | |
| 283 | + int n = lua_gettop(L) - 1; /* number of arguments to read */ | |
| 284 | + /* ensure that arguments will fit here and into 'io_readline' stack */ | |
| 285 | + luaL_argcheck(L, n <= LUA_MINSTACK - 3, LUA_MINSTACK - 3, "too many options"); | |
| 286 | + lua_pushvalue(L, 1); /* file handle */ | |
| 287 | + lua_pushinteger(L, n); /* number of arguments to read */ | |
| 276 | 288 | lua_pushboolean(L, toclose); /* close/not close file when finished */ |
| 277 | − lua_pushcclosure(L, io_readline, 2); | |
| 289 | + for (i = 1; i <= n; i++) lua_pushvalue(L, i + 1); /* copy arguments */ | |
| 290 | + lua_pushcclosure(L, io_readline, 3 + n); | |
| 278 | 291 | } |
| 279 | 292 | |
| 280 | 293 | |
| 281 | 294 | static int f_lines (lua_State *L) { |
| 282 | 295 | tofile(L); /* check that it's a valid file handle */ |
| 283 | − aux_lines(L, 1, 0); | |
| 296 | + aux_lines(L, 0); | |
| 284 | 297 | return 1; |
| 285 | 298 | } |
| 286 | 299 | |
| 287 | 300 | |
| 288 | 301 | static int io_lines (lua_State *L) { |
| 289 | − if (lua_isnoneornil(L, 1)) { /* no arguments? */ | |
| 290 | − /* will iterate over default input */ | |
| 291 | − lua_rawgeti(L, LUA_ENVIRONINDEX, IO_INPUT); | |
| 292 | − return f_lines(L); | |
| 302 | + int toclose; | |
| 303 | + if (lua_isnone(L, 1)) lua_pushnil(L); /* at least one argument */ | |
| 304 | + if (lua_isnil(L, 1)) { /* no file name? */ | |
| 305 | + lua_rawgeti(L, lua_upvalueindex(1), IO_INPUT); /* get default input */ | |
| 306 | + lua_replace(L, 1); /* put it at index 1 */ | |
| 307 | + tofile(L); /* check that it's a valid file handle */ | |
| 308 | + toclose = 0; /* do not close it after iteration */ | |
| 293 | 309 | } |
| 294 | − else { | |
| 310 | + else { /* open a new file */ | |
| 295 | 311 | const char *filename = luaL_checkstring(L, 1); |
| 296 | 312 | FILE **pf = newfile(L); |
| 297 | 313 | *pf = fopen(filename, "r"); |
| 298 | 314 | if (*pf == NULL) |
| 299 | 315 | fileerror(L, 1, filename); |
| 300 | − aux_lines(L, lua_gettop(L), 1); | |
| 301 | − return 1; | |
| 316 | + lua_replace(L, 1); /* put file at index 1 */ | |
| 317 | + toclose = 1; /* close it after iteration */ | |
| 302 | 318 | } |
| 319 | + aux_lines(L, toclose); | |
| 320 | + return 1; | |
| 303 | 321 | } |
| 304 | 322 | |
| 305 | 323 | |
| @@ -316,7 +334,10 @@ static int read_number (lua_State *L, FILE *f) { · 10 unmodified lines | ||
| 316 | 334 | lua_pushnumber(L, d); |
| 317 | 335 | return 1; |
| 318 | 336 | } |
| 319 | − else return 0; /* read fails */ | |
| 337 | + else { | |
| 338 | + lua_pushnil(L); /* "result" to be removed */ | |
| 339 | + return 0; /* read fails */ | |
| 340 | + } | |
| 320 | 341 | } |
| 321 | 342 | |
| 322 | 343 | |
| @@ -328,7 +349,7 @@ static int test_eof (lua_State *L, FILE *f) { · 5 unmodified lines | ||
| 328 | 349 | } |
| 329 | 350 | |
| 330 | 351 | |
| 331 | −static int read_line (lua_State *L, FILE *f) { | |
| 352 | +static int read_line (lua_State *L, FILE *f, int chop) { | |
| 332 | 353 | luaL_Buffer b; |
| 333 | 354 | luaL_buffinit(L, &b); |
| 334 | 355 | for (;;) { |
| @@ -342,7 +363,7 @@ static int read_line (lua_State *L, FILE *f) { · 7 unmodified lines | ||
| 342 | 363 | if (l == 0 || p[l-1] != '\n') |
| 343 | 364 | luaL_addsize(&b, l); |
| 344 | 365 | else { |
| 345 | − luaL_addsize(&b, l - 1); /* do not include `eol' */ | |
| 366 | + luaL_addsize(&b, l - chop); /* chop 'eol' if needed */ | |
| 346 | 367 | luaL_pushresult(&b); /* close buffer */ |
| 347 | 368 | return 1; /* read at least an `eol' */ |
| 348 | 369 | } |
| @@ -375,7 +396,7 @@ static int g_read (lua_State *L, FILE *f, int first) { · 26 unmodified lines | ||
| 375 | 396 | int n; |
| 376 | 397 | clearerr(f); |
| 377 | 398 | if (nargs == 0) { /* no arguments? */ |
| 378 | − success = read_line(L, f); | |
| 399 | + success = read_line(L, f, 1); | |
| 379 | 400 | n = first+1; /* to return 1 result */ |
| 380 | 401 | } |
| 381 | 402 | else { /* ensure stack space for all results and for auxlib's buffer */ |
| @@ -394,7 +415,10 @@ static int g_read (lua_State *L, FILE *f, int first) { · 12 unmodified lines | ||
| 394 | 415 | success = read_number(L, f); |
| 395 | 416 | break; |
| 396 | 417 | case 'l': /* line */ |
| 397 | − success = read_line(L, f); | |
| 418 | + success = read_line(L, f, 1); | |
| 419 | + break; | |
| 420 | + case 'L': /* line with end-of-line */ | |
| 421 | + success = read_line(L, f, 0); | |
| 398 | 422 | break; |
| 399 | 423 | case 'a': /* file */ |
| 400 | 424 | read_chars(L, f, ~((size_t)0)); /* read MAX_SIZE_T chars */ |
| @@ -428,15 +452,22 @@ static int f_read (lua_State *L) { · 27 unmodified lines | ||
| 428 | 452 | |
| 429 | 453 | static int io_readline (lua_State *L) { |
| 430 | 454 | FILE *f = *(FILE **)lua_touserdata(L, lua_upvalueindex(1)); |
| 431 | − int success; | |
| 455 | + int i; | |
| 456 | + int n = lua_tointeger(L, lua_upvalueindex(2)); | |
| 432 | 457 | if (f == NULL) /* file is already closed? */ |
| 433 | 458 | luaL_error(L, "file is already closed"); |
| 434 | − success = read_line(L, f); | |
| 435 | − if (ferror(f)) | |
| 436 | − return luaL_error(L, "%s", strerror(errno)); | |
| 437 | − if (success) return 1; | |
| 438 | − else { /* EOF */ | |
| 439 | − if (lua_toboolean(L, lua_upvalueindex(2))) { /* generator created file? */ | |
| 459 | + lua_settop(L , 1); | |
| 460 | + for (i = 1; i <= n; i++) /* push arguments to 'g_read' */ | |
| 461 | + lua_pushvalue(L, lua_upvalueindex(3 + i)); | |
| 462 | + n = g_read(L, f, 2); /* 'n' is number of results */ | |
| 463 | + lua_assert(n > 0); /* should return at least a nil */ | |
| 464 | + if (!lua_isnil(L, -n)) /* read at least one value? */ | |
| 465 | + return n; /* return them */ | |
| 466 | + else { /* first result is nil: EOF or error */ | |
| 467 | + if (!lua_isnil(L, -1)) /* is there error information? */ | |
| 468 | + return luaL_error(L, "%s", lua_tostring(L, -1)); /* error */ | |
| 469 | + /* else EOF */ | |
| 470 | + if (lua_toboolean(L, lua_upvalueindex(3))) { /* generator created file? */ | |
| 440 | 471 | lua_settop(L, 0); |
| 441 | 472 | lua_pushvalue(L, lua_upvalueindex(1)); |
| 442 | 473 | aux_close(L); /* close it */ |
| @@ -552,23 +583,27 @@ static void createmeta (lua_State *L) { · 109 unmodified lines | ||
| 552 | 583 | luaL_newmetatable(L, LUA_FILEHANDLE); /* create metatable for file handles */ |
| 553 | 584 | lua_pushvalue(L, -1); /* push metatable */ |
| 554 | 585 | lua_setfield(L, -2, "__index"); /* metatable.__index = metatable */ |
| 555 | − luaL_register(L, NULL, flib); /* file methods */ | |
| 586 | + luaL_register(L, NULL, flib); /* add file methods to new metatable */ | |
| 587 | + lua_pop(L, 1); /* pop new metatable */ | |
| 556 | 588 | } |
| 557 | 589 | |
| 558 | 590 | |
| 559 | 591 | static void createstdfile (lua_State *L, FILE *f, int k, const char *fname) { |
| 560 | − *newfile(L) = f; | |
| 592 | + *newprefile(L) = f; | |
| 561 | 593 | if (k > 0) { |
| 562 | − lua_pushvalue(L, -1); | |
| 563 | − lua_rawseti(L, LUA_ENVIRONINDEX, k); | |
| 594 | + lua_pushvalue(L, -1); /* copy new file */ | |
| 595 | + lua_rawseti(L, 1, k); /* add it to common upvalue */ | |
| 564 | 596 | } |
| 565 | − lua_pushvalue(L, -2); /* copy environment */ | |
| 566 | − lua_setfenv(L, -2); /* set it */ | |
| 567 | − lua_setfield(L, -3, fname); | |
| 597 | + lua_pushvalue(L, 3); /* get environment for default files */ | |
| 598 | + lua_setenv(L, -2); /* set it as environment for file */ | |
| 599 | + lua_setfield(L, 2, fname); /* add file to module */ | |
| 568 | 600 | } |
| 569 | 601 | |
| 570 | 602 | |
| 571 | −static void newfenv (lua_State *L, lua_CFunction cls) { | |
| 603 | +/* | |
| 604 | +** pushes a new table with {__close = cls} | |
| 605 | +*/ | |
| 606 | +static void newenv (lua_State *L, lua_CFunction cls) { | |
| 572 | 607 | lua_createtable(L, 0, 1); |
| 573 | 608 | lua_pushcfunction(L, cls); |
| 574 | 609 | lua_setfield(L, -2, "__close"); |
| @@ -576,21 +611,21 @@ static void newfenv (lua_State *L, lua_CFunction cls) { · 1 unmodified line | ||
| 576 | 611 | |
| 577 | 612 | |
| 578 | 613 | LUAMOD_API int luaopen_io (lua_State *L) { |
| 614 | + lua_settop(L, 0); | |
| 579 | 615 | createmeta(L); |
| 580 | 616 | /* create (private) environment (with fields IO_INPUT, IO_OUTPUT, __close) */ |
| 581 | − newfenv(L, io_fclose); | |
| 582 | − lua_replace(L, LUA_ENVIRONINDEX); | |
| 583 | − /* open library */ | |
| 584 | − luaL_register(L, LUA_IOLIBNAME, iolib); | |
| 617 | + newenv(L, io_fclose); /* upvalue for all io functions at index 1 */ | |
| 618 | + lua_pushvalue(L, -1); /* copy to be consumed by 'openlib' */ | |
| 619 | + luaL_openlib(L, LUA_IOLIBNAME, iolib, 1); /* new module at index 2 */ | |
| 585 | 620 | /* create (and set) default files */ |
| 586 | − newfenv(L, io_noclose); /* close function for default files */ | |
| 621 | + newenv(L, io_noclose); /* environment for default files at index 3 */ | |
| 587 | 622 | createstdfile(L, stdin, IO_INPUT, "stdin"); |
| 588 | 623 | createstdfile(L, stdout, IO_OUTPUT, "stdout"); |
| 589 | 624 | createstdfile(L, stderr, 0, "stderr"); |
| 590 | 625 | lua_pop(L, 1); /* pop environment for default files */ |
| 591 | − lua_getfield(L, -1, "popen"); | |
| 592 | − newfenv(L, io_pclose); /* create environment for 'popen' */ | |
| 593 | − lua_setfenv(L, -2); /* set fenv for 'popen' */ | |
| 626 | + lua_getfield(L, 2, "popen"); | |
| 627 | + newenv(L, io_pclose); /* create environment for 'popen' streams */ | |
| 628 | + lua_setupvalue(L, -2, 1); /* set it as upvalue for 'popen' */ | |
| 594 | 629 | lua_pop(L, 1); /* pop 'popen' */ |
| 595 | 630 | return 1; |
| 596 | 631 | } |
| @@ -1,5 +1,5 @@ | ||
| 1 | 1 | /* |
| 2 | −** $Id: llex.c,v 2.34 2009/11/17 16:33:38 roberto Exp $ | |
| 2 | +** $Id: llex.c,v 2.37 2010/04/16 12:31:07 roberto Exp $ | |
| 3 | 3 | ** Lexical Analyzer |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| @@ -117,21 +117,30 @@ void luaX_syntaxerror (LexState *ls, const char *msg) { · 111 unmodified lines | ||
| 117 | 117 | } |
| 118 | 118 | |
| 119 | 119 | |
| 120 | +/* | |
| 121 | +** creates a new string and anchors it in function's table so that | |
| 122 | +** it will not be collected until the end of the function's compilation | |
| 123 | +** (by that time it should be anchored in function's prototype) | |
| 124 | +*/ | |
| 120 | 125 | TString *luaX_newstring (LexState *ls, const char *str, size_t l) { |
| 121 | 126 | lua_State *L = ls->L; |
| 122 | 127 | TValue *o; /* entry for `str' */ |
| 123 | − TString *ts = luaS_newlstr(L, str, l); | |
| 124 | − setsvalue2s(L, L->top++, ts); /* anchor string */ | |
| 125 | − o = luaH_setstr(L, ls->fs->h, ts); | |
| 128 | + TString *ts = luaS_newlstr(L, str, l); /* create new string */ | |
| 129 | + setsvalue2s(L, L->top++, ts); /* temporarily anchor it in stack */ | |
| 130 | + o = luaH_setstr(L, ls->fs->h, ts); | |
| 126 | 131 | if (ttisnil(o)) { |
| 127 | − setbvalue(o, 1); /* make sure `str' will not be collected */ | |
| 132 | + setbvalue(o, 1); /* t[string] = true */ | |
| 128 | 133 | luaC_checkGC(L); |
| 129 | 134 | } |
| 130 | − L->top--; | |
| 135 | + L->top--; /* remove string from stack */ | |
| 131 | 136 | return ts; |
| 132 | 137 | } |
| 133 | 138 | |
| 134 | 139 | |
| 140 | +/* | |
| 141 | +** increment line number and skips newline sequence (any of | |
| 142 | +** \n, \r, \n\r, or \r\n) | |
| 143 | +*/ | |
| 135 | 144 | static void inclinenumber (LexState *ls) { |
| 136 | 145 | int old = ls->current; |
| 137 | 146 | lua_assert(currIsNewline(ls)); |
| @@ -152,6 +161,8 @@ void luaX_setinput (lua_State *L, LexState *ls, ZIO *z, TString *source) { · 14 unmodified lines | ||
| 152 | 161 | ls->linenumber = 1; |
| 153 | 162 | ls->lastline = 1; |
| 154 | 163 | ls->source = source; |
| 164 | + ls->envn = luaS_new(L, "_ENV"); /* create env name */ | |
| 165 | + luaS_fix(ls->envn); /* never collect this name */ | |
| 155 | 166 | luaZ_resizebuffer(ls->L, ls->buff, LUA_MINBUFFER); /* initialize buffer */ |
| 156 | 167 | next(ls); /* read first char */ |
| 157 | 168 | } |
| @@ -174,6 +185,9 @@ static int check_next (LexState *ls, const char *set) { · 16 unmodified lines | ||
| 174 | 185 | } |
| 175 | 186 | |
| 176 | 187 | |
| 188 | +/* | |
| 189 | +** change all characters 'from' in buffer to 'to' | |
| 190 | +*/ | |
| 177 | 191 | static void buffreplace (LexState *ls, char from, char to) { |
| 178 | 192 | size_t n = luaZ_bufflen(ls->buff); |
| 179 | 193 | char *p = luaZ_buffer(ls->buff); |
| @@ -186,11 +200,14 @@ static void buffreplace (LexState *ls, char from, char to) { · 6 unmodified lines | ||
| 186 | 200 | #define getlocaledecpoint() (localeconv()->decimal_point[0]) |
| 187 | 201 | #endif |
| 188 | 202 | |
| 203 | +/* | |
| 204 | +** in case of format error, try to change decimal point separator to | |
| 205 | +** the one defined in the current locale and check again | |
| 206 | +*/ | |
| 189 | 207 | static void trydecpoint (LexState *ls, SemInfo *seminfo) { |
| 190 | − /* format error: try to update decimal point separator */ | |
| 191 | 208 | char old = ls->decpoint; |
| 192 | 209 | ls->decpoint = getlocaledecpoint(); |
| 193 | − buffreplace(ls, old, ls->decpoint); /* try updated decimal separator */ | |
| 210 | + buffreplace(ls, old, ls->decpoint); /* try new decimal separator */ | |
| 194 | 211 | if (!luaO_str2d(luaZ_buffer(ls->buff), &seminfo->r)) { |
| 195 | 212 | /* format error with correct decimal point: no more options */ |
| 196 | 213 | buffreplace(ls, ls->decpoint, '.'); /* undo change (for error message) */ |
| @@ -216,6 +233,10 @@ static void read_numeral (LexState *ls, SemInfo *seminfo) { · 19 unmodified lines | ||
| 216 | 233 | } |
| 217 | 234 | |
| 218 | 235 | |
| 236 | +/* | |
| 237 | +** skip a sequence '[=*=[' or ']=*]' and return its number of '='s or | |
| 238 | +** -1 if sequence is malformed | |
| 239 | +*/ | |
| 219 | 240 | static int skip_sep (LexState *ls) { |
| 220 | 241 | int count = 0; |
| 221 | 242 | int s = ls->current; |
| @@ -246,8 +267,7 @@ static void read_long_string (LexState *ls, SemInfo *seminfo, int sep) { · 24 unmodified lines | ||
| 246 | 267 | } |
| 247 | 268 | break; |
| 248 | 269 | } |
| 249 | − case '\n': | |
| 250 | − case '\r': { | |
| 270 | + case '\n': case '\r': { | |
| 251 | 271 | save(ls, '\n'); |
| 252 | 272 | inclinenumber(ls); |
| 253 | 273 | if (!seminfo) luaZ_resetbuffer(ls->buff); /* avoid wasting space */ |
| @@ -308,16 +328,16 @@ static int readdecesc (LexState *ls) { · 54 unmodified lines | ||
| 308 | 328 | |
| 309 | 329 | |
| 310 | 330 | static void read_string (LexState *ls, int del, SemInfo *seminfo) { |
| 311 | − save_and_next(ls); | |
| 331 | + save_and_next(ls); /* keep delimiter (for error messages) */ | |
| 312 | 332 | while (ls->current != del) { |
| 313 | 333 | switch (ls->current) { |
| 314 | 334 | case EOZ: |
| 315 | 335 | lexerror(ls, "unfinished string", TK_EOS); |
| 316 | − continue; /* to avoid warnings */ | |
| 336 | + break; /* to avoid warnings */ | |
| 317 | 337 | case '\n': |
| 318 | 338 | case '\r': |
| 319 | 339 | lexerror(ls, "unfinished string", TK_STRING); |
| 320 | − continue; /* to avoid warnings */ | |
| 340 | + break; /* to avoid warnings */ | |
| 321 | 341 | case '\\': { /* escape sequences */ |
| 322 | 342 | int c; /* final character to be saved */ |
| 323 | 343 | next(ls); /* do not save the `\' */ |
| @@ -333,6 +353,14 @@ static void read_string (LexState *ls, int del, SemInfo *seminfo) { · 9 unmodified lines | ||
| 333 | 353 | case '\n': |
| 334 | 354 | case '\r': save(ls, '\n'); inclinenumber(ls); continue; |
| 335 | 355 | case EOZ: continue; /* will raise an error next loop */ |
| 356 | + case '*': { /* skip following span of spaces */ | |
| 357 | + next(ls); /* skip the '*' */ | |
| 358 | + while (lisspace(ls->current)) { | |
| 359 | + if (currIsNewline(ls)) inclinenumber(ls); | |
| 360 | + else next(ls); | |
| 361 | + } | |
| 362 | + continue; /* do not save 'c' */ | |
| 363 | + } | |
| 336 | 364 | default: { |
| 337 | 365 | if (!lisdigit(ls->current)) |
| 338 | 366 | c = ls->current; /* handles \\, \", \', and \? */ |
| @@ -343,7 +371,7 @@ static void read_string (LexState *ls, int del, SemInfo *seminfo) { · 4 unmodified lines | ||
| 343 | 371 | } |
| 344 | 372 | next(ls); |
| 345 | 373 | save(ls, c); |
| 346 | − continue; | |
| 374 | + break; | |
| 347 | 375 | } |
| 348 | 376 | default: |
| 349 | 377 | save_and_next(ls); |
| @@ -359,31 +387,34 @@ static int llex (LexState *ls, SemInfo *seminfo) { · 9 unmodified lines | ||
| 359 | 387 | luaZ_resetbuffer(ls->buff); |
| 360 | 388 | for (;;) { |
| 361 | 389 | switch (ls->current) { |
| 362 | − case '\n': | |
| 363 | − case '\r': { | |
| 390 | + case '\n': case '\r': { /* line breaks */ | |
| 364 | 391 | inclinenumber(ls); |
| 365 | − continue; | |
| 392 | + break; | |
| 366 | 393 | } |
| 367 | − case '-': { | |
| 394 | + case ' ': case '\f': case '\t': case '\v': { /* spaces */ | |
| 395 | + next(ls); | |
| 396 | + break; | |
| 397 | + } | |
| 398 | + case '-': { /* '-' or '--' (comment) */ | |
| 368 | 399 | next(ls); |
| 369 | 400 | if (ls->current != '-') return '-'; |
| 370 | 401 | /* else is a comment */ |
| 371 | 402 | next(ls); |
| 372 | − if (ls->current == '[') { | |
| 403 | + if (ls->current == '[') { /* long comment? */ | |
| 373 | 404 | int sep = skip_sep(ls); |
| 374 | 405 | luaZ_resetbuffer(ls->buff); /* `skip_sep' may dirty the buffer */ |
| 375 | 406 | if (sep >= 0) { |
| 376 | − read_long_string(ls, NULL, sep); /* long comment */ | |
| 377 | − luaZ_resetbuffer(ls->buff); | |
| 378 | − continue; | |
| 407 | + read_long_string(ls, NULL, sep); /* skip long comment */ | |
| 408 | + luaZ_resetbuffer(ls->buff); /* previous call may dirty the buff. */ | |
| 409 | + break; | |
| 379 | 410 | } |
| 380 | 411 | } |
| 381 | 412 | /* else short comment */ |
| 382 | 413 | while (!currIsNewline(ls) && ls->current != EOZ) |
| 383 | − next(ls); | |
| 384 | − continue; | |
| 414 | + next(ls); /* skip until end of line (or end of file) */ | |
| 415 | + break; | |
| 385 | 416 | } |
| 386 | − case '[': { | |
| 417 | + case '[': { /* long string or simply '[' */ | |
| 387 | 418 | int sep = skip_sep(ls); |
| 388 | 419 | if (sep >= 0) { |
| 389 | 420 | read_long_string(ls, seminfo, sep); |
| @@ -412,39 +443,30 @@ static int llex (LexState *ls, SemInfo *seminfo) { · 22 unmodified lines | ||
| 412 | 443 | if (ls->current != '=') return '~'; |
| 413 | 444 | else { next(ls); return TK_NE; } |
| 414 | 445 | } |
| 415 | − case '"': | |
| 416 | − case '\'': { | |
| 446 | + case '"': case '\'': { /* short literal strings */ | |
| 417 | 447 | read_string(ls, ls->current, seminfo); |
| 418 | 448 | return TK_STRING; |
| 419 | 449 | } |
| 420 | − case '.': { | |
| 450 | + case '.': { /* '.', '..', '...', or number */ | |
| 421 | 451 | save_and_next(ls); |
| 422 | 452 | if (check_next(ls, ".")) { |
| 423 | 453 | if (check_next(ls, ".")) |
| 424 | − return TK_DOTS; /* ... */ | |
| 425 | − else return TK_CONCAT; /* .. */ | |
| 454 | + return TK_DOTS; /* '...' */ | |
| 455 | + else return TK_CONCAT; /* '..' */ | |
| 426 | 456 | } |
| 427 | 457 | else if (!lisdigit(ls->current)) return '.'; |
| 428 | − else { | |
| 429 | − read_numeral(ls, seminfo); | |
| 430 | − return TK_NUMBER; | |
| 431 | − } | |
| 458 | + /* else go through */ | |
| 459 | + } | |
| 460 | + case '0': case '1': case '2': case '3': case '4': | |
| 461 | + case '5': case '6': case '7': case '8': case '9': { | |
| 462 | + read_numeral(ls, seminfo); | |
| 463 | + return TK_NUMBER; | |
| 432 | 464 | } |
| 433 | 465 | case EOZ: { |
| 434 | 466 | return TK_EOS; |
| 435 | 467 | } |
| 436 | 468 | default: { |
| 437 | − if (lisspace(ls->current)) { | |
| 438 | − lua_assert(!currIsNewline(ls)); | |
| 439 | − next(ls); | |
| 440 | − continue; | |
| 441 | − } | |
| 442 | − else if (lisdigit(ls->current)) { | |
| 443 | − read_numeral(ls, seminfo); | |
| 444 | − return TK_NUMBER; | |
| 445 | − } | |
| 446 | − else if (lislalpha(ls->current)) { | |
| 447 | − /* identifier or reserved word */ | |
| 469 | + if (lislalpha(ls->current)) { /* identifier or reserved word? */ | |
| 448 | 470 | TString *ts; |
| 449 | 471 | do { |
| 450 | 472 | save_and_next(ls); |
| @@ -458,10 +480,10 @@ static int llex (LexState *ls, SemInfo *seminfo) { · 7 unmodified lines | ||
| 458 | 480 | return TK_NAME; |
| 459 | 481 | } |
| 460 | 482 | } |
| 461 | − else { | |
| 483 | + else { /* single-char tokens (+ - / ...) */ | |
| 462 | 484 | int c = ls->current; |
| 463 | 485 | next(ls); |
| 464 | − return c; /* single-char tokens (+ - / ...) */ | |
| 486 | + return c; | |
| 465 | 487 | } |
| 466 | 488 | } |
| 467 | 489 | } |
| @@ -1,5 +1,5 @@ | ||
| 1 | 1 | /* |
| 2 | −** $Id: llex.h,v 1.62 2009/10/11 20:02:19 roberto Exp $ | |
| 2 | +** $Id: llex.h,v 1.65 2010/04/05 16:35:37 roberto Exp $ | |
| 3 | 3 | ** Lexical Analyzer |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| @@ -60,6 +60,7 @@ typedef struct LexState { · 54 unmodified lines | ||
| 60 | 60 | Mbuffer *buff; /* buffer for tokens */ |
| 61 | 61 | struct Varlist *varl; /* list of all active local variables */ |
| 62 | 62 | TString *source; /* current source name */ |
| 63 | + TString *envn; /* environment variable name */ | |
| 63 | 64 | char decpoint; /* locale decimal point */ |
| 64 | 65 | } LexState; |
| 65 | 66 | |
| @@ -1,5 +1,5 @@ | ||
| 1 | 1 | /* |
| 2 | −** $Id: llimits.h,v 1.77 2009/12/17 12:50:20 roberto Exp $ | |
| 2 | +** $Id: llimits.h,v 1.80 2010/05/07 18:44:12 roberto Exp $ | |
| 3 | 3 | ** Limits, basic types, and some other `installation-dependent' definitions |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| @@ -30,6 +30,7 @@ typedef unsigned char lu_byte; · 24 unmodified lines | ||
| 30 | 30 | #define MAX_SIZET ((size_t)(~(size_t)0)-2) |
| 31 | 31 | |
| 32 | 32 | #define MAX_LUMEM ((lu_mem)(~(lu_mem)0)-2) |
| 33 | +#define MIN_LMEM ((l_mem)~((~(lu_mem)0)>>1)) | |
| 33 | 34 | |
| 34 | 35 | |
| 35 | 36 | #define MAX_INT (INT_MAX-2) /* maximum value of an int (-2 for safety) */ |
| @@ -59,7 +60,7 @@ typedef LUAI_UACNUMBER l_uacNumber; · 23 unmodified lines | ||
| 59 | 60 | #if defined(lua_assert) |
| 60 | 61 | #define check_exp(c,e) (lua_assert(c), (e)) |
| 61 | 62 | #else |
| 62 | −#define lua_assert(c) ((void)0) | |
| 63 | +#define lua_assert(c) /* empty */ | |
| 63 | 64 | #define check_exp(c,e) (e) |
| 64 | 65 | #endif |
| 65 | 66 | |
| @@ -139,19 +140,19 @@ typedef lu_int32 Instruction; · 73 unmodified lines | ||
| 139 | 140 | ** created/deleted/resumed/yielded. |
| 140 | 141 | */ |
| 141 | 142 | #if !defined(luai_userstateopen) |
| 142 | −#define luai_userstateopen(L) ((void)L) | |
| 143 | +#define luai_userstateopen(L) ((void)L) | |
| 143 | 144 | #endif |
| 144 | 145 | |
| 145 | 146 | #if !defined(luai_userstateclose) |
| 146 | −#define luai_userstateclose(L) ((void)L) | |
| 147 | +#define luai_userstateclose(L) ((void)L) | |
| 147 | 148 | #endif |
| 148 | 149 | |
| 149 | 150 | #if !defined(luai_userstatethread) |
| 150 | −#define luai_userstatethread(L,L1) ((void)L) | |
| 151 | +#define luai_userstatethread(L,L1) ((void)L) | |
| 151 | 152 | #endif |
| 152 | 153 | |
| 153 | 154 | #if !defined(luai_userstatefree) |
| 154 | −#define luai_userstatefree(L) ((void)L) | |
| 155 | +#define luai_userstatefree(L,L1) ((void)L) | |
| 155 | 156 | #endif |
| 156 | 157 | |
| 157 | 158 | #if !defined(luai_userstateresume) |
| @@ -1,5 +1,5 @@ | ||
| 1 | 1 | /* |
| 2 | −** $Id: lmem.c,v 1.74 2009/12/16 16:42:58 roberto Exp $ | |
| 2 | +** $Id: lmem.c,v 1.79 2010/05/05 18:49:56 roberto Exp $ | |
| 3 | 3 | ** Interface to Memory Manager |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| @@ -79,13 +79,14 @@ void *luaM_realloc_ (lua_State *L, void *block, size_t osize, size_t nsize) { · 73 unmodified lines | ||
| 79 | 79 | size_t realosize = (block) ? osize : 0; |
| 80 | 80 | lua_assert((realosize == 0) == (block == NULL)); |
| 81 | 81 | #if defined(HARDMEMTESTS) |
| 82 | − if (nsize > realosize && g->GCthreshold != MAX_LUMEM) | |
| 82 | + if (nsize > realosize && !gcstopped(g)) | |
| 83 | 83 | luaC_fullgc(L, 1); /* force a GC whenever possible */ |
| 84 | 84 | #endif |
| 85 | 85 | newblock = (*g->frealloc)(g->ud, block, osize, nsize); |
| 86 | 86 | if (newblock == NULL && nsize > 0) { |
| 87 | − lua_assert(nsize > realosize); /* cannot fail when shrinking a block */ | |
| 88 | − if (g->GCthreshold != MAX_LUMEM) { | |
| 87 | + api_check(L, nsize > realosize, | |
| 88 | + "realloc cannot fail when shrinking a block"); | |
| 89 | + if (!gcstopped(g)) { | |
| 89 | 90 | luaC_fullgc(L, 1); /* try to free some memory... */ |
| 90 | 91 | newblock = (*g->frealloc)(g->ud, block, osize, nsize); /* try again */ |
| 91 | 92 | } |
| @@ -94,6 +95,26 @@ void *luaM_realloc_ (lua_State *L, void *block, size_t osize, size_t nsize) { · 2 unmodified lines | ||
| 94 | 95 | } |
| 95 | 96 | lua_assert((nsize == 0) == (newblock == NULL)); |
| 96 | 97 | g->totalbytes = (g->totalbytes - realosize) + nsize; |
| 98 | + if (!gcstopped(g)) | |
| 99 | + g->GCdebt += nsize; /* give some credit to garbage collector */ | |
| 100 | +#if defined(TRACEMEM) | |
| 101 | + { /* auxiliary patch to monitor garbage collection. | |
| 102 | + ** To plot, gnuplot with following command: | |
| 103 | + ** plot TRACEMEM using 1:2 with lines, TRACEMEM using 1:3 with lines | |
| 104 | + */ | |
| 105 | + static unsigned long total = 0; /* our "time" */ | |
| 106 | + static FILE *f = NULL; /* output file */ | |
| 107 | + total++; /* "time" always grows */ | |
| 108 | + if ((total % 200) == 0) { | |
| 109 | + if (f == NULL) f = fopen(TRACEMEM, "w"); | |
| 110 | + fprintf(f, "%lu %u %d %d\n", total, | |
| 111 | + g->totalbytes, | |
| 112 | + gcstopped(g) ? 0 : g->GCdebt, | |
| 113 | + g->gcstate * 1000); | |
| 114 | + } | |
| 115 | + } | |
| 116 | +#endif | |
| 117 | + | |
| 97 | 118 | return newblock; |
| 98 | 119 | } |
| 99 | 120 | |
| @@ -1,5 +1,5 @@ | ||
| 1 | 1 | /* |
| 2 | −** $Id: lmem.h,v 1.35 2009/12/16 16:42:58 roberto Exp $ | |
| 2 | +** $Id: lmem.h,v 1.36 2010/04/08 17:16:46 roberto Exp $ | |
| 3 | 3 | ** Interface to Memory Manager |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| @@ -13,8 +13,6 @@ · 7 unmodified lines | ||
| 13 | 13 | #include "llimits.h" |
| 14 | 14 | #include "lua.h" |
| 15 | 15 | |
| 16 | −#define MEMERRMSG "not enough memory" | |
| 17 | − | |
| 18 | 16 | |
| 19 | 17 | #define luaM_reallocv(L,b,on,n,e) \ |
| 20 | 18 | ((cast(size_t, (n)+1) <= MAX_SIZET/(e)) ? /* +1 to avoid warnings */ \ |
| @@ -1,5 +1,5 @@ | ||
| 1 | 1 | /* |
| 2 | −** $Id: loadlib.c,v 1.80 2010/01/13 16:30:27 roberto Exp $ | |
| 2 | +** $Id: loadlib.c,v 1.82 2010/03/19 15:02:34 roberto Exp $ | |
| 3 | 3 | ** Dynamic library loader for Lua |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | ** |
| @@ -353,9 +353,7 @@ static int ll_loadfunc (lua_State *L, const char *path, const char *sym) { · 347 unmodified lines | ||
| 353 | 353 | lua_CFunction f = ll_sym(L, *reg, sym); |
| 354 | 354 | if (f == NULL) |
| 355 | 355 | return ERRFUNC; /* unable to find function */ |
| 356 | − lua_pushcfunction(L, f); /* else create new function... */ | |
| 357 | − lua_pushglobaltable(L); /* ... and set the standard global table... */ | |
| 358 | − lua_setfenv(L, -2); /* ... as its environment */ | |
| 356 | + lua_pushcfunction(L, f); /* else create new function */ | |
| 359 | 357 | return 0; /* no errors */ |
| 360 | 358 | } |
| 361 | 359 | } |
| @@ -435,7 +433,7 @@ static int ll_searchpath (lua_State *L) { · 73 unmodified lines | ||
| 435 | 433 | static const char *findfile (lua_State *L, const char *name, |
| 436 | 434 | const char *pname) { |
| 437 | 435 | const char *path; |
| 438 | − lua_getfield(L, LUA_ENVIRONINDEX, pname); | |
| 436 | + lua_getfield(L, lua_upvalueindex(1), pname); | |
| 439 | 437 | path = lua_tostring(L, -1); |
| 440 | 438 | if (path == NULL) |
| 441 | 439 | luaL_error(L, LUA_QL("package.%s") " must be a string", pname); |
| @@ -509,7 +507,7 @@ static int loader_Croot (lua_State *L) { · 67 unmodified lines | ||
| 509 | 507 | |
| 510 | 508 | static int loader_preload (lua_State *L) { |
| 511 | 509 | const char *name = luaL_checkstring(L, 1); |
| 512 | − lua_getfield(L, LUA_ENVIRONINDEX, "preload"); | |
| 510 | + lua_getfield(L, lua_upvalueindex(1), "preload"); | |
| 513 | 511 | if (!lua_istable(L, -1)) |
| 514 | 512 | luaL_error(L, LUA_QL("package.preload") " must be a table"); |
| 515 | 513 | lua_getfield(L, -1, name); |
| @@ -535,7 +533,7 @@ static int ll_require (lua_State *L) { · 19 unmodified lines | ||
| 535 | 533 | return 1; /* package is already loaded */ |
| 536 | 534 | } |
| 537 | 535 | /* else must load it; iterate over available loaders */ |
| 538 | − lua_getfield(L, LUA_ENVIRONINDEX, "loaders"); | |
| 536 | + lua_getfield(L, lua_upvalueindex(1), "loaders"); | |
| 539 | 537 | if (!lua_istable(L, -1)) |
| 540 | 538 | luaL_error(L, LUA_QL("package.loaders") " must be a table"); |
| 541 | 539 | lua_pushliteral(L, ""); /* error message accumulator */ |
| @@ -579,14 +577,18 @@ static int ll_require (lua_State *L) { · 37 unmodified lines | ||
| 579 | 577 | */ |
| 580 | 578 | |
| 581 | 579 | |
| 582 | −static void setfenv (lua_State *L) { | |
| 580 | +/* | |
| 581 | +** FOR COMPATIBILITY ONLY: changes the _ENV variable of | |
| 582 | +** calling function | |
| 583 | +*/ | |
| 584 | +static void set_env (lua_State *L) { | |
| 583 | 585 | lua_Debug ar; |
| 584 | 586 | if (lua_getstack(L, 1, &ar) == 0 || |
| 585 | 587 | lua_getinfo(L, "f", &ar) == 0 || /* get calling function */ |
| 586 | 588 | lua_iscfunction(L, -1)) |
| 587 | 589 | luaL_error(L, LUA_QL("module") " not called from a Lua function"); |
| 588 | 590 | lua_pushvalue(L, -2); /* copy new environment table to top */ |
| 589 | − lua_setfenv(L, -2); | |
| 591 | + lua_setupvalue(L, -2, 1); | |
| 590 | 592 | lua_pop(L, 1); /* remove function */ |
| 591 | 593 | } |
| 592 | 594 | |
| @@ -639,7 +641,7 @@ static int ll_module (lua_State *L) { · 46 unmodified lines | ||
| 639 | 641 | modinit(L, modname); |
| 640 | 642 | } |
| 641 | 643 | lua_pushvalue(L, -1); |
| 642 | − setfenv(L); | |
| 644 | + set_env(L); | |
| 643 | 645 | dooptions(L, loaded - 1); |
| 644 | 646 | return 1; |
| 645 | 647 | } |
| @@ -709,12 +711,12 @@ LUAMOD_API int luaopen_package (lua_State *L) { · 63 unmodified lines | ||
| 709 | 711 | lua_setfield(L, -2, "__gc"); |
| 710 | 712 | /* create `package' table */ |
| 711 | 713 | luaL_register(L, LUA_LOADLIBNAME, pk_funcs); |
| 712 | − lua_copy(L, -1, LUA_ENVIRONINDEX); | |
| 713 | 714 | /* create `loaders' table */ |
| 714 | 715 | lua_createtable(L, sizeof(loaders)/sizeof(loaders[0]) - 1, 0); |
| 715 | 716 | /* fill it with pre-defined loaders */ |
| 716 | 717 | for (i=0; loaders[i] != NULL; i++) { |
| 717 | − lua_pushcfunction(L, loaders[i]); | |
| 718 | + lua_pushvalue(L, -2); /* set 'package' as upvalue for all loaders */ | |
| 719 | + lua_pushcclosure(L, loaders[i], 1); | |
| 718 | 720 | lua_rawseti(L, -2, i+1); |
| 719 | 721 | } |
| 720 | 722 | lua_setfield(L, -2, "loaders"); /* put it in field `loaders' */ |
| @@ -731,8 +733,9 @@ LUAMOD_API int luaopen_package (lua_State *L) { · 10 unmodified lines | ||
| 731 | 733 | lua_newtable(L); |
| 732 | 734 | lua_setfield(L, -2, "preload"); |
| 733 | 735 | lua_pushglobaltable(L); |
| 734 | − luaL_register(L, NULL, ll_funcs); /* open lib into global table */ | |
| 735 | − lua_pop(L, 1); | |
| 736 | + lua_pushvalue(L, -2); /* set 'package' as upvalue for next lib */ | |
| 737 | + luaL_openlib(L, NULL, ll_funcs, 1); /* open lib into global table */ | |
| 738 | + lua_pop(L, 1); /* pop global table */ | |
| 736 | 739 | return 1; /* return 'package' table */ |
| 737 | 740 | } |
| 738 | 741 | |
| @@ -1,5 +1,5 @@ | ||
| 1 | 1 | /* |
| 2 | −** $Id: lobject.c,v 2.34 2009/11/26 11:39:20 roberto Exp $ | |
| 2 | +** $Id: lobject.c,v 2.40 2010/04/18 13:22:48 roberto Exp $ | |
| 3 | 3 | ** Some generic functions over Lua objects |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| @@ -81,6 +81,10 @@ int luaO_rawequalObj (const TValue *t1, const TValue *t2) { · 75 unmodified lines | ||
| 81 | 81 | return bvalue(t1) == bvalue(t2); /* boolean true must be 1 !! */ |
| 82 | 82 | case LUA_TLIGHTUSERDATA: |
| 83 | 83 | return pvalue(t1) == pvalue(t2); |
| 84 | + case LUA_TSTRING: | |
| 85 | + return rawtsvalue(t1) == rawtsvalue(t2); | |
| 86 | + case LUA_TLCF: | |
| 87 | + return fvalue(t1) == fvalue(t2); | |
| 84 | 88 | default: |
| 85 | 89 | lua_assert(iscollectable(t1)); |
| 86 | 90 | return gcvalue(t1) == gcvalue(t2); |
| @@ -96,7 +100,7 @@ lua_Number luaO_arith (int op, lua_Number v1, lua_Number v2) { · 9 unmodified lines | ||
| 96 | 100 | case LUA_OPDIV: return luai_numdiv(NULL, v1, v2); |
| 97 | 101 | case LUA_OPMOD: return luai_nummod(NULL, v1, v2); |
| 98 | 102 | case LUA_OPPOW: return luai_numpow(NULL, v1, v2); |
| 99 | − case LUA_OPUNM: return luai_numunm(N, v1); | |
| 103 | + case LUA_OPUNM: return luai_numunm(NULL, v1); | |
| 100 | 104 | default: lua_assert(0); return 0; |
| 101 | 105 | } |
| 102 | 106 | } |
| @@ -108,24 +112,21 @@ int luaO_str2d (const char *s, lua_Number *result) { · 5 unmodified lines | ||
| 108 | 112 | if (endptr == s) return 0; /* conversion failed */ |
| 109 | 113 | if (*endptr == 'x' || *endptr == 'X') /* maybe an hexadecimal constant? */ |
| 110 | 114 | *result = cast_num(strtoul(s, &endptr, 16)); |
| 111 | − if (*endptr == '\0') return 1; /* most common case */ | |
| 112 | 115 | while (lisspace(cast(unsigned char, *endptr))) endptr++; |
| 113 | − if (*endptr != '\0') return 0; /* invalid trailing characters? */ | |
| 114 | − return 1; | |
| 116 | + return (*endptr == '\0'); /* OK if no trailing characters */ | |
| 115 | 117 | } |
| 116 | 118 | |
| 117 | 119 | |
| 118 | 120 | |
| 119 | −static void pushstr (lua_State *L, const char *str) { | |
| 120 | − setsvalue2s(L, L->top, luaS_new(L, str)); | |
| 121 | +static void pushstr (lua_State *L, const char *str, size_t l) { | |
| 122 | + setsvalue2s(L, L->top, luaS_newlstr(L, str, l)); | |
| 121 | 123 | incr_top(L); |
| 122 | 124 | } |
| 123 | 125 | |
| 124 | 126 | |
| 125 | 127 | /* this function handles only `%d', `%c', %f, %p, and `%s' formats */ |
| 126 | 128 | const char *luaO_pushvfstring (lua_State *L, const char *fmt, va_list argp) { |
| 127 | − int n = 1; | |
| 128 | − pushstr(L, ""); | |
| 129 | + int n = 0; | |
| 129 | 130 | for (;;) { |
| 130 | 131 | const char *e = strchr(fmt, '%'); |
| 131 | 132 | if (e == NULL) break; |
| @@ -135,14 +136,13 @@ const char *luaO_pushvfstring (lua_State *L, const char *fmt, va_list argp) { · 3 unmodified lines | ||
| 135 | 136 | case 's': { |
| 136 | 137 | const char *s = va_arg(argp, char *); |
| 137 | 138 | if (s == NULL) s = "(null)"; |
| 138 | − pushstr(L, s); | |
| 139 | + pushstr(L, s, strlen(s)); | |
| 139 | 140 | break; |
| 140 | 141 | } |
| 141 | 142 | case 'c': { |
| 142 | − char buff[2]; | |
| 143 | − buff[0] = cast(char, va_arg(argp, int)); | |
| 144 | − buff[1] = '\0'; | |
| 145 | − pushstr(L, buff); | |
| 143 | + char buff; | |
| 144 | + buff = cast(char, va_arg(argp, int)); | |
| 145 | + pushstr(L, &buff, 1); | |
| 146 | 146 | break; |
| 147 | 147 | } |
| 148 | 148 | case 'd': { |
| @@ -157,12 +157,12 @@ const char *luaO_pushvfstring (lua_State *L, const char *fmt, va_list argp) { · 8 unmodified lines | ||
| 157 | 157 | } |
| 158 | 158 | case 'p': { |
| 159 | 159 | char buff[4*sizeof(void *) + 8]; /* should be enough space for a `%p' */ |
| 160 | − sprintf(buff, "%p", va_arg(argp, void *)); | |
| 161 | − pushstr(L, buff); | |
| 160 | + int l = sprintf(buff, "%p", va_arg(argp, void *)); | |
| 161 | + pushstr(L, buff, l); | |
| 162 | 162 | break; |
| 163 | 163 | } |
| 164 | 164 | case '%': { |
| 165 | − pushstr(L, "%"); | |
| 165 | + pushstr(L, "%", 1); | |
| 166 | 166 | break; |
| 167 | 167 | } |
| 168 | 168 | default: { |
| @@ -175,8 +175,8 @@ const char *luaO_pushvfstring (lua_State *L, const char *fmt, va_list argp) { · 6 unmodified lines | ||
| 175 | 175 | n += 2; |
| 176 | 176 | fmt = e+2; |
| 177 | 177 | } |
| 178 | − pushstr(L, fmt); | |
| 179 | − luaV_concat(L, n+1); | |
| 178 | + pushstr(L, fmt, strlen(fmt)); | |
| 179 | + if (n > 0) luaV_concat(L, n + 1); | |
| 180 | 180 | return svalue(L->top - 1); |
| 181 | 181 | } |
| 182 | 182 | |
| @@ -1,5 +1,5 @@ | ||
| 1 | 1 | /* |
| 2 | −** $Id: lobject.h,v 2.34 2010/01/08 20:00:20 roberto Exp $ | |
| 2 | +** $Id: lobject.h,v 2.40 2010/05/07 18:44:46 roberto Exp $ | |
| 3 | 3 | ** Type definitions for Lua objects |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| @@ -16,20 +16,20 @@ · 10 unmodified lines | ||
| 16 | 16 | #include "lua.h" |
| 17 | 17 | |
| 18 | 18 | |
| 19 | −/* tags for values visible from Lua */ | |
| 20 | −#define LAST_TAG LUA_TTHREAD | |
| 21 | − | |
| 22 | −#define NUM_TAGS (LAST_TAG+1) | |
| 23 | − | |
| 24 | − | |
| 25 | 19 | /* |
| 26 | 20 | ** Extra tags for non-values |
| 27 | 21 | */ |
| 28 | −#define LUA_TPROTO (LAST_TAG+1) | |
| 29 | −#define LUA_TUPVAL (LAST_TAG+2) | |
| 30 | −#define LUA_TDEADKEY (LAST_TAG+3) | |
| 22 | +#define LUA_TPROTO LUA_NUMTAGS | |
| 23 | +#define LUA_TUPVAL (LUA_NUMTAGS+1) | |
| 24 | +#define LUA_TDEADKEY (LUA_NUMTAGS+2) | |
| 31 | 25 | |
| 32 | 26 | |
| 27 | +/* | |
| 28 | +** Variant tag for light C functions (negative to be considered | |
| 29 | +** non collectable by 'iscollectable') | |
| 30 | +*/ | |
| 31 | +#define LUA_TLCF (~0x0F | LUA_TFUNCTION) | |
| 32 | + | |
| 33 | 33 | /* |
| 34 | 34 | ** Union of all collectable objects |
| 35 | 35 | */ |
| @@ -60,6 +60,7 @@ typedef union { · 24 unmodified lines | ||
| 60 | 60 | void *p; |
| 61 | 61 | lua_Number n; |
| 62 | 62 | int b; |
| 63 | + lua_CFunction f; | |
| 63 | 64 | } Value; |
| 64 | 65 | |
| 65 | 66 | |
| @@ -79,12 +80,26 @@ typedef struct lua_TValue { · 13 unmodified lines | ||
| 79 | 80 | #define NILCONSTANT {NULL}, LUA_TNIL |
| 80 | 81 | |
| 81 | 82 | |
| 83 | +/* | |
| 84 | +** type tag of a TValue | |
| 85 | +*/ | |
| 86 | +#define ttype(o) ((o)->tt_) | |
| 87 | + | |
| 88 | + | |
| 89 | +/* | |
| 90 | +** type tag of a TValue with no variants | |
| 91 | +*/ | |
| 92 | +#define ttypenv(o) (ttype(o) & 0x0F) | |
| 93 | + | |
| 94 | + | |
| 82 | 95 | /* Macros to test type */ |
| 83 | 96 | #define ttisnil(o) (ttype(o) == LUA_TNIL) |
| 84 | 97 | #define ttisnumber(o) (ttype(o) == LUA_TNUMBER) |
| 85 | 98 | #define ttisstring(o) (ttype(o) == LUA_TSTRING) |
| 86 | 99 | #define ttistable(o) (ttype(o) == LUA_TTABLE) |
| 87 | −#define ttisfunction(o) (ttype(o) == LUA_TFUNCTION) | |
| 100 | +#define ttisfunction(o) (ttypenv(o) == LUA_TFUNCTION) | |
| 101 | +#define ttisclosure(o) (ttype(o) == LUA_TFUNCTION) | |
| 102 | +#define ttislcf(o) (ttype(o) == LUA_TLCF) | |
| 88 | 103 | #define ttisboolean(o) (ttype(o) == LUA_TBOOLEAN) |
| 89 | 104 | #define ttisuserdata(o) (ttype(o) == LUA_TUSERDATA) |
| 90 | 105 | #define ttisthread(o) (ttype(o) == LUA_TTHREAD) |
| @@ -92,7 +107,6 @@ typedef struct lua_TValue { · 1 unmodified line | ||
| 92 | 107 | #define ttisdeadkey(o) (ttype(o) == LUA_TDEADKEY) |
| 93 | 108 | |
| 94 | 109 | /* Macros to access values */ |
| 95 | −#define ttype(o) ((o)->tt_) | |
| 96 | 110 | #define gcvalue(o) check_exp(iscollectable(o), (o)->value_.gc) |
| 97 | 111 | #define pvalue(o) check_exp(ttislightuserdata(o), (o)->value_.p) |
| 98 | 112 | #define nvalue(o) check_exp(ttisnumber(o), (o)->value_.n) |
| @@ -100,16 +114,15 @@ typedef struct lua_TValue { · 1 unmodified line | ||
| 100 | 114 | #define tsvalue(o) (&rawtsvalue(o)->tsv) |
| 101 | 115 | #define rawuvalue(o) check_exp(ttisuserdata(o), &(o)->value_.gc->u) |
| 102 | 116 | #define uvalue(o) (&rawuvalue(o)->uv) |
| 103 | −#define clvalue(o) check_exp(ttisfunction(o), &(o)->value_.gc->cl) | |
| 117 | +#define clvalue(o) check_exp(ttisclosure(o), &(o)->value_.gc->cl) | |
| 118 | +#define fvalue(o) check_exp(ttislcf(o), (o)->value_.f) | |
| 104 | 119 | #define hvalue(o) check_exp(ttistable(o), &(o)->value_.gc->h) |
| 105 | 120 | #define bvalue(o) check_exp(ttisboolean(o), (o)->value_.b) |
| 106 | 121 | #define thvalue(o) check_exp(ttisthread(o), &(o)->value_.gc->th) |
| 107 | 122 | |
| 108 | 123 | #define l_isfalse(o) (ttisnil(o) || (ttisboolean(o) && bvalue(o) == 0)) |
| 109 | 124 | |
| 110 | −/* | |
| 111 | −** for internal debug only | |
| 112 | −*/ | |
| 125 | + | |
| 113 | 126 | #define iscollectable(o) (ttype(o) >= LUA_TSTRING) |
| 114 | 127 | |
| 115 | 128 | #define righttt(obj) (ttype(obj) == gcvalue(obj)->gch.tt) |
| @@ -126,8 +139,10 @@ typedef struct lua_TValue { · 10 unmodified lines | ||
| 126 | 139 | #define setnvalue(obj,x) \ |
| 127 | 140 | { TValue *i_o=(obj); i_o->value_.n=(x); i_o->tt_=LUA_TNUMBER; } |
| 128 | 141 | |
| 129 | −#define changenvalue(obj,x) \ | |
| 130 | − ( lua_assert((obj)->tt_==LUA_TNUMBER), (obj)->value_.n=(x) ) | |
| 142 | +#define setfvalue(obj,x) \ | |
| 143 | + { TValue *i_o=(obj); i_o->value_.f=(x); i_o->tt_=LUA_TLCF; } | |
| 144 | + | |
| 145 | +#define changenvalue(o,x) check_exp((o)->tt_==LUA_TNUMBER, (o)->value_.n=(x)) | |
| 131 | 146 | |
| 132 | 147 | #define setpvalue(obj,x) \ |
| 133 | 148 | { TValue *i_o=(obj); i_o->value_.p=(x); i_o->tt_=LUA_TLIGHTUSERDATA; } |
| @@ -264,7 +279,6 @@ typedef struct Proto { · 130 unmodified lines | ||
| 264 | 279 | lu_byte numparams; |
| 265 | 280 | lu_byte is_vararg; |
| 266 | 281 | lu_byte maxstacksize; |
| 267 | − lu_byte envreg; /* register in outer function with initial environment */ | |
| 268 | 282 | } Proto; |
| 269 | 283 | |
| 270 | 284 | |
| @@ -298,8 +312,7 @@ typedef struct UpVal { · 27 unmodified lines | ||
| 298 | 312 | */ |
| 299 | 313 | |
| 300 | 314 | #define ClosureHeader \ |
| 301 | − CommonHeader; lu_byte isC; lu_byte nupvalues; GCObject *gclist; \ | |
| 302 | − struct Table *env | |
| 315 | + CommonHeader; lu_byte isC; lu_byte nupvalues; GCObject *gclist | |
| 303 | 316 | |
| 304 | 317 | typedef struct CClosure { |
| 305 | 318 | ClosureHeader; |
| @@ -321,8 +334,7 @@ typedef union Closure { · 15 unmodified lines | ||
| 321 | 334 | } Closure; |
| 322 | 335 | |
| 323 | 336 | |
| 324 | −#define iscfunction(o) (ttisfunction(o) && clvalue(o)->c.isC) | |
| 325 | −#define isLfunction(o) (ttisfunction(o) && !clvalue(o)->c.isC) | |
| 337 | +#define isLfunction(o) (ttisclosure(o) && !clvalue(o)->c.isC) | |
| 326 | 338 | |
| 327 | 339 | #define getproto(o) (clvalue(o)->l.p) |
| 328 | 340 | |
| @@ -1,5 +1,5 @@ | ||
| 1 | 1 | /* |
| 2 | −** $Id: lopcodes.c,v 1.41 2009/11/19 19:06:52 roberto Exp $ | |
| 2 | +** $Id: lopcodes.c,v 1.43 2010/03/12 19:14:06 roberto Exp $ | |
| 3 | 3 | ** See Copyright Notice in lua.h |
| 4 | 4 | */ |
| 5 | 5 | |
| @@ -19,9 +19,9 @@ LUAI_DDEF const char *const luaP_opnames[NUM_OPCODES+1] = { · 13 unmodified lines | ||
| 19 | 19 | "LOADBOOL", |
| 20 | 20 | "LOADNIL", |
| 21 | 21 | "GETUPVAL", |
| 22 | − "GETGLOBAL", | |
| 22 | + "GETTABUP", | |
| 23 | 23 | "GETTABLE", |
| 24 | − "SETGLOBAL", | |
| 24 | + "SETTABUP", | |
| 25 | 25 | "SETUPVAL", |
| 26 | 26 | "SETTABLE", |
| 27 | 27 | "NEWTABLE", |
| @@ -67,9 +67,9 @@ LUAI_DDEF const lu_byte luaP_opmodes[NUM_OPCODES] = { · 39 unmodified lines | ||
| 67 | 67 | ,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_LOADBOOL */ |
| 68 | 68 | ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_LOADNIL */ |
| 69 | 69 | ,opmode(0, 1, OpArgU, OpArgN, iABC) /* OP_GETUPVAL */ |
| 70 | − ,opmode(0, 1, OpArgK, OpArgN, iABx) /* OP_GETGLOBAL */ | |
| 70 | + ,opmode(0, 1, OpArgU, OpArgK, iABC) /* OP_GETTABUP */ | |
| 71 | 71 | ,opmode(0, 1, OpArgR, OpArgK, iABC) /* OP_GETTABLE */ |
| 72 | − ,opmode(0, 0, OpArgK, OpArgN, iABx) /* OP_SETGLOBAL */ | |
| 72 | + ,opmode(0, 0, OpArgK, OpArgK, iABC) /* OP_SETTABUP */ | |
| 73 | 73 | ,opmode(0, 0, OpArgU, OpArgN, iABC) /* OP_SETUPVAL */ |
| 74 | 74 | ,opmode(0, 0, OpArgK, OpArgK, iABC) /* OP_SETTABLE */ |
| 75 | 75 | ,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_NEWTABLE */ |
| @@ -1,5 +1,5 @@ | ||
| 1 | 1 | /* |
| 2 | −** $Id: lopcodes.h,v 1.133 2009/11/19 19:06:52 roberto Exp $ | |
| 2 | +** $Id: lopcodes.h,v 1.135 2010/03/12 19:14:06 roberto Exp $ | |
| 3 | 3 | ** Opcodes for Lua virtual machine |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| @@ -171,10 +171,10 @@ OP_LOADBOOL,/* A B C R(A) := (Bool)B; if (C) pc++ */ · 165 unmodified lines | ||
| 171 | 171 | OP_LOADNIL,/* A B R(A) := ... := R(B) := nil */ |
| 172 | 172 | OP_GETUPVAL,/* A B R(A) := UpValue[B] */ |
| 173 | 173 | |
| 174 | −OP_GETGLOBAL,/* A Bx R(A) := Gbl[Kst(Bx - 1)] */ | |
| 174 | +OP_GETTABUP,/* A B C R(A) := UpValue[B][RK(C)] */ | |
| 175 | 175 | OP_GETTABLE,/* A B C R(A) := R(B)[RK(C)] */ |
| 176 | 176 | |
| 177 | −OP_SETGLOBAL,/* A Bx Gbl[Kst(Bx - 1)] := R(A) */ | |
| 177 | +OP_SETTABUP,/* A B C UpValue[A][RK(B)] := RK(C) */ | |
| 178 | 178 | OP_SETUPVAL,/* A B UpValue[B] := R(A) */ |
| 179 | 179 | OP_SETTABLE,/* A B C R(A)[RK(B)] := RK(C) */ |
| 180 | 180 | |
| @@ -243,8 +243,7 @@ OP_EXTRAARG/* Ax extra (larger) argument for previous opcode */ · 62 unmodified lines | ||
| 243 | 243 | (*) In OP_SETLIST, if (B == 0) then B = `top'; if (C == 0) then next |
| 244 | 244 | 'instruction' is EXTRAARG(real C). |
| 245 | 245 | |
| 246 | − (*) In OP_LOADK, OP_GETGLOBAL, and OP_SETGLOBAL, if (Bx == 0) then next | |
| 247 | − 'instruction' is EXTRAARG(real Bx). | |
| 246 | + (*) In OP_LOADK, if (Bx == 0) then next 'instruction' is EXTRAARG(real Bx). | |
| 248 | 247 | |
| 249 | 248 | (*) For comparisons, A specifies what condition the test should accept |
| 250 | 249 | (true or false). |
| @@ -1,5 +1,5 @@ | ||
| 1 | 1 | /* |
| 2 | −** $Id: lparser.c,v 2.75 2010/01/06 11:48:02 roberto Exp $ | |
| 2 | +** $Id: lparser.c,v 2.86 2010/05/15 13:32:02 roberto Exp $ | |
| 3 | 3 | ** Lua Parser |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| @@ -74,9 +74,10 @@ static void error_expected (LexState *ls, int token) { · 68 unmodified lines | ||
| 74 | 74 | |
| 75 | 75 | static void errorlimit (FuncState *fs, int limit, const char *what) { |
| 76 | 76 | const char *msg; |
| 77 | − const char *where = (fs->f->linedefined == 0) ? | |
| 78 | − "main function" : | |
| 79 | − luaO_pushfstring(fs->L, "function at line %d", fs->f->linedefined); | |
| 77 | + int line = fs->f->linedefined; | |
| 78 | + const char *where = (line == 0) | |
| 79 | + ? "main function" | |
| 80 | + : luaO_pushfstring(fs->L, "function at line %d", line); | |
| 80 | 81 | msg = luaO_pushfstring(fs->L, "too many %s (limit is %d) in %s", |
| 81 | 82 | what, limit, where); |
| 82 | 83 | luaX_syntaxerror(fs->ls, msg); |
| @@ -207,27 +208,27 @@ static void removevars (FuncState *fs, int tolevel) { · 124 unmodified lines | ||
| 207 | 208 | } |
| 208 | 209 | |
| 209 | 210 | |
| 210 | −static int indexupvalue (FuncState *fs, TString *name, expdesc *v) { | |
| 211 | +static int searchupvalue (FuncState *fs, TString *name) { | |
| 211 | 212 | int i; |
| 213 | + Upvaldesc *up = fs->f->upvalues; | |
| 214 | + for (i = 0; i < fs->nups; i++) { | |
| 215 | + if (eqstr(up[i].name, name)) return i; | |
| 216 | + } | |
| 217 | + return -1; /* not found */ | |
| 218 | +} | |
| 219 | + | |
| 220 | + | |
| 221 | +static int newupvalue (FuncState *fs, TString *name, expdesc *v) { | |
| 212 | 222 | Proto *f = fs->f; |
| 213 | 223 | int oldsize = f->sizeupvalues; |
| 214 | − int instk = (v->k == VLOCAL); | |
| 215 | − lua_assert(instk || v->k == VUPVAL); | |
| 216 | − for (i=0; i<fs->nups; i++) { | |
| 217 | − if (f->upvalues[i].instack == instk && f->upvalues[i].idx == v->u.s.info) { | |
| 218 | − lua_assert(f->upvalues[i].name == name); | |
| 219 | − return i; | |
| 220 | − } | |
| 221 | − } | |
| 222 | − /* new one */ | |
| 223 | 224 | checklimit(fs, fs->nups + 1, UCHAR_MAX, "upvalues"); |
| 224 | 225 | luaM_growvector(fs->L, f->upvalues, fs->nups, f->sizeupvalues, |
| 225 | 226 | Upvaldesc, UCHAR_MAX, "upvalues"); |
| 226 | 227 | while (oldsize < f->sizeupvalues) f->upvalues[oldsize++].name = NULL; |
| 228 | + f->upvalues[fs->nups].instack = (v->k == VLOCAL); | |
| 229 | + f->upvalues[fs->nups].idx = cast_byte(v->u.s.info); | |
| 227 | 230 | f->upvalues[fs->nups].name = name; |
| 228 | 231 | luaC_objbarrier(fs->L, f, name); |
| 229 | − f->upvalues[fs->nups].instack = cast_byte(instk); | |
| 230 | − f->upvalues[fs->nups].idx = cast_byte(v->u.s.info); | |
| 231 | 232 | return fs->nups++; |
| 232 | 233 | } |
| 233 | 234 | |
| @@ -235,13 +236,17 @@ static int indexupvalue (FuncState *fs, TString *name, expdesc *v) { · 1 unmodified line | ||
| 235 | 236 | static int searchvar (FuncState *fs, TString *n) { |
| 236 | 237 | int i; |
| 237 | 238 | for (i=fs->nactvar-1; i >= 0; i--) { |
| 238 | − if (n == getlocvar(fs, i)->varname) | |
| 239 | + if (eqstr(n, getlocvar(fs, i)->varname)) | |
| 239 | 240 | return i; |
| 240 | 241 | } |
| 241 | 242 | return -1; /* not found */ |
| 242 | 243 | } |
| 243 | 244 | |
| 244 | 245 | |
| 246 | +/* | |
| 247 | + Mark block where variable at given level was defined | |
| 248 | + (to emit OP_CLOSE later). | |
| 249 | +*/ | |
| 245 | 250 | static void markupval (FuncState *fs, int level) { |
| 246 | 251 | BlockCnt *bl = fs->bl; |
| 247 | 252 | while (bl && bl->nactvar > level) bl = bl->previous; |
| @@ -249,22 +254,30 @@ static void markupval (FuncState *fs, int level) { · 1 unmodified line | ||
| 249 | 254 | } |
| 250 | 255 | |
| 251 | 256 | |
| 257 | +/* | |
| 258 | + Find variable with given name 'n'. If it is an upvalue, add this | |
| 259 | + upvalue into all intermediate functions. | |
| 260 | +*/ | |
| 252 | 261 | static int singlevaraux (FuncState *fs, TString *n, expdesc *var, int base) { |
| 253 | 262 | if (fs == NULL) /* no more levels? */ |
| 254 | − return VGLOBAL; /* default is global variable */ | |
| 263 | + return VVOID; /* default is global */ | |
| 255 | 264 | else { |
| 256 | − int v = searchvar(fs, n); /* look up at current level */ | |
| 257 | − if (v >= 0) { | |
| 258 | − init_exp(var, VLOCAL, v); | |
| 265 | + int v = searchvar(fs, n); /* look up locals at current level */ | |
| 266 | + if (v >= 0) { /* found? */ | |
| 267 | + init_exp(var, VLOCAL, v); /* variable is local */ | |
| 259 | 268 | if (!base) |
| 260 | 269 | markupval(fs, v); /* local will be used as an upval */ |
| 261 | 270 | return VLOCAL; |
| 262 | 271 | } |
| 263 | − else { /* not found at current level; try upper one */ | |
| 264 | − if (singlevaraux(fs->prev, n, var, 0) == VGLOBAL) | |
| 265 | − return VGLOBAL; | |
| 266 | − var->u.s.info = indexupvalue(fs, n, var); /* else was LOCAL or UPVAL */ | |
| 267 | − var->k = VUPVAL; /* upvalue in this level */ | |
| 272 | + else { /* not found as local at current level; try upvalues */ | |
| 273 | + int idx = searchupvalue(fs, n); /* try existing upvalues */ | |
| 274 | + if (idx < 0) { /* not found? */ | |
| 275 | + if (singlevaraux(fs->prev, n, var, 0) == VVOID) /* try upper levels */ | |
| 276 | + return VVOID; /* not found; is a global */ | |
| 277 | + /* else was LOCAL or UPVAL */ | |
| 278 | + idx = newupvalue(fs, n, var); /* will be a new upvalue */ | |
| 279 | + } | |
| 280 | + init_exp(var, VUPVAL, idx); | |
| 268 | 281 | return VUPVAL; |
| 269 | 282 | } |
| 270 | 283 | } |
| @@ -274,15 +287,12 @@ static int singlevaraux (FuncState *fs, TString *n, expdesc *var, int base) { · 3 unmodified lines | ||
| 274 | 287 | static void singlevar (LexState *ls, expdesc *var) { |
| 275 | 288 | TString *varname = str_checkname(ls); |
| 276 | 289 | FuncState *fs = ls->fs; |
| 277 | − if (singlevaraux(fs, varname, var, 1) == VGLOBAL) { | |
| 278 | − if (fs->envreg == NO_REG) /* regular global? */ | |
| 279 | − init_exp(var, VGLOBAL, luaK_stringK(fs, varname)); | |
| 280 | − else { /* "globals" are in current lexical environment */ | |
| 281 | − expdesc key; | |
| 282 | − init_exp(var, VLOCAL, fs->envreg); /* current environment */ | |
| 283 | − codestring(ls, &key, varname); /* key is variable name */ | |
| 284 | − luaK_indexed(fs, var, &key); /* env[varname] */ | |
| 285 | − } | |
| 290 | + if (singlevaraux(fs, varname, var, 1) == VVOID) { /* global name? */ | |
| 291 | + expdesc key; | |
| 292 | + singlevaraux(fs, ls->envn, var, 1); /* get _ENV variable */ | |
| 293 | + lua_assert(var->k == VLOCAL || var->k == VUPVAL); | |
| 294 | + codestring(ls, &key, varname); /* key is variable name */ | |
| 295 | + luaK_indexed(fs, var, &key); /* env[varname] */ | |
| 286 | 296 | } |
| 287 | 297 | } |
| 288 | 298 | |
| @@ -351,7 +361,6 @@ static void pushclosure (LexState *ls, Proto *clp, expdesc *v) { · 62 unmodified lines | ||
| 351 | 361 | while (oldsize < f->sizep) f->p[oldsize++] = NULL; |
| 352 | 362 | f->p[fs->np++] = clp; |
| 353 | 363 | /* initial environment for new function is current lexical environment */ |
| 354 | − clp->envreg = fs->envreg; | |
| 355 | 364 | luaC_objbarrier(ls->L, f, clp); |
| 356 | 365 | init_exp(v, VRELOCABLE, luaK_codeABx(fs, OP_CLOSURE, 0, fs->np-1)); |
| 357 | 366 | } |
| @@ -374,7 +383,6 @@ static void open_func (LexState *ls, FuncState *fs) { · 16 unmodified lines | ||
| 374 | 383 | fs->nlocvars = 0; |
| 375 | 384 | fs->nactvar = 0; |
| 376 | 385 | fs->firstlocal = ls->varl->nactvar; |
| 377 | − fs->envreg = NO_REG; | |
| 378 | 386 | fs->bl = NULL; |
| 379 | 387 | f = luaF_newproto(L); |
| 380 | 388 | fs->f = f; |
| @@ -418,26 +426,36 @@ static void close_func (LexState *ls) { · 37 unmodified lines | ||
| 418 | 426 | } |
| 419 | 427 | |
| 420 | 428 | |
| 429 | +/* | |
| 430 | +** opens the main function, which is a regular vararg function with an | |
| 431 | +** upvalue named '_ENV' | |
| 432 | +*/ | |
| 433 | +static void open_mainfunc (LexState *ls, FuncState *fs) { | |
| 434 | + expdesc v; | |
| 435 | + open_func(ls, fs); | |
| 436 | + fs->f->is_vararg = 1; /* main function is always vararg */ | |
| 437 | + init_exp(&v, VLOCAL, 0); | |
| 438 | + newupvalue(fs, ls->envn, &v); /* create '_ENV' upvalue */ | |
| 439 | +} | |
| 440 | + | |
| 441 | + | |
| 421 | 442 | Proto *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff, Varlist *varl, |
| 422 | 443 | const char *name) { |
| 423 | − struct LexState lexstate; | |
| 424 | − struct FuncState funcstate; | |
| 444 | + LexState lexstate; | |
| 445 | + FuncState funcstate; | |
| 425 | 446 | TString *tname = luaS_new(L, name); |
| 426 | 447 | setsvalue2s(L, L->top, tname); /* push name to protect it */ |
| 427 | 448 | incr_top(L); |
| 428 | 449 | lexstate.buff = buff; |
| 429 | 450 | lexstate.varl = varl; |
| 430 | 451 | luaX_setinput(L, &lexstate, z, tname); |
| 431 | − open_func(&lexstate, &funcstate); | |
| 432 | − funcstate.f->is_vararg = 1; /* main function is always vararg */ | |
| 452 | + open_mainfunc(&lexstate, &funcstate); | |
| 433 | 453 | luaX_next(&lexstate); /* read first token */ |
| 434 | − chunk(&lexstate); | |
| 454 | + chunk(&lexstate); /* read main chunk */ | |
| 435 | 455 | check(&lexstate, TK_EOS); |
| 436 | 456 | close_func(&lexstate); |
| 437 | 457 | L->top--; /* pop name */ |
| 438 | − lua_assert(funcstate.prev == NULL); | |
| 439 | − lua_assert(funcstate.nups == 0); | |
| 440 | − lua_assert(lexstate.fs == NULL); | |
| 458 | + lua_assert(!funcstate.prev && funcstate.nups == 1 && !lexstate.fs); | |
| 441 | 459 | return funcstate.f; |
| 442 | 460 | } |
| 443 | 461 | |
| @@ -452,7 +470,7 @@ static void fieldsel (LexState *ls, expdesc *v) { · 8 unmodified lines | ||
| 452 | 470 | /* fieldsel -> ['.' | ':'] NAME */ |
| 453 | 471 | FuncState *fs = ls->fs; |
| 454 | 472 | expdesc key; |
| 455 | − luaK_exp2anyreg(fs, v); | |
| 473 | + luaK_exp2anyregup(fs, v); | |
| 456 | 474 | luaX_next(ls); /* skip the dot or colon */ |
| 457 | 475 | checkname(ls, &key); |
| 458 | 476 | luaK_indexed(fs, v, &key); |
| @@ -653,15 +671,12 @@ static int explist1 (LexState *ls, expdesc *v) { · 194 unmodified lines | ||
| 653 | 671 | } |
| 654 | 672 | |
| 655 | 673 | |
| 656 | −static void funcargs (LexState *ls, expdesc *f) { | |
| 674 | +static void funcargs (LexState *ls, expdesc *f, int line) { | |
| 657 | 675 | FuncState *fs = ls->fs; |
| 658 | 676 | expdesc args; |
| 659 | 677 | int base, nparams; |
| 660 | − int line = ls->linenumber; | |
| 661 | 678 | switch (ls->t.token) { |
| 662 | 679 | case '(': { /* funcargs -> `(' [ explist1 ] `)' */ |
| 663 | − if (line != ls->lastline) | |
| 664 | − luaX_syntaxerror(ls,"ambiguous syntax (function call x new statement)"); | |
| 665 | 680 | luaX_next(ls); |
| 666 | 681 | if (ls->t.token == ')') /* arg list is empty? */ |
| 667 | 682 | args.k = VVOID; |
| @@ -738,6 +753,7 @@ static void primaryexp (LexState *ls, expdesc *v) { · 70 unmodified lines | ||
| 738 | 753 | /* primaryexp -> |
| 739 | 754 | prefixexp { `.' NAME | `[' exp `]' | `:' NAME funcargs | funcargs } */ |
| 740 | 755 | FuncState *fs = ls->fs; |
| 756 | + int line = ls->linenumber; | |
| 741 | 757 | prefixexp(ls, v); |
| 742 | 758 | for (;;) { |
| 743 | 759 | switch (ls->t.token) { |
| @@ -747,7 +763,7 @@ static void primaryexp (LexState *ls, expdesc *v) { · 3 unmodified lines | ||
| 747 | 763 | } |
| 748 | 764 | case '[': { /* `[' exp1 `]' */ |
| 749 | 765 | expdesc key; |
| 750 | − luaK_exp2anyreg(fs, v); | |
| 766 | + luaK_exp2anyregup(fs, v); | |
| 751 | 767 | yindex(ls, &key); |
| 752 | 768 | luaK_indexed(fs, v, &key); |
| 753 | 769 | break; |
| @@ -757,12 +773,12 @@ static void primaryexp (LexState *ls, expdesc *v) { · 3 unmodified lines | ||
| 757 | 773 | luaX_next(ls); |
| 758 | 774 | checkname(ls, &key); |
| 759 | 775 | luaK_self(fs, v, &key); |
| 760 | − funcargs(ls, v); | |
| 776 | + funcargs(ls, v, line); | |
| 761 | 777 | break; |
| 762 | 778 | } |
| 763 | 779 | case '(': case TK_STRING: case '{': { /* funcargs */ |
| 764 | 780 | luaK_exp2nextreg(fs, v); |
| 765 | − funcargs(ls, v); | |
| 781 | + funcargs(ls, v, line); | |
| 766 | 782 | break; |
| 767 | 783 | } |
| 768 | 784 | default: return; |
| @@ -877,9 +893,10 @@ static BinOpr subexpr (LexState *ls, expdesc *v, unsigned int limit) { · 108 unmodified lines | ||
| 877 | 893 | enterlevel(ls); |
| 878 | 894 | uop = getunopr(ls->t.token); |
| 879 | 895 | if (uop != OPR_NOUNOPR) { |
| 896 | + int line = ls->linenumber; | |
| 880 | 897 | luaX_next(ls); |
| 881 | 898 | subexpr(ls, v, UNARY_PRIORITY); |
| 882 | − luaK_prefix(ls->fs, uop, v); | |
| 899 | + luaK_prefix(ls->fs, uop, v, line); | |
| 883 | 900 | } |
| 884 | 901 | else simpleexp(ls, v); |
| 885 | 902 | /* expand while operators have priorities higher than `limit' */ |
| @@ -887,11 +904,12 @@ static BinOpr subexpr (LexState *ls, expdesc *v, unsigned int limit) { · 1 unmodified line | ||
| 887 | 904 | while (op != OPR_NOBINOPR && priority[op].left > limit) { |
| 888 | 905 | expdesc v2; |
| 889 | 906 | BinOpr nextop; |
| 907 | + int line = ls->linenumber; | |
| 890 | 908 | luaX_next(ls); |
| 891 | 909 | luaK_infix(ls->fs, op, v); |
| 892 | 910 | /* read sub-expression with higher priority */ |
| 893 | 911 | nextop = subexpr(ls, &v2, priority[op].right); |
| 894 | − luaK_posfix(ls->fs, op, v, &v2); | |
| 912 | + luaK_posfix(ls->fs, op, v, &v2, line); | |
| 895 | 913 | op = nextop; |
| 896 | 914 | } |
| 897 | 915 | leavelevel(ls); |
| @@ -951,24 +969,27 @@ struct LHS_assign { · 53 unmodified lines | ||
| 951 | 969 | ** local value in a safe place and use this safe copy in the previous |
| 952 | 970 | ** assignment. |
| 953 | 971 | */ |
| 954 | −static void check_conflict (LexState *ls, struct LHS_assign *lh, expdesc *v) { | |
| 972 | +static void check_conflict (LexState *ls, struct LHS_assign *lh, expdesc *v, | |
| 973 | + expkind ix, OpCode op) { | |
| 955 | 974 | FuncState *fs = ls->fs; |
| 956 | 975 | int extra = fs->freereg; /* eventual position to save local variable */ |
| 957 | 976 | int conflict = 0; |
| 958 | 977 | for (; lh; lh = lh->prev) { |
| 959 | − if (lh->v.k == VINDEXED) { | |
| 978 | + if (lh->v.k == ix) { | |
| 960 | 979 | if (lh->v.u.s.info == v->u.s.info) { /* conflict? */ |
| 961 | 980 | conflict = 1; |
| 981 | + lh->v.k = VINDEXED; | |
| 962 | 982 | lh->v.u.s.info = extra; /* previous assignment will use safe copy */ |
| 963 | 983 | } |
| 964 | − if (lh->v.u.s.aux == v->u.s.info) { /* conflict? */ | |
| 984 | + if (v->k == VLOCAL && lh->v.u.s.aux == v->u.s.info) { /* conflict? */ | |
| 965 | 985 | conflict = 1; |
| 986 | + lua_assert(lh->v.k == VINDEXED); | |
| 966 | 987 | lh->v.u.s.aux = extra; /* previous assignment will use safe copy */ |
| 967 | 988 | } |
| 968 | 989 | } |
| 969 | 990 | } |
| 970 | 991 | if (conflict) { |
| 971 | − luaK_codeABC(fs, OP_MOVE, fs->freereg, v->u.s.info, 0); /* make copy */ | |
| 992 | + luaK_codeABC(fs, op, fs->freereg, v->u.s.info, 0); /* make copy */ | |
| 972 | 993 | luaK_reserveregs(fs, 1); |
| 973 | 994 | } |
| 974 | 995 | } |
| @@ -976,14 +997,16 @@ static void check_conflict (LexState *ls, struct LHS_assign *lh, expdesc *v) { · 1 unmodified line | ||
| 976 | 997 | |
| 977 | 998 | static void assignment (LexState *ls, struct LHS_assign *lh, int nvars) { |
| 978 | 999 | expdesc e; |
| 979 | − check_condition(ls, VLOCAL <= lh->v.k && lh->v.k <= VINDEXED, | |
| 1000 | + check_condition(ls, VLOCAL <= lh->v.k && lh->v.k <= VINDEXEDUP, | |
| 980 | 1001 | "syntax error"); |
| 981 | 1002 | if (testnext(ls, ',')) { /* assignment -> `,' primaryexp assignment */ |
| 982 | 1003 | struct LHS_assign nv; |
| 983 | 1004 | nv.prev = lh; |
| 984 | 1005 | primaryexp(ls, &nv.v); |
| 985 | 1006 | if (nv.v.k == VLOCAL) |
| 986 | − check_conflict(ls, lh, &nv.v); | |
| 1007 | + check_conflict(ls, lh, &nv.v, VINDEXED, OP_MOVE); | |
| 1008 | + else if (nv.v.k == VUPVAL) | |
| 1009 | + check_conflict(ls, lh, &nv.v, VINDEXEDUP, OP_GETUPVAL); | |
| 987 | 1010 | checklimit(ls->fs, nvars, LUAI_MAXCCALLS - G(ls->L)->nCcalls, |
| 988 | 1011 | "variable names"); |
| 989 | 1012 | assignment(ls, &nv, nvars+1); |
| @@ -1274,24 +1297,6 @@ static void funcstat (LexState *ls, int line) { · 284 unmodified lines | ||
| 1274 | 1297 | } |
| 1275 | 1298 | |
| 1276 | 1299 | |
| 1277 | −static void instat (LexState *ls, int line) { | |
| 1278 | − /* instat -> IN exp DO block END */ | |
| 1279 | − FuncState *fs = ls->fs; | |
| 1280 | − int oldenv = fs->envreg; /* save current environment */ | |
| 1281 | − BlockCnt bl; | |
| 1282 | − luaX_next(ls); /* skip IN */ | |
| 1283 | − enterblock(fs, &bl, 0); /* scope for environment variable */ | |
| 1284 | − new_localvarliteral(ls, "(environment)"); | |
| 1285 | − fs->envreg = exp1(ls); /* new environment */ | |
| 1286 | − adjustlocalvars(ls, 1); | |
| 1287 | − checknext(ls, TK_DO); | |
| 1288 | − block(ls); | |
| 1289 | − leaveblock(fs); | |
| 1290 | − check_match(ls, TK_END, TK_IN, line); | |
| 1291 | − fs->envreg = oldenv; /* restore outer environment */ | |
| 1292 | −} | |
| 1293 | − | |
| 1294 | − | |
| 1295 | 1300 | static void exprstat (LexState *ls) { |
| 1296 | 1301 | /* stat -> func | assignment */ |
| 1297 | 1302 | FuncState *fs = ls->fs; |
| @@ -1311,7 +1316,6 @@ static void retstat (LexState *ls) { · 13 unmodified lines | ||
| 1311 | 1316 | FuncState *fs = ls->fs; |
| 1312 | 1317 | expdesc e; |
| 1313 | 1318 | int first, nret; /* registers with returned values */ |
| 1314 | − luaX_next(ls); /* skip RETURN */ | |
| 1315 | 1319 | if (block_follow(ls->t.token) || ls->t.token == ';') |
| 1316 | 1320 | first = nret = 0; /* return no values */ |
| 1317 | 1321 | else { |
| @@ -1342,6 +1346,10 @@ static void retstat (LexState *ls) { · 24 unmodified lines | ||
| 1342 | 1346 | static int statement (LexState *ls) { |
| 1343 | 1347 | int line = ls->linenumber; /* may be needed for error messages */ |
| 1344 | 1348 | switch (ls->t.token) { |
| 1349 | + case ';': { /* stat -> ';' (empty statement) */ | |
| 1350 | + luaX_next(ls); /* skip ';' */ | |
| 1351 | + return 0; | |
| 1352 | + } | |
| 1345 | 1353 | case TK_IF: { /* stat -> ifstat */ |
| 1346 | 1354 | ifstat(ls, line); |
| 1347 | 1355 | return 0; |
| @@ -1356,10 +1364,6 @@ static int statement (LexState *ls) { · 8 unmodified lines | ||
| 1356 | 1364 | check_match(ls, TK_END, TK_DO, line); |
| 1357 | 1365 | return 0; |
| 1358 | 1366 | } |
| 1359 | − case TK_IN: { | |
| 1360 | − instat(ls, line); | |
| 1361 | − return 0; | |
| 1362 | − } | |
| 1363 | 1367 | case TK_FOR: { /* stat -> forstat */ |
| 1364 | 1368 | forstat(ls, line); |
| 1365 | 1369 | return 0; |
| @@ -1368,8 +1372,8 @@ static int statement (LexState *ls) { · 2 unmodified lines | ||
| 1368 | 1372 | repeatstat(ls, line); |
| 1369 | 1373 | return 0; |
| 1370 | 1374 | } |
| 1371 | − case TK_FUNCTION: { | |
| 1372 | − funcstat(ls, line); /* stat -> funcstat */ | |
| 1375 | + case TK_FUNCTION: { /* stat -> funcstat */ | |
| 1376 | + funcstat(ls, line); | |
| 1373 | 1377 | return 0; |
| 1374 | 1378 | } |
| 1375 | 1379 | case TK_LOCAL: { /* stat -> localstat */ |
| @@ -1381,6 +1385,7 @@ static int statement (LexState *ls) { · 5 unmodified lines | ||
| 1381 | 1385 | return 0; |
| 1382 | 1386 | } |
| 1383 | 1387 | case TK_RETURN: { /* stat -> retstat */ |
| 1388 | + luaX_next(ls); /* skip RETURN */ | |
| 1384 | 1389 | retstat(ls); |
| 1385 | 1390 | return 1; /* must be last statement */ |
| 1386 | 1391 | } |
| @@ -1389,9 +1394,9 @@ static int statement (LexState *ls) { · 2 unmodified lines | ||
| 1389 | 1394 | breakstat(ls); |
| 1390 | 1395 | return 1; /* must be last statement */ |
| 1391 | 1396 | } |
| 1392 | − default: { | |
| 1397 | + default: { /* stat -> func | assignment */ | |
| 1393 | 1398 | exprstat(ls); |
| 1394 | − return 0; /* to avoid warnings */ | |
| 1399 | + return 0; | |
| 1395 | 1400 | } |
| 1396 | 1401 | } |
| 1397 | 1402 | } |
| @@ -1403,7 +1408,8 @@ static void chunk (LexState *ls) { · 5 unmodified lines | ||
| 1403 | 1408 | enterlevel(ls); |
| 1404 | 1409 | while (!islast && !block_follow(ls->t.token)) { |
| 1405 | 1410 | islast = statement(ls); |
| 1406 | − testnext(ls, ';'); | |
| 1411 | + if (islast) | |
| 1412 | + testnext(ls, ';'); | |
| 1407 | 1413 | lua_assert(ls->fs->f->maxstacksize >= ls->fs->freereg && |
| 1408 | 1414 | ls->fs->freereg >= ls->fs->nactvar); |
| 1409 | 1415 | ls->fs->freereg = ls->fs->nactvar; /* free registers */ |
| @@ -1,5 +1,5 @@ | ||
| 1 | 1 | /* |
| 2 | −** $Id: lparser.h,v 1.61 2009/10/11 20:02:19 roberto Exp $ | |
| 2 | +** $Id: lparser.h,v 1.63 2010/03/12 19:14:06 roberto Exp $ | |
| 3 | 3 | ** Lua Parser |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| @@ -23,10 +23,10 @@ typedef enum { · 17 unmodified lines | ||
| 23 | 23 | VFALSE, |
| 24 | 24 | VK, /* info = index of constant in `k' */ |
| 25 | 25 | VKNUM, /* nval = numerical value */ |
| 26 | − VLOCAL, /* info = local register; aux = read only */ | |
| 27 | − VUPVAL, /* info = index of upvalue in 'upvalues'; aux = read only */ | |
| 28 | − VGLOBAL, /* info = index of table; aux = index of global name in `k' */ | |
| 29 | − VINDEXED, /* info = table register; aux = index register (or `k') */ | |
| 26 | + VLOCAL, /* info = local register */ | |
| 27 | + VUPVAL, /* info = index of upvalue in 'upvalues' */ | |
| 28 | + VINDEXED, /* info = table R/K; aux = index R/K */ | |
| 29 | + VINDEXEDUP, /* info = table upvalue; aux = R/K */ | |
| 30 | 30 | VJMP, /* info = instruction pc */ |
| 31 | 31 | VRELOCABLE, /* info = instruction pc */ |
| 32 | 32 | VNONRELOC, /* info = result register */ |
| @@ -80,7 +80,6 @@ typedef struct FuncState { · 47 unmodified lines | ||
| 80 | 80 | short nlocvars; /* number of elements in `locvars' */ |
| 81 | 81 | lu_byte nactvar; /* number of active local variables */ |
| 82 | 82 | lu_byte nups; /* number of upvalues */ |
| 83 | − lu_byte envreg; /* register holding current lexical environment */ | |
| 84 | 83 | } FuncState; |
| 85 | 84 | |
| 86 | 85 | |
| @@ -1,5 +1,5 @@ | ||
| 1 | 1 | /* |
| 2 | −** $Id: lstate.c,v 2.68 2009/12/22 15:32:50 roberto Exp $ | |
| 2 | +** $Id: lstate.c,v 2.85 2010/04/30 18:36:22 roberto Exp $ | |
| 3 | 3 | ** Global State |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| @@ -26,7 +26,7 @@ · 20 unmodified lines | ||
| 26 | 26 | |
| 27 | 27 | |
| 28 | 28 | #if !defined(LUAI_GCPAUSE) |
| 29 | −#define LUAI_GCPAUSE 162 /* 162% (wait memory to double before next GC) */ | |
| 29 | +#define LUAI_GCPAUSE 200 /* 200% */ | |
| 30 | 30 | #endif |
| 31 | 31 | |
| 32 | 32 | #if !defined(LUAI_GCMUL) |
| @@ -34,6 +34,9 @@ · 1 unmodified line | ||
| 34 | 34 | #endif |
| 35 | 35 | |
| 36 | 36 | |
| 37 | +#define MEMERRMSG "not enough memory" | |
| 38 | + | |
| 39 | + | |
| 37 | 40 | /* |
| 38 | 41 | ** thread state + extra space |
| 39 | 42 | */ |
| @@ -87,7 +90,7 @@ void luaE_freeCI (lua_State *L) { · 47 unmodified lines | ||
| 87 | 90 | |
| 88 | 91 | |
| 89 | 92 | static void stack_init (lua_State *L1, lua_State *L) { |
| 90 | − int i; | |
| 93 | + int i; CallInfo *ci; | |
| 91 | 94 | /* initialize stack array */ |
| 92 | 95 | L1->stack = luaM_newvector(L, BASIC_STACK_SIZE, TValue); |
| 93 | 96 | L1->stacksize = BASIC_STACK_SIZE; |
| @@ -96,32 +99,22 @@ static void stack_init (lua_State *L1, lua_State *L) { · 2 unmodified lines | ||
| 96 | 99 | L1->top = L1->stack; |
| 97 | 100 | L1->stack_last = L1->stack + L1->stacksize - EXTRA_STACK; |
| 98 | 101 | /* initialize first ci */ |
| 99 | − L1->ci->func = L1->top; | |
| 102 | + ci = &L1->base_ci; | |
| 103 | + ci->next = ci->previous = NULL; | |
| 104 | + ci->callstatus = 0; | |
| 105 | + ci->func = L1->top; | |
| 100 | 106 | setnilvalue(L1->top++); /* 'function' entry for this 'ci' */ |
| 101 | − L1->ci->top = L1->top + LUA_MINSTACK; | |
| 102 | − L1->ci->callstatus = 0; | |
| 107 | + ci->top = L1->top + LUA_MINSTACK; | |
| 108 | + L1->ci = ci; | |
| 103 | 109 | } |
| 104 | 110 | |
| 105 | 111 | |
| 106 | 112 | static void freestack (lua_State *L) { |
| 107 | − L->ci = &L->base_ci; /* reset 'ci' list */ | |
| 113 | + if (L->stack == NULL) | |
| 114 | + return; /* stack not completely built yet */ | |
| 115 | + L->ci = &L->base_ci; /* free the entire 'ci' list */ | |
| 108 | 116 | luaE_freeCI(L); |
| 109 | − luaM_freearray(L, L->stack, L->stacksize); | |
| 110 | −} | |
| 111 | − | |
| 112 | − | |
| 113 | −/* | |
| 114 | −** Calls the function in variable pointed to by userdata in first argument | |
| 115 | −** (Userdata cannot point directly to the function because pointer to | |
| 116 | −** function is not compatible with void*.) | |
| 117 | −*/ | |
| 118 | −static int cpcall (lua_State *L) { | |
| 119 | − lua_CFunction f = *(lua_CFunction *)lua_touserdata(L, 1); | |
| 120 | − lua_remove(L, 1); /* remove f from stack */ | |
| 121 | − /* restore original environment for 'cpcall' */ | |
| 122 | − lua_pushglobaltable(L); | |
| 123 | − lua_replace(L, LUA_ENVIRONINDEX); | |
| 124 | − return f(L); | |
| 117 | + luaM_freearray(L, L->stack, L->stacksize); /* free stack array */ | |
| 125 | 118 | } |
| 126 | 119 | |
| 127 | 120 | |
| @@ -129,7 +122,6 @@ static int cpcall (lua_State *L) { · 1 unmodified line | ||
| 129 | 122 | ** Create registry table and its predefined values |
| 130 | 123 | */ |
| 131 | 124 | static void init_registry (lua_State *L, global_State *g) { |
| 132 | − Closure *cp; | |
| 133 | 125 | TValue mt; |
| 134 | 126 | /* create registry */ |
| 135 | 127 | Table *registry = luaH_new(L); |
| @@ -138,13 +130,8 @@ static void init_registry (lua_State *L, global_State *g) { · 2 unmodified lines | ||
| 138 | 130 | /* registry[LUA_RIDX_MAINTHREAD] = L */ |
| 139 | 131 | setthvalue(L, &mt, L); |
| 140 | 132 | setobj2t(L, luaH_setint(L, registry, LUA_RIDX_MAINTHREAD), &mt); |
| 141 | − /* registry[LUA_RIDX_CPCALL] = cpcall */ | |
| 142 | − cp = luaF_newCclosure(L, 0, g->l_gt); | |
| 143 | − cp->c.f = cpcall; | |
| 144 | − setclvalue(L, &mt, cp); | |
| 145 | − setobj2t(L, luaH_setint(L, registry, LUA_RIDX_CPCALL), &mt); | |
| 146 | − /* registry[LUA_RIDX_GLOBALS] = l_gt */ | |
| 147 | − sethvalue(L, &mt, g->l_gt); | |
| 133 | + /* registry[LUA_RIDX_GLOBALS] = table of globals */ | |
| 134 | + sethvalue(L, &mt, luaH_new(L)); | |
| 148 | 135 | setobj2t(L, luaH_setint(L, registry, LUA_RIDX_GLOBALS), &mt); |
| 149 | 136 | } |
| 150 | 137 | |
| @@ -156,13 +143,14 @@ static void f_luaopen (lua_State *L, void *ud) { · 5 unmodified lines | ||
| 156 | 143 | global_State *g = G(L); |
| 157 | 144 | UNUSED(ud); |
| 158 | 145 | stack_init(L, L); /* init stack */ |
| 159 | − g->l_gt = luaH_new(L); /* table of globals */ | |
| 160 | 146 | init_registry(L, g); |
| 161 | 147 | luaS_resize(L, MINSTRTABSIZE); /* initial size of string table */ |
| 162 | 148 | luaT_init(L); |
| 163 | 149 | luaX_init(L); |
| 164 | − luaS_fix(luaS_newliteral(L, MEMERRMSG)); | |
| 165 | − g->GCthreshold = 4*g->totalbytes; | |
| 150 | + /* pre-create memory-error message */ | |
| 151 | + g->memerrmsg = luaS_newliteral(L, MEMERRMSG); | |
| 152 | + luaS_fix(g->memerrmsg); /* it should never be collected */ | |
| 153 | + g->GCdebt = 0; | |
| 166 | 154 | } |
| 167 | 155 | |
| 168 | 156 | |
| @@ -173,6 +161,7 @@ static void f_luaopen (lua_State *L, void *ud) { · 4 unmodified lines | ||
| 173 | 161 | static void preinit_state (lua_State *L, global_State *g) { |
| 174 | 162 | G(L) = g; |
| 175 | 163 | L->stack = NULL; |
| 164 | + L->ci = NULL; | |
| 176 | 165 | L->stacksize = 0; |
| 177 | 166 | L->errorJmp = NULL; |
| 178 | 167 | L->hook = NULL; |
| @@ -183,8 +172,6 @@ static void preinit_state (lua_State *L, global_State *g) { · 4 unmodified lines | ||
| 183 | 172 | L->openupval = NULL; |
| 184 | 173 | L->nny = 1; |
| 185 | 174 | L->status = LUA_OK; |
| 186 | − L->base_ci.next = L->base_ci.previous = NULL; | |
| 187 | − L->ci = &L->base_ci; | |
| 188 | 175 | L->errfunc = 0; |
| 189 | 176 | } |
| 190 | 177 | |
| @@ -209,14 +196,13 @@ LUA_API lua_State *lua_newthread (lua_State *L) { · 18 unmodified lines | ||
| 209 | 196 | setthvalue(L, L->top, L1); |
| 210 | 197 | api_incr_top(L); |
| 211 | 198 | preinit_state(L1, G(L)); |
| 212 | − stack_init(L1, L); /* init stack */ | |
| 213 | 199 | L1->hookmask = L->hookmask; |
| 214 | 200 | L1->basehookcount = L->basehookcount; |
| 215 | 201 | L1->hook = L->hook; |
| 216 | 202 | resethookcount(L1); |
| 217 | − lua_assert(iswhite(obj2gco(L1))); | |
| 218 | − lua_unlock(L); | |
| 219 | 203 | luai_userstatethread(L, L1); |
| 204 | + stack_init(L1, L); /* init stack */ | |
| 205 | + lua_unlock(L); | |
| 220 | 206 | return L1; |
| 221 | 207 | } |
| 222 | 208 | |
| @@ -225,7 +211,7 @@ void luaE_freethread (lua_State *L, lua_State *L1) { · 2 unmodified lines | ||
| 225 | 211 | LX *l = fromstate(L1); |
| 226 | 212 | luaF_close(L1, L1->stack); /* close all upvalues for this thread */ |
| 227 | 213 | lua_assert(L1->openupval == NULL); |
| 228 | − luai_userstatefree(L1); | |
| 214 | + luai_userstatefree(L, L1); | |
| 229 | 215 | freestack(L1); |
| 230 | 216 | luaM_free(L, l); |
| 231 | 217 | } |
| @@ -235,7 +221,7 @@ LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) { · 3 unmodified lines | ||
| 235 | 221 | int i; |
| 236 | 222 | lua_State *L; |
| 237 | 223 | global_State *g; |
| 238 | − LG *l = cast(LG *, (*f)(ud, NULL, 0, sizeof(LG))); | |
| 224 | + LG *l = cast(LG *, (*f)(ud, NULL, LUA_TTHREAD, sizeof(LG))); | |
| 239 | 225 | if (l == NULL) return NULL; |
| 240 | 226 | L = &l->l.l; |
| 241 | 227 | g = &l->g; |
| @@ -245,29 +231,31 @@ LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) { · 3 unmodified lines | ||
| 245 | 231 | L->marked = luaC_white(g); |
| 246 | 232 | g->gckind = KGC_NORMAL; |
| 247 | 233 | g->nCcalls = 0; |
| 248 | − set2bits(L->marked, FIXEDBIT, SFIXEDBIT); | |
| 249 | 234 | preinit_state(L, g); |
| 250 | 235 | g->frealloc = f; |
| 251 | 236 | g->ud = ud; |
| 252 | 237 | g->mainthread = L; |
| 253 | 238 | g->uvhead.u.l.prev = &g->uvhead; |
| 254 | 239 | g->uvhead.u.l.next = &g->uvhead; |
| 255 | − g->GCthreshold = MAX_LUMEM; /* no GC while building state */ | |
| 240 | + stopgc(g); /* no GC while building state */ | |
| 241 | + g->lastmajormem = 0; | |
| 256 | 242 | g->strt.size = 0; |
| 257 | 243 | g->strt.nuse = 0; |
| 258 | 244 | g->strt.hash = NULL; |
| 259 | 245 | setnilvalue(&g->l_registry); |
| 260 | − g->l_gt = NULL; | |
| 261 | 246 | luaZ_initbuffer(L, &g->buff); |
| 262 | 247 | g->panic = NULL; |
| 263 | 248 | g->version = lua_version(NULL); |
| 264 | 249 | g->gcstate = GCSpause; |
| 265 | − g->rootgc = obj2gco(L); | |
| 250 | + g->allgc = NULL; | |
| 251 | + g->udgc = NULL; | |
| 266 | 252 | g->tobefnz = NULL; |
| 253 | + g->gray = g->grayagain = NULL; | |
| 254 | + g->weak = g->ephemeron = g->allweak = NULL; | |
| 267 | 255 | g->totalbytes = sizeof(LG); |
| 268 | 256 | g->gcpause = LUAI_GCPAUSE; |
| 269 | 257 | g->gcstepmul = LUAI_GCMUL; |
| 270 | − for (i=0; i<NUM_TAGS; i++) g->mt[i] = NULL; | |
| 258 | + for (i=0; i < LUA_NUMTAGS; i++) g->mt[i] = NULL; | |
| 271 | 259 | if (luaD_rawrunprotected(L, f_luaopen, NULL) != LUA_OK) { |
| 272 | 260 | /* memory allocation error: free partial state */ |
| 273 | 261 | close_state(L); |
| @@ -1,5 +1,5 @@ | ||
| 1 | 1 | /* |
| 2 | −** $Id: lstate.h,v 2.52 2009/12/22 15:32:50 roberto Exp $ | |
| 2 | +** $Id: lstate.h,v 2.65 2010/05/03 17:39:48 roberto Exp $ | |
| 3 | 3 | ** Global State |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| @@ -19,7 +19,7 @@ · 13 unmodified lines | ||
| 19 | 19 | ** Some notes about garbage-collected objects: All objects in Lua must |
| 20 | 20 | ** be kept somehow accessible until being freed. |
| 21 | 21 | ** |
| 22 | −** Lua keeps most objects linked in list g->rootgc. The link uses field | |
| 22 | +** Lua keeps most objects linked in list g->allgc. The link uses field | |
| 23 | 23 | ** 'next' of the CommonHeader. |
| 24 | 24 | ** |
| 25 | 25 | ** Strings are kept in several lists headed by the array g->strt.hash. |
| @@ -32,9 +32,7 @@ · 6 unmodified lines | ||
| 32 | 32 | ** when traversing the respective threads, but the thread may already be |
| 33 | 33 | ** dead, while the upvalue is still accessible through closures.) |
| 34 | 34 | ** |
| 35 | −** Userdata with finalizers are kept in the list g->rootgc, but after | |
| 36 | −** the mainthread, which should be otherwise the last element in the | |
| 37 | −** list, as it was the first one inserted there. | |
| 35 | +** Userdata with finalizers are kept in the list g->udgc. | |
| 38 | 36 | ** |
| 39 | 37 | ** The list g->tobefnz links all userdata being finalized. |
| 40 | 38 | |
| @@ -56,8 +54,8 @@ struct lua_longjmp; /* defined in ldo.c */ · 15 unmodified lines | ||
| 56 | 54 | |
| 57 | 55 | /* kinds of Garbage Collection */ |
| 58 | 56 | #define KGC_NORMAL 0 |
| 59 | −#define KGC_FORCED 1 /* gc was forced by the program */ | |
| 60 | −#define KGC_EMERGENCY 2 /* gc was forced by an allocation failure */ | |
| 57 | +#define KGC_EMERGENCY 1 /* gc was forced by an allocation failure */ | |
| 58 | +#define KGC_GEN 2 /* generational collection */ | |
| 61 | 59 | |
| 62 | 60 | |
| 63 | 61 | typedef struct stringtable { |
| @@ -85,7 +83,7 @@ typedef struct CallInfo { · 21 unmodified lines | ||
| 85 | 83 | int ctx; /* context info. in case of yields */ |
| 86 | 84 | lua_CFunction k; /* continuation in case of yields */ |
| 87 | 85 | ptrdiff_t old_errfunc; |
| 88 | − ptrdiff_t oldtop; | |
| 86 | + ptrdiff_t extra; | |
| 89 | 87 | lu_byte old_allowhook; |
| 90 | 88 | lu_byte status; |
| 91 | 89 | } c; |
| @@ -106,7 +104,6 @@ typedef struct CallInfo { · 14 unmodified lines | ||
| 106 | 104 | #define CIST_TAIL (1<<6) /* call was tail called */ |
| 107 | 105 | |
| 108 | 106 | |
| 109 | −#define curr_func(L) (clvalue(L->ci->func)) | |
| 110 | 107 | #define ci_func(ci) (clvalue((ci)->func)) |
| 111 | 108 | #define isLua(ci) ((ci)->callstatus & CIST_LUA) |
| 112 | 109 | |
| @@ -115,15 +112,20 @@ typedef struct CallInfo { · 2 unmodified lines | ||
| 115 | 112 | ** `global state', shared by all threads of this state |
| 116 | 113 | */ |
| 117 | 114 | typedef struct global_State { |
| 118 | − stringtable strt; /* hash table for strings */ | |
| 119 | 115 | lua_Alloc frealloc; /* function to reallocate memory */ |
| 120 | 116 | void *ud; /* auxiliary data to `frealloc' */ |
| 117 | + lu_mem totalbytes; /* number of bytes currently allocated */ | |
| 118 | + l_mem GCdebt; /* when positive, run a GC step */ | |
| 119 | + lu_mem lastmajormem; /* memory in use after last major collection */ | |
| 120 | + stringtable strt; /* hash table for strings */ | |
| 121 | + TValue l_registry; | |
| 121 | 122 | unsigned short nCcalls; /* number of nested C calls */ |
| 122 | 123 | lu_byte currentwhite; |
| 123 | 124 | lu_byte gcstate; /* state of garbage collector */ |
| 124 | 125 | lu_byte gckind; /* kind of GC running */ |
| 125 | 126 | int sweepstrgc; /* position of sweep in `strt' */ |
| 126 | − GCObject *rootgc; /* list of all collectable objects */ | |
| 127 | + GCObject *allgc; /* list of all collectable objects */ | |
| 128 | + GCObject *udgc; /* list of collectable userdata with finalizers */ | |
| 127 | 129 | GCObject **sweepgc; /* current position of sweep */ |
| 128 | 130 | GCObject *gray; /* list of gray objects */ |
| 129 | 131 | GCObject *grayagain; /* list of objects to be traversed atomically */ |
| @@ -131,19 +133,16 @@ typedef struct global_State { · 1 unmodified line | ||
| 131 | 133 | GCObject *ephemeron; /* list of ephemeron tables (weak keys) */ |
| 132 | 134 | GCObject *allweak; /* list of all-weak tables */ |
| 133 | 135 | GCObject *tobefnz; /* list of userdata to be GC */ |
| 136 | + UpVal uvhead; /* head of double-linked list of all open upvalues */ | |
| 134 | 137 | Mbuffer buff; /* temporary buffer for string concatenation */ |
| 135 | − lu_mem GCthreshold; /* when totalbytes > GCthreshold, run GC step */ | |
| 136 | − lu_mem totalbytes; /* number of bytes currently allocated */ | |
| 137 | 138 | int gcpause; /* size of pause between successive GCs */ |
| 138 | 139 | int gcstepmul; /* GC `granularity' */ |
| 139 | 140 | lua_CFunction panic; /* to be called in unprotected errors */ |
| 140 | − TValue l_registry; | |
| 141 | − struct Table *l_gt; /* table of globals */ | |
| 142 | 141 | struct lua_State *mainthread; |
| 143 | − UpVal uvhead; /* head of double-linked list of all open upvalues */ | |
| 144 | 142 | const lua_Number *version; /* pointer to version number */ |
| 145 | − struct Table *mt[NUM_TAGS]; /* metatables for basic types */ | |
| 143 | + TString *memerrmsg; /* memory-error message */ | |
| 146 | 144 | TString *tmname[TM_N]; /* array with tag-method names */ |
| 145 | + struct Table *mt[LUA_NUMTAGS]; /* metatables for basic types */ | |
| 147 | 146 | } global_State; |
| 148 | 147 | |
| 149 | 148 | |
| @@ -166,7 +165,6 @@ struct lua_State { · 16 unmodified lines | ||
| 166 | 165 | int basehookcount; |
| 167 | 166 | int hookcount; |
| 168 | 167 | lua_Hook hook; |
| 169 | − TValue env; /* temporary place for environments */ | |
| 170 | 168 | GCObject *openupval; /* list of open upvalues in this stack */ |
| 171 | 169 | GCObject *gclist; |
| 172 | 170 | struct lua_longjmp *errorJmp; /* current error recover point */ |
| @@ -1,5 +1,5 @@ | ||
| 1 | 1 | /* |
| 2 | −** $Id: lstring.c,v 2.16 2009/12/16 16:42:58 roberto Exp $ | |
| 2 | +** $Id: lstring.c,v 2.18 2010/05/10 18:23:45 roberto Exp $ | |
| 3 | 3 | ** String table (keeps all strings handled by Lua) |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| @@ -37,6 +37,7 @@ void luaS_resize (lua_State *L, int newsize) { · 31 unmodified lines | ||
| 37 | 37 | unsigned int h = lmod(gco2ts(p)->hash, newsize); /* new position */ |
| 38 | 38 | gch(p)->next = tb->hash[h]; /* chain it */ |
| 39 | 39 | tb->hash[h] = p; |
| 40 | + resetoldbit(p); /* see MOVE OLD rule */ | |
| 40 | 41 | p = next; |
| 41 | 42 | } |
| 42 | 43 | } |
| @@ -94,6 +95,11 @@ TString *luaS_newlstr (lua_State *L, const char *str, size_t l) { · 51 unmodified lines | ||
| 94 | 95 | } |
| 95 | 96 | |
| 96 | 97 | |
| 98 | +TString *luaS_new (lua_State *L, const char *str) { | |
| 99 | + return luaS_newlstr(L, str, strlen(str)); | |
| 100 | +} | |
| 101 | + | |
| 102 | + | |
| 97 | 103 | Udata *luaS_newudata (lua_State *L, size_t s, Table *e) { |
| 98 | 104 | Udata *u; |
| 99 | 105 | if (s > MAX_SIZET - sizeof(Udata)) |
| @@ -1,5 +1,5 @@ | ||
| 1 | 1 | /* |
| 2 | −** $Id: lstring.h,v 1.43 2005/04/25 19:24:10 roberto Exp $ | |
| 2 | +** $Id: lstring.h,v 1.46 2010/04/05 16:26:37 roberto Exp $ | |
| 3 | 3 | ** String table (keep all strings handled by Lua) |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| @@ -7,7 +7,6 @@ · 1 unmodified line | ||
| 7 | 7 | #ifndef lstring_h |
| 8 | 8 | #define lstring_h |
| 9 | 9 | |
| 10 | − | |
| 11 | 10 | #include "lgc.h" |
| 12 | 11 | #include "lobject.h" |
| 13 | 12 | #include "lstate.h" |
| @@ -17,15 +16,22 @@ · 3 unmodified lines | ||
| 17 | 16 | |
| 18 | 17 | #define sizeudata(u) (sizeof(union Udata)+(u)->len) |
| 19 | 18 | |
| 20 | −#define luaS_new(L, s) (luaS_newlstr(L, s, strlen(s))) | |
| 21 | 19 | #define luaS_newliteral(L, s) (luaS_newlstr(L, "" s, \ |
| 22 | 20 | (sizeof(s)/sizeof(char))-1)) |
| 23 | 21 | |
| 24 | 22 | #define luaS_fix(s) l_setbit((s)->tsv.marked, FIXEDBIT) |
| 25 | 23 | |
| 24 | + | |
| 25 | +/* | |
| 26 | +** as all string are internalized, string equality becomes | |
| 27 | +** pointer equality | |
| 28 | +*/ | |
| 29 | +#define eqstr(a,b) ((a) == (b)) | |
| 30 | + | |
| 26 | 31 | LUAI_FUNC void luaS_resize (lua_State *L, int newsize); |
| 27 | 32 | LUAI_FUNC Udata *luaS_newudata (lua_State *L, size_t s, Table *e); |
| 28 | 33 | LUAI_FUNC TString *luaS_newlstr (lua_State *L, const char *str, size_t l); |
| 34 | +LUAI_FUNC TString *luaS_new (lua_State *L, const char *str); | |
| 29 | 35 | |
| 30 | 36 | |
| 31 | 37 | #endif |
| @@ -1,5 +1,5 @@ | ||
| 1 | 1 | /* |
| 2 | −** $Id: lstrlib.c,v 1.148 2010/01/04 16:37:19 roberto Exp $ | |
| 2 | +** $Id: lstrlib.c,v 1.152 2010/05/04 17:20:33 roberto Exp $ | |
| 3 | 3 | ** Standard library for string operations and pattern-matching |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| @@ -65,12 +65,13 @@ static int str_sub (lua_State *L) { · 59 unmodified lines | ||
| 65 | 65 | |
| 66 | 66 | |
| 67 | 67 | static int str_reverse (lua_State *L) { |
| 68 | − size_t l; | |
| 68 | + size_t l, i; | |
| 69 | 69 | luaL_Buffer b; |
| 70 | 70 | const char *s = luaL_checklstring(L, 1, &l); |
| 71 | − luaL_buffinit(L, &b); | |
| 72 | − while (l--) luaL_addchar(&b, s[l]); | |
| 73 | − luaL_pushresult(&b); | |
| 71 | + char *p = luaL_buffinitsize(L, &b, l); | |
| 72 | + for (i = 0; i < l; i++) | |
| 73 | + p[i] = s[l - i - 1]; | |
| 74 | + luaL_pushresultsize(&b, l); | |
| 74 | 75 | return 1; |
| 75 | 76 | } |
| 76 | 77 | |
| @@ -80,10 +81,10 @@ static int str_lower (lua_State *L) { · 3 unmodified lines | ||
| 80 | 81 | size_t i; |
| 81 | 82 | luaL_Buffer b; |
| 82 | 83 | const char *s = luaL_checklstring(L, 1, &l); |
| 83 | − luaL_buffinit(L, &b); | |
| 84 | + char *p = luaL_buffinitsize(L, &b, l); | |
| 84 | 85 | for (i=0; i<l; i++) |
| 85 | − luaL_addchar(&b, tolower(uchar(s[i]))); | |
| 86 | − luaL_pushresult(&b); | |
| 86 | + p[i] = tolower(uchar(s[i])); | |
| 87 | + luaL_pushresultsize(&b, l); | |
| 87 | 88 | return 1; |
| 88 | 89 | } |
| 89 | 90 | |
| @@ -93,10 +94,10 @@ static int str_upper (lua_State *L) { · 3 unmodified lines | ||
| 93 | 94 | size_t i; |
| 94 | 95 | luaL_Buffer b; |
| 95 | 96 | const char *s = luaL_checklstring(L, 1, &l); |
| 96 | − luaL_buffinit(L, &b); | |
| 97 | + char *p = luaL_buffinitsize(L, &b, l); | |
| 97 | 98 | for (i=0; i<l; i++) |
| 98 | − luaL_addchar(&b, toupper(uchar(s[i]))); | |
| 99 | − luaL_pushresult(&b); | |
| 99 | + p[i] = toupper(uchar(s[i])); | |
| 100 | + luaL_pushresultsize(&b, l); | |
| 100 | 101 | return 1; |
| 101 | 102 | } |
| 102 | 103 | |
| @@ -136,13 +137,13 @@ static int str_char (lua_State *L) { · 33 unmodified lines | ||
| 136 | 137 | int n = lua_gettop(L); /* number of arguments */ |
| 137 | 138 | int i; |
| 138 | 139 | luaL_Buffer b; |
| 139 | − luaL_buffinit(L, &b); | |
| 140 | + char *p = luaL_buffinitsize(L, &b, n); | |
| 140 | 141 | for (i=1; i<=n; i++) { |
| 141 | 142 | int c = luaL_checkint(L, i); |
| 142 | 143 | luaL_argcheck(L, uchar(c) == c, i, "invalid value"); |
| 143 | − luaL_addchar(&b, uchar(c)); | |
| 144 | + p[i - 1] = uchar(c); | |
| 144 | 145 | } |
| 145 | − luaL_pushresult(&b); | |
| 146 | + luaL_pushresultsize(&b, n); | |
| 146 | 147 | return 1; |
| 147 | 148 | } |
| 148 | 149 | |
| @@ -179,7 +180,8 @@ static int str_dump (lua_State *L) { · 30 unmodified lines | ||
| 179 | 180 | |
| 180 | 181 | typedef struct MatchState { |
| 181 | 182 | const char *src_init; /* init of source string */ |
| 182 | − const char *src_end; /* end (`\0') of source string */ | |
| 183 | + const char *src_end; /* end ('\0') of source string */ | |
| 184 | + const char *p_end; /* end ('\0') of pattern */ | |
| 183 | 185 | lua_State *L; |
| 184 | 186 | int level; /* total number of captures (finished or unfinished) */ |
| 185 | 187 | struct { |
| @@ -212,16 +214,16 @@ static int capture_to_close (MatchState *ms) { · 26 unmodified lines | ||
| 212 | 214 | static const char *classend (MatchState *ms, const char *p) { |
| 213 | 215 | switch (*p++) { |
| 214 | 216 | case L_ESC: { |
| 215 | − if (*p == '\0') | |
| 217 | + if (p == ms->p_end) | |
| 216 | 218 | luaL_error(ms->L, "malformed pattern (ends with " LUA_QL("%%") ")"); |
| 217 | 219 | return p+1; |
| 218 | 220 | } |
| 219 | 221 | case '[': { |
| 220 | 222 | if (*p == '^') p++; |
| 221 | 223 | do { /* look for a `]' */ |
| 222 | − if (*p == '\0') | |
| 224 | + if (p == ms->p_end) | |
| 223 | 225 | luaL_error(ms->L, "malformed pattern (missing " LUA_QL("]") ")"); |
| 224 | − if (*(p++) == L_ESC && *p != '\0') | |
| 226 | + if (*(p++) == L_ESC && p < ms->p_end) | |
| 225 | 227 | p++; /* skip escapes (e.g. `%]') */ |
| 226 | 228 | } while (*p != ']'); |
| 227 | 229 | return p+1; |
| @@ -245,7 +247,7 @@ static int match_class (int c, int cl) { · 17 unmodified lines | ||
| 245 | 247 | case 'u' : res = isupper(c); break; |
| 246 | 248 | case 'w' : res = isalnum(c); break; |
| 247 | 249 | case 'x' : res = isxdigit(c); break; |
| 248 | − case 'z' : res = (c == 0); break; | |
| 250 | + case 'z' : res = (c == 0); break; /* deprecated option */ | |
| 249 | 251 | default: return (cl == c); |
| 250 | 252 | } |
| 251 | 253 | return (islower(cl) ? res : !res); |
| @@ -290,8 +292,9 @@ static const char *match (MatchState *ms, const char *s, const char *p); · 38 unmodified lines | ||
| 290 | 292 | |
| 291 | 293 | static const char *matchbalance (MatchState *ms, const char *s, |
| 292 | 294 | const char *p) { |
| 293 | − if (*p == 0 || *(p+1) == 0) | |
| 294 | − luaL_error(ms->L, "unbalanced pattern"); | |
| 295 | + if (p >= ms->p_end - 1) | |
| 296 | + luaL_error(ms->L, "malformed pattern " | |
| 297 | + "(missing arguments to " LUA_QL("%%b") ")"); | |
| 295 | 298 | if (*s != *p) return NULL; |
| 296 | 299 | else { |
| 297 | 300 | int b = *p; |
| @@ -374,6 +377,8 @@ static const char *match_capture (MatchState *ms, const char *s, int l) { · 76 unmodified lines | ||
| 374 | 377 | |
| 375 | 378 | static const char *match (MatchState *ms, const char *s, const char *p) { |
| 376 | 379 | init: /* using goto's to optimize tail recursion */ |
| 380 | + if (p == ms->p_end) /* end of pattern? */ | |
| 381 | + return s; /* match succeeded */ | |
| 377 | 382 | switch (*p) { |
| 378 | 383 | case '(': { /* start capture */ |
| 379 | 384 | if (*(p+1) == ')') /* position capture? */ |
| @@ -384,11 +389,8 @@ static const char *match (MatchState *ms, const char *s, const char *p) { · 4 unmodified lines | ||
| 384 | 389 | case ')': { /* end capture */ |
| 385 | 390 | return end_capture(ms, s, p+1); |
| 386 | 391 | } |
| 387 | − case '\0': { /* end of pattern */ | |
| 388 | − return s; /* match succeeded */ | |
| 389 | − } | |
| 390 | 392 | case '$': { |
| 391 | − if (*(p+1) == '\0') /* is the `$' the last char in pattern? */ | |
| 393 | + if ((p+1) == ms->p_end) /* is the `$' the last char in pattern? */ | |
| 392 | 394 | return (s == ms->src_end) ? s : NULL; /* check end of string */ |
| 393 | 395 | else goto dflt; |
| 394 | 396 | } |
| @@ -418,12 +420,12 @@ static const char *match (MatchState *ms, const char *s, const char *p) { · 23 unmodified lines | ||
| 418 | 420 | if (s == NULL) return NULL; |
| 419 | 421 | p+=2; goto init; /* else return match(ms, s, p+2) */ |
| 420 | 422 | } |
| 421 | − default: break; /* go through to 'dflt' */ | |
| 423 | + default: goto dflt; | |
| 422 | 424 | } |
| 423 | 425 | } |
| 424 | 426 | default: dflt: { /* pattern class plus optional sufix */ |
| 425 | 427 | const char *ep = classend(ms, p); /* points to what is next */ |
| 426 | − int m = s<ms->src_end && singlematch(uchar(*s), p, ep); | |
| 428 | + int m = s < ms->src_end && singlematch(uchar(*s), p, ep); | |
| 427 | 429 | switch (*ep) { |
| 428 | 430 | case '?': { /* optional */ |
| 429 | 431 | const char *res; |
| @@ -503,32 +505,36 @@ static int push_captures (MatchState *ms, const char *s, const char *e) { · 73 unmodified lines | ||
| 503 | 505 | |
| 504 | 506 | |
| 505 | 507 | static int str_find_aux (lua_State *L, int find) { |
| 506 | − size_t l1, l2; | |
| 507 | − const char *s = luaL_checklstring(L, 1, &l1); | |
| 508 | − const char *p = luaL_checklstring(L, 2, &l2); | |
| 509 | − size_t init = posrelat(luaL_optinteger(L, 3, 1), l1); | |
| 508 | + size_t ls, lp; | |
| 509 | + const char *s = luaL_checklstring(L, 1, &ls); | |
| 510 | + const char *p = luaL_checklstring(L, 2, &lp); | |
| 511 | + size_t init = posrelat(luaL_optinteger(L, 3, 1), ls); | |
| 510 | 512 | if (init < 1) init = 1; |
| 511 | − else if (init > l1 + 1) { /* start after string's end? */ | |
| 513 | + else if (init > ls + 1) { /* start after string's end? */ | |
| 512 | 514 | lua_pushnil(L); /* cannot find anything */ |
| 513 | 515 | return 1; |
| 514 | 516 | } |
| 515 | 517 | if (find && (lua_toboolean(L, 4) || /* explicit request? */ |
| 516 | 518 | strpbrk(p, SPECIALS) == NULL)) { /* or no special characters? */ |
| 517 | 519 | /* do a plain search */ |
| 518 | − const char *s2 = lmemfind(s + init - 1, l1 - init + 1, p, l2); | |
| 520 | + const char *s2 = lmemfind(s + init - 1, ls - init + 1, p, lp); | |
| 519 | 521 | if (s2) { |
| 520 | 522 | lua_pushinteger(L, s2 - s + 1); |
| 521 | − lua_pushinteger(L, s2 - s + l2); | |
| 523 | + lua_pushinteger(L, s2 - s + lp); | |
| 522 | 524 | return 2; |
| 523 | 525 | } |
| 524 | 526 | } |
| 525 | 527 | else { |
| 526 | 528 | MatchState ms; |
| 527 | − int anchor = (*p == '^') ? (p++, 1) : 0; | |
| 528 | 529 | const char *s1 = s + init - 1; |
| 530 | + int anchor = (*p == '^'); | |
| 531 | + if (anchor) { | |
| 532 | + p++; lp--; /* skip anchor character */ | |
| 533 | + } | |
| 529 | 534 | ms.L = L; |
| 530 | 535 | ms.src_init = s; |
| 531 | − ms.src_end = s + l1; | |
| 536 | + ms.src_end = s + ls; | |
| 537 | + ms.p_end = p + lp; | |
| 532 | 538 | do { |
| 533 | 539 | const char *res; |
| 534 | 540 | ms.level = 0; |
| @@ -560,13 +566,14 @@ static int str_match (lua_State *L) { · 25 unmodified lines | ||
| 560 | 566 | |
| 561 | 567 | static int gmatch_aux (lua_State *L) { |
| 562 | 568 | MatchState ms; |
| 563 | − size_t ls; | |
| 569 | + size_t ls, lp; | |
| 564 | 570 | const char *s = lua_tolstring(L, lua_upvalueindex(1), &ls); |
| 565 | − const char *p = lua_tostring(L, lua_upvalueindex(2)); | |
| 571 | + const char *p = lua_tolstring(L, lua_upvalueindex(2), &lp); | |
| 566 | 572 | const char *src; |
| 567 | 573 | ms.L = L; |
| 568 | 574 | ms.src_init = s; |
| 569 | 575 | ms.src_end = s+ls; |
| 576 | + ms.p_end = p + lp; | |
| 570 | 577 | for (src = s + (size_t)lua_tointeger(L, lua_upvalueindex(3)); |
| 571 | 578 | src <= ms.src_end; |
| 572 | 579 | src++) { |
| @@ -658,12 +665,12 @@ static void add_value (MatchState *ms, luaL_Buffer *b, const char *s, · 85 unmodified lines | ||
| 658 | 665 | |
| 659 | 666 | |
| 660 | 667 | static int str_gsub (lua_State *L) { |
| 661 | − size_t srcl; | |
| 668 | + size_t srcl, lp; | |
| 662 | 669 | const char *src = luaL_checklstring(L, 1, &srcl); |
| 663 | − const char *p = luaL_checkstring(L, 2); | |
| 670 | + const char *p = luaL_checklstring(L, 2, &lp); | |
| 664 | 671 | int tr = lua_type(L, 3); |
| 665 | 672 | size_t max_s = luaL_optinteger(L, 4, srcl+1); |
| 666 | − int anchor = (*p == '^') ? (p++, 1) : 0; | |
| 673 | + int anchor = (*p == '^'); | |
| 667 | 674 | size_t n = 0; |
| 668 | 675 | MatchState ms; |
| 669 | 676 | luaL_Buffer b; |
| @@ -671,9 +678,13 @@ static int str_gsub (lua_State *L) { · 1 unmodified line | ||
| 671 | 678 | tr == LUA_TFUNCTION || tr == LUA_TTABLE, 3, |
| 672 | 679 | "string/function/table expected"); |
| 673 | 680 | luaL_buffinit(L, &b); |
| 681 | + if (anchor) { | |
| 682 | + p++; lp--; /* skip anchor character */ | |
| 683 | + } | |
| 674 | 684 | ms.L = L; |
| 675 | 685 | ms.src_init = src; |
| 676 | 686 | ms.src_end = src+srcl; |
| 687 | + ms.p_end = p + lp; | |
| 677 | 688 | while (n < max_s) { |
| 678 | 689 | const char *e; |
| 679 | 690 | ms.level = 0; |
| @@ -698,11 +709,18 @@ static int str_gsub (lua_State *L) { · 18 unmodified lines | ||
| 698 | 709 | /* }====================================================== */ |
| 699 | 710 | |
| 700 | 711 | |
| 712 | + | |
| 701 | 713 | /* |
| 702 | −** length modifier for integer conversions ** in 'string.format' and | |
| 703 | −** integer type corresponding to the previous length | |
| 714 | +** {====================================================== | |
| 715 | +** STRING FORMAT | |
| 716 | +** ======================================================= | |
| 704 | 717 | */ |
| 705 | 718 | |
| 719 | +/* | |
| 720 | +** LUA_INTFRMLEN is the length modifier for integer conversions in | |
| 721 | +** 'string.format'; LUA_INTFRM_T is the integer type corresponding to | |
| 722 | +** the previous length | |
| 723 | +*/ | |
| 706 | 724 | #if defined(LUA_USELONGLONG) |
| 707 | 725 | |
| 708 | 726 | #define LUA_INTFRMLEN "ll" |
| @@ -738,7 +756,7 @@ static void addquoted (lua_State *L, luaL_Buffer *b, int arg) { · 29 unmodified lines | ||
| 738 | 756 | } |
| 739 | 757 | else if (*s == '\0' || iscntrl(uchar(*s))) { |
| 740 | 758 | char buff[10]; |
| 741 | − if (*s != '\0' && !isdigit(uchar(*(s+1)))) | |
| 759 | + if (!isdigit(uchar(*(s+1)))) | |
| 742 | 760 | sprintf(buff, "\\%d", uchar(*s)); |
| 743 | 761 | else |
| 744 | 762 | sprintf(buff, "\\%03d", uchar(*s)); |
| @@ -773,6 +791,9 @@ static const char *scanformat (lua_State *L, const char *strfrmt, char *form) { · 28 unmodified lines | ||
| 773 | 791 | } |
| 774 | 792 | |
| 775 | 793 | |
| 794 | +/* | |
| 795 | +** add length modifier into integer formats | |
| 796 | +*/ | |
| 776 | 797 | static void addintlen (char *form) { |
| 777 | 798 | size_t l = strlen(form); |
| 778 | 799 | char spec = form[l - 1]; |
| @@ -783,6 +804,7 @@ static void addintlen (char *form) { · 4 unmodified lines | ||
| 783 | 804 | |
| 784 | 805 | |
| 785 | 806 | static int str_format (lua_State *L) { |
| 807 | + int top = lua_gettop(L); | |
| 786 | 808 | int arg = 1; |
| 787 | 809 | size_t sfl; |
| 788 | 810 | const char *strfrmt = luaL_checklstring(L, arg, &sfl); |
| @@ -796,12 +818,14 @@ static int str_format (lua_State *L) { · 7 unmodified lines | ||
| 796 | 818 | luaL_addchar(&b, *strfrmt++); /* %% */ |
| 797 | 819 | else { /* format item */ |
| 798 | 820 | char form[MAX_FORMAT]; /* to store the format (`%...') */ |
| 799 | − char buff[MAX_ITEM]; /* to store the formatted item */ | |
| 800 | − arg++; | |
| 821 | + char *buff = luaL_prepbuffsize(&b, MAX_ITEM); /* to put formatted item */ | |
| 822 | + int nb = 0; /* number of bytes in added item */ | |
| 823 | + if (++arg > top) | |
| 824 | + luaL_argerror(L, arg, "no value"); | |
| 801 | 825 | strfrmt = scanformat(L, strfrmt, form); |
| 802 | 826 | switch (*strfrmt++) { |
| 803 | 827 | case 'c': { |
| 804 | − sprintf(buff, form, luaL_checkint(L, arg)); | |
| 828 | + nb = sprintf(buff, form, luaL_checkint(L, arg)); | |
| 805 | 829 | break; |
| 806 | 830 | } |
| 807 | 831 | case 'd': case 'i': |
| @@ -810,17 +834,17 @@ static int str_format (lua_State *L) { · 2 unmodified lines | ||
| 810 | 834 | LUA_INTFRM_T r = (n < 0) ? (LUA_INTFRM_T)n : |
| 811 | 835 | (LUA_INTFRM_T)(unsigned LUA_INTFRM_T)n; |
| 812 | 836 | addintlen(form); |
| 813 | − sprintf(buff, form, r); | |
| 837 | + nb = sprintf(buff, form, r); | |
| 814 | 838 | break; |
| 815 | 839 | } |
| 816 | 840 | case 'e': case 'E': case 'f': |
| 817 | 841 | case 'g': case 'G': { |
| 818 | − sprintf(buff, form, (double)luaL_checknumber(L, arg)); | |
| 842 | + nb = sprintf(buff, form, (double)luaL_checknumber(L, arg)); | |
| 819 | 843 | break; |
| 820 | 844 | } |
| 821 | 845 | case 'q': { |
| 822 | 846 | addquoted(L, &b, arg); |
| 823 | − continue; /* skip the 'addsize' at the end */ | |
| 847 | + break; | |
| 824 | 848 | } |
| 825 | 849 | case 's': { |
| 826 | 850 | size_t l; |
| @@ -830,10 +854,10 @@ static int str_format (lua_State *L) { · 3 unmodified lines | ||
| 830 | 854 | keep original string */ |
| 831 | 855 | lua_pushvalue(L, arg); |
| 832 | 856 | luaL_addvalue(&b); |
| 833 | − continue; /* skip the `addsize' at the end */ | |
| 857 | + break; | |
| 834 | 858 | } |
| 835 | 859 | else { |
| 836 | − sprintf(buff, form, s); | |
| 860 | + nb = sprintf(buff, form, s); | |
| 837 | 861 | break; |
| 838 | 862 | } |
| 839 | 863 | } |
| @@ -842,13 +866,15 @@ static int str_format (lua_State *L) { · 2 unmodified lines | ||
| 842 | 866 | LUA_QL("format"), *(strfrmt - 1)); |
| 843 | 867 | } |
| 844 | 868 | } |
| 845 | − luaL_addlstring(&b, buff, strlen(buff)); | |
| 869 | + luaL_addsize(&b, nb); | |
| 846 | 870 | } |
| 847 | 871 | } |
| 848 | 872 | luaL_pushresult(&b); |
| 849 | 873 | return 1; |
| 850 | 874 | } |
| 851 | 875 | |
| 876 | +/* }====================================================== */ | |
| 877 | + | |
| 852 | 878 | |
| 853 | 879 | static const luaL_Reg strlib[] = { |
| 854 | 880 | {"byte", str_byte}, |
| @@ -1,5 +1,5 @@ | ||
| 1 | 1 | /* |
| 2 | −** $Id: ltable.c,v 2.47 2009/12/17 15:46:44 roberto Exp $ | |
| 2 | +** $Id: ltable.c,v 2.50 2010/04/18 13:22:48 roberto Exp $ | |
| 3 | 3 | ** Lua tables (hash) |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| @@ -31,6 +31,7 @@ · 25 unmodified lines | ||
| 31 | 31 | #include "lmem.h" |
| 32 | 32 | #include "lobject.h" |
| 33 | 33 | #include "lstate.h" |
| 34 | +#include "lstring.h" | |
| 34 | 35 | #include "ltable.h" |
| 35 | 36 | |
| 36 | 37 | |
| @@ -108,6 +109,8 @@ static Node *mainposition (const Table *t, const TValue *key) { · 71 unmodified lines | ||
| 108 | 109 | return hashboolean(t, bvalue(key)); |
| 109 | 110 | case LUA_TLIGHTUSERDATA: |
| 110 | 111 | return hashpointer(t, pvalue(key)); |
| 112 | + case LUA_TLCF: | |
| 113 | + return hashpointer(t, fvalue(key)); | |
| 111 | 114 | default: |
| 112 | 115 | return hashpointer(t, gcvalue(key)); |
| 113 | 116 | } |
| @@ -452,7 +455,7 @@ const TValue *luaH_getint (Table *t, int key) { · 338 unmodified lines | ||
| 452 | 455 | const TValue *luaH_getstr (Table *t, TString *key) { |
| 453 | 456 | Node *n = hashstr(t, key); |
| 454 | 457 | do { /* check whether `key' is somewhere in the chain */ |
| 455 | − if (ttisstring(gkey(n)) && rawtsvalue(gkey(n)) == key) | |
| 458 | + if (ttisstring(gkey(n)) && eqstr(rawtsvalue(gkey(n)), key)) | |
| 456 | 459 | return gval(n); /* that's it */ |
| 457 | 460 | else n = gnext(n); |
| 458 | 461 | } while (n); |
| @@ -1,5 +1,5 @@ | ||
| 1 | 1 | /* |
| 2 | −** $Id: ltablib.c,v 1.54 2010/01/13 19:59:10 roberto Exp $ | |
| 2 | +** $Id: ltablib.c,v 1.55 2010/03/13 03:57:46 roberto Exp $ | |
| 3 | 3 | ** Library for Table Manipulation |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| @@ -171,15 +171,15 @@ static int tconcat (lua_State *L) { · 165 unmodified lines | ||
| 171 | 171 | static int pack (lua_State *L) { |
| 172 | 172 | int top = lua_gettop(L); |
| 173 | 173 | lua_createtable(L, top, 1); /* create result table */ |
| 174 | − /* use function environment as a temporary place to keep new table */ | |
| 175 | − lua_replace(L, LUA_ENVIRONINDEX); | |
| 176 | 174 | lua_pushinteger(L, top); /* number of elements */ |
| 177 | − lua_setfield(L, LUA_ENVIRONINDEX, "n"); /* t.n = number of elements */ | |
| 178 | − for (; top >= 1; top--) /* assign elements */ | |
| 179 | − lua_rawseti(L, LUA_ENVIRONINDEX, top); | |
| 180 | − lua_pushvalue(L, LUA_ENVIRONINDEX); /* return new table */ | |
| 181 | − /* remove new table from environment to allow its later collection */ | |
| 182 | − lua_copy(L, LUA_REGISTRYINDEX, LUA_ENVIRONINDEX); | |
| 175 | + lua_setfield(L, -2, "n"); /* t.n = number of elements */ | |
| 176 | + if (top > 0) { /* at least one element? */ | |
| 177 | + lua_pushvalue(L, 1); | |
| 178 | + lua_rawseti(L, -2, 1); /* insert first element */ | |
| 179 | + lua_replace(L, 1); /* move table into its position (index 1) */ | |
| 180 | + for (; top >= 2; top--) /* assign other elements */ | |
| 181 | + lua_rawseti(L, 1, top); | |
| 182 | + } | |
| 183 | 183 | return 1; |
| 184 | 184 | } |
| 185 | 185 | |
| @@ -328,7 +328,7 @@ LUAMOD_API int luaopen_table (lua_State *L) { · 142 unmodified lines | ||
| 328 | 328 | #if defined(LUA_COMPAT_UNPACK) |
| 329 | 329 | /* _G.unpack = table.unpack */ |
| 330 | 330 | lua_getfield(L, -1, "unpack"); |
| 331 | − lua_setfield(L, LUA_ENVIRONINDEX, "unpack"); | |
| 331 | + lua_setglobal(L, "unpack"); | |
| 332 | 332 | #endif |
| 333 | 333 | return 1; |
| 334 | 334 | } |
| @@ -1,5 +1,5 @@ | ||
| 1 | 1 | /* |
| 2 | −** $Id: ltm.c,v 2.11 2010/01/13 16:18:25 roberto Exp $ | |
| 2 | +** $Id: ltm.c,v 2.12 2010/04/13 20:48:12 roberto Exp $ | |
| 3 | 3 | ** Tag methods |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| @@ -70,7 +70,7 @@ const TValue *luaT_gettmbyobj (lua_State *L, const TValue *o, TMS event) { · 64 unmodified lines | ||
| 70 | 70 | mt = uvalue(o)->metatable; |
| 71 | 71 | break; |
| 72 | 72 | default: |
| 73 | − mt = G(L)->mt[ttype(o)]; | |
| 73 | + mt = G(L)->mt[ttypenv(o)]; | |
| 74 | 74 | } |
| 75 | 75 | return (mt ? luaH_getstr(mt, G(L)->tmname[event]) : luaO_nilobject); |
| 76 | 76 | } |
| @@ -1,5 +1,5 @@ | ||
| 1 | 1 | /* |
| 2 | −** $Id: ltm.h,v 2.9 2010/01/13 16:18:25 roberto Exp $ | |
| 2 | +** $Id: ltm.h,v 2.10 2010/04/13 20:48:12 roberto Exp $ | |
| 3 | 3 | ** Tag methods |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| @@ -43,7 +43,8 @@ typedef enum { · 37 unmodified lines | ||
| 43 | 43 | |
| 44 | 44 | #define fasttm(l,et,e) gfasttm(G(l), et, e) |
| 45 | 45 | |
| 46 | −#define typename(x) luaT_typenames_[(x) + 1] | |
| 46 | +#define ttypename(x) luaT_typenames_[(x) + 1] | |
| 47 | +#define objtypename(x) ttypename(ttypenv(x)) | |
| 47 | 48 | |
| 48 | 49 | LUAI_DDEC const char *const luaT_typenames_[]; |
| 49 | 50 | |
| @@ -1,5 +1,5 @@ | ||
| 1 | 1 | /* |
| 2 | −** $Id: lua.c,v 1.182 2009/12/22 16:47:12 roberto Exp $ | |
| 2 | +** $Id: lua.c,v 1.190 2010/04/14 15:14:21 roberto Exp $ | |
| 3 | 3 | ** Lua stand-alone interpreter |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| @@ -102,26 +102,31 @@ static void laction (int i) { · 96 unmodified lines | ||
| 102 | 102 | } |
| 103 | 103 | |
| 104 | 104 | |
| 105 | −static void print_usage (void) { | |
| 106 | − fprintf(stderr, | |
| 105 | +static void print_usage (const char *badoption) { | |
| 106 | + if (badoption[1] == 'e' || badoption[1] == 'l') { | |
| 107 | + luai_writestringerror("%s: ", progname); | |
| 108 | + luai_writestringerror("'%s' needs argument\n", badoption); | |
| 109 | + } else { | |
| 110 | + luai_writestringerror("%s: ", progname); | |
| 111 | + luai_writestringerror("unrecognized option '%s'\n", badoption); | |
| 112 | + } | |
| 113 | + luai_writestringerror( | |
| 107 | 114 | "usage: %s [options] [script [args]]\n" |
| 108 | 115 | "Available options are:\n" |
| 109 | 116 | " -e stat execute string " LUA_QL("stat") "\n" |
| 110 | − " -l name require library " LUA_QL("name") "\n" | |
| 111 | 117 | " -i enter interactive mode after executing " LUA_QL("script") "\n" |
| 118 | + " -l name require library " LUA_QL("name") "\n" | |
| 112 | 119 | " -v show version information\n" |
| 113 | 120 | " -- stop handling options\n" |
| 114 | − " - execute stdin and stop handling options\n" | |
| 121 | + " - stop handling options and execute stdin\n" | |
| 115 | 122 | , |
| 116 | 123 | progname); |
| 117 | − fflush(stderr); | |
| 118 | 124 | } |
| 119 | 125 | |
| 120 | 126 | |
| 121 | 127 | static void l_message (const char *pname, const char *msg) { |
| 122 | − if (pname) fprintf(stderr, "%s: ", pname); | |
| 123 | − fprintf(stderr, "%s\n", msg); | |
| 124 | − fflush(stderr); | |
| 128 | + if (pname) luai_writestringerror("%s: ", pname); | |
| 129 | + luai_writestringerror("%s\n", msg); | |
| 125 | 130 | } |
| 126 | 131 | |
| 127 | 132 | |
| @@ -214,7 +219,7 @@ static int dostring (lua_State *L, const char *s, const char *name) { · 86 unmodified lines | ||
| 214 | 219 | |
| 215 | 220 | |
| 216 | 221 | static int dolibrary (lua_State *L, const char *name) { |
| 217 | − lua_getfield(L, LUA_ENVIRONINDEX, "require"); | |
| 222 | + lua_getglobal(L, "require"); | |
| 218 | 223 | lua_pushstring(L, name); |
| 219 | 224 | return report(L, docall(L, 1, 1)); |
| 220 | 225 | } |
| @@ -222,7 +227,7 @@ static int dolibrary (lua_State *L, const char *name) { · 1 unmodified line | ||
| 222 | 227 | |
| 223 | 228 | static const char *get_prompt (lua_State *L, int firstline) { |
| 224 | 229 | const char *p; |
| 225 | − lua_getfield(L, LUA_ENVIRONINDEX, firstline ? "_PROMPT" : "_PROMPT2"); | |
| 230 | + lua_getglobal(L, firstline ? "_PROMPT" : "_PROMPT2"); | |
| 226 | 231 | p = lua_tostring(L, -1); |
| 227 | 232 | if (p == NULL) p = (firstline ? LUA_PROMPT : LUA_PROMPT2); |
| 228 | 233 | lua_pop(L, 1); /* remove global */ |
| @@ -296,7 +301,7 @@ static void dotty (lua_State *L) { · 67 unmodified lines | ||
| 296 | 301 | report(L, status); |
| 297 | 302 | if (status == LUA_OK && lua_gettop(L) > 0) { /* any result to print? */ |
| 298 | 303 | luaL_checkstack(L, LUA_MINSTACK, "too many results to print"); |
| 299 | − lua_getfield(L, LUA_ENVIRONINDEX, "print"); | |
| 304 | + lua_getglobal(L, "print"); | |
| 300 | 305 | lua_insert(L, 1); |
| 301 | 306 | if (lua_pcall(L, lua_gettop(L)-1, 0, 0) != LUA_OK) |
| 302 | 307 | l_message(progname, lua_pushfstring(L, |
| @@ -306,7 +311,6 @@ static void dotty (lua_State *L) { · 3 unmodified lines | ||
| 306 | 311 | } |
| 307 | 312 | lua_settop(L, 0); /* clear stack */ |
| 308 | 313 | luai_writestring("\n", 1); |
| 309 | − fflush(stdout); | |
| 310 | 314 | progname = oldprogname; |
| 311 | 315 | } |
| 312 | 316 | |
| @@ -315,7 +319,7 @@ static int handle_script (lua_State *L, char **argv, int n) { · 2 unmodified lines | ||
| 315 | 319 | int status; |
| 316 | 320 | const char *fname; |
| 317 | 321 | int narg = getargs(L, argv, n); /* collect arguments */ |
| 318 | − lua_setfield(L, LUA_ENVIRONINDEX, "arg"); | |
| 322 | + lua_setglobal(L, "arg"); | |
| 319 | 323 | fname = argv[n]; |
| 320 | 324 | if (strcmp(fname, "-") == 0 && strcmp(argv[n-1], "--") != 0) |
| 321 | 325 | fname = NULL; /* stdin */ |
| @@ -356,10 +360,11 @@ static int collectargs (char **argv, int *pi, int *pv, int *pe) { · 34 unmodified lines | ||
| 356 | 360 | case 'l': |
| 357 | 361 | if (argv[i][2] == '\0') { |
| 358 | 362 | i++; |
| 359 | − if (argv[i] == NULL) return -1; | |
| 363 | + if (argv[i] == NULL) return -(i - 1); | |
| 360 | 364 | } |
| 361 | 365 | break; |
| 362 | − default: return -1; /* invalid option */ | |
| 366 | + default: /* invalid option; return its index... */ | |
| 367 | + return -i; /* ...as a negative value */ | |
| 363 | 368 | } |
| 364 | 369 | } |
| 365 | 370 | return 0; |
| @@ -369,7 +374,6 @@ static int collectargs (char **argv, int *pi, int *pv, int *pe) { · 3 unmodified lines | ||
| 369 | 374 | static int runargs (lua_State *L, char **argv, int n) { |
| 370 | 375 | int i; |
| 371 | 376 | for (i = 1; i < n; i++) { |
| 372 | − if (argv[i] == NULL) continue; | |
| 373 | 377 | lua_assert(argv[i][0] == '-'); |
| 374 | 378 | switch (argv[i][1]) { /* option */ |
| 375 | 379 | case 'e': { |
| @@ -412,8 +416,8 @@ static int pmain (lua_State *L) { · 36 unmodified lines | ||
| 412 | 416 | int has_i = 0, has_v = 0, has_e = 0; |
| 413 | 417 | if (argv[0] && argv[0][0]) progname = argv[0]; |
| 414 | 418 | script = collectargs(argv, &has_i, &has_v, &has_e); |
| 415 | − if (script < 0) { /* invalid args? */ | |
| 416 | − print_usage(); | |
| 419 | + if (script < 0) { /* invalid arg? */ | |
| 420 | + print_usage(argv[-script]); | |
| 417 | 421 | return 0; |
| 418 | 422 | } |
| 419 | 423 | if (has_v) print_version(); |
| @@ -443,7 +447,6 @@ static int pmain (lua_State *L) { · 23 unmodified lines | ||
| 443 | 447 | |
| 444 | 448 | |
| 445 | 449 | int main (int argc, char **argv) { |
| 446 | − static lua_CFunction ppmain = &pmain; | |
| 447 | 450 | int status, result; |
| 448 | 451 | lua_State *L = luaL_newstate(); /* create state */ |
| 449 | 452 | if (L == NULL) { |
| @@ -451,11 +454,10 @@ int main (int argc, char **argv) { · 1 unmodified line | ||
| 451 | 454 | return EXIT_FAILURE; |
| 452 | 455 | } |
| 453 | 456 | /* call 'pmain' in protected mode */ |
| 454 | − lua_rawgeti(L, LUA_REGISTRYINDEX, LUA_RIDX_CPCALL); /* calling function */ | |
| 455 | − lua_pushlightuserdata(L, &ppmain); | |
| 456 | − lua_pushinteger(L, argc); | |
| 457 | − lua_pushlightuserdata(L, argv); | |
| 458 | − status = lua_pcall(L, 3, 1, 0); | |
| 457 | + lua_pushcfunction(L, &pmain); | |
| 458 | + lua_pushinteger(L, argc); /* 1st argument */ | |
| 459 | + lua_pushlightuserdata(L, argv); /* 2nd argument */ | |
| 460 | + status = lua_pcall(L, 2, 1, 0); | |
| 459 | 461 | result = lua_toboolean(L, -1); /* get result */ |
| 460 | 462 | finalreport(L, status); |
| 461 | 463 | lua_close(L); |
| @@ -1,5 +1,5 @@ | ||
| 1 | 1 | /* |
| 2 | −** $Id: lua.h,v 1.261 2010/01/11 17:15:11 roberto Exp $ | |
| 2 | +** $Id: lua.h,v 1.270 2010/05/12 14:09:20 roberto Exp $ | |
| 3 | 3 | ** Lua - A Scripting Language |
| 4 | 4 | ** Lua.org, PUC-Rio, Brazil (http://www.lua.org) |
| 5 | 5 | ** See Copyright Notice at the end of this file |
| @@ -17,7 +17,7 @@ · 11 unmodified lines | ||
| 17 | 17 | |
| 18 | 18 | |
| 19 | 19 | #define LUA_VERSION "Lua 5.2" |
| 20 | −#define LUA_RELEASE "Lua 5.2.0 (work2)" | |
| 20 | +#define LUA_RELEASE "Lua 5.2.0 (work3)" | |
| 21 | 21 | #define LUA_VERSION_NUM 502 |
| 22 | 22 | #define LUA_COPYRIGHT LUA_RELEASE " Copyright (C) 1994-2010 Lua.org, PUC-Rio" |
| 23 | 23 | #define LUA_AUTHORS "R. Ierusalimschy, L. H. de Figueiredo, W. Celes" |
| @@ -34,8 +34,7 @@ · 10 unmodified lines | ||
| 34 | 34 | ** pseudo-indices |
| 35 | 35 | */ |
| 36 | 36 | #define LUA_REGISTRYINDEX LUAI_FIRSTPSEUDOIDX |
| 37 | −#define LUA_ENVIRONINDEX (LUA_REGISTRYINDEX - 1) | |
| 38 | −#define lua_upvalueindex(i) (LUA_ENVIRONINDEX - (i)) | |
| 37 | +#define lua_upvalueindex(i) (LUA_REGISTRYINDEX - (i)) | |
| 39 | 38 | |
| 40 | 39 | |
| 41 | 40 | /* thread status */ |
| @@ -82,6 +81,8 @@ typedef void * (*lua_Alloc) (void *ud, void *ptr, size_t osize, size_t nsize); · 40 unmodified lines | ||
| 82 | 81 | #define LUA_TUSERDATA 7 |
| 83 | 82 | #define LUA_TTHREAD 8 |
| 84 | 83 | |
| 84 | +#define LUA_NUMTAGS 9 | |
| 85 | + | |
| 85 | 86 | |
| 86 | 87 | |
| 87 | 88 | /* minimum Lua stack available to a C function */ |
| @@ -90,8 +91,7 @@ typedef void * (*lua_Alloc) (void *ud, void *ptr, size_t osize, size_t nsize); · 2 unmodified lines | ||
| 90 | 91 | |
| 91 | 92 | /* predefined values in the registry */ |
| 92 | 93 | #define LUA_RIDX_MAINTHREAD 1 |
| 93 | −#define LUA_RIDX_CPCALL 2 | |
| 94 | −#define LUA_RIDX_GLOBALS 3 | |
| 94 | +#define LUA_RIDX_GLOBALS 2 | |
| 95 | 95 | #define LUA_RIDX_LAST LUA_RIDX_GLOBALS |
| 96 | 96 | |
| 97 | 97 | |
| @@ -129,6 +129,7 @@ LUA_API const lua_Number *(lua_version) (lua_State *L); · 31 unmodified lines | ||
| 129 | 129 | /* |
| 130 | 130 | ** basic stack manipulation |
| 131 | 131 | */ |
| 132 | +LUA_API int (lua_absindex) (lua_State *L, int idx); | |
| 132 | 133 | LUA_API int (lua_gettop) (lua_State *L); |
| 133 | 134 | LUA_API void (lua_settop) (lua_State *L, int idx); |
| 134 | 135 | LUA_API void (lua_pushvalue) (lua_State *L, int idx); |
| @@ -212,7 +213,7 @@ LUA_API void (lua_rawgeti) (lua_State *L, int idx, int n); · 77 unmodified lines | ||
| 212 | 213 | LUA_API void (lua_createtable) (lua_State *L, int narr, int nrec); |
| 213 | 214 | LUA_API void *(lua_newuserdata) (lua_State *L, size_t sz); |
| 214 | 215 | LUA_API int (lua_getmetatable) (lua_State *L, int objindex); |
| 215 | −LUA_API void (lua_getfenv) (lua_State *L, int idx); | |
| 216 | +LUA_API void (lua_getenv) (lua_State *L, int idx); | |
| 216 | 217 | |
| 217 | 218 | |
| 218 | 219 | /* |
| @@ -223,7 +224,7 @@ LUA_API void (lua_setfield) (lua_State *L, int idx, const char *k); · 4 unmodified lines | ||
| 223 | 224 | LUA_API void (lua_rawset) (lua_State *L, int idx); |
| 224 | 225 | LUA_API void (lua_rawseti) (lua_State *L, int idx, int n); |
| 225 | 226 | LUA_API int (lua_setmetatable) (lua_State *L, int objindex); |
| 226 | −LUA_API int (lua_setfenv) (lua_State *L, int idx); | |
| 227 | +LUA_API void (lua_setenv) (lua_State *L, int idx); | |
| 227 | 228 | |
| 228 | 229 | |
| 229 | 230 | /* |
| @@ -267,6 +268,8 @@ LUA_API int (lua_status) (lua_State *L); · 37 unmodified lines | ||
| 267 | 268 | #define LUA_GCSETPAUSE 6 |
| 268 | 269 | #define LUA_GCSETSTEPMUL 7 |
| 269 | 270 | #define LUA_GCISRUNNING 8 |
| 271 | +#define LUA_GCGEN 9 | |
| 272 | +#define LUA_GCINC 10 | |
| 270 | 273 | |
| 271 | 274 | LUA_API int (lua_gc) (lua_State *L, int what, int data); |
| 272 | 275 | |
| @@ -297,11 +300,14 @@ LUA_API void (lua_setallocf) (lua_State *L, lua_Alloc f, void *ud); · 24 unmodified lines | ||
| 297 | 300 | |
| 298 | 301 | #define lua_newtable(L) lua_createtable(L, 0, 0) |
| 299 | 302 | |
| 300 | −#define lua_setglobal(L,s) lua_setfield(L, LUA_ENVIRONINDEX, (s)) | |
| 301 | −#define lua_getglobal(L,s) lua_getfield(L, LUA_ENVIRONINDEX, (s)) | |
| 303 | +#define lua_setglobal(L,s) \ | |
| 304 | + (lua_pushglobaltable(L), lua_pushvalue(L, -2), \ | |
| 305 | + lua_setfield(L, -2, (s)), lua_pop(L, 2)) | |
| 306 | + | |
| 307 | +#define lua_getglobal(L,s) \ | |
| 308 | + (lua_pushglobaltable(L), lua_getfield(L, -1, (s)), lua_remove(L, -2)) | |
| 302 | 309 | |
| 303 | −#define lua_register(L,n,f) \ | |
| 304 | − (lua_pushcfunction(L, (f)), lua_setfield(L, LUA_ENVIRONINDEX, (n))) | |
| 310 | +#define lua_register(L,n,f) (lua_pushcfunction(L, (f)), lua_setglobal(L, (n))) | |
| 305 | 311 | |
| 306 | 312 | #define lua_pushcfunction(L,f) lua_pushcclosure(L, (f), 0) |
| 307 | 313 | |
| @@ -1,5 +1,5 @@ | ||
| 1 | 1 | /* |
| 2 | −** $Id: luac.c,v 1.57 2008/03/26 13:40:18 lhf Exp $ | |
| 2 | +** $Id: luac.c,v 1.61 2010/05/14 11:40:22 lhf Exp $ | |
| 3 | 3 | ** Lua compiler (saves bytecodes to files; also list bytecodes) |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| @@ -60,7 +60,7 @@ static void usage(const char* message) · 54 unmodified lines | ||
| 60 | 60 | " -s strip debug information\n" |
| 61 | 61 | " -v show version information\n" |
| 62 | 62 | " -- stop handling options\n" |
| 63 | − " - process stdin and stop handling options\n" | |
| 63 | + " - stop handling options and process stdin\n" | |
| 64 | 64 | ,progname,Output); |
| 65 | 65 | exit(EXIT_FAILURE); |
| 66 | 66 | } |
| @@ -89,7 +89,7 @@ static int doargs(int argc, char* argv[]) · 22 unmodified lines | ||
| 89 | 89 | else if (IS("-o")) /* output file */ |
| 90 | 90 | { |
| 91 | 91 | output=argv[++i]; |
| 92 | − if (output==NULL || *output==0) usage(LUA_QL("-o") " needs argument"); | |
| 92 | + if (output==NULL || *output==0 || *output=='-') usage(LUA_QL("-o") " needs argument"); | |
| 93 | 93 | if (IS("-")) output=NULL; |
| 94 | 94 | } |
| 95 | 95 | else if (IS("-p")) /* parse only */ |
| @@ -150,16 +150,10 @@ static int writer(lua_State* L, const void* p, size_t size, void* u) · 54 unmodified lines | ||
| 150 | 150 | return (fwrite(p,size,1,(FILE*)u)!=1) && (size!=0); |
| 151 | 151 | } |
| 152 | 152 | |
| 153 | −struct Smain { | |
| 154 | − int argc; | |
| 155 | − char** argv; | |
| 156 | −}; | |
| 157 | − | |
| 158 | 153 | static int pmain(lua_State* L) |
| 159 | 154 | { |
| 160 | − struct Smain* s = (struct Smain*)lua_touserdata(L, 1); | |
| 161 | − int argc=s->argc; | |
| 162 | − char** argv=s->argv; | |
| 155 | + int argc=lua_tointeger(L,1); | |
| 156 | + char** argv=lua_touserdata(L,2); | |
| 163 | 157 | const Proto* f; |
| 164 | 158 | int i; |
| 165 | 159 | if (!lua_checkstack(L,argc)) fatal("too many input files"); |
| @@ -183,25 +177,18 @@ static int pmain(lua_State* L) · 17 unmodified lines | ||
| 183 | 177 | return 0; |
| 184 | 178 | } |
| 185 | 179 | |
| 186 | −LUA_API int lua_cpcall (lua_State *L, lua_CFunction func, void *ud) { | |
| 187 | − lua_rawgeti(L, LUA_REGISTRYINDEX, LUA_RIDX_CPCALL); | |
| 188 | − lua_pushlightuserdata(L, &func); | |
| 189 | − lua_pushlightuserdata(L, ud); | |
| 190 | − return lua_pcall(L, 2, 0, 0); | |
| 191 | −} | |
| 192 | − | |
| 193 | 180 | int main(int argc, char* argv[]) |
| 194 | 181 | { |
| 195 | 182 | lua_State* L; |
| 196 | − struct Smain s; | |
| 197 | 183 | int i=doargs(argc,argv); |
| 198 | 184 | argc-=i; argv+=i; |
| 199 | 185 | if (argc<=0) usage("no input files given"); |
| 200 | 186 | L=luaL_newstate(); |
| 201 | 187 | if (L==NULL) fatal("not enough memory for state"); |
| 202 | − s.argc=argc; | |
| 203 | − s.argv=argv; | |
| 204 | − if (lua_cpcall(L,pmain,&s)!=0) fatal(lua_tostring(L,-1)); | |
| 188 | + lua_pushcfunction(L,&pmain); | |
| 189 | + lua_pushinteger(L,argc); | |
| 190 | + lua_pushlightuserdata(L,argv); | |
| 191 | + if (lua_pcall(L,2,0,0)!=0) fatal(lua_tostring(L,-1)); | |
| 205 | 192 | lua_close(L); |
| 206 | 193 | return EXIT_SUCCESS; |
| 207 | 194 | } |
| @@ -1,5 +1,5 @@ | ||
| 1 | 1 | /* |
| 2 | −** $Id: luaconf.h,v 1.130 2010/01/11 17:15:30 roberto Exp $ | |
| 2 | +** $Id: luaconf.h,v 1.137 2010/05/12 14:17:36 roberto Exp $ | |
| 3 | 3 | ** Configuration file for Lua |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| @@ -89,7 +89,7 @@ · 83 unmodified lines | ||
| 89 | 89 | #define LUA_CPATH_DEFAULT \ |
| 90 | 90 | LUA_CDIR"?.dll;" LUA_CDIR"loadall.dll;" ".\\?.dll" |
| 91 | 91 | |
| 92 | −#else | |
| 92 | +#else /* _WIN32 */ | |
| 93 | 93 | #define LUA_ROOT "/usr/local/" |
| 94 | 94 | #define LUA_LDIR LUA_ROOT "share/lua/5.2/" |
| 95 | 95 | #define LUA_CDIR LUA_ROOT "lib/lua/5.2/" |
| @@ -98,7 +98,7 @@ · 2 unmodified lines | ||
| 98 | 98 | LUA_CDIR"?.lua;" LUA_CDIR"?/init.lua;" "./?.lua" |
| 99 | 99 | #define LUA_CPATH_DEFAULT \ |
| 100 | 100 | LUA_CDIR"?.so;" LUA_CDIR"loadall.so;" "./?.so" |
| 101 | −#endif | |
| 101 | +#endif /* _WIN32 */ | |
| 102 | 102 | |
| 103 | 103 | |
| 104 | 104 | /* |
| @@ -130,11 +130,12 @@ · 25 unmodified lines | ||
| 130 | 130 | #define LUA_API __declspec(dllimport) |
| 131 | 131 | #endif |
| 132 | 132 | |
| 133 | −#else | |
| 133 | +#else /* LUA_BUILD_AS_DLL */ | |
| 134 | 134 | |
| 135 | 135 | #define LUA_API extern |
| 136 | 136 | |
| 137 | −#endif | |
| 137 | +#endif /* LUA_BUILD_AS_DLL */ | |
| 138 | + | |
| 138 | 139 | |
| 139 | 140 | /* more often than not the libs go together with the core */ |
| 140 | 141 | #define LUALIB_API LUA_API |
| @@ -166,11 +167,11 @@ · 25 unmodified lines | ||
| 166 | 167 | #define LUAI_DDEC LUAI_FUNC |
| 167 | 168 | #define LUAI_DDEF /* empty */ |
| 168 | 169 | |
| 169 | −#else | |
| 170 | +#else /* luaall_c */ | |
| 170 | 171 | #define LUAI_FUNC extern |
| 171 | 172 | #define LUAI_DDEC extern |
| 172 | 173 | #define LUAI_DDEF /* empty */ |
| 173 | −#endif | |
| 174 | +#endif /* luaall_c */ | |
| 174 | 175 | |
| 175 | 176 | |
| 176 | 177 | |
| @@ -192,10 +193,17 @@ · 15 unmodified lines | ||
| 192 | 193 | |
| 193 | 194 | /* |
| 194 | 195 | @@ luai_writestring defines how 'print' prints its results. |
| 195 | −** CHANGE it if your system does not have a useful stdout. | |
| 196 | 196 | */ |
| 197 | +#include <stdio.h> | |
| 197 | 198 | #define luai_writestring(s,l) fwrite((s), sizeof(char), (l), stdout) |
| 198 | 199 | |
| 200 | +/* | |
| 201 | +@@ luai_writestringerror defines how to print error messages. | |
| 202 | +** (A format string with one argument is enough for Lua...) | |
| 203 | +*/ | |
| 204 | +#define luai_writestringerror(s,p) \ | |
| 205 | + (fprintf(stderr, (s), (p)), fflush(stderr)) | |
| 206 | + | |
| 199 | 207 | |
| 200 | 208 | |
| 201 | 209 | |
| @@ -220,18 +228,12 @@ · 18 unmodified lines | ||
| 220 | 228 | #define LUA_COMPAT_UNPACK |
| 221 | 229 | |
| 222 | 230 | /* |
| 223 | −@@ LUA_COMPAT_CPCALL controls the presence of function 'lua_cpcall'. | |
| 231 | +@@ LUA_COMPAT_CPCALL controls the presence of macro 'lua_cpcall'. | |
| 224 | 232 | ** You can replace it with the preregistered function 'cpcall'. |
| 225 | 233 | */ |
| 226 | −#define LUA_COMPAT_CPCALL | |
| 227 | −LUA_API int (lua_cpcall) (lua_State *L, lua_CFunction func, void *ud); | |
| 234 | +#define lua_cpcall(L,f,u) \ | |
| 235 | + (lua_pushlightuserdata(L,(u)), luaL_cpcall(L,(f),1,0)) | |
| 228 | 236 | |
| 229 | −/* | |
| 230 | −@@ LUA_COMPAT_FENV controls the presence of functions 'setfenv/getfenv'. | |
| 231 | −** You can replace them with lexical environments, 'loadin', or the | |
| 232 | −** debug library. | |
| 233 | −*/ | |
| 234 | −#define LUA_COMPAT_FENV | |
| 235 | 237 | |
| 236 | 238 | /* |
| 237 | 239 | @@ LUA_COMPAT_LOG10 defines the function 'log10' in the math library. |
| @@ -267,7 +269,7 @@ LUA_API int (lua_cpcall) (lua_State *L, lua_CFunction func, void *ud); · 29 unmodified lines | ||
| 267 | 269 | /* compatibility with previous wrong spelling */ |
| 268 | 270 | #define luaL_typerror luaL_typeerror |
| 269 | 271 | |
| 270 | −#endif | |
| 272 | +#endif /* LUA_COMPAT_ALL */ | |
| 271 | 273 | |
| 272 | 274 | /* }================================================================== */ |
| 273 | 275 | |
| @@ -421,7 +423,7 @@ LUA_API int (lua_cpcall) (lua_State *L, lua_CFunction func, void *ud); · 147 unmodified lines | ||
| 421 | 423 | |
| 422 | 424 | /* |
| 423 | 425 | @@ lua_number2int is a macro to convert lua_Number to int. |
| 424 | −@@ lua_number2integer is a macro to convert lua_Number to lUA_INTEGER. | |
| 426 | +@@ lua_number2integer is a macro to convert lua_Number to LUA_INTEGER. | |
| 425 | 427 | @@ lua_number2uint is a macro to convert a lua_Number to an unsigned |
| 426 | 428 | @* LUA_INT32. |
| 427 | 429 | @@ lua_uint2number is a macro to convert an unsigned LUA_INT32 |
| @@ -439,30 +441,31 @@ LUA_API int (lua_cpcall) (lua_State *L, lua_CFunction func, void *ud); · 11 unmodified lines | ||
| 439 | 441 | /* On a Microsoft compiler, use assembler */ |
| 440 | 442 | #if defined(_MSC_VER) |
| 441 | 443 | |
| 442 | −#define lua_number2int(i,d) {__asm fld d __asm fistp i} | |
| 444 | +#define lua_number2int(i,n) __asm {__asm fld n __asm fistp i} | |
| 443 | 445 | #define lua_number2integer(i,n) lua_number2int(i, n) |
| 444 | −#define lua_number2uint(i,n) lua_number2int(i, n) | |
| 446 | +#define lua_number2uint(i,n) \ | |
| 447 | + {__int64 l; __asm {__asm fld n __asm fistp l} i = (unsigned int)l;} | |
| 445 | 448 | |
| 446 | −#else | |
| 449 | +#else /* _MSC_VER */ | |
| 447 | 450 | /* the next trick should work on any Pentium, but sometimes clashes |
| 448 | 451 | with a DirectX idiosyncrasy */ |
| 449 | 452 | |
| 450 | 453 | union luai_Cast { double l_d; long l_l; }; |
| 451 | −#define lua_number2int(i,d) \ | |
| 452 | − { volatile union luai_Cast u; u.l_d = (d) + 6755399441055744.0; (i) = u.l_l; } | |
| 454 | +#define lua_number2int(i,n) \ | |
| 455 | + { volatile union luai_Cast u; u.l_d = (n) + 6755399441055744.0; (i) = u.l_l; } | |
| 453 | 456 | #define lua_number2integer(i,n) lua_number2int(i, n) |
| 454 | 457 | #define lua_number2uint(i,n) lua_number2int(i, n) |
| 455 | 458 | |
| 456 | −#endif | |
| 459 | +#endif /* _MSC_VER */ | |
| 457 | 460 | |
| 458 | 461 | |
| 459 | −#else | |
| 462 | +#else /* LUA_NUMBER_DOUBLE ... (Pentium) */ | |
| 460 | 463 | /* this option always works, but may be slow */ |
| 461 | −#define lua_number2int(i,d) ((i)=(int)(d)) | |
| 462 | −#define lua_number2integer(i,d) ((i)=(LUA_INTEGER)(d)) | |
| 463 | −#define lua_number2uint(i,d) ((i)=(unsigned LUA_INT32)(d)) | |
| 464 | +#define lua_number2int(i,n) ((i)=(int)(n)) | |
| 465 | +#define lua_number2integer(i,n) ((i)=(LUA_INTEGER)(n)) | |
| 466 | +#define lua_number2uint(i,n) ((i)=(unsigned LUA_INT32)(n)) | |
| 464 | 467 | |
| 465 | −#endif | |
| 468 | +#endif /* LUA_NUMBER_DOUBLE ... (Pentium) */ | |
| 466 | 469 | |
| 467 | 470 | |
| 468 | 471 | /* on several machines, coercion from unsigned to double is too slow, |
| @@ -483,11 +486,11 @@ union luai_Cast { double l_d; long l_l; }; · 14 unmodified lines | ||
| 483 | 486 | #include <float.h> |
| 484 | 487 | #include <math.h> |
| 485 | 488 | |
| 486 | −#define luai_hashnum(i,d) { int e; \ | |
| 487 | − d = frexp(d, &e) * (lua_Number)(INT_MAX - DBL_MAX_EXP); \ | |
| 488 | − lua_number2int(i, d); i += e; } | |
| 489 | +#define luai_hashnum(i,n) { int e; \ | |
| 490 | + n = frexp(n, &e) * (lua_Number)(INT_MAX - DBL_MAX_EXP); \ | |
| 491 | + lua_number2int(i, n); i += e; } | |
| 489 | 492 | |
| 490 | −#endif | |
| 493 | +#endif /* ltable_c */ | |
| 491 | 494 | |
| 492 | 495 | /* }================================================================== */ |
| 493 | 496 | |
| @@ -1,5 +1,5 @@ | ||
| 1 | 1 | /* |
| 2 | −** $Id: lundump.c,v 2.12 2009/09/30 15:38:37 roberto Exp $ | |
| 2 | +** $Id: lundump.c,v 2.13 2010/03/12 19:14:06 roberto Exp $ | |
| 3 | 3 | ** load precompiled Lua chunks |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| @@ -180,7 +180,6 @@ static Proto* LoadFunction(LoadState* S, TString* p) · 174 unmodified lines | ||
| 180 | 180 | f->numparams=LoadByte(S); |
| 181 | 181 | f->is_vararg=LoadByte(S); |
| 182 | 182 | f->maxstacksize=LoadByte(S); |
| 183 | − f->envreg=LoadByte(S); | |
| 184 | 183 | LoadCode(S,f); |
| 185 | 184 | LoadConstants(S,f); |
| 186 | 185 | LoadUpvalues(S,f); |
| @@ -1,5 +1,5 @@ | ||
| 1 | 1 | /* |
| 2 | −** $Id: lvm.c,v 2.102 2009/12/17 16:20:01 roberto Exp $ | |
| 2 | +** $Id: lvm.c,v 2.120 2010/05/13 19:53:05 roberto Exp $ | |
| 3 | 3 | ** Lua virtual machine |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| @@ -50,8 +50,8 @@ int luaV_tostring (lua_State *L, StkId obj) { · 44 unmodified lines | ||
| 50 | 50 | else { |
| 51 | 51 | char s[LUAI_MAXNUMBER2STR]; |
| 52 | 52 | lua_Number n = nvalue(obj); |
| 53 | − lua_number2str(s, n); | |
| 54 | − setsvalue2s(L, obj, luaS_new(L, s)); | |
| 53 | + int l = lua_number2str(s, n); | |
| 54 | + setsvalue2s(L, obj, luaS_newlstr(L, s, l)); | |
| 55 | 55 | return 1; |
| 56 | 56 | } |
| 57 | 57 | } |
| @@ -74,6 +74,10 @@ static void traceexec (lua_State *L) { · 16 unmodified lines | ||
| 74 | 74 | luaD_hook(L, LUA_HOOKLINE, newline); |
| 75 | 75 | } |
| 76 | 76 | L->oldpc = ci->u.l.savedpc; |
| 77 | + if (L->status == LUA_YIELD) { /* did hook yield? */ | |
| 78 | + ci->u.l.savedpc--; /* undo increment (resume will increment it again) */ | |
| 79 | + luaD_throw(L, LUA_YIELD); | |
| 80 | + } | |
| 77 | 81 | } |
| 78 | 82 | |
| 79 | 83 | |
| @@ -102,7 +106,7 @@ void luaV_gettable (lua_State *L, const TValue *t, TValue *key, StkId val) { · 22 unmodified lines | ||
| 102 | 106 | if (ttistable(t)) { /* `t' is a table? */ |
| 103 | 107 | Table *h = hvalue(t); |
| 104 | 108 | const TValue *res = luaH_get(h, key); /* do a primitive get */ |
| 105 | − if (!ttisnil(res) || /* result is no nil? */ | |
| 109 | + if (!ttisnil(res) || /* result is not nil? */ | |
| 106 | 110 | (tm = fasttm(L, h->metatable, TM_INDEX)) == NULL) { /* or no TM? */ |
| 107 | 111 | setobj2s(L, val, res); |
| 108 | 112 | return; |
| @@ -129,7 +133,7 @@ void luaV_settable (lua_State *L, const TValue *t, TValue *key, StkId val) { · 20 unmodified lines | ||
| 129 | 133 | if (ttistable(t)) { /* `t' is a table? */ |
| 130 | 134 | Table *h = hvalue(t); |
| 131 | 135 | TValue *oldval = luaH_set(L, h, key); /* do a primitive set */ |
| 132 | − if (!ttisnil(oldval) || /* result is no nil? */ | |
| 136 | + if (!ttisnil(oldval) || /* result is not nil? */ | |
| 133 | 137 | (tm = fasttm(L, h->metatable, TM_NEWINDEX)) == NULL) { /* or no TM? */ |
| 134 | 138 | setobj2t(L, oldval, val); |
| 135 | 139 | luaC_barriert(L, h, val); |
| @@ -157,12 +161,13 @@ static int call_binTM (lua_State *L, const TValue *p1, const TValue *p2, · 21 unmodified lines | ||
| 157 | 161 | if (ttisnil(tm)) |
| 158 | 162 | tm = luaT_gettmbyobj(L, p2, event); /* try second operand */ |
| 159 | 163 | if (ttisnil(tm)) return 0; |
| 164 | + if (event == TM_UNM) p2 = luaO_nilobject; | |
| 160 | 165 | callTM(L, tm, p1, p2, res, 1); |
| 161 | 166 | return 1; |
| 162 | 167 | } |
| 163 | 168 | |
| 164 | 169 | |
| 165 | −static const TValue *get_compTM (lua_State *L, Table *mt1, Table *mt2, | |
| 170 | +static const TValue *get_equalTM (lua_State *L, Table *mt1, Table *mt2, | |
| 166 | 171 | TMS event) { |
| 167 | 172 | const TValue *tm1 = fasttm(L, mt1, event); |
| 168 | 173 | const TValue *tm2; |
| @@ -178,14 +183,10 @@ static const TValue *get_compTM (lua_State *L, Table *mt1, Table *mt2, · 9 unmodified lines | ||
| 178 | 183 | |
| 179 | 184 | static int call_orderTM (lua_State *L, const TValue *p1, const TValue *p2, |
| 180 | 185 | TMS event) { |
| 181 | − const TValue *tm1 = luaT_gettmbyobj(L, p1, event); | |
| 182 | − const TValue *tm2; | |
| 183 | − if (ttisnil(tm1)) return -1; /* no metamethod? */ | |
| 184 | − tm2 = luaT_gettmbyobj(L, p2, event); | |
| 185 | − if (!luaO_rawequalObj(tm1, tm2)) /* different metamethods? */ | |
| 186 | − return -1; | |
| 187 | − callTM(L, tm1, p1, p2, L->top, 1); | |
| 188 | − return !l_isfalse(L->top); | |
| 186 | + if (!call_binTM(L, p1, p2, L->top, event)) | |
| 187 | + return -1; /* no metamethod */ | |
| 188 | + else | |
| 189 | + return !l_isfalse(L->top); | |
| 189 | 190 | } |
| 190 | 191 | |
| 191 | 192 | |
| @@ -213,11 +214,9 @@ static int l_strcmp (const TString *ls, const TString *rs) { · 21 unmodified lines | ||
| 213 | 214 | |
| 214 | 215 | int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r) { |
| 215 | 216 | int res; |
| 216 | − if (ttype(l) != ttype(r)) | |
| 217 | − return luaG_ordererror(L, l, r); | |
| 218 | − else if (ttisnumber(l)) | |
| 217 | + if (ttisnumber(l) && ttisnumber(r)) | |
| 219 | 218 | return luai_numlt(L, nvalue(l), nvalue(r)); |
| 220 | − else if (ttisstring(l)) | |
| 219 | + else if (ttisstring(l) && ttisstring(r)) | |
| 221 | 220 | return l_strcmp(rawtsvalue(l), rawtsvalue(r)) < 0; |
| 222 | 221 | else if ((res = call_orderTM(L, l, r, TM_LT)) != -1) |
| 223 | 222 | return res; |
| @@ -227,11 +226,9 @@ int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r) { · 3 unmodified lines | ||
| 227 | 226 | |
| 228 | 227 | int luaV_lessequal (lua_State *L, const TValue *l, const TValue *r) { |
| 229 | 228 | int res; |
| 230 | − if (ttype(l) != ttype(r)) | |
| 231 | − return luaG_ordererror(L, l, r); | |
| 232 | − else if (ttisnumber(l)) | |
| 229 | + if (ttisnumber(l) && ttisnumber(r)) | |
| 233 | 230 | return luai_numle(L, nvalue(l), nvalue(r)); |
| 234 | − else if (ttisstring(l)) | |
| 231 | + else if (ttisstring(l) && ttisstring(r)) | |
| 235 | 232 | return l_strcmp(rawtsvalue(l), rawtsvalue(r)) <= 0; |
| 236 | 233 | else if ((res = call_orderTM(L, l, r, TM_LE)) != -1) /* first try `le' */ |
| 237 | 234 | return res; |
| @@ -249,14 +246,16 @@ int luaV_equalval_ (lua_State *L, const TValue *t1, const TValue *t2) { · 11 unmodified lines | ||
| 249 | 246 | case LUA_TNUMBER: return luai_numeq(nvalue(t1), nvalue(t2)); |
| 250 | 247 | case LUA_TBOOLEAN: return bvalue(t1) == bvalue(t2); /* true must be 1 !! */ |
| 251 | 248 | case LUA_TLIGHTUSERDATA: return pvalue(t1) == pvalue(t2); |
| 249 | + case LUA_TLCF: return fvalue(t1) == fvalue(t2); | |
| 250 | + case LUA_TSTRING: return eqstr(rawtsvalue(t1), rawtsvalue(t2)); | |
| 252 | 251 | case LUA_TUSERDATA: { |
| 253 | 252 | if (uvalue(t1) == uvalue(t2)) return 1; |
| 254 | − tm = get_compTM(L, uvalue(t1)->metatable, uvalue(t2)->metatable, TM_EQ); | |
| 253 | + tm = get_equalTM(L, uvalue(t1)->metatable, uvalue(t2)->metatable, TM_EQ); | |
| 255 | 254 | break; /* will try TM */ |
| 256 | 255 | } |
| 257 | 256 | case LUA_TTABLE: { |
| 258 | 257 | if (hvalue(t1) == hvalue(t2)) return 1; |
| 259 | − tm = get_compTM(L, hvalue(t1)->metatable, hvalue(t2)->metatable, TM_EQ); | |
| 258 | + tm = get_equalTM(L, hvalue(t1)->metatable, hvalue(t2)->metatable, TM_EQ); | |
| 260 | 259 | break; /* will try TM */ |
| 261 | 260 | } |
| 262 | 261 | default: return gcvalue(t1) == gcvalue(t2); |
| @@ -354,14 +353,10 @@ void luaV_finishOp (lua_State *L) { · 91 unmodified lines | ||
| 354 | 353 | StkId base = ci->u.l.base; |
| 355 | 354 | Instruction inst = *(ci->u.l.savedpc - 1); /* interrupted instruction */ |
| 356 | 355 | OpCode op = GET_OPCODE(inst); |
| 357 | − if (op == OP_EXTRAARG) { /* extra argument? */ | |
| 358 | − inst = *(ci->u.l.savedpc - 2); /* get its 'main' instruction */ | |
| 359 | − op = GET_OPCODE(inst); | |
| 360 | − } | |
| 361 | 356 | switch (op) { /* finish its execution */ |
| 362 | 357 | case OP_ADD: case OP_SUB: case OP_MUL: case OP_DIV: |
| 363 | 358 | case OP_MOD: case OP_POW: case OP_UNM: case OP_LEN: |
| 364 | − case OP_GETGLOBAL: case OP_GETTABLE: case OP_SELF: { | |
| 359 | + case OP_GETTABUP: case OP_GETTABLE: case OP_SELF: { | |
| 365 | 360 | setobjs2s(L, base + GETARG_A(inst), --L->top); |
| 366 | 361 | break; |
| 367 | 362 | } |
| @@ -402,7 +397,7 @@ void luaV_finishOp (lua_State *L) { · 34 unmodified lines | ||
| 402 | 397 | L->top = ci->top; /* adjust results */ |
| 403 | 398 | break; |
| 404 | 399 | } |
| 405 | − case OP_TAILCALL: case OP_SETGLOBAL: case OP_SETTABLE: | |
| 400 | + case OP_TAILCALL: case OP_SETTABUP: case OP_SETTABLE: | |
| 406 | 401 | break; |
| 407 | 402 | default: lua_assert(0); |
| 408 | 403 | } |
| @@ -426,11 +421,13 @@ void luaV_finishOp (lua_State *L) { · 17 unmodified lines | ||
| 426 | 421 | (k + (GETARG_Bx(i) != 0 ? GETARG_Bx(i) - 1 : GETARG_Ax(*ci->u.l.savedpc++))) |
| 427 | 422 | |
| 428 | 423 | |
| 429 | −#define dojump(i) { ci->u.l.savedpc += (i); luai_threadyield(L);} | |
| 424 | +#define dojump(i) (ci->u.l.savedpc += (i)) | |
| 430 | 425 | |
| 431 | 426 | |
| 432 | 427 | #define Protect(x) { {x;}; base = ci->u.l.base; } |
| 433 | 428 | |
| 429 | +#define checkGC(L) Protect(luaC_checkGC(L); luai_threadyield(L);) | |
| 430 | + | |
| 434 | 431 | |
| 435 | 432 | #define arith_op(op,tm) { \ |
| 436 | 433 | TValue *rb = RKB(i); \ |
| @@ -439,133 +436,109 @@ void luaV_finishOp (lua_State *L) { · 2 unmodified lines | ||
| 439 | 436 | lua_Number nb = nvalue(rb), nc = nvalue(rc); \ |
| 440 | 437 | setnvalue(ra, op(L, nb, nc)); \ |
| 441 | 438 | } \ |
| 442 | − else \ | |
| 443 | − Protect(luaV_arith(L, ra, rb, rc, tm)); \ | |
| 444 | − } | |
| 439 | + else { Protect(luaV_arith(L, ra, rb, rc, tm)); } } | |
| 445 | 440 | |
| 446 | 441 | |
| 442 | +#define vmdispatch(o) switch(o) | |
| 443 | +#define vmcase(l,b) case l: {b} break; | |
| 447 | 444 | |
| 448 | 445 | void luaV_execute (lua_State *L) { |
| 449 | 446 | CallInfo *ci = L->ci; |
| 450 | − LClosure *cl = &clvalue(ci->func)->l; | |
| 451 | − TValue *k = cl->p->k; | |
| 452 | − StkId base = ci->u.l.base; | |
| 447 | + LClosure *cl; | |
| 448 | + TValue *k; | |
| 449 | + StkId base; | |
| 450 | + newframe: /* reentry point when frame changes (call/return) */ | |
| 453 | 451 | lua_assert(isLua(ci)); |
| 452 | + lua_assert(ci == L->ci); | |
| 453 | + cl = &clvalue(ci->func)->l; | |
| 454 | + k = cl->p->k; | |
| 455 | + base = ci->u.l.base; | |
| 454 | 456 | /* main loop of interpreter */ |
| 455 | 457 | for (;;) { |
| 456 | 458 | Instruction i = *(ci->u.l.savedpc++); |
| 457 | 459 | StkId ra; |
| 458 | 460 | if ((L->hookmask & (LUA_MASKLINE | LUA_MASKCOUNT)) && |
| 459 | 461 | (--L->hookcount == 0 || L->hookmask & LUA_MASKLINE)) { |
| 460 | − traceexec(L); | |
| 461 | − if (L->status == LUA_YIELD) { /* did hook yield? */ | |
| 462 | − ci->u.l.savedpc--; /* undo increment */ | |
| 463 | − luaD_throw(L, LUA_YIELD); | |
| 464 | − } | |
| 465 | − base = ci->u.l.base; | |
| 462 | + Protect(traceexec(L)); | |
| 466 | 463 | } |
| 467 | 464 | /* warning!! several calls may realloc the stack and invalidate `ra' */ |
| 468 | 465 | ra = RA(i); |
| 469 | 466 | lua_assert(base == ci->u.l.base); |
| 470 | 467 | lua_assert(base <= L->top && L->top < L->stack + L->stacksize); |
| 471 | − switch (GET_OPCODE(i)) { | |
| 472 | − case OP_MOVE: { | |
| 468 | + vmdispatch (GET_OPCODE(i)) { | |
| 469 | + vmcase(OP_MOVE, | |
| 473 | 470 | setobjs2s(L, ra, RB(i)); |
| 474 | − continue; | |
| 475 | − } | |
| 476 | − case OP_LOADK: { | |
| 471 | + ) | |
| 472 | + vmcase(OP_LOADK, | |
| 477 | 473 | TValue *rb = KBx(i); |
| 478 | 474 | setobj2s(L, ra, rb); |
| 479 | − continue; | |
| 480 | − } | |
| 481 | − case OP_LOADBOOL: { | |
| 475 | + ) | |
| 476 | + vmcase(OP_LOADBOOL, | |
| 482 | 477 | setbvalue(ra, GETARG_B(i)); |
| 483 | 478 | if (GETARG_C(i)) ci->u.l.savedpc++; /* skip next instruction (if C) */ |
| 484 | − continue; | |
| 485 | − } | |
| 486 | − case OP_LOADNIL: { | |
| 479 | + ) | |
| 480 | + vmcase(OP_LOADNIL, | |
| 487 | 481 | TValue *rb = RB(i); |
| 488 | 482 | do { |
| 489 | 483 | setnilvalue(rb--); |
| 490 | 484 | } while (rb >= ra); |
| 491 | − continue; | |
| 492 | − } | |
| 493 | − case OP_GETUPVAL: { | |
| 485 | + ) | |
| 486 | + vmcase(OP_GETUPVAL, | |
| 494 | 487 | int b = GETARG_B(i); |
| 495 | 488 | setobj2s(L, ra, cl->upvals[b]->v); |
| 496 | − continue; | |
| 497 | − } | |
| 498 | − case OP_GETGLOBAL: { | |
| 499 | − TValue g; | |
| 500 | − TValue *rb = KBx(i); | |
| 501 | − sethvalue(L, &g, cl->env); | |
| 502 | − lua_assert(ttisstring(rb)); | |
| 503 | − Protect(luaV_gettable(L, &g, rb, ra)); | |
| 504 | − continue; | |
| 505 | − } | |
| 506 | − case OP_GETTABLE: { | |
| 489 | + ) | |
| 490 | + vmcase(OP_GETTABUP, | |
| 491 | + int b = GETARG_B(i); | |
| 492 | + Protect(luaV_gettable(L, cl->upvals[b]->v, RKC(i), ra)); | |
| 493 | + ) | |
| 494 | + vmcase(OP_GETTABLE, | |
| 507 | 495 | Protect(luaV_gettable(L, RB(i), RKC(i), ra)); |
| 508 | − continue; | |
| 509 | − } | |
| 510 | − case OP_SETGLOBAL: { | |
| 511 | − TValue g; | |
| 512 | − TValue *rb = KBx(i); | |
| 513 | − sethvalue(L, &g, cl->env); | |
| 514 | − lua_assert(ttisstring(rb)); | |
| 515 | − Protect(luaV_settable(L, &g, rb, ra)); | |
| 516 | − continue; | |
| 517 | − } | |
| 518 | − case OP_SETUPVAL: { | |
| 496 | + ) | |
| 497 | + vmcase(OP_SETTABUP, | |
| 498 | + int a = GETARG_A(i); | |
| 499 | + Protect(luaV_settable(L, cl->upvals[a]->v, RKB(i), RKC(i))); | |
| 500 | + ) | |
| 501 | + vmcase(OP_SETUPVAL, | |
| 519 | 502 | UpVal *uv = cl->upvals[GETARG_B(i)]; |
| 520 | 503 | setobj(L, uv->v, ra); |
| 521 | 504 | luaC_barrier(L, uv, ra); |
| 522 | − continue; | |
| 523 | − } | |
| 524 | − case OP_SETTABLE: { | |
| 505 | + ) | |
| 506 | + vmcase(OP_SETTABLE, | |
| 525 | 507 | Protect(luaV_settable(L, ra, RKB(i), RKC(i))); |
| 526 | − continue; | |
| 527 | − } | |
| 528 | − case OP_NEWTABLE: { | |
| 508 | + ) | |
| 509 | + vmcase(OP_NEWTABLE, | |
| 529 | 510 | int b = GETARG_B(i); |
| 530 | 511 | int c = GETARG_C(i); |
| 531 | 512 | Table *t = luaH_new(L); |
| 532 | 513 | sethvalue(L, ra, t); |
| 533 | 514 | if (b != 0 || c != 0) |
| 534 | 515 | luaH_resize(L, t, luaO_fb2int(b), luaO_fb2int(c)); |
| 535 | − Protect(luaC_checkGC(L)); | |
| 536 | − continue; | |
| 537 | − } | |
| 538 | − case OP_SELF: { | |
| 516 | + checkGC(L); | |
| 517 | + ) | |
| 518 | + vmcase(OP_SELF, | |
| 539 | 519 | StkId rb = RB(i); |
| 540 | 520 | setobjs2s(L, ra+1, rb); |
| 541 | 521 | Protect(luaV_gettable(L, rb, RKC(i), ra)); |
| 542 | − continue; | |
| 543 | − } | |
| 544 | − case OP_ADD: { | |
| 522 | + ) | |
| 523 | + vmcase(OP_ADD, | |
| 545 | 524 | arith_op(luai_numadd, TM_ADD); |
| 546 | − continue; | |
| 547 | − } | |
| 548 | − case OP_SUB: { | |
| 525 | + ) | |
| 526 | + vmcase(OP_SUB, | |
| 549 | 527 | arith_op(luai_numsub, TM_SUB); |
| 550 | − continue; | |
| 551 | − } | |
| 552 | − case OP_MUL: { | |
| 528 | + ) | |
| 529 | + vmcase(OP_MUL, | |
| 553 | 530 | arith_op(luai_nummul, TM_MUL); |
| 554 | − continue; | |
| 555 | − } | |
| 556 | − case OP_DIV: { | |
| 531 | + ) | |
| 532 | + vmcase(OP_DIV, | |
| 557 | 533 | arith_op(luai_numdiv, TM_DIV); |
| 558 | − continue; | |
| 559 | − } | |
| 560 | − case OP_MOD: { | |
| 534 | + ) | |
| 535 | + vmcase(OP_MOD, | |
| 561 | 536 | arith_op(luai_nummod, TM_MOD); |
| 562 | − continue; | |
| 563 | − } | |
| 564 | − case OP_POW: { | |
| 537 | + ) | |
| 538 | + vmcase(OP_POW, | |
| 565 | 539 | arith_op(luai_numpow, TM_POW); |
| 566 | − continue; | |
| 567 | − } | |
| 568 | − case OP_UNM: { | |
| 540 | + ) | |
| 541 | + vmcase(OP_UNM, | |
| 569 | 542 | TValue *rb = RB(i); |
| 570 | 543 | if (ttisnumber(rb)) { |
| 571 | 544 | lua_Number nb = nvalue(rb); |
| @@ -574,31 +547,26 @@ void luaV_execute (lua_State *L) { · 2 unmodified lines | ||
| 574 | 547 | else { |
| 575 | 548 | Protect(luaV_arith(L, ra, rb, rb, TM_UNM)); |
| 576 | 549 | } |
| 577 | − continue; | |
| 578 | − } | |
| 579 | − case OP_NOT: { | |
| 550 | + ) | |
| 551 | + vmcase(OP_NOT, | |
| 580 | 552 | int res = l_isfalse(RB(i)); /* next assignment may change this value */ |
| 581 | 553 | setbvalue(ra, res); |
| 582 | − continue; | |
| 583 | − } | |
| 584 | − case OP_LEN: { | |
| 554 | + ) | |
| 555 | + vmcase(OP_LEN, | |
| 585 | 556 | Protect(luaV_objlen(L, ra, RB(i))); |
| 586 | − continue; | |
| 587 | − } | |
| 588 | − case OP_CONCAT: { | |
| 557 | + ) | |
| 558 | + vmcase(OP_CONCAT, | |
| 589 | 559 | int b = GETARG_B(i); |
| 590 | 560 | int c = GETARG_C(i); |
| 591 | 561 | L->top = base + c + 1; /* mark the end of concat operands */ |
| 592 | − Protect(luaV_concat(L, c-b+1); luaC_checkGC(L)); | |
| 562 | + Protect(luaV_concat(L, c-b+1); checkGC(L);) | |
| 593 | 563 | L->top = ci->top; /* restore top */ |
| 594 | 564 | setobjs2s(L, RA(i), base+b); |
| 595 | − continue; | |
| 596 | − } | |
| 597 | − case OP_JMP: { | |
| 565 | + ) | |
| 566 | + vmcase(OP_JMP, | |
| 598 | 567 | dojump(GETARG_sBx(i)); |
| 599 | − continue; | |
| 600 | − } | |
| 601 | − case OP_EQ: { | |
| 568 | + ) | |
| 569 | + vmcase(OP_EQ, | |
| 602 | 570 | TValue *rb = RKB(i); |
| 603 | 571 | TValue *rc = RKC(i); |
| 604 | 572 | Protect( |
| @@ -606,62 +574,54 @@ void luaV_execute (lua_State *L) { · 1 unmodified line | ||
| 606 | 574 | dojump(GETARG_sBx(*ci->u.l.savedpc)); |
| 607 | 575 | ) |
| 608 | 576 | ci->u.l.savedpc++; |
| 609 | − continue; | |
| 610 | − } | |
| 611 | − case OP_LT: { | |
| 577 | + ) | |
| 578 | + vmcase(OP_LT, | |
| 612 | 579 | Protect( |
| 613 | 580 | if (luaV_lessthan(L, RKB(i), RKC(i)) == GETARG_A(i)) |
| 614 | 581 | dojump(GETARG_sBx(*ci->u.l.savedpc)); |
| 615 | 582 | ) |
| 616 | 583 | ci->u.l.savedpc++; |
| 617 | − continue; | |
| 618 | − } | |
| 619 | − case OP_LE: { | |
| 584 | + ) | |
| 585 | + vmcase(OP_LE, | |
| 620 | 586 | Protect( |
| 621 | 587 | if (luaV_lessequal(L, RKB(i), RKC(i)) == GETARG_A(i)) |
| 622 | 588 | dojump(GETARG_sBx(*ci->u.l.savedpc)); |
| 623 | 589 | ) |
| 624 | 590 | ci->u.l.savedpc++; |
| 625 | − continue; | |
| 626 | − } | |
| 627 | − case OP_TEST: { | |
| 591 | + ) | |
| 592 | + vmcase(OP_TEST, | |
| 628 | 593 | if (GETARG_C(i) ? !l_isfalse(ra) : l_isfalse(ra)) |
| 629 | 594 | dojump(GETARG_sBx(*ci->u.l.savedpc)); |
| 630 | 595 | ci->u.l.savedpc++; |
| 631 | − continue; | |
| 632 | − } | |
| 633 | − case OP_TESTSET: { | |
| 596 | + ) | |
| 597 | + vmcase(OP_TESTSET, | |
| 634 | 598 | TValue *rb = RB(i); |
| 635 | 599 | if (GETARG_C(i) ? !l_isfalse(rb) : l_isfalse(rb)) { |
| 636 | 600 | setobjs2s(L, ra, rb); |
| 637 | 601 | dojump(GETARG_sBx(*ci->u.l.savedpc)); |
| 638 | 602 | } |
| 639 | 603 | ci->u.l.savedpc++; |
| 640 | − continue; | |
| 641 | − } | |
| 642 | − case OP_CALL: { | |
| 604 | + ) | |
| 605 | + vmcase(OP_CALL, | |
| 643 | 606 | int b = GETARG_B(i); |
| 644 | 607 | int nresults = GETARG_C(i) - 1; |
| 645 | 608 | if (b != 0) L->top = ra+b; /* else previous instruction set top */ |
| 646 | 609 | if (luaD_precall(L, ra, nresults)) { /* C function? */ |
| 647 | 610 | if (nresults >= 0) L->top = ci->top; /* adjust results */ |
| 648 | 611 | base = ci->u.l.base; |
| 649 | − continue; | |
| 650 | 612 | } |
| 651 | 613 | else { /* Lua function */ |
| 652 | 614 | ci = L->ci; |
| 653 | 615 | ci->callstatus |= CIST_REENTRY; |
| 654 | − break; /* restart luaV_execute over new Lua function */ | |
| 616 | + goto newframe; /* restart luaV_execute over new Lua function */ | |
| 655 | 617 | } |
| 656 | − } | |
| 657 | − case OP_TAILCALL: { | |
| 618 | + ) | |
| 619 | + vmcase(OP_TAILCALL, | |
| 658 | 620 | int b = GETARG_B(i); |
| 659 | 621 | if (b != 0) L->top = ra+b; /* else previous instruction set top */ |
| 660 | 622 | lua_assert(GETARG_C(i) - 1 == LUA_MULTRET); |
| 661 | − if (luaD_precall(L, ra, LUA_MULTRET)) { /* C function? */ | |
| 623 | + if (luaD_precall(L, ra, LUA_MULTRET)) /* C function? */ | |
| 662 | 624 | base = ci->u.l.base; |
| 663 | − continue; | |
| 664 | − } | |
| 665 | 625 | else { |
| 666 | 626 | /* tail call: put called frame (n) in place of caller one (o) */ |
| 667 | 627 | CallInfo *nci = L->ci; /* called frame */ |
| @@ -682,10 +642,10 @@ void luaV_execute (lua_State *L) { · 14 unmodified lines | ||
| 682 | 642 | oci->callstatus |= CIST_TAIL; /* function was tail called */ |
| 683 | 643 | ci = L->ci = oci; /* remove new frame */ |
| 684 | 644 | lua_assert(L->top == oci->u.l.base + getproto(ofunc)->maxstacksize); |
| 685 | − break; /* restart luaV_execute over new Lua function */ | |
| 645 | + goto newframe; /* restart luaV_execute over new Lua function */ | |
| 686 | 646 | } |
| 687 | − } | |
| 688 | − case OP_RETURN: { | |
| 647 | + ) | |
| 648 | + vmcase(OP_RETURN, | |
| 689 | 649 | int b = GETARG_B(i); |
| 690 | 650 | if (b != 0) L->top = ra+b-1; |
| 691 | 651 | if (cl->p->sizep > 0) luaF_close(L, base); |
| @@ -697,10 +657,10 @@ void luaV_execute (lua_State *L) { · 5 unmodified lines | ||
| 697 | 657 | if (b) L->top = ci->top; |
| 698 | 658 | lua_assert(isLua(ci)); |
| 699 | 659 | lua_assert(GET_OPCODE(*((ci)->u.l.savedpc - 1)) == OP_CALL); |
| 700 | − break; /* restart luaV_execute over new Lua function */ | |
| 660 | + goto newframe; /* restart luaV_execute over new Lua function */ | |
| 701 | 661 | } |
| 702 | − } | |
| 703 | − case OP_FORLOOP: { | |
| 662 | + ) | |
| 663 | + vmcase(OP_FORLOOP, | |
| 704 | 664 | lua_Number step = nvalue(ra+2); |
| 705 | 665 | lua_Number idx = luai_numadd(L, nvalue(ra), step); /* increment index */ |
| 706 | 666 | lua_Number limit = nvalue(ra+1); |
| @@ -710,9 +670,8 @@ void luaV_execute (lua_State *L) { · 3 unmodified lines | ||
| 710 | 670 | setnvalue(ra, idx); /* update internal index... */ |
| 711 | 671 | setnvalue(ra+3, idx); /* ...and external index */ |
| 712 | 672 | } |
| 713 | − continue; | |
| 714 | − } | |
| 715 | − case OP_FORPREP: { | |
| 673 | + ) | |
| 674 | + vmcase(OP_FORPREP, | |
| 716 | 675 | const TValue *init = ra; |
| 717 | 676 | const TValue *plimit = ra+1; |
| 718 | 677 | const TValue *pstep = ra+2; |
| @@ -724,9 +683,8 @@ void luaV_execute (lua_State *L) { · 5 unmodified lines | ||
| 724 | 683 | luaG_runerror(L, LUA_QL("for") " step must be a number"); |
| 725 | 684 | setnvalue(ra, luai_numsub(L, nvalue(ra), nvalue(pstep))); |
| 726 | 685 | dojump(GETARG_sBx(i)); |
| 727 | − continue; | |
| 728 | − } | |
| 729 | − case OP_TFORCALL: { | |
| 686 | + ) | |
| 687 | + vmcase(OP_TFORCALL, | |
| 730 | 688 | StkId cb = ra + 3; /* call base */ |
| 731 | 689 | setobjs2s(L, cb+2, ra+2); |
| 732 | 690 | setobjs2s(L, cb+1, ra+1); |
| @@ -737,16 +695,16 @@ void luaV_execute (lua_State *L) { · 4 unmodified lines | ||
| 737 | 695 | i = *(ci->u.l.savedpc++); /* go to next instruction */ |
| 738 | 696 | ra = RA(i); |
| 739 | 697 | lua_assert(GET_OPCODE(i) == OP_TFORLOOP); |
| 740 | − /* go through */ | |
| 741 | − } | |
| 742 | − case OP_TFORLOOP: { | |
| 698 | + goto l_tforloop; | |
| 699 | + ) | |
| 700 | + vmcase(OP_TFORLOOP, | |
| 701 | + l_tforloop: | |
| 743 | 702 | if (!ttisnil(ra + 1)) { /* continue loop? */ |
| 744 | 703 | setobjs2s(L, ra, ra + 1); /* save control variable */ |
| 745 | 704 | dojump(GETARG_sBx(i)); /* jump back */ |
| 746 | 705 | } |
| 747 | − continue; | |
| 748 | − } | |
| 749 | − case OP_SETLIST: { | |
| 706 | + ) | |
| 707 | + vmcase(OP_SETLIST, | |
| 750 | 708 | int n = GETARG_B(i); |
| 751 | 709 | int c = GETARG_C(i); |
| 752 | 710 | int last; |
| @@ -759,45 +717,34 @@ void luaV_execute (lua_State *L) { · 6 unmodified lines | ||
| 759 | 717 | h = hvalue(ra); |
| 760 | 718 | last = ((c-1)*LFIELDS_PER_FLUSH) + n; |
| 761 | 719 | if (last > h->sizearray) /* needs more space? */ |
| 762 | − luaH_resizearray(L, h, last); /* pre-alloc it at once */ | |
| 720 | + luaH_resizearray(L, h, last); /* pre-allocate it at once */ | |
| 763 | 721 | for (; n > 0; n--) { |
| 764 | 722 | TValue *val = ra+n; |
| 765 | 723 | setobj2t(L, luaH_setint(L, h, last--), val); |
| 766 | 724 | luaC_barriert(L, h, val); |
| 767 | 725 | } |
| 768 | 726 | L->top = ci->top; /* correct top (in case of previous open call) */ |
| 769 | − continue; | |
| 770 | − } | |
| 771 | − case OP_CLOSE: { | |
| 727 | + ) | |
| 728 | + vmcase(OP_CLOSE, | |
| 772 | 729 | luaF_close(L, ra); |
| 773 | − continue; | |
| 774 | − } | |
| 775 | − case OP_CLOSURE: { | |
| 730 | + ) | |
| 731 | + vmcase(OP_CLOSURE, | |
| 776 | 732 | Proto *p = cl->p->p[GETARG_Bx(i)]; /* prototype for new closure */ |
| 777 | 733 | int nup = p->sizeupvalues; |
| 778 | − Closure *ncl = luaF_newLclosure(L, nup, cl->env); | |
| 734 | + Closure *ncl = luaF_newLclosure(L, nup); | |
| 779 | 735 | Upvaldesc *uv = p->upvalues; |
| 780 | 736 | int j; |
| 781 | 737 | ncl->l.p = p; |
| 782 | 738 | setclvalue(L, ra, ncl); /* anchor new closure in stack */ |
| 783 | − if (p->envreg != NO_REG) { /* lexical environment? */ | |
| 784 | − StkId env = base + p->envreg; | |
| 785 | − if (!ttistable(env)) | |
| 786 | − luaG_runerror(L, "environment is not a table: " | |
| 787 | − "cannot create closure"); | |
| 788 | − else | |
| 789 | − ncl->l.env = hvalue(env); | |
| 790 | − } | |
| 791 | 739 | for (j = 0; j < nup; j++) { /* fill in upvalues */ |
| 792 | 740 | if (uv[j].instack) /* upvalue refers to local variable? */ |
| 793 | 741 | ncl->l.upvals[j] = luaF_findupval(L, base + uv[j].idx); |
| 794 | 742 | else /* get upvalue from enclosing function */ |
| 795 | 743 | ncl->l.upvals[j] = cl->upvals[uv[j].idx]; |
| 796 | 744 | } |
| 797 | − Protect(luaC_checkGC(L)); | |
| 798 | − continue; | |
| 799 | − } | |
| 800 | − case OP_VARARG: { | |
| 745 | + checkGC(L); | |
| 746 | + ) | |
| 747 | + vmcase(OP_VARARG, | |
| 801 | 748 | int b = GETARG_B(i) - 1; |
| 802 | 749 | int j; |
| 803 | 750 | int n = cast_int(base - ci->func) - cl->p->numparams - 1; |
| @@ -815,18 +762,11 @@ void luaV_execute (lua_State *L) { · 11 unmodified lines | ||
| 815 | 762 | setnilvalue(ra + j); |
| 816 | 763 | } |
| 817 | 764 | } |
| 818 | − continue; | |
| 819 | − } | |
| 820 | − case OP_EXTRAARG: { | |
| 821 | − luaG_runerror(L, "bad opcode"); | |
| 822 | − return; | |
| 823 | − } | |
| 765 | + ) | |
| 766 | + vmcase(OP_EXTRAARG, | |
| 767 | + lua_assert(0); | |
| 768 | + ) | |
| 824 | 769 | } |
| 825 | − /* function changed (call/return): update pointers */ | |
| 826 | − lua_assert(ci == L->ci); | |
| 827 | − cl = &clvalue(ci->func)->l; | |
| 828 | − k = cl->p->k; | |
| 829 | − base = ci->u.l.base; | |
| 830 | 770 | } |
| 831 | 771 | } |
| 832 | 772 | |
| @@ -1,5 +1,5 @@ | ||
| 1 | 1 | /* |
| 2 | −** $Id: print.c,v 1.58 2008/09/11 12:05:06 lhf Exp $ | |
| 2 | +** $Id: print.c,v 1.60 2010/05/17 22:27:10 lhf Exp $ | |
| 3 | 3 | ** print bytecodes |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| @@ -82,6 +82,7 @@ static void PrintCode(const Proto* f) · 76 unmodified lines | ||
| 82 | 82 | int a=GETARG_A(i); |
| 83 | 83 | int b=GETARG_B(i); |
| 84 | 84 | int c=GETARG_C(i); |
| 85 | + int ax=GETARG_Ax(i); | |
| 85 | 86 | int bx=GETARG_Bx(i); |
| 86 | 87 | int sbx=GETARG_sBx(i); |
| 87 | 88 | int line=getfuncline(f,pc); |
| @@ -99,24 +100,32 @@ static void PrintCode(const Proto* f) · 11 unmodified lines | ||
| 99 | 100 | if (getCMode(o)!=OpArgN) printf(" %d",ISK(c) ? (-1-INDEXK(c)) : c); |
| 100 | 101 | break; |
| 101 | 102 | case iABx: |
| 102 | − if (getBMode(o)==OpArgK) printf("%d %d",a,-1-bx); else printf("%d %d",a,bx); | |
| 103 | + if (getBMode(o)==OpArgK) printf("%d %d",a,-bx); else printf("%d %d",a,bx); | |
| 103 | 104 | break; |
| 104 | 105 | case iAsBx: |
| 105 | 106 | if (o==OP_JMP) printf("%d",sbx); else printf("%d %d",a,sbx); |
| 106 | 107 | break; |
| 108 | + case iAx: | |
| 109 | + printf("%d",ax); | |
| 110 | + break; | |
| 107 | 111 | } |
| 108 | 112 | switch (o) |
| 109 | 113 | { |
| 110 | 114 | case OP_LOADK: |
| 111 | − printf("\t; "); PrintConstant(f,bx); | |
| 115 | + printf("\t; "); PrintConstant(f,bx-1); | |
| 112 | 116 | break; |
| 113 | 117 | case OP_GETUPVAL: |
| 114 | 118 | case OP_SETUPVAL: |
| 115 | 119 | printf("\t; %s", (f->sizeupvalues>0) ? getstr(f->upvalues[b].name) : "-"); |
| 116 | 120 | break; |
| 117 | − case OP_GETGLOBAL: | |
| 118 | − case OP_SETGLOBAL: | |
| 119 | − printf("\t; %s",svalue(&f->k[bx])); | |
| 121 | + case OP_GETTABUP: | |
| 122 | + printf("\t; %s", (f->sizeupvalues>0) ? getstr(f->upvalues[b].name) : "-"); | |
| 123 | + if (ISK(c)) { printf(" "); PrintConstant(f,INDEXK(c)); } | |
| 124 | + break; | |
| 125 | + case OP_SETTABUP: | |
| 126 | + printf("\t; %s", (f->sizeupvalues>0) ? getstr(f->upvalues[a].name) : "-"); | |
| 127 | + if (ISK(b)) { printf(" "); PrintConstant(f,INDEXK(b)); } | |
| 128 | + if (ISK(c)) { printf(" "); PrintConstant(f,INDEXK(c)); } | |
| 120 | 129 | break; |
| 121 | 130 | case OP_GETTABLE: |
| 122 | 131 | case OP_SELF: |
| @@ -1,26 +0,0 @@ | ||
| 1 | −function run(x) | |
| 2 | − print("\n-------------------------------------------------------------") | |
| 3 | − print(x) | |
| 4 | − os.execute("../src/lua "..x) | |
| 5 | − print("DONE",x) | |
| 6 | −end | |
| 7 | − | |
| 8 | −run"bisect.lua" | |
| 9 | −run"cf.lua" | |
| 10 | −run"echo.lua jan feb mar apr may jun jul aug sep oct nov dec" | |
| 11 | −run"env.lua" | |
| 12 | −run"factorial.lua" | |
| 13 | −run"fib.lua" | |
| 14 | −run"fibfor.lua" | |
| 15 | −--run"globals.lua" | |
| 16 | −run"hello.lua" | |
| 17 | −run"luac.lua" | |
| 18 | −run"printf.lua" | |
| 19 | −run"readonly.lua" | |
| 20 | −run"sieve.lua" | |
| 21 | −run"sort.lua" | |
| 22 | −run"table.lua" | |
| 23 | −run"trace-calls.lua" | |
| 24 | −run"trace-globals.lua" | |
| 25 | −run"xd.lua < hello.lua" | |
| 26 | −run"life.lua" | |
| @@ -1,26 +0,0 @@ | ||
| 1 | −These are simple tests for Lua. Some of them contain useful code. | |
| 2 | −They are meant to be run to make sure Lua is built correctly and also | |
| 3 | −to be read, to see how Lua programs look. | |
| 4 | − | |
| 5 | −Here is a one-line summary of each program: | |
| 6 | − | |
| 7 | − bisect.lua bisection method for solving non-linear equations | |
| 8 | − cf.lua temperature conversion table (celsius to farenheit) | |
| 9 | − echo.lua echo command line arguments | |
| 10 | − env.lua environment variables as automatic global variables | |
| 11 | − factorial.lua factorial without recursion | |
| 12 | − fib.lua fibonacci function with cache | |
| 13 | − fibfor.lua fibonacci numbers with coroutines and generators | |
| 14 | − globals.lua report global variable usage | |
| 15 | − hello.lua the first program in every language | |
| 16 | − life.lua Conway's Game of Life | |
| 17 | − luac.lua bare-bones luac | |
| 18 | − printf.lua an implementation of printf | |
| 19 | − readonly.lua make global variables readonly | |
| 20 | − sieve.lua the sieve of of Eratosthenes programmed with coroutines | |
| 21 | − sort.lua two implementations of a sort function | |
| 22 | − table.lua make table, grouping all data for the same item | |
| 23 | − trace-calls.lua trace calls | |
| 24 | − trace-globals.lua trace assigments to global variables | |
| 25 | − xd.lua hex dump | |
| 26 | − | |
| @@ -1,27 +0,0 @@ | ||
| 1 | −-- bisection method for solving non-linear equations | |
| 2 | − | |
| 3 | −delta=1e-6 -- tolerance | |
| 4 | − | |
| 5 | −function bisect(f,a,b,fa,fb) | |
| 6 | − local c=(a+b)/2 | |
| 7 | − io.write(n," c=",c," a=",a," b=",b,"\n") | |
| 8 | − if c==a or c==b or math.abs(a-b)<delta then return c,b-a end | |
| 9 | − n=n+1 | |
| 10 | − local fc=f(c) | |
| 11 | − if fa*fc<0 then return bisect(f,a,c,fa,fc) else return bisect(f,c,b,fc,fb) end | |
| 12 | −end | |
| 13 | − | |
| 14 | −-- find root of f in the inverval [a,b]. needs f(a)*f(b)<0 | |
| 15 | −function solve(f,a,b) | |
| 16 | − n=0 | |
| 17 | − local z,e=bisect(f,a,b,f(a),f(b)) | |
| 18 | − io.write(string.format("after %d steps, root is %.17g with error %.1e, f=%.1e\n",n,z,e,f(z))) | |
| 19 | −end | |
| 20 | − | |
| 21 | −-- our function | |
| 22 | −function f(x) | |
| 23 | − return x*x*x-x-1 | |
| 24 | −end | |
| 25 | − | |
| 26 | −-- find zero in [1,2] | |
| 27 | −solve(f,1,2) | |
| @@ -1,16 +0,0 @@ | ||
| 1 | −-- temperature conversion table (celsius to farenheit) | |
| 2 | − | |
| 3 | −for c0=-20,50-1,10 do | |
| 4 | − io.write("C ") | |
| 5 | − for c=c0,c0+10-1 do | |
| 6 | − io.write(string.format("%3.0f ",c)) | |
| 7 | − end | |
| 8 | − io.write("\n") | |
| 9 | − | |
| 10 | − io.write("F ") | |
| 11 | − for c=c0,c0+10-1 do | |
| 12 | − f=(9/5)*c+32 | |
| 13 | − io.write(string.format("%3.0f ",f)) | |
| 14 | − end | |
| 15 | − io.write("\n\n") | |
| 16 | −end | |
| @@ -1,5 +0,0 @@ | ||
| 1 | −-- echo command line arguments | |
| 2 | − | |
| 3 | −for i=0,table.getn(arg) do | |
| 4 | − print(i,arg[i]) | |
| 5 | −end | |
| @@ -1,7 +0,0 @@ | ||
| 1 | −-- read environment variables as if they were global variables | |
| 2 | − | |
| 3 | −local f=function (t,i) return os.getenv(i) end | |
| 4 | −setmetatable(getfenv(),{__index=f}) | |
| 5 | − | |
| 6 | −-- an example | |
| 7 | −print(a,USER,PATH) | |
| @@ -1,32 +0,0 @@ | ||
| 1 | −-- function closures are powerful | |
| 2 | − | |
| 3 | −-- traditional fixed-point operator from functional programming | |
| 4 | −Y = function (g) | |
| 5 | − local a = function (f) return f(f) end | |
| 6 | − return a(function (f) | |
| 7 | − return g(function (x) | |
| 8 | − local c=f(f) | |
| 9 | − return c(x) | |
| 10 | − end) | |
| 11 | − end) | |
| 12 | −end | |
| 13 | − | |
| 14 | − | |
| 15 | −-- factorial without recursion | |
| 16 | −F = function (f) | |
| 17 | − return function (n) | |
| 18 | − if n == 0 then return 1 | |
| 19 | − else return n*f(n-1) end | |
| 20 | − end | |
| 21 | − end | |
| 22 | − | |
| 23 | −factorial = Y(F) -- factorial is the fixed point of F | |
| 24 | − | |
| 25 | −-- now test it | |
| 26 | −function test(x) | |
| 27 | − io.write(x,"! = ",factorial(x),"\n") | |
| 28 | −end | |
| 29 | − | |
| 30 | −for n=0,16 do | |
| 31 | − test(n) | |
| 32 | −end | |
| @@ -1,40 +0,0 @@ | ||
| 1 | −-- fibonacci function with cache | |
| 2 | − | |
| 3 | −-- very inefficient fibonacci function | |
| 4 | −function fib(n) | |
| 5 | − N=N+1 | |
| 6 | − if n<2 then | |
| 7 | − return n | |
| 8 | − else | |
| 9 | − return fib(n-1)+fib(n-2) | |
| 10 | − end | |
| 11 | −end | |
| 12 | − | |
| 13 | −-- a general-purpose value cache | |
| 14 | −function cache(f) | |
| 15 | − local c={} | |
| 16 | − return function (x) | |
| 17 | − local y=c[x] | |
| 18 | − if not y then | |
| 19 | − y=f(x) | |
| 20 | − c[x]=y | |
| 21 | − end | |
| 22 | − return y | |
| 23 | − end | |
| 24 | −end | |
| 25 | − | |
| 26 | −-- run and time it | |
| 27 | −function test(s,f) | |
| 28 | − N=0 | |
| 29 | − local c=os.clock() | |
| 30 | − local v=f(n) | |
| 31 | − local t=os.clock()-c | |
| 32 | − print(s,n,v,t,N) | |
| 33 | −end | |
| 34 | − | |
| 35 | −n=arg[1] or 24 -- for other values, do lua fib.lua XX | |
| 36 | −n=tonumber(n) | |
| 37 | −print("","n","value","time","evals") | |
| 38 | −test("plain",fib) | |
| 39 | −fib=cache(fib) | |
| 40 | −test("cached",fib) | |
| @@ -1,13 +0,0 @@ | ||
| 1 | −-- example of for with generator functions | |
| 2 | − | |
| 3 | −function generatefib (n) | |
| 4 | − return coroutine.wrap(function () | |
| 5 | − local a,b = 1, 1 | |
| 6 | − while a <= n do | |
| 7 | − coroutine.yield(a) | |
| 8 | − a, b = b, a+b | |
| 9 | − end | |
| 10 | − end) | |
| 11 | −end | |
| 12 | − | |
| 13 | −for i in generatefib(1000) do print(i) end | |
| @@ -1,13 +0,0 @@ | ||
| 1 | −-- reads luac listings and reports global variable usage | |
| 2 | −-- lines where a global is written to are marked with "*" | |
| 3 | −-- typical usage: luac -p -l file.lua | lua globals.lua | sort | lua table.lua | |
| 4 | − | |
| 5 | −while 1 do | |
| 6 | − local s=io.read() | |
| 7 | − if s==nil then break end | |
| 8 | − local ok,_,l,op,g=string.find(s,"%[%-?(%d*)%]%s*([GS])ETGLOBAL.-;%s+(.*)$") | |
| 9 | − if ok then | |
| 10 | − if op=="S" then op="*" else op="" end | |
| 11 | − io.write(g,"\t",l,op,"\n") | |
| 12 | − end | |
| 13 | −end | |
| @@ -1,111 +0,0 @@ | ||
| 1 | −-- life.lua | |
| 2 | −-- original by Dave Bollinger <DBollinger@compuserve.com> posted to lua-l | |
| 3 | −-- modified to use ANSI terminal escape sequences | |
| 4 | −-- modified to use for instead of while | |
| 5 | − | |
| 6 | −local write=io.write | |
| 7 | − | |
| 8 | −ALIVE="�" DEAD="�" | |
| 9 | −ALIVE="O" DEAD="-" | |
| 10 | − | |
| 11 | −function delay() -- NOTE: SYSTEM-DEPENDENT, adjust as necessary | |
| 12 | − for i=1,10000 do end | |
| 13 | − -- local i=os.clock()+1 while(os.clock()<i) do end | |
| 14 | −end | |
| 15 | − | |
| 16 | −function ARRAY2D(w,h) | |
| 17 | − local t = {w=w,h=h} | |
| 18 | − for y=1,h do | |
| 19 | − t[y] = {} | |
| 20 | − for x=1,w do | |
| 21 | − t[y][x]=0 | |
| 22 | − end | |
| 23 | − end | |
| 24 | − return t | |
| 25 | −end | |
| 26 | − | |
| 27 | −_CELLS = {} | |
| 28 | − | |
| 29 | −-- give birth to a "shape" within the cell array | |
| 30 | −function _CELLS:spawn(shape,left,top) | |
| 31 | − for y=0,shape.h-1 do | |
| 32 | − for x=0,shape.w-1 do | |
| 33 | − self[top+y][left+x] = shape[y*shape.w+x+1] | |
| 34 | − end | |
| 35 | − end | |
| 36 | −end | |
| 37 | − | |
| 38 | −-- run the CA and produce the next generation | |
| 39 | −function _CELLS:evolve(next) | |
| 40 | − local ym1,y,yp1,yi=self.h-1,self.h,1,self.h | |
| 41 | − while yi > 0 do | |
| 42 | − local xm1,x,xp1,xi=self.w-1,self.w,1,self.w | |
| 43 | − while xi > 0 do | |
| 44 | − local sum = self[ym1][xm1] + self[ym1][x] + self[ym1][xp1] + | |
| 45 | − self[y][xm1] + self[y][xp1] + | |
| 46 | − self[yp1][xm1] + self[yp1][x] + self[yp1][xp1] | |
| 47 | − next[y][x] = ((sum==2) and self[y][x]) or ((sum==3) and 1) or 0 | |
| 48 | − xm1,x,xp1,xi = x,xp1,xp1+1,xi-1 | |
| 49 | − end | |
| 50 | − ym1,y,yp1,yi = y,yp1,yp1+1,yi-1 | |
| 51 | − end | |
| 52 | −end | |
| 53 | − | |
| 54 | −-- output the array to screen | |
| 55 | −function _CELLS:draw() | |
| 56 | − local out="" -- accumulate to reduce flicker | |
| 57 | − for y=1,self.h do | |
| 58 | − for x=1,self.w do | |
| 59 | − out=out..(((self[y][x]>0) and ALIVE) or DEAD) | |
| 60 | − end | |
| 61 | − out=out.."\n" | |
| 62 | − end | |
| 63 | − write(out) | |
| 64 | −end | |
| 65 | − | |
| 66 | −-- constructor | |
| 67 | −function CELLS(w,h) | |
| 68 | − local c = ARRAY2D(w,h) | |
| 69 | − c.spawn = _CELLS.spawn | |
| 70 | − c.evolve = _CELLS.evolve | |
| 71 | − c.draw = _CELLS.draw | |
| 72 | − return c | |
| 73 | −end | |
| 74 | − | |
| 75 | −-- | |
| 76 | −-- shapes suitable for use with spawn() above | |
| 77 | −-- | |
| 78 | −HEART = { 1,0,1,1,0,1,1,1,1; w=3,h=3 } | |
| 79 | −GLIDER = { 0,0,1,1,0,1,0,1,1; w=3,h=3 } | |
| 80 | −EXPLODE = { 0,1,0,1,1,1,1,0,1,0,1,0; w=3,h=4 } | |
| 81 | −FISH = { 0,1,1,1,1,1,0,0,0,1,0,0,0,0,1,1,0,0,1,0; w=5,h=4 } | |
| 82 | −BUTTERFLY = { 1,0,0,0,1,0,1,1,1,0,1,0,0,0,1,1,0,1,0,1,1,0,0,0,1; w=5,h=5 } | |
| 83 | − | |
| 84 | −-- the main routine | |
| 85 | −function LIFE(w,h) | |
| 86 | − -- create two arrays | |
| 87 | − local thisgen = CELLS(w,h) | |
| 88 | − local nextgen = CELLS(w,h) | |
| 89 | − | |
| 90 | − -- create some life | |
| 91 | − -- about 1000 generations of fun, then a glider steady-state | |
| 92 | − thisgen:spawn(GLIDER,5,4) | |
| 93 | − thisgen:spawn(EXPLODE,25,10) | |
| 94 | − thisgen:spawn(FISH,4,12) | |
| 95 | − | |
| 96 | − -- run until break | |
| 97 | − local gen=1 | |
| 98 | − write("\027[2J") -- ANSI clear screen | |
| 99 | − while 1 do | |
| 100 | − thisgen:evolve(nextgen) | |
| 101 | − thisgen,nextgen = nextgen,thisgen | |
| 102 | − write("\027[H") -- ANSI home cursor | |
| 103 | − thisgen:draw() | |
| 104 | − write("Life - generation ",gen,"\n") | |
| 105 | − gen=gen+1 | |
| 106 | − if gen>2000 then break end | |
| 107 | − --delay() -- no delay | |
| 108 | − end | |
| 109 | −end | |
| 110 | − | |
| 111 | −LIFE(40,20) | |
| @@ -1,7 +0,0 @@ | ||
| 1 | −-- bare-bones luac in Lua | |
| 2 | −-- usage: lua luac.lua file.lua | |
| 3 | − | |
| 4 | −assert(arg[1]~=nil and arg[2]==nil,"usage: lua luac.lua file.lua") | |
| 5 | −f=assert(io.open("luac.out","wb")) | |
| 6 | −assert(f:write(string.dump(assert(loadfile(arg[1]))))) | |
| 7 | −assert(f:close()) | |
| @@ -1,7 +0,0 @@ | ||
| 1 | −-- an implementation of printf | |
| 2 | − | |
| 3 | −function printf(...) | |
| 4 | − io.write(string.format(...)) | |
| 5 | −end | |
| 6 | − | |
| 7 | −printf("Hello %s from %s on %s\n",os.getenv"USER" or "there",_VERSION,os.date()) | |
| @@ -1,12 +0,0 @@ | ||
| 1 | −-- make global variables readonly | |
| 2 | − | |
| 3 | −local f=function (t,i) error("cannot redefine global variable `"..i.."'",2) end | |
| 4 | −local g={} | |
| 5 | −local G=getfenv() | |
| 6 | −setmetatable(g,{__index=G,__newindex=f}) | |
| 7 | −setfenv(1,g) | |
| 8 | − | |
| 9 | −-- an example | |
| 10 | −rawset(g,"x",3) | |
| 11 | −x=2 | |
| 12 | −y=1 -- cannot redefine `y' | |
| @@ -1,29 +0,0 @@ | ||
| 1 | −-- the sieve of of Eratosthenes programmed with coroutines | |
| 2 | −-- typical usage: lua -e N=1000 sieve.lua | column | |
| 3 | − | |
| 4 | −-- generate all the numbers from 2 to n | |
| 5 | −function gen (n) | |
| 6 | − return coroutine.wrap(function () | |
| 7 | − for i=2,n do coroutine.yield(i) end | |
| 8 | − end) | |
| 9 | −end | |
| 10 | − | |
| 11 | −-- filter the numbers generated by `g', removing multiples of `p' | |
| 12 | −function filter (p, g) | |
| 13 | − return coroutine.wrap(function () | |
| 14 | − while 1 do | |
| 15 | − local n = g() | |
| 16 | − if n == nil then return end | |
| 17 | − if n % p ~= 0 then coroutine.yield(n) end | |
| 18 | − end | |
| 19 | − end) | |
| 20 | −end | |
| 21 | − | |
| 22 | −N=N or 1000 -- from command line | |
| 23 | −x = gen(N) -- generate primes up to N | |
| 24 | −while 1 do | |
| 25 | − local n = x() -- pick a number until done | |
| 26 | − if n == nil then break end | |
| 27 | − print(n) -- must be a prime number | |
| 28 | − x = filter(n, x) -- now remove its multiples | |
| 29 | −end | |
| @@ -1,66 +0,0 @@ | ||
| 1 | −-- two implementations of a sort function | |
| 2 | −-- this is an example only. Lua has now a built-in function "sort" | |
| 3 | − | |
| 4 | −-- extracted from Programming Pearls, page 110 | |
| 5 | −function qsort(x,l,u,f) | |
| 6 | − if l<u then | |
| 7 | − local m=math.random(u-(l-1))+l-1 -- choose a random pivot in range l..u | |
| 8 | − x[l],x[m]=x[m],x[l] -- swap pivot to first position | |
| 9 | − local t=x[l] -- pivot value | |
| 10 | − m=l | |
| 11 | − local i=l+1 | |
| 12 | − while i<=u do | |
| 13 | − -- invariant: x[l+1..m] < t <= x[m+1..i-1] | |
| 14 | − if f(x[i],t) then | |
| 15 | − m=m+1 | |
| 16 | − x[m],x[i]=x[i],x[m] -- swap x[i] and x[m] | |
| 17 | − end | |
| 18 | − i=i+1 | |
| 19 | − end | |
| 20 | − x[l],x[m]=x[m],x[l] -- swap pivot to a valid place | |
| 21 | − -- x[l+1..m-1] < x[m] <= x[m+1..u] | |
| 22 | − qsort(x,l,m-1,f) | |
| 23 | − qsort(x,m+1,u,f) | |
| 24 | − end | |
| 25 | −end | |
| 26 | − | |
| 27 | −function selectionsort(x,n,f) | |
| 28 | − local i=1 | |
| 29 | − while i<=n do | |
| 30 | − local m,j=i,i+1 | |
| 31 | − while j<=n do | |
| 32 | − if f(x[j],x[m]) then m=j end | |
| 33 | − j=j+1 | |
| 34 | − end | |
| 35 | − x[i],x[m]=x[m],x[i] -- swap x[i] and x[m] | |
| 36 | − i=i+1 | |
| 37 | − end | |
| 38 | −end | |
| 39 | − | |
| 40 | −function show(m,x) | |
| 41 | − io.write(m,"\n\t") | |
| 42 | − local i=1 | |
| 43 | − while x[i] do | |
| 44 | − io.write(x[i]) | |
| 45 | − i=i+1 | |
| 46 | − if x[i] then io.write(",") end | |
| 47 | − end | |
| 48 | − io.write("\n") | |
| 49 | −end | |
| 50 | − | |
| 51 | −function testsorts(x) | |
| 52 | − local n=1 | |
| 53 | − while x[n] do n=n+1 end; n=n-1 -- count elements | |
| 54 | − show("original",x) | |
| 55 | − qsort(x,1,n,function (x,y) return x<y end) | |
| 56 | − show("after quicksort",x) | |
| 57 | − selectionsort(x,n,function (x,y) return x>y end) | |
| 58 | − show("after reverse selection sort",x) | |
| 59 | − qsort(x,1,n,function (x,y) return x<y end) | |
| 60 | − show("after quicksort again",x) | |
| 61 | −end | |
| 62 | − | |
| 63 | −-- array to be sorted | |
| 64 | −x={"Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"} | |
| 65 | − | |
| 66 | −testsorts(x) | |
| @@ -1,12 +0,0 @@ | ||
| 1 | −-- make table, grouping all data for the same item | |
| 2 | −-- input is 2 columns (item, data) | |
| 3 | − | |
| 4 | −local A | |
| 5 | −while 1 do | |
| 6 | − local l=io.read() | |
| 7 | − if l==nil then break end | |
| 8 | − local _,_,a,b=string.find(l,'"?([_%w]+)"?%s*(.*)$') | |
| 9 | − if a~=A then A=a io.write("\n",a,":") end | |
| 10 | − io.write(" ",b) | |
| 11 | −end | |
| 12 | −io.write("\n") | |
| @@ -1,32 +0,0 @@ | ||
| 1 | −-- trace calls | |
| 2 | −-- example: lua -ltrace-calls bisect.lua | |
| 3 | − | |
| 4 | −local level=0 | |
| 5 | − | |
| 6 | −local function hook(event) | |
| 7 | − local t=debug.getinfo(3) | |
| 8 | − io.write(level," >>> ",string.rep(" ",level)) | |
| 9 | − if t~=nil and t.currentline>=0 then io.write(t.short_src,":",t.currentline," ") end | |
| 10 | − t=debug.getinfo(2) | |
| 11 | − if event=="call" then | |
| 12 | − level=level+1 | |
| 13 | − else | |
| 14 | − level=level-1 if level<0 then level=0 end | |
| 15 | − end | |
| 16 | − if t.what=="main" then | |
| 17 | − if event=="call" then | |
| 18 | − io.write("begin ",t.short_src) | |
| 19 | − else | |
| 20 | − io.write("end ",t.short_src) | |
| 21 | − end | |
| 22 | − elseif t.what=="Lua" then | |
| 23 | −-- table.foreach(t,print) | |
| 24 | − io.write(event," ",t.name or "(Lua)"," <",t.linedefined,":",t.short_src,">") | |
| 25 | − else | |
| 26 | − io.write(event," ",t.name or "(C)"," [",t.what,"] ") | |
| 27 | − end | |
| 28 | − io.write("\n") | |
| 29 | −end | |
| 30 | − | |
| 31 | −debug.sethook(hook,"cr") | |
| 32 | −level=0 | |
| @@ -1,38 +0,0 @@ | ||
| 1 | −-- trace assigments to global variables | |
| 2 | − | |
| 3 | −do | |
| 4 | − -- a tostring that quotes strings. note the use of the original tostring. | |
| 5 | − local _tostring=tostring | |
| 6 | − local tostring=function(a) | |
| 7 | − if type(a)=="string" then | |
| 8 | − return string.format("%q",a) | |
| 9 | − else | |
| 10 | − return _tostring(a) | |
| 11 | − end | |
| 12 | − end | |
| 13 | − | |
| 14 | − local log=function (name,old,new) | |
| 15 | − local t=debug.getinfo(3,"Sl") | |
| 16 | − local line=t.currentline | |
| 17 | − io.write(t.short_src) | |
| 18 | − if line>=0 then io.write(":",line) end | |
| 19 | − io.write(": ",name," is now ",tostring(new)," (was ",tostring(old),")","\n") | |
| 20 | − end | |
| 21 | − | |
| 22 | − local g={} | |
| 23 | − local set=function (t,name,value) | |
| 24 | − log(name,g[name],value) | |
| 25 | − g[name]=value | |
| 26 | − end | |
| 27 | − setmetatable(getfenv(),{__index=g,__newindex=set}) | |
| 28 | −end | |
| 29 | − | |
| 30 | −-- an example | |
| 31 | − | |
| 32 | −a=1 | |
| 33 | −b=2 | |
| 34 | −a=10 | |
| 35 | −b=20 | |
| 36 | −b=nil | |
| 37 | −b=200 | |
| 38 | −print(a,b,c) | |
| @@ -1,15 +0,0 @@ | ||
| 1 | −-- hex dump | |
| 2 | −-- usage: lua xd.lua < file | |
| 3 | − | |
| 4 | −local N=16 | |
| 5 | −local offset=0 | |
| 6 | −while true do | |
| 7 | − local s=io.read(N) | |
| 8 | − if s==nil then return end | |
| 9 | − io.write(string.format("%08X ",offset)) | |
| 10 | − string.gsub(s,"(.)", | |
| 11 | − function (c) io.write(string.format("%02X ",string.byte(c))) end) | |
| 12 | − io.write(string.rep(" ",3*(N-string.len(s)))) | |
| 13 | − io.write(" ",string.gsub(s,"%c","."),"\n") | |
| 14 | − offset=offset+N | |
| 15 | −end | |