Unified · Split
| @@ -81,7 +81,7 @@ none: · 80 unmodified lines | |||
| 81 | @echo " $(PLATS)" | 81 | @echo " $(PLATS)" |
| 82 | @echo "See doc/readme.html for complete instructions." | 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 | dummy: | 85 | dummy: |
| 86 | 86 | ||
| 87 | # echo config parameters | 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 | For information about Lua, including installation instructions and | 3 | For information about Lua, including installation instructions and |
| 4 | license details, see doc/readme.html. | 4 | license details, see doc/readme.html. |
Binary file not shown.
| @@ -20,6 +20,11 @@ ul { · 19 unmodified lines | |||
| 20 | Lua 5.2 Reference Manual | 20 | Lua 5.2 Reference Manual |
| 21 | </H1> | 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 | The reference manual is the official definition of the Lua language. | 28 | The reference manual is the official definition of the Lua language. |
| 24 | For a complete introduction to Lua programming, see the book | 29 | For a complete introduction to Lua programming, see the book |
| 25 | <A HREF="http://www.lua.org/docs.html#books">Programming in Lua</A>. | 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 | <UL style="padding: 0"> | 47 | <UL style="padding: 0"> |
| 43 | <LI><A HREF="manual.html">1 - Introduction</A> | 48 | <LI><A HREF="manual.html">1 - Introduction</A> |
| 44 | <P> | 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 | <UL> | 51 | <UL> |
| 47 | <LI><A HREF="manual.html#2.1">2.1 - Lexical Conventions</A> | 52 | <LI><A HREF="manual.html#2.1">2.1 - Values and Types</A> |
| 48 | <LI><A HREF="manual.html#2.2">2.2 - 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 | <UL> | 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 | </UL> | 60 | </UL> |
| 52 | <LI><A HREF="manual.html#2.3">2.3 - Variables</A> | 61 | <LI><A HREF="manual.html#2.6">2.6 - Coroutines</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> | ||
| 63 | </UL> | 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 | <UL> | 69 | <UL> |
| 66 | <LI><A HREF="manual.html#2.5.1">2.5.1 - Arithmetic Operators</A> | 70 | <LI><A HREF="manual.html#3.3.1">3.3.1 - Chunks</A> |
| 67 | <LI><A HREF="manual.html#2.5.2">2.5.2 - Relational Operators</A> | 71 | <LI><A HREF="manual.html#3.3.2">3.3.2 - Blocks</A> |
| 68 | <LI><A HREF="manual.html#2.5.3">2.5.3 - Logical Operators</A> | 72 | <LI><A HREF="manual.html#3.3.3">3.3.3 - Assignment</A> |
| 69 | <LI><A HREF="manual.html#2.5.4">2.5.4 - Concatenation</A> | 73 | <LI><A HREF="manual.html#3.3.4">3.3.4 - Control Structures</A> |
| 70 | <LI><A HREF="manual.html#2.5.5">2.5.5 - The Length Operator</A> | 74 | <LI><A HREF="manual.html#3.3.5">3.3.5 - For Statement</A> |
| 71 | <LI><A HREF="manual.html#2.5.6">2.5.6 - Precedence</A> | 75 | <LI><A HREF="manual.html#3.3.6">3.3.6 - Function Calls as Statements</A> |
| 72 | <LI><A HREF="manual.html#2.5.7">2.5.7 - Table Constructors</A> | 76 | <LI><A HREF="manual.html#3.3.7">3.3.7 - Local Declarations</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> | ||
| 75 | </UL> | 77 | </UL> |
| 76 | <LI><A HREF="manual.html#2.6">2.6 - Visibility Rules</A> | 78 | <LI><A HREF="manual.html#3.4">3.4 - Expressions</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> | ||
| 81 | <UL> | 79 | <UL> |
| 82 | <LI><A HREF="manual.html#2.10.1">2.10.1 - Garbage-Collection Metamethods</A> | 80 | <LI><A HREF="manual.html#3.4.1">3.4.1 - Arithmetic Operators</A> |
| 83 | <LI><A HREF="manual.html#2.10.2">2.10.2 - Weak Tables</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 | </UL> | 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 | </UL> | 92 | </UL> |
| 87 | <P> | 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 | <UL> | 95 | <UL> |
| 90 | <LI><A HREF="manual.html#3.1">3.1 - The Stack</A> | 96 | <LI><A HREF="manual.html#4.1">4.1 - The Stack</A> |
| 91 | <LI><A HREF="manual.html#3.2">3.2 - Stack Size</A> | 97 | <LI><A HREF="manual.html#4.2">4.2 - Stack Size</A> |
| 92 | <LI><A HREF="manual.html#3.3">3.3 - Pseudo-Indices</A> | 98 | <LI><A HREF="manual.html#4.3">4.3 - Pseudo-Indices</A> |
| 93 | <LI><A HREF="manual.html#3.4">3.4 - C Closures</A> | 99 | <LI><A HREF="manual.html#4.4">4.4 - C Closures</A> |
| 94 | <LI><A HREF="manual.html#3.5">3.5 - Registry</A> | 100 | <LI><A HREF="manual.html#4.5">4.5 - Registry</A> |
| 95 | <LI><A HREF="manual.html#3.6">3.6 - Error Handling in C</A> | 101 | <LI><A HREF="manual.html#4.6">4.6 - Error Handling in C</A> |
| 96 | <LI><A HREF="manual.html#3.7">3.7 - Handling Yields in C</A> | 102 | <LI><A HREF="manual.html#4.7">4.7 - Handling Yields in C</A> |
| 97 | <LI><A HREF="manual.html#3.8">3.8 - Functions and Types</A> | 103 | <LI><A HREF="manual.html#4.8">4.8 - Functions and Types</A> |
| 98 | <LI><A HREF="manual.html#3.9">3.9 - The Debug Interface</A> | 104 | <LI><A HREF="manual.html#4.9">4.9 - The Debug Interface</A> |
| 99 | </UL> | 105 | </UL> |
| 100 | <P> | 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 | <UL> | 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 | </UL> | 110 | </UL> |
| 105 | <P> | 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 | <UL> | 113 | <UL> |
| 108 | <LI><A HREF="manual.html#5.1">5.1 - Basic Functions</A> | 114 | <LI><A HREF="manual.html#6.1">6.1 - Basic Functions</A> |
| 109 | <LI><A HREF="manual.html#5.2">5.2 - Coroutine Manipulation</A> | 115 | <LI><A HREF="manual.html#6.2">6.2 - Coroutine Manipulation</A> |
| 110 | <LI><A HREF="manual.html#5.3">5.3 - Modules</A> | 116 | <LI><A HREF="manual.html#6.3">6.3 - Modules</A> |
| 111 | <LI><A HREF="manual.html#5.4">5.4 - String Manipulation</A> | 117 | <LI><A HREF="manual.html#6.4">6.4 - String Manipulation</A> |
| 112 | <UL> | 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 | </UL> | 120 | </UL> |
| 115 | <LI><A HREF="manual.html#5.5">5.5 - Table Manipulation</A> | 121 | <LI><A HREF="manual.html#6.5">6.5 - Table Manipulation</A> |
| 116 | <LI><A HREF="manual.html#5.6">5.6 - Mathematical Functions</A> | 122 | <LI><A HREF="manual.html#6.6">6.6 - Mathematical Functions</A> |
| 117 | <LI><A HREF="manual.html#5.7">5.7 - Bitwise operations</A> | 123 | <LI><A HREF="manual.html#6.7">6.7 - Bitwise operations</A> |
| 118 | <LI><A HREF="manual.html#5.8">5.8 - Input and Output Facilities</A> | 124 | <LI><A HREF="manual.html#6.8">6.8 - Input and Output Facilities</A> |
| 119 | <LI><A HREF="manual.html#5.9">5.9 - Operating System Facilities</A> | 125 | <LI><A HREF="manual.html#6.9">6.9 - Operating System Facilities</A> |
| 120 | <LI><A HREF="manual.html#5.10">5.10 - The Debug Library</A> | 126 | <LI><A HREF="manual.html#6.10">6.10 - The Debug Library</A> |
| 121 | </UL> | 127 | </UL> |
| 122 | <P> | 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 | <P> | 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 | <UL> | 132 | <UL> |
| 127 | <LI><A HREF="manual.html#7.1">7.1 - Changes in the Language</A> | 133 | <LI><A HREF="manual.html#8.1">8.1 - Changes in the Language</A> |
| 128 | <LI><A HREF="manual.html#7.2">7.2 - Changes in the Libraries</A> | 134 | <LI><A HREF="manual.html#8.2">8.2 - Changes in the Libraries</A> |
| 129 | <LI><A HREF="manual.html#7.3">7.3 - Changes in the API</A> | 135 | <LI><A HREF="manual.html#8.3">8.3 - Changes in the API</A> |
| 130 | </UL> | 136 | </UL> |
| 131 | <P> | 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 | </UL> | 139 | </UL> |
| 134 | 140 | ||
| 135 | <H2><A NAME="index">Index</A></H2> | 141 | <H2><A NAME="index">Index</A></H2> |
| @@ -144,7 +150,6 @@ Freely available under the terms of the · 8 unmodified lines | |||
| 144 | <A HREF="manual.html#pdf-dofile">dofile</A><BR> | 150 | <A HREF="manual.html#pdf-dofile">dofile</A><BR> |
| 145 | <A HREF="manual.html#pdf-error">error</A><BR> | 151 | <A HREF="manual.html#pdf-error">error</A><BR> |
| 146 | <A HREF="manual.html#pdf-getmetatable">getmetatable</A><BR> | 152 | <A HREF="manual.html#pdf-getmetatable">getmetatable</A><BR> |
| 147 | <A HREF="manual.html#pdf-ipairs">ipairs</A><BR> | ||
| 148 | <A HREF="manual.html#pdf-load">load</A><BR> | 153 | <A HREF="manual.html#pdf-load">load</A><BR> |
| 149 | <A HREF="manual.html#pdf-loadin">loadin</A><BR> | 154 | <A HREF="manual.html#pdf-loadin">loadin</A><BR> |
| 150 | <A HREF="manual.html#pdf-loadfile">loadfile</A><BR> | 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 | <A HREF="manual.html#pdf-bit.band">bit.band</A><BR> | 174 | <A HREF="manual.html#pdf-bit.band">bit.band</A><BR> |
| 170 | <A HREF="manual.html#pdf-bit.bnot">bit.bnot</A><BR> | 175 | <A HREF="manual.html#pdf-bit.bnot">bit.bnot</A><BR> |
| 171 | <A HREF="manual.html#pdf-bit.bor">bit.bor</A><BR> | 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 | <A HREF="manual.html#pdf-bit.btest">bit.btest</A><BR> | 177 | <A HREF="manual.html#pdf-bit.btest">bit.btest</A><BR> |
| 175 | <A HREF="manual.html#pdf-bit.bxor">bit.bxor</A><BR> | 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 | <P> | 183 | <P> |
| 177 | 184 | ||
| 178 | <A HREF="manual.html#pdf-coroutine.create">coroutine.create</A><BR> | 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 | <A HREF="manual.html#pdf-debug.traceback">debug.traceback</A><BR> | 206 | <A HREF="manual.html#pdf-debug.traceback">debug.traceback</A><BR> |
| 200 | <A HREF="manual.html#pdf-debug.upvalueid">debug.upvalueid</A><BR> | 207 | <A HREF="manual.html#pdf-debug.upvalueid">debug.upvalueid</A><BR> |
| 201 | <A HREF="manual.html#pdf-debug.upvaluejoin">debug.upvaluejoin</A><BR> | 208 | <A HREF="manual.html#pdf-debug.upvaluejoin">debug.upvaluejoin</A><BR> |
| 209 | <P> | ||
| 202 | 210 | ||
| 203 | </TD> | ||
| 204 | <TD> | ||
| 205 | <H3> </H3> | ||
| 206 | <A HREF="manual.html#pdf-file:close">file:close</A><BR> | 211 | <A HREF="manual.html#pdf-file:close">file:close</A><BR> |
| 207 | <A HREF="manual.html#pdf-file:flush">file:flush</A><BR> | 212 | <A HREF="manual.html#pdf-file:flush">file:flush</A><BR> |
| 208 | <A HREF="manual.html#pdf-file:lines">file:lines</A><BR> | 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 | <A HREF="manual.html#pdf-io.write">io.write</A><BR> | 233 | <A HREF="manual.html#pdf-io.write">io.write</A><BR> |
| 229 | <P> | 234 | <P> |
| 230 | 235 | ||
| 236 | </TD> | ||
| 237 | <TD> | ||
| 238 | <H3> </H3> | ||
| 231 | <A HREF="manual.html#pdf-math.abs">math.abs</A><BR> | 239 | <A HREF="manual.html#pdf-math.abs">math.abs</A><BR> |
| 232 | <A HREF="manual.html#pdf-math.acos">math.acos</A><BR> | 240 | <A HREF="manual.html#pdf-math.acos">math.acos</A><BR> |
| 233 | <A HREF="manual.html#pdf-math.asin">math.asin</A><BR> | 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 | <A HREF="manual.html#lua_Writer">lua_Writer</A><BR> | 328 | <A HREF="manual.html#lua_Writer">lua_Writer</A><BR> |
| 321 | <P> | 329 | <P> |
| 322 | 330 | ||
| 331 | <A HREF="manual.html#lua_absindex">lua_absindex</A><BR> | ||
| 323 | <A HREF="manual.html#lua_atpanic">lua_atpanic</A><BR> | 332 | <A HREF="manual.html#lua_atpanic">lua_atpanic</A><BR> |
| 324 | <A HREF="manual.html#lua_call">lua_call</A><BR> | 333 | <A HREF="manual.html#lua_call">lua_call</A><BR> |
| 325 | <A HREF="manual.html#lua_callk">lua_callk</A><BR> | 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 | <A HREF="manual.html#lua_getfenv">lua_getfenv</A><BR> | 346 | <A HREF="manual.html#lua_getfenv">lua_getfenv</A><BR> |
| 338 | <A HREF="manual.html#lua_getfield">lua_getfield</A><BR> | 347 | <A HREF="manual.html#lua_getfield">lua_getfield</A><BR> |
| 339 | <A HREF="manual.html#lua_getglobal">lua_getglobal</A><BR> | 348 | <A HREF="manual.html#lua_getglobal">lua_getglobal</A><BR> |
| 340 | <A HREF="manual.html#lua_gethookcount">lua_gethookcount</A><BR> | ||
| 341 | <A HREF="manual.html#lua_gethook">lua_gethook</A><BR> | 349 | <A HREF="manual.html#lua_gethook">lua_gethook</A><BR> |
| 350 | <A HREF="manual.html#lua_gethookcount">lua_gethookcount</A><BR> | ||
| 342 | <A HREF="manual.html#lua_gethookmask">lua_gethookmask</A><BR> | 351 | <A HREF="manual.html#lua_gethookmask">lua_gethookmask</A><BR> |
| 343 | <A HREF="manual.html#lua_getinfo">lua_getinfo</A><BR> | 352 | <A HREF="manual.html#lua_getinfo">lua_getinfo</A><BR> |
| 344 | <A HREF="manual.html#lua_getlocal">lua_getlocal</A><BR> | 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 | <A HREF="manual.html#lua_pushvalue">lua_pushvalue</A><BR> | 394 | <A HREF="manual.html#lua_pushvalue">lua_pushvalue</A><BR> |
| 386 | <A HREF="manual.html#lua_pushvfstring">lua_pushvfstring</A><BR> | 395 | <A HREF="manual.html#lua_pushvfstring">lua_pushvfstring</A><BR> |
| 387 | <A HREF="manual.html#lua_rawequal">lua_rawequal</A><BR> | 396 | <A HREF="manual.html#lua_rawequal">lua_rawequal</A><BR> |
| 388 | <A HREF="manual.html#lua_rawgeti">lua_rawgeti</A><BR> | ||
| 389 | <A HREF="manual.html#lua_rawget">lua_rawget</A><BR> | 397 | <A HREF="manual.html#lua_rawget">lua_rawget</A><BR> |
| 398 | <A HREF="manual.html#lua_rawgeti">lua_rawgeti</A><BR> | ||
| 390 | <A HREF="manual.html#lua_rawlen">lua_rawlen</A><BR> | 399 | <A HREF="manual.html#lua_rawlen">lua_rawlen</A><BR> |
| 391 | <A HREF="manual.html#lua_rawseti">lua_rawseti</A><BR> | ||
| 392 | <A HREF="manual.html#lua_rawset">lua_rawset</A><BR> | 400 | <A HREF="manual.html#lua_rawset">lua_rawset</A><BR> |
| 401 | <A HREF="manual.html#lua_rawseti">lua_rawseti</A><BR> | ||
| 393 | <A HREF="manual.html#lua_register">lua_register</A><BR> | 402 | <A HREF="manual.html#lua_register">lua_register</A><BR> |
| 394 | <A HREF="manual.html#lua_remove">lua_remove</A><BR> | 403 | <A HREF="manual.html#lua_remove">lua_remove</A><BR> |
| 395 | <A HREF="manual.html#lua_replace">lua_replace</A><BR> | 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 | <A HREF="manual.html#luaL_loadstring">luaL_loadstring</A><BR> | 473 | <A HREF="manual.html#luaL_loadstring">luaL_loadstring</A><BR> |
| 465 | <A HREF="manual.html#luaL_newmetatable">luaL_newmetatable</A><BR> | 474 | <A HREF="manual.html#luaL_newmetatable">luaL_newmetatable</A><BR> |
| 466 | <A HREF="manual.html#luaL_newstate">luaL_newstate</A><BR> | 475 | <A HREF="manual.html#luaL_newstate">luaL_newstate</A><BR> |
| 476 | <A HREF="manual.html#luaL_openlib">luaL_openlib</A><BR> | ||
| 467 | <A HREF="manual.html#luaL_openlibs">luaL_openlibs</A><BR> | 477 | <A HREF="manual.html#luaL_openlibs">luaL_openlibs</A><BR> |
| 468 | <A HREF="manual.html#luaL_optint">luaL_optint</A><BR> | 478 | <A HREF="manual.html#luaL_optint">luaL_optint</A><BR> |
| 469 | <A HREF="manual.html#luaL_optinteger">luaL_optinteger</A><BR> | 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 | <HR> | 501 | <HR> |
| 492 | <SMALL> | 502 | <SMALL> |
| 493 | Last update: | 503 | Last update: |
| 494 | Wed Jan 13 15:31:47 BRST 2010 | 504 | Mon May 17 16:58:54 BRT 2010 |
| 495 | </SMALL> | 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 | </BODY> | 510 | </BODY> |
Binary file not shown.
| @@ -16,6 +16,11 @@ · 15 unmodified lines | |||
| 16 | Lua 5.2 Reference Manual | 16 | Lua 5.2 Reference Manual |
| 17 | </h1> | 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 | by Roberto Ierusalimschy, Luiz Henrique de Figueiredo, Waldemar Celes | 24 | by Roberto Ierusalimschy, Luiz Henrique de Figueiredo, Waldemar Celes |
| 20 | <p> | 25 | <p> |
| 21 | <small> | 26 | <small> |
| @@ -33,7 +38,7 @@ Freely available under the terms of the · 11 unmodified lines | |||
| 33 | <!-- ====================================================================== --> | 38 | <!-- ====================================================================== --> |
| 34 | <p> | 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> | 92 | <h1>2 - <a name="2">Basic Concepts</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> | ||
| 244 | 93 | ||
| 245 | <p> | 94 | <p> |
| 246 | A <em>comment</em> starts with a double hyphen (<code>--</code>) | 95 | This section describes some basic concepts of the language. |
| 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 | |||
| 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 | <p> | 101 | <p> |
| 262 | Lua is a <em>dynamically typed language</em>. | 102 | Lua is a <em>dynamically typed language</em>. |
| @@ -291,14 +131,14 @@ see file <code>luaconf.h</code>.) · 28 unmodified lines | |||
| 291 | <em>String</em> represents arrays of characters. | 131 | <em>String</em> represents arrays of characters. |
| 292 | 132 | ||
| 293 | Lua is 8-bit clean: | 133 | Lua is 8-bit clean: |
| 294 | strings can contain any 8-bit character, | 134 | strings can contain any 8-bit value, |
| 295 | including embedded zeros ('<code>\0</code>') (see <a href="#2.1">§2.1</a>). | 135 | including embedded zeros ('<code>\0</code>'). |
| 296 | 136 | ||
| 297 | 137 | ||
| 298 | <p> | 138 | <p> |
| 299 | Lua can call (and manipulate) functions written in Lua and | 139 | Lua can call (and manipulate) functions written in Lua and |
| 300 | functions written in C | 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 | <p> | 144 | <p> |
| @@ -309,7 +149,7 @@ and has no pre-defined operations in Lua, · 4 unmodified lines | |||
| 309 | except assignment and identity test. | 149 | except assignment and identity test. |
| 310 | However, by using <em>metatables</em>, | 150 | However, by using <em>metatables</em>, |
| 311 | the programmer can define operations for userdata values | 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 | Userdata values cannot be created or modified in Lua, | 153 | Userdata values cannot be created or modified in Lua, |
| 314 | only through the C API. | 154 | only through the C API. |
| 315 | This guarantees the integrity of data owned by the host program. | 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 | <p> | 158 | <p> |
| 319 | The type <em>thread</em> represents independent threads of execution | 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 | Do not confuse Lua threads with operating-system threads. | 161 | Do not confuse Lua threads with operating-system threads. |
| 322 | Lua supports coroutines on all systems, | 162 | Lua supports coroutines on all systems, |
| 323 | even those that do not support threads. | 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 | The language supports this representation by | 176 | The language supports this representation by |
| 337 | providing <code>a.name</code> as syntactic sugar for <code>a["name"]</code>. | 177 | providing <code>a.name</code> as syntactic sugar for <code>a["name"]</code>. |
| 338 | There are several convenient ways to create tables in Lua | 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 | <p> | 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 | In particular, | 185 | In particular, |
| 346 | because functions are first-class values, | 186 | because functions are first-class values, |
| 347 | table fields can contain functions. | 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 | <p> | 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 | <p> | 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 | <p> | 255 | <p> |
| 406 | Any variable is assumed to be global unless explicitly declared | 256 | Because Lua is an embedded extension language, |
| 407 | as a local (see <a href="#2.4.7">§2.4.7</a>). | 257 | all Lua actions start from C code in the host program |
| 408 | Local variables are <em>lexically scoped</em>: | 258 | calling a function from the Lua library (see <a href="#lua_pcall"><code>lua_pcall</code></a>). |
| 409 | local variables can be freely accessed by functions | 259 | Whenever an error occurs during Lua compilation or execution, |
| 410 | defined inside their scope (see <a href="#2.6">§2.6</a>). | 260 | control returns to C, |
| 261 | which can take appropriate measures | ||
| 262 | (such as printing an error message). | ||
| 411 | 263 | ||
| 412 | 264 | ||
| 413 | <p> | 265 | <p> |
| 414 | Before the first assignment to a variable, its value is <b>nil</b>. | 266 | Lua code can explicitly generate an error by calling the |
| 415 | 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> | 275 | <h2>2.4 - <a name="2.4">Metatables</a></h2> |
| 438 | var ::= prefixexp `<b>.</b>´ Name | ||
| 439 | </pre> | ||
| 440 | 276 | ||
| 441 | <p> | 277 | <p> |
| 442 | All global variables live as fields in ordinary Lua tables, | 278 | Every value in Lua can have a <em>metatable</em>. |
| 443 | called <em>environment tables</em> or simply | 279 | This <em>metatable</em> is an ordinary Lua table |
| 444 | <em>environments</em> (see <a href="#2.9">§2.9</a>). | 280 | that defines the behavior of the original value |
| 445 | An access to a global variable <code>x</code> | 281 | under certain special operations. |
| 446 | is equivalent to <code>_env.x</code>, | 282 | You can change several aspects of the behavior |
| 447 | which in turn is equivalent to | 283 | of operations over a value by setting specific fields in its metatable. |
| 448 | 284 | For instance, when a non-numeric value is the operand of an addition, | |
| 449 | <pre> | 285 | Lua checks for a function in the field <code>"__add"</code> in its metatable. |
| 450 | gettable_event(_env, "x") | 286 | If it finds one, |
| 451 | </pre><p> | 287 | Lua calls this function to perform the addition. |
| 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.) | ||
| 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 | <p> | 302 | <p> |
| 466 | Lua supports an almost conventional set of statements, | 303 | You can replace the metatable of tables |
| 467 | similar to those in Pascal or C. | 304 | through the <a href="#pdf-setmetatable"><code>setmetatable</code></a> |
| 468 | This set includes | 305 | function. |
| 469 | assignments, control structures, function calls, | 306 | You cannot change the metatable of other types from Lua |
| 470 | and variable declarations. | 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 | <p> | 321 | <p> |
| 477 | The unit of execution of Lua is called a <em>chunk</em>. | 322 | A metatable controls how an object behaves in arithmetic operations, |
| 478 | A chunk is simply a sequence of statements, | 323 | order comparisons, concatenation, length operation, and indexing. |
| 479 | which are executed sequentially. | 324 | A metatable also can define a function to be called when a userdata |
| 480 | Each statement can be optionally followed by a semicolon: | 325 | is garbage collected. |
| 481 | 326 | For each of these operations Lua associates a specific key | |
| 482 | <pre> | 327 | called an <em>event</em>. |
| 483 | chunk ::= {stat [`<b>;</b>´]} | 328 | When Lua performs one of these operations over a value, |
| 484 | </pre><p> | 329 | it checks whether this value has a metatable with the corresponding event. |
| 485 | There are no empty statements and thus '<code>;;</code>' is not legal. | 330 | If so, the value associated with that key (the metamethod) |
| 486 | 331 | controls how Lua will perform the operation. | |
| 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. | ||
| 494 | 332 | ||
| 495 | 333 | ||
| 496 | <p> | 334 | <p> |
| 497 | A chunk can be stored in a file or in a string inside the host program. | 335 | Metatables control the operations listed next. |
| 498 | To execute a chunk, | 336 | Each operation is identified by its corresponding name. |
| 499 | Lua first pre-compiles the chunk into instructions for a virtual machine, | 337 | The key for each operation is a string with its name prefixed by |
| 500 | and then it executes the compiled code | 338 | two underscores, '<code>__</code>'; |
| 501 | with an interpreter for the virtual machine. | 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 | <p> | 345 | <p> |
| 505 | Chunks can also be pre-compiled into binary form; | 346 | The code shown here in Lua is only illustrative; |
| 506 | see program <code>luac</code> for details. | 347 | the real behavior is hard coded in the interpreter |
| 507 | Programs in source and compiled forms are interchangeable; | 348 | and it is much more efficient than this simulation. |
| 508 | Lua automatically detects the file type and acts accordingly. | 349 | All functions used in these descriptions |
| 509 | 350 | (<a href="#pdf-rawget"><code>rawget</code></a>, <a href="#pdf-tonumber"><code>tonumber</code></a>, etc.) | |
| 510 | 351 | are described in <a href="#6.1">§6.1</a>. | |
| 511 | 352 | In particular, to retrieve the metamethod of a given object, | |
| 512 | 353 | we use the expression | |
| 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: | ||
| 518 | 354 | ||
| 519 | <pre> | 355 | <pre> |
| 520 | block ::= chunk | 356 | metatable(obj)[event] |
| 521 | </pre> | 357 | </pre><p> |
| 522 | 358 | This should be read as | |
| 523 | <p> | ||
| 524 | A block can be explicitly delimited to produce a single statement: | ||
| 525 | 359 | ||
| 526 | <pre> | 360 | <pre> |
| 527 | stat ::= <b>do</b> block <b>end</b> | 361 | rawget(getmetatable(obj) or {}, event) |
| 528 | </pre><p> | 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> | 379 | <ul> |
| 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>. | ||
| 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 | <p> | 386 | <p> |
| 571 | The assignment statement first evaluates all its expressions | 387 | The function <code>getbinhandler</code> below defines how Lua chooses a handler |
| 572 | and only then are the assignments performed. | 388 | for a binary operation. |
| 573 | Thus the code | 389 | First, Lua tries the first operand. |
| 574 | 390 | If its type does not define a handler for the operation, | |
| 575 | <pre> | 391 | then Lua tries the second operand. |
| 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 | ||
| 583 | 392 | ||
| 584 | <pre> | 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 | </pre><p> | 397 | </pre><p> |
| 587 | exchanges the values of <code>x</code> and <code>y</code>, | 398 | By using this function, |
| 588 | and | 399 | the behavior of the <code>op1 + op2</code> is |
| 589 | 400 | ||
| 590 | <pre> | 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 | </pre><p> | 416 | </pre><p> |
| 593 | cyclically permutes the values of <code>x</code>, <code>y</code>, and <code>z</code>. | 417 | </li> |
| 594 | |||
| 595 | 418 | ||
| 596 | <p> | 419 | <li><b>"sub":</b> |
| 597 | The meaning of assignments to global variables | 420 | the <code>-</code> operation. |
| 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.) | ||
| 605 | 421 | ||
| 422 | Behavior similar to the "add" operation. | ||
| 423 | </li> | ||
| 606 | 424 | ||
| 607 | <p> | 425 | <li><b>"mul":</b> |
| 608 | An assignment to a global variable <code>x = val</code> | 426 | the <code>*</code> operation. |
| 609 | is equivalent to the assignment | ||
| 610 | <code>_env.x = val</code>, | ||
| 611 | which in turn is equivalent to | ||
| 612 | 427 | ||
| 613 | <pre> | 428 | Behavior similar to the "add" operation. |
| 614 | settable_event(_env, "x", val) | 429 | </li> |
| 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.) | ||
| 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> | 445 | <li><b>"pow":</b> |
| 625 | The control structures | 446 | the <code>^</code> (exponentiation) operation. |
| 626 | <b>if</b>, <b>while</b>, and <b>repeat</b> have the usual meaning and | ||
| 627 | familiar syntax: | ||
| 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 | <pre> | 457 | <pre> |
| 633 | stat ::= <b>while</b> exp <b>do</b> block <b>end</b> | 458 | function unm_event (op) |
| 634 | stat ::= <b>repeat</b> block <b>until</b> exp | 459 | local o = tonumber(op) |
| 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> | 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 | </pre><p> | 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> | 520 | <li><b>"eq":</b> |
| 657 | The <b>return</b> statement is used to return values | 521 | the <code>==</code> operation. |
| 658 | from a function or a chunk (which is just a function). | ||
| 659 | 522 | ||
| 660 | Functions and chunks can return more than one value, | 523 | The function <code>getequalhandler</code> defines how Lua chooses a metamethod |
| 661 | and so the syntax for the <b>return</b> statement is | 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 | <pre> | 529 | <pre> |
| 664 | stat ::= <b>return</b> [explist] | 530 | function getequalhandler (op1, op2, event) |
| 665 | </pre> | 531 | if type(op1) ~= type(op2) then return nil end |
| 666 | 532 | local mm1 = metatable(op1)[event] | |
| 667 | <p> | 533 | local mm2 = metatable(op2)[event] |
| 668 | The <b>break</b> statement is used to terminate the execution of a | 534 | if mm1 == mm2 then return mm1 else return nil end |
| 669 | <b>while</b>, <b>repeat</b>, or <b>for</b> loop, | 535 | end |
| 670 | skipping to the next statement after the loop: | ||
| 671 | |||
| 672 | |||
| 673 | <pre> | ||
| 674 | stat ::= <b>break</b> | ||
| 675 | </pre><p> | 536 | </pre><p> |
| 676 | A <b>break</b> ends the innermost enclosing loop. | 537 | The "eq" event is defined as follows: |
| 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: | ||
| 706 | 538 | ||
| 707 | <pre> | 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 | </pre><p> | 555 | </pre><p> |
| 710 | The <em>block</em> is repeated for <em>name</em> starting at the value of | 556 | </li> |
| 711 | the first <em>exp</em>, until it passes the second <em>exp</em> by steps of the | 557 | |
| 712 | third <em>exp</em>. | 558 | <li><b>"lt":</b> |
| 713 | More precisely, a <b>for</b> statement like | 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 | <pre> | 562 | <pre> |
| 721 | do | 563 | function lt_event (op1, op2) |
| 722 | local <em>var</em>, <em>limit</em>, <em>step</em> = tonumber(<em>e1</em>), tonumber(<em>e2</em>), tonumber(<em>e3</em>) | 564 | if type(op1) == "number" and type(op2) == "number" then |
| 723 | if not (<em>var</em> and <em>limit</em> and <em>step</em>) then error() end | 565 | return op1 < op2 -- numeric comparison |
| 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 | 566 | elseif type(op1) == "string" and type(op2) == "string" then |
| 725 | local v = <em>var</em> | 567 | return op1 < op2 -- lexicographic comparison |
| 726 | <em>block</em> | 568 | else |
| 727 | <em>var</em> = <em>var</em> + <em>step</em> | 569 | local h = getbinhandler(op1, op2, "__lt") |
| 570 | if h then | ||
| 571 | return (h(op1, op2)) | ||
| 572 | else | ||
| 573 | error(···) | ||
| 574 | end | ||
| 728 | end | 575 | end |
| 729 | end | 576 | end |
| 730 | </pre><p> | 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 | </li> | 578 | </li> |
| 745 | 579 | ||
| 746 | <li> | 580 | <li><b>"le":</b> |
| 747 | If the third expression (the step) is absent, | 581 | the <code><=</code> operation. |
| 748 | then a step of 1 is used. | ||
| 749 | </li> | ||
| 750 | 582 | ||
| 751 | <li> | ||
| 752 | You can use <b>break</b> to exit a <b>for</b> loop. | ||
| 753 | </li> | ||
| 754 | 583 | ||
| 755 | <li> | 584 | <pre> |
| 756 | The loop variable <code>v</code> is local to the loop; | 585 | function le_event (op1, op2) |
| 757 | you cannot use its value after the <b>for</b> ends or is broken. | 586 | if type(op1) == "number" and type(op2) == "number" then |
| 758 | If you need this value, | 587 | return op1 <= op2 -- numeric comparison |
| 759 | assign it to another variable before breaking or exiting the loop. | 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 | </li> | 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 | <pre> | 614 | <pre> |
| 772 | stat ::= <b>for</b> namelist <b>in</b> explist <b>do</b> block <b>end</b> | 615 | function gettable_event (table, key) |
| 773 | namelist ::= Name {`<b>,</b>´ Name} | 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 | </pre><p> | 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 | <pre> | 640 | <pre> |
| 783 | do | 641 | function settable_event (table, key, value) |
| 784 | local <em>f</em>, <em>s</em>, <em>var</em> = <em>explist</em> | 642 | local h |
| 785 | while true do | 643 | if type(table) == "table" then |
| 786 | local <em>var_1</em>, ···, <em>var_n</em> = <em>f</em>(<em>s</em>, <em>var</em>) | 644 | local v = rawget(table, key) |
| 787 | <em>var</em> = <em>var_1</em> | 645 | if v ~= nil then rawset(table, key, value); return end |
| 788 | if <em>var</em> == nil then break end | 646 | h = metatable(table).__newindex |
| 789 | <em>block</em> | 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 | end | 657 | end |
| 791 | end | 658 | end |
| 792 | </pre><p> | 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 | </li> | 660 | </li> |
| 803 | 661 | ||
| 804 | <li> | 662 | <li><b>"call":</b> |
| 805 | <code><em>f</em></code>, <code><em>s</em></code>, and <code><em>var</em></code> are invisible variables. | 663 | called when Lua calls a value. |
| 806 | The names are here for explanatory purposes only. | ||
| 807 | </li> | ||
| 808 | 664 | ||
| 809 | <li> | ||
| 810 | You can use <b>break</b> to exit a <b>for</b> loop. | ||
| 811 | </li> | ||
| 812 | 665 | ||
| 813 | <li> | 666 | <pre> |
| 814 | The loop variables <code><em>var_i</em></code> are local to the loop; | 667 | function function_event (func, ...) |
| 815 | you cannot use their values after the <b>for</b> ends. | 668 | if type(func) == "function" then |
| 816 | If you need these values, | 669 | return func(...) -- primitive call |
| 817 | then assign them to other variables before breaking or exiting the loop. | 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 | </li> | 680 | </li> |
| 819 | 681 | ||
| 820 | </ul> | 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> | 687 | <h2>2.5 - <a name="2.5">Garbage Collection</a></h2> |
| 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>. | ||
| 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> | 710 | <p> |
| 840 | Local variables can be declared anywhere inside a block. | 711 | The garbage-collector pause |
| 841 | The declaration can include an initial assignment: | 712 | controls how long the collector waits before starting a new cycle. |
| 842 | 713 | Larger values make the collector less aggressive. | |
| 843 | <pre> | 714 | Values smaller than 100 mean the collector will not wait to |
| 844 | stat ::= <b>local</b> namelist [`<b>=</b>´ explist] | 715 | start a new cycle. |
| 845 | </pre><p> | 716 | A value of 200 means that the collector waits for the total memory in use |
| 846 | If present, an initial assignment has the same semantics | 717 | to double before starting a new cycle. |
| 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>. | ||
| 849 | 718 | ||
| 850 | 719 | ||
| 851 | <p> | 720 | <p> |
| 852 | A chunk is also a block (see <a href="#2.4.1">§2.4.1</a>), | 721 | The step multiplier |
| 853 | and so local variables can be declared in a chunk outside any explicit block. | 722 | controls the relative speed of the collector relative to |
| 854 | The scope of such local variables extends until the end of the chunk. | 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 | <p> | 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 | <p> | 753 | <p> |
| 867 | A lexical environment defines a new current environment (see <a href="#2.9">§2.9</a>) | 754 | Using the C API, |
| 868 | for the code inside its block: | 755 | you can set garbage-collector metamethods for userdata (see <a href="#2.4">§2.4</a>). |
| 869 | 756 | These metamethods are also called <em>finalizers</em>. | |
| 870 | <pre> | 757 | Finalizers allow you to coordinate Lua's garbage collection |
| 871 | stat ::= <b>in</b> exp <b>do</b> block <b>end</b> | 758 | with external resource management |
| 872 | </pre><p> | 759 | (such as closing files, network or database connections, |
| 873 | That is, a lexical environment changes the | 760 | or freeing your own memory). |
| 874 | table used to resolve all accesses | ||
| 875 | to global (free) variables inside a block. | ||
| 876 | 761 | ||
| 877 | 762 | ||
| 878 | <p> | 763 | <p> |
| 879 | Inside a lexical environment, | 764 | Garbage userdata with a field <code>__gc</code> in their metatables are not |
| 880 | the result of <code><em>exp</em></code> becomes the current environment. | 765 | collected immediately by the garbage collector. |
| 881 | Expression <code><em>exp</em></code> is evaluated only once in the beginning of | 766 | Instead, Lua puts them in a list. |
| 882 | the statement and it is stored in a hidden local variable named | 767 | After the collection, |
| 883 | <a name="pdf-(environment)"><code>(environment)</code></a>. | 768 | Lua does the equivalent of the following function |
| 884 | Then, any global variable | 769 | for each userdata in that list: |
| 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>). | ||
| 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 | <p> | 780 | <p> |
| 893 | A lexical environment does not shadow local declarations. | 781 | At the end of each garbage-collection cycle, |
| 894 | That is, any local variable that is visible just before | 782 | the finalizers for userdata are called in <em>reverse</em> |
| 895 | a lexical environment is still visible inside the environment. | 783 | order of their creation, |
| 896 | 784 | among those collected in that cycle. | |
| 897 | 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 | <p> | 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 | <p> | 804 | <p> |
| 922 | Numbers and literal strings are explained in <a href="#2.1">§2.1</a>; | 805 | A weak table can have weak keys, weak values, or both. |
| 923 | variables are explained in <a href="#2.3">§2.3</a>; | 806 | A table with weak keys allows the collection of its keys, |
| 924 | function definitions are explained in <a href="#2.5.9">§2.5.9</a>; | 807 | but prevents the collection of its values. |
| 925 | function calls are explained in <a href="#2.5.8">§2.5.8</a>; | 808 | A table with both weak keys and weak values allows the collection of |
| 926 | table constructors are explained in <a href="#2.5.7">§2.5.7</a>. | 809 | both keys and values. |
| 927 | Vararg expressions, | 810 | In any case, if either the key or the value is collected, |
| 928 | denoted by three dots ('<code>...</code>'), can only be used when | 811 | the whole pair is removed from the table. |
| 929 | directly inside a vararg function; | 812 | The weakness of a table is controlled by the |
| 930 | they are explained in <a href="#2.5.9">§2.5.9</a>. | 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 | <p> | 820 | <p> |
| 934 | Binary operators comprise arithmetic operators (see <a href="#2.5.1">§2.5.1</a>), | 821 | A table with weak keys and strong values |
| 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>), | 822 | is also called an <em>ephemeron table</em>. |
| 936 | and the concatenation operator (see <a href="#2.5.4">§2.5.4</a>). | 823 | In an ephemeron table, |
| 937 | Unary operators comprise the unary minus (see <a href="#2.5.1">§2.5.1</a>), | 824 | a value is considered reachable only if its key is reachable. |
| 938 | the unary <b>not</b> (see <a href="#2.5.3">§2.5.3</a>), | 825 | In particular, |
| 939 | and the unary <em>length operator</em> (see <a href="#2.5.5">§2.5.5</a>). | 826 | if the only reference to a key comes from its value, |
| 827 | the pair is removed. | ||
| 940 | 828 | ||
| 941 | 829 | ||
| 942 | <p> | 830 | <p> |
| 943 | Both function calls and vararg expressions can result in multiple values. | 831 | After you use a table as a metatable, |
| 944 | If an expression is used as a statement | 832 | you should not change the value of its <code>__mode</code> field. |
| 945 | (only possible for function calls (see <a href="#2.4.6">§2.4.6</a>)), | 833 | Otherwise, the weak behavior of the tables controlled by this |
| 946 | then its return list is adjusted to zero elements, | 834 | metatable is undefined. |
| 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. | ||
| 955 | 835 | ||
| 956 | 836 | ||
| 957 | <p> | 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 | <p> | 847 | <p> |
| 980 | Any expression enclosed in parentheses always results in only one value. | 848 | Userdata with finalizers has a special behavior in weak tables. |
| 981 | Thus, | 849 | When a userdata is a value in a weak table, |
| 982 | <code>(f(x,y,z))</code> is always a single value, | 850 | it is removed from the table the first time it is collected, |
| 983 | even if <code>f</code> returns several values. | 851 | before running its finalizer. |
| 984 | (The value of <code>(f(x,y,z))</code> is the first value returned by <code>f</code> | 852 | When it is a key, however, |
| 985 | or <b>nil</b> if <code>f</code> does not return any values.) | 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> | 875 | <p> |
| 1016 | == ~= < > <= >= | 876 | You create a coroutine with a call to <a href="#pdf-coroutine.create"><code>coroutine.create</code></a>. |
| 1017 | </pre><p> | 877 | Its sole argument is a function |
| 1018 | These operators always result in <b>false</b> or <b>true</b>. | 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 | <p> | 884 | <p> |
| 1022 | Equality (<code>==</code>) first compares the type of its operands. | 885 | When you first call <a href="#pdf-coroutine.resume"><code>coroutine.resume</code></a>, |
| 1023 | If the types are different, then the result is <b>false</b>. | 886 | passing as its first argument |
| 1024 | Otherwise, the values of the operands are compared. | 887 | a thread returned by <a href="#pdf-coroutine.create"><code>coroutine.create</code></a>, |
| 1025 | Numbers and strings are compared in the usual way. | 888 | the coroutine starts its execution, |
| 1026 | Objects (tables, userdata, threads, and functions) | 889 | at the first line of its main function. |
| 1027 | are compared by <em>reference</em>: | 890 | Extra arguments passed to <a href="#pdf-coroutine.resume"><code>coroutine.resume</code></a> are passed on |
| 1028 | two objects are considered equal only if they are the <em>same</em> object. | 891 | to the coroutine main function. |
| 1029 | Every time you create a new object | 892 | After the coroutine starts running, |
| 1030 | (a table, userdata, thread, or function), | 893 | it runs until it terminates or <em>yields</em>. |
| 1031 | this new object is different from any previously existing object. | ||
| 1032 | 894 | ||
| 1033 | 895 | ||
| 1034 | <p> | 896 | <p> |
| 1035 | You can change the way that Lua compares tables and userdata | 897 | A coroutine can terminate its execution in two ways: |
| 1036 | by using the "eq" metamethod (see <a href="#2.8">§2.8</a>). | 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 | <p> | 907 | <p> |
| 1040 | The conversion rules of <a href="#2.2.1">§2.2.1</a> | 908 | A coroutine yields by calling <a href="#pdf-coroutine.yield"><code>coroutine.yield</code></a>. |
| 1041 | <em>do not</em> apply to equality comparisons. | 909 | When a coroutine yields, |
| 1042 | Thus, <code>"0"==0</code> evaluates to <b>false</b>, | 910 | the corresponding <a href="#pdf-coroutine.resume"><code>coroutine.resume</code></a> returns immediately, |
| 1043 | and <code>t[0]</code> and <code>t["0"]</code> denote different | 911 | even if the yield happens inside nested function calls |
| 1044 | entries in a table. | 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 | <p> | 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 | <p> | 936 | <p> |
| 1052 | The order operators work as follows. | 937 | As an example, |
| 1053 | If both arguments are numbers, then they are compared as such. | 938 | consider the following code: |
| 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>. | ||
| 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 | <p> | 979 | <p> |
| 1074 | The negation operator <b>not</b> always returns <b>false</b> or <b>true</b>. | 980 | This section describes the lexis, the syntax, and the semantics of Lua. |
| 1075 | The conjunction operator <b>and</b> returns its first argument | 981 | In other words, |
| 1076 | if this value is <b>false</b> or <b>nil</b>; | 982 | this section describes |
| 1077 | otherwise, <b>and</b> returns its second argument. | 983 | which tokens are valid, |
| 1078 | The disjunction operator <b>or</b> returns its first argument | 984 | how they can be combined, |
| 1079 | if this value is different from <b>nil</b> and <b>false</b>; | 985 | and what their combinations mean. |
| 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: | ||
| 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 | <p> | 1032 | <p> |
| 1117 | The length operator is denoted by the unary prefix operator <code>#</code>. | 1033 | Lua is a case-sensitive language: |
| 1118 | The length of a string is its number of bytes | 1034 | <code>and</code> is a reserved word, but <code>And</code> and <code>AND</code> |
| 1119 | (that is, the usual meaning of string length when each | 1035 | are two different, valid names. |
| 1120 | character is one byte). | 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 | <p> | 1041 | <p> |
| 1124 | The length of a table <code>t</code> is defined to be any | 1042 | The following strings denote other tokens: |
| 1125 | integer index <code>n</code> | 1043 | |
| 1126 | such that <code>t[n]</code> is not <b>nil</b> and <code>t[n+1]</code> is <b>nil</b>; | 1044 | <pre> |
| 1127 | moreover, if <code>t[1]</code> is <b>nil</b>, <code>n</code> can be zero. | 1045 | + - * / % ^ # |
| 1128 | For a regular array, where all non-nil values | 1046 | == ~= <= >= < > = |
| 1129 | have keys from 1 to a given <code>n</code>, | 1047 | ( ) { } [ ] |
| 1130 | its length is exactly that <code>n</code>, | 1048 | ; : , . .. ... |
| 1131 | the index of its last value. | 1049 | </pre> |
| 1132 | If the array has "holes" | 1050 | |
| 1133 | (that is, <b>nil</b> values between other non-nil values), | 1051 | <p> |
| 1134 | then <code>#t</code> can be any of the indices that | 1052 | <em>Literal strings</em> |
| 1135 | directly precedes a <b>nil</b> value | 1053 | can be delimited by matching single or double quotes, |
| 1136 | (that is, it may consider any such <b>nil</b> value as the end of | 1054 | and can contain the following C-like escape sequences: |
| 1137 | the array). | 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 | <p> | 1075 | <p> |
| 1141 | A program can modify the behavior of the length operator for | 1076 | A character in a literal string can also be specified by its numerical value. |
| 1142 | any value but strings through metamethods (see <a href="#2.8">§2.8</a>). | 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> | 1122 | <pre> |
| 1149 | Operator precedence in Lua follows the table below, | 1123 | a = 'alo\n123"' |
| 1150 | from lower to higher priority: | 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 | <pre> | 1140 | <pre> |
| 1153 | or | 1141 | 3 3.0 3.1416 314.16e-2 0.31416E1 0xff 0x56 |
| 1154 | and | 1142 | </pre> |
| 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. | ||
| 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> | 1158 | <h2>3.2 - <a name="3.2">Variables</a></h2> |
| 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> | ||
| 1185 | 1159 | ||
| 1186 | <p> | 1160 | <p> |
| 1187 | Each field of the form <code>[exp1] = exp2</code> adds to the new table an entry | 1161 | Variables are places that store values. |
| 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, | ||
| 1196 | 1162 | ||
| 1197 | <pre> | 1163 | There are three kinds of variables in Lua: |
| 1198 | a = { [f(1)] = g; "x", "y"; x = 1, f(x), [30] = 23; 45 } | 1164 | global variables, local variables, and table fields. |
| 1199 | </pre><p> | ||
| 1200 | is equivalent to | ||
| 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 | <p> | 1167 | <p> |
| 1217 | If the last field in the list has the form <code>exp</code> | 1168 | A single name can denote a global variable or a local variable |
| 1218 | and the expression is a function call or a vararg expression, | 1169 | (or a function's formal parameter, |
| 1219 | then all values returned by this expression enter the list consecutively | 1170 | which is a particular kind of local variable): |
| 1220 | (see <a href="#2.5.8">§2.5.8</a>). | 1171 | |
| 1221 | To avoid this, | 1172 | <pre> |
| 1222 | enclose the function call or the vararg expression | 1173 | var ::= Name |
| 1223 | in parentheses (see <a href="#2.5">§2.5</a>). | 1174 | </pre><p> |
| 1175 | Name denotes identifiers, as defined in <a href="#3.1">§3.1</a>. | ||
| 1224 | 1176 | ||
| 1225 | 1177 | ||
| 1226 | <p> | 1178 | <p> |
| 1227 | The field list can have an optional trailing separator, | 1179 | Any variable name is assumed to be global unless explicitly declared |
| 1228 | as a convenience for machine-generated code. | 1180 | as a local (see <a href="#3.3.7">§3.3.7</a>). |
| 1229 | 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> | 1190 | <p> |
| 1235 | A function call in Lua has the following syntax: | 1191 | Square brackets are used to index a table: |
| 1236 | 1192 | ||
| 1237 | <pre> | 1193 | <pre> |
| 1238 | functioncall ::= prefixexp args | 1194 | var ::= prefixexp &lsquo<b>[</b>’ exp &lsquo<b>]</b>’ |
| 1239 | </pre><p> | 1195 | </pre><p> |
| 1240 | In a function call, | 1196 | The meaning of accesses to table fields can be changed via metatables. |
| 1241 | first prefixexp and args are evaluated. | 1197 | An access to an indexed variable <code>t[i]</code> is equivalent to |
| 1242 | If the value of prefixexp has type <em>function</em>, | 1198 | a call <code>gettable_event(t,i)</code>. |
| 1243 | then this function is called | 1199 | (See <a href="#2.4">§2.4</a> for a complete description of the |
| 1244 | with the given arguments. | 1200 | <code>gettable_event</code> function. |
| 1245 | Otherwise, the prefixexp "call" metamethod is called, | 1201 | This function is not defined or callable in Lua. |
| 1246 | having as first parameter the value of prefixexp, | 1202 | We use it here only for explanatory purposes.) |
| 1247 | followed by the original call arguments | ||
| 1248 | (see <a href="#2.8">§2.8</a>). | ||
| 1249 | 1203 | ||
| 1250 | 1204 | ||
| 1251 | <p> | 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 | <pre> | 1209 | <pre> |
| 1255 | functioncall ::= prefixexp `<b>:</b>´ Name args | 1210 | var ::= prefixexp &lsquo<b>.</b>’ Name |
| 1256 | </pre><p> | 1211 | </pre> |
| 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 | |||
| 1262 | 1212 | ||
| 1263 | <p> | 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 | <p> | 1225 | <p> |
| 1282 | As an exception to the free-form character of Lua, | 1226 | Lua supports an almost conventional set of statements, |
| 1283 | you cannot put a line break before the '<code>(</code>' in a function call. | 1227 | similar to those in Pascal or C. |
| 1284 | This restriction avoids some ambiguities in the language. | 1228 | This set includes |
| 1285 | If you write | 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 | <p> | 1236 | <p> |
| 1299 | A call of the form <code>return</code> <em>functioncall</em> is called | 1237 | The unit of execution of Lua is called a <em>chunk</em>. |
| 1300 | a <em>tail call</em>. | 1238 | A chunk is simply a sequence of statements, |
| 1301 | Lua implements <em>proper tail calls</em> | 1239 | which are executed sequentially. |
| 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: | ||
| 1314 | 1240 | ||
| 1315 | <pre> | 1241 | <pre> |
| 1316 | return (f(x)) -- results adjusted to 1 | 1242 | chunk ::= {stat } |
| 1317 | return 2 * f(x) | 1243 | </pre><p> |
| 1318 | return x, f(x) -- additional results | 1244 | Lua has <em>empty statements</em> |
| 1319 | f(x); return -- results discarded | 1245 | that allow you to separate statements with semicolons, |
| 1320 | return x or f(x) -- results adjusted to 1 | 1246 | start a chunk with a semicolon |
| 1247 | or write two semicolons in sequence: | ||
| 1248 | |||
| 1249 | <pre> | ||
| 1250 | stat ::= &lsquo<b>;</b>’ | ||
| 1321 | </pre> | 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 | <p> | 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 | <pre> | 1286 | <pre> |
| 1332 | function ::= <b>function</b> funcbody | 1287 | block ::= chunk |
| 1333 | funcbody ::= `<b>(</b>´ [parlist] `<b>)</b>´ block <b>end</b> | ||
| 1334 | </pre> | 1288 | </pre> |
| 1335 | 1289 | ||
| 1336 | <p> | 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 | <pre> | 1293 | <pre> |
| 1340 | stat ::= <b>function</b> funcname funcbody | 1294 | stat ::= <b>do</b> block <b>end</b> |
| 1341 | stat ::= <b>local</b> <b>function</b> Name funcbody | ||
| 1342 | funcname ::= Name {`<b>.</b>´ Name} [`<b>:</b>´ Name] | ||
| 1343 | </pre><p> | 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> | 1304 | |
| 1357 | function t.a.b.c.f () <em>body</em> end | 1305 | |
| 1358 | </pre><p> | 1306 | <h3>3.3.3 - <a name="3.3.3">Assignment</a></h3> |
| 1359 | translates to | 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 | <pre> | 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 | </pre><p> | 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 | <pre> | 1342 | <pre> |
| 1367 | local function f () <em>body</em> end | 1343 | i = 3 |
| 1344 | i, a[i] = i+1, 20 | ||
| 1368 | </pre><p> | 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 | <pre> | 1351 | <pre> |
| 1372 | local f; f = function () <em>body</em> end | 1352 | x, y = y, x |
| 1373 | </pre><p> | 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 | <pre> | 1357 | <pre> |
| 1377 | local f = function () <em>body</em> end | 1358 | x, y, z = y, z, x |
| 1378 | </pre><p> | 1359 | </pre><p> |
| 1379 | (This only makes a difference when the body of the function | 1360 | cyclically permutes the values of <code>x</code>, <code>y</code>, and <code>z</code>. |
| 1380 | contains references to <code>f</code>.) | ||
| 1381 | 1361 | ||
| 1382 | 1362 | ||
| 1383 | <p> | 1363 | <p> |
| 1384 | A function definition is an executable expression, | 1364 | The meaning of assignments to global variables |
| 1385 | whose value has type <em>function</em>. | 1365 | and table fields can be changed via metatables. |
| 1386 | When Lua pre-compiles a chunk, | 1366 | An assignment to an indexed variable <code>t[i] = val</code> is equivalent to |
| 1387 | all its function bodies are pre-compiled too. | 1367 | <code>settable_event(t,i,val)</code>. |
| 1388 | Then, whenever Lua executes the function definition, | 1368 | (See <a href="#2.4">§2.4</a> for a complete description of the |
| 1389 | the function is <em>instantiated</em> (or <em>closed</em>). | 1369 | <code>settable_event</code> function. |
| 1390 | This function instance (or <em>closure</em>) | 1370 | This function is not defined or callable in Lua. |
| 1391 | is the final value of the expression. | 1371 | We use it here only for explanatory purposes.) |
| 1392 | Different instances of the same function | ||
| 1393 | can refer to different external local variables | ||
| 1394 | and can have different environment tables. | ||
| 1395 | 1372 | ||
| 1396 | 1373 | ||
| 1397 | <p> | 1374 | <p> |
| 1398 | Parameters act as local variables that are | 1375 | An assignment to a global variable <code>x = val</code> |
| 1399 | initialized with the argument values: | 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> | 1383 | <h3>3.3.4 - <a name="3.3.4">Control Structures</a></h3><p> |
| 1436 | CALL PARAMETERS | 1384 | The control structures |
| 1437 | 1385 | <b>if</b>, <b>while</b>, and <b>repeat</b> have the usual meaning and | |
| 1438 | f(3) a=3, b=nil | 1386 | familiar syntax: |
| 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> | ||
| 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 | <pre> | 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 | </pre><p> | 1395 | </pre><p> |
| 1466 | is syntactic sugar for | 1396 | Lua also has a <b>for</b> statement, in two flavors (see <a href="#3.3.5">§3.3.5</a>). |
| 1467 | |||
| 1468 | <pre> | ||
| 1469 | t.a.b.c.f = function (self, <em>params</em>) <em>body</em> end | ||
| 1470 | </pre> | ||
| 1471 | |||
| 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 | <p> | 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. | 1419 | Functions and chunks can return more than one value, |
| 1482 | The scope of variables begins at the first statement <em>after</em> | 1420 | and so the syntax for the <b>return</b> statement is |
| 1483 | their declaration and lasts until the end of the innermost block that | ||
| 1484 | includes the declaration. | ||
| 1485 | Consider the following example: | ||
| 1486 | 1421 | ||
| 1487 | <pre> | 1422 | <pre> |
| 1488 | x = 10 -- global variable | 1423 | stat ::= <b>return</b> [explist] [&lsquo<b>;</b>’] |
| 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) | ||
| 1500 | </pre> | 1424 | </pre> |
| 1501 | 1425 | ||
| 1502 | <p> | 1426 | <p> |
| 1503 | Notice that, in a declaration like <code>local x = x</code>, | 1427 | The <b>break</b> statement is used to terminate the execution of a |
| 1504 | the new <code>x</code> being declared is not in scope yet, | 1428 | <b>while</b>, <b>repeat</b>, or <b>for</b> loop, |
| 1505 | and so the second <code>x</code> refers to the outside variable. | 1429 | skipping to the next statement after the loop: |
| 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 | |||
| 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 | <pre> | 1432 | <pre> |
| 1523 | a = {} | 1433 | stat ::= <b>break</b> [&lsquo<b>;</b>’] |
| 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 | ||
| 1529 | </pre><p> | 1434 | </pre><p> |
| 1530 | The loop creates ten closures | 1435 | A <b>break</b> ends the innermost enclosing loop. |
| 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). | ||
| 1549 | 1436 | ||
| 1550 | 1437 | ||
| 1551 | <p> | 1438 | <p> |
| 1552 | Lua code can explicitly generate an error by calling the | 1439 | The <b>return</b> and <b>break</b> |
| 1553 | <a href="#pdf-error"><code>error</code></a> function. | 1440 | statements can only be written as the <em>last</em> statement of a block. |
| 1554 | If you need to catch errors in Lua, | 1441 | If it is really necessary to <b>return</b> or <b>break</b> in the |
| 1555 | you can use the <a href="#pdf-pcall"><code>pcall</code></a> function. | 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 | <p> | 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 | 1457 | The <b>for</b> statement has two forms: | |
| 1576 | <p> | 1458 | one numeric and one generic. |
| 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. | ||
| 1581 | 1459 | ||
| 1582 | 1460 | ||
| 1583 | <p> | 1461 | <p> |
| 1584 | You can query the metatable of any value | 1462 | The numeric <b>for</b> loop repeats a block of code while a |
| 1585 | through the <a href="#pdf-getmetatable"><code>getmetatable</code></a> function. | 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> | 1474 | <pre> |
| 1589 | You can replace the metatable of tables | 1475 | for v = <em>e1</em>, <em>e2</em>, <em>e3</em> do <em>block</em> end |
| 1590 | through the <a href="#pdf-setmetatable"><code>setmetatable</code></a> | 1476 | </pre><p> |
| 1591 | function. | 1477 | is equivalent to the code: |
| 1592 | You cannot change the metatable of other types from Lua | 1478 | |
| 1593 | (except by using the debug library); | 1479 | <pre> |
| 1594 | you must use the C API for that. | 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> | 1494 | <li> |
| 1598 | Tables and full userdata have individual metatables | 1495 | All three control expressions are evaluated only once, |
| 1599 | (although multiple tables and userdata can share their metatables). | 1496 | before the loop starts. |
| 1600 | Values of all other types share one single metatable per type; | 1497 | They must all result in numbers. |
| 1601 | that is, there is one single metatable for all numbers, | 1498 | </li> |
| 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>). | ||
| 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> | 1505 | <li> |
| 1608 | A metatable controls how an object behaves in arithmetic operations, | 1506 | If the third expression (the step) is absent, |
| 1609 | order comparisons, concatenation, length operation, and indexing. | 1507 | then a step of 1 is used. |
| 1610 | A metatable also can define a function to be called when a userdata | 1508 | </li> |
| 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. | ||
| 1618 | 1509 | ||
| 1510 | <li> | ||
| 1511 | You can use <b>break</b> to exit a <b>for</b> loop. | ||
| 1512 | </li> | ||
| 1619 | 1513 | ||
| 1620 | <p> | 1514 | <li> |
| 1621 | Metatables control the operations listed next. | 1515 | The loop variable <code>v</code> is local to the loop; |
| 1622 | Each operation is identified by its corresponding name. | 1516 | you cannot use its value after the <b>for</b> ends or is broken. |
| 1623 | The key for each operation is a string with its name prefixed by | 1517 | If you need this value, |
| 1624 | two underscores, '<code>__</code>'; | 1518 | assign it to another variable before breaking or exiting the loop. |
| 1625 | for instance, the key for operation "add" is the | 1519 | </li> |
| 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. | ||
| 1629 | 1520 | ||
| 1521 | </ul> | ||
| 1630 | 1522 | ||
| 1631 | <p> | 1523 | <p> |
| 1632 | The code shown here in Lua is only illustrative; | 1524 | The generic <b>for</b> statement works over functions, |
| 1633 | the real behavior is hard coded in the interpreter | 1525 | called <em>iterators</em>. |
| 1634 | and it is much more efficient than this simulation. | 1526 | On each iteration, the iterator function is called to produce a new value, |
| 1635 | All functions used in these descriptions | 1527 | stopping when this new value is <b>nil</b>. |
| 1636 | (<a href="#pdf-rawget"><code>rawget</code></a>, <a href="#pdf-tonumber"><code>tonumber</code></a>, etc.) | 1528 | The generic <b>for</b> loop has the following syntax: |
| 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 | ||
| 1640 | 1529 | ||
| 1641 | <pre> | 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 | </pre><p> | 1533 | </pre><p> |
| 1644 | This should be read as | 1534 | A <b>for</b> statement like |
| 1645 | 1535 | ||
| 1646 | <pre> | 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 | </pre><p> | 1538 | </pre><p> |
| 1539 | is equivalent to the code: | ||
| 1649 | 1540 | ||
| 1650 | That is, the access to a metamethod does not invoke other metamethods, | 1541 | <pre> |
| 1651 | and the access to objects with no metatables does not fail | 1542 | do |
| 1652 | (it simply results in <b>nil</b>). | 1543 | local <em>f</em>, <em>s</em>, <em>var</em> = <em>explist</em> |
| 1653 | 1544 | while true do | |
| 1654 | 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 | <ul> | 1554 | <ul> |
| 1657 | 1555 | ||
| 1658 | <li><b>"add":</b> | 1556 | <li> |
| 1659 | the <code>+</code> operation. | 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> | 1582 | |
| 1664 | The function <code>getbinhandler</code> below defines how Lua chooses a handler | 1583 | |
| 1665 | for a binary operation. | 1584 | <h3>3.3.6 - <a name="3.3.6">Function Calls as Statements</a></h3><p> |
| 1666 | First, Lua tries the first operand. | 1585 | To allow possible side-effects, |
| 1667 | If its type does not define a handler for the operation, | 1586 | function calls can be executed as statements: |
| 1668 | then Lua tries the second operand. | ||
| 1669 | 1587 | ||
| 1670 | <pre> | 1588 | <pre> |
| 1671 | function getbinhandler (op1, op2, event) | 1589 | stat ::= functioncall |
| 1672 | return metatable(op1)[event] or metatable(op2)[event] | ||
| 1673 | end | ||
| 1674 | </pre><p> | 1590 | </pre><p> |
| 1675 | By using this function, | 1591 | In this case, all returned values are thrown away. |
| 1676 | the behavior of the <code>op1 + op2</code> is | 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 | <pre> | 1602 | <pre> |
| 1679 | function add_event (op1, op2) | 1603 | stat ::= <b>local</b> namelist [&lsquo<b>=</b>’ explist] |
| 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 | ||
| 1693 | </pre><p> | 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. | 1610 | <p> |
| 1700 | </li> | 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. | 1616 | <p> |
| 1706 | </li> | 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> | 1625 | <h2>3.4 - <a name="3.4">Expressions</a></h2> |
| 1731 | the unary <code>-</code> operation. | ||
| 1732 | 1626 | ||
| 1627 | <p> | ||
| 1628 | The basic expressions in Lua are the following: | ||
| 1733 | 1629 | ||
| 1734 | <pre> | 1630 | <pre> |
| 1735 | function unm_event (op) | 1631 | exp ::= prefixexp |
| 1736 | local o = tonumber(op) | 1632 | exp ::= <b>nil</b> | <b>false</b> | <b>true</b> |
| 1737 | if o then -- operand is numeric? | 1633 | exp ::= Number |
| 1738 | return -o -- '-' here is the primitive 'unm' | 1634 | exp ::= String |
| 1739 | else -- the operand is not numeric. | 1635 | exp ::= function |
| 1740 | -- Try to get a handler from the operand | 1636 | exp ::= tableconstructor |
| 1741 | local h = metatable(op).__unm | 1637 | exp ::= &lsquo<b>...</b>’ |
| 1742 | if h then | 1638 | exp ::= exp binop exp |
| 1743 | -- call the handler with the operand | 1639 | exp ::= unop exp |
| 1744 | return (h(op)) | 1640 | prefixexp ::= var | functioncall | &lsquo<b>(</b>’ exp &lsquo<b>)</b>’ |
| 1745 | else -- no handler available: default behavior | 1641 | </pre> |
| 1746 | error(···) | ||
| 1747 | end | ||
| 1748 | end | ||
| 1749 | end | ||
| 1750 | </pre><p> | ||
| 1751 | </li> | ||
| 1752 | 1642 | ||
| 1753 | <li><b>"concat":</b> | 1643 | <p> |
| 1754 | the <code>..</code> (concatenation) operation. | 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> | 1655 | <p> |
| 1758 | function concat_event (op1, op2) | 1656 | Binary operators comprise arithmetic operators (see <a href="#3.4.1">§3.4.1</a>), |
| 1759 | if (type(op1) == "string" or type(op1) == "number") and | 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>), |
| 1760 | (type(op2) == "string" or type(op2) == "number") then | 1658 | and the concatenation operator (see <a href="#3.4.5">§3.4.5</a>). |
| 1761 | return op1 .. op2 -- primitive string concatenation | 1659 | Unary operators comprise the unary minus (see <a href="#3.4.1">§3.4.1</a>), |
| 1762 | else | 1660 | the unary <b>not</b> (see <a href="#3.4.4">§3.4.4</a>), |
| 1763 | local h = getbinhandler(op1, op2, "__concat") | 1661 | and the unary <em>length operator</em> (see <a href="#3.4.6">§3.4.6</a>). |
| 1764 | if h then | 1662 | |
| 1765 | return (h(op1, op2)) | 1663 | |
| 1766 | else | 1664 | <p> |
| 1767 | error(···) | 1665 | Both function calls and vararg expressions can result in multiple values. |
| 1768 | end | 1666 | If an expression is used as a statement |
| 1769 | end | 1667 | (only possible for function calls (see <a href="#3.3.6">§3.3.6</a>)), |
| 1770 | end | 1668 | then its return list is adjusted to zero elements, |
| 1771 | </pre><p> | 1669 | thus discarding all returned values. |
| 1772 | </li> | 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 | <pre> | 1682 | <pre> |
| 1779 | function len_event (op) | 1683 | f() -- adjusted to 0 results |
| 1780 | if type(op) == "string" then | 1684 | g(f(), x) -- f() is adjusted to 1 result |
| 1781 | return strlen(op) -- primitive string length | 1685 | g(x, f()) -- g gets x plus all results from f() |
| 1782 | else | 1686 | a,b,c = f(), x -- f() is adjusted to 1 result (c gets nil) |
| 1783 | local h = metatable(op).__len | 1687 | a,b = ... -- a gets the first vararg parameter, b gets |
| 1784 | if h then | 1688 | -- the second (both a and b can get nil if there |
| 1785 | return (h(op)) -- call handler with the operand | 1689 | -- is no corresponding vararg parameter) |
| 1786 | elseif type(op) == "table" then | 1690 | |
| 1787 | return #op -- primitive table length | 1691 | a,b,c = x, f() -- f() is adjusted to 2 results |
| 1788 | else -- no handler available: error | 1692 | a,b,c = f() -- f() is adjusted to 3 results |
| 1789 | error(···) | 1693 | return f() -- returns all results from f() |
| 1790 | end | 1694 | return ... -- returns all received vararg parameters |
| 1791 | end | 1695 | return x,y,f() -- returns x, y, and all results from f() |
| 1792 | end | 1696 | {f()} -- creates a list with all results from f() |
| 1793 | </pre><p> | 1697 | {...} -- creates a list with all vararg parameters |
| 1794 | See <a href="#2.5.5">§2.5.5</a> for a description of the length of a table. | 1698 | {f(), nil} -- f() is adjusted to 1 result |
| 1795 | </li> | 1699 | </pre> |
| 1796 | 1700 | ||
| 1797 | <li><b>"eq":</b> | 1701 | <p> |
| 1798 | the <code>==</code> operation. | 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> | 1710 | |
| 1807 | function getcomphandler (op1, op2, event) | 1711 | <h3>3.4.1 - <a name="3.4.1">Arithmetic Operators</a></h3><p> |
| 1808 | if type(op1) ~= type(op2) then return nil end | 1712 | Lua supports the usual arithmetic operators: |
| 1809 | local mm1 = metatable(op1)[event] | 1713 | the binary <code>+</code> (addition), |
| 1810 | local mm2 = metatable(op2)[event] | 1714 | <code>-</code> (subtraction), <code>*</code> (multiplication), |
| 1811 | if mm1 == mm2 then return mm1 else return nil end | 1715 | <code>/</code> (division), <code>%</code> (modulo), and <code>^</code> (exponentiation); |
| 1812 | end | 1716 | and unary <code>-</code> (negation). |
| 1813 | </pre><p> | 1717 | If the operands are numbers, or strings that can be converted to |
| 1814 | The "eq" event is defined as follows: | 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 | <pre> | 1724 | <pre> |
| 1817 | function eq_event (op1, op2) | 1725 | a % b == a - math.floor(a/b)*b |
| 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 | ||
| 1832 | </pre><p> | 1726 | </pre><p> |
| 1833 | <code>a ~= b</code> is equivalent to <code>not (a == b)</code>. | 1727 | That is, it is the remainder of a division that rounds |
| 1834 | </li> | 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> | 1733 | |
| 1860 | the <code><=</code> operation. | 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 | <pre> | 1754 | <pre> |
| 1895 | function gettable_event (table, key) | 1755 | == ~= < > <= >= |
| 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 | ||
| 1913 | </pre><p> | 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 | <pre> | 1825 | <pre> |
| 1921 | function settable_event (table, key, value) | 1826 | 10 or 20 --> 10 |
| 1922 | local h | 1827 | 10 or error() --> 10 |
| 1923 | if type(table) == "table" then | 1828 | nil or "a" --> "a" |
| 1924 | local v = rawget(table, key) | 1829 | nil and 10 --> nil |
| 1925 | if v ~= nil then rawset(table, key, value); return end | 1830 | false and error() --> false |
| 1926 | h = metatable(table).__newindex | 1831 | false and nil --> false |
| 1927 | if h == nil then rawset(table, key, value); return end | 1832 | false or nil --> nil |
| 1928 | else | 1833 | 10 and 20 --> 20 |
| 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 | ||
| 1939 | </pre><p> | 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 | <p> | 1855 | <p> |
| 1981 | Userdata and C functions are created sharing the environment | 1856 | The length operator is denoted by the unary prefix operator <code>#</code>. |
| 1982 | of the creating C function. | 1857 | The length of a string is its number of bytes |
| 1983 | Non-nested Lua functions | 1858 | (that is, the usual meaning of string length when each |
| 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>) | 1859 | character is one byte). |
| 1985 | are created sharing the global environment. | ||
| 1986 | Nested Lua functions are created sharing the current environment | ||
| 1987 | of where it is defined. | ||
| 1988 | 1860 | ||
| 1989 | 1861 | ||
| 1990 | <p> | 1862 | <p> |
| 1991 | Environments associated with userdata have no meaning for Lua. | 1863 | The length of a table <code>t</code> is defined to be any |
| 1992 | It is only a convenience feature for programmers to associate a table to | 1864 | integer index <code>n</code> |
| 1993 | a userdata. | 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 | <p> | 1879 | <p> |
| 1997 | The environment associated with a C function can be directly | 1880 | A program can modify the behavior of the length operator for |
| 1998 | accessed by C code (see <a href="#3.3">§3.3</a>). | 1881 | any value but strings through metamethods (see <a href="#2.4">§2.4</a>). |
| 1999 | It is used as the default environment for other C functions | ||
| 2000 | and userdata created by the function. | ||
| 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> | 1911 | <h3>3.4.8 - <a name="3.4.8">Table Constructors</a></h3><p> |
| 2034 | Lua implements an incremental mark-and-sweep collector. | 1912 | Table constructors are expressions that create tables. |
| 2035 | It uses two numbers to control its garbage-collection cycles: | 1913 | Every time a constructor is evaluated, a new table is created. |
| 2036 | the <em>garbage-collector pause</em> and | 1914 | A constructor can be used to create an empty table |
| 2037 | the <em>garbage-collector step multiplier</em>. | 1915 | or to create a table and initialize some of its fields. |
| 2038 | Both use percentage points as units | 1916 | The general syntax for constructors is |
| 2039 | (so that a value of 100 means an internal value of 1). | ||
| 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 | <p> | 1925 | <p> |
| 2043 | The garbage-collector pause | 1926 | Each field of the form <code>[exp1] = exp2</code> adds to the new table an entry |
| 2044 | controls how long the collector waits before starting a new cycle. | 1927 | with key <code>exp1</code> and value <code>exp2</code>. |
| 2045 | Larger values make the collector less aggressive. | 1928 | A field of the form <code>name = exp</code> is equivalent to |
| 2046 | Values smaller than 100 mean the collector will not wait to | 1929 | <code>["name"] = exp</code>. |
| 2047 | start a new cycle. | 1930 | Finally, fields of the form <code>exp</code> are equivalent to |
| 2048 | A value of 200 means that the collector waits for the total memory in use | 1931 | <code>[i] = exp</code>, where <code>i</code> are consecutive numerical integers, |
| 2049 | to double before starting a new cycle. | 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 | <p> | 1955 | <p> |
| 2053 | The step multiplier | 1956 | If the last field in the list has the form <code>exp</code> |
| 2054 | controls the relative speed of the collector relative to | 1957 | and the expression is a function call or a vararg expression, |
| 2055 | memory allocation. | 1958 | then all values returned by this expression enter the list consecutively |
| 2056 | Larger values make the collector more aggressive but also increase | 1959 | (see <a href="#3.4.9">§3.4.9</a>). |
| 2057 | the size of each incremental step. | 1960 | To avoid this, |
| 2058 | Values smaller than 100 make the collector too slow and | 1961 | enclose the function call or the vararg expression |
| 2059 | can result in the collector never finishing a cycle. | 1962 | in parentheses (see <a href="#3.4">§3.4</a>). |
| 2060 | The default, 200, means that the collector runs at "twice" | ||
| 2061 | the speed of memory allocation. | ||
| 2062 | 1963 | ||
| 2063 | 1964 | ||
| 2064 | <p> | 1965 | <p> |
| 2065 | If you set the step multiplier to a very large number | 1966 | The field list can have an optional trailing separator, |
| 2066 | (larger than 10% of the maximum number of | 1967 | as a convenience for machine-generated code. |
| 2067 | bytes that the program may use), | 1968 | |
| 2068 | the collector behaves like a stop-the-world collector. | 1969 | |
| 2069 | If you then set the pause to 200, | 1970 | |
| 2070 | the collector behaves as in old Lua versions, | 1971 | |
| 2071 | doing a complete collection every time Lua doubles its | 1972 | |
| 2072 | memory usage. | 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 | <p> | 1990 | <p> |
| 2076 | You can change these numbers by calling <a href="#lua_gc"><code>lua_gc</code></a> in C | 1991 | The form |
| 2077 | or <a href="#pdf-collectgarbage"><code>collectgarbage</code></a> in Lua. | 1992 | |
| 2078 | With these functions you can also control | 1993 | <pre> |
| 2079 | the collector directly (e.g., stop and restart it). | 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 | <p> | 2020 | <p> |
| 2086 | Using the C API, | 2021 | A call of the form <code>return</code> <em>functioncall</em> is called |
| 2087 | you can set garbage-collector metamethods for userdata (see <a href="#2.8">§2.8</a>). | 2022 | a <em>tail call</em>. |
| 2088 | These metamethods are also called <em>finalizers</em>. | 2023 | Lua implements <em>proper tail calls</em> |
| 2089 | Finalizers allow you to coordinate Lua's garbage collection | 2024 | (or <em>proper tail recursion</em>): |
| 2090 | with external resource management | 2025 | in a tail call, |
| 2091 | (such as closing files, network or database connections, | 2026 | the called function reuses the stack entry of the calling function. |
| 2092 | or freeing your own memory). | 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 | <p> | 2050 | <p> |
| 2096 | Garbage userdata with a field <code>__gc</code> in their metatables are not | 2051 | The syntax for function definition is |
| 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: | ||
| 2102 | 2052 | ||
| 2103 | <pre> | 2053 | <pre> |
| 2104 | function gc_event (udata) | 2054 | function ::= <b>function</b> funcbody |
| 2105 | local h = metatable(udata).__gc | 2055 | funcbody ::= &lsquo<b>(</b>’ [parlist] &lsquo<b>)</b>’ block <b>end</b> |
| 2106 | if h then | ||
| 2107 | h(udata) | ||
| 2108 | end | ||
| 2109 | end | ||
| 2110 | </pre> | 2056 | </pre> |
| 2111 | 2057 | ||
| 2112 | <p> | 2058 | <p> |
| 2113 | At the end of each garbage-collection cycle, | 2059 | The following syntactic sugar simplifies function definitions: |
| 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. | ||
| 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> | 2088 | <pre> |
| 2128 | A <em>weak table</em> is a table whose elements are | 2089 | local function f () <em>body</em> end |
| 2129 | <em>weak references</em>. | 2090 | </pre><p> |
| 2130 | A weak reference is ignored by the garbage collector. | 2091 | translates to |
| 2131 | In other words, | ||
| 2132 | if the only references to an object are weak references, | ||
| 2133 | then the garbage collector will collect this object. | ||
| 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> | 2098 | <pre> |
| 2137 | A weak table can have weak keys, weak values, or both. | 2099 | local f = function () <em>body</em> end |
| 2138 | A table with weak keys allows the collection of its keys, | 2100 | </pre><p> |
| 2139 | but prevents the collection of its values. | 2101 | (This only makes a difference when the body of the function |
| 2140 | A table with both weak keys and weak values allows the collection of | 2102 | contains references to <code>f</code>.) |
| 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. | ||
| 2150 | 2103 | ||
| 2151 | 2104 | ||
| 2152 | <p> | 2105 | <p> |
| 2153 | Userdata with finalizers has a special behavior in weak tables. | 2106 | A function definition is an executable expression, |
| 2154 | When a userdata is a value in a weak table, | 2107 | whose value has type <em>function</em>. |
| 2155 | it is removed from the table the first time it is collected, | 2108 | When Lua pre-compiles a chunk, |
| 2156 | before running its finalizer. | 2109 | all its function bodies are pre-compiled too. |
| 2157 | When it is a key, however, | 2110 | Then, whenever Lua executes the function definition, |
| 2158 | it is removed from the table only when it is really freed, | 2111 | the function is <em>instantiated</em> (or <em>closed</em>). |
| 2159 | after running its finalizer. | 2112 | This function instance (or <em>closure</em>) |
| 2160 | This behavior allows the finalizer to access values | 2113 | is the final value of the expression. |
| 2161 | associated with the userdata through weak tables. | 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 | <p> | 2119 | <p> |
| 2165 | A table with weak keys and strong values | 2120 | Parameters act as local variables that are |
| 2166 | is also called an <em>ephemeron table</em>. | 2121 | initialized with the argument values: |
| 2167 | In an ephemeron table, | 2122 | |
| 2168 | a value is considered reachable only if its key is reachable. | 2123 | <pre> |
| 2169 | In particular, | 2124 | parlist ::= namelist [&lsquo<b>,</b>’ &lsquo<b>...</b>’] | &lsquo<b>...</b>’ |
| 2170 | if the only reference to a key comes from its value, | 2125 | </pre><p> |
| 2171 | the pair is removed. | 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 | <p> | 2146 | <p> |
| 2175 | After you use a table as a metatable, | 2147 | As an example, consider the following definitions: |
| 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. | ||
| 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 | <p> | 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 | <p> | 2224 | <p> |
| 2230 | A coroutine yields by calling <a href="#pdf-coroutine.yield"><code>coroutine.yield</code></a>. | 2225 | Notice that, in a declaration like <code>local x = x</code>, |
| 2231 | When a coroutine yields, | 2226 | the new <code>x</code> being declared is not in scope yet, |
| 2232 | the corresponding <a href="#pdf-coroutine.resume"><code>coroutine.resume</code></a> returns immediately, | 2227 | and so the second <code>x</code> refers to the outside variable. |
| 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>. | ||
| 2242 | 2228 | ||
| 2243 | 2229 | ||
| 2244 | <p> | 2230 | <p> |
| 2245 | Like <a href="#pdf-coroutine.create"><code>coroutine.create</code></a>, | 2231 | Because of the lexical scoping rules, |
| 2246 | the <a href="#pdf-coroutine.wrap"><code>coroutine.wrap</code></a> function also creates a coroutine, | 2232 | local variables can be freely accessed by functions |
| 2247 | but instead of returning the coroutine itself, | 2233 | defined inside their scope. |
| 2248 | it returns a function that, when called, resumes the coroutine. | 2234 | A local variable used by an inner function is called |
| 2249 | Any arguments passed to this function | 2235 | an <em>upvalue</em>, or <em>external local variable</em>, |
| 2250 | go as extra arguments to <a href="#pdf-coroutine.resume"><code>coroutine.resume</code></a>. | 2236 | inside the inner function. |
| 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. | ||
| 2256 | 2237 | ||
| 2257 | 2238 | ||
| 2258 | <p> | 2239 | <p> |
| 2259 | As an example, | 2240 | Notice that each execution of a <b>local</b> statement |
| 2260 | consider the following code: | 2241 | defines new local variables. |
| 2242 | Consider the following example: | ||
| 2261 | 2243 | ||
| 2262 | <pre> | 2244 | <pre> |
| 2263 | function foo (a) | 2245 | a = {} |
| 2264 | print("foo", a) | 2246 | local x = 20 |
| 2265 | return coroutine.yield(2*a) | 2247 | for i=1,10 do |
| 2248 | local y = 0 | ||
| 2249 | a[i] = function () y=y+1; return x+y end | ||
| 2266 | end | 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 | </pre><p> | 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 | <p> | 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 | <p> | 2291 | <p> |
| 2330 | Lua uses a <em>virtual stack</em> to pass values to and from C. | 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 | <p> | 2333 | <p> |
| 2372 | When you interact with Lua API, | 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 | <p> | 2379 | <p> |
| 2418 | Unless otherwise noted, | 2380 | Unless otherwise noted, |
| 2419 | any function that accepts valid indices also accepts <em>pseudo-indices</em>, | 2381 | any function that accepts valid indices also accepts <em>pseudo-indices</em>, |
| 2420 | which represent some Lua values that are accessible to C code | 2382 | which represent some Lua values that are accessible to C code |
| 2421 | but which are not in the stack. | 2383 | but which are not in the stack. |
| 2422 | Pseudo-indices are used to access the thread environment, | 2384 | Pseudo-indices are used to access |
| 2423 | the function environment, | 2385 | the registry |
| 2424 | the registry, | 2386 | and the upvalues of a C function (see <a href="#4.4">§4.4</a>). |
| 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>. | ||
| 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 | <p> | 2394 | <p> |
| 2448 | When a C function is created, | 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 | <p> | 2421 | <p> |
| 2475 | Lua provides a <em>registry</em>, | 2422 | Lua provides a <em>registry</em>, |
| @@ -2503,29 +2450,6 @@ The following constants are defined: · 27 unmodified lines | |||
| 2503 | the main thread of the state. | 2450 | the main thread of the state. |
| 2504 | (The main thread is the one created together with the state.) | 2451 | (The main thread is the one created together with the state.) |
| 2505 | </li> | 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 | <li><b>LUA_RIDX_GLOBALS:</b> At this index the registry has | 2454 | <li><b>LUA_RIDX_GLOBALS:</b> At this index the registry has |
| 2531 | the global environment. | 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 | <p> | 2465 | <p> |
| 2542 | Internally, Lua uses the C <code>longjmp</code> facility to handle errors. | 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 | <p> | 2504 | <p> |
| 2581 | Internally, Lua uses the C <code>longjmp</code> facility to yield a coroutine. | 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 | let us set some terminology. | 2524 | let us set some terminology. |
| 2601 | We have a C function called from Lua which we will call | 2525 | We have a C function called from Lua which we will call |
| 2602 | the <em>original function</em>. | 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 | which we will call the <em>callee function</em>, | 2528 | which we will call the <em>callee function</em>, |
| 2605 | that may yield the current thread. | 2529 | that then yields the current thread. |
| 2606 | (This will happen when the callee function is <a href="#lua_yieldk"><code>lua_yieldk</code></a>, | 2530 | (This can happen when the callee function is <a href="#lua_yieldk"><code>lua_yieldk</code></a>, |
| 2607 | 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> | 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 | and the function called by them yields.) | 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 | <p> | 2572 | <p> |
| 2649 | Here we list all functions and types from the C API in | 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 | <hr><h3><a name="lua_Alloc"><code>lua_Alloc</code></a></h3> | 2614 | <hr><h3><a name="lua_Alloc"><code>lua_Alloc</code></a></h3> |
| 2679 | <pre>typedef void * (*lua_Alloc) (void *ud, | 2615 | <pre>typedef void * (*lua_Alloc) (void *ud, |
| 2680 | void *ptr, | 2616 | void *ptr, |
| @@ -2768,12 +2704,12 @@ but it seems a safe assumption.) · 87 unmodified lines | |||
| 2768 | <pre>lua_CFunction lua_atpanic (lua_State *L, lua_CFunction panicf);</pre> | 2704 | <pre>lua_CFunction lua_atpanic (lua_State *L, lua_CFunction panicf);</pre> |
| 2769 | 2705 | ||
| 2770 | <p> | 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 | <p> | 2710 | <p> |
| 2775 | The panic function should not try to run anything on the failed Lua state. | 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 | to gather information about the state. | 2713 | to gather information about the state. |
| 2778 | In particular, the error message is at the top of the stack. | 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 | Here it is in C: | 2760 | Here it is in C: |
| 2825 | 2761 | ||
| 2826 | <pre> | 2762 | <pre> |
| 2827 | lua_getfield(L, LUA_ENVIRONINDEX, "f"); /* function to be called */ | 2763 | lua_getglobal(L, "f"); /* function to be called */ |
| 2828 | lua_pushstring(L, "how"); /* 1st argument */ | 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 | lua_getfield(L, -1, "x"); /* push result of t.x (2nd arg) */ | 2766 | lua_getfield(L, -1, "x"); /* push result of t.x (2nd arg) */ |
| 2831 | lua_remove(L, -2); /* remove 't' from the stack */ | 2767 | lua_remove(L, -2); /* remove 't' from the stack */ |
| 2832 | lua_pushinteger(L, 14); /* 3rd argument */ | 2768 | lua_pushinteger(L, 14); /* 3rd argument */ |
| 2833 | lua_call(L, 3, 1); /* call 'f' with 3 arguments and 1 result */ | 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 | </pre><p> | 2771 | </pre><p> |
| 2836 | Note that the code above is "balanced": | 2772 | Note that the code above is "balanced": |
| 2837 | at its end, the stack is back to its original configuration. | 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 | <p> | 2785 | <p> |
| 2850 | This function behaves exactly like <a href="#lua_call"><code>lua_call</code></a>, | 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 | (that is, the function does nothing); | 2916 | (that is, the function does nothing); |
| 2981 | if <code>n</code> is 0, the result is the empty string. | 2917 | if <code>n</code> is 0, the result is the empty string. |
| 2982 | Concatenation is performed following the usual semantics of Lua | 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 | <li><b><code>LUA_GCSETPAUSE</code>:</b> | 3045 | <li><b><code>LUA_GCSETPAUSE</code>:</b> |
| 3110 | sets <code>data</code> as the new value | 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 | The function returns the previous value of the pause. | 3048 | The function returns the previous value of the pause. |
| 3113 | </li> | 3049 | </li> |
| 3114 | 3050 | ||
| 3115 | <li><b><code>LUA_GCSETSTEPMUL</code>:</b> | 3051 | <li><b><code>LUA_GCSETSTEPMUL</code>:</b> |
| 3116 | sets <code>data</code> as the new value for the <em>step multiplier</em> of | 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 | The function returns the previous value of the step multiplier. | 3054 | The function returns the previous value of the step multiplier. |
| 3119 | </li> | 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 | <pre>int lua_getctx (lua_State *L, int *ctx);</pre> | 3082 | <pre>int lua_getctx (lua_State *L, int *ctx);</pre> |
| 3147 | 3083 | ||
| 3148 | <p> | 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 | to retrieve the status of the thread and a context information. | 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 | Pushes onto the stack the value <code>t[k]</code>, | 3133 | Pushes onto the stack the value <code>t[k]</code>, |
| 3198 | where <code>t</code> is the value at the given valid index. | 3134 | where <code>t</code> is the value at the given valid index. |
| 3199 | As in Lua, this function may trigger a metamethod | 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 | <p> | 3146 | <p> |
| 3211 | Pushes onto the stack the value of the global <code>name</code>. | 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 | This function pops the key from the stack | 3180 | This function pops the key from the stack |
| 3248 | (putting the resulting value in its place). | 3181 | (putting the resulting value in its place). |
| 3249 | As in Lua, this function may trigger a metamethod | 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 | <p> | 3386 | <p> |
| 3454 | Returns the "length" of the value at the given acceptable index; | 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 | The result is pushed on the stack. | 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 | <p> | 3444 | <p> |
| 3512 | The <code>source</code> argument gives a name to the chunk, | 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 | <p> | 3671 | <p> |
| 3731 | This function behaves exactly like <a href="#lua_pcall"><code>lua_pcall</code></a>, | 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 | <p> | 3709 | <p> |
| 3769 | When a C function is created, | 3710 | When a C function is created, |
| 3770 | it is possible to associate some values with it, | 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 | these values are then accessible to the function whenever it is called. | 3713 | these values are then accessible to the function whenever it is called. |
| 3773 | To associate values with a C function, | 3714 | To associate values with a C function, |
| 3774 | first these values should be pushed onto the stack | 3715 | first these values should be pushed onto the stack |
| @@ -3784,11 +3725,18 @@ associated with the function. · 9 unmodified lines | |||
| 3784 | The maximum value for <code>n</code> is 255. | 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 | <hr><h3><a name="lua_pushcfunction"><code>lua_pushcfunction</code></a></h3><p> | 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 | <pre>void lua_pushcfunction (lua_State *L, lua_CFunction f);</pre> | 3740 | <pre>void lua_pushcfunction (lua_State *L, lua_CFunction f);</pre> |
| 3793 | 3741 | ||
| 3794 | <p> | 3742 | <p> |
| @@ -3946,7 +3894,7 @@ onto the stack. · 151 unmodified lines | |||
| 3946 | Lua makes (or reuses) an internal copy of the given string, | 3894 | Lua makes (or reuses) an internal copy of the given string, |
| 3947 | so the memory at <code>s</code> can be freed or reused immediately after | 3895 | so the memory at <code>s</code> can be freed or reused immediately after |
| 3948 | the function returns. | 3896 | the function returns. |
| 3949 | The string cannot contain embedded zeros; | 3897 | The string should not contain embedded zeros; |
| 3950 | it is assumed to end at the first zero. | 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 | Returns a pointer to the internal copy of the string. | 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 | <p> | 4184 | <p> |
| 4233 | This function pops the value from the stack. | 4185 | This function pops the value from the stack. |
| 4234 | As in Lua, this function may trigger a metamethod | 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 | <p> | 4197 | <p> |
| 4246 | Pops a value from the stack and | 4198 | Pops a value from the stack and |
| 4247 | sets it as the new value of global <code>name</code>. | 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 | <p> | 4230 | <p> |
| 4282 | This function pops both the key and the value from the stack. | 4231 | This function pops both the key and the value from the stack. |
| 4283 | As in Lua, this function may trigger a metamethod | 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 | Converts the Lua value at the given acceptable index | 4328 | Converts the Lua value at the given acceptable index |
| 4380 | to the signed integral type <a href="#lua_Integer"><code>lua_Integer</code></a>. | 4329 | to the signed integral type <a href="#lua_Integer"><code>lua_Integer</code></a>. |
| 4381 | The Lua value must be a number or a string convertible to a number | 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 | otherwise, <a href="#lua_tointeger"><code>lua_tointeger</code></a> returns 0. | 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 | Converts the Lua value at the given acceptable index | 4379 | Converts the Lua value at the given acceptable index |
| 4431 | to the C type <a href="#lua_Number"><code>lua_Number</code></a> (see <a href="#lua_Number"><code>lua_Number</code></a>). | 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 | The Lua value must be a number or a string convertible to a number | 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 | otherwise, <a href="#lua_tonumber"><code>lua_tonumber</code></a> returns 0. | 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 | <p> | 4546 | <p> |
| 4598 | This function is equivalent to <a href="#lua_yieldk"><code>lua_yieldk</code></a>, | 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 | Therefore, when the thread resumes, | 4549 | Therefore, when the thread resumes, |
| 4601 | it returns to the function that called | 4550 | it returns to the function that called |
| 4602 | the function calling <code>lua_yield</code>. | 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 | <p> | 4580 | <p> |
| 4632 | When the coroutine is resumed again, | 4581 | When the coroutine is resumed again, |
| 4633 | Lua calls the given continuation function <code>k</code> to continue | 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 | This continuation function receives the same stack | 4584 | This continuation function receives the same stack |
| 4636 | from the previous function, | 4585 | from the previous function, |
| 4637 | with the results removed and | 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 | <p> | 4600 | <p> |
| 4652 | Lua has no built-in debugging facilities. | 4601 | Lua has no built-in debugging facilities. |
| @@ -4830,7 +4779,7 @@ you can write the following code: · 177 unmodified lines | |||
| 4830 | 4779 | ||
| 4831 | <pre> | 4780 | <pre> |
| 4832 | lua_Debug ar; | 4781 | lua_Debug ar; |
| 4833 | lua_getfield(L, LUA_ENVIRONINDEX, "f"); /* get global 'f' */ | 4782 | lua_getglobal(L, "f"); /* get global 'f' */ |
| 4834 | lua_getinfo(L, ">S", &ar); | 4783 | lua_getinfo(L, ">S", &ar); |
| 4835 | printf("%d\n", ar.linedefined); | 4784 | printf("%d\n", ar.linedefined); |
| 4836 | </pre> | 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 | <p> | 5080 | <p> |
| 5132 | 5081 | ||
| @@ -5150,6 +5099,14 @@ top of the basic API, · 17 unmodified lines | |||
| 5150 | and so they provide nothing that cannot be done with that API. | 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 | <p> | 5110 | <p> |
| 5154 | Several functions in the auxiliary library are used to | 5111 | Several functions in the auxiliary library are used to |
| 5155 | check C function arguments. | 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 | <p> | 5126 | <p> |
| 5170 | Here we list all functions and types from the auxiliary library | 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 | Adds the string pointed to by <code>s</code> with length <code>l</code> to | 5149 | Adds the string pointed to by <code>s</code> with length <code>l</code> to |
| 5193 | the buffer <code>B</code> | 5150 | the buffer <code>B</code> |
| 5194 | (see <a href="#luaL_Buffer"><code>luaL_Buffer</code></a>). | 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 | Adds the zero-terminated string pointed to by <code>s</code> | 5176 | Adds the zero-terminated string pointed to by <code>s</code> |
| 5220 | to the buffer <code>B</code> | 5177 | to the buffer <code>B</code> |
| 5221 | (see <a href="#luaL_Buffer"><code>luaL_Buffer</code></a>). | 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 | <p> | 5618 | <p> |
| 5662 | Returns the "length" of the value at the given acceptable index | 5619 | Returns the "length" of the value at the given acceptable index |
| 5663 | as a number; | 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 | Raises an error if the result of the operation is not a number. | 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 | Creates a new Lua state. | 5726 | Creates a new Lua state. |
| 5770 | It calls <a href="#lua_newstate"><code>lua_newstate</code></a> with an | 5727 | It calls <a href="#lua_newstate"><code>lua_newstate</code></a> with an |
| 5771 | allocator based on the standard C <code>realloc</code> function | 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 | an error message to the standard error output in case of fatal | 5730 | an error message to the standard error output in case of fatal |
| 5774 | errors. | 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 | <hr><h3><a name="luaL_openlibs"><code>luaL_openlibs</code></a></h3><p> | 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 | <pre>void luaL_openlibs (lua_State *L);</pre> | 5790 | <pre>void luaL_openlibs (lua_State *L);</pre> |
| 5788 | 5791 | ||
| 5789 | <p> | 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 | <p> | 5964 | <p> |
| 5962 | Type for arrays of functions to be registered by | 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 | <code>name</code> is the function name and <code>func</code> is a pointer to | 5967 | <code>name</code> is the function name and <code>func</code> is a pointer to |
| 5965 | the function. | 5968 | the function. |
| 5966 | Any array of <a href="#luaL_Reg"><code>luaL_Reg</code></a> must end with an sentinel entry | 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 | const luaL_Reg *l);</pre> | 5980 | const luaL_Reg *l);</pre> |
| 5978 | 5981 | ||
| 5979 | <p> | 5982 | <p> |
| 5980 | Opens a library. | 5983 | This macro is equivalent to calling <a href="#luaL_openlib"><code>luaL_openlib</code></a> |
| 5981 | 5984 | with no upvalues. | |
| 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. | ||
| 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 | <p> | 6119 | <p> |
| 6140 | The standard Lua libraries provide useful functions | 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 | <p> | 6185 | <p> |
| 6206 | The basic library provides some core functions to Lua. | 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 | <li><b>"setpause":</b> | 6247 | <li><b>"setpause":</b> |
| 6268 | sets <code>arg</code> as the new value for the <em>pause</em> of | 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 | Returns the previous value for <em>pause</em>. | 6250 | Returns the previous value for <em>pause</em>. |
| 6271 | </li> | 6251 | </li> |
| 6272 | 6252 | ||
| 6273 | <li><b>"setstepmul":</b> | 6253 | <li><b>"setstepmul":</b> |
| 6274 | sets <code>arg</code> as the new value for the <em>step multiplier</em> of | 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 | Returns the previous value for <em>step</em>. | 6256 | Returns the previous value for <em>step</em>. |
| 6277 | </li> | 6257 | </li> |
| 6278 | 6258 | ||
| @@ -6321,7 +6301,7 @@ to the message. · 42 unmodified lines | |||
| 6321 | <p> | 6301 | <p> |
| 6322 | <hr><h3><a name="pdf-_G"><code>_G</code></a></h3> | 6302 | <hr><h3><a name="pdf-_G"><code>_G</code></a></h3> |
| 6323 | A global variable (not a function) that | 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 | Lua itself does not use this variable; | 6305 | Lua itself does not use this variable; |
| 6326 | changing its value does not affect any environment, | 6306 | changing its value does not affect any environment, |
| 6327 | nor vice-versa. | 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 | <p> | 6326 | <p> |
| 6372 | <hr><h3><a name="pdf-load"><code>load (ld [, source [, mode]])</code></a></h3> | 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 | If there are no errors, | 6347 | If there are no errors, |
| 6393 | returns the compiled chunk as a function; | 6348 | returns the compiled chunk as a function; |
| 6394 | otherwise, returns <b>nil</b> plus the error message. | 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 | <p> | 6356 | <p> |
| 6399 | <code>source</code> is used as the source of the chunk for error messages | 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 | When absent, | 6359 | When absent, |
| 6402 | it defaults to "<code>=(load)</code>". | 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 | <p> | 6377 | <p> |
| 6420 | This function is similar to <a href="#pdf-load"><code>load</code></a>, | 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 | of the created function in case of success. | 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 | The parameters after <code>env</code> are similar to those of <a href="#pdf-load"><code>load</code></a>, too. | 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 | The order in which the indices are enumerated is not specified, | 6445 | The order in which the indices are enumerated is not specified, |
| 6487 | <em>even for numeric indices</em>. | 6446 | <em>even for numeric indices</em>. |
| 6488 | (To traverse a table in numeric order, | 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 | <p> | 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 | represents 10, '<code>B</code>' represents 11, and so forth, | 6600 | represents 10, '<code>B</code>' represents 11, and so forth, |
| 6642 | with '<code>Z</code>' representing 35. | 6601 | with '<code>Z</code>' representing 35. |
| 6643 | In base 10 (the default), the number can have a decimal part, | 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 | In other bases, only unsigned integers are accepted. | 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 | <p> | 6667 | <p> |
| 6709 | The operations related to coroutines comprise a sub-library of | 6668 | The operations related to coroutines comprise a sub-library of |
| 6710 | the basic library and come inside the table <a name="pdf-coroutine"><code>coroutine</code></a>. | 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 | <p> | 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 | <p> | 6777 | <p> |
| 6819 | The package library provides basic | 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 | <p> | 7158 | <p> |
| 7200 | This library provides generic functions for string manipulation, | 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 | which can be a string, a table, or a function. | 7336 | which can be a string, a table, or a function. |
| 7378 | <code>gsub</code> also returns, as its second value, | 7337 | <code>gsub</code> also returns, as its second value, |
| 7379 | the total number of matches that occurred. | 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 | <p> | 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 | <h4>Character Class:</h4><p> | 7483 | <h4>Character Class:</h4><p> |
| @@ -7552,8 +7512,6 @@ represents the character <em>x</em> itself. · 28 unmodified lines | |||
| 7552 | 7512 | ||
| 7553 | <li><b><code>%x</code>:</b> represents all hexadecimal digits.</li> | 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 | <li><b><code>%<em>x</em></code>:</b> (where <em>x</em> is any non-alphanumeric character) | 7515 | <li><b><code>%<em>x</em></code>:</b> (where <em>x</em> is any non-alphanumeric character) |
| 7558 | represents the character <em>x</em>. | 7516 | represents the character <em>x</em>. |
| 7559 | This is the standard way to escape the magic characters. | 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 | string <code>"flaaap"</code>, there will be two captures: 3 and 5. | 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 | 7672 | <h2>6.5 - <a name="6.5">Table Manipulation</a></h2><p> | |
| 7718 | <h2>5.5 - <a name="5.5">Table Manipulation</a></h2><p> | ||
| 7719 | This library provides generic functions for table manipulation. | 7673 | This library provides generic functions for table manipulation. |
| 7720 | It provides all its functions inside the table <a name="pdf-table"><code>table</code></a>. | 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 | Inserts element <code>value</code> at position <code>pos</code> in <code>table</code>, | 7701 | Inserts element <code>value</code> at position <code>pos</code> in <code>table</code>, |
| 7748 | shifting up other elements to open space, if necessary. | 7702 | shifting up other elements to open space, if necessary. |
| 7749 | The default value for <code>pos</code> is <code>n+1</code>, | 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 | so that a call <code>table.insert(t,x)</code> inserts <code>x</code> at the end | 7705 | so that a call <code>table.insert(t,x)</code> inserts <code>x</code> at the end |
| 7752 | of table <code>t</code>. | 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 | from <code>table[1]</code> to <code>table[n]</code>, | 7742 | from <code>table[1]</code> to <code>table[n]</code>, |
| 7789 | where <code>n</code> is the length of the table. | 7743 | where <code>n</code> is the length of the table. |
| 7790 | If <code>comp</code> is given, | 7744 | If <code>comp</code> is given, |
| 7791 | then it must be a function that receives two table elements, | 7745 | then it must be a function that receives two table elements |
| 7792 | and returns true | 7746 | and returns true when the first element must come |
| 7793 | when the first is less than the second | 7747 | before the second in the final order |
| 7794 | (so that <code>not comp(a[i+1],a[i])</code> will be true after the sort). | 7748 | (so that <code>not comp(a[i+1],a[i])</code> will be true after the sort). |
| 7795 | If <code>comp</code> is not given, | 7749 | If <code>comp</code> is not given, |
| 7796 | then the standard Lua operator <code><</code> is used instead. | 7750 | then the standard Lua operator <code><</code> is used instead. |
| @@ -7815,7 +7769,7 @@ This function is equivalent to · 18 unmodified lines | |||
| 7815 | except that the above code can be written only for a fixed number | 7769 | except that the above code can be written only for a fixed number |
| 7816 | of elements. | 7770 | of elements. |
| 7817 | By default, <code>i</code> is 1 and <code>j</code> is the length of the list, | 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 | <p> | 7782 | <p> |
| 7829 | This library is an interface to the standard C math library. | 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 | <p> | 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 | <p> | 8111 | <p> |
| 8158 | This library provides bitwise operations. | 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 | <p> | 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 | <p> | 8162 | <p> |
| 8209 | Returns the number <code>x</code> rotated <code>disp</code> bits to the left. | 8163 | Returns a boolean signaling |
| 8210 | The number <code>disp</code> may be any representable integer. | 8164 | whether the bitwise and of its operands is different from zero. |
| 8165 | |||
| 8166 | |||
| 8211 | 8167 | ||
| 8212 | 8168 | ||
| 8213 | <p> | 8169 | <p> |
| 8214 | For any valid displacement, | 8170 | <hr><h3><a name="pdf-bit.bxor"><code>bit.bxor (···)</code></a></h3> |
| 8215 | the following identity holds: | ||
| 8216 | 8171 | ||
| 8217 | <pre> | 8172 | |
| 8218 | assert(bit.rotate(x, disp) == bit.rotate(x, disp % 32)) | 8173 | <p> |
| 8219 | </pre><p> | 8174 | Returns the bitwise exclusive or of its operands. |
| 8220 | This allows you to consider that | ||
| 8221 | negative displacements rotate to the right. | ||
| 8222 | 8175 | ||
| 8223 | 8176 | ||
| 8224 | 8177 | ||
| 8225 | 8178 | ||
| 8226 | <p> | 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 | <p> | 8183 | <p> |
| @@ -8243,42 +8196,82 @@ For positive displacements, · 12 unmodified lines | |||
| 8243 | the following equality holds: | 8196 | the following equality holds: |
| 8244 | 8197 | ||
| 8245 | <pre> | 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 | </pre> | 8200 | </pre> |
| 8248 | 8201 | ||
| 8202 | |||
| 8203 | |||
| 8249 | <p> | 8204 | <p> |
| 8250 | For negative displacements, | 8205 | <hr><h3><a name="pdf-bit.rol"><code>bit.rol (x, disp)</code></a></h3> |
| 8251 | the following equality holds: | 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 | <pre> | 8217 | <pre> |
| 8254 | assert(bit.bshift(b, disp) == math.floor(b * 2^disp)) | 8218 | assert(bit.rol(x, disp) == bit.rol(x, disp % 32)) |
| 8255 | </pre> | 8219 | </pre><p> |
| 8220 | In particular, | ||
| 8221 | negative displacements rotate to the right. | ||
| 8222 | |||
| 8223 | |||
| 8224 | |||
| 8256 | 8225 | ||
| 8257 | <p> | 8226 | <p> |
| 8258 | This shift operation is what is called logical shift. | 8227 | <hr><h3><a name="pdf-bit.ror"><code>bit.ror (x, disp)</code></a></h3> |
| 8259 | For an arithmetic shift, | ||
| 8260 | you should use the arithmetic operators. | ||
| 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 | <p> | 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 | <p> | 8248 | <p> |
| 8270 | Returns a boolean signaling | 8249 | <hr><h3><a name="pdf-bit.rshift"><code>bit.rshift (x, disp)</code></a></h3> |
| 8271 | whether the bitwise and of its operands is different from zero. | ||
| 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 | <p> | 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 | <p> | 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 | <p> | 8284 | <p> |
| 8292 | The I/O library provides two different styles for file manipulation. | 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 | <p> | 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 | <p> | 8361 | <p> |
| @@ -8387,6 +8380,11 @@ that is, it iterates over the lines of the default input file. · 18 unmodified lines | |||
| 8387 | In this case it does not close the file when the loop ends. | 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 | <p> | 8390 | <p> |
| @@ -8521,7 +8519,7 @@ Saves any written data to <code>file</code>. · 128 unmodified lines | |||
| 8521 | 8519 | ||
| 8522 | 8520 | ||
| 8523 | <p> | 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 | <p> | 8525 | <p> |
| @@ -8533,11 +8531,17 @@ Therefore, the construction · 5 unmodified lines | |||
| 8533 | <pre> | 8531 | <pre> |
| 8534 | for line in file:lines() do <em>body</em> end | 8532 | for line in file:lines() do <em>body</em> end |
| 8535 | </pre><p> | 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 | (Unlike <a href="#pdf-io.lines"><code>io.lines</code></a>, this function does not close the file | 8536 | (Unlike <a href="#pdf-io.lines"><code>io.lines</code></a>, this function does not close the file |
| 8538 | when the loop ends.) | 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 | <p> | 8547 | <p> |
| @@ -8551,7 +8555,7 @@ For each format, · 7 unmodified lines | |||
| 8551 | the function returns a string (or a number) with the characters read, | 8555 | the function returns a string (or a number) with the characters read, |
| 8552 | or <b>nil</b> if it cannot read data with the specified format. | 8556 | or <b>nil</b> if it cannot read data with the specified format. |
| 8553 | When called without formats, | 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 | (see below). | 8559 | (see below). |
| 8556 | 8560 | ||
| 8557 | 8561 | ||
| @@ -8571,11 +8575,16 @@ On end of file, it returns the empty string. · 13 unmodified lines | |||
| 8571 | </li> | 8575 | </li> |
| 8572 | 8576 | ||
| 8573 | <li><b>"*l":</b> | 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 | returning <b>nil</b> on end of file. | 8579 | returning <b>nil</b> on end of file. |
| 8576 | This is the default format. | 8580 | This is the default format. |
| 8577 | </li> | 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 | <li><b><em>number</em>:</b> | 8588 | <li><b><em>number</em>:</b> |
| 8580 | reads a string with up to this number of characters, | 8589 | reads a string with up to this number of characters, |
| 8581 | returning <b>nil</b> on end of file. | 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 | <p> | 8692 | <p> |
| 8684 | This library is implemented through table <a name="pdf-os"><code>os</code></a>. | 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 | <p> | 8918 | <p> |
| 8910 | This library provides | 8919 | This library provides |
| 8911 | the functionality of the debug interface to Lua programs. | 8920 | the functionality of the debug interface to Lua programs. |
| 8912 | You should exert care when using this library. | 8921 | You should exert care when using this library. |
| 8913 | The functions provided here should be used exclusively for debugging | 8922 | Several of these functions |
| 8914 | and similar tasks, such as profiling. | 8923 | violate basic assumptions about Lua code |
| 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 | ||
| 8920 | (e.g., that variables local to a function | 8924 | (e.g., that variables local to a function |
| 8921 | cannot be accessed from outside or | 8925 | cannot be accessed from outside; |
| 8922 | that userdata metatables cannot be changed by Lua code) | 8926 | that userdata metatables cannot be changed by Lua code; |
| 8927 | that Lua programs do not crash) | ||
| 8923 | and therefore can compromise otherwise secure code. | 8928 | and therefore can compromise otherwise secure code. |
| 8929 | Moreover, some functions in this library may be slow. | ||
| 8924 | 8930 | ||
| 8925 | 8931 | ||
| 8926 | <p> | 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 | <p> | 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 | <p> | 9228 | <p> |
| 9223 | Although Lua has been designed as an extension language, | 9229 | Although Lua has been designed as an extension language, |
| @@ -9268,7 +9274,7 @@ For instance, an invocation like · 44 unmodified lines | |||
| 9268 | </pre><p> | 9274 | </pre><p> |
| 9269 | will first set <code>a</code> to 1, then print the value of <code>a</code> (which is '<code>1</code>'), | 9275 | will first set <code>a</code> to 1, then print the value of <code>a</code> (which is '<code>1</code>'), |
| 9270 | and finally run the file <code>script.lua</code> with no arguments. | 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 | <p> | 9280 | <p> |
| @@ -9352,7 +9358,7 @@ as in · 77 unmodified lines | |||
| 9352 | #!/usr/local/bin/lua | 9358 | #!/usr/local/bin/lua |
| 9353 | </pre><p> | 9359 | </pre><p> |
| 9354 | (Of course, | 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 | If <code>lua</code> is in your <code>PATH</code>, | 9362 | If <code>lua</code> is in your <code>PATH</code>, |
| 9357 | then | 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 | <p> | 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 | from Lua 5.1 to Lua 5.2. | 9376 | from Lua 5.1 to Lua 5.2. |
| 9371 | You can avoid some incompatibilities compiling Lua with | 9377 | You can avoid some incompatibilities compiling Lua with |
| 9372 | appropriate options (see file <code>luaconf.h</code>). | 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 | <ul> | 9385 | <ul> |
| 9380 | 9386 | ||
| 9381 | <li> | 9387 | <li> |
| @@ -9396,12 +9402,19 @@ Threads do not have individual environments. · 14 unmodified lines | |||
| 9396 | All threads share a single fixed environment. | 9402 | All threads share a single fixed environment. |
| 9397 | </li> | 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 | </ul> | 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 | <ul> | 9418 | <ul> |
| 9406 | 9419 | ||
| 9407 | <li> | 9420 | <li> |
| @@ -9412,9 +9425,13 @@ You must explicitly require it. · 4 unmodified lines | |||
| 9412 | <li> | 9425 | <li> |
| 9413 | Functions <code>setfenv</code> and <code>getfenv</code> are deprecated. | 9426 | Functions <code>setfenv</code> and <code>getfenv</code> are deprecated. |
| 9414 | To set the environment of a Lua function, | 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>. | 9428 | use the variable <code>_ENV</code> or the new function <a href="#pdf-loadin"><code>loadin</code></a>. |
| 9416 | (If you really need them, | 9429 | </li> |
| 9417 | you may use their equivalents in the debug library.) | 9430 | |
| 9431 | <li> | ||
| 9432 | Function <code>ipairs</code> is deprecated. | ||
| 9433 | Use a numerical for loop instead, | ||
| 9434 | or write it in Lua. | ||
| 9418 | </li> | 9435 | </li> |
| 9419 | 9436 | ||
| 9420 | <li> | 9437 | <li> |
| @@ -9432,20 +9449,44 @@ Function <code>unpack</code> was moved into the table library · 11 unmodified lines | |||
| 9432 | and therefore must be called as <a href="#pdf-table.unpack"><code>table.unpack</code></a>. | 9449 | and therefore must be called as <a href="#pdf-table.unpack"><code>table.unpack</code></a>. |
| 9433 | </li> | 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 | </ul> | 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 | <ul> | 9475 | <ul> |
| 9442 | 9476 | ||
| 9443 | <li> | 9477 | <li> |
| 9444 | Pseudoindex <code>LUA_GLOBALSINDEX</code> was removed. | 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, | 9479 | You must get the global environment from the registry |
| 9446 | if the C function does not change its standard environment. | 9480 | (see <a href="#4.5">§4.5</a>). |
| 9447 | Otherwise, you should get the global environment from the registry | 9481 | </li> |
| 9448 | (see <a href="#3.5">§3.5</a>). | 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 | </li> | 9490 | </li> |
121 more lines aren’t shown here.
| @@ -9,25 +9,31 @@ blockquote, .display { · 8 unmodified lines | |||
| 9 | color: black ; | 9 | color: black ; |
| 10 | padding: 8px ; | 10 | padding: 8px ; |
| 11 | border: solid #a0a0a0 2px ; | 11 | border: solid #a0a0a0 2px ; |
| 12 | background-color: #EFEFFF ; | 12 | xbackground-color: #EFEFFF ; |
| 13 | margin-left: 0px ; | 13 | margin-left: 0px ; |
| 14 | } | 14 | } |
| 15 | 15 | ||
| 16 | .review { | ||
| 17 | color: red ; | ||
| 18 | } | ||
| 19 | |||
| 20 | .external { | 16 | .external { |
| 21 | padding-right: 15px; | 17 | padding-right: 15px; |
| 22 | background: transparent url(external.png) no-repeat center right; | 18 | background: transparent url(external.png) no-repeat center right; |
| 23 | } | 19 | } |
| 24 | 20 | ||
| 25 | tt, kbd { | 21 | tt, kbd, code { |
| 26 | font-size: 120% ; | 22 | font-size: 120% ; |
| 27 | xcolor: black ; | 23 | xcolor: black ; |
| 28 | xpadding: 4px ; | 24 | xpadding: 4px ; |
| 29 | xbackground-color: #E0E0E0 ; | 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 | </STYLE> | 37 | </STYLE> |
| 32 | </HEAD> | 38 | </HEAD> |
| 33 | 39 | ||
| @@ -39,6 +45,11 @@ tt, kbd { · 5 unmodified lines | |||
| 39 | Welcome to Lua 5.2 | 45 | Welcome to Lua 5.2 |
| 40 | </H1> | 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 | <A HREF="#about">about</A> | 53 | <A HREF="#about">about</A> |
| 43 | · | 54 | · |
| 44 | <A HREF="#install">installation</A> | 55 | <A HREF="#install">installation</A> |
| @@ -51,11 +62,6 @@ Welcome to Lua 5.2 · 6 unmodified lines | |||
| 51 | <HR> | 62 | <HR> |
| 52 | <P> | 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 | <H2><A NAME="about">About Lua</A></H2> | 65 | <H2><A NAME="about">About Lua</A></H2> |
| 60 | 66 | ||
| 61 | Lua is a powerful, fast, lightweight, embeddable scripting language | 67 | Lua is a powerful, fast, lightweight, embeddable scripting language |
| @@ -270,6 +276,24 @@ compiler: · 208 unmodified lines | |||
| 270 | 276 | ||
| 271 | <H2><A NAME="changes">Changes since Lua 5.1</A></H2> | 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 | Here are the main changes in Lua since its last release. | 297 | Here are the main changes in Lua since its last release. |
| 274 | The | 298 | The |
| 275 | <A HREF="contents.html">reference manual</A> | 299 | <A HREF="contents.html">reference manual</A> |
| @@ -281,13 +305,13 @@ lists the · 5 unmodified lines | |||
| 281 | <UL> | 305 | <UL> |
| 282 | <LI> new lexical environments. | 306 | <LI> new lexical environments. |
| 283 | <LI> no more fenv for threads. | 307 | <LI> no more fenv for threads. |
| 284 | <LI> ephemeron tables. | 308 | <LI> ephemeron tables |
| 285 | <LI> yieldable pcall/metamethods. | 309 | (tables with weak keys only visit value when key is accessible). |
| 310 | <LI> yieldable pcall and metamethods. | ||
| 286 | <LI> tables honor the <CODE>__len</CODE> metamethod. | 311 | <LI> tables honor the <CODE>__len</CODE> metamethod. |
| 287 | <LI> max constants per function raised to 2^26. | 312 | <LI> max constants per function raised to 2^26. |
| 288 | <LI> hex escapes in strings. | 313 | <LI> hex escapes in strings. |
| 289 | <LI> no more verification of opcode consistency. | 314 | <LI> no more verification of opcode consistency. |
| 290 | |||
| 291 | </UL> | 315 | </UL> |
| 292 | 316 | ||
| 293 | <H3>Libraries</H3> | 317 | <H3>Libraries</H3> |
| @@ -299,27 +323,39 @@ lists the · 5 unmodified lines | |||
| 299 | <LI> <CODE>loadlib</CODE> may load libraries with global names (RTLD_GLOBAL). | 323 | <LI> <CODE>loadlib</CODE> may load libraries with global names (RTLD_GLOBAL). |
| 300 | <LI> new function <CODE>package.searchpath</CODE>. | 324 | <LI> new function <CODE>package.searchpath</CODE>. |
| 301 | <LI> optional base in <CODE>math.log</CODE>. | 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 | <LI> closing a pipe returns exit status. | 327 | <LI> closing a pipe returns exit status. |
| 304 | <LI> <CODE>os.exit</CODE> may close state. | 328 | <LI> <CODE>os.exit</CODE> may close state. |
| 305 | <LI> new option 'isrunning' for <CODE>collectgarbage</CODE> and <CODE>lua_gc</CODE>. | 329 | <LI> new option 'isrunning' for <CODE>collectgarbage</CODE> and <CODE>lua_gc</CODE>. |
| 306 | <LI> frontier patterns. | 330 | <LI> frontier patterns. |
| 307 | <LI> <CODE>ipairs</CODE> now goes until #t. | 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 | </UL> | 347 | </UL> |
| 310 | 348 | ||
| 311 | <H3>Implementation</H3> | 349 | <H3>Implementation</H3> |
| 312 | <UL> | 350 | <UL> |
| 313 | <LI> emergency garbage collector | 351 | <LI> emergency garbage collector |
| 314 | (core forces a full collection when allocation fails). | 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 | <LI> udata with finalizers are kept in a separated list for the GC. | 353 | <LI> udata with finalizers are kept in a separated list for the GC. |
| 319 | <LI> CallInfo stack now is a linked list. | 354 | <LI> CallInfo stack now is a linked list. |
| 320 | <LI> internal (immutable) version of ctypes. | 355 | <LI> internal (immutable) version of ctypes. |
| 321 | <LI> parser uses much less C-stack space (no more auto arrays). | 356 | <LI> parser uses much less C-stack space (no more auto arrays). |
| 322 | <LI> new hash for floats. | 357 | <LI> new hash for floats. |
| 358 | <LI> handling of non-string error messages in the standalone interpreter. | ||
| 323 | </UL> | 359 | </UL> |
| 324 | 360 | ||
| 325 | 361 | ||
| @@ -372,10 +408,10 @@ THE SOFTWARE. · 46 unmodified lines | |||
| 372 | <HR> | 408 | <HR> |
| 373 | <SMALL> | 409 | <SMALL> |
| 374 | Last update: | 410 | Last update: |
| 375 | Wed Jan 13 15:35:05 BRST 2010 | 411 | Tue May 18 13:59:06 BRT 2010 |
| 376 | </SMALL> | 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 | </BODY> | 417 | </BODY> |
| @@ -7,32 +7,48 @@ BIN= $(TOP)/src · 6 unmodified lines | |||
| 7 | SRC= $(TOP)/src | 7 | SRC= $(TOP)/src |
| 8 | TST= $(TOP)/test | 8 | TST= $(TOP)/test |
| 9 | 9 | ||
| 10 | T= test | ||
| 10 | CC= gcc | 11 | CC= gcc |
| 11 | CFLAGS= -O2 -Wall -I$(INC) $(MYCFLAGS) | 12 | CFLAGS= -O2 -Wall -I$(INC) $(MYCFLAGS) |
| 12 | MYCFLAGS= | 13 | MYCFLAGS= |
| 13 | MYLDFLAGS= -Wl,-E | 14 | MYLIBS= -lm # -ldl -lreadline -lncurses -Wl,-E |
| 14 | MYLIBS= -lm | ||
| 15 | #MYLIBS= -lm -Wl,-E -ldl -lreadline -lhistory -lncurses | ||
| 16 | RM= rm -f | 15 | RM= rm -f |
| 17 | 16 | ||
| 17 | |||
| 18 | default: | 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 | min: min.c | 21 | min: min.c |
| 22 | $(CC) $(CFLAGS) $@.c -L$(LIB) -llua $(MYLIBS) | 22 | $(CC) $(CFLAGS) -o $T min.c -L$(LIB) -llua $(MYLIBS) |
| 23 | echo 'print"Hello there!"' | ./a.out | 23 | echo 'print"Hello there!"' | ./$T |
| 24 | ./a.out $(TST)/hello.lua | 24 | ./$T $(TST)/hello.lua |
| 25 | echo 'print("Hello world, from",_VERSION,"!")' | ./a.out | 25 | echo 'print("Hello world, from",_VERSION,"!")' | ./$T |
| 26 | 26 | ||
| 27 | noparser: noparser.o | 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 | $(BIN)/luac $(TST)/hello.lua | 29 | $(BIN)/luac $(TST)/hello.lua |
| 30 | -./a.out luac.out | 30 | -./$T luac.out |
| 31 | -./a.out -e'a=1' | 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: | 48 | so: |
| 34 | $(CC) $(CFLAGS) one.c $(MYLIBS) | 49 | $(CC) $(CFLAGS) -shared -o dummy.so dummy.c |
| 35 | ./a.out $(TST)/hello.lua | 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 | strict: | 53 | strict: |
| 38 | -$(BIN)/lua -e 'print(a);b=2' | 54 | -$(BIN)/lua -e 'print(a);b=2' |
| @@ -41,6 +57,6 @@ strict: · 2 unmodified lines | |||
| 41 | -$(BIN)/lua -lstrict -e 'function f() b=2 end f()' | 57 | -$(BIN)/lua -lstrict -e 'function f() b=2 end f()' |
| 42 | 58 | ||
| 43 | clean: | 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 | If any of the makes fail, you're probably not using the same libraries used | 4 | If any of the makes fail, you're probably not using the same libraries used |
| 5 | to build Lua. Set MYLIBS in Makefile or in the command line accordingly. | 5 | to build Lua. Set MYLIBS in Makefile or in the command line accordingly. |
| 6 | 6 | ||
| 7 | one.c | 7 | dummy.c: |
| 8 | Full Lua interpreter in a single file. | 8 | A minimal Lua library for testing dynamic loading. |
| 9 | Do "make one" for a demo. | 9 | Do "make so" for a demo. |
| 10 | 10 | ||
| 11 | luavs.bat | 11 | luavs.bat |
| 12 | Script to build Lua under "Visual Studio .NET Command Prompt". | 12 | Script to build Lua under "Visual Studio .NET Command Prompt". |
| 13 | Run it from the toplevel as etc\luavs.bat. | 13 | Run it from the toplevel as etc\luavs.bat. |
| 14 | 14 | ||
| 15 | min.c | 15 | min.c |
| 16 | A minimal Lua interpreter. | 16 | A minimal Lua interpreter for learning and for starting your own. |
| 17 | Good for learning and for starting your own. | ||
| 18 | Do "make min" for a demo. | 17 | Do "make min" for a demo. |
| 19 | 18 | ||
| 20 | noparser.c | 19 | noparser.c |
| 21 | Linking with noparser.o avoids loading the parsing modules in lualib.a. | 20 | Linking with noparser.o avoids loading the parsing modules in lualib.a. |
| 22 | Do "make noparser" for a demo. | 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 | strict.lua | 27 | strict.lua |
| 25 | Traps uses of undeclared global variables. | 28 | Traps uses of undeclared global variables. |
| 26 | Do "make strict" for a demo. | 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 | /* default is to build the full interpreter */ | 5 | /* default is to build the full interpreter */ |
| 6 | #ifndef MAKE_LIB | 6 | #ifndef MAKE_LIB |
| 7 | #ifndef MAKE_LUAC | 7 | #ifndef MAKE_LUAC |
| 8 | #undef MAKE_LUA | 8 | #ifndef MAKE_LUA |
| 9 | #define MAKE_LUA | 9 | #define MAKE_LUA |
| 10 | #endif | 10 | #endif |
| 11 | #endif | 11 | #endif |
| 12 | #endif | ||
| 12 | 13 | ||
| 13 | /* choose suitable platform-specific features */ | 14 | /* choose suitable platform-specific features */ |
| 14 | /* some of these may need extra libraries such as -ldl -lreadline -lncurses */ | 15 | /* some of these may need extra libraries such as -ldl -lreadline -lncurses */ |
| @@ -16,7 +17,6 @@ · 1 unmodified line | |||
| 16 | #define LUA_USE_LINUX | 17 | #define LUA_USE_LINUX |
| 17 | #define LUA_USE_MACOSX | 18 | #define LUA_USE_MACOSX |
| 18 | #define LUA_USE_POSIX | 19 | #define LUA_USE_POSIX |
| 19 | #define LUA_USE_DLOPEN | ||
| 20 | #define LUA_ANSI | 20 | #define LUA_ANSI |
| 21 | #endif | 21 | #endif |
| 22 | 22 | ||
| @@ -58,11 +58,11 @@ · 35 unmodified lines | |||
| 58 | #include "loslib.c" | 58 | #include "loslib.c" |
| 59 | #include "lstrlib.c" | 59 | #include "lstrlib.c" |
| 60 | #include "ltablib.c" | 60 | #include "ltablib.c" |
| 61 | #include "linit.c" | ||
| 61 | #endif | 62 | #endif |
| 62 | 63 | ||
| 63 | /* lua */ | 64 | /* lua */ |
| 64 | #ifdef MAKE_LUA | 65 | #ifdef MAKE_LUA |
| 65 | #include "linit.c" | ||
| 66 | #include "lua.c" | 66 | #include "lua.c" |
| 67 | #endif | 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 | lmem.o lobject.o lopcodes.o lparser.o lstate.o lstring.o ltable.o \ | 27 | lmem.o lobject.o lopcodes.o lparser.o lstate.o lstring.o ltable.o \ |
| 28 | ltm.o lundump.o lvm.o lzio.o | 28 | ltm.o lundump.o lvm.o lzio.o |
| 29 | LIB_O= lauxlib.o lbaselib.o lbitlib.o ldblib.o liolib.o lmathlib.o loslib.o \ | 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 | LUA_T= lua | 32 | LUA_T= lua |
| 33 | LUA_O= lua.o | 33 | LUA_O= lua.o |
| @@ -103,7 +103,7 @@ macosx: · 69 unmodified lines | |||
| 103 | $(MAKE) $(ALL) MYCFLAGS="-DLUA_USE_MACOSX" MYLIBS="-lreadline" | 103 | $(MAKE) $(ALL) MYCFLAGS="-DLUA_USE_MACOSX" MYLIBS="-lreadline" |
| 104 | 104 | ||
| 105 | mingw: | 105 | mingw: |
| 106 | $(MAKE) "LUA_A=lua51.dll" "LUA_T=lua.exe" \ | 106 | $(MAKE) "LUA_A=lua52.dll" "LUA_T=lua.exe" \ |
| 107 | "AR=$(CC) -shared -o" "RANLIB=strip --strip-unneeded" \ | 107 | "AR=$(CC) -shared -o" "RANLIB=strip --strip-unneeded" \ |
| 108 | "MYCFLAGS=-DLUA_BUILD_AS_DLL" "MYLIBS=" "MYLDFLAGS=-s" lua.exe | 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 | lstring.h ltable.h lundump.h lvm.h | 137 | lstring.h ltable.h lundump.h lvm.h |
| 138 | ldump.o: ldump.c lua.h luaconf.h lobject.h llimits.h lstate.h ltm.h \ | 138 | ldump.o: ldump.c lua.h luaconf.h lobject.h llimits.h lstate.h ltm.h \ |
| 139 | lzio.h lmem.h lundump.h | 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 \ | 140 | lfunc.o: lfunc.c lua.h luaconf.h lfunc.h lobject.h llimits.h lgc.h \ |
| 141 | lopcodes.h lstate.h ltm.h lzio.h | 141 | lstate.h ltm.h lzio.h lmem.h lopcodes.h |
| 142 | lgc.o: lgc.c lua.h luaconf.h ldebug.h lstate.h lobject.h llimits.h ltm.h \ | 142 | lgc.o: lgc.c lua.h luaconf.h ldebug.h lstate.h lobject.h llimits.h ltm.h \ |
| 143 | lzio.h lmem.h ldo.h lfunc.h lgc.h lstring.h ltable.h | 143 | lzio.h lmem.h ldo.h lfunc.h lgc.h lstring.h ltable.h |
| 144 | linit.o: linit.c lua.h luaconf.h lualib.h lauxlib.h | 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 | ltm.h lzio.h lstring.h lgc.h | 163 | ltm.h lzio.h lstring.h lgc.h |
| 164 | lstrlib.o: lstrlib.c lua.h luaconf.h lauxlib.h lualib.h | 164 | lstrlib.o: lstrlib.c lua.h luaconf.h lauxlib.h lualib.h |
| 165 | ltable.o: ltable.c lua.h luaconf.h ldebug.h lstate.h lobject.h llimits.h \ | 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 | ltablib.o: ltablib.c lua.h luaconf.h lauxlib.h lualib.h | 167 | ltablib.o: ltablib.c lua.h luaconf.h lauxlib.h lualib.h |
| 168 | ltm.o: ltm.c lua.h luaconf.h lobject.h llimits.h lstate.h ltm.h lzio.h \ | 168 | ltm.o: ltm.c lua.h luaconf.h lobject.h llimits.h lstate.h ltm.h lzio.h \ |
| 169 | lmem.h lstring.h lgc.h ltable.h | 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 | ** Lua API | 3 | ** Lua API |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -39,16 +39,6 @@ const char lua_ident[] = · 33 unmodified lines | |||
| 39 | "invalid index") | 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 | static TValue *index2addr (lua_State *L, int idx) { | 42 | static TValue *index2addr (lua_State *L, int idx) { |
| 53 | CallInfo *ci = L->ci; | 43 | CallInfo *ci = L->ci; |
| 54 | if (idx > 0) { | 44 | if (idx > 0) { |
| @@ -61,26 +51,25 @@ static TValue *index2addr (lua_State *L, int idx) { · 6 unmodified lines | |||
| 61 | api_check(L, idx != 0 && -idx <= L->top - (ci->func + 1), "invalid index"); | 51 | api_check(L, idx != 0 && -idx <= L->top - (ci->func + 1), "invalid index"); |
| 62 | return L->top + idx; | 52 | return L->top + idx; |
| 63 | } | 53 | } |
| 64 | else switch (idx) { /* pseudo-indices */ | 54 | else if (idx == LUA_REGISTRYINDEX) |
| 65 | case LUA_REGISTRYINDEX: return &G(L)->l_registry; | 55 | return &G(L)->l_registry; |
| 66 | case LUA_ENVIRONINDEX: { | 56 | else { /* upvalues */ |
| 67 | sethvalue(L, &L->env, getcurrenv(L)); | 57 | idx = LUA_REGISTRYINDEX - idx; |
| 68 | return &L->env; | 58 | api_check(L, idx <= UCHAR_MAX + 1, "upvalue index too large"); |
| 69 | } | 59 | if (ttislcf(ci->func)) /* light C function? */ |
| 70 | default: { | 60 | return cast(TValue *, luaO_nilobject); /* it has no upvalues */ |
| 71 | Closure *func = curr_func(L); | 61 | else { |
| 72 | idx = LUA_ENVIRONINDEX - idx; | 62 | Closure *func = clvalue(ci->func); |
| 73 | api_check(L, idx <= UCHAR_MAX + 1, "upvalue index too large"); | ||
| 74 | return (idx <= func->c.nupvalues) | 63 | return (idx <= func->c.nupvalues) |
| 75 | ? &func->c.upvalue[idx-1] | 64 | ? &func->c.upvalue[idx-1] |
| 76 | : cast(TValue *, luaO_nilobject); | 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 | ** capturing memory errors | 73 | ** capturing memory errors |
| 85 | */ | 74 | */ |
| 86 | static void growstack (lua_State *L, void *ud) { | 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 | LUA_API int lua_gettop (lua_State *L) { | 149 | LUA_API int lua_gettop (lua_State *L) { |
| 151 | return cast_int(L->top - (L->ci->func + 1)); | 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 | static void moveto (lua_State *L, TValue *fr, int idx) { | 194 | static void moveto (lua_State *L, TValue *fr, int idx) { |
| 196 | TValue *to = index2addr(L, idx); | 195 | TValue *to = index2addr(L, idx); |
| 197 | api_checkvalidindex(L, to); | 196 | api_checkvalidindex(L, to); |
| 198 | if (idx == LUA_ENVIRONINDEX) { | 197 | setobj(L, to, fr); |
| 199 | Closure *func = curr_func(L); | 198 | if (idx < LUA_REGISTRYINDEX) { /* function upvalue? */ |
| 200 | api_check(L, ttistable(fr), "table expected"); | 199 | lua_assert(ttisclosure(L->ci->func)); |
| 201 | func->c.env = hvalue(fr); | 200 | luaC_barrier(L, clvalue(L->ci->func), 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); | ||
| 208 | } | 201 | } |
| 209 | /* LUA_REGISTRYINDEX does not need gc barrier | 202 | /* LUA_REGISTRYINDEX does not need gc barrier |
| 210 | (collector revisits it before finishing collection) */ | 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 | LUA_API void lua_replace (lua_State *L, int idx) { | 207 | LUA_API void lua_replace (lua_State *L, int idx) { |
| 215 | lua_lock(L); | 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 | api_checknelems(L, 1); | 209 | api_checknelems(L, 1); |
| 220 | moveto(L, L->top - 1, idx); | 210 | moveto(L, L->top - 1, idx); |
| 221 | L->top--; | 211 | L->top--; |
| @@ -249,19 +239,19 @@ LUA_API void lua_pushvalue (lua_State *L, int idx) { · 27 unmodified lines | |||
| 249 | 239 | ||
| 250 | LUA_API int lua_type (lua_State *L, int idx) { | 240 | LUA_API int lua_type (lua_State *L, int idx) { |
| 251 | StkId o = index2addr(L, idx); | 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 | LUA_API const char *lua_typename (lua_State *L, int t) { | 246 | LUA_API const char *lua_typename (lua_State *L, int t) { |
| 257 | UNUSED(L); | 247 | UNUSED(L); |
| 258 | return typename(t); | 248 | return ttypename(t); |
| 259 | } | 249 | } |
| 260 | 250 | ||
| 261 | 251 | ||
| 262 | LUA_API int lua_iscfunction (lua_State *L, int idx) { | 252 | LUA_API int lua_iscfunction (lua_State *L, int idx) { |
| 263 | StkId o = index2addr(L, idx); | 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 | LUA_API lua_CFunction lua_tocfunction (lua_State *L, int idx) { | 378 | LUA_API lua_CFunction lua_tocfunction (lua_State *L, int idx) { |
| 389 | StkId o = index2addr(L, idx); | 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 | switch (ttype(o)) { | 405 | switch (ttype(o)) { |
| 413 | case LUA_TTABLE: return hvalue(o); | 406 | case LUA_TTABLE: return hvalue(o); |
| 414 | case LUA_TFUNCTION: return clvalue(o); | 407 | case LUA_TFUNCTION: return clvalue(o); |
| 408 | case LUA_TLCF: return cast(void *, cast(size_t, fvalue(o))); | ||
| 415 | case LUA_TTHREAD: return thvalue(o); | 409 | case LUA_TTHREAD: return thvalue(o); |
| 416 | case LUA_TUSERDATA: | 410 | case LUA_TUSERDATA: |
| 417 | case LUA_TLIGHTUSERDATA: | 411 | case LUA_TLIGHTUSERDATA: |
| @@ -468,8 +462,16 @@ LUA_API const char *lua_pushstring (lua_State *L, const char *s) { · 50 unmodified lines | |||
| 468 | lua_pushnil(L); | 462 | lua_pushnil(L); |
| 469 | return NULL; | 463 | return NULL; |
| 470 | } | 464 | } |
| 471 | else | 465 | else { |
| 472 | return lua_pushlstring(L, s, strlen(s)); | 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 | LUA_API void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n) { | 502 | LUA_API void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n) { |
| 501 | Closure *cl; | ||
| 502 | lua_lock(L); | 503 | lua_lock(L); |
| 503 | api_checknelems(L, n); | 504 | if (n == 0) { |
| 504 | api_check(L, n <= UCHAR_MAX, "upvalue index too large"); | 505 | setfvalue(L->top, fn); |
| 505 | luaC_checkGC(L); | 506 | } |
| 506 | cl = luaF_newCclosure(L, n, getcurrenv(L)); | 507 | else { |
| 507 | cl->c.f = fn; | 508 | Closure *cl; |
| 508 | L->top -= n; | 509 | api_checknelems(L, n); |
| 509 | while (n--) | 510 | api_check(L, n <= UCHAR_MAX, "upvalue index too large"); |
| 510 | setobj2n(L, &cl->c.upvalue[n], L->top+n); | 511 | luaC_checkGC(L); |
| 511 | setclvalue(L, L->top, cl); | 512 | cl = luaF_newCclosure(L, n); |
| 512 | lua_assert(iswhite(obj2gco(cl))); | 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 | api_incr_top(L); | 519 | api_incr_top(L); |
| 514 | lua_unlock(L); | 520 | lua_unlock(L); |
| 515 | } | 521 | } |
| @@ -616,7 +622,7 @@ LUA_API int lua_getmetatable (lua_State *L, int objindex) { · 100 unmodified lines | |||
| 616 | mt = uvalue(obj)->metatable; | 622 | mt = uvalue(obj)->metatable; |
| 617 | break; | 623 | break; |
| 618 | default: | 624 | default: |
| 619 | mt = G(L)->mt[ttype(obj)]; | 625 | mt = G(L)->mt[ttypenv(obj)]; |
| 620 | break; | 626 | break; |
| 621 | } | 627 | } |
| 622 | if (mt == NULL) | 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 | StkId o; | 641 | StkId o; |
| 636 | lua_lock(L); | 642 | lua_lock(L); |
| 637 | o = index2addr(L, idx); | 643 | o = index2addr(L, idx); |
| 638 | api_checkvalidindex(L, o); | 644 | api_checkvalidindex(L, o); |
| 639 | switch (ttype(o)) { | 645 | api_check(L, ttisuserdata(o), "userdata expected"); |
| 640 | case LUA_TFUNCTION: | 646 | if (uvalue(o)->env) { |
| 641 | sethvalue(L, L->top, clvalue(o)->c.env); | 647 | sethvalue(L, L->top, uvalue(o)->env); |
| 642 | break; | 648 | } else |
| 643 | case LUA_TUSERDATA: | 649 | setnilvalue(L->top); |
| 644 | sethvalue(L, L->top, uvalue(o)->env); | ||
| 645 | break; | ||
| 646 | default: | ||
| 647 | setnilvalue(L->top); | ||
| 648 | break; | ||
| 649 | } | ||
| 650 | api_incr_top(L); | 650 | api_incr_top(L); |
| 651 | lua_unlock(L); | 651 | lua_unlock(L); |
| 652 | } | 652 | } |
| @@ -737,7 +737,7 @@ LUA_API int lua_setmetatable (lua_State *L, int objindex) { · 84 unmodified lines | |||
| 737 | break; | 737 | break; |
| 738 | } | 738 | } |
| 739 | default: { | 739 | default: { |
| 740 | G(L)->mt[ttype(obj)] = mt; | 740 | G(L)->mt[ttypenv(obj)] = mt; |
| 741 | break; | 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 | StkId o; | 751 | StkId o; |
| 752 | int res = 1; | ||
| 753 | lua_lock(L); | 752 | lua_lock(L); |
| 754 | api_checknelems(L, 1); | 753 | api_checknelems(L, 1); |
| 755 | o = index2addr(L, idx); | 754 | o = index2addr(L, idx); |
| 756 | api_checkvalidindex(L, o); | 755 | api_checkvalidindex(L, o); |
| 757 | api_check(L, ttistable(L->top - 1), "table expected"); | 756 | api_check(L, ttisuserdata(o), "userdata expected"); |
| 758 | switch (ttype(o)) { | 757 | if (ttisnil(L->top - 1)) |
| 759 | case LUA_TFUNCTION: | 758 | uvalue(o)->env = NULL; |
| 760 | clvalue(o)->c.env = hvalue(L->top - 1); | 759 | else { |
| 761 | break; | 760 | api_check(L, ttistable(L->top - 1), "table expected"); |
| 762 | case LUA_TUSERDATA: | 761 | uvalue(o)->env = hvalue(L->top - 1); |
| 763 | uvalue(o)->env = hvalue(L->top - 1); | 762 | luaC_objbarrier(L, gcvalue(o), hvalue(L->top - 1)); |
| 764 | break; | ||
| 765 | default: | ||
| 766 | res = 0; | ||
| 767 | break; | ||
| 768 | } | 763 | } |
| 769 | if (res) luaC_objbarrier(L, gcvalue(o), hvalue(L->top - 1)); | ||
| 770 | L->top--; | 764 | L->top--; |
| 771 | lua_unlock(L); | 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 | ci->u.c.k = k; /* save continuation */ | 850 | ci->u.c.k = k; /* save continuation */ |
| 858 | ci->u.c.ctx = ctx; /* save context */ | 851 | ci->u.c.ctx = ctx; /* save context */ |
| 859 | /* save information for error recovery */ | 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 | ci->u.c.old_allowhook = L->allowhook; | 854 | ci->u.c.old_allowhook = L->allowhook; |
| 862 | ci->u.c.old_errfunc = L->errfunc; | 855 | ci->u.c.old_errfunc = L->errfunc; |
| 863 | L->errfunc = func; | 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 | if (!chunkname) chunkname = "?"; | 875 | if (!chunkname) chunkname = "?"; |
| 883 | luaZ_init(L, &z, reader, data); | 876 | luaZ_init(L, &z, reader, data); |
| 884 | status = luaD_protectedparser(L, &z, chunkname); | 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 | lua_unlock(L); | 890 | lua_unlock(L); |
| 886 | return status; | 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 | g = G(L); | 923 | g = G(L); |
| 919 | switch (what) { | 924 | switch (what) { |
| 920 | case LUA_GCSTOP: { | 925 | case LUA_GCSTOP: { |
| 921 | g->GCthreshold = MAX_LUMEM; | 926 | stopgc(g); |
| 922 | break; | 927 | break; |
| 923 | } | 928 | } |
| 924 | case LUA_GCRESTART: { | 929 | case LUA_GCRESTART: { |
| 925 | g->GCthreshold = g->totalbytes; | 930 | g->GCdebt = 0; |
| 926 | break; | 931 | break; |
| 927 | } | 932 | } |
| 928 | case LUA_GCCOLLECT: { | 933 | case LUA_GCCOLLECT: { |
| @@ -939,18 +944,22 @@ LUA_API int lua_gc (lua_State *L, int what, int data) { · 10 unmodified lines | |||
| 939 | break; | 944 | break; |
| 940 | } | 945 | } |
| 941 | case LUA_GCSTEP: { | 946 | case LUA_GCSTEP: { |
| 942 | lu_mem oldts = g->GCthreshold; | 947 | int stopped = gcstopped(g); |
| 943 | lu_mem a = (cast(lu_mem, data) << 10); | 948 | if (g->gckind == KGC_GEN) { /* generational mode? */ |
| 944 | g->GCthreshold = (a <= g->totalbytes) ? g->totalbytes - a : 0; | 949 | res = (g->lastmajormem == 0); /* 1 if will do major collection */ |
| 945 | while (g->GCthreshold <= g->totalbytes) { | 950 | luaC_step(L); /* do a single step */ |
| 946 | luaC_step(L); | 951 | } |
| 947 | if (g->gcstate == GCSpause) { /* end of cycle? */ | 952 | else { |
| 948 | res = 1; /* signal it */ | 953 | while (data-- >= 0) { |
| 949 | break; | 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? */ | 961 | if (stopped) /* collector was stopped? */ |
| 953 | g->GCthreshold = oldts; /* keep it that way */ | 962 | stopgc(g); /* keep it that way */ |
| 954 | break; | 963 | break; |
| 955 | } | 964 | } |
| 956 | case LUA_GCSETPAUSE: { | 965 | case LUA_GCSETPAUSE: { |
| @@ -964,7 +973,15 @@ LUA_API int lua_gc (lua_State *L, int what, int data) { · 7 unmodified lines | |||
| 964 | break; | 973 | break; |
| 965 | } | 974 | } |
| 966 | case LUA_GCISRUNNING: { | 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 | break; | 985 | break; |
| 969 | } | 986 | } |
| 970 | default: res = -1; /* invalid option */ | 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 | Udata *u; | 1071 | Udata *u; |
| 1055 | lua_lock(L); | 1072 | lua_lock(L); |
| 1056 | luaC_checkGC(L); | 1073 | luaC_checkGC(L); |
| 1057 | u = luaS_newudata(L, size, getcurrenv(L)); | 1074 | u = luaS_newudata(L, size, NULL); |
| 1058 | setuvalue(L, L->top, u); | 1075 | setuvalue(L, L->top, u); |
| 1059 | api_incr_top(L); | 1076 | api_incr_top(L); |
| 1060 | lua_unlock(L); | 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 | Closure *f; | 1086 | Closure *f; |
| 1069 | if (!ttisfunction(fi)) return NULL; | 1087 | if (!ttisclosure(fi)) return NULL; |
| 1070 | f = clvalue(fi); | 1088 | f = clvalue(fi); |
| 1071 | if (f->c.isC) { | 1089 | if (f->c.isC) { |
| 1072 | if (!(1 <= n && n <= f->c.nupvalues)) return NULL; | 1090 | if (!(1 <= n && n <= f->c.nupvalues)) return NULL; |
| 1073 | *val = &f->c.upvalue[n-1]; | 1091 | *val = &f->c.upvalue[n-1]; |
| 1092 | if (owner) *owner = obj2gco(f); | ||
| 1074 | return ""; | 1093 | return ""; |
| 1075 | } | 1094 | } |
| 1076 | else { | 1095 | else { |
| 1077 | Proto *p = f->l.p; | 1096 | Proto *p = f->l.p; |
| 1078 | if (!(1 <= n && n <= p->sizeupvalues)) return NULL; | 1097 | if (!(1 <= n && n <= p->sizeupvalues)) return NULL; |
| 1079 | *val = f->l.upvals[n-1]->v; | 1098 | *val = f->l.upvals[n-1]->v; |
| 1099 | if (owner) *owner = obj2gco(f->l.upvals[n - 1]); | ||
| 1080 | return getstr(p->upvalues[n-1].name); | 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 | const char *name; | 1106 | const char *name; |
| 1087 | TValue *val; | 1107 | TValue *val; |
| 1088 | lua_lock(L); | 1108 | lua_lock(L); |
| 1089 | name = aux_upvalue(index2addr(L, funcindex), n, &val); | 1109 | name = aux_upvalue(index2addr(L, funcindex), n, &val, NULL); |
| 1090 | if (name) { | 1110 | if (name) { |
| 1091 | setobj2s(L, L->top, val); | 1111 | setobj2s(L, L->top, val); |
| 1092 | api_incr_top(L); | 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 | LUA_API const char *lua_setupvalue (lua_State *L, int funcindex, int n) { | 1119 | LUA_API const char *lua_setupvalue (lua_State *L, int funcindex, int n) { |
| 1100 | const char *name; | 1120 | const char *name; |
| 1101 | TValue *val; | 1121 | TValue *val; |
| 1122 | GCObject *owner; | ||
| 1102 | StkId fi; | 1123 | StkId fi; |
| 1103 | lua_lock(L); | 1124 | lua_lock(L); |
| 1104 | fi = index2addr(L, funcindex); | 1125 | fi = index2addr(L, funcindex); |
| 1105 | api_checknelems(L, 1); | 1126 | api_checknelems(L, 1); |
| 1106 | name = aux_upvalue(fi, n, &val); | 1127 | name = aux_upvalue(fi, n, &val, &owner); |
| 1107 | if (name) { | 1128 | if (name) { |
| 1108 | L->top--; | 1129 | L->top--; |
| 1109 | setobj(L, val, L->top); | 1130 | setobj(L, val, L->top); |
| 1110 | luaC_barrier(L, clvalue(fi), L->top); | 1131 | luaC_barrier(L, owner, L->top); |
| 1111 | } | 1132 | } |
| 1112 | lua_unlock(L); | 1133 | lua_unlock(L); |
| 1113 | return name; | 1134 | return name; |
| @@ -1118,7 +1139,7 @@ static UpVal **getupvalref (lua_State *L, int fidx, int n, Closure **pf) { · 4 unmodified lines | |||
| 1118 | Closure *f; | 1139 | Closure *f; |
| 1119 | Proto *p; | 1140 | Proto *p; |
| 1120 | StkId fi = index2addr(L, fidx); | 1141 | StkId fi = index2addr(L, fidx); |
| 1121 | api_check(L, ttisfunction(fi), "function expected"); | 1142 | api_check(L, ttisclosure(fi), "Lua function expected"); |
| 1122 | f = clvalue(fi); | 1143 | f = clvalue(fi); |
| 1123 | api_check(L, !f->c.isC, "Lua function expected"); | 1144 | api_check(L, !f->c.isC, "Lua function expected"); |
| 1124 | p = f->l.p; | 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 | LUA_API void *lua_upvalueid (lua_State *L, int fidx, int n) { | 1152 | LUA_API void *lua_upvalueid (lua_State *L, int fidx, int n) { |
| 1132 | Closure *f; | 1153 | Closure *f; |
| 1133 | StkId fi = index2addr(L, fidx); | 1154 | StkId fi = index2addr(L, fidx); |
| 1134 | api_check(L, ttisfunction(fi), "function expected"); | 1155 | api_check(L, ttisclosure(fi), "function expected"); |
| 1135 | f = clvalue(fi); | 1156 | f = clvalue(fi); |
| 1136 | if (f->c.isC) { | 1157 | if (f->c.isC) { |
| 1137 | api_check(L, 1 <= n && n <= f->c.nupvalues, "invalid upvalue index"); | 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 | luaC_objbarrier(L, f1, *up2); | 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 | ** Auxiliary functions for building Lua libraries | 3 | ** Auxiliary functions for building Lua libraries |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -24,11 +24,6 @@ · 18 unmodified lines | |||
| 24 | #include "lauxlib.h" | 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 | ** Traceback | 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 | 345 | /* | |
| 351 | #define bufflen(B) ((B)->p - (B)->buffer) | 346 | ** check whether buffer is using a userdata on the stack as a temporary |
| 352 | #define bufffree(B) ((size_t)(LUAL_BUFFERSIZE - bufflen(B))) | 347 | ** buffer |
| 353 | 348 | */ | |
| 354 | #define LIMIT (LUA_MINSTACK/2) | 349 | #define buffonstack(B) ((B)->b != (B)->initb) |
| 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 | } | ||
| 367 | 350 | ||
| 368 | 351 | ||
| 369 | static void adjuststack (luaL_Buffer *B) { | 352 | /* |
| 370 | if (B->lvl > 1) { | 353 | ** returns a pointer to a free area with at least 'sz' bytes |
| 371 | lua_State *L = B->L; | 354 | */ |
| 372 | int toget = 1; /* number of levels to concat */ | 355 | LUALIB_API char *luaL_prepbuffsize (luaL_Buffer *B, size_t sz) { |
| 373 | size_t toplen = lua_rawlen(L, -1); | 356 | lua_State *L = B->L; |
| 374 | do { | 357 | if (B->size - B->n < sz) { /* not enough space? */ |
| 375 | size_t l = lua_rawlen(L, -(toget+1)); | 358 | char *newbuff; |
| 376 | if (B->lvl - toget + 1 >= LIMIT || toplen > l) { | 359 | size_t newsize = B->size * 2; /* double buffer size */ |
| 377 | toplen += l; | 360 | if (newsize - B->n < sz) /* not bit enough? */ |
| 378 | toget++; | 361 | newsize = B->n + sz; |
| 379 | } | 362 | if (newsize < B->n || newsize - B->n < sz) |
| 380 | else break; | 363 | luaL_error(L, "string too large"); |
| 381 | } while (toget < B->lvl); | 364 | newbuff = (char *)lua_newuserdata(L, newsize); /* create larger buffer */ |
| 382 | lua_concat(L, toget); | 365 | memcpy(newbuff, B->b, B->n); /* move content to new buffer */ |
| 383 | B->lvl = B->lvl - toget + 1; | 366 | if (buffonstack(B)) |
| 367 | lua_remove(L, -2); /* remove old buffer */ | ||
| 368 | B->b = newbuff; | ||
| 369 | B->size = newsize; | ||
| 384 | } | 370 | } |
| 385 | } | 371 | return &B->b[B->n]; |
| 386 | |||
| 387 | |||
| 388 | LUALIB_API char *luaL_prepbuffer (luaL_Buffer *B) { | ||
| 389 | if (emptybuffer(B)) | ||
| 390 | adjuststack(B); | ||
| 391 | return B->buffer; | ||
| 392 | } | 372 | } |
| 393 | 373 | ||
| 394 | 374 | ||
| 395 | LUALIB_API void luaL_addlstring (luaL_Buffer *B, const char *s, size_t l) { | 375 | LUALIB_API void luaL_addlstring (luaL_Buffer *B, const char *s, size_t l) { |
| 396 | while (l--) | 376 | char *b = luaL_prepbuffsize(B, l); |
| 397 | luaL_addchar(B, *s++); | 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 | LUALIB_API void luaL_pushresult (luaL_Buffer *B) { | 387 | LUALIB_API void luaL_pushresult (luaL_Buffer *B) { |
| 407 | emptybuffer(B); | 388 | lua_State *L = B->L; |
| 408 | lua_concat(B->L, B->lvl); | 389 | lua_pushlstring(L, B->b, B->n); |
| 409 | B->lvl = 1; | 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 | LUALIB_API void luaL_addvalue (luaL_Buffer *B) { | 401 | LUALIB_API void luaL_addvalue (luaL_Buffer *B) { |
| 414 | lua_State *L = B->L; | 402 | lua_State *L = B->L; |
| 415 | size_t vl; | 403 | size_t l; |
| 416 | const char *s = lua_tolstring(L, -1, &vl); | 404 | const char *s = lua_tolstring(L, -1, &l); |
| 417 | if (vl <= bufffree(B)) { /* fit into buffer? */ | 405 | if (buffonstack(B)) |
| 418 | memcpy(B->p, s, vl); /* put it there */ | 406 | lua_insert(L, -2); /* put value below buffer */ |
| 419 | B->p += vl; | 407 | luaL_addlstring(B, s, l); |
| 420 | lua_pop(L, 1); /* remove from stack */ | 408 | lua_remove(L, (buffonstack(B)) ? -2 : -1); /* remove value */ |
| 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 | } | ||
| 428 | } | 409 | } |
| 429 | 410 | ||
| 430 | 411 | ||
| 431 | LUALIB_API void luaL_buffinit (lua_State *L, luaL_Buffer *B) { | 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 | B->L = L; | 413 | B->L = L; |
| 434 | B->p = B->buffer; | 414 | B->b = B->initb; |
| 435 | B->lvl = 0; | 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) */ | 434 | /* index of free-list header */ |
| 448 | #define FREELIST_REF (LUA_RIDX_LAST + 1) /* free list of references */ | 435 | #define freelist "lua-freelist" |
| 449 | 436 | ||
| 450 | 437 | ||
| 451 | LUALIB_API int luaL_ref (lua_State *L, int t) { | 438 | LUALIB_API int luaL_ref (lua_State *L, int t) { |
| 452 | int ref; | 439 | int ref; |
| 453 | t = abs_index(L, t); | 440 | t = lua_absindex(L, t); |
| 454 | if (lua_isnil(L, -1)) { | 441 | if (lua_isnil(L, -1)) { |
| 455 | lua_pop(L, 1); /* remove from stack */ | 442 | lua_pop(L, 1); /* remove from stack */ |
| 456 | return LUA_REFNIL; /* `nil' has a unique fixed reference */ | 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 | ref = (int)lua_tointeger(L, -1); /* ref = t[FREELIST_REF] */ | 446 | ref = (int)lua_tointeger(L, -1); /* ref = t[FREELIST_REF] */ |
| 460 | lua_pop(L, 1); /* remove it from stack */ | 447 | lua_pop(L, 1); /* remove it from stack */ |
| 461 | if (ref != 0) { /* any free element? */ | 448 | if (ref != 0) { /* any free element? */ |
| 462 | lua_rawgeti(L, t, ref); /* remove it from list */ | 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 | ref = (int)lua_rawlen(L, t) + 1; /* get a new reference */ | 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 | lua_rawseti(L, t, ref); | 454 | lua_rawseti(L, t, ref); |
| 474 | return ref; | 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 | LUALIB_API void luaL_unref (lua_State *L, int t, int ref) { | 459 | LUALIB_API void luaL_unref (lua_State *L, int t, int ref) { |
| 479 | if (ref >= 0) { | 460 | if (ref >= 0) { |
| 480 | t = abs_index(L, t); | 461 | t = lua_absindex(L, t); |
| 481 | lua_rawgeti(L, t, FREELIST_REF); | 462 | lua_getfield(L, t, freelist); |
| 482 | lua_rawseti(L, t, ref); /* t[ref] = t[FREELIST_REF] */ | 463 | lua_rawseti(L, t, ref); /* t[ref] = t[freelist] */ |
| 483 | lua_pushinteger(L, ref); | 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 | typedef struct LoadF { | 478 | typedef struct LoadF { |
| 498 | int extraline; | 479 | int first; |
| 499 | FILE *f; | 480 | FILE *f; |
| 500 | char buff[LUAL_BUFFERSIZE]; | 481 | char buff[LUAL_BUFFERSIZE]; |
| 501 | } LoadF; | 482 | } LoadF; |
| @@ -504,17 +485,19 @@ typedef struct LoadF { · 2 unmodified lines | |||
| 504 | static const char *getF (lua_State *L, void *ud, size_t *size) { | 485 | static const char *getF (lua_State *L, void *ud, size_t *size) { |
| 505 | LoadF *lf = (LoadF *)ud; | 486 | LoadF *lf = (LoadF *)ud; |
| 506 | (void)L; | 487 | (void)L; |
| 507 | if (lf->extraline) { | 488 | if (lf->first != EOF) { |
| 508 | lf->extraline = 0; | ||
| 509 | *size = 1; | 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 | 500 | return lf->buff; |
| 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; | ||
| 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 | int status, readstatus; | 515 | int status, readstatus; |
| 533 | int c; | 516 | int c; |
| 534 | int fnameindex = lua_gettop(L) + 1; /* index of filename on the stack */ | 517 | int fnameindex = lua_gettop(L) + 1; /* index of filename on the stack */ |
| 535 | lf.extraline = 0; | ||
| 536 | if (filename == NULL) { | 518 | if (filename == NULL) { |
| 537 | lua_pushliteral(L, "=stdin"); | 519 | lua_pushliteral(L, "=stdin"); |
| 538 | lf.f = stdin; | 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 | c = getc(lf.f); | 527 | c = getc(lf.f); |
| 546 | if (c == '#') { /* Unix exec. file? */ | 528 | if (c == '#') { /* Unix exec. file? */ |
| 547 | lf.extraline = 1; | ||
| 548 | while ((c = getc(lf.f)) != EOF && c != '\n') ; /* skip first line */ | 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 | lf.f = freopen(filename, "rb", lf.f); /* reopen in binary mode */ | 532 | lf.f = freopen(filename, "rb", lf.f); /* reopen in binary mode */ |
| 553 | if (lf.f == NULL) return errfile(L, "reopen", fnameindex); | 533 | if (lf.f == NULL) return errfile(L, "reopen", fnameindex); |
| 554 | /* skip eventual `#!...' */ | 534 | c = getc(lf.f); /* re-read first character */ |
| 555 | while ((c = getc(lf.f)) != EOF && c != LUA_SIGNATURE[0]) ; | ||
| 556 | lf.extraline = 0; | ||
| 557 | } | 535 | } |
| 558 | ungetc(c, lf.f); | 536 | lf.first = c; /* 'c' is the first character of the stream */ |
| 559 | status = lua_load(L, getF, &lf, lua_tostring(L, -1)); | 537 | status = lua_load(L, getF, &lf, lua_tostring(L, -1)); |
| 560 | readstatus = ferror(lf.f); | 538 | readstatus = ferror(lf.f); |
| 561 | if (filename) fclose(lf.f); /* close file (even in case of errors) */ | 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 | LUALIB_API int luaL_callmeta (lua_State *L, int obj, const char *event) { | 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 | if (!luaL_getmetafield(L, obj, event)) /* no metafield? */ | 600 | if (!luaL_getmetafield(L, obj, event)) /* no metafield? */ |
| 623 | return 0; | 601 | return 0; |
| 624 | lua_pushvalue(L, obj); | 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 | static int libsize (const luaL_Reg *l) { | 642 | static int libsize (const luaL_Reg *l) { |
| 665 | int size = 0; | 643 | int size = 0; |
| 666 | for (; l->name; l++) size++; | 644 | for (; l && l->name; l++) size++; |
| 667 | return size; | 645 | return size; |
| 668 | } | 646 | } |
| 669 | 647 | ||
| 670 | 648 | ||
| 671 | LUALIB_API void luaL_register (lua_State *L, const char *libname, | 649 | LUALIB_API void luaL_openlib (lua_State *L, const char *libname, |
| 672 | const luaL_Reg *l) { | 650 | const luaL_Reg *l, int nup) { |
| 673 | luaL_checkversion(L); | 651 | luaL_checkversion(L); |
| 674 | if (libname) { | 652 | if (libname) { |
| 675 | /* check whether lib already exists */ | 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 | lua_setfield(L, -3, libname); /* _LOADED[libname] = new table */ | 663 | lua_setfield(L, -3, libname); /* _LOADED[libname] = new table */ |
| 686 | } | 664 | } |
| 687 | lua_remove(L, -2); /* remove _LOADED table */ | 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? */ | 668 | luaL_checkstack(L, nup, "too many upvalues"); |
| 690 | for (; l->name; l++) { /* else fill the table with given functions */ | 669 | for (; l && l->name; l++) { /* fill the table with given functions */ |
| 691 | lua_pushcfunction(L, l->func); | 670 | int i; |
| 692 | lua_setfield(L, -2, l->name); | 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 | static int panic (lua_State *L) { | 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 | lua_tostring(L, -1)); | 738 | lua_tostring(L, -1)); |
| 756 | return 0; /* return to Lua to abort */ | 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 | ** Auxiliary functions for building Lua libraries | 3 | ** Auxiliary functions for building Lua libraries |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -29,11 +29,11 @@ typedef struct luaL_Reg { · 23 unmodified lines | |||
| 29 | LUALIB_API void (luaL_checkversion_) (lua_State *L, lua_Number ver); | 29 | LUALIB_API void (luaL_checkversion_) (lua_State *L, lua_Number ver); |
| 30 | #define luaL_checkversion(L) luaL_checkversion_(L, LUA_VERSION_NUM) | 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, | 32 | LUALIB_API void (luaL_openlib) (lua_State *L, const char *libname, |
| 33 | const luaL_Reg *l); | 33 | const luaL_Reg *l, int nup); |
| 34 | LUALIB_API int (luaL_getmetafield) (lua_State *L, int obj, const char *e); | 34 | LUALIB_API int (luaL_getmetafield) (lua_State *L, int obj, const char *e); |
| 35 | LUALIB_API int (luaL_callmeta) (lua_State *L, int obj, const char *e); | 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 | LUALIB_API int (luaL_typeerror) (lua_State *L, int narg, const char *tname); | 37 | LUALIB_API int (luaL_typeerror) (lua_State *L, int narg, const char *tname); |
| 38 | LUALIB_API int (luaL_argerror) (lua_State *L, int numarg, const char *extramsg); | 38 | LUALIB_API int (luaL_argerror) (lua_State *L, int numarg, const char *extramsg); |
| 39 | LUALIB_API const char *(luaL_checklstring) (lua_State *L, int numArg, | 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 | LUALIB_API lua_State *(luaL_newstate) (void); | 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 | LUALIB_API const char *(luaL_gsub) (lua_State *L, const char *s, const char *p, | 76 | LUALIB_API const char *(luaL_gsub) (lua_State *L, const char *s, const char *p, |
| 77 | const char *r); | 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 | LUALIB_API const char *(luaL_findtable) (lua_State *L, int idx, | 79 | LUALIB_API const char *(luaL_findtable) (lua_State *L, int idx, |
| 80 | const char *fname, int szhint); | 80 | const char *fname, int szhint); |
| 81 | 81 | ||
| 82 | LUALIB_API void luaL_traceback (lua_State *L, lua_State *L1, | 82 | LUALIB_API void (luaL_traceback) (lua_State *L, lua_State *L1, |
| 83 | const char *msg, int level); | 83 | const char *msg, int level); |
| 84 | |||
| 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 | #define luaL_opt(L,f,n,d) (lua_isnoneornil(L,(n)) ? (d) : f(L,(n))) | 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 | ** Generic Buffer manipulation | 118 | ** Generic Buffer manipulation |
| 117 | ** ======================================================= | 119 | ** ======================================================= |
| 118 | */ | 120 | */ |
| 119 | 121 | ||
| 120 | |||
| 121 | |||
| 122 | typedef struct luaL_Buffer { | 122 | typedef struct luaL_Buffer { |
| 123 | char *p; /* current position in buffer */ | 123 | char *b; /* buffer address */ |
| 124 | int lvl; /* number of strings in the stack (level) */ | 124 | size_t size; /* buffer size */ |
| 125 | size_t n; /* number of characters in buffer */ | ||
| 125 | lua_State *L; | 126 | lua_State *L; |
| 126 | char buffer[LUAL_BUFFERSIZE]; | 127 | char initb[LUAL_BUFFERSIZE]; /* initial buffer */ |
| 127 | } luaL_Buffer; | 128 | } luaL_Buffer; |
| 128 | 129 | ||
| 130 | |||
| 129 | #define luaL_addchar(B,c) \ | 131 | #define luaL_addchar(B,c) \ |
| 130 | ((void)((B)->p < ((B)->buffer+LUAL_BUFFERSIZE) || luaL_prepbuffer(B)), \ | 132 | ((void)((B)->n < (B)->size || luaL_prepbuffsize((B), 1)), \ |
| 131 | (*(B)->p++ = (char)(c))) | 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 | LUALIB_API void (luaL_buffinit) (lua_State *L, luaL_Buffer *B); | 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 | LUALIB_API void (luaL_addlstring) (luaL_Buffer *B, const char *s, size_t l); | 139 | LUALIB_API void (luaL_addlstring) (luaL_Buffer *B, const char *s, size_t l); |
| 138 | LUALIB_API void (luaL_addstring) (luaL_Buffer *B, const char *s); | 140 | LUALIB_API void (luaL_addstring) (luaL_Buffer *B, const char *s); |
| 139 | LUALIB_API void (luaL_addvalue) (luaL_Buffer *B); | 141 | LUALIB_API void (luaL_addvalue) (luaL_Buffer *B); |
| 140 | LUALIB_API void (luaL_pushresult) (luaL_Buffer *B); | 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 | ** Basic library | 3 | ** Basic library |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -23,7 +23,7 @@ · 17 unmodified lines | |||
| 23 | static int luaB_print (lua_State *L) { | 23 | static int luaB_print (lua_State *L) { |
| 24 | int n = lua_gettop(L); /* number of arguments */ | 24 | int n = lua_gettop(L); /* number of arguments */ |
| 25 | int i; | 25 | int i; |
| 26 | lua_getfield(L, LUA_ENVIRONINDEX, "tostring"); | 26 | lua_getglobal(L, "tostring"); |
| 27 | for (i=1; i<=n; i++) { | 27 | for (i=1; i<=n; i++) { |
| 28 | const char *s; | 28 | const char *s; |
| 29 | size_t l; | 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 | static int luaB_getfenv (lua_State *L) { | 110 | static int luaB_getfenv (lua_State *L) { |
| 147 | return luaL_error(L, "getfenv/setfenv deprecated"); | 111 | return luaL_error(L, "getfenv/setfenv deprecated"); |
| 148 | } | 112 | } |
| 149 | 113 | ||
| 150 | #define luaB_setfenv luaB_getfenv | 114 | #define luaB_setfenv luaB_getfenv |
| 151 | 115 | ||
| 152 | #endif | ||
| 153 | |||
| 154 | 116 | ||
| 155 | static int luaB_rawequal (lua_State *L) { | 117 | static int luaB_rawequal (lua_State *L) { |
| 156 | luaL_checkany(L, 1); | 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 | static int luaB_collectgarbage (lua_State *L) { | 143 | static int luaB_collectgarbage (lua_State *L) { |
| 188 | static const char *const opts[] = {"stop", "restart", "collect", | 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 | static const int optsnum[] = {LUA_GCSTOP, LUA_GCRESTART, LUA_GCCOLLECT, | 147 | static const int optsnum[] = {LUA_GCSTOP, LUA_GCRESTART, LUA_GCCOLLECT, |
| 191 | LUA_GCCOUNT, LUA_GCSTEP, LUA_GCSETPAUSE, LUA_GCSETSTEPMUL, | 148 | LUA_GCCOUNT, LUA_GCSTEP, LUA_GCSETPAUSE, LUA_GCSETSTEPMUL, |
| 192 | LUA_GCISRUNNING}; | 149 | LUA_GCISRUNNING, LUA_GCGEN, LUA_GCINC}; |
| 193 | int o = optsnum[luaL_checkoption(L, 1, "collect", opts)]; | 150 | int o = optsnum[luaL_checkoption(L, 1, "collect", opts)]; |
| 194 | int ex = luaL_optint(L, 2, 0); | 151 | int ex = luaL_optint(L, 2, 0); |
| 195 | int res = lua_gc(L, o, ex); | 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 | if (!luaL_getmetafield(L, 1, method)) { /* no metamethod? */ | 181 | if (!luaL_getmetafield(L, 1, method)) { /* no metamethod? */ |
| 224 | luaL_checktype(L, 1, LUA_TTABLE); /* argument must be a table */ | 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 | lua_pushvalue(L, 1); /* state, */ | 184 | lua_pushvalue(L, 1); /* state, */ |
| 227 | if (iszero) lua_pushinteger(L, 0); /* and initial value */ | 185 | if (iszero) lua_pushinteger(L, 0); /* and initial value */ |
| 228 | else lua_pushnil(L); | 186 | else lua_pushnil(L); |
| @@ -248,10 +206,12 @@ static int luaB_next (lua_State *L) { · 19 unmodified lines | |||
| 248 | 206 | ||
| 249 | 207 | ||
| 250 | static int luaB_pairs (lua_State *L) { | 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 | static int ipairsaux (lua_State *L) { | 215 | static int ipairsaux (lua_State *L) { |
| 256 | int i = luaL_checkint(L, 2); | 216 | int i = luaL_checkint(L, 2); |
| 257 | luaL_checktype(L, 1, LUA_TTABLE); | 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 | static int luaB_ipairs (lua_State *L) { | 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 | static int load_aux (lua_State *L, int status) { | 238 | static int load_aux (lua_State *L, int status) { |
| 271 | if (status == LUA_OK) | 239 | if (status == LUA_OK) |
| @@ -376,7 +344,7 @@ static int luaB_loadin (lua_State *L) { · 104 unmodified lines | |||
| 376 | n = luaB_load_aux(L, 2); | 344 | n = luaB_load_aux(L, 2); |
| 377 | if (n == 1) { /* success? */ | 345 | if (n == 1) { /* success? */ |
| 378 | lua_pushvalue(L, 1); /* environment for loaded function */ | 346 | lua_pushvalue(L, 1); /* environment for loaded function */ |
| 379 | lua_setfenv(L, -2); | 347 | lua_setupvalue(L, -2, 1); |
| 380 | } | 348 | } |
| 381 | return n; | 349 | return n; |
| 382 | } | 350 | } |
| @@ -507,14 +475,15 @@ static const luaL_Reg base_funcs[] = { · 124 unmodified lines | |||
| 507 | {"collectgarbage", luaB_collectgarbage}, | 475 | {"collectgarbage", luaB_collectgarbage}, |
| 508 | {"dofile", luaB_dofile}, | 476 | {"dofile", luaB_dofile}, |
| 509 | {"error", luaB_error}, | 477 | {"error", luaB_error}, |
| 510 | {"gcinfo", luaB_gcinfo}, | ||
| 511 | {"getfenv", luaB_getfenv}, | 478 | {"getfenv", luaB_getfenv}, |
| 512 | {"getmetatable", luaB_getmetatable}, | 479 | {"getmetatable", luaB_getmetatable}, |
| 480 | {"ipairs", luaB_ipairs}, | ||
| 513 | {"loadfile", luaB_loadfile}, | 481 | {"loadfile", luaB_loadfile}, |
| 514 | {"load", luaB_load}, | 482 | {"load", luaB_load}, |
| 515 | {"loadin", luaB_loadin}, | 483 | {"loadin", luaB_loadin}, |
| 516 | {"loadstring", luaB_loadstring}, | 484 | {"loadstring", luaB_loadstring}, |
| 517 | {"next", luaB_next}, | 485 | {"next", luaB_next}, |
| 486 | {"pairs", luaB_pairs}, | ||
| 518 | {"pcall", luaB_pcall}, | 487 | {"pcall", luaB_pcall}, |
| 519 | {"print", luaB_print}, | 488 | {"print", luaB_print}, |
| 520 | {"rawequal", luaB_rawequal}, | 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 | static void base_open (lua_State *L) { | 640 | static void base_open (lua_State *L) { |
| 680 | /* set global _G */ | 641 | /* set global _G */ |
| 681 | lua_pushglobaltable(L); | 642 | lua_pushglobaltable(L); |
| 682 | lua_setfield(L, LUA_ENVIRONINDEX, "_G"); | 643 | lua_pushglobaltable(L); |
| 644 | lua_setfield(L, -2, "_G"); | ||
| 683 | /* open lib into global table */ | 645 | /* open lib into global table */ |
| 684 | luaL_register(L, "_G", base_funcs); | 646 | luaL_register(L, "_G", base_funcs); |
| 685 | lua_pushliteral(L, LUA_VERSION); | 647 | lua_pushliteral(L, LUA_VERSION); |
| 686 | lua_setfield(L, LUA_ENVIRONINDEX, "_VERSION"); /* set global _VERSION */ | 648 | lua_setfield(L, -2, "_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); | ||
| 690 | /* `newproxy' needs a weaktable as upvalue */ | 649 | /* `newproxy' needs a weaktable as upvalue */ |
| 691 | lua_createtable(L, 0, 1); /* new table `w' */ | 650 | lua_createtable(L, 0, 1); /* new table `w' */ |
| 692 | lua_pushvalue(L, -1); /* `w' will be its own metatable */ | 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 | lua_pushliteral(L, "kv"); | 653 | lua_pushliteral(L, "kv"); |
| 695 | lua_setfield(L, -2, "__mode"); /* metatable(w).__mode = "kv" */ | 654 | lua_setfield(L, -2, "__mode"); /* metatable(w).__mode = "kv" */ |
| 696 | lua_pushcclosure(L, luaB_newproxy, 1); | 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 | ** Standard library for bitwise operations | 3 | ** Standard library for bitwise operations |
| 4 | ** See Copyright Notice in lua.h | 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 | b_uint r = getuintarg(L, 1); | 84 | b_uint r = getuintarg(L, 1); |
| 85 | lua_Integer i = luaL_checkinteger(L, 2); | ||
| 86 | if (i < 0) { /* shift right? */ | 85 | if (i < 0) { /* shift right? */ |
| 87 | i = -i; | 86 | i = -i; |
| 88 | if (i >= NBITS) r = 0; | 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 | b_uint r = getuintarg(L, 1); | 110 | b_uint r = getuintarg(L, 1); |
| 102 | lua_Integer i = luaL_checkinteger(L, 2); | ||
| 103 | i &= (NBITS - 1); /* i = i % NBITS */ | 111 | i &= (NBITS - 1); /* i = i % NBITS */ |
| 104 | r = (r << i) | (r >> (NBITS - i)); | 112 | r = (r << i) | (r >> (NBITS - i)); |
| 105 | lua_pushnumber(L, lua_uint2number(r)); | 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 | static const luaL_Reg bitlib[] = { | 128 | static const luaL_Reg bitlib[] = { |
| 111 | {"band", b_and}, | 129 | {"band", b_and}, |
| 112 | {"btest", b_test}, | 130 | {"btest", b_test}, |
| 113 | {"bor", b_or}, | 131 | {"bor", b_or}, |
| 114 | {"bxor", b_xor}, | 132 | {"bxor", b_xor}, |
| 115 | {"bnot", b_not}, | 133 | {"bnot", b_not}, |
| 116 | {"bshift", b_shift}, | 134 | {"lshift", b_lshift}, |
| 117 | {"brotate", b_rotate}, | 135 | {"rshift", b_rshift}, |
| 136 | {"rol", b_rol}, | ||
| 137 | {"ror", b_ror}, | ||
| 118 | {NULL, NULL} | 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 | ** Code generator for Lua | 3 | ** Code generator for Lua |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -372,11 +372,6 @@ void luaK_dischargevars (FuncState *fs, expdesc *e) { · 366 unmodified lines | |||
| 372 | e->k = VRELOCABLE; | 372 | e->k = VRELOCABLE; |
| 373 | break; | 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 | case VINDEXED: { | 375 | case VINDEXED: { |
| 381 | freereg(fs, e->u.s.aux); | 376 | freereg(fs, e->u.s.aux); |
| 382 | freereg(fs, e->u.s.info); | 377 | freereg(fs, e->u.s.info); |
| @@ -384,6 +379,12 @@ void luaK_dischargevars (FuncState *fs, expdesc *e) { · 1 unmodified line | |||
| 384 | e->k = VRELOCABLE; | 379 | e->k = VRELOCABLE; |
| 385 | break; | 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 | case VVARARG: | 388 | case VVARARG: |
| 388 | case VCALL: { | 389 | case VCALL: { |
| 389 | luaK_setoneret(fs, e); | 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 | void luaK_exp2val (FuncState *fs, expdesc *e) { | 503 | void luaK_exp2val (FuncState *fs, expdesc *e) { |
| 497 | if (hasjumps(e)) | 504 | if (hasjumps(e)) |
| 498 | luaK_exp2anyreg(fs, e); | 505 | luaK_exp2anyreg(fs, e); |
| @@ -543,16 +550,16 @@ void luaK_storevar (FuncState *fs, expdesc *var, expdesc *ex) { · 44 unmodified lines | |||
| 543 | luaK_codeABC(fs, OP_SETUPVAL, e, var->u.s.info, 0); | 550 | luaK_codeABC(fs, OP_SETUPVAL, e, var->u.s.info, 0); |
| 544 | break; | 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 | case VINDEXED: { | 553 | case VINDEXED: { |
| 552 | int e = luaK_exp2RK(fs, ex); | 554 | int e = luaK_exp2RK(fs, ex); |
| 553 | luaK_codeABC(fs, OP_SETTABLE, var->u.s.info, var->u.s.aux, e); | 555 | luaK_codeABC(fs, OP_SETTABLE, var->u.s.info, var->u.s.aux, e); |
| 554 | break; | 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 | default: { | 563 | default: { |
| 557 | lua_assert(0); /* invalid var kind to store */ | 564 | lua_assert(0); /* invalid var kind to store */ |
| 558 | break; | 565 | break; |
| @@ -567,9 +574,9 @@ void luaK_self (FuncState *fs, expdesc *e, expdesc *key) { · 8 unmodified lines | |||
| 567 | luaK_exp2anyreg(fs, e); | 574 | luaK_exp2anyreg(fs, e); |
| 568 | freeexp(fs, e); | 575 | freeexp(fs, e); |
| 569 | func = fs->freereg; | 576 | func = fs->freereg; |
| 570 | luaK_reserveregs(fs, 2); | ||
| 571 | luaK_codeABC(fs, OP_SELF, func, e->u.s.info, luaK_exp2RK(fs, key)); | 577 | luaK_codeABC(fs, OP_SELF, func, e->u.s.info, luaK_exp2RK(fs, key)); |
| 572 | freeexp(fs, key); | 578 | freeexp(fs, key); |
| 579 | luaK_reserveregs(fs, 2); | ||
| 573 | e->u.s.info = func; | 580 | e->u.s.info = func; |
| 574 | e->k = VNONRELOC; | 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 | void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k) { | 704 | void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k) { |
| 705 | lua_assert(!hasjumps(t)); | ||
| 698 | t->u.s.aux = luaK_exp2RK(fs, k); | 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 | if (constfolding(op, e1, e2)) | 724 | if (constfolding(op, e1, e2)) |
| 716 | return; | 725 | return; |
| 717 | else { | 726 | else { |
| @@ -727,6 +736,7 @@ static void codearith (FuncState *fs, OpCode op, expdesc *e1, expdesc *e2) { · 9 unmodified lines | |||
| 727 | } | 736 | } |
| 728 | e1->u.s.info = luaK_codeABC(fs, op, 0, o1, o2); | 737 | e1->u.s.info = luaK_codeABC(fs, op, 0, o1, o2); |
| 729 | e1->k = VRELOCABLE; | 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 | expdesc e2; | 761 | expdesc e2; |
| 752 | e2.t = e2.f = NO_JUMP; e2.k = VKNUM; e2.u.nval = 0; | 762 | e2.t = e2.f = NO_JUMP; e2.k = VKNUM; e2.u.nval = 0; |
| 753 | switch (op) { | 763 | switch (op) { |
| @@ -756,14 +766,14 @@ void luaK_prefix (FuncState *fs, UnOpr op, expdesc *e) { · 2 unmodified lines | |||
| 756 | e->u.nval = luai_numunm(NULL, e->u.nval); /* fold it */ | 766 | e->u.nval = luai_numunm(NULL, e->u.nval); /* fold it */ |
| 757 | else { | 767 | else { |
| 758 | luaK_exp2anyreg(fs, e); | 768 | luaK_exp2anyreg(fs, e); |
| 759 | codearith(fs, OP_UNM, e, &e2); | 769 | codearith(fs, OP_UNM, e, &e2, line); |
| 760 | } | 770 | } |
| 761 | break; | 771 | break; |
| 762 | } | 772 | } |
| 763 | case OPR_NOT: codenot(fs, e); break; | 773 | case OPR_NOT: codenot(fs, e); break; |
| 764 | case OPR_LEN: { | 774 | case OPR_LEN: { |
| 765 | luaK_exp2anyreg(fs, e); /* cannot operate on constants */ | 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 | break; | 777 | break; |
| 768 | } | 778 | } |
| 769 | default: lua_assert(0); | 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 | switch (op) { | 813 | switch (op) { |
| 803 | case OPR_AND: { | 814 | case OPR_AND: { |
| 804 | lua_assert(e1->t == NO_JUMP); /* list must be closed */ | 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 | else { | 836 | else { |
| 826 | luaK_exp2nextreg(fs, e2); /* operand must be on the 'stack' */ | 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 | break; | 840 | break; |
| 830 | } | 841 | } |
| 831 | case OPR_ADD: case OPR_SUB: case OPR_MUL: case OPR_DIV: | 842 | case OPR_ADD: case OPR_SUB: case OPR_MUL: case OPR_DIV: |
| 832 | case OPR_MOD: case OPR_POW: { | 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 | break; | 845 | break; |
| 835 | } | 846 | } |
| 836 | case OPR_EQ: case OPR_LT: case OPR_LE: { | 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 | ** Code generator for Lua | 3 | ** Code generator for Lua |
| 4 | ** See Copyright Notice in lua.h | 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 | LUAI_FUNC int luaK_numberK (FuncState *fs, lua_Number r); | 57 | LUAI_FUNC int luaK_numberK (FuncState *fs, lua_Number r); |
| 58 | LUAI_FUNC void luaK_dischargevars (FuncState *fs, expdesc *e); | 58 | LUAI_FUNC void luaK_dischargevars (FuncState *fs, expdesc *e); |
| 59 | LUAI_FUNC int luaK_exp2anyreg (FuncState *fs, expdesc *e); | 59 | LUAI_FUNC int luaK_exp2anyreg (FuncState *fs, expdesc *e); |
| 60 | LUAI_FUNC void luaK_exp2anyregup (FuncState *fs, expdesc *e); | ||
| 60 | LUAI_FUNC void luaK_exp2nextreg (FuncState *fs, expdesc *e); | 61 | LUAI_FUNC void luaK_exp2nextreg (FuncState *fs, expdesc *e); |
| 61 | LUAI_FUNC void luaK_exp2val (FuncState *fs, expdesc *e); | 62 | LUAI_FUNC void luaK_exp2val (FuncState *fs, expdesc *e); |
| 62 | LUAI_FUNC int luaK_exp2RK (FuncState *fs, expdesc *e); | 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 | LUAI_FUNC void luaK_patchtohere (FuncState *fs, int list); | 73 | LUAI_FUNC void luaK_patchtohere (FuncState *fs, int list); |
| 73 | LUAI_FUNC void luaK_concat (FuncState *fs, int *l1, int l2); | 74 | LUAI_FUNC void luaK_concat (FuncState *fs, int *l1, int l2); |
| 74 | LUAI_FUNC int luaK_getlabel (FuncState *fs); | 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 | LUAI_FUNC void luaK_infix (FuncState *fs, BinOpr op, expdesc *v); | 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 | LUAI_FUNC void luaK_setlist (FuncState *fs, int base, int nelems, int tostore); | 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 | ** Interface from Lua to its debug API | 3 | ** Interface from Lua to its debug API |
| 4 | ** See Copyright Notice in lua.h | 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) { | 47 | static int db_getenv (lua_State *L) { |
| 48 | luaL_checkany(L, 1); | 48 | luaL_checktype(L, 1, LUA_TUSERDATA); |
| 49 | lua_getfenv(L, 1); | 49 | lua_getenv(L, 1); |
| 50 | return 1; | 50 | return 1; |
| 51 | } | 51 | } |
| 52 | 52 | ||
| 53 | 53 | ||
| 54 | static int db_setfenv (lua_State *L) { | 54 | static int db_setenv (lua_State *L) { |
| 55 | luaL_checktype(L, 2, LUA_TTABLE); | 55 | luaL_checktype(L, 1, LUA_TUSERDATA); |
| 56 | if (!lua_isnoneornil(L, 2)) | ||
| 57 | luaL_checktype(L, 2, LUA_TTABLE); | ||
| 56 | lua_settop(L, 2); | 58 | lua_settop(L, 2); |
| 57 | if (lua_setfenv(L, 1) == 0) | 59 | lua_setenv(L, 1); |
| 58 | luaL_error(L, LUA_QL("setfenv") | ||
| 59 | " cannot change environment of given object"); | ||
| 60 | return 1; | 60 | return 1; |
| 61 | } | 61 | } |
| 62 | 62 | ||
| @@ -339,15 +339,13 @@ static int db_gethook (lua_State *L) { · 276 unmodified lines | |||
| 339 | static int db_debug (lua_State *L) { | 339 | static int db_debug (lua_State *L) { |
| 340 | for (;;) { | 340 | for (;;) { |
| 341 | char buffer[250]; | 341 | char buffer[250]; |
| 342 | fputs("lua_debug> ", stderr); | 342 | luai_writestringerror("%s", "lua_debug> "); |
| 343 | if (fgets(buffer, sizeof(buffer), stdin) == 0 || | 343 | if (fgets(buffer, sizeof(buffer), stdin) == 0 || |
| 344 | strcmp(buffer, "cont\n") == 0) | 344 | strcmp(buffer, "cont\n") == 0) |
| 345 | return 0; | 345 | return 0; |
| 346 | if (luaL_loadbuffer(L, buffer, strlen(buffer), "=(debug command)") || | 346 | if (luaL_loadbuffer(L, buffer, strlen(buffer), "=(debug command)") || |
| 347 | lua_pcall(L, 0, 0, 0)) { | 347 | lua_pcall(L, 0, 0, 0)) |
| 348 | fputs(lua_tostring(L, -1), stderr); | 348 | luai_writestringerror("%s\n", lua_tostring(L, -1)); |
| 349 | fputs("\n", stderr); | ||
| 350 | } | ||
| 351 | lua_settop(L, 0); /* remove eventual returns */ | 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 | static const luaL_Reg dblib[] = { | 368 | static const luaL_Reg dblib[] = { |
| 371 | {"debug", db_debug}, | 369 | {"debug", db_debug}, |
| 372 | {"getfenv", db_getfenv}, | 370 | {"getenv", db_getenv}, |
| 373 | {"gethook", db_gethook}, | 371 | {"gethook", db_gethook}, |
| 374 | {"getinfo", db_getinfo}, | 372 | {"getinfo", db_getinfo}, |
| 375 | {"getlocal", db_getlocal}, | 373 | {"getlocal", db_getlocal}, |
| @@ -378,7 +376,7 @@ static const luaL_Reg dblib[] = { · 2 unmodified lines | |||
| 378 | {"getupvalue", db_getupvalue}, | 376 | {"getupvalue", db_getupvalue}, |
| 379 | {"upvaluejoin", db_upvaluejoin}, | 377 | {"upvaluejoin", db_upvaluejoin}, |
| 380 | {"upvalueid", db_upvalueid}, | 378 | {"upvalueid", db_upvalueid}, |
| 381 | {"setfenv", db_setfenv}, | 379 | {"setenv", db_setenv}, |
| 382 | {"sethook", db_sethook}, | 380 | {"sethook", db_sethook}, |
| 383 | {"setlocal", db_setlocal}, | 381 | {"setlocal", db_setlocal}, |
| 384 | {"setmetatable", db_setmetatable}, | 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 | ** Debug Interface | 3 | ** Debug Interface |
| 4 | ** See Copyright Notice in lua.h | 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 | static void funcinfo (lua_Debug *ar, Closure *cl) { | 146 | static void funcinfo (lua_Debug *ar, Closure *cl) { |
| 147 | if (cl->c.isC) { | 147 | if (cl == NULL || cl->c.isC) { |
| 148 | ar->source = "=[C]"; | 148 | ar->source = "=[C]"; |
| 149 | ar->linedefined = -1; | 149 | ar->linedefined = -1; |
| 150 | ar->lastlinedefined = -1; | 150 | ar->lastlinedefined = -1; |
| @@ -191,8 +191,8 @@ static int auxgetinfo (lua_State *L, const char *what, lua_Debug *ar, · 40 unmodified lines | |||
| 191 | break; | 191 | break; |
| 192 | } | 192 | } |
| 193 | case 'u': { | 193 | case 'u': { |
| 194 | ar->nups = f->c.nupvalues; | 194 | ar->nups = (f == NULL) ? 0 : f->c.nupvalues; |
| 195 | if (f->c.isC) { | 195 | if (f == NULL || f->c.isC) { |
| 196 | ar->isvararg = 1; | 196 | ar->isvararg = 1; |
| 197 | ar->nparams = 0; | 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 | LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar) { | 227 | LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar) { |
| 228 | int status; | 228 | int status; |
| 229 | Closure *f = NULL; | 229 | Closure *cl; |
| 230 | CallInfo *ci = NULL; | 230 | CallInfo *ci; |
| 231 | StkId func; | ||
| 231 | lua_lock(L); | 232 | lua_lock(L); |
| 232 | if (*what == '>') { | 233 | if (*what == '>') { |
| 233 | StkId func = L->top - 1; | 234 | ci = NULL; |
| 235 | func = L->top - 1; | ||
| 234 | luai_apicheck(L, ttisfunction(func)); | 236 | luai_apicheck(L, ttisfunction(func)); |
| 235 | what++; /* skip the '>' */ | 237 | what++; /* skip the '>' */ |
| 236 | f = clvalue(func); | ||
| 237 | L->top--; /* pop function */ | 238 | L->top--; /* pop function */ |
| 238 | } | 239 | } |
| 239 | else { | 240 | else { |
| 240 | ci = ar->i_ci; | 241 | ci = ar->i_ci; |
| 242 | func = ci->func; | ||
| 241 | lua_assert(ttisfunction(ci->func)); | 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 | if (strchr(what, 'f')) { | 247 | if (strchr(what, 'f')) { |
| 246 | setclvalue(L, L->top, f); | 248 | setobjs2s(L, L->top, func); |
| 247 | incr_top(L); | 249 | incr_top(L); |
| 248 | } | 250 | } |
| 249 | if (strchr(what, 'L')) | 251 | if (strchr(what, 'L')) |
| 250 | collectvalidlines(L, f); | 252 | collectvalidlines(L, cl); |
| 251 | lua_unlock(L); | 253 | lua_unlock(L); |
| 252 | return status; | 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) { | 265 | static void kname (Proto *p, int c, int reg, const char *what, |
| 264 | if (ISK(c) && ttisstring(&p->k[INDEXK(c)])) | 266 | const char **name) { |
| 265 | return svalue(&p->k[INDEXK(c)]); | 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 | else | 271 | else |
| 267 | return "?"; | 272 | *name = "?"; |
| 268 | } | 273 | } |
| 269 | 274 | ||
| 270 | 275 | ||
| 271 | static const char *getobjname (lua_State *L, CallInfo *ci, int reg, | 276 | static const char *getobjname (lua_State *L, CallInfo *ci, int reg, |
| 272 | const char **name) { | 277 | const char **name) { |
| 273 | Proto *p; | 278 | Proto *p = ci_func(ci)->l.p; |
| 274 | int lastpc, pc; | ||
| 275 | const char *what = NULL; | 279 | const char *what = NULL; |
| 276 | lua_assert(isLua(ci)); | 280 | int lastpc = currentpc(ci); |
| 277 | p = ci_func(ci)->l.p; | 281 | int pc; |
| 278 | lastpc = currentpc(ci); | ||
| 279 | *name = luaF_getlocalname(p, reg + 1, lastpc); | 282 | *name = luaF_getlocalname(p, reg + 1, lastpc); |
| 280 | if (*name) /* is a local? */ | 283 | if (*name) /* is a local? */ |
| 281 | return "local"; | 284 | return "local"; |
| @@ -285,17 +288,6 @@ static const char *getobjname (lua_State *L, CallInfo *ci, int reg, · 3 unmodified lines | |||
| 285 | OpCode op = GET_OPCODE(i); | 288 | OpCode op = GET_OPCODE(i); |
| 286 | int a = GETARG_A(i); | 289 | int a = GETARG_A(i); |
| 287 | switch (op) { | 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 | case OP_MOVE: { | 291 | case OP_MOVE: { |
| 300 | if (reg == a) { | 292 | if (reg == a) { |
| 301 | int b = GETARG_B(i); /* move from 'b' to 'a' */ | 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 | break; | 298 | break; |
| 307 | } | 299 | } |
| 300 | case OP_GETTABUP: | ||
| 308 | case OP_GETTABLE: { | 301 | case OP_GETTABLE: { |
| 309 | if (reg == a) { | 302 | if (reg == a) { |
| 310 | int k = GETARG_C(i); /* key index */ | 303 | int k = GETARG_C(i); /* key index */ |
| 311 | *name = kname(p, k); | 304 | int t = GETARG_B(i); |
| 312 | what = "field"; | 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 | break; | 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 | break; | 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 | case OP_LOADNIL: { | 333 | case OP_LOADNIL: { |
| 326 | int b = GETARG_B(i); /* move from 'b' to 'a' */ | 334 | int b = GETARG_B(i); /* move from 'b' to 'a' */ |
| 327 | if (a <= reg && reg <= b) /* set registers from 'a' to 'b' */ | 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 | case OP_SELF: { | 339 | case OP_SELF: { |
| 332 | if (reg == a) { | 340 | if (reg == a) { |
| 333 | int k = GETARG_C(i); /* key index */ | 341 | int k = GETARG_C(i); /* key index */ |
| 334 | *name = kname(p, k); | 342 | kname(p, k, a, what, name); |
| 335 | what = "method"; | 343 | what = "method"; |
| 336 | } | 344 | } |
| 337 | break; | 345 | break; |
| @@ -374,12 +382,15 @@ static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name) { · 36 unmodified lines | |||
| 374 | switch (GET_OPCODE(i)) { | 382 | switch (GET_OPCODE(i)) { |
| 375 | case OP_CALL: | 383 | case OP_CALL: |
| 376 | case OP_TAILCALL: | 384 | case OP_TAILCALL: |
| 377 | case OP_TFORLOOP: | ||
| 378 | return getobjname(L, ci, GETARG_A(i), name); | 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 | case OP_SELF: | 390 | case OP_SELF: |
| 391 | case OP_GETTABUP: | ||
| 381 | case OP_GETTABLE: tm = TM_INDEX; break; | 392 | case OP_GETTABLE: tm = TM_INDEX; break; |
| 382 | case OP_SETGLOBAL: | 393 | case OP_SETTABUP: |
| 383 | case OP_SETTABLE: tm = TM_NEWINDEX; break; | 394 | case OP_SETTABLE: tm = TM_NEWINDEX; break; |
| 384 | case OP_EQ: tm = TM_EQ; break; | 395 | case OP_EQ: tm = TM_EQ; break; |
| 385 | case OP_ADD: tm = TM_ADD; break; | 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 | void luaG_typeerror (lua_State *L, const TValue *o, const char *op) { | 441 | void luaG_typeerror (lua_State *L, const TValue *o, const char *op) { |
| 417 | CallInfo *ci = L->ci; | 442 | CallInfo *ci = L->ci; |
| 418 | const char *name = NULL; | 443 | const char *name = NULL; |
| 419 | const char *t = typename(ttype(o)); | 444 | const char *t = objtypename(o); |
| 420 | const char *kind = (isLua(ci) && isinstack(ci, o)) ? | 445 | const char *kind = NULL; |
| 421 | getobjname(L, ci, cast_int(o - ci->u.l.base), &name) : | 446 | if (isLua(ci)) { |
| 422 | NULL; | 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 | if (kind) | 451 | if (kind) |
| 424 | luaG_runerror(L, "attempt to %s %s " LUA_QS " (a %s value)", | 452 | luaG_runerror(L, "attempt to %s %s " LUA_QS " (a %s value)", |
| 425 | op, kind, name, t); | 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 | int luaG_ordererror (lua_State *L, const TValue *p1, const TValue *p2) { | 474 | int luaG_ordererror (lua_State *L, const TValue *p1, const TValue *p2) { |
| 447 | const char *t1 = typename(ttype(p1)); | 475 | const char *t1 = objtypename(p1); |
| 448 | const char *t2 = typename(ttype(p2)); | 476 | const char *t2 = objtypename(p2); |
| 449 | if (t1 == t2) | 477 | if (t1 == t2) |
| 450 | luaG_runerror(L, "attempt to compare two %s values", t1); | 478 | luaG_runerror(L, "attempt to compare two %s values", t1); |
| 451 | else | 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 | ** Stack and Call structure of Lua | 3 | ** Stack and Call structure of Lua |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -48,7 +48,7 @@ · 42 unmodified lines | |||
| 48 | */ | 48 | */ |
| 49 | #if !defined(LUAI_THROW) | 49 | #if !defined(LUAI_THROW) |
| 50 | 50 | ||
| 51 | #if defined(__cplusplus) | 51 | #if defined(__cplusplus) && !defined(LUA_USE_LONGJMP) |
| 52 | /* C++ exceptions */ | 52 | /* C++ exceptions */ |
| 53 | #define LUAI_THROW(L,c) throw(c) | 53 | #define LUAI_THROW(L,c) throw(c) |
| 54 | #define LUAI_TRY(L,c,a) \ | 54 | #define LUAI_TRY(L,c,a) \ |
| @@ -83,8 +83,8 @@ struct lua_longjmp { · 28 unmodified lines | |||
| 83 | 83 | ||
| 84 | static void seterrorobj (lua_State *L, int errcode, StkId oldtop) { | 84 | static void seterrorobj (lua_State *L, int errcode, StkId oldtop) { |
| 85 | switch (errcode) { | 85 | switch (errcode) { |
| 86 | case LUA_ERRMEM: { | 86 | case LUA_ERRMEM: { /* memory error? */ |
| 87 | setsvalue2s(L, oldtop, luaS_newliteral(L, MEMERRMSG)); | 87 | setsvalue2s(L, oldtop, G(L)->memerrmsg); /* reuse preregistered msg. */ |
| 88 | break; | 88 | break; |
| 89 | } | 89 | } |
| 90 | case LUA_ERRERR: { | 90 | case LUA_ERRERR: { |
| @@ -293,18 +293,43 @@ static StkId tryfuncTM (lua_State *L, StkId func) { · 202 unmodified lines | |||
| 293 | ** returns true if function has been executed (C function) | 293 | ** returns true if function has been executed (C function) |
| 294 | */ | 294 | */ |
| 295 | int luaD_precall (lua_State *L, StkId func, int nresults) { | 295 | int luaD_precall (lua_State *L, StkId func, int nresults) { |
| 296 | LClosure *cl; | 296 | Closure *cl; |
| 297 | lua_CFunction f; | ||
| 297 | ptrdiff_t funcr; | 298 | ptrdiff_t funcr; |
| 298 | if (!ttisfunction(func)) /* `func' is not a function? */ | 299 | if (!ttisfunction(func)) /* `func' is not a function? */ |
| 299 | func = tryfuncTM(L, func); /* check the `function' tag method */ | 300 | func = tryfuncTM(L, func); /* check the `function' tag method */ |
| 300 | funcr = savestack(L, func); | 301 | funcr = savestack(L, func); |
| 301 | cl = &clvalue(func)->l; | ||
| 302 | L->ci->nresults = nresults; | 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 | CallInfo *ci; | 329 | CallInfo *ci; |
| 305 | int nparams, nargs; | 330 | int nparams, nargs; |
| 306 | StkId base; | 331 | StkId base; |
| 307 | Proto *p = cl->p; | 332 | Proto *p = cl->l.p; |
| 308 | luaD_checkstack(L, p->maxstacksize); | 333 | luaD_checkstack(L, p->maxstacksize); |
| 309 | func = restorestack(L, funcr); | 334 | func = restorestack(L, funcr); |
| 310 | nargs = cast_int(L->top - func) - 1; /* number of real arguments */ | 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 | callhook(L, ci); | 352 | callhook(L, ci); |
| 328 | return 0; | 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 | CallInfo *ci = findpcall(L); | 459 | CallInfo *ci = findpcall(L); |
| 453 | if (ci == NULL) return 0; /* no recovery point */ | 460 | if (ci == NULL) return 0; /* no recovery point */ |
| 454 | /* "finish" luaD_pcall */ | 461 | /* "finish" luaD_pcall */ |
| 455 | oldtop = restorestack(L, ci->u.c.oldtop); | 462 | oldtop = restorestack(L, ci->u.c.extra); |
| 456 | luaF_close(L, oldtop); | 463 | luaF_close(L, oldtop); |
| 457 | seterrorobj(L, status, oldtop); | 464 | seterrorobj(L, status, oldtop); |
| 458 | L->ci = ci; | 465 | L->ci = ci; |
| @@ -469,7 +476,7 @@ static int recover (lua_State *L, int status) { · 10 unmodified lines | |||
| 469 | /* | 476 | /* |
| 470 | ** signal an error in the call to 'resume', not in the execution of the | 477 | ** signal an error in the call to 'resume', not in the execution of the |
| 471 | ** coroutine itself. (Such errors should not be handled by any coroutine | 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 | static void resume_error (lua_State *L, const char *msg, StkId firstArg) { | 481 | static void resume_error (lua_State *L, const char *msg, StkId firstArg) { |
| 475 | L->top = firstArg; /* remove args from the stack */ | 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 | if (isLua(ci)) /* yielded inside a hook? */ | 508 | if (isLua(ci)) /* yielded inside a hook? */ |
| 502 | luaV_execute(L); /* just continue running Lua code */ | 509 | luaV_execute(L); /* just continue running Lua code */ |
| 503 | else { /* 'common' yield */ | 510 | else { /* 'common' yield */ |
| 511 | ci->func = restorestack(L, ci->u.c.extra); | ||
| 504 | if (ci->u.c.k != NULL) { /* does it have a continuation? */ | 512 | if (ci->u.c.k != NULL) { /* does it have a continuation? */ |
| 505 | int n; | 513 | int n; |
| 506 | ci->u.c.status = LUA_YIELD; /* 'default' status */ | 514 | ci->u.c.status = LUA_YIELD; /* 'default' status */ |
| 507 | ci->callstatus |= CIST_YIELDED; | 515 | ci->callstatus |= CIST_YIELDED; |
| 508 | ci->func = restorestack(L, ci->u.c.oldtop); | ||
| 509 | lua_unlock(L); | 516 | lua_unlock(L); |
| 510 | n = (*ci->u.c.k)(L); /* call continuation */ | 517 | n = (*ci->u.c.k)(L); /* call continuation */ |
| 511 | lua_lock(L); | 518 | lua_lock(L); |
| @@ -526,6 +533,7 @@ LUA_API int lua_resume (lua_State *L, int nargs) { · 14 unmodified lines | |||
| 526 | luai_userstateresume(L, nargs); | 533 | luai_userstateresume(L, nargs); |
| 527 | ++G(L)->nCcalls; /* count resume */ | 534 | ++G(L)->nCcalls; /* count resume */ |
| 528 | L->nny = 0; /* allow yields */ | 535 | L->nny = 0; /* allow yields */ |
| 536 | api_checknelems(L, (L->status == LUA_OK) ? nargs + 1 : nargs); | ||
| 529 | status = luaD_rawrunprotected(L, resume, L->top - nargs); | 537 | status = luaD_rawrunprotected(L, resume, L->top - nargs); |
| 530 | if (status == -1) /* error calling 'lua_resume'? */ | 538 | if (status == -1) /* error calling 'lua_resume'? */ |
| 531 | status = LUA_ERRRUN; | 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 | api_check(L, k == NULL, "hooks cannot continue after yielding"); | 573 | api_check(L, k == NULL, "hooks cannot continue after yielding"); |
| 566 | } | 574 | } |
| 567 | else { | 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 | ci->u.c.ctx = ctx; /* save context */ | 577 | ci->u.c.ctx = ctx; /* save context */ |
| 570 | ci->u.c.oldtop = savestack(L, ci->func); /* save current 'func' */ | 578 | ci->u.c.extra = savestack(L, ci->func); /* save current 'func' */ |
| 571 | } | 579 | ci->func = L->top - nresults - 1; /* protect stack below results */ |
| 572 | ci->func = L->top - nresults - 1; /* protect stack slots below */ | ||
| 573 | luaD_throw(L, LUA_YIELD); | 580 | luaD_throw(L, LUA_YIELD); |
| 574 | } | 581 | } |
| 575 | lua_assert(ci->callstatus & CIST_HOOKED); /* must be inside a hook */ | 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 | : luaY_parser(L, p->z, &p->buff, &p->varl, p->name); | 630 | : luaY_parser(L, p->z, &p->buff, &p->varl, p->name); |
| 624 | setptvalue2s(L, L->top, tf); | 631 | setptvalue2s(L, L->top, tf); |
| 625 | incr_top(L); | 632 | incr_top(L); |
| 626 | cl = luaF_newLclosure(L, tf->sizeupvalues, G(L)->l_gt); | 633 | cl = luaF_newLclosure(L, tf->sizeupvalues); |
| 627 | cl->l.p = tf; | 634 | cl->l.p = tf; |
| 628 | setclvalue(L, L->top - 1, cl); | 635 | setclvalue(L, L->top - 1, cl); |
| 629 | for (i = 0; i < tf->sizeupvalues; i++) /* initialize upvalues */ | 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 | ** save precompiled Lua chunks | 3 | ** save precompiled Lua chunks |
| 4 | ** See Copyright Notice in lua.h | 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 | DumpChar(f->numparams,D); | 145 | DumpChar(f->numparams,D); |
| 146 | DumpChar(f->is_vararg,D); | 146 | DumpChar(f->is_vararg,D); |
| 147 | DumpChar(f->maxstacksize,D); | 147 | DumpChar(f->maxstacksize,D); |
| 148 | DumpChar(f->envreg,D); | ||
| 149 | DumpCode(f,D); | 148 | DumpCode(f,D); |
| 150 | DumpConstants(f,D); | 149 | DumpConstants(f,D); |
| 151 | DumpUpvalues(f,D); | 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 | ** Auxiliary functions to manipulate prototypes and closures | 3 | ** Auxiliary functions to manipulate prototypes and closures |
| 4 | ** See Copyright Notice in lua.h | 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 | Closure *c = &luaC_newobj(L, LUA_TFUNCTION, sizeCclosure(n), NULL, 0)->cl; | 25 | Closure *c = &luaC_newobj(L, LUA_TFUNCTION, sizeCclosure(n), NULL, 0)->cl; |
| 26 | c->c.isC = 1; | 26 | c->c.isC = 1; |
| 27 | c->c.env = e; | ||
| 28 | c->c.nupvalues = cast_byte(n); | 27 | c->c.nupvalues = cast_byte(n); |
| 29 | return c; | 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 | Closure *c = &luaC_newobj(L, LUA_TFUNCTION, sizeLclosure(n), NULL, 0)->cl; | 33 | Closure *c = &luaC_newobj(L, LUA_TFUNCTION, sizeLclosure(n), NULL, 0)->cl; |
| 35 | c->l.isC = 0; | 34 | c->l.isC = 0; |
| 36 | c->l.env = e; | ||
| 37 | c->l.nupvalues = cast_byte(n); | 35 | c->l.nupvalues = cast_byte(n); |
| 38 | while (n--) c->l.upvals[n] = NULL; | 36 | while (n--) c->l.upvals[n] = NULL; |
| 39 | return c; | 37 | return c; |
| @@ -54,12 +52,14 @@ UpVal *luaF_findupval (lua_State *L, StkId level) { · 14 unmodified lines | |||
| 54 | UpVal *p; | 52 | UpVal *p; |
| 55 | UpVal *uv; | 53 | UpVal *uv; |
| 56 | while (*pp != NULL && (p = gco2uv(*pp))->v >= level) { | 54 | while (*pp != NULL && (p = gco2uv(*pp))->v >= level) { |
| 55 | GCObject *o = obj2gco(p); | ||
| 57 | lua_assert(p->v != &p->u.value); | 56 | lua_assert(p->v != &p->u.value); |
| 58 | if (p->v == level) { /* found a corresponding upvalue? */ | 57 | if (p->v == level) { /* found a corresponding upvalue? */ |
| 59 | if (isdead(g, obj2gco(p))) /* is it dead? */ | 58 | if (isdead(g, o)) /* is it dead? */ |
| 60 | changewhite(obj2gco(p)); /* ressurrect it */ | 59 | changewhite(o); /* ressurrect it */ |
| 61 | return p; | 60 | return p; |
| 62 | } | 61 | } |
| 62 | resetoldbit(o); /* may create a newer upval after this one */ | ||
| 63 | pp = &p->next; | 63 | pp = &p->next; |
| 64 | } | 64 | } |
| 65 | /* not found: create a new one */ | 65 | /* not found: create a new one */ |
| @@ -98,10 +98,12 @@ void luaF_close (lua_State *L, StkId level) { · 32 unmodified lines | |||
| 98 | if (isdead(g, o)) | 98 | if (isdead(g, o)) |
| 99 | luaF_freeupval(L, uv); /* free upvalue */ | 99 | luaF_freeupval(L, uv); /* free upvalue */ |
| 100 | else { | 100 | else { |
| 101 | unlinkupval(uv); | 101 | unlinkupval(uv); /* remove upvalue from 'uvhead' list */ |
| 102 | setobj(L, &uv->u.value, uv->v); | 102 | setobj(L, &uv->u.value, uv->v); /* move value to upvalue slot */ |
| 103 | uv->v = &uv->u.value; /* now current value lives here */ | 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 | f->linedefined = 0; | 129 | f->linedefined = 0; |
| 128 | f->lastlinedefined = 0; | 130 | f->lastlinedefined = 0; |
| 129 | f->source = NULL; | 131 | f->source = NULL; |
| 130 | f->envreg = NO_REG; | ||
| 131 | return f; | 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 | ** Auxiliary functions to manipulate prototypes and closures | 3 | ** Auxiliary functions to manipulate prototypes and closures |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -19,8 +19,8 @@ · 13 unmodified lines | |||
| 19 | 19 | ||
| 20 | 20 | ||
| 21 | LUAI_FUNC Proto *luaF_newproto (lua_State *L); | 21 | LUAI_FUNC Proto *luaF_newproto (lua_State *L); |
| 22 | LUAI_FUNC Closure *luaF_newCclosure (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, Table *e); | 23 | LUAI_FUNC Closure *luaF_newLclosure (lua_State *L, int nelems); |
| 24 | LUAI_FUNC UpVal *luaF_newupval (lua_State *L); | 24 | LUAI_FUNC UpVal *luaF_newupval (lua_State *L); |
| 25 | LUAI_FUNC UpVal *luaF_findupval (lua_State *L, StkId level); | 25 | LUAI_FUNC UpVal *luaF_findupval (lua_State *L, StkId level); |
| 26 | LUAI_FUNC void luaF_close (lua_State *L, StkId level); | 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 | ** Garbage Collector | 3 | ** Garbage Collector |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -23,21 +23,49 @@ · 17 unmodified lines | |||
| 23 | #include "ltm.h" | 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 | #define GCSWEEPMAX 40 | 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 | #define makewhite(g,x) \ | 62 | #define makewhite(g,x) \ |
| 35 | (gch(x)->marked = cast_byte((gch(x)->marked & maskcolors) | luaC_white(g))) | 63 | (gch(x)->marked = cast_byte((gch(x)->marked & maskcolors) | luaC_white(g))) |
| 36 | 64 | ||
| 37 | #define white2gray(x) resetbits(gch(x)->marked, WHITEBITS) | 65 | #define white2gray(x) resetbits(gch(x)->marked, WHITEBITS) |
| 38 | #define black2gray(x) resetbit(gch(x)->marked, BLACKBIT) | 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 | #define isfinalized(u) testbit((u)->marked, FINALIZEDBIT) | 71 | #define isfinalized(u) testbit((u)->marked, FINALIZEDBIT) |
| @@ -51,7 +79,6 @@ · 7 unmodified lines | |||
| 51 | #define markobject(g,t) { if ((t) && iswhite(obj2gco(t))) \ | 79 | #define markobject(g,t) { if ((t) && iswhite(obj2gco(t))) \ |
| 52 | reallymarkobject(g, obj2gco(t)); } | 80 | reallymarkobject(g, obj2gco(t)); } |
| 53 | 81 | ||
| 54 | |||
| 55 | static void reallymarkobject (global_State *g, GCObject *o); | 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) { | 91 | |
| 65 | h->gclist = *p; | 92 | /* |
| 66 | *p = obj2gco(h); | 93 | ** link table 'h' into list pointed by 'p' |
| 67 | } | 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 | static void removeentry (Node *n) { | 101 | static void removeentry (Node *n) { |
| 71 | lua_assert(ttisnil(gval(n))); | 102 | lua_assert(ttisnil(gval(n))); |
| 72 | if (iscollectable(gkey(n))) | 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 | 109 | ** tells whether a key or value can be cleared from a weak |
| 79 | ** a weak table. Non-collectable objects are never removed from weak | 110 | ** table. Non-collectable objects are never removed from weak |
| 80 | ** tables. Strings behave as `values', so are never removed too. for | 111 | ** tables. Strings behave as `values', so are never removed too. for |
| 81 | ** other objects: if really collected, cannot keep them; for objects | 112 | ** other objects: if really collected, cannot keep them; for objects |
| 82 | ** being finalized, keep them in keys, but not in values | 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 | void luaC_barrierf (lua_State *L, GCObject *o, GCObject *v) { | 130 | void luaC_barrierf (lua_State *L, GCObject *o, GCObject *v) { |
| 96 | global_State *g = G(L); | 131 | global_State *g = G(L); |
| 97 | lua_assert(isblack(o) && iswhite(v) && !isdead(g, v) && !isdead(g, o)); | 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 | lua_assert(gch(o)->tt != LUA_TTABLE); | 134 | lua_assert(gch(o)->tt != LUA_TTABLE); |
| 100 | /* must keep invariant? */ | 135 | if (keepinvariant(g)) /* must keep invariant? */ |
| 101 | if (g->gcstate == GCSpropagate) | ||
| 102 | reallymarkobject(g, v); /* restore invariant */ | 136 | reallymarkobject(g, v); /* restore invariant */ |
| 103 | else /* don't mind */ | 137 | else { /* sweep phase */ |
| 104 | makewhite(g, o); /* mark as white just to avoid other barriers */ | 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 | void luaC_barrierback (lua_State *L, Table *t) { | 148 | void luaC_barrierback (lua_State *L, Table *t) { |
| 109 | global_State *g = G(L); | 149 | global_State *g = G(L); |
| 110 | GCObject *o = obj2gco(t); | 150 | GCObject *o = obj2gco(t); |
| 111 | lua_assert(isblack(o) && !isdead(g, o)); | 151 | lua_assert(isblack(o) && !isdead(g, o)); |
| 112 | lua_assert(g->gcstate != GCSfinalize && g->gcstate != GCSpause); | ||
| 113 | black2gray(o); /* make table gray (again) */ | 152 | black2gray(o); /* make table gray (again) */ |
| 114 | t->gclist = g->grayagain; | 153 | t->gclist = g->grayagain; |
| 115 | g->grayagain = o; | 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 | GCObject *luaC_newobj (lua_State *L, int tt, size_t sz, GCObject **list, | 184 | GCObject *luaC_newobj (lua_State *L, int tt, size_t sz, GCObject **list, |
| 123 | int offset) { | 185 | int offset) { |
| 124 | global_State *g = G(L); | 186 | global_State *g = G(L); |
| 125 | GCObject *o = obj2gco(cast(char *, luaM_newobject(L, tt, sz)) + offset); | 187 | GCObject *o = obj2gco(cast(char *, luaM_newobject(L, tt, sz)) + offset); |
| 126 | if (list == NULL) | 188 | if (list == NULL) |
| 127 | list = &g->rootgc; /* standard list for collectable objects */ | 189 | list = &g->allgc; /* standard list for collectable objects */ |
| 128 | gch(o)->marked = luaC_white(g); | 190 | gch(o)->marked = luaC_white(g); |
| 129 | gch(o)->tt = tt; | 191 | gch(o)->tt = tt; |
| 130 | gch(o)->next = *list; | 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 | return o; | 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 | static void reallymarkobject (global_State *g, GCObject *o) { | 215 | static void reallymarkobject (global_State *g, GCObject *o) { |
| 164 | lua_assert(iswhite(o) && !isdead(g, o)); | 216 | lua_assert(iswhite(o) && !isdead(g, o)); |
| 165 | white2gray(o); | 217 | white2gray(o); |
| 166 | switch (gch(o)->tt) { | 218 | switch (gch(o)->tt) { |
| 167 | case LUA_TSTRING: { | 219 | case LUA_TSTRING: { |
| 168 | return; | 220 | return; /* for strings, gray is as good as black */ |
| 169 | } | 221 | } |
| 170 | case LUA_TUSERDATA: { | 222 | case LUA_TUSERDATA: { |
| 171 | Table *mt = gco2u(o)->metatable; | 223 | Table *mt = gco2u(o)->metatable; |
| 172 | gray2black(o); /* udata are never gray */ | ||
| 173 | markobject(g, mt); | 224 | markobject(g, mt); |
| 174 | markobject(g, gco2u(o)->env); | 225 | markobject(g, gco2u(o)->env); |
| 226 | gray2black(o); /* all pointers marked */ | ||
| 175 | return; | 227 | return; |
| 176 | } | 228 | } |
| 177 | case LUA_TUPVAL: { | 229 | case LUA_TUPVAL: { |
| 178 | UpVal *uv = gco2uv(o); | 230 | UpVal *uv = gco2uv(o); |
| 179 | markvalue(g, uv->v); | 231 | markvalue(g, uv->v); |
| 180 | if (uv->v == &uv->u.value) /* closed? */ | 232 | if (uv->v == &uv->u.value) /* closed? (open upvalues remain gray) */ |
| 181 | gray2black(o); /* open upvalues are never black */ | 233 | gray2black(o); /* make it black */ |
| 182 | return; | 234 | return; |
| 183 | } | 235 | } |
| 184 | case LUA_TFUNCTION: { | 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 | static void markmt (global_State *g) { | 263 | static void markmt (global_State *g) { |
| 209 | int i; | 264 | int i; |
| 210 | for (i=0; i<NUM_TAGS; i++) | 265 | for (i=0; i < LUA_NUMTAGS; i++) |
| 211 | markobject(g, g->mt[i]); | 266 | markobject(g, g->mt[i]); |
| 212 | } | 267 | } |
| 213 | 268 | ||
| 214 | 269 | ||
| 270 | /* | ||
| 271 | ** mark all objects in list of being-finalized | ||
| 272 | */ | ||
| 215 | static void markbeingfnz (global_State *g) { | 273 | static void markbeingfnz (global_State *g) { |
| 216 | GCObject *o; | 274 | GCObject *o; |
| 217 | for (o = g->tobefnz; o != NULL; o = gch(o)->next) { | 275 | for (o = g->tobefnz; o != NULL; o = gch(o)->next) { |
| 218 | lua_assert(testbit(gch(o)->marked, SEPARATED)); | ||
| 219 | makewhite(g, o); | 276 | makewhite(g, o); |
| 220 | reallymarkobject(g, o); | 277 | reallymarkobject(g, o); |
| 221 | } | 278 | } |
| 222 | } | 279 | } |
| 223 | 280 | ||
| 224 | 281 | ||
| 225 | /* mark root set */ | 282 | /* |
| 226 | static void markroot (lua_State *L) { | 283 | ** mark all values stored in marked open upvalues. (See comment in |
| 227 | global_State *g = G(L); | 284 | ** 'lstate.h'.) |
| 228 | g->gray = NULL; | 285 | */ |
| 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 | |||
| 241 | static void remarkupvals (global_State *g) { | 286 | static void remarkupvals (global_State *g) { |
| 242 | UpVal *uv; | 287 | UpVal *uv; |
| 243 | for (uv = g->uvhead.u.l.next; uv != &g->uvhead; uv = uv->u.l.next) { | 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 | if (isgray(obj2gco(uv))) | 289 | if (isgray(obj2gco(uv))) |
| 246 | markvalue(g, uv->v); | 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 | static void traverseweakvalue (global_State *g, Table *h) { | 318 | static void traverseweakvalue (global_State *g, Table *h) { |
| 260 | int i = sizenode(h); | 319 | Node *n, *limit = gnode(h, sizenode(h)); |
| 261 | while (i--) { | 320 | for (n = gnode(h, 0); n < limit; n++) { |
| 262 | Node *n = gnode(h, i); | ||
| 263 | checkdeadkey(n); | 321 | checkdeadkey(n); |
| 264 | if (ttisnil(gval(n))) | 322 | if (ttisnil(gval(n))) /* entry is empty? */ |
| 265 | removeentry(n); /* remove empty entries */ | 323 | removeentry(n); /* remove it */ |
| 266 | else { | 324 | else { |
| 267 | lua_assert(!ttisnil(gkey(n))); | 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 | static int traverseephemeron (global_State *g, Table *h) { | 333 | static int traverseephemeron (global_State *g, Table *h) { |
| 276 | int marked = 0; | 334 | int marked = 0; /* true if an object is marked in this traversal */ |
| 277 | int hasclears = 0; | 335 | int hasclears = 0; /* true if table has unmarked pairs */ |
| 278 | int i = h->sizearray; | 336 | Node *n, *limit = gnode(h, sizenode(h)); |
| 279 | while (i--) { /* mark array part (numeric keys are 'strong') */ | 337 | int i; |
| 338 | /* traverse array part (numeric keys are 'strong') */ | ||
| 339 | for (i = 0; i < h->sizearray; i++) { | ||
| 280 | if (valiswhite(&h->array[i])) { | 340 | if (valiswhite(&h->array[i])) { |
| 281 | marked = 1; | 341 | marked = 1; |
| 282 | reallymarkobject(g, gcvalue(&h->array[i])); | 342 | reallymarkobject(g, gcvalue(&h->array[i])); |
| 283 | } | 343 | } |
| 284 | } | 344 | } |
| 285 | i = sizenode(h); | 345 | /* traverse hash part */ |
| 286 | while (i--) { | 346 | for (n = gnode(h, 0); n < limit; n++) { |
| 287 | Node *n = gnode(h, i); | ||
| 288 | checkdeadkey(n); | 347 | checkdeadkey(n); |
| 289 | if (ttisnil(gval(n))) /* entry is empty? */ | 348 | if (ttisnil(gval(n))) /* entry is empty? */ |
| 290 | removeentry(n); /* remove it */ | 349 | removeentry(n); /* remove it */ |
| 291 | else if (valiswhite(gval(n))) { | 350 | else if (valiswhite(gval(n))) { /* value not marked yet? */ |
| 292 | /* value is not marked yet */ | ||
| 293 | if (iscleared(key2tval(n), 1)) /* key is not marked (yet)? */ | 351 | if (iscleared(key2tval(n), 1)) /* key is not marked (yet)? */ |
| 294 | hasclears = 1; /* may have to propagate mark from key to value */ | 352 | hasclears = 1; /* may have to propagate mark from key to value */ |
| 295 | else { /* mark value only if key is marked */ | 353 | else { /* key is marked, so mark value */ |
| 296 | marked = 1; /* some mark changed status */ | 354 | marked = 1; /* value was not marked */ |
| 297 | reallymarkobject(g, gcvalue(gval(n))); | 355 | reallymarkobject(g, gcvalue(gval(n))); |
| 298 | } | 356 | } |
| 299 | } | 357 | } |
| 300 | } | 358 | } |
| 301 | if (hasclears) | 359 | if (hasclears) /* does table have unmarked pairs? */ |
| 302 | linktable(h, &g->ephemeron); | 360 | linktable(h, &g->ephemeron); /* will have to propagate again */ |
| 303 | else /* nothing to propagate */ | 361 | else /* nothing to propagate */ |
| 304 | linktable(h, &g->weak); /* avoid convergence phase */ | 362 | linktable(h, &g->weak); /* avoid convergence phase */ |
| 305 | return marked; | 363 | return marked; |
| @@ -307,26 +365,24 @@ static int traverseephemeron (global_State *g, Table *h) { · 1 unmodified line | |||
| 307 | 365 | ||
| 308 | 366 | ||
| 309 | static void traversestrongtable (global_State *g, Table *h) { | 367 | static void traversestrongtable (global_State *g, Table *h) { |
| 368 | Node *n, *limit = gnode(h, sizenode(h)); | ||
| 310 | int i; | 369 | int i; |
| 311 | i = h->sizearray; | 370 | for (i = 0; i < h->sizearray; i++) /* traverse array part */ |
| 312 | while (i--) | ||
| 313 | markvalue(g, &h->array[i]); | 371 | markvalue(g, &h->array[i]); |
| 314 | i = sizenode(h); | 372 | for (n = gnode(h, 0); n < limit; n++) { /* traverse hash part */ |
| 315 | while (i--) { | ||
| 316 | Node *n = gnode(h, i); | ||
| 317 | checkdeadkey(n); | 373 | checkdeadkey(n); |
| 318 | if (ttisnil(gval(n))) | 374 | if (ttisnil(gval(n))) /* entry is empty? */ |
| 319 | removeentry(n); /* remove empty entries */ | 375 | removeentry(n); /* remove it */ |
| 320 | else { | 376 | else { |
| 321 | lua_assert(!ttisnil(gkey(n))); | 377 | lua_assert(!ttisnil(gkey(n))); |
| 322 | markvalue(g, gkey(n)); | 378 | markvalue(g, gkey(n)); /* mark key */ |
| 323 | markvalue(g, gval(n)); | 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 | const TValue *mode = gfasttm(g, h->metatable, TM_MODE); | 386 | const TValue *mode = gfasttm(g, h->metatable, TM_MODE); |
| 331 | markobject(g, h->metatable); | 387 | markobject(g, h->metatable); |
| 332 | if (mode && ttisstring(mode)) { /* is there a weak mode? */ | 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 | int weakvalue = (strchr(svalue(mode), 'v') != NULL); | 390 | int weakvalue = (strchr(svalue(mode), 'v') != NULL); |
| 335 | if (weakkey || weakvalue) { /* is really weak? */ | 391 | if (weakkey || weakvalue) { /* is really weak? */ |
| 336 | black2gray(obj2gco(h)); /* keep table gray */ | 392 | black2gray(obj2gco(h)); /* keep table gray */ |
| 337 | if (!weakkey) /* strong keys? */ | 393 | if (!weakkey) { /* strong keys? */ |
| 338 | traverseweakvalue(g, h); | 394 | traverseweakvalue(g, h); |
| 339 | else if (!weakvalue) /* strong values? */ | 395 | return TRAVCOST + sizenode(h); |
| 396 | } | ||
| 397 | else if (!weakvalue) { /* strong values? */ | ||
| 340 | traverseephemeron(g, h); | 398 | traverseephemeron(g, h); |
| 341 | else | 399 | return TRAVCOST + h->sizearray + sizenode(h); |
| 400 | } | ||
| 401 | else { | ||
| 342 | linktable(h, &g->allweak); /* nothing to traverse now */ | 402 | linktable(h, &g->allweak); /* nothing to traverse now */ |
| 343 | return; | 403 | return TRAVCOST; |
| 404 | } | ||
| 344 | } /* else go through */ | 405 | } /* else go through */ |
| 345 | } | 406 | } |
| 346 | traversestrongtable(g, h); | 407 | traversestrongtable(g, h); |
| 408 | return TRAVCOST + h->sizearray + (2 * sizenode(h)); | ||
| 347 | } | 409 | } |
| 348 | 410 | ||
| 349 | 411 | ||
| 350 | /* | 412 | static int traverseproto (global_State *g, Proto *f) { |
| 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) { | ||
| 355 | int i; | 413 | int i; |
| 356 | if (f->source) stringmark(f->source); | 414 | stringmark(f->source); |
| 357 | for (i=0; i<f->sizek; i++) /* mark literals */ | 415 | for (i = 0; i < f->sizek; i++) /* mark literals */ |
| 358 | markvalue(g, &f->k[i]); | 416 | markvalue(g, &f->k[i]); |
| 359 | for (i=0; i<f->sizeupvalues; i++) { /* mark upvalue names */ | 417 | for (i = 0; i < f->sizeupvalues; i++) /* mark upvalue names */ |
| 360 | if (f->upvalues[i].name) | 418 | stringmark(f->upvalues[i].name); |
| 361 | stringmark(f->upvalues[i].name); | 419 | for (i = 0; i < f->sizep; i++) /* mark nested protos */ |
| 362 | } | ||
| 363 | for (i=0; i<f->sizep; i++) /* mark nested protos */ | ||
| 364 | markobject(g, f->p[i]); | 420 | markobject(g, f->p[i]); |
| 365 | for (i=0; i<f->sizelocvars; i++) { /* mark local-variable names */ | 421 | for (i = 0; i < f->sizelocvars; i++) /* mark local-variable names */ |
| 366 | if (f->locvars[i].varname) | 422 | stringmark(f->locvars[i].varname); |
| 367 | stringmark(f->locvars[i].varname); | 423 | return TRAVCOST + f->sizek + f->sizeupvalues + f->sizep + f->sizelocvars; |
| 368 | } | ||
| 369 | } | 424 | } |
| 370 | 425 | ||
| 371 | 426 | ||
| 372 | static void traverseclosure (global_State *g, Closure *cl) { | 427 | static l_mem traverseclosure (global_State *g, Closure *cl) { |
| 373 | markobject(g, cl->c.env); | ||
| 374 | if (cl->c.isC) { | 428 | if (cl->c.isC) { |
| 375 | int i; | 429 | int i; |
| 376 | for (i=0; i<cl->c.nupvalues; i++) /* mark its upvalues */ | 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 | else { | 433 | else { |
| 380 | int i; | 434 | int i; |
| 381 | lua_assert(cl->l.nupvalues == cl->l.p->sizeupvalues); | 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 | for (i=0; i<cl->l.nupvalues; i++) /* mark its upvalues */ | 437 | for (i=0; i<cl->l.nupvalues; i++) /* mark its upvalues */ |
| 384 | markobject(g, cl->l.upvals[i]); | 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) { | 444 | static int traversestack (global_State *g, lua_State *L) { |
| 390 | StkId o; | 445 | StkId o = L->stack; |
| 391 | if (L->stack == NULL) | 446 | if (o == NULL) |
| 392 | return; /* stack not completely built yet */ | 447 | return 1; /* stack not completely built yet */ |
| 393 | for (o = L->stack; o < L->top; o++) | 448 | for (; o < L->top; o++) |
| 394 | markvalue(g, o); | 449 | markvalue(g, o); |
| 395 | if (g->gcstate == GCSatomic) { /* final traversal? */ | 450 | if (g->gcstate == GCSatomic) { /* final traversal? */ |
| 396 | StkId lim = L->stack + L->stacksize; /* real end of stack */ | 451 | StkId lim = L->stack + L->stacksize; /* real end of stack */ |
| 397 | for (; o < lim; o++) /* clear not-marked stack slice */ | 452 | for (; o < lim; o++) /* clear not-marked stack slice */ |
| 398 | setnilvalue(o); | 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. | 460 | ** traverse one gray object, turning it to black (except for threads, |
| 405 | ** Returns `quantity' traversed. | 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 | GCObject *o = g->gray; | 465 | GCObject *o = g->gray; |
| 409 | lua_assert(isgray(o)); | 466 | lua_assert(isgray(o)); |
| 410 | gray2black(o); | 467 | gray2black(o); |
| @@ -412,16 +469,12 @@ static l_mem propagatemark (global_State *g) { · 1 unmodified line | |||
| 412 | case LUA_TTABLE: { | 469 | case LUA_TTABLE: { |
| 413 | Table *h = gco2t(o); | 470 | Table *h = gco2t(o); |
| 414 | g->gray = h->gclist; | 471 | g->gray = h->gclist; |
| 415 | traversetable(g, h); | 472 | return traversetable(g, h); |
| 416 | return sizeof(Table) + sizeof(TValue) * h->sizearray + | ||
| 417 | sizeof(Node) * sizenode(h); | ||
| 418 | } | 473 | } |
| 419 | case LUA_TFUNCTION: { | 474 | case LUA_TFUNCTION: { |
| 420 | Closure *cl = gco2cl(o); | 475 | Closure *cl = gco2cl(o); |
| 421 | g->gray = cl->c.gclist; | 476 | g->gray = cl->c.gclist; |
| 422 | traverseclosure(g, cl); | 477 | return traverseclosure(g, cl); |
| 423 | return (cl->c.isC) ? sizeCclosure(cl->c.nupvalues) : | ||
| 424 | sizeLclosure(cl->l.nupvalues); | ||
| 425 | } | 478 | } |
| 426 | case LUA_TTHREAD: { | 479 | case LUA_TTHREAD: { |
| 427 | lua_State *th = gco2th(o); | 480 | lua_State *th = gco2th(o); |
| @@ -429,19 +482,12 @@ static l_mem propagatemark (global_State *g) { · 1 unmodified line | |||
| 429 | th->gclist = g->grayagain; | 482 | th->gclist = g->grayagain; |
| 430 | g->grayagain = o; | 483 | g->grayagain = o; |
| 431 | black2gray(o); | 484 | black2gray(o); |
| 432 | traversestack(g, th); | 485 | return traversestack(g, th); |
| 433 | return sizeof(lua_State) + sizeof(TValue) * th->stacksize; | ||
| 434 | } | 486 | } |
| 435 | case LUA_TPROTO: { | 487 | case LUA_TPROTO: { |
| 436 | Proto *p = gco2p(o); | 488 | Proto *p = gco2p(o); |
| 437 | g->gray = p->gclist; | 489 | g->gray = p->gclist; |
| 438 | traverseproto(g, p); | 490 | return 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; | ||
| 445 | } | 491 | } |
| 446 | default: lua_assert(0); return 0; | 492 | default: lua_assert(0); return 0; |
| 447 | } | 493 | } |
| @@ -465,14 +511,14 @@ static void convergeephemerons (global_State *g) { · 17 unmodified lines | |||
| 465 | int changed; | 511 | int changed; |
| 466 | do { | 512 | do { |
| 467 | GCObject *w; | 513 | GCObject *w; |
| 468 | GCObject *next = g->ephemeron; | 514 | GCObject *next = g->ephemeron; /* get ephemeron list */ |
| 469 | g->ephemeron = NULL; | 515 | g->ephemeron = NULL; /* tables will return to this list when traversed */ |
| 470 | changed = 0; | 516 | changed = 0; |
| 471 | while ((w = next) != NULL) { | 517 | while ((w = next) != NULL) { |
| 472 | next = gco2t(w)->gclist; | 518 | next = gco2t(w)->gclist; |
| 473 | if (traverseephemeron(g, gco2t(w))) { | 519 | if (traverseephemeron(g, gco2t(w))) { /* traverse marked some value? */ |
| 474 | changed = 1; | 520 | propagateall(g); /* propagate changes */ |
| 475 | propagateall(g); | 521 | changed = 1; /* will have to revisit all ephemeron tables */ |
| 476 | } | 522 | } |
| 477 | } | 523 | } |
| 478 | } while (changed); | 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 | static void cleartable (GCObject *l) { | 539 | static void cleartable (GCObject *l) { |
| 492 | while (l) { | 540 | for (; l != NULL; l = gco2t(l)->gclist) { |
| 493 | Table *h = gco2t(l); | 541 | Table *h = gco2t(l); |
| 494 | int i = h->sizearray; | 542 | Node *n, *limit = gnode(h, sizenode(h)); |
| 495 | while (i--) { | 543 | int i; |
| 544 | for (i = 0; i < h->sizearray; i++) { | ||
| 496 | TValue *o = &h->array[i]; | 545 | TValue *o = &h->array[i]; |
| 497 | if (iscleared(o, 0)) /* value was collected? */ | 546 | if (iscleared(o, 0)) /* value was collected? */ |
| 498 | setnilvalue(o); /* remove value */ | 547 | setnilvalue(o); /* remove value */ |
| 499 | } | 548 | } |
| 500 | i = sizenode(h); | 549 | for (n = gnode(h, 0); n < limit; n++) { |
| 501 | while (i--) { | ||
| 502 | Node *n = gnode(h, i); | ||
| 503 | if (!ttisnil(gval(n)) && /* non-empty entry? */ | 550 | if (!ttisnil(gval(n)) && /* non-empty entry? */ |
| 504 | (iscleared(key2tval(n), 1) || iscleared(gval(n), 0))) { | 551 | (iscleared(key2tval(n), 1) || iscleared(gval(n), 0))) { |
| 505 | setnilvalue(gval(n)); /* remove value ... */ | 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 | static GCObject **sweeplist (lua_State *L, GCObject **p, lu_mem count); | 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 | if (L1->stack == NULL) return; /* stack not completely built yet */ | 587 | if (L1->stack == NULL) return; /* stack not completely built yet */ |
| 538 | sweepwholelist(L, &L1->openupval); /* sweep open upvalues */ | 588 | sweepwholelist(L, &L1->openupval); /* sweep open upvalues */ |
| 539 | luaE_freeCI(L1); /* free extra CallInfo slots */ | 589 | luaE_freeCI(L1); /* free extra CallInfo slots */ |
| 540 | /* should not change the stack during an emergency gc cycle */ | 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 | luaD_shrinkstack(L1); | 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 | static GCObject **sweeplist (lua_State *L, GCObject **p, lu_mem count) { | 607 | static GCObject **sweeplist (lua_State *L, GCObject **p, lu_mem count) { |
| 547 | GCObject *curr; | ||
| 548 | global_State *g = G(L); | 608 | global_State *g = G(L); |
| 549 | int deadmask = otherwhite(g); | 609 | int ow = otherwhite(g); |
| 550 | while ((curr = *p) != NULL && count-- > 0) { | 610 | int toclear, toset; /* bits to clear and to set in all live objects */ |
| 551 | int alive = (gch(curr)->marked ^ WHITEBITS) & deadmask; | 611 | int tostop; /* stop sweep when this is true */ |
| 552 | if (gch(curr)->tt == LUA_TTHREAD) | 612 | if (isgenerational(g)) { /* generational mode? */ |
| 553 | sweepthread(L, gco2th(curr), alive); | 613 | toclear = ~0; /* clear nothing */ |
| 554 | if (alive) { | 614 | toset = bitmask(OLDBIT); /* set the old bit of all surviving objects */ |
| 555 | lua_assert(!isdead(g, curr) || testbit(gch(curr)->marked, FIXEDBIT)); | 615 | tostop = bitmask(OLDBIT); /* do not sweep old generation */ |
| 556 | makewhite(g, curr); /* make it white (for next cycle) */ | 616 | } |
| 557 | p = &gch(curr)->next; | 617 | else { /* normal mode */ |
| 558 | } | 618 | toclear = maskcolors; /* clear all color bits + old bit */ |
| 559 | else { /* must erase `curr' */ | 619 | toset = luaC_white(g); /* make object white */ |
| 560 | lua_assert(isdead(g, curr) || deadmask == bitmask(SFIXEDBIT)); | 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 | *p = gch(curr)->next; /* remove 'curr' from list */ | 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 | return p; | 641 | return p; |
| @@ -576,25 +652,28 @@ static GCObject **sweeplist (lua_State *L, GCObject **p, lu_mem count) { · 10 unmodified lines | |||
| 576 | 652 | ||
| 577 | static void checkSizes (lua_State *L) { | 653 | static void checkSizes (lua_State *L) { |
| 578 | global_State *g = G(L); | 654 | global_State *g = G(L); |
| 579 | if (g->strt.nuse < cast(lu_int32, g->strt.size)) { | 655 | if (g->gckind != KGC_EMERGENCY) { /* do not change sizes in emergency */ |
| 580 | /* string-table size could be the smaller power of 2 larger than 'nuse' */ | 656 | int hs = g->strt.size / 2; /* half the size of the string table */ |
| 581 | int size = 1 << luaO_ceillog2(g->strt.nuse); | 657 | if (g->strt.nuse < cast(lu_int32, hs)) /* using less than that half? */ |
| 582 | if (size < g->strt.size) /* current table too large? */ | 658 | luaS_resize(L, hs); /* halve its size */ |
| 583 | luaS_resize(L, size); /* shrink it */ | 659 | luaZ_freebuffer(L, &g->buff); /* free concatenation buffer */ |
| 584 | } | 660 | } |
| 585 | luaZ_freebuffer(L, &g->buff); | ||
| 586 | } | 661 | } |
| 587 | 662 | ||
| 588 | 663 | ||
| 589 | static Udata *udata2finalize (global_State *g) { | 664 | static Udata *udata2finalize (global_State *g) { |
| 590 | GCObject *o = g->tobefnz; /* get first element */ | 665 | GCObject *o = g->tobefnz; /* get first element */ |
| 591 | g->tobefnz = gch(o)->next; /* remove it from 'tobefnz' list */ | 666 | Udata *u = rawgco2u(o); |
| 592 | gch(o)->next = g->rootgc; /* return it to `root' list */ | 667 | lua_assert(isfinalized(&u->uv)); |
| 593 | g->rootgc = o; | 668 | lua_assert(!isold(o)); |
| 594 | lua_assert(isfinalized(gch(o))); | 669 | g->tobefnz = u->uv.next; /* remove it from 'tobefnz' list */ |
| 595 | resetbit(gch(o)->marked, SEPARATED); /* mark it as such */ | 670 | u->uv.next = g->allgc; /* return it to 'allgc' list */ |
| 596 | makewhite(g, o); | 671 | g->allgc = o; |
| 597 | return rawgco2u(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 | global_State *g = G(L); | 687 | global_State *g = G(L); |
| 609 | Udata *udata = udata2finalize(g); | 688 | Udata *udata = udata2finalize(g); |
| 610 | const TValue *tm = gfasttm(g, udata->uv.metatable, TM_GC); | 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 | int status; | 691 | int status; |
| 613 | lu_byte oldah = L->allowhook; | 692 | lu_byte oldah = L->allowhook; |
| 614 | lu_mem oldt = g->GCthreshold; | 693 | lu_mem oldd = g->GCdebt; |
| 615 | L->allowhook = 0; /* stop debug hooks during GC tag method */ | 694 | L->allowhook = 0; /* stop debug hooks during GC tag method */ |
| 616 | g->GCthreshold = 2*g->totalbytes; /* avoid GC steps */ | 695 | stopgc(g); /* avoid GC steps */ |
| 617 | setobj2s(L, L->top, tm); | 696 | setobj2s(L, L->top, tm); /* push finalizer... */ |
| 618 | setuvalue(L, L->top+1, udata); | 697 | setuvalue(L, L->top+1, udata); /* ... and its argument */ |
| 619 | L->top += 2; | 698 | L->top += 2; /* and (next line) call the finalizer */ |
| 620 | status = luaD_pcall(L, dothecall, NULL, savestack(L, L->top - 2), 0); | 699 | status = luaD_pcall(L, dothecall, NULL, savestack(L, L->top - 2), 0); |
| 621 | L->allowhook = oldah; /* restore hooks */ | 700 | L->allowhook = oldah; /* restore hooks */ |
| 622 | g->GCthreshold = oldt; /* restore threshold */ | 701 | g->GCdebt = oldd; /* restore threshold */ |
| 623 | if (status != LUA_OK && propagateerrors) { /* error while running __gc? */ | 702 | if (status != LUA_OK && propagateerrors) { /* error while running __gc? */ |
| 624 | if (status == LUA_ERRRUN) { /* is there an error msg.? */ | 703 | if (status == LUA_ERRRUN) { /* is there an error msg.? */ |
| 625 | luaO_pushfstring(L, "error in __gc tag method (%s)", | 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 | void luaC_separateudata (lua_State *L, int all) { | 718 | void luaC_separateudata (lua_State *L, int all) { |
| 637 | global_State *g = G(L); | 719 | global_State *g = G(L); |
| 638 | GCObject **p = &g->mainthread->next; | 720 | GCObject **p = &g->udgc; |
| 639 | GCObject *curr; | 721 | GCObject *curr; |
| 640 | GCObject **lastnext = &g->tobefnz; | 722 | GCObject **lastnext = &g->tobefnz; |
| 641 | /* find last 'next' field in 'tobefnz' list (to insert elements in its end) */ | 723 | /* find last 'next' field in 'tobefnz' list (to add elements in its end) */ |
| 642 | while (*lastnext != NULL) lastnext = &gch(*lastnext)->next; | 724 | while (*lastnext != NULL) |
| 725 | lastnext = &gch(*lastnext)->next; | ||
| 643 | while ((curr = *p) != NULL) { /* traverse all finalizable objects */ | 726 | while ((curr = *p) != NULL) { /* traverse all finalizable objects */ |
| 644 | lua_assert(gch(curr)->tt == LUA_TUSERDATA && !isfinalized(gco2u(curr))); | 727 | lua_assert(gch(curr)->tt == LUA_TUSERDATA && !isfinalized(gco2u(curr))); |
| 645 | lua_assert(testbit(gch(curr)->marked, SEPARATED)); | 728 | lua_assert(testbit(gch(curr)->marked, SEPARATED)); |
| @@ -647,9 +730,8 @@ void luaC_separateudata (lua_State *L, int all) { · 1 unmodified line | |||
| 647 | p = &gch(curr)->next; /* don't bother with it */ | 730 | p = &gch(curr)->next; /* don't bother with it */ |
| 648 | else { | 731 | else { |
| 649 | l_setbit(gch(curr)->marked, FINALIZEDBIT); /* won't be finalized again */ | 732 | l_setbit(gch(curr)->marked, FINALIZEDBIT); /* won't be finalized again */ |
| 650 | *p = gch(curr)->next; /* remove 'curr' from 'rootgc' list */ | 733 | *p = gch(curr)->next; /* remove 'curr' from 'udgc' list */ |
| 651 | /* link 'curr' at the end of 'tobefnz' list */ | 734 | gch(curr)->next = *lastnext; /* link at the end of 'tobefnz' list */ |
| 652 | gch(curr)->next = *lastnext; | ||
| 653 | *lastnext = curr; | 735 | *lastnext = curr; |
| 654 | lastnext = &gch(curr)->next; | 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 | void luaC_checkfinalizer (lua_State *L, Udata *u) { | 746 | void luaC_checkfinalizer (lua_State *L, Udata *u) { |
| 661 | global_State *g = G(L); | 747 | global_State *g = G(L); |
| 662 | if (testbit(u->uv.marked, SEPARATED) || /* userdata is already separated... */ | 748 | if (testbit(u->uv.marked, SEPARATED) || /* udata is already separated... */ |
| 663 | isfinalized(&u->uv) || /* ... or is finalized... */ | 749 | isfinalized(&u->uv) || /* ... or is finalized... */ |
| 664 | gfasttm(g, u->uv.metatable, TM_GC) == NULL) /* or has no finalization? */ | 750 | gfasttm(g, u->uv.metatable, TM_GC) == NULL) /* or has no finalizer? */ |
| 665 | return; /* nothing to be done */ | 751 | return; /* nothing to be done */ |
| 666 | else { /* move 'u' to 2nd part of root list */ | 752 | else { /* move 'u' to 'udgc' list */ |
| 667 | GCObject **p; | 753 | GCObject **p; |
| 668 | for (p = &g->rootgc; *p != obj2gco(u); p = &gch(*p)->next) | 754 | for (p = &g->allgc; *p != obj2gco(u); p = &gch(*p)->next) ; |
| 669 | lua_assert(*p != obj2gco(g->mainthread)); /* 'u' must be in this list */ | ||
| 670 | *p = u->uv.next; /* remove 'u' from root list */ | 755 | *p = u->uv.next; /* remove 'u' from root list */ |
| 671 | u->uv.next = g->mainthread->next; /* re-link it in list */ | 756 | u->uv.next = g->udgc; /* link it in list 'udgc' */ |
| 672 | g->mainthread->next = obj2gco(u); | 757 | g->udgc = obj2gco(u); |
| 673 | l_setbit(u->uv.marked, SEPARATED); /* mark it as such */ | 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 | void luaC_freeallobjects (lua_State *L) { | 807 | void luaC_freeallobjects (lua_State *L) { |
| 687 | global_State *g = G(L); | 808 | global_State *g = G(L); |
| 688 | int i; | 809 | int i; |
| 689 | while (g->tobefnz) GCTM(L, 0); /* Call all pending finalizers */ | 810 | callallpendingfinalizers(L, 0); |
| 690 | /* following "white" makes all objects look dead */ | 811 | /* following "white" makes all objects look dead */ |
| 691 | g->currentwhite = WHITEBITS | bitmask(SFIXEDBIT); | 812 | g->currentwhite = WHITEBITS; |
| 692 | sweepwholelist(L, &g->rootgc); | 813 | g->gckind = KGC_NORMAL; |
| 693 | lua_assert(g->rootgc == obj2gco(g->mainthread) && | 814 | sweepwholelist(L, &g->udgc); |
| 694 | g->mainthread->next == NULL); | 815 | lua_assert(g->udgc == NULL); |
| 816 | sweepwholelist(L, &g->allgc); | ||
| 817 | lua_assert(g->allgc == NULL); | ||
| 695 | for (i = 0; i < g->strt.size; i++) /* free all string lists */ | 818 | for (i = 0; i < g->strt.size; i++) /* free all string lists */ |
| 696 | sweepwholelist(L, &g->strt.hash[i]); | 819 | sweepwholelist(L, &g->strt.hash[i]); |
| 697 | lua_assert(g->strt.nuse == 0); | 820 | lua_assert(g->strt.nuse == 0); |
| @@ -700,7 +823,6 @@ void luaC_freeallobjects (lua_State *L) { · 2 unmodified lines | |||
| 700 | 823 | ||
| 701 | static void atomic (lua_State *L) { | 824 | static void atomic (lua_State *L) { |
| 702 | global_State *g = G(L); | 825 | global_State *g = G(L); |
| 703 | g->gcstate = GCSatomic; | ||
| 704 | lua_assert(!iswhite(obj2gco(g->mainthread))); | 826 | lua_assert(!iswhite(obj2gco(g->mainthread))); |
| 705 | markobject(g, L); /* mark running thread */ | 827 | markobject(g, L); /* mark running thread */ |
| 706 | /* registry and global metatables may be changed by API */ | 828 | /* registry and global metatables may be changed by API */ |
| @@ -710,12 +832,11 @@ static void atomic (lua_State *L) { · 3 unmodified lines | |||
| 710 | remarkupvals(g); | 832 | remarkupvals(g); |
| 711 | /* traverse objects caught by write barrier and by 'remarkupvals' */ | 833 | /* traverse objects caught by write barrier and by 'remarkupvals' */ |
| 712 | propagateall(g); | 834 | propagateall(g); |
| 713 | /* at this point, all strongly accessible objects are marked. | ||
| 714 | Start marking weakly accessible objects. */ | ||
| 715 | traverselistofgrays(g, &g->weak); /* remark weak tables */ | 835 | traverselistofgrays(g, &g->weak); /* remark weak tables */ |
| 716 | traverselistofgrays(g, &g->ephemeron); /* remark ephemeron tables */ | 836 | traverselistofgrays(g, &g->ephemeron); /* remark ephemeron tables */ |
| 717 | traverselistofgrays(g, &g->grayagain); /* remark gray again */ | 837 | traverselistofgrays(g, &g->grayagain); /* remark gray again */ |
| 718 | convergeephemerons(g); | 838 | convergeephemerons(g); |
| 839 | /* at this point, all strongly accessible objects are marked. */ | ||
| 719 | luaC_separateudata(L, 0); /* separate userdata to be finalized */ | 840 | luaC_separateudata(L, 0); /* separate userdata to be finalized */ |
| 720 | markbeingfnz(g); /* mark userdata that will be finalized */ | 841 | markbeingfnz(g); /* mark userdata that will be finalized */ |
| 721 | propagateall(g); /* remark, to propagate `preserveness' */ | 842 | propagateall(g); /* remark, to propagate `preserveness' */ |
| @@ -724,51 +845,68 @@ static void atomic (lua_State *L) { · 2 unmodified lines | |||
| 724 | cleartable(g->weak); | 845 | cleartable(g->weak); |
| 725 | cleartable(g->ephemeron); | 846 | cleartable(g->ephemeron); |
| 726 | cleartable(g->allweak); | 847 | cleartable(g->allweak); |
| 727 | g->currentwhite = cast_byte(otherwhite(g)); /* flip current white */ | 848 | g->sweepstrgc = 0; /* prepare to sweep strings */ |
| 728 | g->sweepstrgc = 0; /* go to sweep phase */ | ||
| 729 | g->gcstate = GCSsweepstring; | 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 | static l_mem singlestep (lua_State *L) { | 855 | static l_mem singlestep (lua_State *L) { |
| 734 | global_State *g = G(L); | 856 | global_State *g = G(L); |
| 735 | /*lua_checkmemory(L);*/ | ||
| 736 | switch (g->gcstate) { | 857 | switch (g->gcstate) { |
| 737 | case GCSpause: { | 858 | case GCSpause: { |
| 738 | markroot(L); /* start a new collection */ | 859 | if (!isgenerational(g)) |
| 739 | return 0; | 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 | case GCSpropagate: { | 867 | case GCSpropagate: { |
| 742 | if (g->gray) | 868 | if (g->gray) |
| 743 | return propagatemark(g); | 869 | return propagatemark(g); |
| 744 | else { /* no more `gray' objects */ | 870 | else { /* no more `gray' objects */ |
| 745 | atomic(L); /* finish mark phase */ | 871 | g->gcstate = GCSatomic; /* finish mark phase */ |
| 746 | return 0; | 872 | atomic(L); |
| 873 | return GCATOMICCOST; | ||
| 747 | } | 874 | } |
| 748 | } | 875 | } |
| 749 | case GCSsweepstring: { | 876 | case GCSsweepstring: { |
| 750 | sweepwholelist(L, &g->strt.hash[g->sweepstrgc++]); | 877 | if (g->sweepstrgc < g->strt.size) { |
| 751 | if (g->sweepstrgc >= g->strt.size) { /* nothing more to sweep? */ | 878 | sweepwholelist(L, &g->strt.hash[g->sweepstrgc++]); |
| 752 | g->sweepgc = &g->rootgc; | 879 | return GCSWEEPCOST; |
| 753 | g->gcstate = GCSsweep; /* sweep all other objects */ | 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: { | 887 | case GCSsweepudata: { |
| 758 | g->sweepgc = sweeplist(L, g->sweepgc, GCSWEEPMAX); | 888 | if (*g->sweepgc) { |
| 759 | if (*g->sweepgc == NULL) /* nothing more to sweep? */ | 889 | g->sweepgc = sweeplist(L, g->sweepgc, GCSWEEPMAX); |
| 760 | g->gcstate = GCSfinalize; /* end sweep phase */ | 890 | return GCSWEEPMAX*GCSWEEPCOST; |
| 761 | 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: { | 898 | case GCSsweep: { |
| 764 | if (g->tobefnz) { | 899 | if (*g->sweepgc) { |
| 765 | GCTM(L, 1); | 900 | g->sweepgc = sweeplist(L, g->sweepgc, GCSWEEPMAX); |
| 766 | return GCFINALIZECOST; | 901 | return GCSWEEPMAX*GCSWEEPCOST; |
| 767 | } | 902 | } |
| 768 | else { | 903 | else { |
| 904 | /* sweep main thread */ | ||
| 905 | GCObject *mt = obj2gco(g->mainthread); | ||
| 906 | sweeplist(L, &mt, 1); | ||
| 769 | checkSizes(L); | 907 | checkSizes(L); |
| 770 | g->gcstate = GCSpause; /* end collection */ | 908 | g->gcstate = GCSpause; /* finish collection */ |
| 771 | return 0; | 909 | return GCSWEEPCOST; |
| 772 | } | 910 | } |
| 773 | } | 911 | } |
| 774 | default: lua_assert(0); return 0; | 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 | ** advances the garbage collector until it reaches a state allowed | 918 | ** advances the garbage collector until it reaches a state allowed |
| 797 | ** by 'statemask' | 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 | ** finalizers (which could change stack positions) | 967 | ** finalizers (which could change stack positions) |
| 809 | */ | 968 | */ |
| 810 | void luaC_fullgc (lua_State *L, int isemergency) { | 969 | void luaC_fullgc (lua_State *L, int isemergency) { |
| 811 | global_State *g = G(L); | 970 | global_State *g = G(L); |
| 812 | lua_assert(g->gckind == KGC_NORMAL); | 971 | int origkind = g->gckind; |
| 813 | g->gckind = isemergency ? KGC_EMERGENCY : KGC_FORCED; | 972 | lua_assert(origkind != KGC_EMERGENCY); |
| 814 | if (g->gcstate == GCSpropagate) { /* marking phase? */ | 973 | if (!isemergency) /* do not run finalizers during emergency GC */ |
| 974 | callallpendingfinalizers(L, 1); | ||
| 975 | if (keepinvariant(g)) { /* marking phase? */ | ||
| 815 | /* must sweep all objects to turn them back to white | 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 | g->sweepstrgc = 0; | 978 | g->sweepstrgc = 0; |
| 818 | g->gcstate = GCSsweepstring; | 979 | g->gcstate = GCSsweepstring; |
| 819 | } | 980 | } |
| 820 | /* finish any pending sweep phase */ | 981 | g->gckind = isemergency ? KGC_EMERGENCY : KGC_NORMAL; |
| 821 | luaC_runtilstate(L, ~bit2mask(GCSsweepstring, GCSsweep)); | 982 | /* finish any pending sweep phase to start a new cycle */ |
| 822 | markroot(L); /* start a new collection */ | 983 | luaC_runtilstate(L, bitmask(GCSpause)); |
| 823 | /* run collector up to finalizers */ | 984 | /* run entire collector */ |
| 824 | luaC_runtilstate(L, bitmask(GCSfinalize)); | 985 | luaC_runtilstate(L, ~bitmask(GCSpause)); |
| 825 | g->gckind = KGC_NORMAL; | 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 | if (!isemergency) /* do not run finalizers during emergency GC */ | 993 | if (!isemergency) /* do not run finalizers during emergency GC */ |
| 827 | luaC_runtilstate(L, ~bitmask(GCSfinalize)); | 994 | callallpendingfinalizers(L, 1); |
| 828 | g->GCthreshold = (g->totalbytes/100) * g->gcpause; | ||
| 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 | ** Garbage Collector | 3 | ** Garbage Collector |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -9,18 +9,51 @@ · 3 unmodified lines | |||
| 9 | 9 | ||
| 10 | 10 | ||
| 11 | #include "lobject.h" | 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 | ** Possible states of the Garbage Collector | 29 | ** Possible states of the Garbage Collector |
| 16 | */ | 30 | */ |
| 17 | #define GCSpause 0 | 31 | #define GCSpropagate 0 |
| 18 | #define GCSpropagate 1 | 32 | #define GCSatomic 1 |
| 19 | #define GCSatomic 2 | 33 | #define GCSsweepstring 2 |
| 20 | #define GCSsweepstring 3 | 34 | #define GCSsweepudata 3 |
| 21 | #define GCSsweep 4 | 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 | /* | 75 | /* Layout for bit use in `marked' field: */ |
| 43 | ** Layout for bit use in `marked' field: | 76 | #define WHITE0BIT 0 /* object is white (type 0) */ |
| 44 | ** bit 0 - object is white (type 0) | 77 | #define WHITE1BIT 1 /* object is white (type 1) */ |
| 45 | ** bit 1 - object is white (type 1) | 78 | #define BLACKBIT 2 /* object is black */ |
| 46 | ** bit 2 - object is black | 79 | #define FINALIZEDBIT 3 /* for userdata: has been finalized */ |
| 47 | ** bit 3 - for userdata: has been finalized | 80 | #define SEPARATED 4 /* " ": it's in 'udgc' list or in 'tobefnz' */ |
| 48 | ** bit 4 - for userdata: it's in 2nd part of rootgc list or in tobefnz | 81 | #define FIXEDBIT 5 /* object is fixed (should not be collected) */ |
| 49 | ** bit 5 - object is fixed (should not be collected) | 82 | #define OLDBIT 6 /* object is old (only in generational mode) */ |
| 50 | ** bit 6 - object is "super" fixed (only the main thread) | 83 | /* bit 7 is currently used by tests (luaL_checkmemory) */ |
| 51 | */ | ||
| 52 | |||
| 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 | #define WHITEBITS bit2mask(WHITE0BIT, WHITE1BIT) | 85 | #define WHITEBITS bit2mask(WHITE0BIT, WHITE1BIT) |
| 62 | 86 | ||
| 63 | 87 | ||
| 64 | #define iswhite(x) testbits((x)->gch.marked, WHITEBITS) | 88 | #define iswhite(x) testbits((x)->gch.marked, WHITEBITS) |
| 65 | #define isblack(x) testbit((x)->gch.marked, BLACKBIT) | 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 | #define otherwhite(g) (g->currentwhite ^ WHITEBITS) | 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 | #define changewhite(x) ((x)->gch.marked ^= WHITEBITS) | 103 | #define changewhite(x) ((x)->gch.marked ^= WHITEBITS) |
| 72 | #define gray2black(x) l_setbit((x)->gch.marked, BLACKBIT) | 104 | #define gray2black(x) l_setbit((x)->gch.marked, BLACKBIT) |
| @@ -76,8 +108,7 @@ · 3 unmodified lines | |||
| 76 | #define luaC_white(g) cast(lu_byte, (g)->currentwhite & WHITEBITS) | 108 | #define luaC_white(g) cast(lu_byte, (g)->currentwhite & WHITEBITS) |
| 77 | 109 | ||
| 78 | 110 | ||
| 79 | #define luaC_checkGC(L) \ | 111 | #define luaC_checkGC(L) {condchangemem(L); if (G(L)->GCdebt > 0) luaC_step(L);} |
| 80 | {condchangemem(L); if (G(L)->totalbytes >= G(L)->GCthreshold) luaC_step(L);} | ||
| 81 | 112 | ||
| 82 | 113 | ||
| 83 | #define luaC_barrier(L,p,v) { if (valiswhite(v) && isblack(obj2gco(p))) \ | 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 | LUAI_FUNC void luaC_fullgc (lua_State *L, int isemergency); | 131 | LUAI_FUNC void luaC_fullgc (lua_State *L, int isemergency); |
| 101 | LUAI_FUNC GCObject *luaC_newobj (lua_State *L, int tt, size_t sz, | 132 | LUAI_FUNC GCObject *luaC_newobj (lua_State *L, int tt, size_t sz, |
| 102 | GCObject **list, int offset); | 133 | GCObject **list, int offset); |
| 103 | LUAI_FUNC void luaC_linkupval (lua_State *L, UpVal *uv); | ||
| 104 | LUAI_FUNC void luaC_barrierf (lua_State *L, GCObject *o, GCObject *v); | 134 | LUAI_FUNC void luaC_barrierf (lua_State *L, GCObject *o, GCObject *v); |
| 105 | LUAI_FUNC void luaC_barrierback (lua_State *L, Table *t); | 135 | LUAI_FUNC void luaC_barrierback (lua_State *L, Table *t); |
| 106 | LUAI_FUNC void luaC_checkfinalizer (lua_State *L, Udata *u); | 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 | #endif | 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 | ** Initialization of libraries for lua.c and other clients | 3 | ** Initialization of libraries for lua.c and other clients |
| 4 | ** See Copyright Notice in lua.h | 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 | const luaL_Reg *lib; | 52 | const luaL_Reg *lib; |
| 53 | /* call open functions from 'loadedlibs' */ | 53 | /* call open functions from 'loadedlibs' */ |
| 54 | for (lib = loadedlibs; lib->func; lib++) { | 54 | for (lib = loadedlibs; lib->func; lib++) { |
| 55 | lua_pushcfunction(L, lib->func); | 55 | lua_settop(L, 0); |
| 56 | lua_pushstring(L, lib->name); | 56 | lua_pushstring(L, lib->name); |
| 57 | lua_call(L, 1, 0); | 57 | (lib->func)(L); |
| 58 | } | 58 | } |
| 59 | /* add open functions from 'preloadedlibs' into 'package.preload' table */ | 59 | /* add open functions from 'preloadedlibs' into 'package.preload' table */ |
| 60 | lua_pushglobaltable(L); | 60 | lua_pushglobaltable(L); |
| @@ -65,8 +65,7 @@ LUALIB_API void luaL_openlibs (lua_State *L) { · 4 unmodified lines | |||
| 65 | } | 65 | } |
| 66 | lua_pop(L, 1); /* remove package.preload table */ | 66 | lua_pop(L, 1); /* remove package.preload table */ |
| 67 | #if defined(LUA_COMPAT_DEBUGLIB) | 67 | #if defined(LUA_COMPAT_DEBUGLIB) |
| 68 | lua_pushglobaltable(L); | 68 | lua_getglobal(L, "require"); |
| 69 | lua_getfield(L, -1, "require"); | ||
| 70 | lua_pushliteral(L, LUA_DBLIBNAME); | 69 | lua_pushliteral(L, LUA_DBLIBNAME); |
| 71 | lua_call(L, 1, 0); /* call 'require"debug"' */ | 70 | lua_call(L, 1, 0); /* call 'require"debug"' */ |
| 72 | lua_pop(L, 1); /* remove global table */ | 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 | ** Standard I/O (and system) library | 3 | ** Standard I/O (and system) library |
| 4 | ** See Copyright Notice in lua.h | 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 | ** When creating file handles, always creates a `closed' file handle | 107 | ** When creating file handles, always creates a `closed' file handle |
| 109 | ** before opening the actual file; so, if there is a memory error, the | 108 | ** before opening the actual file; so, if there is a memory error, the |
| 110 | ** file is not left opened. | 109 | ** file is not left opened. |
| 111 | */ | 110 | */ |
| 112 | static FILE **newfile (lua_State *L) { | 111 | static FILE **newprefile (lua_State *L) { |
| 113 | FILE **pf = (FILE **)lua_newuserdata(L, sizeof(FILE *)); | 112 | FILE **pf = (FILE **)lua_newuserdata(L, sizeof(FILE *)); |
| 114 | *pf = NULL; /* file handle is currently `closed' */ | 113 | *pf = NULL; /* file handle is currently `closed' */ |
| 115 | luaL_getmetatable(L, LUA_FILEHANDLE); | 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 | ** function to (not) close the standard files stdin, stdout, and stderr | 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 | static int aux_close (lua_State *L) { | 165 | static int aux_close (lua_State *L) { |
| 159 | lua_getfenv(L, 1); | 166 | lua_getenv(L, 1); |
| 160 | lua_getfield(L, -1, "__close"); | 167 | lua_getfield(L, -1, "__close"); |
| 161 | return (lua_tocfunction(L, -1))(L); | 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 | static int io_close (lua_State *L) { | 172 | static int io_close (lua_State *L) { |
| 166 | if (lua_isnone(L, 1)) | 173 | if (lua_isnone(L, 1)) |
| 167 | lua_rawgeti(L, LUA_ENVIRONINDEX, IO_OUTPUT); | 174 | lua_rawgeti(L, lua_upvalueindex(1), IO_OUTPUT); |
| 168 | tofile(L); /* make sure argument is a file */ | 175 | tofile(L); /* make sure argument is a file */ |
| 169 | return aux_close(L); | 176 | return aux_close(L); |
| 170 | } | 177 | } |
| @@ -229,7 +236,7 @@ static int io_tmpfile (lua_State *L) { · 58 unmodified lines | |||
| 229 | 236 | ||
| 230 | static FILE *getiofile (lua_State *L, int findex) { | 237 | static FILE *getiofile (lua_State *L, int findex) { |
| 231 | FILE *f; | 238 | FILE *f; |
| 232 | lua_rawgeti(L, LUA_ENVIRONINDEX, findex); | 239 | lua_rawgeti(L, lua_upvalueindex(1), findex); |
| 233 | f = *(FILE **)lua_touserdata(L, -1); | 240 | f = *(FILE **)lua_touserdata(L, -1); |
| 234 | if (f == NULL) | 241 | if (f == NULL) |
| 235 | luaL_error(L, "standard %s file is closed", fnames[findex - 1]); | 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 | tofile(L); /* check that it's a valid file handle */ | 257 | tofile(L); /* check that it's a valid file handle */ |
| 251 | lua_pushvalue(L, 1); | 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 | /* return current value */ | 262 | /* return current value */ |
| 256 | lua_rawgeti(L, LUA_ENVIRONINDEX, f); | 263 | lua_rawgeti(L, lua_upvalueindex(1), f); |
| 257 | return 1; | 264 | return 1; |
| 258 | } | 265 | } |
| 259 | 266 | ||
| @@ -271,35 +278,46 @@ static int io_output (lua_State *L) { · 11 unmodified lines | |||
| 271 | static int io_readline (lua_State *L); | 278 | static int io_readline (lua_State *L); |
| 272 | 279 | ||
| 273 | 280 | ||
| 274 | static void aux_lines (lua_State *L, int idx, int toclose) { | 281 | static void aux_lines (lua_State *L, int toclose) { |
| 275 | lua_pushvalue(L, idx); | 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 | lua_pushboolean(L, toclose); /* close/not close file when finished */ | 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 | static int f_lines (lua_State *L) { | 294 | static int f_lines (lua_State *L) { |
| 282 | tofile(L); /* check that it's a valid file handle */ | 295 | tofile(L); /* check that it's a valid file handle */ |
| 283 | aux_lines(L, 1, 0); | 296 | aux_lines(L, 0); |
| 284 | return 1; | 297 | return 1; |
| 285 | } | 298 | } |
| 286 | 299 | ||
| 287 | 300 | ||
| 288 | static int io_lines (lua_State *L) { | 301 | static int io_lines (lua_State *L) { |
| 289 | if (lua_isnoneornil(L, 1)) { /* no arguments? */ | 302 | int toclose; |
| 290 | /* will iterate over default input */ | 303 | if (lua_isnone(L, 1)) lua_pushnil(L); /* at least one argument */ |
| 291 | lua_rawgeti(L, LUA_ENVIRONINDEX, IO_INPUT); | 304 | if (lua_isnil(L, 1)) { /* no file name? */ |
| 292 | return f_lines(L); | 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 | const char *filename = luaL_checkstring(L, 1); | 311 | const char *filename = luaL_checkstring(L, 1); |
| 296 | FILE **pf = newfile(L); | 312 | FILE **pf = newfile(L); |
| 297 | *pf = fopen(filename, "r"); | 313 | *pf = fopen(filename, "r"); |
| 298 | if (*pf == NULL) | 314 | if (*pf == NULL) |
| 299 | fileerror(L, 1, filename); | 315 | fileerror(L, 1, filename); |
| 300 | aux_lines(L, lua_gettop(L), 1); | 316 | lua_replace(L, 1); /* put file at index 1 */ |
| 301 | return 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 | lua_pushnumber(L, d); | 334 | lua_pushnumber(L, d); |
| 317 | return 1; | 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 | luaL_Buffer b; | 353 | luaL_Buffer b; |
| 333 | luaL_buffinit(L, &b); | 354 | luaL_buffinit(L, &b); |
| 334 | for (;;) { | 355 | for (;;) { |
| @@ -342,7 +363,7 @@ static int read_line (lua_State *L, FILE *f) { · 7 unmodified lines | |||
| 342 | if (l == 0 || p[l-1] != '\n') | 363 | if (l == 0 || p[l-1] != '\n') |
| 343 | luaL_addsize(&b, l); | 364 | luaL_addsize(&b, l); |
| 344 | else { | 365 | else { |
| 345 | luaL_addsize(&b, l - 1); /* do not include `eol' */ | 366 | luaL_addsize(&b, l - chop); /* chop 'eol' if needed */ |
| 346 | luaL_pushresult(&b); /* close buffer */ | 367 | luaL_pushresult(&b); /* close buffer */ |
| 347 | return 1; /* read at least an `eol' */ | 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 | int n; | 396 | int n; |
| 376 | clearerr(f); | 397 | clearerr(f); |
| 377 | if (nargs == 0) { /* no arguments? */ | 398 | if (nargs == 0) { /* no arguments? */ |
| 378 | success = read_line(L, f); | 399 | success = read_line(L, f, 1); |
| 379 | n = first+1; /* to return 1 result */ | 400 | n = first+1; /* to return 1 result */ |
| 380 | } | 401 | } |
| 381 | else { /* ensure stack space for all results and for auxlib's buffer */ | 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 | success = read_number(L, f); | 415 | success = read_number(L, f); |
| 395 | break; | 416 | break; |
| 396 | case 'l': /* line */ | 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 | break; | 422 | break; |
| 399 | case 'a': /* file */ | 423 | case 'a': /* file */ |
| 400 | read_chars(L, f, ~((size_t)0)); /* read MAX_SIZE_T chars */ | 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 | static int io_readline (lua_State *L) { | 453 | static int io_readline (lua_State *L) { |
| 430 | FILE *f = *(FILE **)lua_touserdata(L, lua_upvalueindex(1)); | 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 | if (f == NULL) /* file is already closed? */ | 457 | if (f == NULL) /* file is already closed? */ |
| 433 | luaL_error(L, "file is already closed"); | 458 | luaL_error(L, "file is already closed"); |
| 434 | success = read_line(L, f); | 459 | lua_settop(L , 1); |
| 435 | if (ferror(f)) | 460 | for (i = 1; i <= n; i++) /* push arguments to 'g_read' */ |
| 436 | return luaL_error(L, "%s", strerror(errno)); | 461 | lua_pushvalue(L, lua_upvalueindex(3 + i)); |
| 437 | if (success) return 1; | 462 | n = g_read(L, f, 2); /* 'n' is number of results */ |
| 438 | else { /* EOF */ | 463 | lua_assert(n > 0); /* should return at least a nil */ |
| 439 | if (lua_toboolean(L, lua_upvalueindex(2))) { /* generator created file? */ | 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 | lua_settop(L, 0); | 471 | lua_settop(L, 0); |
| 441 | lua_pushvalue(L, lua_upvalueindex(1)); | 472 | lua_pushvalue(L, lua_upvalueindex(1)); |
| 442 | aux_close(L); /* close it */ | 473 | aux_close(L); /* close it */ |
| @@ -552,23 +583,27 @@ static void createmeta (lua_State *L) { · 109 unmodified lines | |||
| 552 | luaL_newmetatable(L, LUA_FILEHANDLE); /* create metatable for file handles */ | 583 | luaL_newmetatable(L, LUA_FILEHANDLE); /* create metatable for file handles */ |
| 553 | lua_pushvalue(L, -1); /* push metatable */ | 584 | lua_pushvalue(L, -1); /* push metatable */ |
| 554 | lua_setfield(L, -2, "__index"); /* metatable.__index = metatable */ | 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 | static void createstdfile (lua_State *L, FILE *f, int k, const char *fname) { | 591 | static void createstdfile (lua_State *L, FILE *f, int k, const char *fname) { |
| 560 | *newfile(L) = f; | 592 | *newprefile(L) = f; |
| 561 | if (k > 0) { | 593 | if (k > 0) { |
| 562 | lua_pushvalue(L, -1); | 594 | lua_pushvalue(L, -1); /* copy new file */ |
| 563 | lua_rawseti(L, LUA_ENVIRONINDEX, k); | 595 | lua_rawseti(L, 1, k); /* add it to common upvalue */ |
| 564 | } | 596 | } |
| 565 | lua_pushvalue(L, -2); /* copy environment */ | 597 | lua_pushvalue(L, 3); /* get environment for default files */ |
| 566 | lua_setfenv(L, -2); /* set it */ | 598 | lua_setenv(L, -2); /* set it as environment for file */ |
| 567 | lua_setfield(L, -3, fname); | 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 | lua_createtable(L, 0, 1); | 607 | lua_createtable(L, 0, 1); |
| 573 | lua_pushcfunction(L, cls); | 608 | lua_pushcfunction(L, cls); |
| 574 | lua_setfield(L, -2, "__close"); | 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 | LUAMOD_API int luaopen_io (lua_State *L) { | 613 | LUAMOD_API int luaopen_io (lua_State *L) { |
| 614 | lua_settop(L, 0); | ||
| 579 | createmeta(L); | 615 | createmeta(L); |
| 580 | /* create (private) environment (with fields IO_INPUT, IO_OUTPUT, __close) */ | 616 | /* create (private) environment (with fields IO_INPUT, IO_OUTPUT, __close) */ |
| 581 | newfenv(L, io_fclose); | 617 | newenv(L, io_fclose); /* upvalue for all io functions at index 1 */ |
| 582 | lua_replace(L, LUA_ENVIRONINDEX); | 618 | lua_pushvalue(L, -1); /* copy to be consumed by 'openlib' */ |
| 583 | /* open library */ | 619 | luaL_openlib(L, LUA_IOLIBNAME, iolib, 1); /* new module at index 2 */ |
| 584 | luaL_register(L, LUA_IOLIBNAME, iolib); | ||
| 585 | /* create (and set) default files */ | 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 | createstdfile(L, stdin, IO_INPUT, "stdin"); | 622 | createstdfile(L, stdin, IO_INPUT, "stdin"); |
| 588 | createstdfile(L, stdout, IO_OUTPUT, "stdout"); | 623 | createstdfile(L, stdout, IO_OUTPUT, "stdout"); |
| 589 | createstdfile(L, stderr, 0, "stderr"); | 624 | createstdfile(L, stderr, 0, "stderr"); |
| 590 | lua_pop(L, 1); /* pop environment for default files */ | 625 | lua_pop(L, 1); /* pop environment for default files */ |
| 591 | lua_getfield(L, -1, "popen"); | 626 | lua_getfield(L, 2, "popen"); |
| 592 | newfenv(L, io_pclose); /* create environment for 'popen' */ | 627 | newenv(L, io_pclose); /* create environment for 'popen' streams */ |
| 593 | lua_setfenv(L, -2); /* set fenv for 'popen' */ | 628 | lua_setupvalue(L, -2, 1); /* set it as upvalue for 'popen' */ |
| 594 | lua_pop(L, 1); /* pop 'popen' */ | 629 | lua_pop(L, 1); /* pop 'popen' */ |
| 595 | return 1; | 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 | ** Lexical Analyzer | 3 | ** Lexical Analyzer |
| 4 | ** See Copyright Notice in lua.h | 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 | TString *luaX_newstring (LexState *ls, const char *str, size_t l) { | 125 | TString *luaX_newstring (LexState *ls, const char *str, size_t l) { |
| 121 | lua_State *L = ls->L; | 126 | lua_State *L = ls->L; |
| 122 | TValue *o; /* entry for `str' */ | 127 | TValue *o; /* entry for `str' */ |
| 123 | TString *ts = luaS_newlstr(L, str, l); | 128 | TString *ts = luaS_newlstr(L, str, l); /* create new string */ |
| 124 | setsvalue2s(L, L->top++, ts); /* anchor string */ | 129 | setsvalue2s(L, L->top++, ts); /* temporarily anchor it in stack */ |
| 125 | o = luaH_setstr(L, ls->fs->h, ts); | 130 | o = luaH_setstr(L, ls->fs->h, ts); |
| 126 | if (ttisnil(o)) { | 131 | if (ttisnil(o)) { |
| 127 | setbvalue(o, 1); /* make sure `str' will not be collected */ | 132 | setbvalue(o, 1); /* t[string] = true */ |
| 128 | luaC_checkGC(L); | 133 | luaC_checkGC(L); |
| 129 | } | 134 | } |
| 130 | L->top--; | 135 | L->top--; /* remove string from stack */ |
| 131 | return ts; | 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 | static void inclinenumber (LexState *ls) { | 144 | static void inclinenumber (LexState *ls) { |
| 136 | int old = ls->current; | 145 | int old = ls->current; |
| 137 | lua_assert(currIsNewline(ls)); | 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 | ls->linenumber = 1; | 161 | ls->linenumber = 1; |
| 153 | ls->lastline = 1; | 162 | ls->lastline = 1; |
| 154 | ls->source = source; | 163 | ls->source = source; |
| 164 | ls->envn = luaS_new(L, "_ENV"); /* create env name */ | ||
| 165 | luaS_fix(ls->envn); /* never collect this name */ | ||
| 155 | luaZ_resizebuffer(ls->L, ls->buff, LUA_MINBUFFER); /* initialize buffer */ | 166 | luaZ_resizebuffer(ls->L, ls->buff, LUA_MINBUFFER); /* initialize buffer */ |
| 156 | next(ls); /* read first char */ | 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 | static void buffreplace (LexState *ls, char from, char to) { | 191 | static void buffreplace (LexState *ls, char from, char to) { |
| 178 | size_t n = luaZ_bufflen(ls->buff); | 192 | size_t n = luaZ_bufflen(ls->buff); |
| 179 | char *p = luaZ_buffer(ls->buff); | 193 | char *p = luaZ_buffer(ls->buff); |
| @@ -186,11 +200,14 @@ static void buffreplace (LexState *ls, char from, char to) { · 6 unmodified lines | |||
| 186 | #define getlocaledecpoint() (localeconv()->decimal_point[0]) | 200 | #define getlocaledecpoint() (localeconv()->decimal_point[0]) |
| 187 | #endif | 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 | static void trydecpoint (LexState *ls, SemInfo *seminfo) { | 207 | static void trydecpoint (LexState *ls, SemInfo *seminfo) { |
| 190 | /* format error: try to update decimal point separator */ | ||
| 191 | char old = ls->decpoint; | 208 | char old = ls->decpoint; |
| 192 | ls->decpoint = getlocaledecpoint(); | 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 | if (!luaO_str2d(luaZ_buffer(ls->buff), &seminfo->r)) { | 211 | if (!luaO_str2d(luaZ_buffer(ls->buff), &seminfo->r)) { |
| 195 | /* format error with correct decimal point: no more options */ | 212 | /* format error with correct decimal point: no more options */ |
| 196 | buffreplace(ls, ls->decpoint, '.'); /* undo change (for error message) */ | 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 | static int skip_sep (LexState *ls) { | 240 | static int skip_sep (LexState *ls) { |
| 220 | int count = 0; | 241 | int count = 0; |
| 221 | int s = ls->current; | 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 | break; | 268 | break; |
| 248 | } | 269 | } |
| 249 | case '\n': | 270 | case '\n': case '\r': { |
| 250 | case '\r': { | ||
| 251 | save(ls, '\n'); | 271 | save(ls, '\n'); |
| 252 | inclinenumber(ls); | 272 | inclinenumber(ls); |
| 253 | if (!seminfo) luaZ_resetbuffer(ls->buff); /* avoid wasting space */ | 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 | static void read_string (LexState *ls, int del, SemInfo *seminfo) { | 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 | while (ls->current != del) { | 332 | while (ls->current != del) { |
| 313 | switch (ls->current) { | 333 | switch (ls->current) { |
| 314 | case EOZ: | 334 | case EOZ: |
| 315 | lexerror(ls, "unfinished string", TK_EOS); | 335 | lexerror(ls, "unfinished string", TK_EOS); |
| 316 | continue; /* to avoid warnings */ | 336 | break; /* to avoid warnings */ |
| 317 | case '\n': | 337 | case '\n': |
| 318 | case '\r': | 338 | case '\r': |
| 319 | lexerror(ls, "unfinished string", TK_STRING); | 339 | lexerror(ls, "unfinished string", TK_STRING); |
| 320 | continue; /* to avoid warnings */ | 340 | break; /* to avoid warnings */ |
| 321 | case '\\': { /* escape sequences */ | 341 | case '\\': { /* escape sequences */ |
| 322 | int c; /* final character to be saved */ | 342 | int c; /* final character to be saved */ |
| 323 | next(ls); /* do not save the `\' */ | 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 | case '\n': | 353 | case '\n': |
| 334 | case '\r': save(ls, '\n'); inclinenumber(ls); continue; | 354 | case '\r': save(ls, '\n'); inclinenumber(ls); continue; |
| 335 | case EOZ: continue; /* will raise an error next loop */ | 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 | default: { | 364 | default: { |
| 337 | if (!lisdigit(ls->current)) | 365 | if (!lisdigit(ls->current)) |
| 338 | c = ls->current; /* handles \\, \", \', and \? */ | 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 | next(ls); | 372 | next(ls); |
| 345 | save(ls, c); | 373 | save(ls, c); |
| 346 | continue; | 374 | break; |
| 347 | } | 375 | } |
| 348 | default: | 376 | default: |
| 349 | save_and_next(ls); | 377 | save_and_next(ls); |
| @@ -359,31 +387,34 @@ static int llex (LexState *ls, SemInfo *seminfo) { · 9 unmodified lines | |||
| 359 | luaZ_resetbuffer(ls->buff); | 387 | luaZ_resetbuffer(ls->buff); |
| 360 | for (;;) { | 388 | for (;;) { |
| 361 | switch (ls->current) { | 389 | switch (ls->current) { |
| 362 | case '\n': | 390 | case '\n': case '\r': { /* line breaks */ |
| 363 | case '\r': { | ||
| 364 | inclinenumber(ls); | 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 | next(ls); | 399 | next(ls); |
| 369 | if (ls->current != '-') return '-'; | 400 | if (ls->current != '-') return '-'; |
| 370 | /* else is a comment */ | 401 | /* else is a comment */ |
| 371 | next(ls); | 402 | next(ls); |
| 372 | if (ls->current == '[') { | 403 | if (ls->current == '[') { /* long comment? */ |
| 373 | int sep = skip_sep(ls); | 404 | int sep = skip_sep(ls); |
| 374 | luaZ_resetbuffer(ls->buff); /* `skip_sep' may dirty the buffer */ | 405 | luaZ_resetbuffer(ls->buff); /* `skip_sep' may dirty the buffer */ |
| 375 | if (sep >= 0) { | 406 | if (sep >= 0) { |
| 376 | read_long_string(ls, NULL, sep); /* long comment */ | 407 | read_long_string(ls, NULL, sep); /* skip long comment */ |
| 377 | luaZ_resetbuffer(ls->buff); | 408 | luaZ_resetbuffer(ls->buff); /* previous call may dirty the buff. */ |
| 378 | continue; | 409 | break; |
| 379 | } | 410 | } |
| 380 | } | 411 | } |
| 381 | /* else short comment */ | 412 | /* else short comment */ |
| 382 | while (!currIsNewline(ls) && ls->current != EOZ) | 413 | while (!currIsNewline(ls) && ls->current != EOZ) |
| 383 | next(ls); | 414 | next(ls); /* skip until end of line (or end of file) */ |
| 384 | continue; | 415 | break; |
| 385 | } | 416 | } |
| 386 | case '[': { | 417 | case '[': { /* long string or simply '[' */ |
| 387 | int sep = skip_sep(ls); | 418 | int sep = skip_sep(ls); |
| 388 | if (sep >= 0) { | 419 | if (sep >= 0) { |
| 389 | read_long_string(ls, seminfo, sep); | 420 | read_long_string(ls, seminfo, sep); |
| @@ -412,39 +443,30 @@ static int llex (LexState *ls, SemInfo *seminfo) { · 22 unmodified lines | |||
| 412 | if (ls->current != '=') return '~'; | 443 | if (ls->current != '=') return '~'; |
| 413 | else { next(ls); return TK_NE; } | 444 | else { next(ls); return TK_NE; } |
| 414 | } | 445 | } |
| 415 | case '"': | 446 | case '"': case '\'': { /* short literal strings */ |
| 416 | case '\'': { | ||
| 417 | read_string(ls, ls->current, seminfo); | 447 | read_string(ls, ls->current, seminfo); |
| 418 | return TK_STRING; | 448 | return TK_STRING; |
| 419 | } | 449 | } |
| 420 | case '.': { | 450 | case '.': { /* '.', '..', '...', or number */ |
| 421 | save_and_next(ls); | 451 | save_and_next(ls); |
| 422 | if (check_next(ls, ".")) { | 452 | if (check_next(ls, ".")) { |
| 423 | if (check_next(ls, ".")) | 453 | if (check_next(ls, ".")) |
| 424 | return TK_DOTS; /* ... */ | 454 | return TK_DOTS; /* '...' */ |
| 425 | else return TK_CONCAT; /* .. */ | 455 | else return TK_CONCAT; /* '..' */ |
| 426 | } | 456 | } |
| 427 | else if (!lisdigit(ls->current)) return '.'; | 457 | else if (!lisdigit(ls->current)) return '.'; |
| 428 | else { | 458 | /* else go through */ |
| 429 | read_numeral(ls, seminfo); | 459 | } |
| 430 | return TK_NUMBER; | 460 | case '0': case '1': case '2': case '3': case '4': |
| 431 | } | 461 | case '5': case '6': case '7': case '8': case '9': { |
| 462 | read_numeral(ls, seminfo); | ||
| 463 | return TK_NUMBER; | ||
| 432 | } | 464 | } |
| 433 | case EOZ: { | 465 | case EOZ: { |
| 434 | return TK_EOS; | 466 | return TK_EOS; |
| 435 | } | 467 | } |
| 436 | default: { | 468 | default: { |
| 437 | if (lisspace(ls->current)) { | 469 | if (lislalpha(ls->current)) { /* identifier or reserved word? */ |
| 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 */ | ||
| 448 | TString *ts; | 470 | TString *ts; |
| 449 | do { | 471 | do { |
| 450 | save_and_next(ls); | 472 | save_and_next(ls); |
| @@ -458,10 +480,10 @@ static int llex (LexState *ls, SemInfo *seminfo) { · 7 unmodified lines | |||
| 458 | return TK_NAME; | 480 | return TK_NAME; |
| 459 | } | 481 | } |
| 460 | } | 482 | } |
| 461 | else { | 483 | else { /* single-char tokens (+ - / ...) */ |
| 462 | int c = ls->current; | 484 | int c = ls->current; |
| 463 | next(ls); | 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 | ** Lexical Analyzer | 3 | ** Lexical Analyzer |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -60,6 +60,7 @@ typedef struct LexState { · 54 unmodified lines | |||
| 60 | Mbuffer *buff; /* buffer for tokens */ | 60 | Mbuffer *buff; /* buffer for tokens */ |
| 61 | struct Varlist *varl; /* list of all active local variables */ | 61 | struct Varlist *varl; /* list of all active local variables */ |
| 62 | TString *source; /* current source name */ | 62 | TString *source; /* current source name */ |
| 63 | TString *envn; /* environment variable name */ | ||
| 63 | char decpoint; /* locale decimal point */ | 64 | char decpoint; /* locale decimal point */ |
| 64 | } LexState; | 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 | ** Limits, basic types, and some other `installation-dependent' definitions | 3 | ** Limits, basic types, and some other `installation-dependent' definitions |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -30,6 +30,7 @@ typedef unsigned char lu_byte; · 24 unmodified lines | |||
| 30 | #define MAX_SIZET ((size_t)(~(size_t)0)-2) | 30 | #define MAX_SIZET ((size_t)(~(size_t)0)-2) |
| 31 | 31 | ||
| 32 | #define MAX_LUMEM ((lu_mem)(~(lu_mem)0)-2) | 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 | #define MAX_INT (INT_MAX-2) /* maximum value of an int (-2 for safety) */ | 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 | #if defined(lua_assert) | 60 | #if defined(lua_assert) |
| 60 | #define check_exp(c,e) (lua_assert(c), (e)) | 61 | #define check_exp(c,e) (lua_assert(c), (e)) |
| 61 | #else | 62 | #else |
| 62 | #define lua_assert(c) ((void)0) | 63 | #define lua_assert(c) /* empty */ |
| 63 | #define check_exp(c,e) (e) | 64 | #define check_exp(c,e) (e) |
| 64 | #endif | 65 | #endif |
| 65 | 66 | ||
| @@ -139,19 +140,19 @@ typedef lu_int32 Instruction; · 73 unmodified lines | |||
| 139 | ** created/deleted/resumed/yielded. | 140 | ** created/deleted/resumed/yielded. |
| 140 | */ | 141 | */ |
| 141 | #if !defined(luai_userstateopen) | 142 | #if !defined(luai_userstateopen) |
| 142 | #define luai_userstateopen(L) ((void)L) | 143 | #define luai_userstateopen(L) ((void)L) |
| 143 | #endif | 144 | #endif |
| 144 | 145 | ||
| 145 | #if !defined(luai_userstateclose) | 146 | #if !defined(luai_userstateclose) |
| 146 | #define luai_userstateclose(L) ((void)L) | 147 | #define luai_userstateclose(L) ((void)L) |
| 147 | #endif | 148 | #endif |
| 148 | 149 | ||
| 149 | #if !defined(luai_userstatethread) | 150 | #if !defined(luai_userstatethread) |
| 150 | #define luai_userstatethread(L,L1) ((void)L) | 151 | #define luai_userstatethread(L,L1) ((void)L) |
| 151 | #endif | 152 | #endif |
| 152 | 153 | ||
| 153 | #if !defined(luai_userstatefree) | 154 | #if !defined(luai_userstatefree) |
| 154 | #define luai_userstatefree(L) ((void)L) | 155 | #define luai_userstatefree(L,L1) ((void)L) |
| 155 | #endif | 156 | #endif |
| 156 | 157 | ||
| 157 | #if !defined(luai_userstateresume) | 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 | ** Interface to Memory Manager | 3 | ** Interface to Memory Manager |
| 4 | ** See Copyright Notice in lua.h | 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 | size_t realosize = (block) ? osize : 0; | 79 | size_t realosize = (block) ? osize : 0; |
| 80 | lua_assert((realosize == 0) == (block == NULL)); | 80 | lua_assert((realosize == 0) == (block == NULL)); |
| 81 | #if defined(HARDMEMTESTS) | 81 | #if defined(HARDMEMTESTS) |
| 82 | if (nsize > realosize && g->GCthreshold != MAX_LUMEM) | 82 | if (nsize > realosize && !gcstopped(g)) |
| 83 | luaC_fullgc(L, 1); /* force a GC whenever possible */ | 83 | luaC_fullgc(L, 1); /* force a GC whenever possible */ |
| 84 | #endif | 84 | #endif |
| 85 | newblock = (*g->frealloc)(g->ud, block, osize, nsize); | 85 | newblock = (*g->frealloc)(g->ud, block, osize, nsize); |
| 86 | if (newblock == NULL && nsize > 0) { | 86 | if (newblock == NULL && nsize > 0) { |
| 87 | lua_assert(nsize > realosize); /* cannot fail when shrinking a block */ | 87 | api_check(L, nsize > realosize, |
| 88 | if (g->GCthreshold != MAX_LUMEM) { | 88 | "realloc cannot fail when shrinking a block"); |
| 89 | if (!gcstopped(g)) { | ||
| 89 | luaC_fullgc(L, 1); /* try to free some memory... */ | 90 | luaC_fullgc(L, 1); /* try to free some memory... */ |
| 90 | newblock = (*g->frealloc)(g->ud, block, osize, nsize); /* try again */ | 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 | lua_assert((nsize == 0) == (newblock == NULL)); | 96 | lua_assert((nsize == 0) == (newblock == NULL)); |
| 96 | g->totalbytes = (g->totalbytes - realosize) + nsize; | 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 | return newblock; | 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 | ** Interface to Memory Manager | 3 | ** Interface to Memory Manager |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -13,8 +13,6 @@ · 7 unmodified lines | |||
| 13 | #include "llimits.h" | 13 | #include "llimits.h" |
| 14 | #include "lua.h" | 14 | #include "lua.h" |
| 15 | 15 | ||
| 16 | #define MEMERRMSG "not enough memory" | ||
| 17 | |||
| 18 | 16 | ||
| 19 | #define luaM_reallocv(L,b,on,n,e) \ | 17 | #define luaM_reallocv(L,b,on,n,e) \ |
| 20 | ((cast(size_t, (n)+1) <= MAX_SIZET/(e)) ? /* +1 to avoid warnings */ \ | 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 | ** Dynamic library loader for Lua | 3 | ** Dynamic library loader for Lua |
| 4 | ** See Copyright Notice in lua.h | 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 | lua_CFunction f = ll_sym(L, *reg, sym); | 353 | lua_CFunction f = ll_sym(L, *reg, sym); |
| 354 | if (f == NULL) | 354 | if (f == NULL) |
| 355 | return ERRFUNC; /* unable to find function */ | 355 | return ERRFUNC; /* unable to find function */ |
| 356 | lua_pushcfunction(L, f); /* else create new 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 */ | ||
| 359 | return 0; /* no errors */ | 357 | return 0; /* no errors */ |
| 360 | } | 358 | } |
| 361 | } | 359 | } |
| @@ -435,7 +433,7 @@ static int ll_searchpath (lua_State *L) { · 73 unmodified lines | |||
| 435 | static const char *findfile (lua_State *L, const char *name, | 433 | static const char *findfile (lua_State *L, const char *name, |
| 436 | const char *pname) { | 434 | const char *pname) { |
| 437 | const char *path; | 435 | const char *path; |
| 438 | lua_getfield(L, LUA_ENVIRONINDEX, pname); | 436 | lua_getfield(L, lua_upvalueindex(1), pname); |
| 439 | path = lua_tostring(L, -1); | 437 | path = lua_tostring(L, -1); |
| 440 | if (path == NULL) | 438 | if (path == NULL) |
| 441 | luaL_error(L, LUA_QL("package.%s") " must be a string", pname); | 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 | static int loader_preload (lua_State *L) { | 508 | static int loader_preload (lua_State *L) { |
| 511 | const char *name = luaL_checkstring(L, 1); | 509 | const char *name = luaL_checkstring(L, 1); |
| 512 | lua_getfield(L, LUA_ENVIRONINDEX, "preload"); | 510 | lua_getfield(L, lua_upvalueindex(1), "preload"); |
| 513 | if (!lua_istable(L, -1)) | 511 | if (!lua_istable(L, -1)) |
| 514 | luaL_error(L, LUA_QL("package.preload") " must be a table"); | 512 | luaL_error(L, LUA_QL("package.preload") " must be a table"); |
| 515 | lua_getfield(L, -1, name); | 513 | lua_getfield(L, -1, name); |
| @@ -535,7 +533,7 @@ static int ll_require (lua_State *L) { · 19 unmodified lines | |||
| 535 | return 1; /* package is already loaded */ | 533 | return 1; /* package is already loaded */ |
| 536 | } | 534 | } |
| 537 | /* else must load it; iterate over available loaders */ | 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 | if (!lua_istable(L, -1)) | 537 | if (!lua_istable(L, -1)) |
| 540 | luaL_error(L, LUA_QL("package.loaders") " must be a table"); | 538 | luaL_error(L, LUA_QL("package.loaders") " must be a table"); |
| 541 | lua_pushliteral(L, ""); /* error message accumulator */ | 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 | lua_Debug ar; | 585 | lua_Debug ar; |
| 584 | if (lua_getstack(L, 1, &ar) == 0 || | 586 | if (lua_getstack(L, 1, &ar) == 0 || |
| 585 | lua_getinfo(L, "f", &ar) == 0 || /* get calling function */ | 587 | lua_getinfo(L, "f", &ar) == 0 || /* get calling function */ |
| 586 | lua_iscfunction(L, -1)) | 588 | lua_iscfunction(L, -1)) |
| 587 | luaL_error(L, LUA_QL("module") " not called from a Lua function"); | 589 | luaL_error(L, LUA_QL("module") " not called from a Lua function"); |
| 588 | lua_pushvalue(L, -2); /* copy new environment table to top */ | 590 | lua_pushvalue(L, -2); /* copy new environment table to top */ |
| 589 | lua_setfenv(L, -2); | 591 | lua_setupvalue(L, -2, 1); |
| 590 | lua_pop(L, 1); /* remove function */ | 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 | modinit(L, modname); | 641 | modinit(L, modname); |
| 640 | } | 642 | } |
| 641 | lua_pushvalue(L, -1); | 643 | lua_pushvalue(L, -1); |
| 642 | setfenv(L); | 644 | set_env(L); |
| 643 | dooptions(L, loaded - 1); | 645 | dooptions(L, loaded - 1); |
| 644 | return 1; | 646 | return 1; |
| 645 | } | 647 | } |
| @@ -709,12 +711,12 @@ LUAMOD_API int luaopen_package (lua_State *L) { · 63 unmodified lines | |||
| 709 | lua_setfield(L, -2, "__gc"); | 711 | lua_setfield(L, -2, "__gc"); |
| 710 | /* create `package' table */ | 712 | /* create `package' table */ |
| 711 | luaL_register(L, LUA_LOADLIBNAME, pk_funcs); | 713 | luaL_register(L, LUA_LOADLIBNAME, pk_funcs); |
| 712 | lua_copy(L, -1, LUA_ENVIRONINDEX); | ||
| 713 | /* create `loaders' table */ | 714 | /* create `loaders' table */ |
| 714 | lua_createtable(L, sizeof(loaders)/sizeof(loaders[0]) - 1, 0); | 715 | lua_createtable(L, sizeof(loaders)/sizeof(loaders[0]) - 1, 0); |
| 715 | /* fill it with pre-defined loaders */ | 716 | /* fill it with pre-defined loaders */ |
| 716 | for (i=0; loaders[i] != NULL; i++) { | 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 | lua_rawseti(L, -2, i+1); | 720 | lua_rawseti(L, -2, i+1); |
| 719 | } | 721 | } |
| 720 | lua_setfield(L, -2, "loaders"); /* put it in field `loaders' */ | 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 | lua_newtable(L); | 733 | lua_newtable(L); |
| 732 | lua_setfield(L, -2, "preload"); | 734 | lua_setfield(L, -2, "preload"); |
| 733 | lua_pushglobaltable(L); | 735 | lua_pushglobaltable(L); |
| 734 | luaL_register(L, NULL, ll_funcs); /* open lib into global table */ | 736 | lua_pushvalue(L, -2); /* set 'package' as upvalue for next lib */ |
| 735 | lua_pop(L, 1); | 737 | luaL_openlib(L, NULL, ll_funcs, 1); /* open lib into global table */ |
| 738 | lua_pop(L, 1); /* pop global table */ | ||
| 736 | return 1; /* return 'package' table */ | 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 | ** Some generic functions over Lua objects | 3 | ** Some generic functions over Lua objects |
| 4 | ** See Copyright Notice in lua.h | 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 | return bvalue(t1) == bvalue(t2); /* boolean true must be 1 !! */ | 81 | return bvalue(t1) == bvalue(t2); /* boolean true must be 1 !! */ |
| 82 | case LUA_TLIGHTUSERDATA: | 82 | case LUA_TLIGHTUSERDATA: |
| 83 | return pvalue(t1) == pvalue(t2); | 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 | default: | 88 | default: |
| 85 | lua_assert(iscollectable(t1)); | 89 | lua_assert(iscollectable(t1)); |
| 86 | return gcvalue(t1) == gcvalue(t2); | 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 | case LUA_OPDIV: return luai_numdiv(NULL, v1, v2); | 100 | case LUA_OPDIV: return luai_numdiv(NULL, v1, v2); |
| 97 | case LUA_OPMOD: return luai_nummod(NULL, v1, v2); | 101 | case LUA_OPMOD: return luai_nummod(NULL, v1, v2); |
| 98 | case LUA_OPPOW: return luai_numpow(NULL, v1, v2); | 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 | default: lua_assert(0); return 0; | 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 | if (endptr == s) return 0; /* conversion failed */ | 112 | if (endptr == s) return 0; /* conversion failed */ |
| 109 | if (*endptr == 'x' || *endptr == 'X') /* maybe an hexadecimal constant? */ | 113 | if (*endptr == 'x' || *endptr == 'X') /* maybe an hexadecimal constant? */ |
| 110 | *result = cast_num(strtoul(s, &endptr, 16)); | 114 | *result = cast_num(strtoul(s, &endptr, 16)); |
| 111 | if (*endptr == '\0') return 1; /* most common case */ | ||
| 112 | while (lisspace(cast(unsigned char, *endptr))) endptr++; | 115 | while (lisspace(cast(unsigned char, *endptr))) endptr++; |
| 113 | if (*endptr != '\0') return 0; /* invalid trailing characters? */ | 116 | return (*endptr == '\0'); /* OK if no trailing characters */ |
| 114 | return 1; | ||
| 115 | } | 117 | } |
| 116 | 118 | ||
| 117 | 119 | ||
| 118 | 120 | ||
| 119 | static void pushstr (lua_State *L, const char *str) { | 121 | static void pushstr (lua_State *L, const char *str, size_t l) { |
| 120 | setsvalue2s(L, L->top, luaS_new(L, str)); | 122 | setsvalue2s(L, L->top, luaS_newlstr(L, str, l)); |
| 121 | incr_top(L); | 123 | incr_top(L); |
| 122 | } | 124 | } |
| 123 | 125 | ||
| 124 | 126 | ||
| 125 | /* this function handles only `%d', `%c', %f, %p, and `%s' formats */ | 127 | /* this function handles only `%d', `%c', %f, %p, and `%s' formats */ |
| 126 | const char *luaO_pushvfstring (lua_State *L, const char *fmt, va_list argp) { | 128 | const char *luaO_pushvfstring (lua_State *L, const char *fmt, va_list argp) { |
| 127 | int n = 1; | 129 | int n = 0; |
| 128 | pushstr(L, ""); | ||
| 129 | for (;;) { | 130 | for (;;) { |
| 130 | const char *e = strchr(fmt, '%'); | 131 | const char *e = strchr(fmt, '%'); |
| 131 | if (e == NULL) break; | 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 | case 's': { | 136 | case 's': { |
| 136 | const char *s = va_arg(argp, char *); | 137 | const char *s = va_arg(argp, char *); |
| 137 | if (s == NULL) s = "(null)"; | 138 | if (s == NULL) s = "(null)"; |
| 138 | pushstr(L, s); | 139 | pushstr(L, s, strlen(s)); |
| 139 | break; | 140 | break; |
| 140 | } | 141 | } |
| 141 | case 'c': { | 142 | case 'c': { |
| 142 | char buff[2]; | 143 | char buff; |
| 143 | buff[0] = cast(char, va_arg(argp, int)); | 144 | buff = cast(char, va_arg(argp, int)); |
| 144 | buff[1] = '\0'; | 145 | pushstr(L, &buff, 1); |
| 145 | pushstr(L, buff); | ||
| 146 | break; | 146 | break; |
| 147 | } | 147 | } |
| 148 | case 'd': { | 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 | case 'p': { | 158 | case 'p': { |
| 159 | char buff[4*sizeof(void *) + 8]; /* should be enough space for a `%p' */ | 159 | char buff[4*sizeof(void *) + 8]; /* should be enough space for a `%p' */ |
| 160 | sprintf(buff, "%p", va_arg(argp, void *)); | 160 | int l = sprintf(buff, "%p", va_arg(argp, void *)); |
| 161 | pushstr(L, buff); | 161 | pushstr(L, buff, l); |
| 162 | break; | 162 | break; |
| 163 | } | 163 | } |
| 164 | case '%': { | 164 | case '%': { |
| 165 | pushstr(L, "%"); | 165 | pushstr(L, "%", 1); |
| 166 | break; | 166 | break; |
| 167 | } | 167 | } |
| 168 | default: { | 168 | default: { |
| @@ -175,8 +175,8 @@ const char *luaO_pushvfstring (lua_State *L, const char *fmt, va_list argp) { · 6 unmodified lines | |||
| 175 | n += 2; | 175 | n += 2; |
| 176 | fmt = e+2; | 176 | fmt = e+2; |
| 177 | } | 177 | } |
| 178 | pushstr(L, fmt); | 178 | pushstr(L, fmt, strlen(fmt)); |
| 179 | luaV_concat(L, n+1); | 179 | if (n > 0) luaV_concat(L, n + 1); |
| 180 | return svalue(L->top - 1); | 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 | ** Type definitions for Lua objects | 3 | ** Type definitions for Lua objects |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -16,20 +16,20 @@ · 10 unmodified lines | |||
| 16 | #include "lua.h" | 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 | ** Extra tags for non-values | 20 | ** Extra tags for non-values |
| 27 | */ | 21 | */ |
| 28 | #define LUA_TPROTO (LAST_TAG+1) | 22 | #define LUA_TPROTO LUA_NUMTAGS |
| 29 | #define LUA_TUPVAL (LAST_TAG+2) | 23 | #define LUA_TUPVAL (LUA_NUMTAGS+1) |
| 30 | #define LUA_TDEADKEY (LAST_TAG+3) | 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 | ** Union of all collectable objects | 34 | ** Union of all collectable objects |
| 35 | */ | 35 | */ |
| @@ -60,6 +60,7 @@ typedef union { · 24 unmodified lines | |||
| 60 | void *p; | 60 | void *p; |
| 61 | lua_Number n; | 61 | lua_Number n; |
| 62 | int b; | 62 | int b; |
| 63 | lua_CFunction f; | ||
| 63 | } Value; | 64 | } Value; |
| 64 | 65 | ||
| 65 | 66 | ||
| @@ -79,12 +80,26 @@ typedef struct lua_TValue { · 13 unmodified lines | |||
| 79 | #define NILCONSTANT {NULL}, LUA_TNIL | 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 | /* Macros to test type */ | 95 | /* Macros to test type */ |
| 83 | #define ttisnil(o) (ttype(o) == LUA_TNIL) | 96 | #define ttisnil(o) (ttype(o) == LUA_TNIL) |
| 84 | #define ttisnumber(o) (ttype(o) == LUA_TNUMBER) | 97 | #define ttisnumber(o) (ttype(o) == LUA_TNUMBER) |
| 85 | #define ttisstring(o) (ttype(o) == LUA_TSTRING) | 98 | #define ttisstring(o) (ttype(o) == LUA_TSTRING) |
| 86 | #define ttistable(o) (ttype(o) == LUA_TTABLE) | 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 | #define ttisboolean(o) (ttype(o) == LUA_TBOOLEAN) | 103 | #define ttisboolean(o) (ttype(o) == LUA_TBOOLEAN) |
| 89 | #define ttisuserdata(o) (ttype(o) == LUA_TUSERDATA) | 104 | #define ttisuserdata(o) (ttype(o) == LUA_TUSERDATA) |
| 90 | #define ttisthread(o) (ttype(o) == LUA_TTHREAD) | 105 | #define ttisthread(o) (ttype(o) == LUA_TTHREAD) |
| @@ -92,7 +107,6 @@ typedef struct lua_TValue { · 1 unmodified line | |||
| 92 | #define ttisdeadkey(o) (ttype(o) == LUA_TDEADKEY) | 107 | #define ttisdeadkey(o) (ttype(o) == LUA_TDEADKEY) |
| 93 | 108 | ||
| 94 | /* Macros to access values */ | 109 | /* Macros to access values */ |
| 95 | #define ttype(o) ((o)->tt_) | ||
| 96 | #define gcvalue(o) check_exp(iscollectable(o), (o)->value_.gc) | 110 | #define gcvalue(o) check_exp(iscollectable(o), (o)->value_.gc) |
| 97 | #define pvalue(o) check_exp(ttislightuserdata(o), (o)->value_.p) | 111 | #define pvalue(o) check_exp(ttislightuserdata(o), (o)->value_.p) |
| 98 | #define nvalue(o) check_exp(ttisnumber(o), (o)->value_.n) | 112 | #define nvalue(o) check_exp(ttisnumber(o), (o)->value_.n) |
| @@ -100,16 +114,15 @@ typedef struct lua_TValue { · 1 unmodified line | |||
| 100 | #define tsvalue(o) (&rawtsvalue(o)->tsv) | 114 | #define tsvalue(o) (&rawtsvalue(o)->tsv) |
| 101 | #define rawuvalue(o) check_exp(ttisuserdata(o), &(o)->value_.gc->u) | 115 | #define rawuvalue(o) check_exp(ttisuserdata(o), &(o)->value_.gc->u) |
| 102 | #define uvalue(o) (&rawuvalue(o)->uv) | 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 | #define hvalue(o) check_exp(ttistable(o), &(o)->value_.gc->h) | 119 | #define hvalue(o) check_exp(ttistable(o), &(o)->value_.gc->h) |
| 105 | #define bvalue(o) check_exp(ttisboolean(o), (o)->value_.b) | 120 | #define bvalue(o) check_exp(ttisboolean(o), (o)->value_.b) |
| 106 | #define thvalue(o) check_exp(ttisthread(o), &(o)->value_.gc->th) | 121 | #define thvalue(o) check_exp(ttisthread(o), &(o)->value_.gc->th) |
| 107 | 122 | ||
| 108 | #define l_isfalse(o) (ttisnil(o) || (ttisboolean(o) && bvalue(o) == 0)) | 123 | #define l_isfalse(o) (ttisnil(o) || (ttisboolean(o) && bvalue(o) == 0)) |
| 109 | 124 | ||
| 110 | /* | 125 | |
| 111 | ** for internal debug only | ||
| 112 | */ | ||
| 113 | #define iscollectable(o) (ttype(o) >= LUA_TSTRING) | 126 | #define iscollectable(o) (ttype(o) >= LUA_TSTRING) |
| 114 | 127 | ||
| 115 | #define righttt(obj) (ttype(obj) == gcvalue(obj)->gch.tt) | 128 | #define righttt(obj) (ttype(obj) == gcvalue(obj)->gch.tt) |
| @@ -126,8 +139,10 @@ typedef struct lua_TValue { · 10 unmodified lines | |||
| 126 | #define setnvalue(obj,x) \ | 139 | #define setnvalue(obj,x) \ |
| 127 | { TValue *i_o=(obj); i_o->value_.n=(x); i_o->tt_=LUA_TNUMBER; } | 140 | { TValue *i_o=(obj); i_o->value_.n=(x); i_o->tt_=LUA_TNUMBER; } |
| 128 | 141 | ||
| 129 | #define changenvalue(obj,x) \ | 142 | #define setfvalue(obj,x) \ |
| 130 | ( lua_assert((obj)->tt_==LUA_TNUMBER), (obj)->value_.n=(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 | #define setpvalue(obj,x) \ | 147 | #define setpvalue(obj,x) \ |
| 133 | { TValue *i_o=(obj); i_o->value_.p=(x); i_o->tt_=LUA_TLIGHTUSERDATA; } | 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 | lu_byte numparams; | 279 | lu_byte numparams; |
| 265 | lu_byte is_vararg; | 280 | lu_byte is_vararg; |
| 266 | lu_byte maxstacksize; | 281 | lu_byte maxstacksize; |
| 267 | lu_byte envreg; /* register in outer function with initial environment */ | ||
| 268 | } Proto; | 282 | } Proto; |
| 269 | 283 | ||
| 270 | 284 | ||
| @@ -298,8 +312,7 @@ typedef struct UpVal { · 27 unmodified lines | |||
| 298 | */ | 312 | */ |
| 299 | 313 | ||
| 300 | #define ClosureHeader \ | 314 | #define ClosureHeader \ |
| 301 | CommonHeader; lu_byte isC; lu_byte nupvalues; GCObject *gclist; \ | 315 | CommonHeader; lu_byte isC; lu_byte nupvalues; GCObject *gclist |
| 302 | struct Table *env | ||
| 303 | 316 | ||
| 304 | typedef struct CClosure { | 317 | typedef struct CClosure { |
| 305 | ClosureHeader; | 318 | ClosureHeader; |
| @@ -321,8 +334,7 @@ typedef union Closure { · 15 unmodified lines | |||
| 321 | } Closure; | 334 | } Closure; |
| 322 | 335 | ||
| 323 | 336 | ||
| 324 | #define iscfunction(o) (ttisfunction(o) && clvalue(o)->c.isC) | 337 | #define isLfunction(o) (ttisclosure(o) && !clvalue(o)->c.isC) |
| 325 | #define isLfunction(o) (ttisfunction(o) && !clvalue(o)->c.isC) | ||
| 326 | 338 | ||
| 327 | #define getproto(o) (clvalue(o)->l.p) | 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 | ** See Copyright Notice in lua.h | 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 | "LOADBOOL", | 19 | "LOADBOOL", |
| 20 | "LOADNIL", | 20 | "LOADNIL", |
| 21 | "GETUPVAL", | 21 | "GETUPVAL", |
| 22 | "GETGLOBAL", | 22 | "GETTABUP", |
| 23 | "GETTABLE", | 23 | "GETTABLE", |
| 24 | "SETGLOBAL", | 24 | "SETTABUP", |
| 25 | "SETUPVAL", | 25 | "SETUPVAL", |
| 26 | "SETTABLE", | 26 | "SETTABLE", |
| 27 | "NEWTABLE", | 27 | "NEWTABLE", |
| @@ -67,9 +67,9 @@ LUAI_DDEF const lu_byte luaP_opmodes[NUM_OPCODES] = { · 39 unmodified lines | |||
| 67 | ,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_LOADBOOL */ | 67 | ,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_LOADBOOL */ |
| 68 | ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_LOADNIL */ | 68 | ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_LOADNIL */ |
| 69 | ,opmode(0, 1, OpArgU, OpArgN, iABC) /* OP_GETUPVAL */ | 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 | ,opmode(0, 1, OpArgR, OpArgK, iABC) /* OP_GETTABLE */ | 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 | ,opmode(0, 0, OpArgU, OpArgN, iABC) /* OP_SETUPVAL */ | 73 | ,opmode(0, 0, OpArgU, OpArgN, iABC) /* OP_SETUPVAL */ |
| 74 | ,opmode(0, 0, OpArgK, OpArgK, iABC) /* OP_SETTABLE */ | 74 | ,opmode(0, 0, OpArgK, OpArgK, iABC) /* OP_SETTABLE */ |
| 75 | ,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_NEWTABLE */ | 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 | ** Opcodes for Lua virtual machine | 3 | ** Opcodes for Lua virtual machine |
| 4 | ** See Copyright Notice in lua.h | 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 | OP_LOADNIL,/* A B R(A) := ... := R(B) := nil */ | 171 | OP_LOADNIL,/* A B R(A) := ... := R(B) := nil */ |
| 172 | OP_GETUPVAL,/* A B R(A) := UpValue[B] */ | 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 | OP_GETTABLE,/* A B C R(A) := R(B)[RK(C)] */ | 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 | OP_SETUPVAL,/* A B UpValue[B] := R(A) */ | 178 | OP_SETUPVAL,/* A B UpValue[B] := R(A) */ |
| 179 | OP_SETTABLE,/* A B C R(A)[RK(B)] := RK(C) */ | 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 | (*) In OP_SETLIST, if (B == 0) then B = `top'; if (C == 0) then next | 243 | (*) In OP_SETLIST, if (B == 0) then B = `top'; if (C == 0) then next |
| 244 | 'instruction' is EXTRAARG(real C). | 244 | 'instruction' is EXTRAARG(real C). |
| 245 | 245 | ||
| 246 | (*) In OP_LOADK, OP_GETGLOBAL, and OP_SETGLOBAL, if (Bx == 0) then next | 246 | (*) In OP_LOADK, if (Bx == 0) then next 'instruction' is EXTRAARG(real Bx). |
| 247 | 'instruction' is EXTRAARG(real Bx). | ||
| 248 | 247 | ||
| 249 | (*) For comparisons, A specifies what condition the test should accept | 248 | (*) For comparisons, A specifies what condition the test should accept |
| 250 | (true or false). | 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 | ** Lua Parser | 3 | ** Lua Parser |
| 4 | ** See Copyright Notice in lua.h | 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 | static void errorlimit (FuncState *fs, int limit, const char *what) { | 75 | static void errorlimit (FuncState *fs, int limit, const char *what) { |
| 76 | const char *msg; | 76 | const char *msg; |
| 77 | const char *where = (fs->f->linedefined == 0) ? | 77 | int line = fs->f->linedefined; |
| 78 | "main function" : | 78 | const char *where = (line == 0) |
| 79 | luaO_pushfstring(fs->L, "function at line %d", fs->f->linedefined); | 79 | ? "main function" |
| 80 | : luaO_pushfstring(fs->L, "function at line %d", line); | ||
| 80 | msg = luaO_pushfstring(fs->L, "too many %s (limit is %d) in %s", | 81 | msg = luaO_pushfstring(fs->L, "too many %s (limit is %d) in %s", |
| 81 | what, limit, where); | 82 | what, limit, where); |
| 82 | luaX_syntaxerror(fs->ls, msg); | 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 | int i; | 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 | Proto *f = fs->f; | 222 | Proto *f = fs->f; |
| 213 | int oldsize = f->sizeupvalues; | 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 | checklimit(fs, fs->nups + 1, UCHAR_MAX, "upvalues"); | 224 | checklimit(fs, fs->nups + 1, UCHAR_MAX, "upvalues"); |
| 224 | luaM_growvector(fs->L, f->upvalues, fs->nups, f->sizeupvalues, | 225 | luaM_growvector(fs->L, f->upvalues, fs->nups, f->sizeupvalues, |
| 225 | Upvaldesc, UCHAR_MAX, "upvalues"); | 226 | Upvaldesc, UCHAR_MAX, "upvalues"); |
| 226 | while (oldsize < f->sizeupvalues) f->upvalues[oldsize++].name = NULL; | 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 | f->upvalues[fs->nups].name = name; | 230 | f->upvalues[fs->nups].name = name; |
| 228 | luaC_objbarrier(fs->L, f, name); | 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 | return fs->nups++; | 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 | static int searchvar (FuncState *fs, TString *n) { | 236 | static int searchvar (FuncState *fs, TString *n) { |
| 236 | int i; | 237 | int i; |
| 237 | for (i=fs->nactvar-1; i >= 0; i--) { | 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 | return i; | 240 | return i; |
| 240 | } | 241 | } |
| 241 | return -1; /* not found */ | 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 | static void markupval (FuncState *fs, int level) { | 250 | static void markupval (FuncState *fs, int level) { |
| 246 | BlockCnt *bl = fs->bl; | 251 | BlockCnt *bl = fs->bl; |
| 247 | while (bl && bl->nactvar > level) bl = bl->previous; | 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 | static int singlevaraux (FuncState *fs, TString *n, expdesc *var, int base) { | 261 | static int singlevaraux (FuncState *fs, TString *n, expdesc *var, int base) { |
| 253 | if (fs == NULL) /* no more levels? */ | 262 | if (fs == NULL) /* no more levels? */ |
| 254 | return VGLOBAL; /* default is global variable */ | 263 | return VVOID; /* default is global */ |
| 255 | else { | 264 | else { |
| 256 | int v = searchvar(fs, n); /* look up at current level */ | 265 | int v = searchvar(fs, n); /* look up locals at current level */ |
| 257 | if (v >= 0) { | 266 | if (v >= 0) { /* found? */ |
| 258 | init_exp(var, VLOCAL, v); | 267 | init_exp(var, VLOCAL, v); /* variable is local */ |
| 259 | if (!base) | 268 | if (!base) |
| 260 | markupval(fs, v); /* local will be used as an upval */ | 269 | markupval(fs, v); /* local will be used as an upval */ |
| 261 | return VLOCAL; | 270 | return VLOCAL; |
| 262 | } | 271 | } |
| 263 | else { /* not found at current level; try upper one */ | 272 | else { /* not found as local at current level; try upvalues */ |
| 264 | if (singlevaraux(fs->prev, n, var, 0) == VGLOBAL) | 273 | int idx = searchupvalue(fs, n); /* try existing upvalues */ |
| 265 | return VGLOBAL; | 274 | if (idx < 0) { /* not found? */ |
| 266 | var->u.s.info = indexupvalue(fs, n, var); /* else was LOCAL or UPVAL */ | 275 | if (singlevaraux(fs->prev, n, var, 0) == VVOID) /* try upper levels */ |
| 267 | var->k = VUPVAL; /* upvalue in this level */ | 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 | return VUPVAL; | 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 | static void singlevar (LexState *ls, expdesc *var) { | 287 | static void singlevar (LexState *ls, expdesc *var) { |
| 275 | TString *varname = str_checkname(ls); | 288 | TString *varname = str_checkname(ls); |
| 276 | FuncState *fs = ls->fs; | 289 | FuncState *fs = ls->fs; |
| 277 | if (singlevaraux(fs, varname, var, 1) == VGLOBAL) { | 290 | if (singlevaraux(fs, varname, var, 1) == VVOID) { /* global name? */ |
| 278 | if (fs->envreg == NO_REG) /* regular global? */ | 291 | expdesc key; |
| 279 | init_exp(var, VGLOBAL, luaK_stringK(fs, varname)); | 292 | singlevaraux(fs, ls->envn, var, 1); /* get _ENV variable */ |
| 280 | else { /* "globals" are in current lexical environment */ | 293 | lua_assert(var->k == VLOCAL || var->k == VUPVAL); |
| 281 | expdesc key; | 294 | codestring(ls, &key, varname); /* key is variable name */ |
| 282 | init_exp(var, VLOCAL, fs->envreg); /* current environment */ | 295 | luaK_indexed(fs, var, &key); /* env[varname] */ |
| 283 | codestring(ls, &key, varname); /* key is variable name */ | ||
| 284 | luaK_indexed(fs, var, &key); /* env[varname] */ | ||
| 285 | } | ||
| 286 | } | 296 | } |
| 287 | } | 297 | } |
| 288 | 298 | ||
| @@ -351,7 +361,6 @@ static void pushclosure (LexState *ls, Proto *clp, expdesc *v) { · 62 unmodified lines | |||
| 351 | while (oldsize < f->sizep) f->p[oldsize++] = NULL; | 361 | while (oldsize < f->sizep) f->p[oldsize++] = NULL; |
| 352 | f->p[fs->np++] = clp; | 362 | f->p[fs->np++] = clp; |
| 353 | /* initial environment for new function is current lexical environment */ | 363 | /* initial environment for new function is current lexical environment */ |
| 354 | clp->envreg = fs->envreg; | ||
| 355 | luaC_objbarrier(ls->L, f, clp); | 364 | luaC_objbarrier(ls->L, f, clp); |
| 356 | init_exp(v, VRELOCABLE, luaK_codeABx(fs, OP_CLOSURE, 0, fs->np-1)); | 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 | fs->nlocvars = 0; | 383 | fs->nlocvars = 0; |
| 375 | fs->nactvar = 0; | 384 | fs->nactvar = 0; |
| 376 | fs->firstlocal = ls->varl->nactvar; | 385 | fs->firstlocal = ls->varl->nactvar; |
| 377 | fs->envreg = NO_REG; | ||
| 378 | fs->bl = NULL; | 386 | fs->bl = NULL; |
| 379 | f = luaF_newproto(L); | 387 | f = luaF_newproto(L); |
| 380 | fs->f = f; | 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 | Proto *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff, Varlist *varl, | 442 | Proto *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff, Varlist *varl, |
| 422 | const char *name) { | 443 | const char *name) { |
| 423 | struct LexState lexstate; | 444 | LexState lexstate; |
| 424 | struct FuncState funcstate; | 445 | FuncState funcstate; |
| 425 | TString *tname = luaS_new(L, name); | 446 | TString *tname = luaS_new(L, name); |
| 426 | setsvalue2s(L, L->top, tname); /* push name to protect it */ | 447 | setsvalue2s(L, L->top, tname); /* push name to protect it */ |
| 427 | incr_top(L); | 448 | incr_top(L); |
| 428 | lexstate.buff = buff; | 449 | lexstate.buff = buff; |
| 429 | lexstate.varl = varl; | 450 | lexstate.varl = varl; |
| 430 | luaX_setinput(L, &lexstate, z, tname); | 451 | luaX_setinput(L, &lexstate, z, tname); |
| 431 | open_func(&lexstate, &funcstate); | 452 | open_mainfunc(&lexstate, &funcstate); |
| 432 | funcstate.f->is_vararg = 1; /* main function is always vararg */ | ||
| 433 | luaX_next(&lexstate); /* read first token */ | 453 | luaX_next(&lexstate); /* read first token */ |
| 434 | chunk(&lexstate); | 454 | chunk(&lexstate); /* read main chunk */ |
| 435 | check(&lexstate, TK_EOS); | 455 | check(&lexstate, TK_EOS); |
| 436 | close_func(&lexstate); | 456 | close_func(&lexstate); |
| 437 | L->top--; /* pop name */ | 457 | L->top--; /* pop name */ |
| 438 | lua_assert(funcstate.prev == NULL); | 458 | lua_assert(!funcstate.prev && funcstate.nups == 1 && !lexstate.fs); |
| 439 | lua_assert(funcstate.nups == 0); | ||
| 440 | lua_assert(lexstate.fs == NULL); | ||
| 441 | return funcstate.f; | 459 | return funcstate.f; |
| 442 | } | 460 | } |
| 443 | 461 | ||
| @@ -452,7 +470,7 @@ static void fieldsel (LexState *ls, expdesc *v) { · 8 unmodified lines | |||
| 452 | /* fieldsel -> ['.' | ':'] NAME */ | 470 | /* fieldsel -> ['.' | ':'] NAME */ |
| 453 | FuncState *fs = ls->fs; | 471 | FuncState *fs = ls->fs; |
| 454 | expdesc key; | 472 | expdesc key; |
| 455 | luaK_exp2anyreg(fs, v); | 473 | luaK_exp2anyregup(fs, v); |
| 456 | luaX_next(ls); /* skip the dot or colon */ | 474 | luaX_next(ls); /* skip the dot or colon */ |
| 457 | checkname(ls, &key); | 475 | checkname(ls, &key); |
| 458 | luaK_indexed(fs, v, &key); | 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 | FuncState *fs = ls->fs; | 675 | FuncState *fs = ls->fs; |
| 658 | expdesc args; | 676 | expdesc args; |
| 659 | int base, nparams; | 677 | int base, nparams; |
| 660 | int line = ls->linenumber; | ||
| 661 | switch (ls->t.token) { | 678 | switch (ls->t.token) { |
| 662 | case '(': { /* funcargs -> `(' [ explist1 ] `)' */ | 679 | case '(': { /* funcargs -> `(' [ explist1 ] `)' */ |
| 663 | if (line != ls->lastline) | ||
| 664 | luaX_syntaxerror(ls,"ambiguous syntax (function call x new statement)"); | ||
| 665 | luaX_next(ls); | 680 | luaX_next(ls); |
| 666 | if (ls->t.token == ')') /* arg list is empty? */ | 681 | if (ls->t.token == ')') /* arg list is empty? */ |
| 667 | args.k = VVOID; | 682 | args.k = VVOID; |
| @@ -738,6 +753,7 @@ static void primaryexp (LexState *ls, expdesc *v) { · 70 unmodified lines | |||
| 738 | /* primaryexp -> | 753 | /* primaryexp -> |
| 739 | prefixexp { `.' NAME | `[' exp `]' | `:' NAME funcargs | funcargs } */ | 754 | prefixexp { `.' NAME | `[' exp `]' | `:' NAME funcargs | funcargs } */ |
| 740 | FuncState *fs = ls->fs; | 755 | FuncState *fs = ls->fs; |
| 756 | int line = ls->linenumber; | ||
| 741 | prefixexp(ls, v); | 757 | prefixexp(ls, v); |
| 742 | for (;;) { | 758 | for (;;) { |
| 743 | switch (ls->t.token) { | 759 | switch (ls->t.token) { |
| @@ -747,7 +763,7 @@ static void primaryexp (LexState *ls, expdesc *v) { · 3 unmodified lines | |||
| 747 | } | 763 | } |
| 748 | case '[': { /* `[' exp1 `]' */ | 764 | case '[': { /* `[' exp1 `]' */ |
| 749 | expdesc key; | 765 | expdesc key; |
| 750 | luaK_exp2anyreg(fs, v); | 766 | luaK_exp2anyregup(fs, v); |
| 751 | yindex(ls, &key); | 767 | yindex(ls, &key); |
| 752 | luaK_indexed(fs, v, &key); | 768 | luaK_indexed(fs, v, &key); |
| 753 | break; | 769 | break; |
| @@ -757,12 +773,12 @@ static void primaryexp (LexState *ls, expdesc *v) { · 3 unmodified lines | |||
| 757 | luaX_next(ls); | 773 | luaX_next(ls); |
| 758 | checkname(ls, &key); | 774 | checkname(ls, &key); |
| 759 | luaK_self(fs, v, &key); | 775 | luaK_self(fs, v, &key); |
| 760 | funcargs(ls, v); | 776 | funcargs(ls, v, line); |
| 761 | break; | 777 | break; |
| 762 | } | 778 | } |
| 763 | case '(': case TK_STRING: case '{': { /* funcargs */ | 779 | case '(': case TK_STRING: case '{': { /* funcargs */ |
| 764 | luaK_exp2nextreg(fs, v); | 780 | luaK_exp2nextreg(fs, v); |
| 765 | funcargs(ls, v); | 781 | funcargs(ls, v, line); |
| 766 | break; | 782 | break; |
| 767 | } | 783 | } |
| 768 | default: return; | 784 | default: return; |
| @@ -877,9 +893,10 @@ static BinOpr subexpr (LexState *ls, expdesc *v, unsigned int limit) { · 108 unmodified lines | |||
| 877 | enterlevel(ls); | 893 | enterlevel(ls); |
| 878 | uop = getunopr(ls->t.token); | 894 | uop = getunopr(ls->t.token); |
| 879 | if (uop != OPR_NOUNOPR) { | 895 | if (uop != OPR_NOUNOPR) { |
| 896 | int line = ls->linenumber; | ||
| 880 | luaX_next(ls); | 897 | luaX_next(ls); |
| 881 | subexpr(ls, v, UNARY_PRIORITY); | 898 | subexpr(ls, v, UNARY_PRIORITY); |
| 882 | luaK_prefix(ls->fs, uop, v); | 899 | luaK_prefix(ls->fs, uop, v, line); |
| 883 | } | 900 | } |
| 884 | else simpleexp(ls, v); | 901 | else simpleexp(ls, v); |
| 885 | /* expand while operators have priorities higher than `limit' */ | 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 | while (op != OPR_NOBINOPR && priority[op].left > limit) { | 904 | while (op != OPR_NOBINOPR && priority[op].left > limit) { |
| 888 | expdesc v2; | 905 | expdesc v2; |
| 889 | BinOpr nextop; | 906 | BinOpr nextop; |
| 907 | int line = ls->linenumber; | ||
| 890 | luaX_next(ls); | 908 | luaX_next(ls); |
| 891 | luaK_infix(ls->fs, op, v); | 909 | luaK_infix(ls->fs, op, v); |
| 892 | /* read sub-expression with higher priority */ | 910 | /* read sub-expression with higher priority */ |
| 893 | nextop = subexpr(ls, &v2, priority[op].right); | 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 | op = nextop; | 913 | op = nextop; |
| 896 | } | 914 | } |
| 897 | leavelevel(ls); | 915 | leavelevel(ls); |
| @@ -951,24 +969,27 @@ struct LHS_assign { · 53 unmodified lines | |||
| 951 | ** local value in a safe place and use this safe copy in the previous | 969 | ** local value in a safe place and use this safe copy in the previous |
| 952 | ** assignment. | 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 | FuncState *fs = ls->fs; | 974 | FuncState *fs = ls->fs; |
| 956 | int extra = fs->freereg; /* eventual position to save local variable */ | 975 | int extra = fs->freereg; /* eventual position to save local variable */ |
| 957 | int conflict = 0; | 976 | int conflict = 0; |
| 958 | for (; lh; lh = lh->prev) { | 977 | for (; lh; lh = lh->prev) { |
| 959 | if (lh->v.k == VINDEXED) { | 978 | if (lh->v.k == ix) { |
| 960 | if (lh->v.u.s.info == v->u.s.info) { /* conflict? */ | 979 | if (lh->v.u.s.info == v->u.s.info) { /* conflict? */ |
| 961 | conflict = 1; | 980 | conflict = 1; |
| 981 | lh->v.k = VINDEXED; | ||
| 962 | lh->v.u.s.info = extra; /* previous assignment will use safe copy */ | 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 | conflict = 1; | 985 | conflict = 1; |
| 986 | lua_assert(lh->v.k == VINDEXED); | ||
| 966 | lh->v.u.s.aux = extra; /* previous assignment will use safe copy */ | 987 | lh->v.u.s.aux = extra; /* previous assignment will use safe copy */ |
| 967 | } | 988 | } |
| 968 | } | 989 | } |
| 969 | } | 990 | } |
| 970 | if (conflict) { | 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 | luaK_reserveregs(fs, 1); | 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 | static void assignment (LexState *ls, struct LHS_assign *lh, int nvars) { | 998 | static void assignment (LexState *ls, struct LHS_assign *lh, int nvars) { |
| 978 | expdesc e; | 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 | "syntax error"); | 1001 | "syntax error"); |
| 981 | if (testnext(ls, ',')) { /* assignment -> `,' primaryexp assignment */ | 1002 | if (testnext(ls, ',')) { /* assignment -> `,' primaryexp assignment */ |
| 982 | struct LHS_assign nv; | 1003 | struct LHS_assign nv; |
| 983 | nv.prev = lh; | 1004 | nv.prev = lh; |
| 984 | primaryexp(ls, &nv.v); | 1005 | primaryexp(ls, &nv.v); |
| 985 | if (nv.v.k == VLOCAL) | 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 | checklimit(ls->fs, nvars, LUAI_MAXCCALLS - G(ls->L)->nCcalls, | 1010 | checklimit(ls->fs, nvars, LUAI_MAXCCALLS - G(ls->L)->nCcalls, |
| 988 | "variable names"); | 1011 | "variable names"); |
| 989 | assignment(ls, &nv, nvars+1); | 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 | static void exprstat (LexState *ls) { | 1300 | static void exprstat (LexState *ls) { |
| 1296 | /* stat -> func | assignment */ | 1301 | /* stat -> func | assignment */ |
| 1297 | FuncState *fs = ls->fs; | 1302 | FuncState *fs = ls->fs; |
| @@ -1311,7 +1316,6 @@ static void retstat (LexState *ls) { · 13 unmodified lines | |||
| 1311 | FuncState *fs = ls->fs; | 1316 | FuncState *fs = ls->fs; |
| 1312 | expdesc e; | 1317 | expdesc e; |
| 1313 | int first, nret; /* registers with returned values */ | 1318 | int first, nret; /* registers with returned values */ |
| 1314 | luaX_next(ls); /* skip RETURN */ | ||
| 1315 | if (block_follow(ls->t.token) || ls->t.token == ';') | 1319 | if (block_follow(ls->t.token) || ls->t.token == ';') |
| 1316 | first = nret = 0; /* return no values */ | 1320 | first = nret = 0; /* return no values */ |
| 1317 | else { | 1321 | else { |
| @@ -1342,6 +1346,10 @@ static void retstat (LexState *ls) { · 24 unmodified lines | |||
| 1342 | static int statement (LexState *ls) { | 1346 | static int statement (LexState *ls) { |
| 1343 | int line = ls->linenumber; /* may be needed for error messages */ | 1347 | int line = ls->linenumber; /* may be needed for error messages */ |
| 1344 | switch (ls->t.token) { | 1348 | switch (ls->t.token) { |
| 1349 | case ';': { /* stat -> ';' (empty statement) */ | ||
| 1350 | luaX_next(ls); /* skip ';' */ | ||
| 1351 | return 0; | ||
| 1352 | } | ||
| 1345 | case TK_IF: { /* stat -> ifstat */ | 1353 | case TK_IF: { /* stat -> ifstat */ |
| 1346 | ifstat(ls, line); | 1354 | ifstat(ls, line); |
| 1347 | return 0; | 1355 | return 0; |
| @@ -1356,10 +1364,6 @@ static int statement (LexState *ls) { · 8 unmodified lines | |||
| 1356 | check_match(ls, TK_END, TK_DO, line); | 1364 | check_match(ls, TK_END, TK_DO, line); |
| 1357 | return 0; | 1365 | return 0; |
| 1358 | } | 1366 | } |
| 1359 | case TK_IN: { | ||
| 1360 | instat(ls, line); | ||
| 1361 | return 0; | ||
| 1362 | } | ||
| 1363 | case TK_FOR: { /* stat -> forstat */ | 1367 | case TK_FOR: { /* stat -> forstat */ |
| 1364 | forstat(ls, line); | 1368 | forstat(ls, line); |
| 1365 | return 0; | 1369 | return 0; |
| @@ -1368,8 +1372,8 @@ static int statement (LexState *ls) { · 2 unmodified lines | |||
| 1368 | repeatstat(ls, line); | 1372 | repeatstat(ls, line); |
| 1369 | return 0; | 1373 | return 0; |
| 1370 | } | 1374 | } |
| 1371 | case TK_FUNCTION: { | 1375 | case TK_FUNCTION: { /* stat -> funcstat */ |
| 1372 | funcstat(ls, line); /* stat -> funcstat */ | 1376 | funcstat(ls, line); |
| 1373 | return 0; | 1377 | return 0; |
| 1374 | } | 1378 | } |
| 1375 | case TK_LOCAL: { /* stat -> localstat */ | 1379 | case TK_LOCAL: { /* stat -> localstat */ |
| @@ -1381,6 +1385,7 @@ static int statement (LexState *ls) { · 5 unmodified lines | |||
| 1381 | return 0; | 1385 | return 0; |
| 1382 | } | 1386 | } |
| 1383 | case TK_RETURN: { /* stat -> retstat */ | 1387 | case TK_RETURN: { /* stat -> retstat */ |
| 1388 | luaX_next(ls); /* skip RETURN */ | ||
| 1384 | retstat(ls); | 1389 | retstat(ls); |
| 1385 | return 1; /* must be last statement */ | 1390 | return 1; /* must be last statement */ |
| 1386 | } | 1391 | } |
| @@ -1389,9 +1394,9 @@ static int statement (LexState *ls) { · 2 unmodified lines | |||
| 1389 | breakstat(ls); | 1394 | breakstat(ls); |
| 1390 | return 1; /* must be last statement */ | 1395 | return 1; /* must be last statement */ |
| 1391 | } | 1396 | } |
| 1392 | default: { | 1397 | default: { /* stat -> func | assignment */ |
| 1393 | exprstat(ls); | 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 | enterlevel(ls); | 1408 | enterlevel(ls); |
| 1404 | while (!islast && !block_follow(ls->t.token)) { | 1409 | while (!islast && !block_follow(ls->t.token)) { |
| 1405 | islast = statement(ls); | 1410 | islast = statement(ls); |
| 1406 | testnext(ls, ';'); | 1411 | if (islast) |
| 1412 | testnext(ls, ';'); | ||
| 1407 | lua_assert(ls->fs->f->maxstacksize >= ls->fs->freereg && | 1413 | lua_assert(ls->fs->f->maxstacksize >= ls->fs->freereg && |
| 1408 | ls->fs->freereg >= ls->fs->nactvar); | 1414 | ls->fs->freereg >= ls->fs->nactvar); |
| 1409 | ls->fs->freereg = ls->fs->nactvar; /* free registers */ | 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 | ** Lua Parser | 3 | ** Lua Parser |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -23,10 +23,10 @@ typedef enum { · 17 unmodified lines | |||
| 23 | VFALSE, | 23 | VFALSE, |
| 24 | VK, /* info = index of constant in `k' */ | 24 | VK, /* info = index of constant in `k' */ |
| 25 | VKNUM, /* nval = numerical value */ | 25 | VKNUM, /* nval = numerical value */ |
| 26 | VLOCAL, /* info = local register; aux = read only */ | 26 | VLOCAL, /* info = local register */ |
| 27 | VUPVAL, /* info = index of upvalue in 'upvalues'; aux = read only */ | 27 | VUPVAL, /* info = index of upvalue in 'upvalues' */ |
| 28 | VGLOBAL, /* info = index of table; aux = index of global name in `k' */ | 28 | VINDEXED, /* info = table R/K; aux = index R/K */ |
| 29 | VINDEXED, /* info = table register; aux = index register (or `k') */ | 29 | VINDEXEDUP, /* info = table upvalue; aux = R/K */ |
| 30 | VJMP, /* info = instruction pc */ | 30 | VJMP, /* info = instruction pc */ |
| 31 | VRELOCABLE, /* info = instruction pc */ | 31 | VRELOCABLE, /* info = instruction pc */ |
| 32 | VNONRELOC, /* info = result register */ | 32 | VNONRELOC, /* info = result register */ |
| @@ -80,7 +80,6 @@ typedef struct FuncState { · 47 unmodified lines | |||
| 80 | short nlocvars; /* number of elements in `locvars' */ | 80 | short nlocvars; /* number of elements in `locvars' */ |
| 81 | lu_byte nactvar; /* number of active local variables */ | 81 | lu_byte nactvar; /* number of active local variables */ |
| 82 | lu_byte nups; /* number of upvalues */ | 82 | lu_byte nups; /* number of upvalues */ |
| 83 | lu_byte envreg; /* register holding current lexical environment */ | ||
| 84 | } FuncState; | 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 | ** Global State | 3 | ** Global State |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -26,7 +26,7 @@ · 20 unmodified lines | |||
| 26 | 26 | ||
| 27 | 27 | ||
| 28 | #if !defined(LUAI_GCPAUSE) | 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 | #endif | 30 | #endif |
| 31 | 31 | ||
| 32 | #if !defined(LUAI_GCMUL) | 32 | #if !defined(LUAI_GCMUL) |
| @@ -34,6 +34,9 @@ · 1 unmodified line | |||
| 34 | #endif | 34 | #endif |
| 35 | 35 | ||
| 36 | 36 | ||
| 37 | #define MEMERRMSG "not enough memory" | ||
| 38 | |||
| 39 | |||
| 37 | /* | 40 | /* |
| 38 | ** thread state + extra space | 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 | static void stack_init (lua_State *L1, lua_State *L) { | 92 | static void stack_init (lua_State *L1, lua_State *L) { |
| 90 | int i; | 93 | int i; CallInfo *ci; |
| 91 | /* initialize stack array */ | 94 | /* initialize stack array */ |
| 92 | L1->stack = luaM_newvector(L, BASIC_STACK_SIZE, TValue); | 95 | L1->stack = luaM_newvector(L, BASIC_STACK_SIZE, TValue); |
| 93 | L1->stacksize = BASIC_STACK_SIZE; | 96 | L1->stacksize = BASIC_STACK_SIZE; |
| @@ -96,32 +99,22 @@ static void stack_init (lua_State *L1, lua_State *L) { · 2 unmodified lines | |||
| 96 | L1->top = L1->stack; | 99 | L1->top = L1->stack; |
| 97 | L1->stack_last = L1->stack + L1->stacksize - EXTRA_STACK; | 100 | L1->stack_last = L1->stack + L1->stacksize - EXTRA_STACK; |
| 98 | /* initialize first ci */ | 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 | setnilvalue(L1->top++); /* 'function' entry for this 'ci' */ | 106 | setnilvalue(L1->top++); /* 'function' entry for this 'ci' */ |
| 101 | L1->ci->top = L1->top + LUA_MINSTACK; | 107 | ci->top = L1->top + LUA_MINSTACK; |
| 102 | L1->ci->callstatus = 0; | 108 | L1->ci = ci; |
| 103 | } | 109 | } |
| 104 | 110 | ||
| 105 | 111 | ||
| 106 | static void freestack (lua_State *L) { | 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 | luaE_freeCI(L); | 116 | luaE_freeCI(L); |
| 109 | luaM_freearray(L, L->stack, L->stacksize); | 117 | luaM_freearray(L, L->stack, L->stacksize); /* free stack array */ |
| 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); | ||
| 125 | } | 118 | } |
| 126 | 119 | ||
| 127 | 120 | ||
| @@ -129,7 +122,6 @@ static int cpcall (lua_State *L) { · 1 unmodified line | |||
| 129 | ** Create registry table and its predefined values | 122 | ** Create registry table and its predefined values |
| 130 | */ | 123 | */ |
| 131 | static void init_registry (lua_State *L, global_State *g) { | 124 | static void init_registry (lua_State *L, global_State *g) { |
| 132 | Closure *cp; | ||
| 133 | TValue mt; | 125 | TValue mt; |
| 134 | /* create registry */ | 126 | /* create registry */ |
| 135 | Table *registry = luaH_new(L); | 127 | Table *registry = luaH_new(L); |
| @@ -138,13 +130,8 @@ static void init_registry (lua_State *L, global_State *g) { · 2 unmodified lines | |||
| 138 | /* registry[LUA_RIDX_MAINTHREAD] = L */ | 130 | /* registry[LUA_RIDX_MAINTHREAD] = L */ |
| 139 | setthvalue(L, &mt, L); | 131 | setthvalue(L, &mt, L); |
| 140 | setobj2t(L, luaH_setint(L, registry, LUA_RIDX_MAINTHREAD), &mt); | 132 | setobj2t(L, luaH_setint(L, registry, LUA_RIDX_MAINTHREAD), &mt); |
| 141 | /* registry[LUA_RIDX_CPCALL] = cpcall */ | 133 | /* registry[LUA_RIDX_GLOBALS] = table of globals */ |
| 142 | cp = luaF_newCclosure(L, 0, g->l_gt); | 134 | sethvalue(L, &mt, luaH_new(L)); |
| 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); | ||
| 148 | setobj2t(L, luaH_setint(L, registry, LUA_RIDX_GLOBALS), &mt); | 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 | global_State *g = G(L); | 143 | global_State *g = G(L); |
| 157 | UNUSED(ud); | 144 | UNUSED(ud); |
| 158 | stack_init(L, L); /* init stack */ | 145 | stack_init(L, L); /* init stack */ |
| 159 | g->l_gt = luaH_new(L); /* table of globals */ | ||
| 160 | init_registry(L, g); | 146 | init_registry(L, g); |
| 161 | luaS_resize(L, MINSTRTABSIZE); /* initial size of string table */ | 147 | luaS_resize(L, MINSTRTABSIZE); /* initial size of string table */ |
| 162 | luaT_init(L); | 148 | luaT_init(L); |
| 163 | luaX_init(L); | 149 | luaX_init(L); |
| 164 | luaS_fix(luaS_newliteral(L, MEMERRMSG)); | 150 | /* pre-create memory-error message */ |
| 165 | g->GCthreshold = 4*g->totalbytes; | 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 | static void preinit_state (lua_State *L, global_State *g) { | 161 | static void preinit_state (lua_State *L, global_State *g) { |
| 174 | G(L) = g; | 162 | G(L) = g; |
| 175 | L->stack = NULL; | 163 | L->stack = NULL; |
| 164 | L->ci = NULL; | ||
| 176 | L->stacksize = 0; | 165 | L->stacksize = 0; |
| 177 | L->errorJmp = NULL; | 166 | L->errorJmp = NULL; |
| 178 | L->hook = NULL; | 167 | L->hook = NULL; |
| @@ -183,8 +172,6 @@ static void preinit_state (lua_State *L, global_State *g) { · 4 unmodified lines | |||
| 183 | L->openupval = NULL; | 172 | L->openupval = NULL; |
| 184 | L->nny = 1; | 173 | L->nny = 1; |
| 185 | L->status = LUA_OK; | 174 | L->status = LUA_OK; |
| 186 | L->base_ci.next = L->base_ci.previous = NULL; | ||
| 187 | L->ci = &L->base_ci; | ||
| 188 | L->errfunc = 0; | 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 | setthvalue(L, L->top, L1); | 196 | setthvalue(L, L->top, L1); |
| 210 | api_incr_top(L); | 197 | api_incr_top(L); |
| 211 | preinit_state(L1, G(L)); | 198 | preinit_state(L1, G(L)); |
| 212 | stack_init(L1, L); /* init stack */ | ||
| 213 | L1->hookmask = L->hookmask; | 199 | L1->hookmask = L->hookmask; |
| 214 | L1->basehookcount = L->basehookcount; | 200 | L1->basehookcount = L->basehookcount; |
| 215 | L1->hook = L->hook; | 201 | L1->hook = L->hook; |
| 216 | resethookcount(L1); | 202 | resethookcount(L1); |
| 217 | lua_assert(iswhite(obj2gco(L1))); | ||
| 218 | lua_unlock(L); | ||
| 219 | luai_userstatethread(L, L1); | 203 | luai_userstatethread(L, L1); |
| 204 | stack_init(L1, L); /* init stack */ | ||
| 205 | lua_unlock(L); | ||
| 220 | return L1; | 206 | return L1; |
| 221 | } | 207 | } |
| 222 | 208 | ||
| @@ -225,7 +211,7 @@ void luaE_freethread (lua_State *L, lua_State *L1) { · 2 unmodified lines | |||
| 225 | LX *l = fromstate(L1); | 211 | LX *l = fromstate(L1); |
| 226 | luaF_close(L1, L1->stack); /* close all upvalues for this thread */ | 212 | luaF_close(L1, L1->stack); /* close all upvalues for this thread */ |
| 227 | lua_assert(L1->openupval == NULL); | 213 | lua_assert(L1->openupval == NULL); |
| 228 | luai_userstatefree(L1); | 214 | luai_userstatefree(L, L1); |
| 229 | freestack(L1); | 215 | freestack(L1); |
| 230 | luaM_free(L, l); | 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 | int i; | 221 | int i; |
| 236 | lua_State *L; | 222 | lua_State *L; |
| 237 | global_State *g; | 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 | if (l == NULL) return NULL; | 225 | if (l == NULL) return NULL; |
| 240 | L = &l->l.l; | 226 | L = &l->l.l; |
| 241 | g = &l->g; | 227 | g = &l->g; |
| @@ -245,29 +231,31 @@ LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) { · 3 unmodified lines | |||
| 245 | L->marked = luaC_white(g); | 231 | L->marked = luaC_white(g); |
| 246 | g->gckind = KGC_NORMAL; | 232 | g->gckind = KGC_NORMAL; |
| 247 | g->nCcalls = 0; | 233 | g->nCcalls = 0; |
| 248 | set2bits(L->marked, FIXEDBIT, SFIXEDBIT); | ||
| 249 | preinit_state(L, g); | 234 | preinit_state(L, g); |
| 250 | g->frealloc = f; | 235 | g->frealloc = f; |
| 251 | g->ud = ud; | 236 | g->ud = ud; |
| 252 | g->mainthread = L; | 237 | g->mainthread = L; |
| 253 | g->uvhead.u.l.prev = &g->uvhead; | 238 | g->uvhead.u.l.prev = &g->uvhead; |
| 254 | g->uvhead.u.l.next = &g->uvhead; | 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 | g->strt.size = 0; | 242 | g->strt.size = 0; |
| 257 | g->strt.nuse = 0; | 243 | g->strt.nuse = 0; |
| 258 | g->strt.hash = NULL; | 244 | g->strt.hash = NULL; |
| 259 | setnilvalue(&g->l_registry); | 245 | setnilvalue(&g->l_registry); |
| 260 | g->l_gt = NULL; | ||
| 261 | luaZ_initbuffer(L, &g->buff); | 246 | luaZ_initbuffer(L, &g->buff); |
| 262 | g->panic = NULL; | 247 | g->panic = NULL; |
| 263 | g->version = lua_version(NULL); | 248 | g->version = lua_version(NULL); |
| 264 | g->gcstate = GCSpause; | 249 | g->gcstate = GCSpause; |
| 265 | g->rootgc = obj2gco(L); | 250 | g->allgc = NULL; |
| 251 | g->udgc = NULL; | ||
| 266 | g->tobefnz = NULL; | 252 | g->tobefnz = NULL; |
| 253 | g->gray = g->grayagain = NULL; | ||
| 254 | g->weak = g->ephemeron = g->allweak = NULL; | ||
| 267 | g->totalbytes = sizeof(LG); | 255 | g->totalbytes = sizeof(LG); |
| 268 | g->gcpause = LUAI_GCPAUSE; | 256 | g->gcpause = LUAI_GCPAUSE; |
| 269 | g->gcstepmul = LUAI_GCMUL; | 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 | if (luaD_rawrunprotected(L, f_luaopen, NULL) != LUA_OK) { | 259 | if (luaD_rawrunprotected(L, f_luaopen, NULL) != LUA_OK) { |
| 272 | /* memory allocation error: free partial state */ | 260 | /* memory allocation error: free partial state */ |
| 273 | close_state(L); | 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 | ** Global State | 3 | ** Global State |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -19,7 +19,7 @@ · 13 unmodified lines | |||
| 19 | ** Some notes about garbage-collected objects: All objects in Lua must | 19 | ** Some notes about garbage-collected objects: All objects in Lua must |
| 20 | ** be kept somehow accessible until being freed. | 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 | ** 'next' of the CommonHeader. | 23 | ** 'next' of the CommonHeader. |
| 24 | ** | 24 | ** |
| 25 | ** Strings are kept in several lists headed by the array g->strt.hash. | 25 | ** Strings are kept in several lists headed by the array g->strt.hash. |
| @@ -32,9 +32,7 @@ · 6 unmodified lines | |||
| 32 | ** when traversing the respective threads, but the thread may already be | 32 | ** when traversing the respective threads, but the thread may already be |
| 33 | ** dead, while the upvalue is still accessible through closures.) | 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 | 35 | ** Userdata with finalizers are kept in the list g->udgc. |
| 36 | ** the mainthread, which should be otherwise the last element in the | ||
| 37 | ** list, as it was the first one inserted there. | ||
| 38 | ** | 36 | ** |
| 39 | ** The list g->tobefnz links all userdata being finalized. | 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 | /* kinds of Garbage Collection */ | 55 | /* kinds of Garbage Collection */ |
| 58 | #define KGC_NORMAL 0 | 56 | #define KGC_NORMAL 0 |
| 59 | #define KGC_FORCED 1 /* gc was forced by the program */ | 57 | #define KGC_EMERGENCY 1 /* gc was forced by an allocation failure */ |
| 60 | #define KGC_EMERGENCY 2 /* gc was forced by an allocation failure */ | 58 | #define KGC_GEN 2 /* generational collection */ |
| 61 | 59 | ||
| 62 | 60 | ||
| 63 | typedef struct stringtable { | 61 | typedef struct stringtable { |
| @@ -85,7 +83,7 @@ typedef struct CallInfo { · 21 unmodified lines | |||
| 85 | int ctx; /* context info. in case of yields */ | 83 | int ctx; /* context info. in case of yields */ |
| 86 | lua_CFunction k; /* continuation in case of yields */ | 84 | lua_CFunction k; /* continuation in case of yields */ |
| 87 | ptrdiff_t old_errfunc; | 85 | ptrdiff_t old_errfunc; |
| 88 | ptrdiff_t oldtop; | 86 | ptrdiff_t extra; |
| 89 | lu_byte old_allowhook; | 87 | lu_byte old_allowhook; |
| 90 | lu_byte status; | 88 | lu_byte status; |
| 91 | } c; | 89 | } c; |
| @@ -106,7 +104,6 @@ typedef struct CallInfo { · 14 unmodified lines | |||
| 106 | #define CIST_TAIL (1<<6) /* call was tail called */ | 104 | #define CIST_TAIL (1<<6) /* call was tail called */ |
| 107 | 105 | ||
| 108 | 106 | ||
| 109 | #define curr_func(L) (clvalue(L->ci->func)) | ||
| 110 | #define ci_func(ci) (clvalue((ci)->func)) | 107 | #define ci_func(ci) (clvalue((ci)->func)) |
| 111 | #define isLua(ci) ((ci)->callstatus & CIST_LUA) | 108 | #define isLua(ci) ((ci)->callstatus & CIST_LUA) |
| 112 | 109 | ||
| @@ -115,15 +112,20 @@ typedef struct CallInfo { · 2 unmodified lines | |||
| 115 | ** `global state', shared by all threads of this state | 112 | ** `global state', shared by all threads of this state |
| 116 | */ | 113 | */ |
| 117 | typedef struct global_State { | 114 | typedef struct global_State { |
| 118 | stringtable strt; /* hash table for strings */ | ||
| 119 | lua_Alloc frealloc; /* function to reallocate memory */ | 115 | lua_Alloc frealloc; /* function to reallocate memory */ |
| 120 | void *ud; /* auxiliary data to `frealloc' */ | 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 | unsigned short nCcalls; /* number of nested C calls */ | 122 | unsigned short nCcalls; /* number of nested C calls */ |
| 122 | lu_byte currentwhite; | 123 | lu_byte currentwhite; |
| 123 | lu_byte gcstate; /* state of garbage collector */ | 124 | lu_byte gcstate; /* state of garbage collector */ |
| 124 | lu_byte gckind; /* kind of GC running */ | 125 | lu_byte gckind; /* kind of GC running */ |
| 125 | int sweepstrgc; /* position of sweep in `strt' */ | 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 | GCObject **sweepgc; /* current position of sweep */ | 129 | GCObject **sweepgc; /* current position of sweep */ |
| 128 | GCObject *gray; /* list of gray objects */ | 130 | GCObject *gray; /* list of gray objects */ |
| 129 | GCObject *grayagain; /* list of objects to be traversed atomically */ | 131 | GCObject *grayagain; /* list of objects to be traversed atomically */ |
| @@ -131,19 +133,16 @@ typedef struct global_State { · 1 unmodified line | |||
| 131 | GCObject *ephemeron; /* list of ephemeron tables (weak keys) */ | 133 | GCObject *ephemeron; /* list of ephemeron tables (weak keys) */ |
| 132 | GCObject *allweak; /* list of all-weak tables */ | 134 | GCObject *allweak; /* list of all-weak tables */ |
| 133 | GCObject *tobefnz; /* list of userdata to be GC */ | 135 | GCObject *tobefnz; /* list of userdata to be GC */ |
| 136 | UpVal uvhead; /* head of double-linked list of all open upvalues */ | ||
| 134 | Mbuffer buff; /* temporary buffer for string concatenation */ | 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 | int gcpause; /* size of pause between successive GCs */ | 138 | int gcpause; /* size of pause between successive GCs */ |
| 138 | int gcstepmul; /* GC `granularity' */ | 139 | int gcstepmul; /* GC `granularity' */ |
| 139 | lua_CFunction panic; /* to be called in unprotected errors */ | 140 | lua_CFunction panic; /* to be called in unprotected errors */ |
| 140 | TValue l_registry; | ||
| 141 | struct Table *l_gt; /* table of globals */ | ||
| 142 | struct lua_State *mainthread; | 141 | struct lua_State *mainthread; |
| 143 | UpVal uvhead; /* head of double-linked list of all open upvalues */ | ||
| 144 | const lua_Number *version; /* pointer to version number */ | 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 | TString *tmname[TM_N]; /* array with tag-method names */ | 144 | TString *tmname[TM_N]; /* array with tag-method names */ |
| 145 | struct Table *mt[LUA_NUMTAGS]; /* metatables for basic types */ | ||
| 147 | } global_State; | 146 | } global_State; |
| 148 | 147 | ||
| 149 | 148 | ||
| @@ -166,7 +165,6 @@ struct lua_State { · 16 unmodified lines | |||
| 166 | int basehookcount; | 165 | int basehookcount; |
| 167 | int hookcount; | 166 | int hookcount; |
| 168 | lua_Hook hook; | 167 | lua_Hook hook; |
| 169 | TValue env; /* temporary place for environments */ | ||
| 170 | GCObject *openupval; /* list of open upvalues in this stack */ | 168 | GCObject *openupval; /* list of open upvalues in this stack */ |
| 171 | GCObject *gclist; | 169 | GCObject *gclist; |
| 172 | struct lua_longjmp *errorJmp; /* current error recover point */ | 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 | ** String table (keeps all strings handled by Lua) | 3 | ** String table (keeps all strings handled by Lua) |
| 4 | ** See Copyright Notice in lua.h | 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 | unsigned int h = lmod(gco2ts(p)->hash, newsize); /* new position */ | 37 | unsigned int h = lmod(gco2ts(p)->hash, newsize); /* new position */ |
| 38 | gch(p)->next = tb->hash[h]; /* chain it */ | 38 | gch(p)->next = tb->hash[h]; /* chain it */ |
| 39 | tb->hash[h] = p; | 39 | tb->hash[h] = p; |
| 40 | resetoldbit(p); /* see MOVE OLD rule */ | ||
| 40 | p = next; | 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 | Udata *luaS_newudata (lua_State *L, size_t s, Table *e) { | 103 | Udata *luaS_newudata (lua_State *L, size_t s, Table *e) { |
| 98 | Udata *u; | 104 | Udata *u; |
| 99 | if (s > MAX_SIZET - sizeof(Udata)) | 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 | ** String table (keep all strings handled by Lua) | 3 | ** String table (keep all strings handled by Lua) |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -7,7 +7,6 @@ · 1 unmodified line | |||
| 7 | #ifndef lstring_h | 7 | #ifndef lstring_h |
| 8 | #define lstring_h | 8 | #define lstring_h |
| 9 | 9 | ||
| 10 | |||
| 11 | #include "lgc.h" | 10 | #include "lgc.h" |
| 12 | #include "lobject.h" | 11 | #include "lobject.h" |
| 13 | #include "lstate.h" | 12 | #include "lstate.h" |
| @@ -17,15 +16,22 @@ · 3 unmodified lines | |||
| 17 | 16 | ||
| 18 | #define sizeudata(u) (sizeof(union Udata)+(u)->len) | 17 | #define sizeudata(u) (sizeof(union Udata)+(u)->len) |
| 19 | 18 | ||
| 20 | #define luaS_new(L, s) (luaS_newlstr(L, s, strlen(s))) | ||
| 21 | #define luaS_newliteral(L, s) (luaS_newlstr(L, "" s, \ | 19 | #define luaS_newliteral(L, s) (luaS_newlstr(L, "" s, \ |
| 22 | (sizeof(s)/sizeof(char))-1)) | 20 | (sizeof(s)/sizeof(char))-1)) |
| 23 | 21 | ||
| 24 | #define luaS_fix(s) l_setbit((s)->tsv.marked, FIXEDBIT) | 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 | LUAI_FUNC void luaS_resize (lua_State *L, int newsize); | 31 | LUAI_FUNC void luaS_resize (lua_State *L, int newsize); |
| 27 | LUAI_FUNC Udata *luaS_newudata (lua_State *L, size_t s, Table *e); | 32 | LUAI_FUNC Udata *luaS_newudata (lua_State *L, size_t s, Table *e); |
| 28 | LUAI_FUNC TString *luaS_newlstr (lua_State *L, const char *str, size_t l); | 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 | #endif | 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 | ** Standard library for string operations and pattern-matching | 3 | ** Standard library for string operations and pattern-matching |
| 4 | ** See Copyright Notice in lua.h | 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 | static int str_reverse (lua_State *L) { | 67 | static int str_reverse (lua_State *L) { |
| 68 | size_t l; | 68 | size_t l, i; |
| 69 | luaL_Buffer b; | 69 | luaL_Buffer b; |
| 70 | const char *s = luaL_checklstring(L, 1, &l); | 70 | const char *s = luaL_checklstring(L, 1, &l); |
| 71 | luaL_buffinit(L, &b); | 71 | char *p = luaL_buffinitsize(L, &b, l); |
| 72 | while (l--) luaL_addchar(&b, s[l]); | 72 | for (i = 0; i < l; i++) |
| 73 | luaL_pushresult(&b); | 73 | p[i] = s[l - i - 1]; |
| 74 | luaL_pushresultsize(&b, l); | ||
| 74 | return 1; | 75 | return 1; |
| 75 | } | 76 | } |
| 76 | 77 | ||
| @@ -80,10 +81,10 @@ static int str_lower (lua_State *L) { · 3 unmodified lines | |||
| 80 | size_t i; | 81 | size_t i; |
| 81 | luaL_Buffer b; | 82 | luaL_Buffer b; |
| 82 | const char *s = luaL_checklstring(L, 1, &l); | 83 | const char *s = luaL_checklstring(L, 1, &l); |
| 83 | luaL_buffinit(L, &b); | 84 | char *p = luaL_buffinitsize(L, &b, l); |
| 84 | for (i=0; i<l; i++) | 85 | for (i=0; i<l; i++) |
| 85 | luaL_addchar(&b, tolower(uchar(s[i]))); | 86 | p[i] = tolower(uchar(s[i])); |
| 86 | luaL_pushresult(&b); | 87 | luaL_pushresultsize(&b, l); |
| 87 | return 1; | 88 | return 1; |
| 88 | } | 89 | } |
| 89 | 90 | ||
| @@ -93,10 +94,10 @@ static int str_upper (lua_State *L) { · 3 unmodified lines | |||
| 93 | size_t i; | 94 | size_t i; |
| 94 | luaL_Buffer b; | 95 | luaL_Buffer b; |
| 95 | const char *s = luaL_checklstring(L, 1, &l); | 96 | const char *s = luaL_checklstring(L, 1, &l); |
| 96 | luaL_buffinit(L, &b); | 97 | char *p = luaL_buffinitsize(L, &b, l); |
| 97 | for (i=0; i<l; i++) | 98 | for (i=0; i<l; i++) |
| 98 | luaL_addchar(&b, toupper(uchar(s[i]))); | 99 | p[i] = toupper(uchar(s[i])); |
| 99 | luaL_pushresult(&b); | 100 | luaL_pushresultsize(&b, l); |
| 100 | return 1; | 101 | return 1; |
| 101 | } | 102 | } |
| 102 | 103 | ||
| @@ -136,13 +137,13 @@ static int str_char (lua_State *L) { · 33 unmodified lines | |||
| 136 | int n = lua_gettop(L); /* number of arguments */ | 137 | int n = lua_gettop(L); /* number of arguments */ |
| 137 | int i; | 138 | int i; |
| 138 | luaL_Buffer b; | 139 | luaL_Buffer b; |
| 139 | luaL_buffinit(L, &b); | 140 | char *p = luaL_buffinitsize(L, &b, n); |
| 140 | for (i=1; i<=n; i++) { | 141 | for (i=1; i<=n; i++) { |
| 141 | int c = luaL_checkint(L, i); | 142 | int c = luaL_checkint(L, i); |
| 142 | luaL_argcheck(L, uchar(c) == c, i, "invalid value"); | 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 | return 1; | 147 | return 1; |
| 147 | } | 148 | } |
| 148 | 149 | ||
| @@ -179,7 +180,8 @@ static int str_dump (lua_State *L) { · 30 unmodified lines | |||
| 179 | 180 | ||
| 180 | typedef struct MatchState { | 181 | typedef struct MatchState { |
| 181 | const char *src_init; /* init of source string */ | 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 | lua_State *L; | 185 | lua_State *L; |
| 184 | int level; /* total number of captures (finished or unfinished) */ | 186 | int level; /* total number of captures (finished or unfinished) */ |
| 185 | struct { | 187 | struct { |
| @@ -212,16 +214,16 @@ static int capture_to_close (MatchState *ms) { · 26 unmodified lines | |||
| 212 | static const char *classend (MatchState *ms, const char *p) { | 214 | static const char *classend (MatchState *ms, const char *p) { |
| 213 | switch (*p++) { | 215 | switch (*p++) { |
| 214 | case L_ESC: { | 216 | case L_ESC: { |
| 215 | if (*p == '\0') | 217 | if (p == ms->p_end) |
| 216 | luaL_error(ms->L, "malformed pattern (ends with " LUA_QL("%%") ")"); | 218 | luaL_error(ms->L, "malformed pattern (ends with " LUA_QL("%%") ")"); |
| 217 | return p+1; | 219 | return p+1; |
| 218 | } | 220 | } |
| 219 | case '[': { | 221 | case '[': { |
| 220 | if (*p == '^') p++; | 222 | if (*p == '^') p++; |
| 221 | do { /* look for a `]' */ | 223 | do { /* look for a `]' */ |
| 222 | if (*p == '\0') | 224 | if (p == ms->p_end) |
| 223 | luaL_error(ms->L, "malformed pattern (missing " LUA_QL("]") ")"); | 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 | p++; /* skip escapes (e.g. `%]') */ | 227 | p++; /* skip escapes (e.g. `%]') */ |
| 226 | } while (*p != ']'); | 228 | } while (*p != ']'); |
| 227 | return p+1; | 229 | return p+1; |
| @@ -245,7 +247,7 @@ static int match_class (int c, int cl) { · 17 unmodified lines | |||
| 245 | case 'u' : res = isupper(c); break; | 247 | case 'u' : res = isupper(c); break; |
| 246 | case 'w' : res = isalnum(c); break; | 248 | case 'w' : res = isalnum(c); break; |
| 247 | case 'x' : res = isxdigit(c); break; | 249 | case 'x' : res = isxdigit(c); break; |
| 248 | case 'z' : res = (c == 0); break; | 250 | case 'z' : res = (c == 0); break; /* deprecated option */ |
| 249 | default: return (cl == c); | 251 | default: return (cl == c); |
| 250 | } | 252 | } |
| 251 | return (islower(cl) ? res : !res); | 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 | static const char *matchbalance (MatchState *ms, const char *s, | 293 | static const char *matchbalance (MatchState *ms, const char *s, |
| 292 | const char *p) { | 294 | const char *p) { |
| 293 | if (*p == 0 || *(p+1) == 0) | 295 | if (p >= ms->p_end - 1) |
| 294 | luaL_error(ms->L, "unbalanced pattern"); | 296 | luaL_error(ms->L, "malformed pattern " |
| 297 | "(missing arguments to " LUA_QL("%%b") ")"); | ||
| 295 | if (*s != *p) return NULL; | 298 | if (*s != *p) return NULL; |
| 296 | else { | 299 | else { |
| 297 | int b = *p; | 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 | static const char *match (MatchState *ms, const char *s, const char *p) { | 378 | static const char *match (MatchState *ms, const char *s, const char *p) { |
| 376 | init: /* using goto's to optimize tail recursion */ | 379 | init: /* using goto's to optimize tail recursion */ |
| 380 | if (p == ms->p_end) /* end of pattern? */ | ||
| 381 | return s; /* match succeeded */ | ||
| 377 | switch (*p) { | 382 | switch (*p) { |
| 378 | case '(': { /* start capture */ | 383 | case '(': { /* start capture */ |
| 379 | if (*(p+1) == ')') /* position capture? */ | 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 | case ')': { /* end capture */ | 389 | case ')': { /* end capture */ |
| 385 | return end_capture(ms, s, p+1); | 390 | return end_capture(ms, s, p+1); |
| 386 | } | 391 | } |
| 387 | case '\0': { /* end of pattern */ | ||
| 388 | return s; /* match succeeded */ | ||
| 389 | } | ||
| 390 | case '$': { | 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 | return (s == ms->src_end) ? s : NULL; /* check end of string */ | 394 | return (s == ms->src_end) ? s : NULL; /* check end of string */ |
| 393 | else goto dflt; | 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 | if (s == NULL) return NULL; | 420 | if (s == NULL) return NULL; |
| 419 | p+=2; goto init; /* else return match(ms, s, p+2) */ | 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 | default: dflt: { /* pattern class plus optional sufix */ | 426 | default: dflt: { /* pattern class plus optional sufix */ |
| 425 | const char *ep = classend(ms, p); /* points to what is next */ | 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 | switch (*ep) { | 429 | switch (*ep) { |
| 428 | case '?': { /* optional */ | 430 | case '?': { /* optional */ |
| 429 | const char *res; | 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 | static int str_find_aux (lua_State *L, int find) { | 507 | static int str_find_aux (lua_State *L, int find) { |
| 506 | size_t l1, l2; | 508 | size_t ls, lp; |
| 507 | const char *s = luaL_checklstring(L, 1, &l1); | 509 | const char *s = luaL_checklstring(L, 1, &ls); |
| 508 | const char *p = luaL_checklstring(L, 2, &l2); | 510 | const char *p = luaL_checklstring(L, 2, &lp); |
| 509 | size_t init = posrelat(luaL_optinteger(L, 3, 1), l1); | 511 | size_t init = posrelat(luaL_optinteger(L, 3, 1), ls); |
| 510 | if (init < 1) init = 1; | 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 | lua_pushnil(L); /* cannot find anything */ | 514 | lua_pushnil(L); /* cannot find anything */ |
| 513 | return 1; | 515 | return 1; |
| 514 | } | 516 | } |
| 515 | if (find && (lua_toboolean(L, 4) || /* explicit request? */ | 517 | if (find && (lua_toboolean(L, 4) || /* explicit request? */ |
| 516 | strpbrk(p, SPECIALS) == NULL)) { /* or no special characters? */ | 518 | strpbrk(p, SPECIALS) == NULL)) { /* or no special characters? */ |
| 517 | /* do a plain search */ | 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 | if (s2) { | 521 | if (s2) { |
| 520 | lua_pushinteger(L, s2 - s + 1); | 522 | lua_pushinteger(L, s2 - s + 1); |
| 521 | lua_pushinteger(L, s2 - s + l2); | 523 | lua_pushinteger(L, s2 - s + lp); |
| 522 | return 2; | 524 | return 2; |
| 523 | } | 525 | } |
| 524 | } | 526 | } |
| 525 | else { | 527 | else { |
| 526 | MatchState ms; | 528 | MatchState ms; |
| 527 | int anchor = (*p == '^') ? (p++, 1) : 0; | ||
| 528 | const char *s1 = s + init - 1; | 529 | const char *s1 = s + init - 1; |
| 530 | int anchor = (*p == '^'); | ||
| 531 | if (anchor) { | ||
| 532 | p++; lp--; /* skip anchor character */ | ||
| 533 | } | ||
| 529 | ms.L = L; | 534 | ms.L = L; |
| 530 | ms.src_init = s; | 535 | ms.src_init = s; |
| 531 | ms.src_end = s + l1; | 536 | ms.src_end = s + ls; |
| 537 | ms.p_end = p + lp; | ||
| 532 | do { | 538 | do { |
| 533 | const char *res; | 539 | const char *res; |
| 534 | ms.level = 0; | 540 | ms.level = 0; |
| @@ -560,13 +566,14 @@ static int str_match (lua_State *L) { · 25 unmodified lines | |||
| 560 | 566 | ||
| 561 | static int gmatch_aux (lua_State *L) { | 567 | static int gmatch_aux (lua_State *L) { |
| 562 | MatchState ms; | 568 | MatchState ms; |
| 563 | size_t ls; | 569 | size_t ls, lp; |
| 564 | const char *s = lua_tolstring(L, lua_upvalueindex(1), &ls); | 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 | const char *src; | 572 | const char *src; |
| 567 | ms.L = L; | 573 | ms.L = L; |
| 568 | ms.src_init = s; | 574 | ms.src_init = s; |
| 569 | ms.src_end = s+ls; | 575 | ms.src_end = s+ls; |
| 576 | ms.p_end = p + lp; | ||
| 570 | for (src = s + (size_t)lua_tointeger(L, lua_upvalueindex(3)); | 577 | for (src = s + (size_t)lua_tointeger(L, lua_upvalueindex(3)); |
| 571 | src <= ms.src_end; | 578 | src <= ms.src_end; |
| 572 | src++) { | 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 | static int str_gsub (lua_State *L) { | 667 | static int str_gsub (lua_State *L) { |
| 661 | size_t srcl; | 668 | size_t srcl, lp; |
| 662 | const char *src = luaL_checklstring(L, 1, &srcl); | 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 | int tr = lua_type(L, 3); | 671 | int tr = lua_type(L, 3); |
| 665 | size_t max_s = luaL_optinteger(L, 4, srcl+1); | 672 | size_t max_s = luaL_optinteger(L, 4, srcl+1); |
| 666 | int anchor = (*p == '^') ? (p++, 1) : 0; | 673 | int anchor = (*p == '^'); |
| 667 | size_t n = 0; | 674 | size_t n = 0; |
| 668 | MatchState ms; | 675 | MatchState ms; |
| 669 | luaL_Buffer b; | 676 | luaL_Buffer b; |
| @@ -671,9 +678,13 @@ static int str_gsub (lua_State *L) { · 1 unmodified line | |||
| 671 | tr == LUA_TFUNCTION || tr == LUA_TTABLE, 3, | 678 | tr == LUA_TFUNCTION || tr == LUA_TTABLE, 3, |
| 672 | "string/function/table expected"); | 679 | "string/function/table expected"); |
| 673 | luaL_buffinit(L, &b); | 680 | luaL_buffinit(L, &b); |
| 681 | if (anchor) { | ||
| 682 | p++; lp--; /* skip anchor character */ | ||
| 683 | } | ||
| 674 | ms.L = L; | 684 | ms.L = L; |
| 675 | ms.src_init = src; | 685 | ms.src_init = src; |
| 676 | ms.src_end = src+srcl; | 686 | ms.src_end = src+srcl; |
| 687 | ms.p_end = p + lp; | ||
| 677 | while (n < max_s) { | 688 | while (n < max_s) { |
| 678 | const char *e; | 689 | const char *e; |
| 679 | ms.level = 0; | 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 | 714 | ** {====================================================== |
| 703 | ** integer type corresponding to the previous length | 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 | #if defined(LUA_USELONGLONG) | 724 | #if defined(LUA_USELONGLONG) |
| 707 | 725 | ||
| 708 | #define LUA_INTFRMLEN "ll" | 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 | else if (*s == '\0' || iscntrl(uchar(*s))) { | 757 | else if (*s == '\0' || iscntrl(uchar(*s))) { |
| 740 | char buff[10]; | 758 | char buff[10]; |
| 741 | if (*s != '\0' && !isdigit(uchar(*(s+1)))) | 759 | if (!isdigit(uchar(*(s+1)))) |
| 742 | sprintf(buff, "\\%d", uchar(*s)); | 760 | sprintf(buff, "\\%d", uchar(*s)); |
| 743 | else | 761 | else |
| 744 | sprintf(buff, "\\%03d", uchar(*s)); | 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 | static void addintlen (char *form) { | 797 | static void addintlen (char *form) { |
| 777 | size_t l = strlen(form); | 798 | size_t l = strlen(form); |
| 778 | char spec = form[l - 1]; | 799 | char spec = form[l - 1]; |
| @@ -783,6 +804,7 @@ static void addintlen (char *form) { · 4 unmodified lines | |||
| 783 | 804 | ||
| 784 | 805 | ||
| 785 | static int str_format (lua_State *L) { | 806 | static int str_format (lua_State *L) { |
| 807 | int top = lua_gettop(L); | ||
| 786 | int arg = 1; | 808 | int arg = 1; |
| 787 | size_t sfl; | 809 | size_t sfl; |
| 788 | const char *strfrmt = luaL_checklstring(L, arg, &sfl); | 810 | const char *strfrmt = luaL_checklstring(L, arg, &sfl); |
| @@ -796,12 +818,14 @@ static int str_format (lua_State *L) { · 7 unmodified lines | |||
| 796 | luaL_addchar(&b, *strfrmt++); /* %% */ | 818 | luaL_addchar(&b, *strfrmt++); /* %% */ |
| 797 | else { /* format item */ | 819 | else { /* format item */ |
| 798 | char form[MAX_FORMAT]; /* to store the format (`%...') */ | 820 | char form[MAX_FORMAT]; /* to store the format (`%...') */ |
| 799 | char buff[MAX_ITEM]; /* to store the formatted item */ | 821 | char *buff = luaL_prepbuffsize(&b, MAX_ITEM); /* to put formatted item */ |
| 800 | arg++; | 822 | int nb = 0; /* number of bytes in added item */ |
| 823 | if (++arg > top) | ||
| 824 | luaL_argerror(L, arg, "no value"); | ||
| 801 | strfrmt = scanformat(L, strfrmt, form); | 825 | strfrmt = scanformat(L, strfrmt, form); |
| 802 | switch (*strfrmt++) { | 826 | switch (*strfrmt++) { |
| 803 | case 'c': { | 827 | case 'c': { |
| 804 | sprintf(buff, form, luaL_checkint(L, arg)); | 828 | nb = sprintf(buff, form, luaL_checkint(L, arg)); |
| 805 | break; | 829 | break; |
| 806 | } | 830 | } |
| 807 | case 'd': case 'i': | 831 | case 'd': case 'i': |
| @@ -810,17 +834,17 @@ static int str_format (lua_State *L) { · 2 unmodified lines | |||
| 810 | LUA_INTFRM_T r = (n < 0) ? (LUA_INTFRM_T)n : | 834 | LUA_INTFRM_T r = (n < 0) ? (LUA_INTFRM_T)n : |
| 811 | (LUA_INTFRM_T)(unsigned LUA_INTFRM_T)n; | 835 | (LUA_INTFRM_T)(unsigned LUA_INTFRM_T)n; |
| 812 | addintlen(form); | 836 | addintlen(form); |
| 813 | sprintf(buff, form, r); | 837 | nb = sprintf(buff, form, r); |
| 814 | break; | 838 | break; |
| 815 | } | 839 | } |
| 816 | case 'e': case 'E': case 'f': | 840 | case 'e': case 'E': case 'f': |
| 817 | case 'g': case 'G': { | 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 | break; | 843 | break; |
| 820 | } | 844 | } |
| 821 | case 'q': { | 845 | case 'q': { |
| 822 | addquoted(L, &b, arg); | 846 | addquoted(L, &b, arg); |
| 823 | continue; /* skip the 'addsize' at the end */ | 847 | break; |
| 824 | } | 848 | } |
| 825 | case 's': { | 849 | case 's': { |
| 826 | size_t l; | 850 | size_t l; |
| @@ -830,10 +854,10 @@ static int str_format (lua_State *L) { · 3 unmodified lines | |||
| 830 | keep original string */ | 854 | keep original string */ |
| 831 | lua_pushvalue(L, arg); | 855 | lua_pushvalue(L, arg); |
| 832 | luaL_addvalue(&b); | 856 | luaL_addvalue(&b); |
| 833 | continue; /* skip the `addsize' at the end */ | 857 | break; |
| 834 | } | 858 | } |
| 835 | else { | 859 | else { |
| 836 | sprintf(buff, form, s); | 860 | nb = sprintf(buff, form, s); |
| 837 | break; | 861 | break; |
| 838 | } | 862 | } |
| 839 | } | 863 | } |
| @@ -842,13 +866,15 @@ static int str_format (lua_State *L) { · 2 unmodified lines | |||
| 842 | LUA_QL("format"), *(strfrmt - 1)); | 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 | luaL_pushresult(&b); | 872 | luaL_pushresult(&b); |
| 849 | return 1; | 873 | return 1; |
| 850 | } | 874 | } |
| 851 | 875 | ||
| 876 | /* }====================================================== */ | ||
| 877 | |||
| 852 | 878 | ||
| 853 | static const luaL_Reg strlib[] = { | 879 | static const luaL_Reg strlib[] = { |
| 854 | {"byte", str_byte}, | 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 | ** Lua tables (hash) | 3 | ** Lua tables (hash) |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -31,6 +31,7 @@ · 25 unmodified lines | |||
| 31 | #include "lmem.h" | 31 | #include "lmem.h" |
| 32 | #include "lobject.h" | 32 | #include "lobject.h" |
| 33 | #include "lstate.h" | 33 | #include "lstate.h" |
| 34 | #include "lstring.h" | ||
| 34 | #include "ltable.h" | 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 | return hashboolean(t, bvalue(key)); | 109 | return hashboolean(t, bvalue(key)); |
| 109 | case LUA_TLIGHTUSERDATA: | 110 | case LUA_TLIGHTUSERDATA: |
| 110 | return hashpointer(t, pvalue(key)); | 111 | return hashpointer(t, pvalue(key)); |
| 112 | case LUA_TLCF: | ||
| 113 | return hashpointer(t, fvalue(key)); | ||
| 111 | default: | 114 | default: |
| 112 | return hashpointer(t, gcvalue(key)); | 115 | return hashpointer(t, gcvalue(key)); |
| 113 | } | 116 | } |
| @@ -452,7 +455,7 @@ const TValue *luaH_getint (Table *t, int key) { · 338 unmodified lines | |||
| 452 | const TValue *luaH_getstr (Table *t, TString *key) { | 455 | const TValue *luaH_getstr (Table *t, TString *key) { |
| 453 | Node *n = hashstr(t, key); | 456 | Node *n = hashstr(t, key); |
| 454 | do { /* check whether `key' is somewhere in the chain */ | 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 | return gval(n); /* that's it */ | 459 | return gval(n); /* that's it */ |
| 457 | else n = gnext(n); | 460 | else n = gnext(n); |
| 458 | } while (n); | 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 | ** Library for Table Manipulation | 3 | ** Library for Table Manipulation |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -171,15 +171,15 @@ static int tconcat (lua_State *L) { · 165 unmodified lines | |||
| 171 | static int pack (lua_State *L) { | 171 | static int pack (lua_State *L) { |
| 172 | int top = lua_gettop(L); | 172 | int top = lua_gettop(L); |
| 173 | lua_createtable(L, top, 1); /* create result table */ | 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 | lua_pushinteger(L, top); /* number of elements */ | 174 | lua_pushinteger(L, top); /* number of elements */ |
| 177 | lua_setfield(L, LUA_ENVIRONINDEX, "n"); /* t.n = number of elements */ | 175 | lua_setfield(L, -2, "n"); /* t.n = number of elements */ |
| 178 | for (; top >= 1; top--) /* assign elements */ | 176 | if (top > 0) { /* at least one element? */ |
| 179 | lua_rawseti(L, LUA_ENVIRONINDEX, top); | 177 | lua_pushvalue(L, 1); |
| 180 | lua_pushvalue(L, LUA_ENVIRONINDEX); /* return new table */ | 178 | lua_rawseti(L, -2, 1); /* insert first element */ |
| 181 | /* remove new table from environment to allow its later collection */ | 179 | lua_replace(L, 1); /* move table into its position (index 1) */ |
| 182 | lua_copy(L, LUA_REGISTRYINDEX, LUA_ENVIRONINDEX); | 180 | for (; top >= 2; top--) /* assign other elements */ |
| 181 | lua_rawseti(L, 1, top); | ||
| 182 | } | ||
| 183 | return 1; | 183 | return 1; |
| 184 | } | 184 | } |
| 185 | 185 | ||
| @@ -328,7 +328,7 @@ LUAMOD_API int luaopen_table (lua_State *L) { · 142 unmodified lines | |||
| 328 | #if defined(LUA_COMPAT_UNPACK) | 328 | #if defined(LUA_COMPAT_UNPACK) |
| 329 | /* _G.unpack = table.unpack */ | 329 | /* _G.unpack = table.unpack */ |
| 330 | lua_getfield(L, -1, "unpack"); | 330 | lua_getfield(L, -1, "unpack"); |
| 331 | lua_setfield(L, LUA_ENVIRONINDEX, "unpack"); | 331 | lua_setglobal(L, "unpack"); |
| 332 | #endif | 332 | #endif |
| 333 | return 1; | 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 | ** Tag methods | 3 | ** Tag methods |
| 4 | ** See Copyright Notice in lua.h | 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 | mt = uvalue(o)->metatable; | 70 | mt = uvalue(o)->metatable; |
| 71 | break; | 71 | break; |
| 72 | default: | 72 | default: |
| 73 | mt = G(L)->mt[ttype(o)]; | 73 | mt = G(L)->mt[ttypenv(o)]; |
| 74 | } | 74 | } |
| 75 | return (mt ? luaH_getstr(mt, G(L)->tmname[event]) : luaO_nilobject); | 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 | ** Tag methods | 3 | ** Tag methods |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -43,7 +43,8 @@ typedef enum { · 37 unmodified lines | |||
| 43 | 43 | ||
| 44 | #define fasttm(l,et,e) gfasttm(G(l), et, e) | 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 | LUAI_DDEC const char *const luaT_typenames_[]; | 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 | ** Lua stand-alone interpreter | 3 | ** Lua stand-alone interpreter |
| 4 | ** See Copyright Notice in lua.h | 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) { | 105 | static void print_usage (const char *badoption) { |
| 106 | fprintf(stderr, | 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 | "usage: %s [options] [script [args]]\n" | 114 | "usage: %s [options] [script [args]]\n" |
| 108 | "Available options are:\n" | 115 | "Available options are:\n" |
| 109 | " -e stat execute string " LUA_QL("stat") "\n" | 116 | " -e stat execute string " LUA_QL("stat") "\n" |
| 110 | " -l name require library " LUA_QL("name") "\n" | ||
| 111 | " -i enter interactive mode after executing " LUA_QL("script") "\n" | 117 | " -i enter interactive mode after executing " LUA_QL("script") "\n" |
| 118 | " -l name require library " LUA_QL("name") "\n" | ||
| 112 | " -v show version information\n" | 119 | " -v show version information\n" |
| 113 | " -- stop handling options\n" | 120 | " -- stop handling options\n" |
| 114 | " - execute stdin and stop handling options\n" | 121 | " - stop handling options and execute stdin\n" |
| 115 | , | 122 | , |
| 116 | progname); | 123 | progname); |
| 117 | fflush(stderr); | ||
| 118 | } | 124 | } |
| 119 | 125 | ||
| 120 | 126 | ||
| 121 | static void l_message (const char *pname, const char *msg) { | 127 | static void l_message (const char *pname, const char *msg) { |
| 122 | if (pname) fprintf(stderr, "%s: ", pname); | 128 | if (pname) luai_writestringerror("%s: ", pname); |
| 123 | fprintf(stderr, "%s\n", msg); | 129 | luai_writestringerror("%s\n", msg); |
| 124 | fflush(stderr); | ||
| 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 | static int dolibrary (lua_State *L, const char *name) { | 221 | static int dolibrary (lua_State *L, const char *name) { |
| 217 | lua_getfield(L, LUA_ENVIRONINDEX, "require"); | 222 | lua_getglobal(L, "require"); |
| 218 | lua_pushstring(L, name); | 223 | lua_pushstring(L, name); |
| 219 | return report(L, docall(L, 1, 1)); | 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 | static const char *get_prompt (lua_State *L, int firstline) { | 228 | static const char *get_prompt (lua_State *L, int firstline) { |
| 224 | const char *p; | 229 | const char *p; |
| 225 | lua_getfield(L, LUA_ENVIRONINDEX, firstline ? "_PROMPT" : "_PROMPT2"); | 230 | lua_getglobal(L, firstline ? "_PROMPT" : "_PROMPT2"); |
| 226 | p = lua_tostring(L, -1); | 231 | p = lua_tostring(L, -1); |
| 227 | if (p == NULL) p = (firstline ? LUA_PROMPT : LUA_PROMPT2); | 232 | if (p == NULL) p = (firstline ? LUA_PROMPT : LUA_PROMPT2); |
| 228 | lua_pop(L, 1); /* remove global */ | 233 | lua_pop(L, 1); /* remove global */ |
| @@ -296,7 +301,7 @@ static void dotty (lua_State *L) { · 67 unmodified lines | |||
| 296 | report(L, status); | 301 | report(L, status); |
| 297 | if (status == LUA_OK && lua_gettop(L) > 0) { /* any result to print? */ | 302 | if (status == LUA_OK && lua_gettop(L) > 0) { /* any result to print? */ |
| 298 | luaL_checkstack(L, LUA_MINSTACK, "too many results to print"); | 303 | luaL_checkstack(L, LUA_MINSTACK, "too many results to print"); |
| 299 | lua_getfield(L, LUA_ENVIRONINDEX, "print"); | 304 | lua_getglobal(L, "print"); |
| 300 | lua_insert(L, 1); | 305 | lua_insert(L, 1); |
| 301 | if (lua_pcall(L, lua_gettop(L)-1, 0, 0) != LUA_OK) | 306 | if (lua_pcall(L, lua_gettop(L)-1, 0, 0) != LUA_OK) |
| 302 | l_message(progname, lua_pushfstring(L, | 307 | l_message(progname, lua_pushfstring(L, |
| @@ -306,7 +311,6 @@ static void dotty (lua_State *L) { · 3 unmodified lines | |||
| 306 | } | 311 | } |
| 307 | lua_settop(L, 0); /* clear stack */ | 312 | lua_settop(L, 0); /* clear stack */ |
| 308 | luai_writestring("\n", 1); | 313 | luai_writestring("\n", 1); |
| 309 | fflush(stdout); | ||
| 310 | progname = oldprogname; | 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 | int status; | 319 | int status; |
| 316 | const char *fname; | 320 | const char *fname; |
| 317 | int narg = getargs(L, argv, n); /* collect arguments */ | 321 | int narg = getargs(L, argv, n); /* collect arguments */ |
| 318 | lua_setfield(L, LUA_ENVIRONINDEX, "arg"); | 322 | lua_setglobal(L, "arg"); |
| 319 | fname = argv[n]; | 323 | fname = argv[n]; |
| 320 | if (strcmp(fname, "-") == 0 && strcmp(argv[n-1], "--") != 0) | 324 | if (strcmp(fname, "-") == 0 && strcmp(argv[n-1], "--") != 0) |
| 321 | fname = NULL; /* stdin */ | 325 | fname = NULL; /* stdin */ |
| @@ -356,10 +360,11 @@ static int collectargs (char **argv, int *pi, int *pv, int *pe) { · 34 unmodified lines | |||
| 356 | case 'l': | 360 | case 'l': |
| 357 | if (argv[i][2] == '\0') { | 361 | if (argv[i][2] == '\0') { |
| 358 | i++; | 362 | i++; |
| 359 | if (argv[i] == NULL) return -1; | 363 | if (argv[i] == NULL) return -(i - 1); |
| 360 | } | 364 | } |
| 361 | break; | 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 | return 0; | 370 | return 0; |
| @@ -369,7 +374,6 @@ static int collectargs (char **argv, int *pi, int *pv, int *pe) { · 3 unmodified lines | |||
| 369 | static int runargs (lua_State *L, char **argv, int n) { | 374 | static int runargs (lua_State *L, char **argv, int n) { |
| 370 | int i; | 375 | int i; |
| 371 | for (i = 1; i < n; i++) { | 376 | for (i = 1; i < n; i++) { |
| 372 | if (argv[i] == NULL) continue; | ||
| 373 | lua_assert(argv[i][0] == '-'); | 377 | lua_assert(argv[i][0] == '-'); |
| 374 | switch (argv[i][1]) { /* option */ | 378 | switch (argv[i][1]) { /* option */ |
| 375 | case 'e': { | 379 | case 'e': { |
| @@ -412,8 +416,8 @@ static int pmain (lua_State *L) { · 36 unmodified lines | |||
| 412 | int has_i = 0, has_v = 0, has_e = 0; | 416 | int has_i = 0, has_v = 0, has_e = 0; |
| 413 | if (argv[0] && argv[0][0]) progname = argv[0]; | 417 | if (argv[0] && argv[0][0]) progname = argv[0]; |
| 414 | script = collectargs(argv, &has_i, &has_v, &has_e); | 418 | script = collectargs(argv, &has_i, &has_v, &has_e); |
| 415 | if (script < 0) { /* invalid args? */ | 419 | if (script < 0) { /* invalid arg? */ |
| 416 | print_usage(); | 420 | print_usage(argv[-script]); |
| 417 | return 0; | 421 | return 0; |
| 418 | } | 422 | } |
| 419 | if (has_v) print_version(); | 423 | if (has_v) print_version(); |
| @@ -443,7 +447,6 @@ static int pmain (lua_State *L) { · 23 unmodified lines | |||
| 443 | 447 | ||
| 444 | 448 | ||
| 445 | int main (int argc, char **argv) { | 449 | int main (int argc, char **argv) { |
| 446 | static lua_CFunction ppmain = &pmain; | ||
| 447 | int status, result; | 450 | int status, result; |
| 448 | lua_State *L = luaL_newstate(); /* create state */ | 451 | lua_State *L = luaL_newstate(); /* create state */ |
| 449 | if (L == NULL) { | 452 | if (L == NULL) { |
| @@ -451,11 +454,10 @@ int main (int argc, char **argv) { · 1 unmodified line | |||
| 451 | return EXIT_FAILURE; | 454 | return EXIT_FAILURE; |
| 452 | } | 455 | } |
| 453 | /* call 'pmain' in protected mode */ | 456 | /* call 'pmain' in protected mode */ |
| 454 | lua_rawgeti(L, LUA_REGISTRYINDEX, LUA_RIDX_CPCALL); /* calling function */ | 457 | lua_pushcfunction(L, &pmain); |
| 455 | lua_pushlightuserdata(L, &ppmain); | 458 | lua_pushinteger(L, argc); /* 1st argument */ |
| 456 | lua_pushinteger(L, argc); | 459 | lua_pushlightuserdata(L, argv); /* 2nd argument */ |
| 457 | lua_pushlightuserdata(L, argv); | 460 | status = lua_pcall(L, 2, 1, 0); |
| 458 | status = lua_pcall(L, 3, 1, 0); | ||
| 459 | result = lua_toboolean(L, -1); /* get result */ | 461 | result = lua_toboolean(L, -1); /* get result */ |
| 460 | finalreport(L, status); | 462 | finalreport(L, status); |
| 461 | lua_close(L); | 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 | ** Lua - A Scripting Language | 3 | ** Lua - A Scripting Language |
| 4 | ** Lua.org, PUC-Rio, Brazil (http://www.lua.org) | 4 | ** Lua.org, PUC-Rio, Brazil (http://www.lua.org) |
| 5 | ** See Copyright Notice at the end of this file | 5 | ** See Copyright Notice at the end of this file |
| @@ -17,7 +17,7 @@ · 11 unmodified lines | |||
| 17 | 17 | ||
| 18 | 18 | ||
| 19 | #define LUA_VERSION "Lua 5.2" | 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 | #define LUA_VERSION_NUM 502 | 21 | #define LUA_VERSION_NUM 502 |
| 22 | #define LUA_COPYRIGHT LUA_RELEASE " Copyright (C) 1994-2010 Lua.org, PUC-Rio" | 22 | #define LUA_COPYRIGHT LUA_RELEASE " Copyright (C) 1994-2010 Lua.org, PUC-Rio" |
| 23 | #define LUA_AUTHORS "R. Ierusalimschy, L. H. de Figueiredo, W. Celes" | 23 | #define LUA_AUTHORS "R. Ierusalimschy, L. H. de Figueiredo, W. Celes" |
| @@ -34,8 +34,7 @@ · 10 unmodified lines | |||
| 34 | ** pseudo-indices | 34 | ** pseudo-indices |
| 35 | */ | 35 | */ |
| 36 | #define LUA_REGISTRYINDEX LUAI_FIRSTPSEUDOIDX | 36 | #define LUA_REGISTRYINDEX LUAI_FIRSTPSEUDOIDX |
| 37 | #define LUA_ENVIRONINDEX (LUA_REGISTRYINDEX - 1) | 37 | #define lua_upvalueindex(i) (LUA_REGISTRYINDEX - (i)) |
| 38 | #define lua_upvalueindex(i) (LUA_ENVIRONINDEX - (i)) | ||
| 39 | 38 | ||
| 40 | 39 | ||
| 41 | /* thread status */ | 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 | #define LUA_TUSERDATA 7 | 81 | #define LUA_TUSERDATA 7 |
| 83 | #define LUA_TTHREAD 8 | 82 | #define LUA_TTHREAD 8 |
| 84 | 83 | ||
| 84 | #define LUA_NUMTAGS 9 | ||
| 85 | |||
| 85 | 86 | ||
| 86 | 87 | ||
| 87 | /* minimum Lua stack available to a C function */ | 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 | /* predefined values in the registry */ | 92 | /* predefined values in the registry */ |
| 92 | #define LUA_RIDX_MAINTHREAD 1 | 93 | #define LUA_RIDX_MAINTHREAD 1 |
| 93 | #define LUA_RIDX_CPCALL 2 | 94 | #define LUA_RIDX_GLOBALS 2 |
| 94 | #define LUA_RIDX_GLOBALS 3 | ||
| 95 | #define LUA_RIDX_LAST LUA_RIDX_GLOBALS | 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 | ** basic stack manipulation | 130 | ** basic stack manipulation |
| 131 | */ | 131 | */ |
| 132 | LUA_API int (lua_absindex) (lua_State *L, int idx); | ||
| 132 | LUA_API int (lua_gettop) (lua_State *L); | 133 | LUA_API int (lua_gettop) (lua_State *L); |
| 133 | LUA_API void (lua_settop) (lua_State *L, int idx); | 134 | LUA_API void (lua_settop) (lua_State *L, int idx); |
| 134 | LUA_API void (lua_pushvalue) (lua_State *L, int idx); | 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 | LUA_API void (lua_createtable) (lua_State *L, int narr, int nrec); | 213 | LUA_API void (lua_createtable) (lua_State *L, int narr, int nrec); |
| 213 | LUA_API void *(lua_newuserdata) (lua_State *L, size_t sz); | 214 | LUA_API void *(lua_newuserdata) (lua_State *L, size_t sz); |
| 214 | LUA_API int (lua_getmetatable) (lua_State *L, int objindex); | 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 | LUA_API void (lua_rawset) (lua_State *L, int idx); | 224 | LUA_API void (lua_rawset) (lua_State *L, int idx); |
| 224 | LUA_API void (lua_rawseti) (lua_State *L, int idx, int n); | 225 | LUA_API void (lua_rawseti) (lua_State *L, int idx, int n); |
| 225 | LUA_API int (lua_setmetatable) (lua_State *L, int objindex); | 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 | #define LUA_GCSETPAUSE 6 | 268 | #define LUA_GCSETPAUSE 6 |
| 268 | #define LUA_GCSETSTEPMUL 7 | 269 | #define LUA_GCSETSTEPMUL 7 |
| 269 | #define LUA_GCISRUNNING 8 | 270 | #define LUA_GCISRUNNING 8 |
| 271 | #define LUA_GCGEN 9 | ||
| 272 | #define LUA_GCINC 10 | ||
| 270 | 273 | ||
| 271 | LUA_API int (lua_gc) (lua_State *L, int what, int data); | 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 | #define lua_newtable(L) lua_createtable(L, 0, 0) | 301 | #define lua_newtable(L) lua_createtable(L, 0, 0) |
| 299 | 302 | ||
| 300 | #define lua_setglobal(L,s) lua_setfield(L, LUA_ENVIRONINDEX, (s)) | 303 | #define lua_setglobal(L,s) \ |
| 301 | #define lua_getglobal(L,s) lua_getfield(L, LUA_ENVIRONINDEX, (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) \ | 310 | #define lua_register(L,n,f) (lua_pushcfunction(L, (f)), lua_setglobal(L, (n))) |
| 304 | (lua_pushcfunction(L, (f)), lua_setfield(L, LUA_ENVIRONINDEX, (n))) | ||
| 305 | 311 | ||
| 306 | #define lua_pushcfunction(L,f) lua_pushcclosure(L, (f), 0) | 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 | ** Lua compiler (saves bytecodes to files; also list bytecodes) | 3 | ** Lua compiler (saves bytecodes to files; also list bytecodes) |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -60,7 +60,7 @@ static void usage(const char* message) · 54 unmodified lines | |||
| 60 | " -s strip debug information\n" | 60 | " -s strip debug information\n" |
| 61 | " -v show version information\n" | 61 | " -v show version information\n" |
| 62 | " -- stop handling options\n" | 62 | " -- stop handling options\n" |
| 63 | " - process stdin and stop handling options\n" | 63 | " - stop handling options and process stdin\n" |
| 64 | ,progname,Output); | 64 | ,progname,Output); |
| 65 | exit(EXIT_FAILURE); | 65 | exit(EXIT_FAILURE); |
| 66 | } | 66 | } |
| @@ -89,7 +89,7 @@ static int doargs(int argc, char* argv[]) · 22 unmodified lines | |||
| 89 | else if (IS("-o")) /* output file */ | 89 | else if (IS("-o")) /* output file */ |
| 90 | { | 90 | { |
| 91 | output=argv[++i]; | 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 | if (IS("-")) output=NULL; | 93 | if (IS("-")) output=NULL; |
| 94 | } | 94 | } |
| 95 | else if (IS("-p")) /* parse only */ | 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 | return (fwrite(p,size,1,(FILE*)u)!=1) && (size!=0); | 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 | static int pmain(lua_State* L) | 153 | static int pmain(lua_State* L) |
| 159 | { | 154 | { |
| 160 | struct Smain* s = (struct Smain*)lua_touserdata(L, 1); | 155 | int argc=lua_tointeger(L,1); |
| 161 | int argc=s->argc; | 156 | char** argv=lua_touserdata(L,2); |
| 162 | char** argv=s->argv; | ||
| 163 | const Proto* f; | 157 | const Proto* f; |
| 164 | int i; | 158 | int i; |
| 165 | if (!lua_checkstack(L,argc)) fatal("too many input files"); | 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 | return 0; | 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 | int main(int argc, char* argv[]) | 180 | int main(int argc, char* argv[]) |
| 194 | { | 181 | { |
| 195 | lua_State* L; | 182 | lua_State* L; |
| 196 | struct Smain s; | ||
| 197 | int i=doargs(argc,argv); | 183 | int i=doargs(argc,argv); |
| 198 | argc-=i; argv+=i; | 184 | argc-=i; argv+=i; |
| 199 | if (argc<=0) usage("no input files given"); | 185 | if (argc<=0) usage("no input files given"); |
| 200 | L=luaL_newstate(); | 186 | L=luaL_newstate(); |
| 201 | if (L==NULL) fatal("not enough memory for state"); | 187 | if (L==NULL) fatal("not enough memory for state"); |
| 202 | s.argc=argc; | 188 | lua_pushcfunction(L,&pmain); |
| 203 | s.argv=argv; | 189 | lua_pushinteger(L,argc); |
| 204 | if (lua_cpcall(L,pmain,&s)!=0) fatal(lua_tostring(L,-1)); | 190 | lua_pushlightuserdata(L,argv); |
| 191 | if (lua_pcall(L,2,0,0)!=0) fatal(lua_tostring(L,-1)); | ||
| 205 | lua_close(L); | 192 | lua_close(L); |
| 206 | return EXIT_SUCCESS; | 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 | ** Configuration file for Lua | 3 | ** Configuration file for Lua |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -89,7 +89,7 @@ · 83 unmodified lines | |||
| 89 | #define LUA_CPATH_DEFAULT \ | 89 | #define LUA_CPATH_DEFAULT \ |
| 90 | LUA_CDIR"?.dll;" LUA_CDIR"loadall.dll;" ".\\?.dll" | 90 | LUA_CDIR"?.dll;" LUA_CDIR"loadall.dll;" ".\\?.dll" |
| 91 | 91 | ||
| 92 | #else | 92 | #else /* _WIN32 */ |
| 93 | #define LUA_ROOT "/usr/local/" | 93 | #define LUA_ROOT "/usr/local/" |
| 94 | #define LUA_LDIR LUA_ROOT "share/lua/5.2/" | 94 | #define LUA_LDIR LUA_ROOT "share/lua/5.2/" |
| 95 | #define LUA_CDIR LUA_ROOT "lib/lua/5.2/" | 95 | #define LUA_CDIR LUA_ROOT "lib/lua/5.2/" |
| @@ -98,7 +98,7 @@ · 2 unmodified lines | |||
| 98 | LUA_CDIR"?.lua;" LUA_CDIR"?/init.lua;" "./?.lua" | 98 | LUA_CDIR"?.lua;" LUA_CDIR"?/init.lua;" "./?.lua" |
| 99 | #define LUA_CPATH_DEFAULT \ | 99 | #define LUA_CPATH_DEFAULT \ |
| 100 | LUA_CDIR"?.so;" LUA_CDIR"loadall.so;" "./?.so" | 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 | #define LUA_API __declspec(dllimport) | 130 | #define LUA_API __declspec(dllimport) |
| 131 | #endif | 131 | #endif |
| 132 | 132 | ||
| 133 | #else | 133 | #else /* LUA_BUILD_AS_DLL */ |
| 134 | 134 | ||
| 135 | #define LUA_API extern | 135 | #define LUA_API extern |
| 136 | 136 | ||
| 137 | #endif | 137 | #endif /* LUA_BUILD_AS_DLL */ |
| 138 | |||
| 138 | 139 | ||
| 139 | /* more often than not the libs go together with the core */ | 140 | /* more often than not the libs go together with the core */ |
| 140 | #define LUALIB_API LUA_API | 141 | #define LUALIB_API LUA_API |
| @@ -166,11 +167,11 @@ · 25 unmodified lines | |||
| 166 | #define LUAI_DDEC LUAI_FUNC | 167 | #define LUAI_DDEC LUAI_FUNC |
| 167 | #define LUAI_DDEF /* empty */ | 168 | #define LUAI_DDEF /* empty */ |
| 168 | 169 | ||
| 169 | #else | 170 | #else /* luaall_c */ |
| 170 | #define LUAI_FUNC extern | 171 | #define LUAI_FUNC extern |
| 171 | #define LUAI_DDEC extern | 172 | #define LUAI_DDEC extern |
| 172 | #define LUAI_DDEF /* empty */ | 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 | @@ luai_writestring defines how 'print' prints its results. | 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 | #define luai_writestring(s,l) fwrite((s), sizeof(char), (l), stdout) | 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 | #define LUA_COMPAT_UNPACK | 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 | ** You can replace it with the preregistered function 'cpcall'. | 232 | ** You can replace it with the preregistered function 'cpcall'. |
| 225 | */ | 233 | */ |
| 226 | #define LUA_COMPAT_CPCALL | 234 | #define lua_cpcall(L,f,u) \ |
| 227 | LUA_API int (lua_cpcall) (lua_State *L, lua_CFunction func, void *ud); | 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 | @@ LUA_COMPAT_LOG10 defines the function 'log10' in the math library. | 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 | /* compatibility with previous wrong spelling */ | 269 | /* compatibility with previous wrong spelling */ |
| 268 | #define luaL_typerror luaL_typeerror | 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 | @@ lua_number2int is a macro to convert lua_Number to int. | 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 | @@ lua_number2uint is a macro to convert a lua_Number to an unsigned | 427 | @@ lua_number2uint is a macro to convert a lua_Number to an unsigned |
| 426 | @* LUA_INT32. | 428 | @* LUA_INT32. |
| 427 | @@ lua_uint2number is a macro to convert an unsigned LUA_INT32 | 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 | /* On a Microsoft compiler, use assembler */ | 441 | /* On a Microsoft compiler, use assembler */ |
| 440 | #if defined(_MSC_VER) | 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 | #define lua_number2integer(i,n) lua_number2int(i, n) | 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 | /* the next trick should work on any Pentium, but sometimes clashes | 450 | /* the next trick should work on any Pentium, but sometimes clashes |
| 448 | with a DirectX idiosyncrasy */ | 451 | with a DirectX idiosyncrasy */ |
| 449 | 452 | ||
| 450 | union luai_Cast { double l_d; long l_l; }; | 453 | union luai_Cast { double l_d; long l_l; }; |
| 451 | #define lua_number2int(i,d) \ | 454 | #define lua_number2int(i,n) \ |
| 452 | { volatile union luai_Cast u; u.l_d = (d) + 6755399441055744.0; (i) = u.l_l; } | 455 | { volatile union luai_Cast u; u.l_d = (n) + 6755399441055744.0; (i) = u.l_l; } |
| 453 | #define lua_number2integer(i,n) lua_number2int(i, n) | 456 | #define lua_number2integer(i,n) lua_number2int(i, n) |
| 454 | #define lua_number2uint(i,n) lua_number2int(i, n) | 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 | /* this option always works, but may be slow */ | 463 | /* this option always works, but may be slow */ |
| 461 | #define lua_number2int(i,d) ((i)=(int)(d)) | 464 | #define lua_number2int(i,n) ((i)=(int)(n)) |
| 462 | #define lua_number2integer(i,d) ((i)=(LUA_INTEGER)(d)) | 465 | #define lua_number2integer(i,n) ((i)=(LUA_INTEGER)(n)) |
| 463 | #define lua_number2uint(i,d) ((i)=(unsigned LUA_INT32)(d)) | 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 | /* on several machines, coercion from unsigned to double is too slow, | 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 | #include <float.h> | 486 | #include <float.h> |
| 484 | #include <math.h> | 487 | #include <math.h> |
| 485 | 488 | ||
| 486 | #define luai_hashnum(i,d) { int e; \ | 489 | #define luai_hashnum(i,n) { int e; \ |
| 487 | d = frexp(d, &e) * (lua_Number)(INT_MAX - DBL_MAX_EXP); \ | 490 | n = frexp(n, &e) * (lua_Number)(INT_MAX - DBL_MAX_EXP); \ |
| 488 | lua_number2int(i, d); i += e; } | 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 | ** load precompiled Lua chunks | 3 | ** load precompiled Lua chunks |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -180,7 +180,6 @@ static Proto* LoadFunction(LoadState* S, TString* p) · 174 unmodified lines | |||
| 180 | f->numparams=LoadByte(S); | 180 | f->numparams=LoadByte(S); |
| 181 | f->is_vararg=LoadByte(S); | 181 | f->is_vararg=LoadByte(S); |
| 182 | f->maxstacksize=LoadByte(S); | 182 | f->maxstacksize=LoadByte(S); |
| 183 | f->envreg=LoadByte(S); | ||
| 184 | LoadCode(S,f); | 183 | LoadCode(S,f); |
| 185 | LoadConstants(S,f); | 184 | LoadConstants(S,f); |
| 186 | LoadUpvalues(S,f); | 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 | ** Lua virtual machine | 3 | ** Lua virtual machine |
| 4 | ** See Copyright Notice in lua.h | 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 | else { | 50 | else { |
| 51 | char s[LUAI_MAXNUMBER2STR]; | 51 | char s[LUAI_MAXNUMBER2STR]; |
| 52 | lua_Number n = nvalue(obj); | 52 | lua_Number n = nvalue(obj); |
| 53 | lua_number2str(s, n); | 53 | int l = lua_number2str(s, n); |
| 54 | setsvalue2s(L, obj, luaS_new(L, s)); | 54 | setsvalue2s(L, obj, luaS_newlstr(L, s, l)); |
| 55 | return 1; | 55 | return 1; |
| 56 | } | 56 | } |
| 57 | } | 57 | } |
| @@ -74,6 +74,10 @@ static void traceexec (lua_State *L) { · 16 unmodified lines | |||
| 74 | luaD_hook(L, LUA_HOOKLINE, newline); | 74 | luaD_hook(L, LUA_HOOKLINE, newline); |
| 75 | } | 75 | } |
| 76 | L->oldpc = ci->u.l.savedpc; | 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 | if (ttistable(t)) { /* `t' is a table? */ | 106 | if (ttistable(t)) { /* `t' is a table? */ |
| 103 | Table *h = hvalue(t); | 107 | Table *h = hvalue(t); |
| 104 | const TValue *res = luaH_get(h, key); /* do a primitive get */ | 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 | (tm = fasttm(L, h->metatable, TM_INDEX)) == NULL) { /* or no TM? */ | 110 | (tm = fasttm(L, h->metatable, TM_INDEX)) == NULL) { /* or no TM? */ |
| 107 | setobj2s(L, val, res); | 111 | setobj2s(L, val, res); |
| 108 | return; | 112 | return; |
| @@ -129,7 +133,7 @@ void luaV_settable (lua_State *L, const TValue *t, TValue *key, StkId val) { · 20 unmodified lines | |||
| 129 | if (ttistable(t)) { /* `t' is a table? */ | 133 | if (ttistable(t)) { /* `t' is a table? */ |
| 130 | Table *h = hvalue(t); | 134 | Table *h = hvalue(t); |
| 131 | TValue *oldval = luaH_set(L, h, key); /* do a primitive set */ | 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 | (tm = fasttm(L, h->metatable, TM_NEWINDEX)) == NULL) { /* or no TM? */ | 137 | (tm = fasttm(L, h->metatable, TM_NEWINDEX)) == NULL) { /* or no TM? */ |
| 134 | setobj2t(L, oldval, val); | 138 | setobj2t(L, oldval, val); |
| 135 | luaC_barriert(L, h, val); | 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 | if (ttisnil(tm)) | 161 | if (ttisnil(tm)) |
| 158 | tm = luaT_gettmbyobj(L, p2, event); /* try second operand */ | 162 | tm = luaT_gettmbyobj(L, p2, event); /* try second operand */ |
| 159 | if (ttisnil(tm)) return 0; | 163 | if (ttisnil(tm)) return 0; |
| 164 | if (event == TM_UNM) p2 = luaO_nilobject; | ||
| 160 | callTM(L, tm, p1, p2, res, 1); | 165 | callTM(L, tm, p1, p2, res, 1); |
| 161 | return 1; | 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 | TMS event) { | 171 | TMS event) { |
| 167 | const TValue *tm1 = fasttm(L, mt1, event); | 172 | const TValue *tm1 = fasttm(L, mt1, event); |
| 168 | const TValue *tm2; | 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 | static int call_orderTM (lua_State *L, const TValue *p1, const TValue *p2, | 184 | static int call_orderTM (lua_State *L, const TValue *p1, const TValue *p2, |
| 180 | TMS event) { | 185 | TMS event) { |
| 181 | const TValue *tm1 = luaT_gettmbyobj(L, p1, event); | 186 | if (!call_binTM(L, p1, p2, L->top, event)) |
| 182 | const TValue *tm2; | 187 | return -1; /* no metamethod */ |
| 183 | if (ttisnil(tm1)) return -1; /* no metamethod? */ | 188 | else |
| 184 | tm2 = luaT_gettmbyobj(L, p2, event); | 189 | return !l_isfalse(L->top); |
| 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); | ||
| 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 | int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r) { | 215 | int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r) { |
| 215 | int res; | 216 | int res; |
| 216 | if (ttype(l) != ttype(r)) | 217 | if (ttisnumber(l) && ttisnumber(r)) |
| 217 | return luaG_ordererror(L, l, r); | ||
| 218 | else if (ttisnumber(l)) | ||
| 219 | return luai_numlt(L, nvalue(l), nvalue(r)); | 218 | return luai_numlt(L, nvalue(l), nvalue(r)); |
| 220 | else if (ttisstring(l)) | 219 | else if (ttisstring(l) && ttisstring(r)) |
| 221 | return l_strcmp(rawtsvalue(l), rawtsvalue(r)) < 0; | 220 | return l_strcmp(rawtsvalue(l), rawtsvalue(r)) < 0; |
| 222 | else if ((res = call_orderTM(L, l, r, TM_LT)) != -1) | 221 | else if ((res = call_orderTM(L, l, r, TM_LT)) != -1) |
| 223 | return res; | 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 | int luaV_lessequal (lua_State *L, const TValue *l, const TValue *r) { | 227 | int luaV_lessequal (lua_State *L, const TValue *l, const TValue *r) { |
| 229 | int res; | 228 | int res; |
| 230 | if (ttype(l) != ttype(r)) | 229 | if (ttisnumber(l) && ttisnumber(r)) |
| 231 | return luaG_ordererror(L, l, r); | ||
| 232 | else if (ttisnumber(l)) | ||
| 233 | return luai_numle(L, nvalue(l), nvalue(r)); | 230 | return luai_numle(L, nvalue(l), nvalue(r)); |
| 234 | else if (ttisstring(l)) | 231 | else if (ttisstring(l) && ttisstring(r)) |
| 235 | return l_strcmp(rawtsvalue(l), rawtsvalue(r)) <= 0; | 232 | return l_strcmp(rawtsvalue(l), rawtsvalue(r)) <= 0; |
| 236 | else if ((res = call_orderTM(L, l, r, TM_LE)) != -1) /* first try `le' */ | 233 | else if ((res = call_orderTM(L, l, r, TM_LE)) != -1) /* first try `le' */ |
| 237 | return res; | 234 | return res; |
| @@ -249,14 +246,16 @@ int luaV_equalval_ (lua_State *L, const TValue *t1, const TValue *t2) { · 11 unmodified lines | |||
| 249 | case LUA_TNUMBER: return luai_numeq(nvalue(t1), nvalue(t2)); | 246 | case LUA_TNUMBER: return luai_numeq(nvalue(t1), nvalue(t2)); |
| 250 | case LUA_TBOOLEAN: return bvalue(t1) == bvalue(t2); /* true must be 1 !! */ | 247 | case LUA_TBOOLEAN: return bvalue(t1) == bvalue(t2); /* true must be 1 !! */ |
| 251 | case LUA_TLIGHTUSERDATA: return pvalue(t1) == pvalue(t2); | 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 | case LUA_TUSERDATA: { | 251 | case LUA_TUSERDATA: { |
| 253 | if (uvalue(t1) == uvalue(t2)) return 1; | 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 | break; /* will try TM */ | 254 | break; /* will try TM */ |
| 256 | } | 255 | } |
| 257 | case LUA_TTABLE: { | 256 | case LUA_TTABLE: { |
| 258 | if (hvalue(t1) == hvalue(t2)) return 1; | 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 | break; /* will try TM */ | 259 | break; /* will try TM */ |
| 261 | } | 260 | } |
| 262 | default: return gcvalue(t1) == gcvalue(t2); | 261 | default: return gcvalue(t1) == gcvalue(t2); |
| @@ -354,14 +353,10 @@ void luaV_finishOp (lua_State *L) { · 91 unmodified lines | |||
| 354 | StkId base = ci->u.l.base; | 353 | StkId base = ci->u.l.base; |
| 355 | Instruction inst = *(ci->u.l.savedpc - 1); /* interrupted instruction */ | 354 | Instruction inst = *(ci->u.l.savedpc - 1); /* interrupted instruction */ |
| 356 | OpCode op = GET_OPCODE(inst); | 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 | switch (op) { /* finish its execution */ | 356 | switch (op) { /* finish its execution */ |
| 362 | case OP_ADD: case OP_SUB: case OP_MUL: case OP_DIV: | 357 | case OP_ADD: case OP_SUB: case OP_MUL: case OP_DIV: |
| 363 | case OP_MOD: case OP_POW: case OP_UNM: case OP_LEN: | 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 | setobjs2s(L, base + GETARG_A(inst), --L->top); | 360 | setobjs2s(L, base + GETARG_A(inst), --L->top); |
| 366 | break; | 361 | break; |
| 367 | } | 362 | } |
| @@ -402,7 +397,7 @@ void luaV_finishOp (lua_State *L) { · 34 unmodified lines | |||
| 402 | L->top = ci->top; /* adjust results */ | 397 | L->top = ci->top; /* adjust results */ |
| 403 | break; | 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 | break; | 401 | break; |
| 407 | default: lua_assert(0); | 402 | default: lua_assert(0); |
| 408 | } | 403 | } |
| @@ -426,11 +421,13 @@ void luaV_finishOp (lua_State *L) { · 17 unmodified lines | |||
| 426 | (k + (GETARG_Bx(i) != 0 ? GETARG_Bx(i) - 1 : GETARG_Ax(*ci->u.l.savedpc++))) | 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 | #define Protect(x) { {x;}; base = ci->u.l.base; } | 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 | #define arith_op(op,tm) { \ | 432 | #define arith_op(op,tm) { \ |
| 436 | TValue *rb = RKB(i); \ | 433 | TValue *rb = RKB(i); \ |
| @@ -439,133 +436,109 @@ void luaV_finishOp (lua_State *L) { · 2 unmodified lines | |||
| 439 | lua_Number nb = nvalue(rb), nc = nvalue(rc); \ | 436 | lua_Number nb = nvalue(rb), nc = nvalue(rc); \ |
| 440 | setnvalue(ra, op(L, nb, nc)); \ | 437 | setnvalue(ra, op(L, nb, nc)); \ |
| 441 | } \ | 438 | } \ |
| 442 | else \ | 439 | else { Protect(luaV_arith(L, ra, rb, rc, tm)); } } |
| 443 | Protect(luaV_arith(L, ra, rb, rc, tm)); \ | ||
| 444 | } | ||
| 445 | 440 | ||
| 446 | 441 | ||
| 442 | #define vmdispatch(o) switch(o) | ||
| 443 | #define vmcase(l,b) case l: {b} break; | ||
| 447 | 444 | ||
| 448 | void luaV_execute (lua_State *L) { | 445 | void luaV_execute (lua_State *L) { |
| 449 | CallInfo *ci = L->ci; | 446 | CallInfo *ci = L->ci; |
| 450 | LClosure *cl = &clvalue(ci->func)->l; | 447 | LClosure *cl; |
| 451 | TValue *k = cl->p->k; | 448 | TValue *k; |
| 452 | StkId base = ci->u.l.base; | 449 | StkId base; |
| 450 | newframe: /* reentry point when frame changes (call/return) */ | ||
| 453 | lua_assert(isLua(ci)); | 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 | /* main loop of interpreter */ | 456 | /* main loop of interpreter */ |
| 455 | for (;;) { | 457 | for (;;) { |
| 456 | Instruction i = *(ci->u.l.savedpc++); | 458 | Instruction i = *(ci->u.l.savedpc++); |
| 457 | StkId ra; | 459 | StkId ra; |
| 458 | if ((L->hookmask & (LUA_MASKLINE | LUA_MASKCOUNT)) && | 460 | if ((L->hookmask & (LUA_MASKLINE | LUA_MASKCOUNT)) && |
| 459 | (--L->hookcount == 0 || L->hookmask & LUA_MASKLINE)) { | 461 | (--L->hookcount == 0 || L->hookmask & LUA_MASKLINE)) { |
| 460 | traceexec(L); | 462 | Protect(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; | ||
| 466 | } | 463 | } |
| 467 | /* warning!! several calls may realloc the stack and invalidate `ra' */ | 464 | /* warning!! several calls may realloc the stack and invalidate `ra' */ |
| 468 | ra = RA(i); | 465 | ra = RA(i); |
| 469 | lua_assert(base == ci->u.l.base); | 466 | lua_assert(base == ci->u.l.base); |
| 470 | lua_assert(base <= L->top && L->top < L->stack + L->stacksize); | 467 | lua_assert(base <= L->top && L->top < L->stack + L->stacksize); |
| 471 | switch (GET_OPCODE(i)) { | 468 | vmdispatch (GET_OPCODE(i)) { |
| 472 | case OP_MOVE: { | 469 | vmcase(OP_MOVE, |
| 473 | setobjs2s(L, ra, RB(i)); | 470 | setobjs2s(L, ra, RB(i)); |
| 474 | continue; | 471 | ) |
| 475 | } | 472 | vmcase(OP_LOADK, |
| 476 | case OP_LOADK: { | ||
| 477 | TValue *rb = KBx(i); | 473 | TValue *rb = KBx(i); |
| 478 | setobj2s(L, ra, rb); | 474 | setobj2s(L, ra, rb); |
| 479 | continue; | 475 | ) |
| 480 | } | 476 | vmcase(OP_LOADBOOL, |
| 481 | case OP_LOADBOOL: { | ||
| 482 | setbvalue(ra, GETARG_B(i)); | 477 | setbvalue(ra, GETARG_B(i)); |
| 483 | if (GETARG_C(i)) ci->u.l.savedpc++; /* skip next instruction (if C) */ | 478 | if (GETARG_C(i)) ci->u.l.savedpc++; /* skip next instruction (if C) */ |
| 484 | continue; | 479 | ) |
| 485 | } | 480 | vmcase(OP_LOADNIL, |
| 486 | case OP_LOADNIL: { | ||
| 487 | TValue *rb = RB(i); | 481 | TValue *rb = RB(i); |
| 488 | do { | 482 | do { |
| 489 | setnilvalue(rb--); | 483 | setnilvalue(rb--); |
| 490 | } while (rb >= ra); | 484 | } while (rb >= ra); |
| 491 | continue; | 485 | ) |
| 492 | } | 486 | vmcase(OP_GETUPVAL, |
| 493 | case OP_GETUPVAL: { | ||
| 494 | int b = GETARG_B(i); | 487 | int b = GETARG_B(i); |
| 495 | setobj2s(L, ra, cl->upvals[b]->v); | 488 | setobj2s(L, ra, cl->upvals[b]->v); |
| 496 | continue; | 489 | ) |
| 497 | } | 490 | vmcase(OP_GETTABUP, |
| 498 | case OP_GETGLOBAL: { | 491 | int b = GETARG_B(i); |
| 499 | TValue g; | 492 | Protect(luaV_gettable(L, cl->upvals[b]->v, RKC(i), ra)); |
| 500 | TValue *rb = KBx(i); | 493 | ) |
| 501 | sethvalue(L, &g, cl->env); | 494 | vmcase(OP_GETTABLE, |
| 502 | lua_assert(ttisstring(rb)); | ||
| 503 | Protect(luaV_gettable(L, &g, rb, ra)); | ||
| 504 | continue; | ||
| 505 | } | ||
| 506 | case OP_GETTABLE: { | ||
| 507 | Protect(luaV_gettable(L, RB(i), RKC(i), ra)); | 495 | Protect(luaV_gettable(L, RB(i), RKC(i), ra)); |
| 508 | continue; | 496 | ) |
| 509 | } | 497 | vmcase(OP_SETTABUP, |
| 510 | case OP_SETGLOBAL: { | 498 | int a = GETARG_A(i); |
| 511 | TValue g; | 499 | Protect(luaV_settable(L, cl->upvals[a]->v, RKB(i), RKC(i))); |
| 512 | TValue *rb = KBx(i); | 500 | ) |
| 513 | sethvalue(L, &g, cl->env); | 501 | vmcase(OP_SETUPVAL, |
| 514 | lua_assert(ttisstring(rb)); | ||
| 515 | Protect(luaV_settable(L, &g, rb, ra)); | ||
| 516 | continue; | ||
| 517 | } | ||
| 518 | case OP_SETUPVAL: { | ||
| 519 | UpVal *uv = cl->upvals[GETARG_B(i)]; | 502 | UpVal *uv = cl->upvals[GETARG_B(i)]; |
| 520 | setobj(L, uv->v, ra); | 503 | setobj(L, uv->v, ra); |
| 521 | luaC_barrier(L, uv, ra); | 504 | luaC_barrier(L, uv, ra); |
| 522 | continue; | 505 | ) |
| 523 | } | 506 | vmcase(OP_SETTABLE, |
| 524 | case OP_SETTABLE: { | ||
| 525 | Protect(luaV_settable(L, ra, RKB(i), RKC(i))); | 507 | Protect(luaV_settable(L, ra, RKB(i), RKC(i))); |
| 526 | continue; | 508 | ) |
| 527 | } | 509 | vmcase(OP_NEWTABLE, |
| 528 | case OP_NEWTABLE: { | ||
| 529 | int b = GETARG_B(i); | 510 | int b = GETARG_B(i); |
| 530 | int c = GETARG_C(i); | 511 | int c = GETARG_C(i); |
| 531 | Table *t = luaH_new(L); | 512 | Table *t = luaH_new(L); |
| 532 | sethvalue(L, ra, t); | 513 | sethvalue(L, ra, t); |
| 533 | if (b != 0 || c != 0) | 514 | if (b != 0 || c != 0) |
| 534 | luaH_resize(L, t, luaO_fb2int(b), luaO_fb2int(c)); | 515 | luaH_resize(L, t, luaO_fb2int(b), luaO_fb2int(c)); |
| 535 | Protect(luaC_checkGC(L)); | 516 | checkGC(L); |
| 536 | continue; | 517 | ) |
| 537 | } | 518 | vmcase(OP_SELF, |
| 538 | case OP_SELF: { | ||
| 539 | StkId rb = RB(i); | 519 | StkId rb = RB(i); |
| 540 | setobjs2s(L, ra+1, rb); | 520 | setobjs2s(L, ra+1, rb); |
| 541 | Protect(luaV_gettable(L, rb, RKC(i), ra)); | 521 | Protect(luaV_gettable(L, rb, RKC(i), ra)); |
| 542 | continue; | 522 | ) |
| 543 | } | 523 | vmcase(OP_ADD, |
| 544 | case OP_ADD: { | ||
| 545 | arith_op(luai_numadd, TM_ADD); | 524 | arith_op(luai_numadd, TM_ADD); |
| 546 | continue; | 525 | ) |
| 547 | } | 526 | vmcase(OP_SUB, |
| 548 | case OP_SUB: { | ||
| 549 | arith_op(luai_numsub, TM_SUB); | 527 | arith_op(luai_numsub, TM_SUB); |
| 550 | continue; | 528 | ) |
| 551 | } | 529 | vmcase(OP_MUL, |
| 552 | case OP_MUL: { | ||
| 553 | arith_op(luai_nummul, TM_MUL); | 530 | arith_op(luai_nummul, TM_MUL); |
| 554 | continue; | 531 | ) |
| 555 | } | 532 | vmcase(OP_DIV, |
| 556 | case OP_DIV: { | ||
| 557 | arith_op(luai_numdiv, TM_DIV); | 533 | arith_op(luai_numdiv, TM_DIV); |
| 558 | continue; | 534 | ) |
| 559 | } | 535 | vmcase(OP_MOD, |
| 560 | case OP_MOD: { | ||
| 561 | arith_op(luai_nummod, TM_MOD); | 536 | arith_op(luai_nummod, TM_MOD); |
| 562 | continue; | 537 | ) |
| 563 | } | 538 | vmcase(OP_POW, |
| 564 | case OP_POW: { | ||
| 565 | arith_op(luai_numpow, TM_POW); | 539 | arith_op(luai_numpow, TM_POW); |
| 566 | continue; | 540 | ) |
| 567 | } | 541 | vmcase(OP_UNM, |
| 568 | case OP_UNM: { | ||
| 569 | TValue *rb = RB(i); | 542 | TValue *rb = RB(i); |
| 570 | if (ttisnumber(rb)) { | 543 | if (ttisnumber(rb)) { |
| 571 | lua_Number nb = nvalue(rb); | 544 | lua_Number nb = nvalue(rb); |
| @@ -574,31 +547,26 @@ void luaV_execute (lua_State *L) { · 2 unmodified lines | |||
| 574 | else { | 547 | else { |
| 575 | Protect(luaV_arith(L, ra, rb, rb, TM_UNM)); | 548 | Protect(luaV_arith(L, ra, rb, rb, TM_UNM)); |
| 576 | } | 549 | } |
| 577 | continue; | 550 | ) |
| 578 | } | 551 | vmcase(OP_NOT, |
| 579 | case OP_NOT: { | ||
| 580 | int res = l_isfalse(RB(i)); /* next assignment may change this value */ | 552 | int res = l_isfalse(RB(i)); /* next assignment may change this value */ |
| 581 | setbvalue(ra, res); | 553 | setbvalue(ra, res); |
| 582 | continue; | 554 | ) |
| 583 | } | 555 | vmcase(OP_LEN, |
| 584 | case OP_LEN: { | ||
| 585 | Protect(luaV_objlen(L, ra, RB(i))); | 556 | Protect(luaV_objlen(L, ra, RB(i))); |
| 586 | continue; | 557 | ) |
| 587 | } | 558 | vmcase(OP_CONCAT, |
| 588 | case OP_CONCAT: { | ||
| 589 | int b = GETARG_B(i); | 559 | int b = GETARG_B(i); |
| 590 | int c = GETARG_C(i); | 560 | int c = GETARG_C(i); |
| 591 | L->top = base + c + 1; /* mark the end of concat operands */ | 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 | L->top = ci->top; /* restore top */ | 563 | L->top = ci->top; /* restore top */ |
| 594 | setobjs2s(L, RA(i), base+b); | 564 | setobjs2s(L, RA(i), base+b); |
| 595 | continue; | 565 | ) |
| 596 | } | 566 | vmcase(OP_JMP, |
| 597 | case OP_JMP: { | ||
| 598 | dojump(GETARG_sBx(i)); | 567 | dojump(GETARG_sBx(i)); |
| 599 | continue; | 568 | ) |
| 600 | } | 569 | vmcase(OP_EQ, |
| 601 | case OP_EQ: { | ||
| 602 | TValue *rb = RKB(i); | 570 | TValue *rb = RKB(i); |
| 603 | TValue *rc = RKC(i); | 571 | TValue *rc = RKC(i); |
| 604 | Protect( | 572 | Protect( |
| @@ -606,62 +574,54 @@ void luaV_execute (lua_State *L) { · 1 unmodified line | |||
| 606 | dojump(GETARG_sBx(*ci->u.l.savedpc)); | 574 | dojump(GETARG_sBx(*ci->u.l.savedpc)); |
| 607 | ) | 575 | ) |
| 608 | ci->u.l.savedpc++; | 576 | ci->u.l.savedpc++; |
| 609 | continue; | 577 | ) |
| 610 | } | 578 | vmcase(OP_LT, |
| 611 | case OP_LT: { | ||
| 612 | Protect( | 579 | Protect( |
| 613 | if (luaV_lessthan(L, RKB(i), RKC(i)) == GETARG_A(i)) | 580 | if (luaV_lessthan(L, RKB(i), RKC(i)) == GETARG_A(i)) |
| 614 | dojump(GETARG_sBx(*ci->u.l.savedpc)); | 581 | dojump(GETARG_sBx(*ci->u.l.savedpc)); |
| 615 | ) | 582 | ) |
| 616 | ci->u.l.savedpc++; | 583 | ci->u.l.savedpc++; |
| 617 | continue; | 584 | ) |
| 618 | } | 585 | vmcase(OP_LE, |
| 619 | case OP_LE: { | ||
| 620 | Protect( | 586 | Protect( |
| 621 | if (luaV_lessequal(L, RKB(i), RKC(i)) == GETARG_A(i)) | 587 | if (luaV_lessequal(L, RKB(i), RKC(i)) == GETARG_A(i)) |
| 622 | dojump(GETARG_sBx(*ci->u.l.savedpc)); | 588 | dojump(GETARG_sBx(*ci->u.l.savedpc)); |
| 623 | ) | 589 | ) |
| 624 | ci->u.l.savedpc++; | 590 | ci->u.l.savedpc++; |
| 625 | continue; | 591 | ) |
| 626 | } | 592 | vmcase(OP_TEST, |
| 627 | case OP_TEST: { | ||
| 628 | if (GETARG_C(i) ? !l_isfalse(ra) : l_isfalse(ra)) | 593 | if (GETARG_C(i) ? !l_isfalse(ra) : l_isfalse(ra)) |
| 629 | dojump(GETARG_sBx(*ci->u.l.savedpc)); | 594 | dojump(GETARG_sBx(*ci->u.l.savedpc)); |
| 630 | ci->u.l.savedpc++; | 595 | ci->u.l.savedpc++; |
| 631 | continue; | 596 | ) |
| 632 | } | 597 | vmcase(OP_TESTSET, |
| 633 | case OP_TESTSET: { | ||
| 634 | TValue *rb = RB(i); | 598 | TValue *rb = RB(i); |
| 635 | if (GETARG_C(i) ? !l_isfalse(rb) : l_isfalse(rb)) { | 599 | if (GETARG_C(i) ? !l_isfalse(rb) : l_isfalse(rb)) { |
| 636 | setobjs2s(L, ra, rb); | 600 | setobjs2s(L, ra, rb); |
| 637 | dojump(GETARG_sBx(*ci->u.l.savedpc)); | 601 | dojump(GETARG_sBx(*ci->u.l.savedpc)); |
| 638 | } | 602 | } |
| 639 | ci->u.l.savedpc++; | 603 | ci->u.l.savedpc++; |
| 640 | continue; | 604 | ) |
| 641 | } | 605 | vmcase(OP_CALL, |
| 642 | case OP_CALL: { | ||
| 643 | int b = GETARG_B(i); | 606 | int b = GETARG_B(i); |
| 644 | int nresults = GETARG_C(i) - 1; | 607 | int nresults = GETARG_C(i) - 1; |
| 645 | if (b != 0) L->top = ra+b; /* else previous instruction set top */ | 608 | if (b != 0) L->top = ra+b; /* else previous instruction set top */ |
| 646 | if (luaD_precall(L, ra, nresults)) { /* C function? */ | 609 | if (luaD_precall(L, ra, nresults)) { /* C function? */ |
| 647 | if (nresults >= 0) L->top = ci->top; /* adjust results */ | 610 | if (nresults >= 0) L->top = ci->top; /* adjust results */ |
| 648 | base = ci->u.l.base; | 611 | base = ci->u.l.base; |
| 649 | continue; | ||
| 650 | } | 612 | } |
| 651 | else { /* Lua function */ | 613 | else { /* Lua function */ |
| 652 | ci = L->ci; | 614 | ci = L->ci; |
| 653 | ci->callstatus |= CIST_REENTRY; | 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 | } | 618 | ) |
| 657 | case OP_TAILCALL: { | 619 | vmcase(OP_TAILCALL, |
| 658 | int b = GETARG_B(i); | 620 | int b = GETARG_B(i); |
| 659 | if (b != 0) L->top = ra+b; /* else previous instruction set top */ | 621 | if (b != 0) L->top = ra+b; /* else previous instruction set top */ |
| 660 | lua_assert(GETARG_C(i) - 1 == LUA_MULTRET); | 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 | base = ci->u.l.base; | 624 | base = ci->u.l.base; |
| 663 | continue; | ||
| 664 | } | ||
| 665 | else { | 625 | else { |
| 666 | /* tail call: put called frame (n) in place of caller one (o) */ | 626 | /* tail call: put called frame (n) in place of caller one (o) */ |
| 667 | CallInfo *nci = L->ci; /* called frame */ | 627 | CallInfo *nci = L->ci; /* called frame */ |
| @@ -682,10 +642,10 @@ void luaV_execute (lua_State *L) { · 14 unmodified lines | |||
| 682 | oci->callstatus |= CIST_TAIL; /* function was tail called */ | 642 | oci->callstatus |= CIST_TAIL; /* function was tail called */ |
| 683 | ci = L->ci = oci; /* remove new frame */ | 643 | ci = L->ci = oci; /* remove new frame */ |
| 684 | lua_assert(L->top == oci->u.l.base + getproto(ofunc)->maxstacksize); | 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 | } | 647 | ) |
| 688 | case OP_RETURN: { | 648 | vmcase(OP_RETURN, |
| 689 | int b = GETARG_B(i); | 649 | int b = GETARG_B(i); |
| 690 | if (b != 0) L->top = ra+b-1; | 650 | if (b != 0) L->top = ra+b-1; |
| 691 | if (cl->p->sizep > 0) luaF_close(L, base); | 651 | if (cl->p->sizep > 0) luaF_close(L, base); |
| @@ -697,10 +657,10 @@ void luaV_execute (lua_State *L) { · 5 unmodified lines | |||
| 697 | if (b) L->top = ci->top; | 657 | if (b) L->top = ci->top; |
| 698 | lua_assert(isLua(ci)); | 658 | lua_assert(isLua(ci)); |
| 699 | lua_assert(GET_OPCODE(*((ci)->u.l.savedpc - 1)) == OP_CALL); | 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 | } | 662 | ) |
| 703 | case OP_FORLOOP: { | 663 | vmcase(OP_FORLOOP, |
| 704 | lua_Number step = nvalue(ra+2); | 664 | lua_Number step = nvalue(ra+2); |
| 705 | lua_Number idx = luai_numadd(L, nvalue(ra), step); /* increment index */ | 665 | lua_Number idx = luai_numadd(L, nvalue(ra), step); /* increment index */ |
| 706 | lua_Number limit = nvalue(ra+1); | 666 | lua_Number limit = nvalue(ra+1); |
| @@ -710,9 +670,8 @@ void luaV_execute (lua_State *L) { · 3 unmodified lines | |||
| 710 | setnvalue(ra, idx); /* update internal index... */ | 670 | setnvalue(ra, idx); /* update internal index... */ |
| 711 | setnvalue(ra+3, idx); /* ...and external index */ | 671 | setnvalue(ra+3, idx); /* ...and external index */ |
| 712 | } | 672 | } |
| 713 | continue; | 673 | ) |
| 714 | } | 674 | vmcase(OP_FORPREP, |
| 715 | case OP_FORPREP: { | ||
| 716 | const TValue *init = ra; | 675 | const TValue *init = ra; |
| 717 | const TValue *plimit = ra+1; | 676 | const TValue *plimit = ra+1; |
| 718 | const TValue *pstep = ra+2; | 677 | const TValue *pstep = ra+2; |
| @@ -724,9 +683,8 @@ void luaV_execute (lua_State *L) { · 5 unmodified lines | |||
| 724 | luaG_runerror(L, LUA_QL("for") " step must be a number"); | 683 | luaG_runerror(L, LUA_QL("for") " step must be a number"); |
| 725 | setnvalue(ra, luai_numsub(L, nvalue(ra), nvalue(pstep))); | 684 | setnvalue(ra, luai_numsub(L, nvalue(ra), nvalue(pstep))); |
| 726 | dojump(GETARG_sBx(i)); | 685 | dojump(GETARG_sBx(i)); |
| 727 | continue; | 686 | ) |
| 728 | } | 687 | vmcase(OP_TFORCALL, |
| 729 | case OP_TFORCALL: { | ||
| 730 | StkId cb = ra + 3; /* call base */ | 688 | StkId cb = ra + 3; /* call base */ |
| 731 | setobjs2s(L, cb+2, ra+2); | 689 | setobjs2s(L, cb+2, ra+2); |
| 732 | setobjs2s(L, cb+1, ra+1); | 690 | setobjs2s(L, cb+1, ra+1); |
| @@ -737,16 +695,16 @@ void luaV_execute (lua_State *L) { · 4 unmodified lines | |||
| 737 | i = *(ci->u.l.savedpc++); /* go to next instruction */ | 695 | i = *(ci->u.l.savedpc++); /* go to next instruction */ |
| 738 | ra = RA(i); | 696 | ra = RA(i); |
| 739 | lua_assert(GET_OPCODE(i) == OP_TFORLOOP); | 697 | lua_assert(GET_OPCODE(i) == OP_TFORLOOP); |
| 740 | /* go through */ | 698 | goto l_tforloop; |
| 741 | } | 699 | ) |
| 742 | case OP_TFORLOOP: { | 700 | vmcase(OP_TFORLOOP, |
| 701 | l_tforloop: | ||
| 743 | if (!ttisnil(ra + 1)) { /* continue loop? */ | 702 | if (!ttisnil(ra + 1)) { /* continue loop? */ |
| 744 | setobjs2s(L, ra, ra + 1); /* save control variable */ | 703 | setobjs2s(L, ra, ra + 1); /* save control variable */ |
| 745 | dojump(GETARG_sBx(i)); /* jump back */ | 704 | dojump(GETARG_sBx(i)); /* jump back */ |
| 746 | } | 705 | } |
| 747 | continue; | 706 | ) |
| 748 | } | 707 | vmcase(OP_SETLIST, |
| 749 | case OP_SETLIST: { | ||
| 750 | int n = GETARG_B(i); | 708 | int n = GETARG_B(i); |
| 751 | int c = GETARG_C(i); | 709 | int c = GETARG_C(i); |
| 752 | int last; | 710 | int last; |
| @@ -759,45 +717,34 @@ void luaV_execute (lua_State *L) { · 6 unmodified lines | |||
| 759 | h = hvalue(ra); | 717 | h = hvalue(ra); |
| 760 | last = ((c-1)*LFIELDS_PER_FLUSH) + n; | 718 | last = ((c-1)*LFIELDS_PER_FLUSH) + n; |
| 761 | if (last > h->sizearray) /* needs more space? */ | 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 | for (; n > 0; n--) { | 721 | for (; n > 0; n--) { |
| 764 | TValue *val = ra+n; | 722 | TValue *val = ra+n; |
| 765 | setobj2t(L, luaH_setint(L, h, last--), val); | 723 | setobj2t(L, luaH_setint(L, h, last--), val); |
| 766 | luaC_barriert(L, h, val); | 724 | luaC_barriert(L, h, val); |
| 767 | } | 725 | } |
| 768 | L->top = ci->top; /* correct top (in case of previous open call) */ | 726 | L->top = ci->top; /* correct top (in case of previous open call) */ |
| 769 | continue; | 727 | ) |
| 770 | } | 728 | vmcase(OP_CLOSE, |
| 771 | case OP_CLOSE: { | ||
| 772 | luaF_close(L, ra); | 729 | luaF_close(L, ra); |
| 773 | continue; | 730 | ) |
| 774 | } | 731 | vmcase(OP_CLOSURE, |
| 775 | case OP_CLOSURE: { | ||
| 776 | Proto *p = cl->p->p[GETARG_Bx(i)]; /* prototype for new closure */ | 732 | Proto *p = cl->p->p[GETARG_Bx(i)]; /* prototype for new closure */ |
| 777 | int nup = p->sizeupvalues; | 733 | int nup = p->sizeupvalues; |
| 778 | Closure *ncl = luaF_newLclosure(L, nup, cl->env); | 734 | Closure *ncl = luaF_newLclosure(L, nup); |
| 779 | Upvaldesc *uv = p->upvalues; | 735 | Upvaldesc *uv = p->upvalues; |
| 780 | int j; | 736 | int j; |
| 781 | ncl->l.p = p; | 737 | ncl->l.p = p; |
| 782 | setclvalue(L, ra, ncl); /* anchor new closure in stack */ | 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 | for (j = 0; j < nup; j++) { /* fill in upvalues */ | 739 | for (j = 0; j < nup; j++) { /* fill in upvalues */ |
| 792 | if (uv[j].instack) /* upvalue refers to local variable? */ | 740 | if (uv[j].instack) /* upvalue refers to local variable? */ |
| 793 | ncl->l.upvals[j] = luaF_findupval(L, base + uv[j].idx); | 741 | ncl->l.upvals[j] = luaF_findupval(L, base + uv[j].idx); |
| 794 | else /* get upvalue from enclosing function */ | 742 | else /* get upvalue from enclosing function */ |
| 795 | ncl->l.upvals[j] = cl->upvals[uv[j].idx]; | 743 | ncl->l.upvals[j] = cl->upvals[uv[j].idx]; |
| 796 | } | 744 | } |
| 797 | Protect(luaC_checkGC(L)); | 745 | checkGC(L); |
| 798 | continue; | 746 | ) |
| 799 | } | 747 | vmcase(OP_VARARG, |
| 800 | case OP_VARARG: { | ||
| 801 | int b = GETARG_B(i) - 1; | 748 | int b = GETARG_B(i) - 1; |
| 802 | int j; | 749 | int j; |
| 803 | int n = cast_int(base - ci->func) - cl->p->numparams - 1; | 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 | setnilvalue(ra + j); | 762 | setnilvalue(ra + j); |
| 816 | } | 763 | } |
| 817 | } | 764 | } |
| 818 | continue; | 765 | ) |
| 819 | } | 766 | vmcase(OP_EXTRAARG, |
| 820 | case OP_EXTRAARG: { | 767 | lua_assert(0); |
| 821 | luaG_runerror(L, "bad opcode"); | 768 | ) |
| 822 | return; | ||
| 823 | } | ||
| 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 | ** print bytecodes | 3 | ** print bytecodes |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -82,6 +82,7 @@ static void PrintCode(const Proto* f) · 76 unmodified lines | |||
| 82 | int a=GETARG_A(i); | 82 | int a=GETARG_A(i); |
| 83 | int b=GETARG_B(i); | 83 | int b=GETARG_B(i); |
| 84 | int c=GETARG_C(i); | 84 | int c=GETARG_C(i); |
| 85 | int ax=GETARG_Ax(i); | ||
| 85 | int bx=GETARG_Bx(i); | 86 | int bx=GETARG_Bx(i); |
| 86 | int sbx=GETARG_sBx(i); | 87 | int sbx=GETARG_sBx(i); |
| 87 | int line=getfuncline(f,pc); | 88 | int line=getfuncline(f,pc); |
| @@ -99,24 +100,32 @@ static void PrintCode(const Proto* f) · 11 unmodified lines | |||
| 99 | if (getCMode(o)!=OpArgN) printf(" %d",ISK(c) ? (-1-INDEXK(c)) : c); | 100 | if (getCMode(o)!=OpArgN) printf(" %d",ISK(c) ? (-1-INDEXK(c)) : c); |
| 100 | break; | 101 | break; |
| 101 | case iABx: | 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 | break; | 104 | break; |
| 104 | case iAsBx: | 105 | case iAsBx: |
| 105 | if (o==OP_JMP) printf("%d",sbx); else printf("%d %d",a,sbx); | 106 | if (o==OP_JMP) printf("%d",sbx); else printf("%d %d",a,sbx); |
| 106 | break; | 107 | break; |
| 108 | case iAx: | ||
| 109 | printf("%d",ax); | ||
| 110 | break; | ||
| 107 | } | 111 | } |
| 108 | switch (o) | 112 | switch (o) |
| 109 | { | 113 | { |
| 110 | case OP_LOADK: | 114 | case OP_LOADK: |
| 111 | printf("\t; "); PrintConstant(f,bx); | 115 | printf("\t; "); PrintConstant(f,bx-1); |
| 112 | break; | 116 | break; |
| 113 | case OP_GETUPVAL: | 117 | case OP_GETUPVAL: |
| 114 | case OP_SETUPVAL: | 118 | case OP_SETUPVAL: |
| 115 | printf("\t; %s", (f->sizeupvalues>0) ? getstr(f->upvalues[b].name) : "-"); | 119 | printf("\t; %s", (f->sizeupvalues>0) ? getstr(f->upvalues[b].name) : "-"); |
| 116 | break; | 120 | break; |
| 117 | case OP_GETGLOBAL: | 121 | case OP_GETTABUP: |
| 118 | case OP_SETGLOBAL: | 122 | printf("\t; %s", (f->sizeupvalues>0) ? getstr(f->upvalues[b].name) : "-"); |
| 119 | printf("\t; %s",svalue(&f->k[bx])); | 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 | break; | 129 | break; |
| 121 | case OP_GETTABLE: | 130 | case OP_GETTABLE: |
| 122 | case OP_SELF: | 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 | ||