Unified · Split
| @@ -1,5 +1,5 @@ | |||
| 1 | 1 | ||
| 2 | This is Lua 5.2 (alpha), released on 23 Nov 2010. | 2 | This is Lua 5.2 (beta), released on 13 Jun 2011. |
| 3 | 3 | ||
| 4 | For installation instructions, license details, and | 4 | For installation instructions, license details, and |
| 5 | further information about Lua, see doc/readme.html. | 5 | further information about Lua, see doc/readme.html. |
| @@ -22,7 +22,7 @@ Lua 5.2 Reference Manual · 21 unmodified lines | |||
| 22 | 22 | ||
| 23 | <P> | 23 | <P> |
| 24 | <IMG SRC="alert.png" ALIGN="absbottom" ALT="[!]"> | 24 | <IMG SRC="alert.png" ALIGN="absbottom" ALT="[!]"> |
| 25 | <EM>This is an alpha version of Lua 5.2. | 25 | <EM>This is a beta version of Lua 5.2. |
| 26 | Some details may change in the final version.</EM> | 26 | Some details may change in the final version.</EM> |
| 27 | 27 | ||
| 28 | <P> | 28 | <P> |
| @@ -38,7 +38,7 @@ For a complete introduction to Lua programming, see the book · 9 unmodified lines | |||
| 38 | <A HREF="#index">index</A> | 38 | <A HREF="#index">index</A> |
| 39 | <HR> | 39 | <HR> |
| 40 | <SMALL> | 40 | <SMALL> |
| 41 | Copyright © 2010 Lua.org, PUC-Rio. | 41 | Copyright © 2011 Lua.org, PUC-Rio. |
| 42 | Freely available under the terms of the | 42 | Freely available under the terms of the |
| 43 | <a href="http://www.lua.org/license.html#5">Lua license</a>. | 43 | <a href="http://www.lua.org/license.html#5">Lua license</a>. |
| 44 | </SMALL> | 44 | </SMALL> |
| @@ -120,7 +120,7 @@ Freely available under the terms of the · 75 unmodified lines | |||
| 120 | </UL> | 120 | </UL> |
| 121 | <LI><A HREF="manual.html#6.5">6.5 – Table Manipulation</A> | 121 | <LI><A HREF="manual.html#6.5">6.5 – Table Manipulation</A> |
| 122 | <LI><A HREF="manual.html#6.6">6.6 – Mathematical Functions</A> | 122 | <LI><A HREF="manual.html#6.6">6.6 – Mathematical Functions</A> |
| 123 | <LI><A HREF="manual.html#6.7">6.7 – Bitwise operations</A> | 123 | <LI><A HREF="manual.html#6.7">6.7 – Bitwise Operations</A> |
| 124 | <LI><A HREF="manual.html#6.8">6.8 – Input and Output Facilities</A> | 124 | <LI><A HREF="manual.html#6.8">6.8 – Input and Output Facilities</A> |
| 125 | <LI><A HREF="manual.html#6.9">6.9 – Operating System Facilities</A> | 125 | <LI><A HREF="manual.html#6.9">6.9 – Operating System Facilities</A> |
| 126 | <LI><A HREF="manual.html#6.10">6.10 – The Debug Library</A> | 126 | <LI><A HREF="manual.html#6.10">6.10 – The Debug Library</A> |
| @@ -154,14 +154,13 @@ Freely available under the terms of the · 27 unmodified lines | |||
| 154 | <A HREF="manual.html#pdf-ipairs">ipairs</A><BR> | 154 | <A HREF="manual.html#pdf-ipairs">ipairs</A><BR> |
| 155 | <A HREF="manual.html#pdf-load">load</A><BR> | 155 | <A HREF="manual.html#pdf-load">load</A><BR> |
| 156 | <A HREF="manual.html#pdf-loadfile">loadfile</A><BR> | 156 | <A HREF="manual.html#pdf-loadfile">loadfile</A><BR> |
| 157 | <A HREF="manual.html#pdf-loadin">loadin</A><BR> | ||
| 158 | <A HREF="manual.html#pdf-loadstring">loadstring</A><BR> | ||
| 159 | <A HREF="manual.html#pdf-next">next</A><BR> | 157 | <A HREF="manual.html#pdf-next">next</A><BR> |
| 160 | <A HREF="manual.html#pdf-pairs">pairs</A><BR> | 158 | <A HREF="manual.html#pdf-pairs">pairs</A><BR> |
| 161 | <A HREF="manual.html#pdf-pcall">pcall</A><BR> | 159 | <A HREF="manual.html#pdf-pcall">pcall</A><BR> |
| 162 | <A HREF="manual.html#pdf-print">print</A><BR> | 160 | <A HREF="manual.html#pdf-print">print</A><BR> |
| 163 | <A HREF="manual.html#pdf-rawequal">rawequal</A><BR> | 161 | <A HREF="manual.html#pdf-rawequal">rawequal</A><BR> |
| 164 | <A HREF="manual.html#pdf-rawget">rawget</A><BR> | 162 | <A HREF="manual.html#pdf-rawget">rawget</A><BR> |
| 163 | <A HREF="manual.html#pdf-rawlen">rawlen</A><BR> | ||
| 165 | <A HREF="manual.html#pdf-rawset">rawset</A><BR> | 164 | <A HREF="manual.html#pdf-rawset">rawset</A><BR> |
| 166 | <A HREF="manual.html#pdf-require">require</A><BR> | 165 | <A HREF="manual.html#pdf-require">require</A><BR> |
| 167 | <A HREF="manual.html#pdf-select">select</A><BR> | 166 | <A HREF="manual.html#pdf-select">select</A><BR> |
| @@ -178,8 +177,10 @@ Freely available under the terms of the · 10 unmodified lines | |||
| 178 | <A HREF="manual.html#pdf-bit32.bor">bit32.bor</A><BR> | 177 | <A HREF="manual.html#pdf-bit32.bor">bit32.bor</A><BR> |
| 179 | <A HREF="manual.html#pdf-bit32.btest">bit32.btest</A><BR> | 178 | <A HREF="manual.html#pdf-bit32.btest">bit32.btest</A><BR> |
| 180 | <A HREF="manual.html#pdf-bit32.bxor">bit32.bxor</A><BR> | 179 | <A HREF="manual.html#pdf-bit32.bxor">bit32.bxor</A><BR> |
| 180 | <A HREF="manual.html#pdf-bit32.extract">bit32.extract</A><BR> | ||
| 181 | <A HREF="manual.html#pdf-bit32.lrotate">bit32.lrotate</A><BR> | 181 | <A HREF="manual.html#pdf-bit32.lrotate">bit32.lrotate</A><BR> |
| 182 | <A HREF="manual.html#pdf-bit32.lshift">bit32.lshift</A><BR> | 182 | <A HREF="manual.html#pdf-bit32.lshift">bit32.lshift</A><BR> |
| 183 | <A HREF="manual.html#pdf-bit32.replace">bit32.replace</A><BR> | ||
| 183 | <A HREF="manual.html#pdf-bit32.rrotate">bit32.rrotate</A><BR> | 184 | <A HREF="manual.html#pdf-bit32.rrotate">bit32.rrotate</A><BR> |
| 184 | <A HREF="manual.html#pdf-bit32.rshift">bit32.rshift</A><BR> | 185 | <A HREF="manual.html#pdf-bit32.rshift">bit32.rshift</A><BR> |
| 185 | 186 | ||
| @@ -475,15 +476,18 @@ Freely available under the terms of the · 289 unmodified lines | |||
| 475 | <A HREF="manual.html#luaL_dofile">luaL_dofile</A><BR> | 476 | <A HREF="manual.html#luaL_dofile">luaL_dofile</A><BR> |
| 476 | <A HREF="manual.html#luaL_dostring">luaL_dostring</A><BR> | 477 | <A HREF="manual.html#luaL_dostring">luaL_dostring</A><BR> |
| 477 | <A HREF="manual.html#luaL_error">luaL_error</A><BR> | 478 | <A HREF="manual.html#luaL_error">luaL_error</A><BR> |
| 478 | <A HREF="manual.html#luaL_findtable">luaL_findtable</A><BR> | 479 | <A HREF="manual.html#luaL_execresult">luaL_execresult</A><BR> |
| 480 | <A HREF="manual.html#luaL_fileresult">luaL_fileresult</A><BR> | ||
| 479 | <A HREF="manual.html#luaL_getmetafield">luaL_getmetafield</A><BR> | 481 | <A HREF="manual.html#luaL_getmetafield">luaL_getmetafield</A><BR> |
| 480 | <A HREF="manual.html#luaL_getmetatable">luaL_getmetatable</A><BR> | 482 | <A HREF="manual.html#luaL_getmetatable">luaL_getmetatable</A><BR> |
| 483 | <A HREF="manual.html#luaL_getsubtable">luaL_getsubtable</A><BR> | ||
| 481 | <A HREF="manual.html#luaL_gsub">luaL_gsub</A><BR> | 484 | <A HREF="manual.html#luaL_gsub">luaL_gsub</A><BR> |
| 482 | <A HREF="manual.html#luaL_len">luaL_len</A><BR> | 485 | <A HREF="manual.html#luaL_len">luaL_len</A><BR> |
| 483 | <A HREF="manual.html#luaL_loadbuffer">luaL_loadbuffer</A><BR> | 486 | <A HREF="manual.html#luaL_loadbuffer">luaL_loadbuffer</A><BR> |
| 484 | <A HREF="manual.html#luaL_loadfile">luaL_loadfile</A><BR> | 487 | <A HREF="manual.html#luaL_loadfile">luaL_loadfile</A><BR> |
| 485 | <A HREF="manual.html#luaL_loadstring">luaL_loadstring</A><BR> | 488 | <A HREF="manual.html#luaL_loadstring">luaL_loadstring</A><BR> |
| 486 | <A HREF="manual.html#luaL_newlib">luaL_newlib</A><BR> | 489 | <A HREF="manual.html#luaL_newlib">luaL_newlib</A><BR> |
| 490 | <A HREF="manual.html#luaL_newlibtable">luaL_newlibtable</A><BR> | ||
| 487 | <A HREF="manual.html#luaL_newmetatable">luaL_newmetatable</A><BR> | 491 | <A HREF="manual.html#luaL_newmetatable">luaL_newmetatable</A><BR> |
| 488 | <A HREF="manual.html#luaL_newstate">luaL_newstate</A><BR> | 492 | <A HREF="manual.html#luaL_newstate">luaL_newstate</A><BR> |
| 489 | <A HREF="manual.html#luaL_openlibs">luaL_openlibs</A><BR> | 493 | <A HREF="manual.html#luaL_openlibs">luaL_openlibs</A><BR> |
| @@ -516,10 +520,10 @@ Freely available under the terms of the · 26 unmodified lines | |||
| 516 | <HR> | 520 | <HR> |
| 517 | <SMALL> | 521 | <SMALL> |
| 518 | Last update: | 522 | Last update: |
| 519 | Mon Nov 22 16:38:54 BRST 2010 | 523 | Mon Jun 13 15:09:33 BRT 2011 |
| 520 | </SMALL> | 524 | </SMALL> |
| 521 | <!-- | 525 | <!-- |
| 522 | Last change: revised for Lua 5.2.0 (alpha) | 526 | Last change: revised for Lua 5.2.0 (beta) |
| 523 | --> | 527 | --> |
| 524 | 528 | ||
| 525 | </BODY> | 529 | </BODY> |
| @@ -8,6 +8,7 @@ body { · 7 unmodified lines | |||
| 8 | } | 8 | } |
| 9 | 9 | ||
| 10 | h1, h2, h3, h4 { | 10 | h1, h2, h3, h4 { |
| 11 | font-family: Verdana, sans-serif ; | ||
| 11 | font-weight: normal ; | 12 | font-weight: normal ; |
| 12 | font-style: italic ; | 13 | font-style: italic ; |
| 13 | } | 14 | } |
| @@ -27,7 +28,7 @@ h3 { · 13 unmodified lines | |||
| 27 | 28 | ||
| 28 | table h3 { | 29 | table h3 { |
| 29 | padding-left: 0px ; | 30 | padding-left: 0px ; |
| 30 | border-left: none ; | 31 | border-left: none ; |
| 31 | } | 32 | } |
| 32 | 33 | ||
| 33 | a:link { | 34 | a:link { |
| @@ -62,3 +63,21 @@ hr { · 28 unmodified lines | |||
| 62 | padding: 8px ; | 63 | padding: 8px ; |
| 63 | border: solid #a0a0a0 2px ; | 64 | border: solid #a0a0a0 2px ; |
| 64 | } | 65 | } |
| 66 | |||
| 67 | .footer { | ||
| 68 | color: gray ; | ||
| 69 | font-size: small ; | ||
| 70 | } | ||
| 71 | |||
| 72 | input[type=text] { | ||
| 73 | border: solid #a0a0a0 2px ; | ||
| 74 | border-radius: 2em ; | ||
| 75 | -moz-border-radius: 2em ; | ||
| 76 | background-image: url('images/search.png') ; | ||
| 77 | background-repeat: no-repeat; | ||
| 78 | background-position: left center ; | ||
| 79 | background-position: 4px center ; | ||
| 80 | padding-left: 20px ; | ||
| 81 | height: 2em ; | ||
| 82 | } | ||
| 83 | |||
| @@ -17,14 +17,14 @@ Lua 5.2 Reference Manual · 16 unmodified lines | |||
| 17 | </h1> | 17 | </h1> |
| 18 | 18 | ||
| 19 | <IMG SRC="alert.png" ALIGN="absbottom" ALT="[!]"> | 19 | <IMG SRC="alert.png" ALIGN="absbottom" ALT="[!]"> |
| 20 | <EM>This is an alpha version of Lua 5.2. | 20 | <EM>This is a beta version of Lua 5.2. |
| 21 | Some details may change in the final version.</EM> | 21 | Some details may change in the final version.</EM> |
| 22 | <P> | 22 | <P> |
| 23 | 23 | ||
| 24 | by Roberto Ierusalimschy, Luiz Henrique de Figueiredo, Waldemar Celes | 24 | by Roberto Ierusalimschy, Luiz Henrique de Figueiredo, Waldemar Celes |
| 25 | <p> | 25 | <p> |
| 26 | <small> | 26 | <small> |
| 27 | Copyright © 2010 Lua.org, PUC-Rio. | 27 | Copyright © 2011 Lua.org, PUC-Rio. |
| 28 | Freely available under the terms of the | 28 | Freely available under the terms of the |
| 29 | <a href="http://www.lua.org/license.html#5">Lua license</a>. | 29 | <a href="http://www.lua.org/license.html#5">Lua license</a>. |
| 30 | </small> | 30 | </small> |
| @@ -38,7 +38,7 @@ Freely available under the terms of the · 7 unmodified lines | |||
| 38 | <!-- ====================================================================== --> | 38 | <!-- ====================================================================== --> |
| 39 | <p> | 39 | <p> |
| 40 | 40 | ||
| 41 | <!-- $Id: manual.of,v 1.66 2010/11/22 18:07:40 roberto Exp $ --> | 41 | <!-- $Id: manual.of,v 1.77 2011/06/13 16:27:54 roberto Exp $ --> |
| 42 | 42 | ||
| 43 | 43 | ||
| 44 | 44 | ||
| @@ -53,7 +53,7 @@ It also offers good support for object-oriented programming, · 8 unmodified lines | |||
| 53 | functional programming, and data-driven programming. | 53 | functional programming, and data-driven programming. |
| 54 | Lua is intended to be used as a powerful, light-weight | 54 | Lua is intended to be used as a powerful, light-weight |
| 55 | scripting language for any program that needs one. | 55 | scripting language for any program that needs one. |
| 56 | Lua is implemented as a library, written in <em>clean</em> C, | 56 | Lua is implemented as a library, written in <em>clean C</em>, |
| 57 | the common subset of ANSI C and C++. | 57 | the common subset of ANSI C and C++. |
| 58 | 58 | ||
| 59 | 59 | ||
| @@ -125,11 +125,14 @@ it usually represents the absence of a useful value. · 65 unmodified lines | |||
| 125 | Both <b>nil</b> and <b>false</b> make a condition false; | 125 | Both <b>nil</b> and <b>false</b> make a condition false; |
| 126 | any other value makes it true. | 126 | any other value makes it true. |
| 127 | <em>Number</em> represents real (double-precision floating-point) numbers. | 127 | <em>Number</em> represents real (double-precision floating-point) numbers. |
| 128 | Operations on numbers follow the same rules of | ||
| 129 | the underlying C implementation, | ||
| 130 | which, in turn, usually follows the IEEE 754 standard. | ||
| 128 | (It is easy to build Lua interpreters that use other | 131 | (It is easy to build Lua interpreters that use other |
| 129 | internal representations for numbers, | 132 | internal representations for numbers, |
| 130 | such as single-precision floats or long integers; | 133 | such as single-precision floats or long integers; |
| 131 | see file <code>luaconf.h</code>.) | 134 | see file <code>luaconf.h</code>.) |
| 132 | <em>String</em> represents arrays of characters. | 135 | <em>String</em> represents immutable sequences of bytes. |
| 133 | 136 | ||
| 134 | Lua is 8-bit clean: | 137 | Lua is 8-bit clean: |
| 135 | strings can contain any 8-bit value, | 138 | strings can contain any 8-bit value, |
| @@ -167,11 +170,19 @@ even those that do not support threads. · 31 unmodified lines | |||
| 167 | <p> | 170 | <p> |
| 168 | The type <em>table</em> implements associative arrays, | 171 | The type <em>table</em> implements associative arrays, |
| 169 | that is, arrays that can be indexed not only with numbers, | 172 | that is, arrays that can be indexed not only with numbers, |
| 170 | but with any value (except <b>nil</b>). | 173 | but with any Lua value except <b>nil</b> and NaN |
| 174 | (<em>Not a Number</em>, a special numeric value used to represent | ||
| 175 | undefined or unrepresentable results, such as <code>0/0</code>). | ||
| 171 | Tables can be <em>heterogeneous</em>; | 176 | Tables can be <em>heterogeneous</em>; |
| 172 | that is, they can contain values of all types (except <b>nil</b>). | 177 | that is, they can contain values of all types (except <b>nil</b>). |
| 178 | Any key with value <b>nil</b> is not considered part of the table. | ||
| 179 | Conversely, any key that is not part of a table has | ||
| 180 | an associated value <b>nil</b>. | ||
| 181 | |||
| 182 | |||
| 183 | <p> | ||
| 173 | Tables are the sole data structuring mechanism in Lua; | 184 | Tables are the sole data structuring mechanism in Lua; |
| 174 | they can be used to represent ordinary arrays, | 185 | they can be used to represent ordinary arrays, sequences, |
| 175 | symbol tables, sets, records, graphs, trees, etc. | 186 | symbol tables, sets, records, graphs, trees, etc. |
| 176 | To represent records, Lua uses the field name as an index. | 187 | To represent records, Lua uses the field name as an index. |
| 177 | The language supports this representation by | 188 | The language supports this representation by |
| @@ -180,15 +191,29 @@ There are several convenient ways to create tables in Lua · 2 unmodified lines | |||
| 180 | (see <a href="#3.4.8">§3.4.8</a>). | 191 | (see <a href="#3.4.8">§3.4.8</a>). |
| 181 | 192 | ||
| 182 | 193 | ||
| 194 | <p> | ||
| 195 | We use the term <em>sequence</em> to denote a table where all | ||
| 196 | integer keys comprise the set <em>{1..n}</em> for some integer <em>n</em>, | ||
| 197 | which is called the length of the sequence (see <a href="#3.4.6">§3.4.6</a>). | ||
| 198 | |||
| 199 | |||
| 183 | <p> | 200 | <p> |
| 184 | Like indices, | 201 | Like indices, |
| 185 | the value of a table field can be of any type (except <b>nil</b>). | 202 | the value of a table field can be of any type. |
| 186 | In particular, | 203 | In particular, |
| 187 | because functions are first-class values, | 204 | because functions are first-class values, |
| 188 | table fields can contain functions. | 205 | table fields can contain functions. |
| 189 | Thus tables can also carry <em>methods</em> (see <a href="#3.4.10">§3.4.10</a>). | 206 | Thus tables can also carry <em>methods</em> (see <a href="#3.4.10">§3.4.10</a>). |
| 190 | 207 | ||
| 191 | 208 | ||
| 209 | <p> | ||
| 210 | The indexing of tables follows | ||
| 211 | the definition of equality in the language. | ||
| 212 | The expressions <code>a[i]</code> and <code>a[j]</code> | ||
| 213 | denote the same table element | ||
| 214 | if and only if <code>i == j</code>. | ||
| 215 | |||
| 216 | |||
| 192 | <p> | 217 | <p> |
| 193 | Tables, functions, threads, and (full) userdata values are <em>objects</em>: | 218 | Tables, functions, threads, and (full) userdata values are <em>objects</em>: |
| 194 | variables do not actually <em>contain</em> these values, | 219 | variables do not actually <em>contain</em> these values, |
| @@ -210,7 +235,7 @@ of a given value. · 15 unmodified lines | |||
| 210 | 235 | ||
| 211 | <p> | 236 | <p> |
| 212 | As discussed in <a href="#3.2">§3.2</a> and <a href="#3.3.3">§3.3.3</a>, | 237 | As discussed in <a href="#3.2">§3.2</a> and <a href="#3.3.3">§3.3.3</a>, |
| 213 | any reference to a global name <code>var</code> is syntactically translated | 238 | any reference to a global name <code>var</code> is syntactically translated |
| 214 | to <code>_ENV.var</code>. | 239 | to <code>_ENV.var</code>. |
| 215 | Moreover, every chunk is compiled in the scope of an external | 240 | Moreover, every chunk is compiled in the scope of an external |
| 216 | variable called <code>_ENV</code> (see <a href="#3.3.2">§3.3.2</a>), | 241 | variable called <code>_ENV</code> (see <a href="#3.3.2">§3.3.2</a>), |
| @@ -241,13 +266,13 @@ In Lua, the variable <a href="#pdf-_G"><code>_G</code></a> is initialized with t · 24 unmodified lines | |||
| 241 | 266 | ||
| 242 | <p> | 267 | <p> |
| 243 | When Lua compiles a chunk, | 268 | When Lua compiles a chunk, |
| 244 | it initializes the value of its <code>_ENV</code> variable | 269 | it initializes the value of its <code>_ENV</code> variable |
| 245 | with the global environment (see <a href="#pdf-load"><code>load</code></a>). | 270 | with the global environment (see <a href="#pdf-load"><code>load</code></a>). |
| 246 | Therefore, by default, | 271 | Therefore, by default, |
| 247 | global variables in Lua code refer to entries in the global environment. | 272 | global variables in Lua code refer to entries in the global environment. |
| 248 | Moreover, all standard libraries are loaded in the global environment, | 273 | Moreover, all standard libraries are loaded in the global environment, |
| 249 | and several functions there operate on that environment. | 274 | and several functions there operate on that environment. |
| 250 | You can use <a href="#pdf-loadin"><code>loadin</code></a> to load a chunk with a different environment. | 275 | You can use <a href="#pdf-load"><code>load</code></a> to load a chunk with a different environment. |
| 251 | (In C, you have to load the chunk and then change the value | 276 | (In C, you have to load the chunk and then change the value |
| 252 | of its first upvalue.) | 277 | of its first upvalue.) |
| 253 | 278 | ||
| @@ -283,7 +308,32 @@ which can take appropriate measures · 29 unmodified lines | |||
| 283 | Lua code can explicitly generate an error by calling the | 308 | Lua code can explicitly generate an error by calling the |
| 284 | <a href="#pdf-error"><code>error</code></a> function. | 309 | <a href="#pdf-error"><code>error</code></a> function. |
| 285 | If you need to catch errors in Lua, | 310 | If you need to catch errors in Lua, |
| 286 | you can use the <a href="#pdf-pcall"><code>pcall</code></a> or the <a href="#pdf-xpcall"><code>xpcall</code></a> function. | 311 | you can use <a href="#pdf-pcall"><code>pcall</code></a> or <a href="#pdf-xpcall"><code>xpcall</code></a> |
| 312 | to call a given function in <em>protected mode</em>. | ||
| 313 | |||
| 314 | |||
| 315 | <p> | ||
| 316 | Whenever there is an error, | ||
| 317 | an <em>error object</em> (also called an <em>error message</em>) | ||
| 318 | is propagated with information about the error. | ||
| 319 | Lua itself only generates errors where the error object is a string, | ||
| 320 | but programs may generate errors with | ||
| 321 | any value for the error object. | ||
| 322 | |||
| 323 | |||
| 324 | <p> | ||
| 325 | When you use <a href="#pdf-xpcall"><code>xpcall</code></a> or <a href="#lua_pcall"><code>lua_pcall</code></a>, | ||
| 326 | you may give an <em>message handler</em> | ||
| 327 | to be called in case of errors. | ||
| 328 | This function is called with the original error message | ||
| 329 | and returns a new error message. | ||
| 330 | It is called before the error unwonds the stack, | ||
| 331 | so that it can gather more information about the error, | ||
| 332 | for instance by inspecting the stack and creating a stack traceback. | ||
| 333 | This message handler is still protected by the protected call; | ||
| 334 | so, an error inside the message handler | ||
| 335 | will call the message handler again. | ||
| 336 | If this loop goes on, Lua breaks it and returns an appropriate message. | ||
| 287 | 337 | ||
| 288 | 338 | ||
| 289 | 339 | ||
| @@ -307,7 +357,7 @@ Lua calls this function to perform the addition. · 17 unmodified lines | |||
| 307 | <p> | 357 | <p> |
| 308 | The keys in a metatable are derived from the <em>event</em> names; | 358 | The keys in a metatable are derived from the <em>event</em> names; |
| 309 | the corresponding values are called <em>metamethods</em>. | 359 | the corresponding values are called <em>metamethods</em>. |
| 310 | In the previous example, the event is <code>"add"</code> | 360 | In the previous example, the event is <code>"add"</code> |
| 311 | and the metamethod is the function that performs the addition. | 361 | and the metamethod is the function that performs the addition. |
| 312 | 362 | ||
| 313 | 363 | ||
| @@ -623,6 +673,11 @@ equivalent to <code>not (b < a)</code>. · 309 unmodified lines | |||
| 623 | 673 | ||
| 624 | <li><b>"index":</b> | 674 | <li><b>"index":</b> |
| 625 | The indexing access <code>table[key]</code>. | 675 | The indexing access <code>table[key]</code>. |
| 676 | Note that the metamethod is tried only | ||
| 677 | when <code>key</code> is not present in <code>table</code>. | ||
| 678 | (When <code>table</code> is not a table, | ||
| 679 | no key is ever present, | ||
| 680 | so the metamethod is always tried.) | ||
| 626 | 681 | ||
| 627 | 682 | ||
| 628 | <pre> | 683 | <pre> |
| @@ -630,6 +685,7 @@ The indexing access <code>table[key]</code>. · 1 unmodified line | |||
| 630 | local h | 685 | local h |
| 631 | if type(table) == "table" then | 686 | if type(table) == "table" then |
| 632 | local v = rawget(table, key) | 687 | local v = rawget(table, key) |
| 688 | -- if key is present, return raw value | ||
| 633 | if v ~= nil then return v end | 689 | if v ~= nil then return v end |
| 634 | h = metatable(table).__index | 690 | h = metatable(table).__index |
| 635 | if h == nil then return nil end | 691 | if h == nil then return nil end |
| @@ -649,6 +705,8 @@ The indexing access <code>table[key]</code>. · 13 unmodified lines | |||
| 649 | 705 | ||
| 650 | <li><b>"newindex":</b> | 706 | <li><b>"newindex":</b> |
| 651 | The indexing assignment <code>table[key] = value</code>. | 707 | The indexing assignment <code>table[key] = value</code>. |
| 708 | Note that the metamethod is tried only | ||
| 709 | when <code>key</code> is not present in <code>table</code>. | ||
| 652 | 710 | ||
| 653 | 711 | ||
| 654 | <pre> | 712 | <pre> |
| @@ -656,6 +714,7 @@ The indexing assignment <code>table[key] = value</code>. · 1 unmodified line | |||
| 656 | local h | 714 | local h |
| 657 | if type(table) == "table" then | 715 | if type(table) == "table" then |
| 658 | local v = rawget(table, key) | 716 | local v = rawget(table, key) |
| 717 | -- if key is present, do raw assignment | ||
| 659 | if v ~= nil then rawset(table, key, value); return end | 718 | if v ~= nil then rawset(table, key, value); return end |
| 660 | h = metatable(table).__newindex | 719 | h = metatable(table).__newindex |
| 661 | if h == nil then rawset(table, key, value); return end | 720 | if h == nil then rawset(table, key, value); return end |
| @@ -758,7 +817,7 @@ memory usage. · 96 unmodified lines | |||
| 758 | <p> | 817 | <p> |
| 759 | You can change these numbers by calling <a href="#lua_gc"><code>lua_gc</code></a> in C | 818 | You can change these numbers by calling <a href="#lua_gc"><code>lua_gc</code></a> in C |
| 760 | or <a href="#pdf-collectgarbage"><code>collectgarbage</code></a> in Lua. | 819 | or <a href="#pdf-collectgarbage"><code>collectgarbage</code></a> in Lua. |
| 761 | With these functions you can also control | 820 | With these functions you can also control |
| 762 | the collector directly (e.g., stop and restart it). | 821 | the collector directly (e.g., stop and restart it). |
| 763 | 822 | ||
| 764 | 823 | ||
| @@ -766,8 +825,9 @@ the collector directly (e.g., stop and restart it). · 1 unmodified line | |||
| 766 | <h3>2.5.1 – <a name="2.5.1">Garbage-Collection Metamethods</a></h3> | 825 | <h3>2.5.1 – <a name="2.5.1">Garbage-Collection Metamethods</a></h3> |
| 767 | 826 | ||
| 768 | <p> | 827 | <p> |
| 769 | Using the C API, | 828 | You can set garbage-collector metamethods for tables |
| 770 | you can set garbage-collector metamethods for full userdata (see <a href="#2.4">§2.4</a>). | 829 | and, using the C API, |
| 830 | for full userdata (see <a href="#2.4">§2.4</a>). | ||
| 771 | These metamethods are also called <em>finalizers</em>. | 831 | These metamethods are also called <em>finalizers</em>. |
| 772 | Finalizers allow you to coordinate Lua's garbage collection | 832 | Finalizers allow you to coordinate Lua's garbage collection |
| 773 | with external resource management | 833 | with external resource management |
| @@ -776,43 +836,43 @@ or freeing your own memory). · 2 unmodified lines | |||
| 776 | 836 | ||
| 777 | 837 | ||
| 778 | <p> | 838 | <p> |
| 779 | For a userdata to be finalized when collected, | 839 | For an object (table or userdata) to be finalized when collected, |
| 780 | you must <em>mark</em> it for finalization. | 840 | you must <em>mark</em> it for finalization. |
| 781 | 841 | ||
| 782 | You mark a userdata for finalization when you set its metatable | 842 | You mark an object for finalization when you set its metatable |
| 783 | and the metatable has a field indexed by the string "<code>__gc</code>". | 843 | and the metatable has a field indexed by the string "<code>__gc</code>". |
| 784 | Note that if you set a metatable without a <code>__gc</code> field | 844 | Note that if you set a metatable without a <code>__gc</code> field |
| 785 | and later create that field in the metatable, | 845 | and later create that field in the metatable, |
| 786 | the userdata will not be marked for finalization. | 846 | the object will not be marked for finalization. |
| 787 | However, after a userdata is marked, | 847 | However, after a userdata is marked, |
| 788 | you can freely change the <code>__gc</code> field of its metatable. | 848 | you can freely change the <code>__gc</code> field of its metatable. |
| 789 | 849 | ||
| 790 | 850 | ||
| 791 | <p> | 851 | <p> |
| 792 | When a marked userdata becomes garbage, | 852 | When a marked object becomes garbage, |
| 793 | it is not collected immediately by the garbage collector. | 853 | it is not collected immediately by the garbage collector. |
| 794 | Instead, Lua puts it in a list. | 854 | Instead, Lua puts it in a list. |
| 795 | After the collection, | 855 | After the collection, |
| 796 | Lua does the equivalent of the following function | 856 | Lua does the equivalent of the following function |
| 797 | for each userdata in that list: | 857 | for each object in that list: |
| 798 | 858 | ||
| 799 | <pre> | 859 | <pre> |
| 800 | function gc_event (udata) | 860 | function gc_event (obj) |
| 801 | local h = metatable(udata).__gc | 861 | local h = metatable(obj).__gc |
| 802 | if type(h) == "function" then | 862 | if type(h) == "function" then |
| 803 | h(udata) | 863 | h(obj) |
| 804 | end | 864 | end |
| 805 | end | 865 | end |
| 806 | </pre> | 866 | </pre> |
| 807 | 867 | ||
| 808 | <p> | 868 | <p> |
| 809 | At the end of each garbage-collection cycle, | 869 | At the end of each garbage-collection cycle, |
| 810 | the finalizers for userdata are called in | 870 | the finalizers for objects are called in |
| 811 | the reverse order that they were marked for collection, | 871 | the reverse order that they were marked for collection, |
| 812 | among those collected in that cycle; | 872 | among those collected in that cycle; |
| 813 | that is, the first finalizer to be called is the one associated | 873 | that is, the first finalizer to be called is the one associated |
| 814 | with the userdata marked last in the program. | 874 | with the object marked last in the program. |
| 815 | The userdata memory is freed only in the next garbage-collection cycle. | 875 | The object memory is freed only in the next garbage-collection cycle. |
| 816 | 876 | ||
| 817 | 877 | ||
| 818 | 878 | ||
| @@ -873,15 +933,13 @@ Lua treats strings and light C functions as non-object values. · 54 unmodified lines | |||
| 873 | 933 | ||
| 874 | 934 | ||
| 875 | <p> | 935 | <p> |
| 876 | Userdata marked for finalization have a special behavior in weak tables. | 936 | Objects marked for finalization have a special behavior in weak tables. |
| 877 | When a marked userdata is a value in a weak table, | 937 | When a marked object is a value in a weak table, |
| 878 | it is removed from the table the first time it is collected, | 938 | it is removed from the table before running its finalizer. |
| 879 | before running its finalizer. | ||
| 880 | However, when it is a key, | 939 | However, when it is a key, |
| 881 | it is removed from the table only when it is really freed, | 940 | it is removed from the table only after running its finalizer. |
| 882 | after running its finalizer. | 941 | This behavior allows the finalizer to access properties |
| 883 | This behavior allows the finalizer to access values | 942 | associated with the object through weak tables. |
| 884 | associated with the userdata through weak tables. | ||
| 885 | 943 | ||
| 886 | 944 | ||
| 887 | 945 | ||
| @@ -980,7 +1038,7 @@ consider the following code: · 92 unmodified lines | |||
| 980 | print("co-body", r, s) | 1038 | print("co-body", r, s) |
| 981 | return b, "end" | 1039 | return b, "end" |
| 982 | end) | 1040 | end) |
| 983 | 1041 | ||
| 984 | print("main", coroutine.resume(co, 1, 10)) | 1042 | print("main", coroutine.resume(co, 1, 10)) |
| 985 | print("main", coroutine.resume(co, "r")) | 1043 | print("main", coroutine.resume(co, "r")) |
| 986 | print("main", coroutine.resume(co, "x", "y")) | 1044 | print("main", coroutine.resume(co, "x", "y")) |
| @@ -1048,8 +1106,7 @@ except as delimiters between names and keywords. · 61 unmodified lines | |||
| 1048 | in Lua can be any string of letters, | 1106 | in Lua can be any string of letters, |
| 1049 | digits, and underscores, | 1107 | digits, and underscores, |
| 1050 | not beginning with a digit. | 1108 | not beginning with a digit. |
| 1051 | This coincides with the definition of names in most languages. | 1109 | Identifiers are used to name variables, table fields, and labels. |
| 1052 | Identifiers are used to name variables and table fields. | ||
| 1053 | 1110 | ||
| 1054 | 1111 | ||
| 1055 | <p> | 1112 | <p> |
| @@ -1058,10 +1115,10 @@ and cannot be used as names: · 2 unmodified lines | |||
| 1058 | 1115 | ||
| 1059 | 1116 | ||
| 1060 | <pre> | 1117 | <pre> |
| 1061 | and break do else elseif | 1118 | and break do else elseif end |
| 1062 | end false for function if | 1119 | false for function goto if in |
| 1063 | in local nil not or | 1120 | local nil not or repeat return |
| 1064 | repeat return then true until while | 1121 | then true until while |
| 1065 | </pre> | 1122 | </pre> |
| 1066 | 1123 | ||
| 1067 | <p> | 1124 | <p> |
| @@ -1102,7 +1159,7 @@ results in a newline in the string. · 34 unmodified lines | |||
| 1102 | The escape sequence '<code>\*</code>' skips the following span | 1159 | The escape sequence '<code>\*</code>' skips the following span |
| 1103 | of white-space characters, | 1160 | of white-space characters, |
| 1104 | including line breaks; | 1161 | including line breaks; |
| 1105 | it is particularly useful to break and indent a long string | 1162 | it is particularly useful to break and indent a long string |
| 1106 | into multiple lines without adding the newlines and spaces | 1163 | into multiple lines without adding the newlines and spaces |
| 1107 | into the string contents. | 1164 | into the string contents. |
| 1108 | 1165 | ||
| @@ -1140,9 +1197,18 @@ Any kind of end-of-line sequence · 31 unmodified lines | |||
| 1140 | (carriage return, newline, carriage return followed by newline, | 1197 | (carriage return, newline, carriage return followed by newline, |
| 1141 | or newline followed by carriage return) | 1198 | or newline followed by carriage return) |
| 1142 | is converted to a simple newline. | 1199 | is converted to a simple newline. |
| 1143 | You should not use long strings for non-text data; | 1200 | |
| 1144 | Use instead a regular quoted literal with explicit escape sequences | 1201 | |
| 1145 | for control characters. | 1202 | <p> |
| 1203 | When parsing a from a string source, | ||
| 1204 | any byte in a literal string not | ||
| 1205 | explicitly affected by the previous rules represents itself. | ||
| 1206 | However, Lua opens files for parsing in text mode, | ||
| 1207 | and the system file functions may have problems with | ||
| 1208 | some control characters. | ||
| 1209 | So, it is safer to represent | ||
| 1210 | non-text data as a quoted literal with | ||
| 1211 | explicit escape sequences for non-text characters. | ||
| 1146 | 1212 | ||
| 1147 | 1213 | ||
| 1148 | <p> | 1214 | <p> |
| @@ -1166,14 +1232,19 @@ the five literal strings below denote the same string: · 17 unmodified lines | |||
| 1166 | </pre> | 1232 | </pre> |
| 1167 | 1233 | ||
| 1168 | <p> | 1234 | <p> |
| 1169 | A <em>numerical constant</em> can be written with an optional decimal part | 1235 | A <em>numerical constant</em> can be written with an optional fractional part |
| 1170 | and an optional decimal exponent. | 1236 | and an optional decimal exponent, |
| 1171 | Lua also accepts integer hexadecimal constants, | 1237 | marked by a letter '<code>e</code>' or '<code>E</code>'. |
| 1172 | by prefixing them with <code>0x</code>. | 1238 | Lua also accepts hexadecimal constants, |
| 1239 | which start with <code>0x</code> or <code>0X</code>. | ||
| 1240 | Hexadecimal constants also accept an optional fractional part | ||
| 1241 | plus an optional binary exponent, | ||
| 1242 | marked by a letter '<code>e</code>' or '<code>E</code>'. | ||
| 1173 | Examples of valid numerical constants are | 1243 | Examples of valid numerical constants are |
| 1174 | 1244 | ||
| 1175 | <pre> | 1245 | <pre> |
| 1176 | 3 3.0 3.1416 314.16e-2 0.31416E1 0xff 0x56 | 1246 | 3 3.0 3.1416 314.16e-2 0.31416E1 |
| 1247 | 0xff 0x0.1E 0xA23p-4 0X1.921FB54442D18P+1 | ||
| 1177 | </pre> | 1248 | </pre> |
| 1178 | 1249 | ||
| 1179 | <p> | 1250 | <p> |
| @@ -1194,7 +1265,6 @@ Long comments are frequently used to disable code temporarily. · 14 unmodified lines | |||
| 1194 | 1265 | ||
| 1195 | <p> | 1266 | <p> |
| 1196 | Variables are places that store values. | 1267 | Variables are places that store values. |
| 1197 | |||
| 1198 | There are three kinds of variables in Lua: | 1268 | There are three kinds of variables in Lua: |
| 1199 | global variables, local variables, and table fields. | 1269 | global variables, local variables, and table fields. |
| 1200 | 1270 | ||
| @@ -1293,7 +1363,7 @@ A block can be explicitly delimited to produce a single statement: · 92 unmodified lines | |||
| 1293 | Explicit blocks are useful | 1363 | Explicit blocks are useful |
| 1294 | to control the scope of variable declarations. | 1364 | to control the scope of variable declarations. |
| 1295 | Explicit blocks are also sometimes used to | 1365 | Explicit blocks are also sometimes used to |
| 1296 | add a <b>return</b> or <b>break</b> statement in the middle | 1366 | add a <b>return</b> statement in the middle |
| 1297 | of another block (see <a href="#3.3.4">§3.3.4</a>). | 1367 | of another block (see <a href="#3.3.4">§3.3.4</a>). |
| 1298 | 1368 | ||
| 1299 | 1369 | ||
| @@ -1312,7 +1382,7 @@ a chunk is simply a block: · 12 unmodified lines | |||
| 1312 | </pre> | 1382 | </pre> |
| 1313 | 1383 | ||
| 1314 | <p> | 1384 | <p> |
| 1315 | Lua handles a chunk as the body of an anonymous function | 1385 | Lua handles a chunk as the body of an anonymous function |
| 1316 | with a variable number of arguments | 1386 | with a variable number of arguments |
| 1317 | (see <a href="#3.4.10">§3.4.10</a>). | 1387 | (see <a href="#3.4.10">§3.4.10</a>). |
| 1318 | As such, chunks can define local variables, | 1388 | As such, chunks can define local variables, |
| @@ -1452,38 +1522,60 @@ declared inside the loop block. · 133 unmodified lines | |||
| 1452 | 1522 | ||
| 1453 | 1523 | ||
| 1454 | <p> | 1524 | <p> |
| 1455 | The <b>return</b> statement is used to return values | 1525 | The <b>goto</b> statement transfers the program control to a label. |
| 1456 | from a function or a chunk (which is just a function). | 1526 | For syntactical reasons, |
| 1527 | labels in Lua are considered statements too: | ||
| 1528 | |||
| 1457 | 1529 | ||
| 1458 | Functions can return more than one value, | ||
| 1459 | so the syntax for the <b>return</b> statement is | ||
| 1460 | 1530 | ||
| 1461 | <pre> | 1531 | <pre> |
| 1462 | stat ::= <b>return</b> [explist] [‘<b>;</b>’] | 1532 | stat ::= <b>goto</b> Name |
| 1533 | stat ::= label | ||
| 1534 | label ::= ‘<b>@</b>’ Name ‘<b>:</b>’ | ||
| 1463 | </pre> | 1535 | </pre> |
| 1464 | 1536 | ||
| 1465 | <p> | 1537 | <p> |
| 1466 | The <b>break</b> statement is used to terminate the execution of a | 1538 | A label is visible in the entire block where it is defined |
| 1539 | (including nested blocks, but not nested functions). | ||
| 1540 | A goto may jump to any visible label as long as it does not | ||
| 1541 | enter into the scope of a local variable. | ||
| 1542 | |||
| 1543 | |||
| 1544 | <p> | ||
| 1545 | Both labels and empty statements are called <em>void statements</em>, | ||
| 1546 | as they perform no actions. | ||
| 1547 | |||
| 1548 | |||
| 1549 | <p> | ||
| 1550 | The <b>break</b> statement terminates the execution of a | ||
| 1467 | <b>while</b>, <b>repeat</b>, or <b>for</b> loop, | 1551 | <b>while</b>, <b>repeat</b>, or <b>for</b> loop, |
| 1468 | skipping to the next statement after the loop: | 1552 | skipping to the next statement after the loop: |
| 1469 | 1553 | ||
| 1470 | 1554 | ||
| 1471 | <pre> | 1555 | <pre> |
| 1472 | stat ::= <b>break</b> [‘<b>;</b>’] | 1556 | stat ::= <b>break</b> |
| 1473 | </pre><p> | 1557 | </pre><p> |
| 1474 | A <b>break</b> ends the innermost enclosing loop. | 1558 | A <b>break</b> ends the innermost enclosing loop. |
| 1475 | 1559 | ||
| 1476 | 1560 | ||
| 1477 | <p> | 1561 | <p> |
| 1478 | The <b>return</b> and <b>break</b> | 1562 | The <b>return</b> statement is used to return values |
| 1479 | statements can only be written as the <em>last</em> statement of a block. | 1563 | from a function or a chunk (which is a function in disguise). |
| 1480 | If it is really necessary to <b>return</b> or <b>break</b> in the | 1564 | |
| 1481 | middle of a block, | 1565 | Functions can return more than one value, |
| 1566 | so the syntax for the <b>return</b> statement is | ||
| 1567 | |||
| 1568 | <pre> | ||
| 1569 | stat ::= <b>return</b> [explist] [‘<b>;</b>’] | ||
| 1570 | </pre> | ||
| 1571 | |||
| 1572 | <p> | ||
| 1573 | The <b>return</b> statement can only be written | ||
| 1574 | as the last statement of a block. | ||
| 1575 | If it is really necessary to <b>return</b> in the middle of a block, | ||
| 1482 | then an explicit inner block can be used, | 1576 | then an explicit inner block can be used, |
| 1483 | as in the idioms | 1577 | as in the idiom <code>do return end</code>, |
| 1484 | <code>do return end</code> and <code>do break end</code>, | 1578 | because now <b>return</b> is the last statement in its (inner) block. |
| 1485 | because now <b>return</b> and <b>break</b> are the last statements in | ||
| 1486 | their (inner) blocks. | ||
| 1487 | 1579 | ||
| 1488 | 1580 | ||
| 1489 | 1581 | ||
| @@ -1582,8 +1674,8 @@ is equivalent to the code: · 92 unmodified lines | |||
| 1582 | local <em>f</em>, <em>s</em>, <em>var</em> = <em>explist</em> | 1674 | local <em>f</em>, <em>s</em>, <em>var</em> = <em>explist</em> |
| 1583 | while true do | 1675 | while true do |
| 1584 | local <em>var_1</em>, ···, <em>var_n</em> = <em>f</em>(<em>s</em>, <em>var</em>) | 1676 | local <em>var_1</em>, ···, <em>var_n</em> = <em>f</em>(<em>s</em>, <em>var</em>) |
| 1677 | if <em>var_1</em> == nil then break end | ||
| 1585 | <em>var</em> = <em>var_1</em> | 1678 | <em>var</em> = <em>var_1</em> |
| 1586 | if <em>var</em> == nil then break end | ||
| 1587 | <em>block</em> | 1679 | <em>block</em> |
| 1588 | end | 1680 | end |
| 1589 | end | 1681 | end |
| @@ -1649,7 +1741,6 @@ Otherwise, all variables are initialized with <b>nil</b>. · 59 unmodified lines | |||
| 1649 | <p> | 1741 | <p> |
| 1650 | A chunk is also a block (see <a href="#3.3.2">§3.3.2</a>), | 1742 | A chunk is also a block (see <a href="#3.3.2">§3.3.2</a>), |
| 1651 | and so local variables can be declared in a chunk outside any explicit block. | 1743 | and so local variables can be declared in a chunk outside any explicit block. |
| 1652 | The scope of such local variables extends until the end of the chunk. | ||
| 1653 | 1744 | ||
| 1654 | 1745 | ||
| 1655 | <p> | 1746 | <p> |
| @@ -1671,7 +1762,7 @@ The basic expressions in Lua are the following: · 15 unmodified lines | |||
| 1671 | exp ::= <b>nil</b> | <b>false</b> | <b>true</b> | 1762 | exp ::= <b>nil</b> | <b>false</b> | <b>true</b> |
| 1672 | exp ::= Number | 1763 | exp ::= Number |
| 1673 | exp ::= String | 1764 | exp ::= String |
| 1674 | exp ::= function | 1765 | exp ::= functiondef |
| 1675 | exp ::= tableconstructor | 1766 | exp ::= tableconstructor |
| 1676 | exp ::= ‘<b>...</b>’ | 1767 | exp ::= ‘<b>...</b>’ |
| 1677 | exp ::= exp binop exp | 1768 | exp ::= exp binop exp |
| @@ -1776,7 +1867,9 @@ the quotient towards minus infinity. · 98 unmodified lines | |||
| 1776 | Lua provides automatic conversion between | 1867 | Lua provides automatic conversion between |
| 1777 | string and number values at run time. | 1868 | string and number values at run time. |
| 1778 | Any arithmetic operation applied to a string tries to convert | 1869 | Any arithmetic operation applied to a string tries to convert |
| 1779 | this string to a number, following the usual conversion rules. | 1870 | this string to a number, following the rules of the Lua lexer. |
| 1871 | (The string may have leading and trailing spaces, | ||
| 1872 | plus an optional sign.) | ||
| 1780 | Conversely, whenever a number is used where a string is expected, | 1873 | Conversely, whenever a number is used where a string is expected, |
| 1781 | the number is converted to a string, in a reasonable format. | 1874 | the number is converted to a string, in a reasonable format. |
| 1782 | For complete control over how numbers are converted to strings, | 1875 | For complete control over how numbers are converted to strings, |
| @@ -1802,8 +1895,8 @@ If the types are different, then the result is <b>false</b>. · 19 unmodified lines | |||
| 1802 | Otherwise, the values of the operands are compared. | 1895 | Otherwise, the values of the operands are compared. |
| 1803 | Numbers and strings are compared in the usual way. | 1896 | Numbers and strings are compared in the usual way. |
| 1804 | Tables, userdata, and threads | 1897 | Tables, userdata, and threads |
| 1805 | are compared by <em>reference</em>: | 1898 | are compared by reference: |
| 1806 | two objects are considered equal only if they are the <em>same</em> object. | 1899 | two objects are considered equal only if they are the same object. |
| 1807 | Every time you create a new object | 1900 | Every time you create a new object |
| 1808 | (a table, userdata, or thread), | 1901 | (a table, userdata, or thread), |
| 1809 | this new object is different from any previously existing object. | 1902 | this new object is different from any previously existing object. |
| @@ -1813,13 +1906,13 @@ Closures with any detectable difference · 3 unmodified lines | |||
| 1813 | 1906 | ||
| 1814 | 1907 | ||
| 1815 | <p> | 1908 | <p> |
| 1816 | You can change the way that Lua compares tables and userdata | 1909 | You can change the way that Lua compares tables and userdata |
| 1817 | by using the "eq" metamethod (see <a href="#2.4">§2.4</a>). | 1910 | by using the "eq" metamethod (see <a href="#2.4">§2.4</a>). |
| 1818 | 1911 | ||
| 1819 | 1912 | ||
| 1820 | <p> | 1913 | <p> |
| 1821 | The conversion rules of <a href="#3.4.2">§3.4.2</a> | 1914 | The conversion rules of <a href="#3.4.2">§3.4.2</a> |
| 1822 | <em>do not</em> apply to equality comparisons. | 1915 | do not apply to equality comparisons. |
| 1823 | Thus, <code>"0"==0</code> evaluates to <b>false</b>, | 1916 | Thus, <code>"0"==0</code> evaluates to <b>false</b>, |
| 1824 | and <code>t[0]</code> and <code>t["0"]</code> denote different | 1917 | and <code>t[0]</code> and <code>t["0"]</code> denote different |
| 1825 | entries in a table. | 1918 | entries in a table. |
| @@ -1902,25 +1995,27 @@ character is one byte). · 76 unmodified lines | |||
| 1902 | 1995 | ||
| 1903 | 1996 | ||
| 1904 | <p> | 1997 | <p> |
| 1905 | The length of a table <code>t</code> can be any integer index <code>n</code> | 1998 | The length of a table <code>t</code> is only defined if the |
| 1906 | such that <code>t[n]</code> is not <b>nil</b> and <code>t[n+1]</code> is <b>nil</b>; | 1999 | table is a <em>sequence</em>, |
| 1907 | moreover, if <code>t[1]</code> is <b>nil</b>, <code>n</code> can be zero. | 2000 | that is, |
| 1908 | (All accesses are assumed to be raw for this description.) | 2001 | all its numeric keys comprise the set <em>{1..n}</em> for some integer <em>n</em>. |
| 1909 | For a regular array, where all non-nil values | 2002 | In that case, <em>n</em> is its length. |
| 1910 | have keys from 1 to a given <code>n</code>, | 2003 | Note that a table like |
| 1911 | its length is exactly that <code>n</code>, | 2004 | |
| 1912 | the index of its last value. | 2005 | <pre> |
| 1913 | If the array has "holes" | 2006 | {10, 20, nil, 40} |
| 1914 | (that is, <b>nil</b> values between other non-nil values), | 2007 | </pre><p> |
| 1915 | then <code>#t</code> can be any of the indices that | 2008 | is not a sequence, because it has the key <code>4</code> |
| 1916 | directly precedes a <b>nil</b> value | 2009 | but does not have the key <code>3</code>. |
| 1917 | (that is, it may consider any such <b>nil</b> value as the end of | 2010 | (So, there is no <em>n</em> such that the set <em>{1..n}</em> is equal |
| 1918 | the array). | 2011 | to the set of numeric keys of that table.) |
| 2012 | Note, however, that non-numeric keys do not interfere | ||
| 2013 | with whether a table is a sequence. | ||
| 1919 | 2014 | ||
| 1920 | 2015 | ||
| 1921 | <p> | 2016 | <p> |
| 1922 | A program can modify the behavior of the length operator for | 2017 | A program can modify the behavior of the length operator for |
| 1923 | any value but strings through metamethods (see <a href="#2.4">§2.4</a>). | 2018 | any value but strings through the <code>__len</code> metamethod (see <a href="#2.4">§2.4</a>). |
| 1924 | 2019 | ||
| 1925 | 2020 | ||
| 1926 | 2021 | ||
| @@ -1999,9 +2094,6 @@ If the last field in the list has the form <code>exp</code> · 72 unmodified lines | |||
| 1999 | and the expression is a function call or a vararg expression, | 2094 | and the expression is a function call or a vararg expression, |
| 2000 | then all values returned by this expression enter the list consecutively | 2095 | then all values returned by this expression enter the list consecutively |
| 2001 | (see <a href="#3.4.9">§3.4.9</a>). | 2096 | (see <a href="#3.4.9">§3.4.9</a>). |
| 2002 | To avoid this, | ||
| 2003 | enclose the function call or the vararg expression | ||
| 2004 | in parentheses (see <a href="#3.4">§3.4</a>). | ||
| 2005 | 2097 | ||
| 2006 | 2098 | ||
| 2007 | <p> | 2099 | <p> |
| @@ -2060,7 +2152,7 @@ that is, the argument list is a single literal string. · 52 unmodified lines | |||
| 2060 | 2152 | ||
| 2061 | 2153 | ||
| 2062 | <p> | 2154 | <p> |
| 2063 | A call of the form <code>return</code> <em>functioncall</em> is called | 2155 | A call of the form <code>return <em>functioncall</em></code> is called |
| 2064 | a <em>tail call</em>. | 2156 | a <em>tail call</em>. |
| 2065 | Lua implements <em>proper tail calls</em> | 2157 | Lua implements <em>proper tail calls</em> |
| 2066 | (or <em>proper tail recursion</em>): | 2158 | (or <em>proper tail recursion</em>): |
| @@ -2093,7 +2185,7 @@ So, none of the following examples are tail calls: · 26 unmodified lines | |||
| 2093 | The syntax for function definition is | 2185 | The syntax for function definition is |
| 2094 | 2186 | ||
| 2095 | <pre> | 2187 | <pre> |
| 2096 | function ::= <b>function</b> funcbody | 2188 | functiondef ::= <b>function</b> funcbody |
| 2097 | funcbody ::= ‘<b>(</b>’ [parlist] ‘<b>)</b>’ block <b>end</b> | 2189 | funcbody ::= ‘<b>(</b>’ [parlist] ‘<b>)</b>’ block <b>end</b> |
| 2098 | </pre> | 2190 | </pre> |
| 2099 | 2191 | ||
| @@ -2135,7 +2227,7 @@ translates to · 35 unmodified lines | |||
| 2135 | <pre> | 2227 | <pre> |
| 2136 | local f; f = function () <em>body</em> end | 2228 | local f; f = function () <em>body</em> end |
| 2137 | </pre><p> | 2229 | </pre><p> |
| 2138 | <em>not</em> to | 2230 | not to |
| 2139 | 2231 | ||
| 2140 | <pre> | 2232 | <pre> |
| 2141 | local f = function () <em>body</em> end | 2233 | local f = function () <em>body</em> end |
| @@ -2153,8 +2245,6 @@ Then, whenever Lua executes the function definition, · 11 unmodified lines | |||
| 2153 | the function is <em>instantiated</em> (or <em>closed</em>). | 2245 | the function is <em>instantiated</em> (or <em>closed</em>). |
| 2154 | This function instance (or <em>closure</em>) | 2246 | This function instance (or <em>closure</em>) |
| 2155 | is the final value of the expression. | 2247 | is the final value of the expression. |
| 2156 | Different instances of the same function | ||
| 2157 | can refer to different external local variables. | ||
| 2158 | 2248 | ||
| 2159 | 2249 | ||
| 2160 | <p> | 2250 | <p> |
| @@ -2249,9 +2339,9 @@ is syntactic sugar for · 88 unmodified lines | |||
| 2249 | <p> | 2339 | <p> |
| 2250 | 2340 | ||
| 2251 | Lua is a lexically scoped language. | 2341 | Lua is a lexically scoped language. |
| 2252 | The scope of variables begins at the first statement <em>after</em> | 2342 | The scope of a local variable begins at the first statement after |
| 2253 | their declaration and lasts until the end of the innermost block that | 2343 | its declaration and lasts until the last non-void statement |
| 2254 | includes the declaration. | 2344 | of the innermost block that includes the declaration. |
| 2255 | Consider the following example: | 2345 | Consider the following example: |
| 2256 | 2346 | ||
| 2257 | <pre> | 2347 | <pre> |
| @@ -2356,9 +2446,9 @@ For convenience, · 98 unmodified lines | |||
| 2356 | most query operations in the API do not follow a strict stack discipline. | 2446 | most query operations in the API do not follow a strict stack discipline. |
| 2357 | Instead, they can refer to any element in the stack | 2447 | Instead, they can refer to any element in the stack |
| 2358 | by using an <em>index</em>: | 2448 | by using an <em>index</em>: |
| 2359 | A positive index represents an <em>absolute</em> stack position | 2449 | A positive index represents an absolute stack position |
| 2360 | (starting at 1); | 2450 | (starting at 1); |
| 2361 | a negative index represents an <em>offset</em> relative to the top of the stack. | 2451 | a negative index represents an offset relative to the top of the stack. |
| 2362 | More specifically, if the stack has <em>n</em> elements, | 2452 | More specifically, if the stack has <em>n</em> elements, |
| 2363 | then index 1 represents the first element | 2453 | then index 1 represents the first element |
| 2364 | (that is, the element that was pushed onto the stack first) | 2454 | (that is, the element that was pushed onto the stack first) |
| @@ -2594,7 +2684,7 @@ because its frame in the C stack was destroyed by the yield. · 229 unmodified lines | |||
| 2594 | Instead, Lua calls a <em>continuation function</em>, | 2684 | Instead, Lua calls a <em>continuation function</em>, |
| 2595 | which was given as an argument to the callee function. | 2685 | which was given as an argument to the callee function. |
| 2596 | As the name implies, | 2686 | As the name implies, |
| 2597 | the continuation function should continue the task | 2687 | the continuation function should continue the task |
| 2598 | of the original function. | 2688 | of the original function. |
| 2599 | 2689 | ||
| 2600 | 2690 | ||
| @@ -2684,8 +2774,7 @@ is being allocated; · 83 unmodified lines | |||
| 2684 | 2774 | ||
| 2685 | <p> | 2775 | <p> |
| 2686 | When <code>ptr</code> is not <code>NULL</code>, | 2776 | When <code>ptr</code> is not <code>NULL</code>, |
| 2687 | <code>osize</code> is the previous size of the block | 2777 | <code>osize</code> is the size of the block pointed by <code>ptr</code>, |
| 2688 | pointed by <code>ptr</code>, | ||
| 2689 | that is, the size given when it was allocated or reallocated. | 2778 | that is, the size given when it was allocated or reallocated. |
| 2690 | 2779 | ||
| 2691 | 2780 | ||
| @@ -2705,18 +2794,14 @@ Lua assumes the following behavior from the allocator function: · 13 unmodified lines | |||
| 2705 | 2794 | ||
| 2706 | 2795 | ||
| 2707 | <p> | 2796 | <p> |
| 2708 | When <code>nsize</code> is zero: | 2797 | When <code>nsize</code> is zero, |
| 2709 | if <code>ptr</code> is not <code>NULL</code>, | 2798 | the allocator should behave like <code>free</code> |
| 2710 | the allocator should free the block pointed to by <code>ptr</code>. | 2799 | and return <code>NULL</code>. |
| 2711 | Anyway, the allocator must return <code>NULL</code>. | ||
| 2712 | 2800 | ||
| 2713 | 2801 | ||
| 2714 | <p> | 2802 | <p> |
| 2715 | When <code>nsize</code> is not zero: | 2803 | When <code>nsize</code> is not zero, |
| 2716 | if <code>ptr</code> is <code>NULL</code>, | 2804 | the allocator should behave like <code>realloc</code>. |
| 2717 | the allocator should behave like <code>malloc</code>; | ||
| 2718 | when <code>ptr</code> is not <code>NULL</code>, | ||
| 2719 | the allocator behaves like <code>realloc</code>. | ||
| 2720 | The allocator returns <code>NULL</code> | 2805 | The allocator returns <code>NULL</code> |
| 2721 | if and only if it cannot fill the request. | 2806 | if and only if it cannot fill the request. |
| 2722 | Lua assumes that the allocator never fails when | 2807 | Lua assumes that the allocator never fails when |
| @@ -2751,12 +2836,14 @@ but it seems a safe assumption. · 28 unmodified lines | |||
| 2751 | 2836 | ||
| 2752 | 2837 | ||
| 2753 | <hr><h3><a name="lua_arith"><code>lua_arith</code></a></h3><p> | 2838 | <hr><h3><a name="lua_arith"><code>lua_arith</code></a></h3><p> |
| 2754 | <span class="apii">[-2, +1, <em>e</em>]</span> | 2839 | <span class="apii">[-(2/1), +1, <em>e</em>]</span> |
| 2755 | <pre>int lua_arith (lua_State *L, int op);</pre> | 2840 | <pre>int lua_arith (lua_State *L, int op);</pre> |
| 2756 | 2841 | ||
| 2757 | <p> | 2842 | <p> |
| 2758 | Performs an arithmetic operation over the two values at the top | 2843 | Performs an arithmetic operation over the two values |
| 2759 | of the stack (with the value at the top being the second operand), | 2844 | (or one, in the case of negation) |
| 2845 | at the top of the stack, | ||
| 2846 | with the value at the top being the second operand, | ||
| 2760 | pops these values, and pushes the result of the operation. | 2847 | pops these values, and pushes the result of the operation. |
| 2761 | The function follows the semantics of the corresponding Lua operator | 2848 | The function follows the semantics of the corresponding Lua operator |
| 2762 | (that is, it may call metamethods). | 2849 | (that is, it may call metamethods). |
| @@ -2824,7 +2911,7 @@ when the function is called. · 61 unmodified lines | |||
| 2824 | The function results are pushed onto the stack when the function returns. | 2911 | The function results are pushed onto the stack when the function returns. |
| 2825 | The number of results is adjusted to <code>nresults</code>, | 2912 | The number of results is adjusted to <code>nresults</code>, |
| 2826 | unless <code>nresults</code> is <a name="pdf-LUA_MULTRET"><code>LUA_MULTRET</code></a>. | 2913 | unless <code>nresults</code> is <a name="pdf-LUA_MULTRET"><code>LUA_MULTRET</code></a>. |
| 2827 | In this case, <em>all</em> results from the function are pushed. | 2914 | In this case, all results from the function are pushed. |
| 2828 | Lua takes care that the returned values fit into the stack space. | 2915 | Lua takes care that the returned values fit into the stack space. |
| 2829 | The function results are pushed onto the stack in direct order | 2916 | The function results are pushed onto the stack in direct order |
| 2830 | (the first result is pushed first), | 2917 | (the first result is pushed first), |
| @@ -3028,10 +3115,13 @@ without shifting any element · 197 unmodified lines | |||
| 3028 | 3115 | ||
| 3029 | <p> | 3116 | <p> |
| 3030 | Creates a new empty table and pushes it onto the stack. | 3117 | Creates a new empty table and pushes it onto the stack. |
| 3031 | The new table has space pre-allocated | 3118 | Parameter <code>narr</code> is a hint for how many elements the table |
| 3032 | for <code>narr</code> array elements and <code>nrec</code> non-array elements. | 3119 | will have as a sequence; |
| 3033 | This pre-allocation is useful when you know exactly how many elements | 3120 | parameter <code>nrec</code> is a hint for how many other elements |
| 3034 | the table will have. | 3121 | the table will have. |
| 3122 | Lua may use these hints to preallocate memory for the new table. | ||
| 3123 | This pre-allocation is useful for performance when you know in advance | ||
| 3124 | how many elements the table will have. | ||
| 3035 | Otherwise you can use the function <a href="#lua_newtable"><code>lua_newtable</code></a>. | 3125 | Otherwise you can use the function <a href="#lua_newtable"><code>lua_newtable</code></a>. |
| 3036 | 3126 | ||
| 3037 | 3127 | ||
| @@ -3147,6 +3237,11 @@ returns a boolean that tells whether the collector is running · 109 unmodified lines | |||
| 3147 | 3237 | ||
| 3148 | </ul> | 3238 | </ul> |
| 3149 | 3239 | ||
| 3240 | <p> | ||
| 3241 | For more details about some options, | ||
| 3242 | see <a href="#pdf-collectgarbage"><code>collectgarbage</code></a>. | ||
| 3243 | |||
| 3244 | |||
| 3150 | 3245 | ||
| 3151 | 3246 | ||
| 3152 | 3247 | ||
| @@ -3655,7 +3750,7 @@ A typical traversal looks like this: · 502 unmodified lines | |||
| 3655 | While traversing a table, | 3750 | While traversing a table, |
| 3656 | do not call <a href="#lua_tolstring"><code>lua_tolstring</code></a> directly on a key, | 3751 | do not call <a href="#lua_tolstring"><code>lua_tolstring</code></a> directly on a key, |
| 3657 | unless you know that the key is actually a string. | 3752 | unless you know that the key is actually a string. |
| 3658 | Recall that <a href="#lua_tolstring"><code>lua_tolstring</code></a> <em>changes</em> | 3753 | Recall that <a href="#lua_tolstring"><code>lua_tolstring</code></a> may change |
| 3659 | the value at the given index; | 3754 | the value at the given index; |
| 3660 | this confuses the next call to <a href="#lua_next"><code>lua_next</code></a>. | 3755 | this confuses the next call to <a href="#lua_next"><code>lua_next</code></a>. |
| 3661 | 3756 | ||
| @@ -3683,7 +3778,7 @@ Lua to operate with another type for numbers (e.g., float or long). · 21 unmodified lines | |||
| 3683 | 3778 | ||
| 3684 | <hr><h3><a name="lua_pcall"><code>lua_pcall</code></a></h3><p> | 3779 | <hr><h3><a name="lua_pcall"><code>lua_pcall</code></a></h3><p> |
| 3685 | <span class="apii">[-(nargs + 1), +(nresults|1), <em>-</em>]</span> | 3780 | <span class="apii">[-(nargs + 1), +(nresults|1), <em>-</em>]</span> |
| 3686 | <pre>int lua_pcall (lua_State *L, int nargs, int nresults, int errfunc);</pre> | 3781 | <pre>int lua_pcall (lua_State *L, int nargs, int nresults, int msgh);</pre> |
| 3687 | 3782 | ||
| 3688 | <p> | 3783 | <p> |
| 3689 | Calls a function in protected mode. | 3784 | Calls a function in protected mode. |
| @@ -3704,19 +3799,20 @@ and its arguments from the stack. · 14 unmodified lines | |||
| 3704 | 3799 | ||
| 3705 | 3800 | ||
| 3706 | <p> | 3801 | <p> |
| 3707 | If <code>errfunc</code> is 0, | 3802 | If <code>msgh</code> is 0, |
| 3708 | then the error message returned on the stack | 3803 | then the error message returned on the stack |
| 3709 | is exactly the original error message. | 3804 | is exactly the original error message. |
| 3710 | Otherwise, <code>errfunc</code> is the stack index of an | 3805 | Otherwise, <code>msgh</code> is the stack index of a |
| 3711 | <em>error handler function</em>. | 3806 | <em>message handler</em>. |
| 3712 | (In the current implementation, this index cannot be a pseudo-index.) | 3807 | (In the current implementation, this index cannot be a pseudo-index.) |
| 3713 | In case of runtime errors, | 3808 | In case of runtime errors, |
| 3714 | this function will be called with the error message | 3809 | this function will be called with the error message |
| 3715 | and its return value will be the message returned on the stack by <a href="#lua_pcall"><code>lua_pcall</code></a>. | 3810 | and its return value will be the message |
| 3811 | returned on the stack by <a href="#lua_pcall"><code>lua_pcall</code></a>. | ||
| 3716 | 3812 | ||
| 3717 | 3813 | ||
| 3718 | <p> | 3814 | <p> |
| 3719 | Typically, the error handler function is used to add more debug | 3815 | Typically, the message handler is used to add more debug |
| 3720 | information to the error message, such as a stack traceback. | 3816 | information to the error message, such as a stack traceback. |
| 3721 | Such information cannot be gathered after the return of <a href="#lua_pcall"><code>lua_pcall</code></a>, | 3817 | Such information cannot be gathered after the return of <a href="#lua_pcall"><code>lua_pcall</code></a>, |
| 3722 | since by then the stack has unwound. | 3818 | since by then the stack has unwound. |
| @@ -3737,11 +3833,11 @@ a runtime error. · 14 unmodified lines | |||
| 3737 | 3833 | ||
| 3738 | <li><b><a name="pdf-LUA_ERRMEM"><code>LUA_ERRMEM</code></a>:</b> | 3834 | <li><b><a name="pdf-LUA_ERRMEM"><code>LUA_ERRMEM</code></a>:</b> |
| 3739 | memory allocation error. | 3835 | memory allocation error. |
| 3740 | For such errors, Lua does not call the error handler function. | 3836 | For such errors, Lua does not call the message handler. |
| 3741 | </li> | 3837 | </li> |
| 3742 | 3838 | ||
| 3743 | <li><b><a name="pdf-LUA_ERRERR"><code>LUA_ERRERR</code></a>:</b> | 3839 | <li><b><a name="pdf-LUA_ERRERR"><code>LUA_ERRERR</code></a>:</b> |
| 3744 | error while running the error handler function. | 3840 | error while running the message handler. |
| 3745 | </li> | 3841 | </li> |
| 3746 | 3842 | ||
| 3747 | <li><b><a name="pdf-LUA_ERRGCMM"><code>LUA_ERRGCMM</code></a>:</b> | 3843 | <li><b><a name="pdf-LUA_ERRGCMM"><code>LUA_ERRGCMM</code></a>:</b> |
| @@ -3944,7 +4040,8 @@ onto the stack. · 196 unmodified lines | |||
| 3944 | Lua makes (or reuses) an internal copy of the given string, | 4040 | Lua makes (or reuses) an internal copy of the given string, |
| 3945 | so the memory at <code>s</code> can be freed or reused immediately after | 4041 | so the memory at <code>s</code> can be freed or reused immediately after |
| 3946 | the function returns. | 4042 | the function returns. |
| 3947 | The string can contain embedded zeros. | 4043 | The string can contain any binary data, |
| 4044 | including embedded zeros. | ||
| 3948 | 4045 | ||
| 3949 | 4046 | ||
| 3950 | <p> | 4047 | <p> |
| @@ -3986,8 +4083,6 @@ onto the stack. · 35 unmodified lines | |||
| 3986 | Lua makes (or reuses) an internal copy of the given string, | 4083 | Lua makes (or reuses) an internal copy of the given string, |
| 3987 | so the memory at <code>s</code> can be freed or reused immediately after | 4084 | so the memory at <code>s</code> can be freed or reused immediately after |
| 3988 | the function returns. | 4085 | the function returns. |
| 3989 | The string should not contain embedded zeros; | ||
| 3990 | it is assumed to end at the first zero. | ||
| 3991 | 4086 | ||
| 3992 | 4087 | ||
| 3993 | <p> | 4088 | <p> |
| @@ -4249,14 +4344,11 @@ with user data <code>ud</code>. · 255 unmodified lines | |||
| 4249 | 4344 | ||
| 4250 | <hr><h3><a name="lua_setuservalue"><code>lua_setuservalue</code></a></h3><p> | 4345 | <hr><h3><a name="lua_setuservalue"><code>lua_setuservalue</code></a></h3><p> |
| 4251 | <span class="apii">[-1, +0, <em>-</em>]</span> | 4346 | <span class="apii">[-1, +0, <em>-</em>]</span> |
| 4252 | <pre>int lua_setuservalue (lua_State *L, int index);</pre> | 4347 | <pre>void lua_setuservalue (lua_State *L, int index);</pre> |
| 4253 | 4348 | ||
| 4254 | <p> | 4349 | <p> |
| 4255 | Pops a table or <b>nil</b> from the stack and sets it as | 4350 | Pops a table or <b>nil</b> from the stack and sets it as |
| 4256 | the new value associated to the userdata at the given index. | 4351 | the new value associated to the userdata at the given index. |
| 4257 | If the value at the given index is not a userdata, | ||
| 4258 | <code>lua_setuservalue</code> returns 0. | ||
| 4259 | Otherwise it returns 1. | ||
| 4260 | 4352 | ||
| 4261 | 4353 | ||
| 4262 | 4354 | ||
| @@ -4296,7 +4388,7 @@ It is defined as a macro. · 33 unmodified lines | |||
| 4296 | 4388 | ||
| 4297 | <hr><h3><a name="lua_setmetatable"><code>lua_setmetatable</code></a></h3><p> | 4389 | <hr><h3><a name="lua_setmetatable"><code>lua_setmetatable</code></a></h3><p> |
| 4298 | <span class="apii">[-1, +0, <em>-</em>]</span> | 4390 | <span class="apii">[-1, +0, <em>-</em>]</span> |
| 4299 | <pre>int lua_setmetatable (lua_State *L, int index);</pre> | 4391 | <pre>void lua_setmetatable (lua_State *L, int index);</pre> |
| 4300 | 4392 | ||
| 4301 | <p> | 4393 | <p> |
| 4302 | Pops a table from the stack and | 4394 | Pops a table from the stack and |
| @@ -4716,7 +4808,7 @@ calling the writer again. · 413 unmodified lines | |||
| 4716 | <pre>void lua_xmove (lua_State *from, lua_State *to, int n);</pre> | 4808 | <pre>void lua_xmove (lua_State *from, lua_State *to, int n);</pre> |
| 4717 | 4809 | ||
| 4718 | <p> | 4810 | <p> |
| 4719 | Exchange values between different threads of the <em>same</em> global state. | 4811 | Exchange values between different threads of the same global state. |
| 4720 | 4812 | ||
| 4721 | 4813 | ||
| 4722 | <p> | 4814 | <p> |
| @@ -5033,17 +5125,14 @@ In the first case, · 310 unmodified lines | |||
| 5033 | the parameter <code>ar</code> must be a valid activation record that was | 5125 | the parameter <code>ar</code> must be a valid activation record that was |
| 5034 | filled by a previous call to <a href="#lua_getstack"><code>lua_getstack</code></a> or | 5126 | filled by a previous call to <a href="#lua_getstack"><code>lua_getstack</code></a> or |
| 5035 | given as argument to a hook (see <a href="#lua_Hook"><code>lua_Hook</code></a>). | 5127 | given as argument to a hook (see <a href="#lua_Hook"><code>lua_Hook</code></a>). |
| 5036 | The index <code>n</code> selects which local variable to inspect | 5128 | The index <code>n</code> selects which local variable to inspect; |
| 5037 | (1 is the first parameter or active local variable, and so on, | 5129 | see <a href="#pdf-debug.getlocal"><code>debug.getlocal</code></a> for details about variable indices |
| 5038 | until the last active local variable). | 5130 | and names. |
| 5039 | <a href="#lua_getlocal"><code>lua_getlocal</code></a> pushes the variable's value onto the stack | ||
| 5040 | and returns its name. | ||
| 5041 | 5131 | ||
| 5042 | 5132 | ||
| 5043 | <p> | 5133 | <p> |
| 5044 | Variable names starting with '<code>(</code>' (open parentheses) | 5134 | <a href="#lua_getlocal"><code>lua_getlocal</code></a> pushes the variable's value onto the stack |
| 5045 | represent internal variables | 5135 | and returns its name. |
| 5046 | (loop control variables, temporaries, and C function locals). | ||
| 5047 | 5136 | ||
| 5048 | 5137 | ||
| 5049 | <p> | 5138 | <p> |
| @@ -5176,7 +5265,8 @@ before the function gets its arguments. · 126 unmodified lines | |||
| 5176 | 5265 | ||
| 5177 | <li><b>The return hook:</b> is called when the interpreter returns from a function. | 5266 | <li><b>The return hook:</b> is called when the interpreter returns from a function. |
| 5178 | The hook is called just before Lua leaves the function. | 5267 | The hook is called just before Lua leaves the function. |
| 5179 | You have no access to the values to be returned by the function. | 5268 | There is no standard way to access the values |
| 5269 | to be returned by the function. | ||
| 5180 | </li> | 5270 | </li> |
| 5181 | 5271 | ||
| 5182 | <li><b>The line hook:</b> is called when the interpreter is about to | 5272 | <li><b>The line hook:</b> is called when the interpreter is about to |
| @@ -5285,7 +5375,7 @@ refer to the <code>n2</code>-th upvalue of the Lua closure at index <code>fidx2< · 102 unmodified lines | |||
| 5285 | 5375 | ||
| 5286 | The <em>auxiliary library</em> provides several convenient functions | 5376 | The <em>auxiliary library</em> provides several convenient functions |
| 5287 | to interface C with Lua. | 5377 | to interface C with Lua. |
| 5288 | While the basic API provides the primitive functions for all | 5378 | While the basic API provides the primitive functions for all |
| 5289 | interactions between C and Lua, | 5379 | interactions between C and Lua, |
| 5290 | the auxiliary library provides higher-level functions for some | 5380 | the auxiliary library provides higher-level functions for some |
| 5291 | common tasks. | 5381 | common tasks. |
| @@ -5816,15 +5906,28 @@ as <code>return luaL_error(<em>args</em>)</code>. · 524 unmodified lines | |||
| 5816 | 5906 | ||
| 5817 | 5907 | ||
| 5818 | 5908 | ||
| 5819 | <hr><h3><a name="luaL_findtable"><code>luaL_findtable</code></a></h3><p> | 5909 | <hr><h3><a name="luaL_execresult"><code>luaL_execresult</code></a></h3><p> |
| 5820 | <span class="apii">[-0, +1, <em>m</em>]</span> | 5910 | <span class="apii">[-0, +(1/3), <em>m</em>]</span> |
| 5821 | <pre>void luaL_findtable (lua_State *L, int idx, const char *fname);</pre> | 5911 | <pre>int luaL_execresult (lua_State *L, int stat);</pre> |
| 5822 | 5912 | ||
| 5823 | <p> | 5913 | <p> |
| 5824 | Ensures that the value <code>t[fname]</code>, | 5914 | This function produces the return values for |
| 5825 | where <code>t</code> is the value at the valid index <code>idx</code>, | 5915 | process-related functions in the standard library |
| 5826 | is a table, | 5916 | (<a href="#pdf-os.execute"><code>os.execute</code></a> and <a href="#pdf-io.close"><code>io.close</code></a>). |
| 5827 | and pushes that table onto the stack. | 5917 | |
| 5918 | |||
| 5919 | |||
| 5920 | |||
| 5921 | |||
| 5922 | <hr><h3><a name="luaL_fileresult"><code>luaL_fileresult</code></a></h3><p> | ||
| 5923 | <span class="apii">[-0, +(1/3), <em>m</em>]</span> | ||
| 5924 | <pre>int luaL_fileresult (lua_State *L, int stat, | ||
| 5925 | const char *fname)</pre> | ||
| 5926 | |||
| 5927 | <p> | ||
| 5928 | This function produces the return values for | ||
| 5929 | file-related functions in the standard library | ||
| 5930 | (<a href="#pdf-io.open"><code>io.open</code></a>, <a href="#pdf-os.rename"><code>os.rename</code></a>, <a href="#pdf-file:seek"><code>file:seek</code></a>, etc.). | ||
| 5828 | 5931 | ||
| 5829 | 5932 | ||
| 5830 | 5933 | ||
| @@ -5857,6 +5960,22 @@ in the registry (see <a href="#luaL_newmetatable"><code>luaL_newmetatable</code> · 26 unmodified lines | |||
| 5857 | 5960 | ||
| 5858 | 5961 | ||
| 5859 | 5962 | ||
| 5963 | <hr><h3><a name="luaL_getsubtable"><code>luaL_getsubtable</code></a></h3><p> | ||
| 5964 | <span class="apii">[-0, +1, <em>m</em>]</span> | ||
| 5965 | <pre>int luaL_getsubtable (lua_State *L, int idx, const char *fname);</pre> | ||
| 5966 | |||
| 5967 | <p> | ||
| 5968 | Ensures that the value <code>t[fname]</code>, | ||
| 5969 | where <code>t</code> is the value at the valid index <code>idx</code>, | ||
| 5970 | is a table, | ||
| 5971 | and pushes that table onto the stack. | ||
| 5972 | Returns true if it finds a previous table there | ||
| 5973 | and false if it creates a new table. | ||
| 5974 | |||
| 5975 | |||
| 5976 | |||
| 5977 | |||
| 5978 | |||
| 5860 | <hr><h3><a name="luaL_gsub"><code>luaL_gsub</code></a></h3><p> | 5979 | <hr><h3><a name="luaL_gsub"><code>luaL_gsub</code></a></h3><p> |
| 5861 | <span class="apii">[-0, +1, <em>m</em>]</span> | 5980 | <span class="apii">[-0, +1, <em>m</em>]</span> |
| 5862 | <pre>const char *luaL_gsub (lua_State *L, | 5981 | <pre>const char *luaL_gsub (lua_State *L, |
| @@ -5965,13 +6084,27 @@ it does not run it. · 102 unmodified lines | |||
| 5965 | <pre>int luaL_newlib (lua_State *L, const luaL_Reg *l);</pre> | 6084 | <pre>int luaL_newlib (lua_State *L, const luaL_Reg *l);</pre> |
| 5966 | 6085 | ||
| 5967 | <p> | 6086 | <p> |
| 5968 | Equivalent to <a href="#luaL_setfuncs"><code>luaL_setfuncs</code></a> with no upvalues, | 6087 | Creates a new table and registers there |
| 5969 | but first creates a new table wherein to register the functions | 6088 | the functions in list <code>l</code>. |
| 5970 | in list <code>l</code>. | 6089 | It is implemented as the following macro: |
| 6090 | |||
| 6091 | <pre> | ||
| 6092 | (luaL_newlibtable(L,l), luaL_setfuncs(L,l,0)) | ||
| 6093 | </pre> | ||
| 6094 | |||
| 6095 | |||
| 6096 | |||
| 5971 | 6097 | ||
| 6098 | <hr><h3><a name="luaL_newlibtable"><code>luaL_newlibtable</code></a></h3><p> | ||
| 6099 | <span class="apii">[-0, +1, <em>m</em>]</span> | ||
| 6100 | <pre>int luaL_newlibtable (lua_State *L, const luaL_Reg *l);</pre> | ||
| 5972 | 6101 | ||
| 5973 | <p> | 6102 | <p> |
| 5974 | Leaves the new table on the stack. | 6103 | Creates a new table with a size optimized |
| 6104 | to store all entries in the array <code>l</code> | ||
| 6105 | (but does not actually store them). | ||
| 6106 | It is intended to be used in conjunction with <a href="#luaL_setfuncs"><code>luaL_setfuncs</code></a> | ||
| 6107 | (see <a href="#luaL_newlib"><code>luaL_newlib</code></a>). | ||
| 5975 | 6108 | ||
| 5976 | 6109 | ||
| 5977 | <p> | 6110 | <p> |
| @@ -6176,7 +6309,7 @@ Returns an address to a space of size <code>sz</code> · 198 unmodified lines | |||
| 6176 | where you can copy a string to be added to buffer <code>B</code> | 6309 | where you can copy a string to be added to buffer <code>B</code> |
| 6177 | (see <a href="#luaL_Buffer"><code>luaL_Buffer</code></a>). | 6310 | (see <a href="#luaL_Buffer"><code>luaL_Buffer</code></a>). |
| 6178 | After copying the string into this space you must call | 6311 | After copying the string into this space you must call |
| 6179 | <a href="#luaL_addsize"><code>luaL_addsize</code></a> with the size of the string to actually add | 6312 | <a href="#luaL_addsize"><code>luaL_addsize</code></a> with the size of the string to actually add |
| 6180 | it to the buffer. | 6313 | it to the buffer. |
| 6181 | 6314 | ||
| 6182 | 6315 | ||
| @@ -6284,8 +6417,6 @@ Leaves a copy of that result on the stack. · 101 unmodified lines | |||
| 6284 | Registers all functions in the array <code>l</code> | 6417 | Registers all functions in the array <code>l</code> |
| 6285 | (see <a href="#luaL_Reg"><code>luaL_Reg</code></a>) into the table on the top of the stack | 6418 | (see <a href="#luaL_Reg"><code>luaL_Reg</code></a>) into the table on the top of the stack |
| 6286 | (below optional upvalues, see next). | 6419 | (below optional upvalues, see next). |
| 6287 | The pointer <code>l</code> may be <code>NULL</code>, | ||
| 6288 | representing an empty list. | ||
| 6289 | 6420 | ||
| 6290 | 6421 | ||
| 6291 | <p> | 6422 | <p> |
| @@ -6495,7 +6626,7 @@ e.g., by using <a href="#lua_call"><code>lua_call</code></a>. · 203 unmodified lines | |||
| 6495 | <p> | 6626 | <p> |
| 6496 | The basic library provides some core functions to Lua. | 6627 | The basic library provides some core functions to Lua. |
| 6497 | If you do not include this library in your application, | 6628 | If you do not include this library in your application, |
| 6498 | you should check carefully whether you need to provide | 6629 | you should check carefully whether you need to provide |
| 6499 | implementations for some of its facilities. | 6630 | implementations for some of its facilities. |
| 6500 | 6631 | ||
| 6501 | 6632 | ||
| @@ -6526,11 +6657,13 @@ This is the default option. · 24 unmodified lines | |||
| 6526 | </li> | 6657 | </li> |
| 6527 | 6658 | ||
| 6528 | <li><b>"stop":</b> | 6659 | <li><b>"stop":</b> |
| 6529 | stops the garbage collector. | 6660 | stops automatic invocation of the garbage collector. |
| 6661 | The collector will run only when explcitly invoked, | ||
| 6662 | until a call to restart it. | ||
| 6530 | </li> | 6663 | </li> |
| 6531 | 6664 | ||
| 6532 | <li><b>"restart":</b> | 6665 | <li><b>"restart":</b> |
| 6533 | restarts the garbage collector. | 6666 | restarts automatic invocation the garbage collector. |
| 6534 | </li> | 6667 | </li> |
| 6535 | 6668 | ||
| 6536 | <li><b>"count":</b> | 6669 | <li><b>"count":</b> |
| @@ -6543,6 +6676,8 @@ so the following equality is always true: · 6 unmodified lines | |||
| 6543 | k, b = collectgarbage("count") | 6676 | k, b = collectgarbage("count") |
| 6544 | assert(k*1024 == math.floor(k)*1024 + b) | 6677 | assert(k*1024 == math.floor(k)*1024 + b) |
| 6545 | </pre><p> | 6678 | </pre><p> |
| 6679 | (The second result is useful when Lua is compiled | ||
| 6680 | with a non floating-point type for numbers.) | ||
| 6546 | </li> | 6681 | </li> |
| 6547 | 6682 | ||
| 6548 | <li><b>"step":</b> | 6683 | <li><b>"step":</b> |
| @@ -6658,7 +6793,7 @@ up to the first integer key absent from the table. · 109 unmodified lines | |||
| 6658 | 6793 | ||
| 6659 | 6794 | ||
| 6660 | <p> | 6795 | <p> |
| 6661 | <hr><h3><a name="pdf-load"><code>load (ld [, source [, mode]])</code></a></h3> | 6796 | <hr><h3><a name="pdf-load"><code>load (ld [, source [, mode [, env]]])</code></a></h3> |
| 6662 | 6797 | ||
| 6663 | 6798 | ||
| 6664 | <p> | 6799 | <p> |
| @@ -6666,32 +6801,35 @@ Loads a chunk. · 1 unmodified line | |||
| 6666 | 6801 | ||
| 6667 | 6802 | ||
| 6668 | <p> | 6803 | <p> |
| 6804 | If <code>ld</code> is a string, the chunk is this string. | ||
| 6669 | If <code>ld</code> is a function, | 6805 | If <code>ld</code> is a function, |
| 6670 | calls it repeatedly to get the chunk pieces. | 6806 | <code>load</code> calls it repeatedly to get the chunk pieces. |
| 6671 | Each call to <code>ld</code> must return a string that concatenates | 6807 | Each call to <code>ld</code> must return a string that concatenates |
| 6672 | with previous results. | 6808 | with previous results. |
| 6673 | A return of an empty string, <b>nil</b>, or no value signals the end of the chunk. | 6809 | A return of an empty string, <b>nil</b>, or no value signals the end of the chunk. |
| 6674 | 6810 | ||
| 6675 | 6811 | ||
| 6676 | <p> | 6812 | <p> |
| 6677 | If <code>ld</code> is a string, the chunk is this string. | 6813 | If there are no errors, |
| 6814 | returns the compiled chunk as a function; | ||
| 6815 | otherwise, returns <b>nil</b> plus the error message. | ||
| 6678 | 6816 | ||
| 6679 | 6817 | ||
| 6680 | <p> | 6818 | <p> |
| 6681 | If there are no errors, | ||
| 6682 | returns the compiled chunk as a function; | ||
| 6683 | otherwise, returns <b>nil</b> plus the error message. | ||
| 6684 | If the resulting function has upvalues, | 6819 | If the resulting function has upvalues, |
| 6685 | the first upvalue is set to the value of the global environment | 6820 | the first upvalue is set to the value of the |
| 6821 | global environment or to <code>env</code>, | ||
| 6822 | if that parameter is given. | ||
| 6686 | (When loading main chunks, | 6823 | (When loading main chunks, |
| 6687 | this upvalue will be the <code>_ENV</code> variable (see <a href="#2.2">§2.2</a>).) | 6824 | the first upvalue will be the <code>_ENV</code> variable (see <a href="#2.2">§2.2</a>).) |
| 6688 | 6825 | ||
| 6689 | 6826 | ||
| 6690 | <p> | 6827 | <p> |
| 6691 | <code>source</code> is used as the source of the chunk for error messages | 6828 | <code>source</code> is used as the source of the chunk for error messages |
| 6692 | and debug information (see <a href="#4.9">§4.9</a>). | 6829 | and debug information (see <a href="#4.9">§4.9</a>). |
| 6693 | When absent, | 6830 | When absent, |
| 6694 | it defaults to "<code>=(load)</code>". | 6831 | it defaults to <code>ld</code>, if <code>ld</code> is a string, |
| 6832 | or to "<code>=(load)</code>". | ||
| 6695 | 6833 | ||
| 6696 | 6834 | ||
| 6697 | <p> | 6835 | <p> |
| @@ -6704,21 +6842,6 @@ The default is "<code>bt</code>". · 6 unmodified lines | |||
| 6704 | 6842 | ||
| 6705 | 6843 | ||
| 6706 | 6844 | ||
| 6707 | <p> | ||
| 6708 | <hr><h3><a name="pdf-loadin"><code>loadin (env, ...)</code></a></h3> | ||
| 6709 | |||
| 6710 | |||
| 6711 | <p> | ||
| 6712 | This function is similar to <a href="#pdf-load"><code>load</code></a>, | ||
| 6713 | but sets <code>env</code> as the value of the first upvalue | ||
| 6714 | of the created function in case of success. | ||
| 6715 | (When loading main chunks, | ||
| 6716 | this upvalue will be the <code>_ENV</code> variable (see <a href="#2.2">§2.2</a>).) | ||
| 6717 | The parameters after <code>env</code> are similar to those of <a href="#pdf-load"><code>load</code></a>, too. | ||
| 6718 | |||
| 6719 | |||
| 6720 | |||
| 6721 | |||
| 6722 | <p> | 6845 | <p> |
| 6723 | <hr><h3><a name="pdf-loadfile"><code>loadfile ([filename])</code></a></h3> | 6846 | <hr><h3><a name="pdf-loadfile"><code>loadfile ([filename])</code></a></h3> |
| 6724 | 6847 | ||
| @@ -6732,29 +6855,6 @@ if no file name is given. · 7 unmodified lines | |||
| 6732 | 6855 | ||
| 6733 | 6856 | ||
| 6734 | 6857 | ||
| 6735 | <p> | ||
| 6736 | <hr><h3><a name="pdf-loadstring"><code>loadstring (string [, chunkname])</code></a></h3> | ||
| 6737 | |||
| 6738 | |||
| 6739 | <p> | ||
| 6740 | Similar to <a href="#pdf-load"><code>load</code></a>, | ||
| 6741 | but gets the chunk from the given string. | ||
| 6742 | |||
| 6743 | |||
| 6744 | <p> | ||
| 6745 | To load and run a given string, use the idiom | ||
| 6746 | |||
| 6747 | <pre> | ||
| 6748 | assert(loadstring(s))() | ||
| 6749 | </pre> | ||
| 6750 | |||
| 6751 | <p> | ||
| 6752 | When absent, | ||
| 6753 | <code>chunkname</code> defaults to the given string. | ||
| 6754 | |||
| 6755 | |||
| 6756 | |||
| 6757 | |||
| 6758 | <p> | 6858 | <p> |
| 6759 | <hr><h3><a name="pdf-next"><code>next (table [, index])</code></a></h3> | 6859 | <hr><h3><a name="pdf-next"><code>next (table [, index])</code></a></h3> |
| 6760 | 6860 | ||
| @@ -6784,7 +6884,7 @@ use a numerical <b>for</b>.) · 23 unmodified lines | |||
| 6784 | 6884 | ||
| 6785 | 6885 | ||
| 6786 | <p> | 6886 | <p> |
| 6787 | The behavior of <code>next</code> is <em>undefined</em> if, | 6887 | The behavior of <code>next</code> is undefined if, |
| 6788 | during the traversal, | 6888 | during the traversal, |
| 6789 | you assign any value to a non-existent field in the table. | 6889 | you assign any value to a non-existent field in the table. |
| 6790 | You may however modify existing fields. | 6890 | You may however modify existing fields. |
| @@ -6872,6 +6972,16 @@ without invoking any metamethod. · 81 unmodified lines | |||
| 6872 | 6972 | ||
| 6873 | 6973 | ||
| 6874 | 6974 | ||
| 6975 | <p> | ||
| 6976 | <hr><h3><a name="pdf-rawlen"><code>rawlen (v)</code></a></h3> | ||
| 6977 | Returns the length of the object <code>v</code>, | ||
| 6978 | which must be a table or a string, | ||
| 6979 | without invoking any metamethod. | ||
| 6980 | Returns an integer number. | ||
| 6981 | |||
| 6982 | |||
| 6983 | |||
| 6984 | |||
| 6875 | <p> | 6985 | <p> |
| 6876 | <hr><h3><a name="pdf-rawset"><code>rawset (table, index, value)</code></a></h3> | 6986 | <hr><h3><a name="pdf-rawset"><code>rawset (table, index, value)</code></a></h3> |
| 6877 | Sets the real value of <code>table[index]</code> to <code>value</code>, | 6987 | Sets the real value of <code>table[index]</code> to <code>value</code>, |
| @@ -6934,9 +7044,9 @@ The base may be any integer between 2 and 36, inclusive. · 56 unmodified lines | |||
| 6934 | In bases above 10, the letter '<code>A</code>' (in either upper or lower case) | 7044 | In bases above 10, the letter '<code>A</code>' (in either upper or lower case) |
| 6935 | represents 10, '<code>B</code>' represents 11, and so forth, | 7045 | represents 10, '<code>B</code>' represents 11, and so forth, |
| 6936 | with '<code>Z</code>' representing 35. | 7046 | with '<code>Z</code>' representing 35. |
| 6937 | In base 10 (the default), the number can have a decimal part, | 7047 | In base 10 (the default), |
| 6938 | as well as an optional exponent part (see <a href="#3.1">§3.1</a>). | 7048 | the numeral is converted following the coercion rules (see <a href="#3.4.2">§3.4.2</a>). |
| 6939 | In other bases, only unsigned integers are accepted. | 7049 | In other bases, only integers are accepted. |
| 6940 | 7050 | ||
| 6941 | 7051 | ||
| 6942 | 7052 | ||
| @@ -6984,12 +7094,12 @@ The current contents of this variable is "<code>Lua 5.2</code>". · 41 unmodified lines | |||
| 6984 | 7094 | ||
| 6985 | 7095 | ||
| 6986 | <p> | 7096 | <p> |
| 6987 | <hr><h3><a name="pdf-xpcall"><code>xpcall (f, err [, arg1, ···])</code></a></h3> | 7097 | <hr><h3><a name="pdf-xpcall"><code>xpcall (f, msgh [, arg1, ···])</code></a></h3> |
| 6988 | 7098 | ||
| 6989 | 7099 | ||
| 6990 | <p> | 7100 | <p> |
| 6991 | This function is similar to <a href="#pdf-pcall"><code>pcall</code></a>, | 7101 | This function is similar to <a href="#pdf-pcall"><code>pcall</code></a>, |
| 6992 | except that it sets a new error handler <code>err</code>. | 7102 | except that it sets a new message handler <code>msgh</code>. |
| 6993 | 7103 | ||
| 6994 | 7104 | ||
| 6995 | 7105 | ||
| @@ -7130,8 +7240,8 @@ Otherwise, it tries to find a <em>loader</em> for the module. · 134 unmodified lines | |||
| 7130 | 7240 | ||
| 7131 | <p> | 7241 | <p> |
| 7132 | To find a loader, | 7242 | To find a loader, |
| 7133 | <code>require</code> is guided by the <a href="#pdf-package.loaders"><code>package.loaders</code></a> array. | 7243 | <code>require</code> is guided by the <a href="#pdf-package.loaders"><code>package.loaders</code></a> sequence. |
| 7134 | By changing this array, | 7244 | By changing this sequence, |
| 7135 | we can change how <code>require</code> looks for a module. | 7245 | we can change how <code>require</code> looks for a module. |
| 7136 | The following explanation is based on the default configuration | 7246 | The following explanation is based on the default configuration |
| 7137 | for <a href="#pdf-package.loaders"><code>package.loaders</code></a>. | 7247 | for <a href="#pdf-package.loaders"><code>package.loaders</code></a>. |
| @@ -7151,7 +7261,10 @@ it tries an <em>all-in-one</em> loader (see <a href="#pdf-package.loaders"><code · 13 unmodified lines | |||
| 7151 | 7261 | ||
| 7152 | <p> | 7262 | <p> |
| 7153 | Once a loader is found, | 7263 | Once a loader is found, |
| 7154 | <code>require</code> calls the loader with a single argument, <code>modname</code>. | 7264 | <code>require</code> calls the loader with two arguments: |
| 7265 | <code>modname</code> and an extra value dependent on how it got the loader. | ||
| 7266 | (If the loader came from a file, | ||
| 7267 | this extra value is the file name.) | ||
| 7155 | If the loader returns any non-nil value, | 7268 | If the loader returns any non-nil value, |
| 7156 | <code>require</code> assigns the returned value to <code>package.loaded[modname]</code>. | 7269 | <code>require</code> assigns the returned value to <code>package.loaded[modname]</code>. |
| 7157 | If the loader does not return a non-nil value and | 7270 | If the loader does not return a non-nil value and |
| @@ -7164,7 +7277,7 @@ final value of <code>package.loaded[modname]</code>. · 6 unmodified lines | |||
| 7164 | <p> | 7277 | <p> |
| 7165 | If there is any error loading or running the module, | 7278 | If there is any error loading or running the module, |
| 7166 | or if it cannot find any loader for the module, | 7279 | or if it cannot find any loader for the module, |
| 7167 | then <code>require</code> signals an error. | 7280 | then <code>require</code> signals an error. |
| 7168 | 7281 | ||
| 7169 | 7282 | ||
| 7170 | 7283 | ||
| @@ -7255,9 +7368,13 @@ When looking for a module, · 84 unmodified lines | |||
| 7255 | with the module name (the argument given to <a href="#pdf-require"><code>require</code></a>) as its | 7368 | with the module name (the argument given to <a href="#pdf-require"><code>require</code></a>) as its |
| 7256 | sole parameter. | 7369 | sole parameter. |
| 7257 | The function can return another function (the module <em>loader</em>) | 7370 | The function can return another function (the module <em>loader</em>) |
| 7371 | plus an extra value that will be passed to that loader, | ||
| 7258 | or a string explaining why it did not find that module | 7372 | or a string explaining why it did not find that module |
| 7259 | (or <b>nil</b> if it has nothing to say). | 7373 | (or <b>nil</b> if it has nothing to say). |
| 7260 | Lua initializes this table with four functions. | 7374 | |
| 7375 | |||
| 7376 | <p> | ||
| 7377 | Lua initializes this table with four searcher functions. | ||
| 7261 | 7378 | ||
| 7262 | 7379 | ||
| 7263 | <p> | 7380 | <p> |
| @@ -7313,6 +7430,13 @@ into one single library, · 49 unmodified lines | |||
| 7313 | with each submodule keeping its original open function. | 7430 | with each submodule keeping its original open function. |
| 7314 | 7431 | ||
| 7315 | 7432 | ||
| 7433 | <p> | ||
| 7434 | All searchers except the first (preload) return as the extra value | ||
| 7435 | the file name where the module was found, | ||
| 7436 | as returned by <a href="#pdf-package.searchpath"><code>package.searchpath</code></a>. | ||
| 7437 | The first searcher returns no extra value. | ||
| 7438 | |||
| 7439 | |||
| 7316 | 7440 | ||
| 7317 | 7441 | ||
| 7318 | <p> | 7442 | <p> |
| @@ -7384,10 +7508,16 @@ A table to store loaders for specific modules · 65 unmodified lines | |||
| 7384 | (see <a href="#pdf-require"><code>require</code></a>). | 7508 | (see <a href="#pdf-require"><code>require</code></a>). |
| 7385 | 7509 | ||
| 7386 | 7510 | ||
| 7511 | <p> | ||
| 7512 | This variable is only a reference to the real table; | ||
| 7513 | assignments to this variable do not change the | ||
| 7514 | table used by <a href="#pdf-require"><code>require</code></a>. | ||
| 7515 | |||
| 7516 | |||
| 7387 | 7517 | ||
| 7388 | 7518 | ||
| 7389 | <p> | 7519 | <p> |
| 7390 | <hr><h3><a name="pdf-package.searchpath"><code>package.searchpath (name, path)</code></a></h3> | 7520 | <hr><h3><a name="pdf-package.searchpath"><code>package.searchpath (name, path [, sep])</code></a></h3> |
| 7391 | 7521 | ||
| 7392 | 7522 | ||
| 7393 | <p> | 7523 | <p> |
| @@ -7400,8 +7530,15 @@ A path is string containing a sequence of · 6 unmodified lines | |||
| 7400 | For each template, | 7530 | For each template, |
| 7401 | the function changes each interrogation | 7531 | the function changes each interrogation |
| 7402 | mark in the template by a copy of <code>name</code> | 7532 | mark in the template by a copy of <code>name</code> |
| 7403 | wherein all dots were replaced by the system's directory separator, | 7533 | wherein all occurrences of <code>sep</code> |
| 7534 | (a dot, by default) | ||
| 7535 | were replaced by the system's directory separator, | ||
| 7404 | and then tries to open the resulting file name. | 7536 | and then tries to open the resulting file name. |
| 7537 | If <code>sep</code> is the empty string, | ||
| 7538 | the replacement is not done. | ||
| 7539 | |||
| 7540 | |||
| 7541 | <p> | ||
| 7405 | For instance, if the path is the string | 7542 | For instance, if the path is the string |
| 7406 | 7543 | ||
| 7407 | <pre> | 7544 | <pre> |
| @@ -7485,9 +7622,8 @@ Note that numerical codes are not necessarily portable across platforms. · 77 unmodified lines | |||
| 7485 | 7622 | ||
| 7486 | <p> | 7623 | <p> |
| 7487 | Returns a string containing a binary representation of the given function, | 7624 | Returns a string containing a binary representation of the given function, |
| 7488 | so that a later <a href="#pdf-loadstring"><code>loadstring</code></a> on this string returns | 7625 | so that a later <a href="#pdf-load"><code>load</code></a> on this string returns |
| 7489 | a copy of the function. | 7626 | a copy of the function (but with new upvalues). |
| 7490 | <code>function</code> must be a Lua function without upvalues. | ||
| 7491 | 7627 | ||
| 7492 | 7628 | ||
| 7493 | 7629 | ||
| @@ -7552,16 +7688,19 @@ will produce the string: · 58 unmodified lines | |||
| 7552 | </pre> | 7688 | </pre> |
| 7553 | 7689 | ||
| 7554 | <p> | 7690 | <p> |
| 7555 | The options <code>c</code>, <code>d</code>, <code>E</code>, <code>e</code>, <code>f</code>, | 7691 | Options |
| 7556 | <code>g</code>, <code>G</code>, <code>i</code>, <code>o</code>, <code>u</code>, <code>X</code>, and <code>x</code> all | 7692 | <code>A</code> and <code>a</code> (when available), |
| 7557 | expect a number as argument, | 7693 | <code>E</code>, <code>e</code>, <code>f</code>, |
| 7558 | whereas <code>q</code> and <code>s</code> expect a string. | 7694 | <code>G</code>, and <code>g</code> all expect a number as argument. |
| 7559 | 7695 | Options <code>c</code>, <code>d</code>, | |
| 7560 | 7696 | <code>i</code>, <code>o</code>, <code>u</code>, <code>X</code>, and <code>x</code> | |
| 7561 | <p> | 7697 | expect an integer as argument; |
| 7562 | This function does not accept string values | 7698 | the range of that integer may be limited by |
| 7563 | containing embedded zeros, | 7699 | the underlying C implementation. |
| 7564 | except as arguments to the <code>q</code> option. | 7700 | Option <code>q</code> expects a string |
| 7701 | and <code>s</code> expects a string without embedded zeros. | ||
| 7702 | If the argument to option <code>s</code> is not a string, | ||
| 7703 | it is converted to one following the same rules of <a href="#pdf-tostring"><code>tostring</code></a>. | ||
| 7565 | 7704 | ||
| 7566 | 7705 | ||
| 7567 | 7706 | ||
| @@ -7577,6 +7716,8 @@ then the whole match is produced in each call. · 9 unmodified lines | |||
| 7577 | 7716 | ||
| 7578 | <p> | 7717 | <p> |
| 7579 | As an example, the following loop | 7718 | As an example, the following loop |
| 7719 | will iterate over all the words from string <code>s</code>, | ||
| 7720 | printing one per line: | ||
| 7580 | 7721 | ||
| 7581 | <pre> | 7722 | <pre> |
| 7582 | s = "hello world from Lua" | 7723 | s = "hello world from Lua" |
| @@ -7584,8 +7725,6 @@ As an example, the following loop · 1 unmodified line | |||
| 7584 | print(w) | 7725 | print(w) |
| 7585 | end | 7726 | end |
| 7586 | </pre><p> | 7727 | </pre><p> |
| 7587 | will iterate over all the words from string <code>s</code>, | ||
| 7588 | printing one per line. | ||
| 7589 | The next example collects all pairs <code>key=value</code> from the | 7728 | The next example collects all pairs <code>key=value</code> from the |
| 7590 | given string into a table: | 7729 | given string into a table: |
| 7591 | 7730 | ||
| @@ -7667,7 +7806,7 @@ Here are some examples: · 75 unmodified lines | |||
| 7667 | --> x="home = /home/roberto, user = roberto" | 7806 | --> x="home = /home/roberto, user = roberto" |
| 7668 | 7807 | ||
| 7669 | x = string.gsub("4+5 = $return 4+5$", "%$(.-)%$", function (s) | 7808 | x = string.gsub("4+5 = $return 4+5$", "%$(.-)%$", function (s) |
| 7670 | return loadstring(s)() | 7809 | return load(s)() |
| 7671 | end) | 7810 | end) |
| 7672 | --> x="4+5 = 9" | 7811 | --> x="4+5 = 9" |
| 7673 | 7812 | ||
| @@ -7715,9 +7854,11 @@ its default value is 1 and can be negative. · 41 unmodified lines | |||
| 7715 | 7854 | ||
| 7716 | 7855 | ||
| 7717 | <p> | 7856 | <p> |
| 7718 | <hr><h3><a name="pdf-string.rep"><code>string.rep (s, n)</code></a></h3> | 7857 | <hr><h3><a name="pdf-string.rep"><code>string.rep (s, n [, sep])</code></a></h3> |
| 7719 | Returns a string that is the concatenation of <code>n</code> copies of | 7858 | Returns a string that is the concatenation of <code>n</code> copies of |
| 7720 | the string <code>s</code>. | 7859 | the string <code>s</code> separated by the string <code>sep</code>. |
| 7860 | The default value for <code>sep</code> is the empty string | ||
| 7861 | (that is, no separator). | ||
| 7721 | 7862 | ||
| 7722 | 7863 | ||
| 7723 | 7864 | ||
| @@ -7867,7 +8008,7 @@ These repetition items will always match the longest possible sequence; · 143 unmodified lines | |||
| 7867 | a single character class followed by '<code>-</code>', | 8008 | a single character class followed by '<code>-</code>', |
| 7868 | which also matches 0 or more repetitions of characters in the class. | 8009 | which also matches 0 or more repetitions of characters in the class. |
| 7869 | Unlike '<code>*</code>', | 8010 | Unlike '<code>*</code>', |
| 7870 | these repetition items will always match the <em>shortest</em> possible sequence; | 8011 | these repetition items will always match the shortest possible sequence; |
| 7871 | </li> | 8012 | </li> |
| 7872 | 8013 | ||
| 7873 | <li> | 8014 | <li> |
| @@ -7949,41 +8090,55 @@ string <code>"flaaap"</code>, there will be two captures: 3 and 5. · 75 unmodified lines | |||
| 7949 | 8090 | ||
| 7950 | 8091 | ||
| 7951 | 8092 | ||
| 7952 | <h2>6.5 – <a name="6.5">Table Manipulation</a></h2><p> | 8093 | <h2>6.5 – <a name="6.5">Table Manipulation</a></h2> |
| 8094 | |||
| 8095 | <p> | ||
| 7953 | This library provides generic functions for table manipulation. | 8096 | This library provides generic functions for table manipulation. |
| 7954 | It provides all its functions inside the table <a name="pdf-table"><code>table</code></a>. | 8097 | It provides all its functions inside the table <a name="pdf-table"><code>table</code></a>. |
| 7955 | 8098 | ||
| 7956 | 8099 | ||
| 7957 | <p> | 8100 | <p> |
| 7958 | Most functions in the table library assume that the table | 8101 | Currently, all functions in the table library assume that the table |
| 7959 | represents an array or a list. | 8102 | represents a list. |
| 7960 | For these functions, when we talk about the "length" of a table | 8103 | In particular, they all ignore non-numeric keys |
| 7961 | we mean the result of the length operator. | 8104 | in tables given as arguments. |
| 8105 | All functions in the table library, | ||
| 8106 | except <a href="#pdf-table.pack"><code>table.pack</code></a>, | ||
| 8107 | may apply the length operator on the list. | ||
| 8108 | In that case, the list must be a proper sequence | ||
| 8109 | or have a <code>__len</code> metamethod (see <a href="#3.4.6">§3.4.6</a>). | ||
| 8110 | |||
| 8111 | |||
| 8112 | <p> | ||
| 8113 | For performance reasons, | ||
| 8114 | all table accesses (get/set) performed by these functions are raw. | ||
| 8115 | |||
| 8116 | |||
| 8117 | <p> | ||
| 8118 | <hr><h3><a name="pdf-table.concat"><code>table.concat (list [, sep [, i [, j]]])</code></a></h3> | ||
| 7962 | 8119 | ||
| 7963 | 8120 | ||
| 7964 | <p> | 8121 | <p> |
| 7965 | <hr><h3><a name="pdf-table.concat"><code>table.concat (table [, sep [, i [, j]]])</code></a></h3> | 8122 | Given a list where all elements are strings or numbers, |
| 7966 | Given an array where all elements are strings or numbers, | 8123 | returns <code>list[i]..sep..list[i+1] ··· sep..list[j]</code>. |
| 7967 | returns <code>table[i]..sep..table[i+1] ··· sep..table[j]</code>. | ||
| 7968 | The default value for <code>sep</code> is the empty string, | 8124 | The default value for <code>sep</code> is the empty string, |
| 7969 | the default for <code>i</code> is 1, | 8125 | the default for <code>i</code> is 1, |
| 7970 | and the default for <code>j</code> is the length of the table. | 8126 | and the default for <code>j</code> is <code>#list</code>. |
| 7971 | If <code>i</code> is greater than <code>j</code>, returns the empty string. | 8127 | If <code>i</code> is greater than <code>j</code>, returns the empty string. |
| 7972 | 8128 | ||
| 7973 | 8129 | ||
| 7974 | 8130 | ||
| 7975 | 8131 | ||
| 7976 | <p> | 8132 | <p> |
| 7977 | <hr><h3><a name="pdf-table.insert"><code>table.insert (table, [pos,] value)</code></a></h3> | 8133 | <hr><h3><a name="pdf-table.insert"><code>table.insert (list, [pos,] value)</code></a></h3> |
| 7978 | 8134 | ||
| 7979 | 8135 | ||
| 7980 | <p> | 8136 | <p> |
| 7981 | Inserts element <code>value</code> at position <code>pos</code> in <code>table</code>, | 8137 | Inserts element <code>value</code> at position <code>pos</code> in <code>list</code>, |
| 7982 | shifting up other elements to open space, if necessary. | 8138 | shifting up other elements to open space, if necessary. |
| 7983 | The default value for <code>pos</code> is <code>n+1</code>, | 8139 | The default value for <code>pos</code> is <code>#list+1</code>, |
| 7984 | where <code>n</code> is the length of the table (see <a href="#3.4.6">§3.4.6</a>), | ||
| 7985 | so that a call <code>table.insert(t,x)</code> inserts <code>x</code> at the end | 8140 | so that a call <code>table.insert(t,x)</code> inserts <code>x</code> at the end |
| 7986 | of table <code>t</code>. | 8141 | of list <code>t</code>. |
| 7987 | 8142 | ||
| 7988 | 8143 | ||
| 7989 | 8144 | ||
| @@ -7993,36 +8148,38 @@ of table <code>t</code>. · 3 unmodified lines | |||
| 7993 | 8148 | ||
| 7994 | 8149 | ||
| 7995 | <p> | 8150 | <p> |
| 7996 | Returns a new table with all parameters stored into | 8151 | Returns a new table with all parameters stored into keys 1, 2, etc. |
| 7997 | keys 1, 2, etc. | ||
| 7998 | and with a field "<code>n</code>" with the total number of parameters. | 8152 | and with a field "<code>n</code>" with the total number of parameters. |
| 8153 | Note that the result may not be a sequence, | ||
| 8154 | if any parameter is <b>nil</b>. | ||
| 7999 | 8155 | ||
| 8000 | 8156 | ||
| 8001 | 8157 | ||
| 8002 | 8158 | ||
| 8003 | <p> | 8159 | <p> |
| 8004 | <hr><h3><a name="pdf-table.remove"><code>table.remove (table [, pos])</code></a></h3> | 8160 | <hr><h3><a name="pdf-table.remove"><code>table.remove (list [, pos])</code></a></h3> |
| 8005 | 8161 | ||
| 8006 | 8162 | ||
| 8007 | <p> | 8163 | <p> |
| 8008 | Removes from <code>table</code> the element at position <code>pos</code>, | 8164 | Removes from <code>list</code> the element at position <code>pos</code>, |
| 8009 | shifting down other elements to close the space, if necessary. | 8165 | shifting down other elements to close the space, if necessary. |
| 8010 | Returns the value of the removed element. | 8166 | Returns the value of the removed element. |
| 8011 | The default value for <code>pos</code> is <code>n</code>, | 8167 | The default value for <code>pos</code> is <code>#list</code>, |
| 8012 | where <code>n</code> is the length of the table, | ||
| 8013 | so that a call <code>table.remove(t)</code> removes the last element | 8168 | so that a call <code>table.remove(t)</code> removes the last element |
| 8014 | of table <code>t</code>. | 8169 | of list <code>t</code>. |
| 8015 | 8170 | ||
| 8016 | 8171 | ||
| 8017 | 8172 | ||
| 8018 | 8173 | ||
| 8019 | <p> | 8174 | <p> |
| 8020 | <hr><h3><a name="pdf-table.sort"><code>table.sort (table [, comp])</code></a></h3> | 8175 | <hr><h3><a name="pdf-table.sort"><code>table.sort (list [, comp])</code></a></h3> |
| 8021 | Sorts table elements in a given order, <em>in-place</em>, | 8176 | |
| 8022 | from <code>table[1]</code> to <code>table[n]</code>, | 8177 | |
| 8023 | where <code>n</code> is the length of the table. | 8178 | <p> |
| 8179 | Sorts list elements in a given order, <em>in-place</em>, | ||
| 8180 | from <code>table[1]</code> to <code>table[#list]</code>. | ||
| 8024 | If <code>comp</code> is given, | 8181 | If <code>comp</code> is given, |
| 8025 | then it must be a function that receives two table elements | 8182 | then it must be a function that receives two list elements |
| 8026 | and returns true when the first element must come | 8183 | and returns true when the first element must come |
| 8027 | before the second in the final order | 8184 | before the second in the final order |
| 8028 | (so that <code>not comp(a[i+1],a[i])</code> will be true after the sort). | 8185 | (so that <code>not comp(a[i+1],a[i])</code> will be true after the sort). |
| @@ -8040,16 +8197,16 @@ may have their relative positions changed by the sort. · 11 unmodified lines | |||
| 8040 | 8197 | ||
| 8041 | <p> | 8198 | <p> |
| 8042 | <hr><h3><a name="pdf-table.unpack"><code>table.unpack (list [, i [, j]])</code></a></h3> | 8199 | <hr><h3><a name="pdf-table.unpack"><code>table.unpack (list [, i [, j]])</code></a></h3> |
| 8200 | |||
| 8201 | |||
| 8202 | <p> | ||
| 8043 | Returns the elements from the given table. | 8203 | Returns the elements from the given table. |
| 8044 | This function is equivalent to | 8204 | This function is equivalent to |
| 8045 | 8205 | ||
| 8046 | <pre> | 8206 | <pre> |
| 8047 | return list[i], list[i+1], ···, list[j] | 8207 | return list[i], list[i+1], ···, list[j] |
| 8048 | </pre><p> | 8208 | </pre><p> |
| 8049 | except that the above code can be written only for a fixed number | 8209 | By default, <code>i</code> is 1 and <code>j</code> is <code>#list</code>. |
| 8050 | of elements. | ||
| 8051 | By default, <code>i</code> is 1 and <code>j</code> is the length of the list, | ||
| 8052 | as defined by the length operator (see <a href="#3.4.6">§3.4.6</a>). | ||
| 8053 | 8210 | ||
| 8054 | 8211 | ||
| 8055 | 8212 | ||
| @@ -8386,7 +8543,7 @@ Returns the hyperbolic tangent of <code>x</code>. · 330 unmodified lines | |||
| 8386 | 8543 | ||
| 8387 | 8544 | ||
| 8388 | 8545 | ||
| 8389 | <h2>6.7 – <a name="6.7">Bitwise operations</a></h2> | 8546 | <h2>6.7 – <a name="6.7">Bitwise Operations</a></h2> |
| 8390 | 8547 | ||
| 8391 | <p> | 8548 | <p> |
| 8392 | This library provides bitwise operations. | 8549 | This library provides bitwise operations. |
| @@ -8468,7 +8625,7 @@ Returns the bitwise or of its operands. · 75 unmodified lines | |||
| 8468 | 8625 | ||
| 8469 | 8626 | ||
| 8470 | <p> | 8627 | <p> |
| 8471 | Returns a boolean signaling | 8628 | Returns a boolean signaling |
| 8472 | whether the bitwise and of its operands is different from zero. | 8629 | whether the bitwise and of its operands is different from zero. |
| 8473 | 8630 | ||
| 8474 | 8631 | ||
| @@ -8484,6 +8641,32 @@ Returns the bitwise exclusive or of its operands. · 9 unmodified lines | |||
| 8484 | 8641 | ||
| 8485 | 8642 | ||
| 8486 | 8643 | ||
| 8644 | <p> | ||
| 8645 | <hr><h3><a name="pdf-bit32.extract"><code>bit32.extract (n, field, width)</code></a></h3> | ||
| 8646 | |||
| 8647 | |||
| 8648 | <p> | ||
| 8649 | Returns the unsigned number formed by the bits | ||
| 8650 | <code>field</code> to <code>field + width - 1</code> from <code>n</code>. | ||
| 8651 | Bits are numbered from 0 (least significant) to 31 (most significant). | ||
| 8652 | All accessed bits must be in the range <em>[0, 31]</em>. | ||
| 8653 | |||
| 8654 | |||
| 8655 | |||
| 8656 | |||
| 8657 | <p> | ||
| 8658 | <hr><h3><a name="pdf-bit32.replace"><code>bit32.replace (n, v, field, width)</code></a></h3> | ||
| 8659 | |||
| 8660 | |||
| 8661 | <p> | ||
| 8662 | Returns a copy of <code>n</code> with | ||
| 8663 | the bits <code>field</code> to <code>field + width - 1</code> | ||
| 8664 | replaced by the value <code>v</code>. | ||
| 8665 | See <a href="#pdf-bit32.extract"><code>bit32.extract</code></a> for details about <code>field</code> and <code>width</code>. | ||
| 8666 | |||
| 8667 | |||
| 8668 | |||
| 8669 | |||
| 8487 | <p> | 8670 | <p> |
| 8488 | <hr><h3><a name="pdf-bit32.lrotate"><code>bit32.lrotate (x, disp)</code></a></h3> | 8671 | <hr><h3><a name="pdf-bit32.lrotate"><code>bit32.lrotate (x, disp)</code></a></h3> |
| 8489 | 8672 | ||
| @@ -8722,6 +8905,11 @@ Similar to <a href="#pdf-io.input"><code>io.input</code></a>, but operates over · 232 unmodified lines | |||
| 8722 | <hr><h3><a name="pdf-io.popen"><code>io.popen (prog [, mode])</code></a></h3> | 8905 | <hr><h3><a name="pdf-io.popen"><code>io.popen (prog [, mode])</code></a></h3> |
| 8723 | 8906 | ||
| 8724 | 8907 | ||
| 8908 | <p> | ||
| 8909 | This function is system dependent and is not available | ||
| 8910 | on all platforms. | ||
| 8911 | |||
| 8912 | |||
| 8725 | <p> | 8913 | <p> |
| 8726 | Starts program <code>prog</code> in a separated process and returns | 8914 | Starts program <code>prog</code> in a separated process and returns |
| 8727 | a file handle that you can use to read data from this program | 8915 | a file handle that you can use to read data from this program |
| @@ -8730,11 +8918,6 @@ or to write data to this program · 2 unmodified lines | |||
| 8730 | (if <code>mode</code> is <code>"w"</code>). | 8918 | (if <code>mode</code> is <code>"w"</code>). |
| 8731 | 8919 | ||
| 8732 | 8920 | ||
| 8733 | <p> | ||
| 8734 | This function is system dependent and is not available | ||
| 8735 | on all platforms. | ||
| 8736 | |||
| 8737 | |||
| 8738 | 8921 | ||
| 8739 | 8922 | ||
| 8740 | <p> | 8923 | <p> |
| @@ -8794,8 +8977,9 @@ but that takes an unpredictable amount of time to happen. · 53 unmodified lines | |||
| 8794 | 8977 | ||
| 8795 | 8978 | ||
| 8796 | <p> | 8979 | <p> |
| 8797 | If <code>file</code> was created with <a href="#pdf-io.popen"><code>io.popen</code></a>, | 8980 | When closing a file handle created with <a href="#pdf-io.popen"><code>io.popen</code></a>, |
| 8798 | a successful close returns the exit status of the process. | 8981 | <a href="#pdf-file:close"><code>file:close</code></a> returns the same values |
| 8982 | returned by <a href="#pdf-os.execute"><code>os.execute</code></a>. | ||
| 8799 | 8983 | ||
| 8800 | 8984 | ||
| 8801 | 8985 | ||
| @@ -9020,6 +9204,8 @@ then <code>date</code> returns a table with the following fields: · 218 unmodified lines | |||
| 9020 | <code>wday</code> (weekday, Sunday is 1), | 9204 | <code>wday</code> (weekday, Sunday is 1), |
| 9021 | <code>yday</code> (day of the year), | 9205 | <code>yday</code> (day of the year), |
| 9022 | and <code>isdst</code> (daylight saving flag, a boolean). | 9206 | and <code>isdst</code> (daylight saving flag, a boolean). |
| 9207 | This last field may be absent | ||
| 9208 | if the information is not available. | ||
| 9023 | 9209 | ||
| 9024 | 9210 | ||
| 9025 | <p> | 9211 | <p> |
| @@ -9056,9 +9242,28 @@ this value is exactly <code>t2</code><em>-</em><code>t1</code>. · 30 unmodified lines | |||
| 9056 | <p> | 9242 | <p> |
| 9057 | This function is equivalent to the C function <code>system</code>. | 9243 | This function is equivalent to the C function <code>system</code>. |
| 9058 | It passes <code>command</code> to be executed by an operating system shell. | 9244 | It passes <code>command</code> to be executed by an operating system shell. |
| 9059 | It returns a status code, which is system-dependent. | 9245 | It returns <b>true</b> |
| 9060 | If <code>command</code> is absent, then it returns nonzero if a shell is available | 9246 | if the command terminated successfully. |
| 9061 | and zero otherwise. | 9247 | Otherwise, it returns <b>nil</b> plus a string and a number, |
| 9248 | as follows: | ||
| 9249 | |||
| 9250 | <ul> | ||
| 9251 | |||
| 9252 | <li><b>"<code>exit</code>":</b> | ||
| 9253 | the command terminated normally; | ||
| 9254 | the following number is the exit status of the command. | ||
| 9255 | </li> | ||
| 9256 | |||
| 9257 | <li><b>"<code>signal</code>":</b> | ||
| 9258 | the command was terminated by a signal; | ||
| 9259 | the following number is the signal that terminated the command. | ||
| 9260 | </li> | ||
| 9261 | |||
| 9262 | </ul> | ||
| 9263 | |||
| 9264 | <p> | ||
| 9265 | When called without a <code>command</code>, | ||
| 9266 | <code>os.execute</code> returns a boolean that is true if a shell is available. | ||
| 9062 | 9267 | ||
| 9063 | 9268 | ||
| 9064 | 9269 | ||
| @@ -9072,10 +9277,10 @@ Calls the C function <code>exit</code> to terminate the host program. · 7 unmodified lines | |||
| 9072 | If <code>code</code> is <b>true</b>, | 9277 | If <code>code</code> is <b>true</b>, |
| 9073 | the returned status is <code>EXIT_SUCCESS</code>; | 9278 | the returned status is <code>EXIT_SUCCESS</code>; |
| 9074 | if <code>code</code> is <b>false</b>, | 9279 | if <code>code</code> is <b>false</b>, |
| 9075 | the returned status is <code>EXIT_FAILURE</code>. | 9280 | the returned status is <code>EXIT_FAILURE</code>; |
| 9076 | if <code>code</code> is a number, | 9281 | if <code>code</code> is a number, |
| 9077 | the returned status is this number. | 9282 | the returned status is this number. |
| 9078 | The default value for <code>code</code> is the success code. | 9283 | The default value for <code>code</code> is <b>true</b>. |
| 9079 | 9284 | ||
| 9080 | 9285 | ||
| 9081 | <p> | 9286 | <p> |
| @@ -9101,8 +9306,8 @@ or <b>nil</b> if the variable is not defined. · 19 unmodified lines | |||
| 9101 | 9306 | ||
| 9102 | 9307 | ||
| 9103 | <p> | 9308 | <p> |
| 9104 | Deletes the file or directory with the given name. | 9309 | Deletes the file (or empty directory, on POSIX systems) |
| 9105 | Directories must be empty to be removed. | 9310 | with the given name. |
| 9106 | If this function fails, it returns <b>nil</b>, | 9311 | If this function fails, it returns <b>nil</b>, |
| 9107 | plus a string describing the error. | 9312 | plus a string describing the error. |
| 9108 | 9313 | ||
| @@ -9165,7 +9370,8 @@ and may have fields <code>hour</code>, <code>min</code>, <code>sec</code>, and < · 56 unmodified lines | |||
| 9165 | 9370 | ||
| 9166 | <p> | 9371 | <p> |
| 9167 | The returned value is a number, whose meaning depends on your system. | 9372 | The returned value is a number, whose meaning depends on your system. |
| 9168 | In POSIX, Windows, and some other systems, this number counts the number | 9373 | In POSIX, Windows, and some other systems, |
| 9374 | this number counts the number | ||
| 9169 | of seconds since some given start time (the "epoch"). | 9375 | of seconds since some given start time (the "epoch"). |
| 9170 | In other systems, the meaning is not specified, | 9376 | In other systems, the meaning is not specified, |
| 9171 | and the number returned by <code>time</code> can be used only as an argument to | 9377 | and the number returned by <code>time</code> can be used only as an argument to |
| @@ -9186,7 +9392,7 @@ and explicitly removed when no longer needed. · 14 unmodified lines | |||
| 9186 | 9392 | ||
| 9187 | 9393 | ||
| 9188 | <p> | 9394 | <p> |
| 9189 | On some systems (POSIX), | 9395 | On POSIX systems, |
| 9190 | this function also creates a file with that name, | 9396 | this function also creates a file with that name, |
| 9191 | to avoid security risks. | 9397 | to avoid security risks. |
| 9192 | (Someone else might create the file with wrong permissions | 9398 | (Someone else might create the file with wrong permissions |
| @@ -9327,10 +9533,16 @@ about the <a href="#pdf-print"><code>print</code></a> function. · 134 unmodified lines | |||
| 9327 | <p> | 9533 | <p> |
| 9328 | This function returns the name and the value of the local variable | 9534 | This function returns the name and the value of the local variable |
| 9329 | with index <code>local</code> of the function at level <code>f</code> of the stack. | 9535 | with index <code>local</code> of the function at level <code>f</code> of the stack. |
| 9330 | (The first parameter or local variable has index 1, and so on, | 9536 | This function accesses not only explicit local variables, |
| 9331 | until the last active local variable.) | 9537 | but also parameters, temporaries, etc. |
| 9332 | The function returns <b>nil</b> if there is no local | 9538 | |
| 9333 | variable with the given index, | 9539 | |
| 9540 | <p> | ||
| 9541 | The first parameter or local variable has index 1, and so on, | ||
| 9542 | until the last active variable. | ||
| 9543 | Negative indices refer to vararg parameters; | ||
| 9544 | -1 is the first vararg parameter. | ||
| 9545 | The function returns <b>nil</b> if there is no variable with the given index, | ||
| 9334 | and raises an error when called with a level out of range. | 9546 | and raises an error when called with a level out of range. |
| 9335 | (You can call <a href="#pdf-debug.getinfo"><code>debug.getinfo</code></a> to check whether the level is valid.) | 9547 | (You can call <a href="#pdf-debug.getinfo"><code>debug.getinfo</code></a> to check whether the level is valid.) |
| 9336 | 9548 | ||
| @@ -9338,7 +9550,7 @@ and raises an error when called with a level out of range. · 1 unmodified line | |||
| 9338 | <p> | 9550 | <p> |
| 9339 | Variable names starting with '<code>(</code>' (open parentheses) | 9551 | Variable names starting with '<code>(</code>' (open parentheses) |
| 9340 | represent internal variables | 9552 | represent internal variables |
| 9341 | (loop control variables, temporaries, and C function locals). | 9553 | (loop control variables, temporaries, varargs, and C function locals). |
| 9342 | 9554 | ||
| 9343 | 9555 | ||
| 9344 | <p> | 9556 | <p> |
| @@ -9454,6 +9666,11 @@ and raises an error when called with a <code>level</code> out of range. · 109 unmodified lines | |||
| 9454 | Otherwise, it returns the name of the local variable. | 9666 | Otherwise, it returns the name of the local variable. |
| 9455 | 9667 | ||
| 9456 | 9668 | ||
| 9669 | <p> | ||
| 9670 | See <a href="#pdf-debug.getlocal"><code>debug.getlocal</code></a> for more information about | ||
| 9671 | variable indices and names. | ||
| 9672 | |||
| 9673 | |||
| 9457 | 9674 | ||
| 9458 | 9675 | ||
| 9459 | <p> | 9676 | <p> |
| @@ -9463,6 +9680,7 @@ Otherwise, it returns the name of the local variable. · 3 unmodified lines | |||
| 9463 | <p> | 9680 | <p> |
| 9464 | Sets the metatable for the given <code>object</code> to the given <code>table</code> | 9681 | Sets the metatable for the given <code>object</code> to the given <code>table</code> |
| 9465 | (which can be <b>nil</b>). | 9682 | (which can be <b>nil</b>). |
| 9683 | Returns <code>object</code>. | ||
| 9466 | 9684 | ||
| 9467 | 9685 | ||
| 9468 | 9686 | ||
| @@ -9482,14 +9700,14 @@ Otherwise, it returns the name of the upvalue. · 13 unmodified lines | |||
| 9482 | 9700 | ||
| 9483 | 9701 | ||
| 9484 | <p> | 9702 | <p> |
| 9485 | <hr><h3><a name="pdf-debug.traceback"><code>debug.traceback ([thread,] [message] [, level])</code></a></h3> | 9703 | <hr><h3><a name="pdf-debug.traceback"><code>debug.traceback ([thread,] [message [, level]])</code></a></h3> |
| 9486 | 9704 | ||
| 9487 | 9705 | ||
| 9488 | <p> | 9706 | <p> |
| 9489 | If <code>message</code> is present but is not a string, | 9707 | If <code>message</code> is present but is neither a string nor <b>nil</b>, |
| 9490 | this function returns <code>message</code> without further processing. | 9708 | this function returns <code>message</code> without further processing. |
| 9491 | Otherwise, | 9709 | Otherwise, |
| 9492 | returns a string with a traceback of the call stack. | 9710 | it returns a string with a traceback of the call stack. |
| 9493 | An optional <code>message</code> string is appended | 9711 | An optional <code>message</code> string is appended |
| 9494 | at the beginning of the traceback. | 9712 | at the beginning of the traceback. |
| 9495 | An optional <code>level</code> number tells at which level | 9713 | An optional <code>level</code> number tells at which level |
| @@ -9635,6 +9853,14 @@ Finally, if the error object is <b>nil</b>, · 139 unmodified lines | |||
| 9635 | the interpreter does not report the error. | 9853 | the interpreter does not report the error. |
| 9636 | 9854 | ||
| 9637 | 9855 | ||
| 9856 | <p> | ||
| 9857 | When finishing normally, | ||
| 9858 | the interpreter closes its main Lua state | ||
| 9859 | (see <a href="#lua_close"><code>lua_close</code></a>). | ||
| 9860 | The script can avoid this step by terminating | ||
| 9861 | through <a href="#pdf-os.exit"><code>os.exit</code></a>. | ||
| 9862 | |||
| 9863 | |||
| 9638 | <p> | 9864 | <p> |
| 9639 | If the global variable <a name="pdf-_PROMPT"><code>_PROMPT</code></a> contains a string, | 9865 | If the global variable <a name="pdf-_PROMPT"><code>_PROMPT</code></a> contains a string, |
| 9640 | then its value is used as the prompt. | 9866 | then its value is used as the prompt. |
| @@ -9671,12 +9897,12 @@ as in · 30 unmodified lines | |||
| 9671 | (Of course, | 9897 | (Of course, |
| 9672 | the location of the Lua interpreter can be different in your machine. | 9898 | the location of the Lua interpreter can be different in your machine. |
| 9673 | If <code>lua</code> is in your <code>PATH</code>, | 9899 | If <code>lua</code> is in your <code>PATH</code>, |
| 9674 | then | 9900 | then |
| 9675 | 9901 | ||
| 9676 | <pre> | 9902 | <pre> |
| 9677 | #!/usr/bin/env lua | 9903 | #!/usr/bin/env lua |
| 9678 | </pre><p> | 9904 | </pre><p> |
| 9679 | is a more portable solution.) | 9905 | is a more portable solution.) |
| 9680 | 9906 | ||
| 9681 | 9907 | ||
| 9682 | 9908 | ||
| @@ -9696,21 +9922,38 @@ all these compatibility options will be removed in the next version of Lua. · 13 unmodified lines | |||
| 9696 | <ul> | 9922 | <ul> |
| 9697 | 9923 | ||
| 9698 | <li> | 9924 | <li> |
| 9699 | Lua identifiers cannot use locale-dependent letters. | 9925 | The concept of <em>environment</em> changed. |
| 9926 | Only Lua functions have environments. | ||
| 9927 | To set the environment of a Lua function, | ||
| 9928 | use the variable <code>_ENV</code> or the function <a href="#pdf-load"><code>load</code></a>. | ||
| 9929 | |||
| 9930 | |||
| 9931 | <p> | ||
| 9932 | C functions do not have environments any more. | ||
| 9933 | Use an upvalue with a shared table if you need to keep | ||
| 9934 | shared state among several C functions. | ||
| 9935 | (You may use <a href="#luaL_setfuncs"><code>luaL_setfuncs</code></a> to open a C library | ||
| 9936 | with all functions sharing a common upvalue.) | ||
| 9937 | |||
| 9938 | |||
| 9939 | <p> | ||
| 9940 | To manipulate the "environment" of a userdata | ||
| 9941 | (which is now called user value), | ||
| 9942 | use the new functions | ||
| 9943 | <a href="#lua_getuservalue"><code>lua_getuservalue</code></a> and <a href="#lua_setuservalue"><code>lua_setuservalue</code></a>. | ||
| 9700 | </li> | 9944 | </li> |
| 9701 | 9945 | ||
| 9702 | <li> | 9946 | <li> |
| 9703 | Doing a step in the garbage collector does not restart the collector | 9947 | Lua identifiers cannot use locale-dependent letters. |
| 9704 | if it has been stopped. | ||
| 9705 | </li> | 9948 | </li> |
| 9706 | 9949 | ||
| 9707 | <li> | 9950 | <li> |
| 9708 | Weak tables with weak keys now perform like <em>ephemeron tables</em>. | 9951 | Doing a step or a full collection in the garbage collector |
| 9952 | does not restart the collector if it has been stopped. | ||
| 9709 | </li> | 9953 | </li> |
| 9710 | 9954 | ||
| 9711 | <li> | 9955 | <li> |
| 9712 | Threads do not have individual environments. | 9956 | Weak tables with weak keys now perform like <em>ephemeron tables</em>. |
| 9713 | All threads share a single fixed environment. | ||
| 9714 | </li> | 9957 | </li> |
| 9715 | 9958 | ||
| 9716 | <li> | 9959 | <li> |
| @@ -9720,6 +9963,13 @@ Instead, tail calls generate a special new event, · 3 unmodified lines | |||
| 9720 | not be a corresponding return event. | 9963 | not be a corresponding return event. |
| 9721 | </li> | 9964 | </li> |
| 9722 | 9965 | ||
| 9966 | <li> | ||
| 9967 | Equality between function values has changed. | ||
| 9968 | Now, a function definition may not create a new value; | ||
| 9969 | it may reuse some previous value if there is no | ||
| 9970 | observable difference to the new function. | ||
| 9971 | </li> | ||
| 9972 | |||
| 9723 | </ul> | 9973 | </ul> |
| 9724 | 9974 | ||
| 9725 | 9975 | ||
| @@ -9735,9 +9985,8 @@ and it is easy to set up a module with regular Lua code. · 9 unmodified lines | |||
| 9735 | </li> | 9985 | </li> |
| 9736 | 9986 | ||
| 9737 | <li> | 9987 | <li> |
| 9738 | Functions <code>setfenv</code> and <code>getfenv</code> are deprecated. | 9988 | Functions <code>setfenv</code> and <code>getfenv</code> are deprecated, |
| 9739 | To set the environment of a Lua function, | 9989 | because of the changes in environments. |
| 9740 | use the variable <code>_ENV</code> or the new function <a href="#pdf-loadin"><code>loadin</code></a>. | ||
| 9741 | </li> | 9990 | </li> |
| 9742 | 9991 | ||
| 9743 | <li> | 9992 | <li> |
| @@ -9745,11 +9994,23 @@ Function <code>math.log10</code> is deprecated. · 1 unmodified line | |||
| 9745 | Use <a href="#pdf-math.log"><code>math.log</code></a> with 10 as its second argument, instead. | 9994 | Use <a href="#pdf-math.log"><code>math.log</code></a> with 10 as its second argument, instead. |
| 9746 | </li> | 9995 | </li> |
| 9747 | 9996 | ||
| 9997 | <li> | ||
| 9998 | Function <code>loadstring</code> is deprecated. | ||
| 9999 | Use <code>load</code> instead; it now accepts string arguments | ||
| 10000 | and are exactly equivalent to <code>loadstring</code>. | ||
| 10001 | </li> | ||
| 10002 | |||
| 9748 | <li> | 10003 | <li> |
| 9749 | Function <code>table.maxn</code> is deprecated. | 10004 | Function <code>table.maxn</code> is deprecated. |
| 9750 | Write it in Lua if you really need it. | 10005 | Write it in Lua if you really need it. |
| 9751 | </li> | 10006 | </li> |
| 9752 | 10007 | ||
| 10008 | <li> | ||
| 10009 | Function <code>os.execute</code> now returns <b>true</b> when command | ||
| 10010 | terminates successfully and <b>nil</b> plus error information | ||
| 10011 | otherwise. | ||
| 10012 | </li> | ||
| 10013 | |||
| 9753 | <li> | 10014 | <li> |
| 9754 | Function <code>unpack</code> was moved into the table library | 10015 | Function <code>unpack</code> was moved into the table library |
| 9755 | and therefore must be called as <a href="#pdf-table.unpack"><code>table.unpack</code></a>. | 10016 | and therefore must be called as <a href="#pdf-table.unpack"><code>table.unpack</code></a>. |
| @@ -9763,7 +10024,7 @@ as now patterns may contain '<code>\0</code>' as a regular character. · 7 unmodified lines | |||
| 9763 | <li> | 10024 | <li> |
| 9764 | Lua does not have bytecode verification anymore. | 10025 | Lua does not have bytecode verification anymore. |
| 9765 | So, all functions that load code | 10026 | So, all functions that load code |
| 9766 | (<a href="#pdf-load"><code>load</code></a>, <a href="#pdf-loadfile"><code>loadfile</code></a>, <a href="#pdf-loadstring"><code>loadstring</code></a>) | 10027 | (<a href="#pdf-load"><code>load</code></a> and <a href="#pdf-loadfile"><code>loadfile</code></a>) |
| 9767 | are potentially insecure when loading untrusted binary data. | 10028 | are potentially insecure when loading untrusted binary data. |
| 9768 | (Actually, those functions were already insecure because | 10029 | (Actually, those functions were already insecure because |
| 9769 | of bugs in the verification algorithm.) | 10030 | of bugs in the verification algorithm.) |
| @@ -9789,19 +10050,8 @@ You must get the global environment from the registry · 19 unmodified lines | |||
| 9789 | <li> | 10050 | <li> |
| 9790 | Pseudoindex <code>LUA_ENVIRONINDEX</code> | 10051 | Pseudoindex <code>LUA_ENVIRONINDEX</code> |
| 9791 | and functions <code>lua_getfenv</code>/<code>lua_setfenv</code> | 10052 | and functions <code>lua_getfenv</code>/<code>lua_setfenv</code> |
| 9792 | were removed. | 10053 | were removed, |
| 9793 | C functions do not have environments any more. | 10054 | as C functions do not have environments any more. |
| 9794 | Use an upvalue with a shared table if you need to keep | ||
| 9795 | shared state among several C functions. | ||
| 9796 | (You may use <a href="#luaL_setfuncs"><code>luaL_setfuncs</code></a> to open a C library | ||
| 9797 | with all functions sharing a common upvalue.) | ||
| 9798 | |||
| 9799 | |||
| 9800 | <p> | ||
| 9801 | To manipulate the "environment" of a userdata | ||
| 9802 | (which is not called "environment" anymore), | ||
| 9803 | use the new functions | ||
| 9804 | <a href="#lua_getuservalue"><code>lua_getuservalue</code></a> and <a href="#lua_setuservalue"><code>lua_setuservalue</code></a>. | ||
| 9805 | </li> | 10055 | </li> |
| 9806 | 10056 | ||
| 9807 | <li> | 10057 | <li> |
| @@ -9812,12 +10062,21 @@ create globals anymore. · 4 unmodified lines | |||
| 9812 | </li> | 10062 | </li> |
| 9813 | 10063 | ||
| 9814 | <li> | 10064 | <li> |
| 9815 | Finalizers ("<code>__gc</code>" metamethods) for userdata are called in the | 10065 | The <code>osize</code> argument to the allocation function |
| 10066 | may not be zero when creating a new block, | ||
| 10067 | that is, when <code>ptr</code> is <code>NULL</code> | ||
| 10068 | (see <a href="#lua_Alloc"><code>lua_Alloc</code></a>). | ||
| 10069 | Use only the test <code>ptr == NULL</code> to check whether | ||
| 10070 | the block is new. | ||
| 10071 | </li> | ||
| 10072 | |||
| 10073 | <li> | ||
| 10074 | Finalizers (<code>__gc</code> metamethods) for userdata are called in the | ||
| 9816 | reverse order that they were marked, | 10075 | reverse order that they were marked, |
| 9817 | not that they were created (see <a href="#2.5.1">§2.5.1</a>). | 10076 | not that they were created (see <a href="#2.5.1">§2.5.1</a>). |
| 9818 | (Most userdata are marked immediately after they are created.) | 10077 | (Most userdata are marked immediately after they are created.) |
| 9819 | Moreover, | 10078 | Moreover, |
| 9820 | if the metatable does not have a "<code>__gc</code>" field when set, | 10079 | if the metatable does not have a <code>__gc</code> field when set, |
| 9821 | the finalizer will not be called, | 10080 | the finalizer will not be called, |
| 9822 | even if it is set later. | 10081 | even if it is set later. |
| 9823 | </li> | 10082 | </li> |
| @@ -9860,11 +10119,14 @@ Here is the complete syntax of Lua in extended BNF. · 36 unmodified lines | |||
| 9860 | 10119 | ||
| 9861 | chunk ::= block | 10120 | chunk ::= block |
| 9862 | 10121 | ||
| 9863 | block ::= {stat} [laststat [‘<b>;</b>’]] | 10122 | block ::= {stat} [retstat] |
| 9864 | 10123 | ||
| 9865 | stat ::= ‘<b>;</b>’ | | 10124 | stat ::= ‘<b>;</b>’ | |
| 9866 | varlist ‘<b>=</b>’ explist | | 10125 | varlist ‘<b>=</b>’ explist | |
| 9867 | functioncall | | 10126 | functioncall | |
| 10127 | label | | ||
| 10128 | <b>break</b> | | ||
| 10129 | <b>goto</b> Name | | ||
| 9868 | <b>do</b> block <b>end</b> | | 10130 | <b>do</b> block <b>end</b> | |
| 9869 | <b>while</b> exp <b>do</b> block <b>end</b> | | 10131 | <b>while</b> exp <b>do</b> block <b>end</b> | |
| 9870 | <b>repeat</b> block <b>until</b> exp | | 10132 | <b>repeat</b> block <b>until</b> exp | |
| @@ -9875,7 +10137,9 @@ Here is the complete syntax of Lua in extended BNF. · 4 unmodified lines | |||
| 9875 | <b>local</b> <b>function</b> Name funcbody | | 10137 | <b>local</b> <b>function</b> Name funcbody | |
| 9876 | <b>local</b> namelist [‘<b>=</b>’ explist] | 10138 | <b>local</b> namelist [‘<b>=</b>’ explist] |
| 9877 | 10139 | ||
| 9878 | laststat ::= <b>return</b> [explist] | <b>break</b> | 10140 | retstat ::= <b>return</b> [explist] [‘<b>;</b>’] |
| 10141 | |||
| 10142 | label ::= ‘<b>@</b>’ Name ‘<b>:</b>’ | ||
| 9879 | 10143 | ||
| 9880 | funcname ::= Name {‘<b>.</b>’ Name} [‘<b>:</b>’ Name] | 10144 | funcname ::= Name {‘<b>.</b>’ Name} [‘<b>:</b>’ Name] |
| 9881 | 10145 | ||
| @@ -9885,7 +10149,7 @@ Here is the complete syntax of Lua in extended BNF. · 3 unmodified lines | |||
| 9885 | 10149 | ||
| 9886 | namelist ::= Name {‘<b>,</b>’ Name} | 10150 | namelist ::= Name {‘<b>,</b>’ Name} |
| 9887 | 10151 | ||
| 9888 | explist ::= {exp ‘<b>,</b>’} exp | 10152 | explist ::= exp {‘<b>,</b>’ exp} |
| 9889 | 10153 | ||
| 9890 | exp ::= <b>nil</b> | <b>false</b> | <b>true</b> | Number | String | ‘<b>...</b>’ | function | | 10154 | exp ::= <b>nil</b> | <b>false</b> | <b>true</b> | Number | String | ‘<b>...</b>’ | function | |
| 9891 | prefixexp | tableconstructor | exp binop exp | unop exp | 10155 | prefixexp | tableconstructor | exp binop exp | unop exp |
| @@ -9896,7 +10160,7 @@ Here is the complete syntax of Lua in extended BNF. · 4 unmodified lines | |||
| 9896 | 10160 | ||
| 9897 | args ::= ‘<b>(</b>’ [explist] ‘<b>)</b>’ | tableconstructor | String | 10161 | args ::= ‘<b>(</b>’ [explist] ‘<b>)</b>’ | tableconstructor | String |
| 9898 | 10162 | ||
| 9899 | function ::= <b>function</b> funcbody | 10163 | functiondef ::= <b>function</b> funcbody |
| 9900 | 10164 | ||
| 9901 | funcbody ::= ‘<b>(</b>’ [parlist] ‘<b>)</b>’ block <b>end</b> | 10165 | funcbody ::= ‘<b>(</b>’ [parlist] ‘<b>)</b>’ block <b>end</b> |
| 9902 | 10166 | ||
| @@ -9929,10 +10193,10 @@ Here is the complete syntax of Lua in extended BNF. · 26 unmodified lines | |||
| 9929 | <HR> | 10193 | <HR> |
| 9930 | <SMALL> | 10194 | <SMALL> |
| 9931 | Last update: | 10195 | Last update: |
| 9932 | Mon Nov 22 16:36:19 BRST 2010 | 10196 | Mon Jun 13 14:56:14 BRT 2011 |
| 9933 | </SMALL> | 10197 | </SMALL> |
| 9934 | <!-- | 10198 | <!-- |
| 9935 | Last change: revised for Lua 5.2.0 (alpha) | 10199 | Last change: revised for Lua 5.2.0 (beta) |
| 9936 | --> | 10200 | --> |
| 9937 | 10201 | ||
| 9938 | </body></html> | 10202 | </body></html> |
| @@ -27,12 +27,12 @@ tt, kbd, code { · 26 unmodified lines | |||
| 27 | <HR> | 27 | <HR> |
| 28 | <H1> | 28 | <H1> |
| 29 | <A HREF="http://www.lua.org/"><IMG SRC="logo.gif" ALT="Lua" BORDER=0></A> | 29 | <A HREF="http://www.lua.org/"><IMG SRC="logo.gif" ALT="Lua" BORDER=0></A> |
| 30 | Welcome to Lua 5.2 (alpha) | 30 | Welcome to Lua 5.2 (beta) |
| 31 | </H1> | 31 | </H1> |
| 32 | 32 | ||
| 33 | <P> | 33 | <P> |
| 34 | <IMG SRC="alert.png" ALIGN="absbottom" ALT="[!]"> | 34 | <IMG SRC="alert.png" ALIGN="absbottom" ALT="[!]"> |
| 35 | <EM>This is an alpha version of Lua 5.2. | 35 | <EM>This is a beta version of Lua 5.2. |
| 36 | Some details may change in the final version.</EM> | 36 | Some details may change in the final version.</EM> |
| 37 | 37 | ||
| 38 | <P> | 38 | <P> |
| @@ -278,11 +278,13 @@ lists the · 239 unmodified lines | |||
| 278 | <H3>Main changes</H3> | 278 | <H3>Main changes</H3> |
| 279 | <UL> | 279 | <UL> |
| 280 | <LI> yieldable pcall and metamethods | 280 | <LI> yieldable pcall and metamethods |
| 281 | <LI> new <CODE>_ENV</CODE> scheme | 281 | <LI> new lexical scheme for globals |
| 282 | <LI> ephemeron tables | 282 | <LI> ephemeron tables |
| 283 | <LI> new library for bitwise operations | 283 | <LI> new library for bitwise operations |
| 284 | <LI> light C functions | 284 | <LI> light C functions |
| 285 | <LI> emergency garbage collector | 285 | <LI> emergency garbage collector |
| 286 | <LI> <CODE>goto</CODE> statement | ||
| 287 | <LI> finalizers for tables | ||
| 286 | </UL> | 288 | </UL> |
| 287 | 289 | ||
| 288 | Here are the other changes introduced in Lua 5.2: | 290 | Here are the other changes introduced in Lua 5.2: |
| @@ -291,29 +293,34 @@ Here are the other changes introduced in Lua 5.2: · 2 unmodified lines | |||
| 291 | <LI> no more fenv for threads or functions | 293 | <LI> no more fenv for threads or functions |
| 292 | <LI> tables honor the <CODE>__len</CODE> metamethod | 294 | <LI> tables honor the <CODE>__len</CODE> metamethod |
| 293 | <LI> hex and <CODE>\*</CODE> escapes in strings | 295 | <LI> hex and <CODE>\*</CODE> escapes in strings |
| 296 | <LI> support for hexadecimal floats | ||
| 294 | <LI> order metamethods work for different types | 297 | <LI> order metamethods work for different types |
| 295 | <LI> no more verification of opcode consistency | 298 | <LI> no more verification of opcode consistency |
| 296 | <LI> hook event "tail return" replaced by "tail call" | 299 | <LI> hook event "tail return" replaced by "tail call" |
| 297 | <LI> empty statement | 300 | <LI> empty statement |
| 301 | <LI> <CODE>break</CODE> statement may appear in the middle of a block | ||
| 298 | </UL> | 302 | </UL> |
| 299 | 303 | ||
| 300 | <H3>Libraries</H3> | 304 | <H3>Libraries</H3> |
| 301 | <UL> | 305 | <UL> |
| 302 | <LI> new metamethods <CODE>__pairs</CODE> and <CODE>__ipairs</CODE> | ||
| 303 | <LI> arguments for function called through <CODE>xpcall</CODE> | 306 | <LI> arguments for function called through <CODE>xpcall</CODE> |
| 304 | <LI> optional 'mode' argument to load (to control binary x text) | 307 | <LI> optional 'mode' argument to load (to control binary x text) |
| 305 | <LI> new function <CODE>loadin</CODE> | 308 | <LI> optional 'env' argument to load (environment for loaded chunk) |
| 306 | <LI> <CODE>loadlib</CODE> may load libraries with global names (RTLD_GLOBAL) | 309 | <LI> <CODE>loadlib</CODE> may load libraries with global names (RTLD_GLOBAL) |
| 307 | <LI> new function <CODE>package.searchpath</CODE> | 310 | <LI> new function <CODE>package.searchpath</CODE> |
| 311 | <LI> modules receive their paths when loaded | ||
| 308 | <LI> optional base in <CODE>math.log</CODE> | 312 | <LI> optional base in <CODE>math.log</CODE> |
| 313 | <LI> optional separator in <CODE>string.rep</CODE> | ||
| 309 | <LI> <CODE>file:write</CODE> returns <CODE>file</CODE> | 314 | <LI> <CODE>file:write</CODE> returns <CODE>file</CODE> |
| 310 | <LI> closing a pipe returns exit status | 315 | <LI> closing a pipe returns exit status |
| 311 | <LI> <CODE>os.exit</CODE> may close state | 316 | <LI> <CODE>os.exit</CODE> may close state |
| 317 | <LI> new metamethods <CODE>__pairs</CODE> and <CODE>__ipairs</CODE> | ||
| 312 | <LI> new option 'isrunning' for <CODE>collectgarbage</CODE> and <CODE>lua_gc</CODE> | 318 | <LI> new option 'isrunning' for <CODE>collectgarbage</CODE> and <CODE>lua_gc</CODE> |
| 313 | <LI> frontier patterns | 319 | <LI> frontier patterns |
| 314 | <LI> <CODE>\0</CODE> in patterns | 320 | <LI> <CODE>\0</CODE> in patterns |
| 315 | <LI> new option <CODE>*L</CODE> for <CODE>io.read</CODE> | 321 | <LI> new option <CODE>*L</CODE> for <CODE>io.read</CODE> |
| 316 | <LI> options for <CODE>io.lines</CODE> | 322 | <LI> options for <CODE>io.lines</CODE> |
| 323 | <LI> <CODE>debug.getlocal</CODE> can access function varargs | ||
| 317 | </UL> | 324 | </UL> |
| 318 | 325 | ||
| 319 | <H3>C API</H3> | 326 | <H3>C API</H3> |
| @@ -321,7 +328,7 @@ Here are the other changes introduced in Lua 5.2: · 1 unmodified line | |||
| 321 | <LI> main thread predefined in the registry | 328 | <LI> main thread predefined in the registry |
| 322 | <LI> new constants <CODE>LUA_OK</CODE> and <CODE>LUA_ERRGCMM</CODE> | 329 | <LI> new constants <CODE>LUA_OK</CODE> and <CODE>LUA_ERRGCMM</CODE> |
| 323 | <LI> new <CODE>lua_compare</CODE>, <CODE>lua_arith</CODE>, and <CODE>lua_len</CODE> | 330 | <LI> new <CODE>lua_compare</CODE>, <CODE>lua_arith</CODE>, and <CODE>lua_len</CODE> |
| 324 | <LI> new <CODE>lua_version</CODE> and <CODE>luaL_version</CODE> | 331 | <LI> new <CODE>lua_version</CODE> and <CODE>luaL_checkversion</CODE> |
| 325 | <LI> <CODE>lua_pushstring</CODE> and <CODE>pushlstring</CODE> return string | 332 | <LI> <CODE>lua_pushstring</CODE> and <CODE>pushlstring</CODE> return string |
| 326 | <LI> new <CODE>luaL_testudata</CODE> and <CODE>luaL_setmetatable</CODE> | 333 | <LI> new <CODE>luaL_testudata</CODE> and <CODE>luaL_setmetatable</CODE> |
| 327 | <LI> new <CODE>luaL_tolstring</CODE> | 334 | <LI> new <CODE>luaL_tolstring</CODE> |
| @@ -364,7 +371,7 @@ For details, see · 36 unmodified lines | |||
| 364 | <A HREF="http://www.lua.org/license.html">this</A>. | 371 | <A HREF="http://www.lua.org/license.html">this</A>. |
| 365 | 372 | ||
| 366 | <BLOCKQUOTE> | 373 | <BLOCKQUOTE> |
| 367 | Copyright © 1994–2010 Lua.org, PUC-Rio. | 374 | Copyright © 1994–2011 Lua.org, PUC-Rio. |
| 368 | 375 | ||
| 369 | <P> | 376 | <P> |
| 370 | Permission is hereby granted, free of charge, to any person obtaining a copy | 377 | Permission is hereby granted, free of charge, to any person obtaining a copy |
| @@ -391,10 +398,10 @@ THE SOFTWARE. · 20 unmodified lines | |||
| 391 | <HR> | 398 | <HR> |
| 392 | <SMALL> | 399 | <SMALL> |
| 393 | Last update: | 400 | Last update: |
| 394 | Sat Nov 20 19:23:14 BRST 2010 | 401 | Mon Jun 13 15:07:49 BRT 2011 |
| 395 | </SMALL> | 402 | </SMALL> |
| 396 | <!-- | 403 | <!-- |
| 397 | Last change: revised for Lua 5.2.0 (alpha) | 404 | Last change: revised for Lua 5.2.0 (beta) |
| 398 | --> | 405 | --> |
| 399 | 406 | ||
| 400 | </BODY> | 407 | </BODY> |
| @@ -126,7 +126,7 @@ lbaselib.o: lbaselib.c lua.h luaconf.h lauxlib.h lualib.h · 125 unmodified lines | |||
| 126 | lbitlib.o: lbitlib.c lua.h luaconf.h lauxlib.h lualib.h | 126 | lbitlib.o: lbitlib.c lua.h luaconf.h lauxlib.h lualib.h |
| 127 | lcode.o: lcode.c lua.h luaconf.h lcode.h llex.h lobject.h llimits.h \ | 127 | lcode.o: lcode.c lua.h luaconf.h lcode.h llex.h lobject.h llimits.h \ |
| 128 | lzio.h lmem.h lopcodes.h lparser.h ldebug.h lstate.h ltm.h ldo.h lgc.h \ | 128 | lzio.h lmem.h lopcodes.h lparser.h ldebug.h lstate.h ltm.h ldo.h lgc.h \ |
| 129 | lstring.h ltable.h | 129 | lstring.h ltable.h lvm.h |
| 130 | lcorolib.o: lcorolib.c lua.h luaconf.h lauxlib.h lualib.h | 130 | lcorolib.o: lcorolib.c lua.h luaconf.h lauxlib.h lualib.h |
| 131 | lctype.o: lctype.c lctype.h lua.h luaconf.h llimits.h | 131 | lctype.o: lctype.c lctype.h lua.h luaconf.h llimits.h |
| 132 | ldblib.o: ldblib.c lua.h luaconf.h lauxlib.h lualib.h | 132 | ldblib.o: ldblib.c lua.h luaconf.h lauxlib.h lualib.h |
| @@ -164,7 +164,7 @@ lstring.o: lstring.c lua.h luaconf.h lmem.h llimits.h lobject.h lstate.h \ · 31 unmodified lines | |||
| 164 | ltm.h lzio.h lstring.h lgc.h | 164 | ltm.h lzio.h lstring.h lgc.h |
| 165 | lstrlib.o: lstrlib.c lua.h luaconf.h lauxlib.h lualib.h | 165 | lstrlib.o: lstrlib.c lua.h luaconf.h lauxlib.h lualib.h |
| 166 | ltable.o: ltable.c lua.h luaconf.h ldebug.h lstate.h lobject.h llimits.h \ | 166 | ltable.o: ltable.c lua.h luaconf.h ldebug.h lstate.h lobject.h llimits.h \ |
| 167 | ltm.h lzio.h lmem.h ldo.h lgc.h lstring.h ltable.h | 167 | ltm.h lzio.h lmem.h ldo.h lgc.h lstring.h ltable.h lvm.h |
| 168 | ltablib.o: ltablib.c lua.h luaconf.h lauxlib.h lualib.h | 168 | ltablib.o: ltablib.c lua.h luaconf.h lauxlib.h lualib.h |
| 169 | ltm.o: ltm.c lua.h luaconf.h lobject.h llimits.h lstate.h ltm.h lzio.h \ | 169 | ltm.o: ltm.c lua.h luaconf.h lobject.h llimits.h lstate.h ltm.h lzio.h \ |
| 170 | lmem.h lstring.h lgc.h ltable.h | 170 | lmem.h lstring.h lgc.h ltable.h |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lapi.c,v 2.140 2010/11/03 15:16:17 roberto Exp $ | 2 | ** $Id: lapi.c,v 2.149 2011/06/13 14:13:06 roberto Exp $ |
| 3 | ** Lua API | 3 | ** Lua API |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -59,9 +59,9 @@ static TValue *index2addr (lua_State *L, int idx) { · 53 unmodified lines | |||
| 59 | if (ttislcf(ci->func)) /* light C function? */ | 59 | if (ttislcf(ci->func)) /* light C function? */ |
| 60 | return cast(TValue *, luaO_nilobject); /* it has no upvalues */ | 60 | return cast(TValue *, luaO_nilobject); /* it has no upvalues */ |
| 61 | else { | 61 | else { |
| 62 | Closure *func = clvalue(ci->func); | 62 | CClosure *func = clCvalue(ci->func); |
| 63 | return (idx <= func->c.nupvalues) | 63 | return (idx <= func->nupvalues) |
| 64 | ? &func->c.upvalue[idx-1] | 64 | ? &func->upvalue[idx-1] |
| 65 | : cast(TValue *, luaO_nilobject); | 65 | : cast(TValue *, luaO_nilobject); |
| 66 | } | 66 | } |
| 67 | } | 67 | } |
| @@ -195,10 +195,8 @@ static void moveto (lua_State *L, TValue *fr, int idx) { · 127 unmodified lines | |||
| 195 | TValue *to = index2addr(L, idx); | 195 | TValue *to = index2addr(L, idx); |
| 196 | api_checkvalidindex(L, to); | 196 | api_checkvalidindex(L, to); |
| 197 | setobj(L, to, fr); | 197 | setobj(L, to, fr); |
| 198 | if (idx < LUA_REGISTRYINDEX) { /* function upvalue? */ | 198 | if (idx < LUA_REGISTRYINDEX) /* function upvalue? */ |
| 199 | lua_assert(ttisclosure(L->ci->func)); | 199 | luaC_barrier(L, clCvalue(L->ci->func), fr); |
| 200 | luaC_barrier(L, clvalue(L->ci->func), fr); | ||
| 201 | } | ||
| 202 | /* LUA_REGISTRYINDEX does not need gc barrier | 200 | /* LUA_REGISTRYINDEX does not need gc barrier |
| 203 | (collector revisits it before finishing collection) */ | 201 | (collector revisits it before finishing collection) */ |
| 204 | } | 202 | } |
| @@ -251,7 +249,7 @@ LUA_API const char *lua_typename (lua_State *L, int t) { · 46 unmodified lines | |||
| 251 | 249 | ||
| 252 | LUA_API int lua_iscfunction (lua_State *L, int idx) { | 250 | LUA_API int lua_iscfunction (lua_State *L, int idx) { |
| 253 | StkId o = index2addr(L, idx); | 251 | StkId o = index2addr(L, idx); |
| 254 | return (ttislcf(o) || (ttisclosure(o) && clvalue(o)->c.isC)); | 252 | return (ttislcf(o) || (ttisCclosure(o))); |
| 255 | } | 253 | } |
| 256 | 254 | ||
| 257 | 255 | ||
| @@ -278,20 +276,28 @@ LUA_API int lua_rawequal (lua_State *L, int index1, int index2) { · 20 unmodified lines | |||
| 278 | StkId o1 = index2addr(L, index1); | 276 | StkId o1 = index2addr(L, index1); |
| 279 | StkId o2 = index2addr(L, index2); | 277 | StkId o2 = index2addr(L, index2); |
| 280 | return (o1 == luaO_nilobject || o2 == luaO_nilobject) ? 0 | 278 | return (o1 == luaO_nilobject || o2 == luaO_nilobject) ? 0 |
| 281 | : luaO_rawequalObj(o1, o2); | 279 | : luaV_rawequalobj(o1, o2); |
| 282 | } | 280 | } |
| 283 | 281 | ||
| 284 | 282 | ||
| 285 | LUA_API void lua_arith (lua_State *L, int op) { | 283 | LUA_API void lua_arith (lua_State *L, int op) { |
| 284 | StkId o1; /* 1st operand */ | ||
| 285 | StkId o2; /* 2nd operand */ | ||
| 286 | lua_lock(L); | 286 | lua_lock(L); |
| 287 | api_checknelems(L, 2); | 287 | if (op != LUA_OPUNM) /* all other operations expect two operands */ |
| 288 | if (ttisnumber(L->top - 2) && ttisnumber(L->top - 1)) { | 288 | api_checknelems(L, 2); |
| 289 | changenvalue(L->top - 2, | 289 | else { /* for unary minus, add fake 2nd operand */ |
| 290 | luaO_arith(op, nvalue(L->top - 2), nvalue(L->top - 1))); | 290 | api_checknelems(L, 1); |
| 291 | setobjs2s(L, L->top, L->top - 1); | ||
| 292 | L->top++; | ||
| 293 | } | ||
| 294 | o1 = L->top - 2; | ||
| 295 | o2 = L->top - 1; | ||
| 296 | if (ttisnumber(o1) && ttisnumber(o2)) { | ||
| 297 | changenvalue(o1, luaO_arith(op, nvalue(o1), nvalue(o2))); | ||
| 291 | } | 298 | } |
| 292 | else | 299 | else |
| 293 | luaV_arith(L, L->top - 2, L->top - 2, L->top - 1, | 300 | luaV_arith(L, o1, o1, o2, cast(TMS, op - LUA_OPADD + TM_ADD)); |
| 294 | cast(TMS, op - LUA_OPADD + TM_ADD)); | ||
| 295 | L->top--; | 301 | L->top--; |
| 296 | lua_unlock(L); | 302 | lua_unlock(L); |
| 297 | } | 303 | } |
| @@ -390,7 +396,7 @@ LUA_API const char *lua_tolstring (lua_State *L, int idx, size_t *len) { · 92 unmodified lines | |||
| 390 | 396 | ||
| 391 | LUA_API size_t lua_rawlen (lua_State *L, int idx) { | 397 | LUA_API size_t lua_rawlen (lua_State *L, int idx) { |
| 392 | StkId o = index2addr(L, idx); | 398 | StkId o = index2addr(L, idx); |
| 393 | switch (ttype(o)) { | 399 | switch (ttypenv(o)) { |
| 394 | case LUA_TSTRING: return tsvalue(o)->len; | 400 | case LUA_TSTRING: return tsvalue(o)->len; |
| 395 | case LUA_TUSERDATA: return uvalue(o)->len; | 401 | case LUA_TUSERDATA: return uvalue(o)->len; |
| 396 | case LUA_TTABLE: return luaH_getn(hvalue(o)); | 402 | case LUA_TTABLE: return luaH_getn(hvalue(o)); |
| @@ -402,15 +408,15 @@ LUA_API size_t lua_rawlen (lua_State *L, int idx) { · 5 unmodified lines | |||
| 402 | LUA_API lua_CFunction lua_tocfunction (lua_State *L, int idx) { | 408 | LUA_API lua_CFunction lua_tocfunction (lua_State *L, int idx) { |
| 403 | StkId o = index2addr(L, idx); | 409 | StkId o = index2addr(L, idx); |
| 404 | if (ttislcf(o)) return fvalue(o); | 410 | if (ttislcf(o)) return fvalue(o); |
| 405 | else if (ttisclosure(o) && clvalue(o)->c.isC) | 411 | else if (ttisCclosure(o)) |
| 406 | return clvalue(o)->c.f; | 412 | return clCvalue(o)->f; |
| 407 | else return NULL; /* not a C function */ | 413 | else return NULL; /* not a C function */ |
| 408 | } | 414 | } |
| 409 | 415 | ||
| 410 | 416 | ||
| 411 | LUA_API void *lua_touserdata (lua_State *L, int idx) { | 417 | LUA_API void *lua_touserdata (lua_State *L, int idx) { |
| 412 | StkId o = index2addr(L, idx); | 418 | StkId o = index2addr(L, idx); |
| 413 | switch (ttype(o)) { | 419 | switch (ttypenv(o)) { |
| 414 | case LUA_TUSERDATA: return (rawuvalue(o) + 1); | 420 | case LUA_TUSERDATA: return (rawuvalue(o) + 1); |
| 415 | case LUA_TLIGHTUSERDATA: return pvalue(o); | 421 | case LUA_TLIGHTUSERDATA: return pvalue(o); |
| 416 | default: return NULL; | 422 | default: return NULL; |
| @@ -428,7 +434,8 @@ LUA_API const void *lua_topointer (lua_State *L, int idx) { · 11 unmodified lines | |||
| 428 | StkId o = index2addr(L, idx); | 434 | StkId o = index2addr(L, idx); |
| 429 | switch (ttype(o)) { | 435 | switch (ttype(o)) { |
| 430 | case LUA_TTABLE: return hvalue(o); | 436 | case LUA_TTABLE: return hvalue(o); |
| 431 | case LUA_TFUNCTION: return clvalue(o); | 437 | case LUA_TLCL: return clLvalue(o); |
| 438 | case LUA_TCCL: return clCvalue(o); | ||
| 432 | case LUA_TLCF: return cast(void *, cast(size_t, fvalue(o))); | 439 | case LUA_TLCF: return cast(void *, cast(size_t, fvalue(o))); |
| 433 | case LUA_TTHREAD: return thvalue(o); | 440 | case LUA_TTHREAD: return thvalue(o); |
| 434 | case LUA_TUSERDATA: | 441 | case LUA_TUSERDATA: |
| @@ -456,6 +463,8 @@ LUA_API void lua_pushnil (lua_State *L) { · 21 unmodified lines | |||
| 456 | LUA_API void lua_pushnumber (lua_State *L, lua_Number n) { | 463 | LUA_API void lua_pushnumber (lua_State *L, lua_Number n) { |
| 457 | lua_lock(L); | 464 | lua_lock(L); |
| 458 | setnvalue(L->top, n); | 465 | setnvalue(L->top, n); |
| 466 | luai_checknum(L, L->top, | ||
| 467 | luaG_runerror(L, "C API - attempt to push a signaling NaN")); | ||
| 459 | api_incr_top(L); | 468 | api_incr_top(L); |
| 460 | lua_unlock(L); | 469 | lua_unlock(L); |
| 461 | } | 470 | } |
| @@ -548,7 +557,7 @@ LUA_API void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n) { · 86 unmodified lines | |||
| 548 | L->top -= n; | 557 | L->top -= n; |
| 549 | while (n--) | 558 | while (n--) |
| 550 | setobj2n(L, &cl->c.upvalue[n], L->top + n); | 559 | setobj2n(L, &cl->c.upvalue[n], L->top + n); |
| 551 | setclvalue(L, L->top, cl); | 560 | setclCvalue(L, L->top, cl); |
| 552 | } | 561 | } |
| 553 | api_incr_top(L); | 562 | api_incr_top(L); |
| 554 | lua_unlock(L); | 563 | lua_unlock(L); |
| @@ -648,7 +657,7 @@ LUA_API int lua_getmetatable (lua_State *L, int objindex) { · 93 unmodified lines | |||
| 648 | int res; | 657 | int res; |
| 649 | lua_lock(L); | 658 | lua_lock(L); |
| 650 | obj = index2addr(L, objindex); | 659 | obj = index2addr(L, objindex); |
| 651 | switch (ttype(obj)) { | 660 | switch (ttypenv(obj)) { |
| 652 | case LUA_TTABLE: | 661 | case LUA_TTABLE: |
| 653 | mt = hvalue(obj)->metatable; | 662 | mt = hvalue(obj)->metatable; |
| 654 | break; | 663 | break; |
| @@ -755,18 +764,19 @@ LUA_API int lua_setmetatable (lua_State *L, int objindex) { · 100 unmodified lines | |||
| 755 | api_check(L, ttistable(L->top - 1), "table expected"); | 764 | api_check(L, ttistable(L->top - 1), "table expected"); |
| 756 | mt = hvalue(L->top - 1); | 765 | mt = hvalue(L->top - 1); |
| 757 | } | 766 | } |
| 758 | switch (ttype(obj)) { | 767 | switch (ttypenv(obj)) { |
| 759 | case LUA_TTABLE: { | 768 | case LUA_TTABLE: { |
| 760 | hvalue(obj)->metatable = mt; | 769 | hvalue(obj)->metatable = mt; |
| 761 | if (mt) | 770 | if (mt) |
| 762 | luaC_objbarrierback(L, gcvalue(obj), mt); | 771 | luaC_objbarrierback(L, gcvalue(obj), mt); |
| 772 | luaC_checkfinalizer(L, gcvalue(obj), mt); | ||
| 763 | break; | 773 | break; |
| 764 | } | 774 | } |
| 765 | case LUA_TUSERDATA: { | 775 | case LUA_TUSERDATA: { |
| 766 | uvalue(obj)->metatable = mt; | 776 | uvalue(obj)->metatable = mt; |
| 767 | if (mt) { | 777 | if (mt) { |
| 768 | luaC_objbarrier(L, rawuvalue(obj), mt); | 778 | luaC_objbarrier(L, rawuvalue(obj), mt); |
| 769 | luaC_checkfinalizer(L, rawuvalue(obj)); | 779 | luaC_checkfinalizer(L, gcvalue(obj), mt); |
| 770 | } | 780 | } |
| 771 | break; | 781 | break; |
| 772 | } | 782 | } |
| @@ -912,15 +922,14 @@ LUA_API int lua_load (lua_State *L, lua_Reader reader, void *data, · 139 unmodified lines | |||
| 912 | luaZ_init(L, &z, reader, data); | 922 | luaZ_init(L, &z, reader, data); |
| 913 | status = luaD_protectedparser(L, &z, chunkname); | 923 | status = luaD_protectedparser(L, &z, chunkname); |
| 914 | if (status == LUA_OK) { /* no errors? */ | 924 | if (status == LUA_OK) { /* no errors? */ |
| 915 | Closure *f = clvalue(L->top - 1); /* get newly created function */ | 925 | LClosure *f = clLvalue(L->top - 1); /* get newly created function */ |
| 916 | lua_assert(!f->c.isC); | 926 | if (f->nupvalues == 1) { /* does it have one upvalue? */ |
| 917 | if (f->l.nupvalues == 1) { /* does it have one upvalue? */ | ||
| 918 | /* get global table from registry */ | 927 | /* get global table from registry */ |
| 919 | Table *reg = hvalue(&G(L)->l_registry); | 928 | Table *reg = hvalue(&G(L)->l_registry); |
| 920 | const TValue *gt = luaH_getint(reg, LUA_RIDX_GLOBALS); | 929 | const TValue *gt = luaH_getint(reg, LUA_RIDX_GLOBALS); |
| 921 | /* set global table as 1st upvalue of 'f' (may be LUA_ENV) */ | 930 | /* set global table as 1st upvalue of 'f' (may be LUA_ENV) */ |
| 922 | setobj(L, f->l.upvals[0]->v, gt); | 931 | setobj(L, f->upvals[0]->v, gt); |
| 923 | luaC_barrier(L, f->l.upvals[0], gt); | 932 | luaC_barrier(L, f->upvals[0], gt); |
| 924 | } | 933 | } |
| 925 | } | 934 | } |
| 926 | lua_unlock(L); | 935 | lua_unlock(L); |
| @@ -959,11 +968,12 @@ LUA_API int lua_gc (lua_State *L, int what, int data) { · 32 unmodified lines | |||
| 959 | g = G(L); | 968 | g = G(L); |
| 960 | switch (what) { | 969 | switch (what) { |
| 961 | case LUA_GCSTOP: { | 970 | case LUA_GCSTOP: { |
| 962 | stopgc(g); | 971 | g->gcrunning = 0; |
| 963 | break; | 972 | break; |
| 964 | } | 973 | } |
| 965 | case LUA_GCRESTART: { | 974 | case LUA_GCRESTART: { |
| 966 | g->GCdebt = 0; | 975 | luaE_setdebt(g, 0); |
| 976 | g->gcrunning = 1; | ||
| 967 | break; | 977 | break; |
| 968 | } | 978 | } |
| 969 | case LUA_GCCOLLECT: { | 979 | case LUA_GCCOLLECT: { |
| @@ -972,30 +982,27 @@ LUA_API int lua_gc (lua_State *L, int what, int data) { · 2 unmodified lines | |||
| 972 | } | 982 | } |
| 973 | case LUA_GCCOUNT: { | 983 | case LUA_GCCOUNT: { |
| 974 | /* GC values are expressed in Kbytes: #bytes/2^10 */ | 984 | /* GC values are expressed in Kbytes: #bytes/2^10 */ |
| 975 | res = cast_int(g->totalbytes >> 10); | 985 | res = cast_int(gettotalbytes(g) >> 10); |
| 976 | break; | 986 | break; |
| 977 | } | 987 | } |
| 978 | case LUA_GCCOUNTB: { | 988 | case LUA_GCCOUNTB: { |
| 979 | res = cast_int(g->totalbytes & 0x3ff); | 989 | res = cast_int(gettotalbytes(g) & 0x3ff); |
| 980 | break; | 990 | break; |
| 981 | } | 991 | } |
| 982 | case LUA_GCSTEP: { | 992 | case LUA_GCSTEP: { |
| 983 | int stopped = gcstopped(g); | ||
| 984 | if (g->gckind == KGC_GEN) { /* generational mode? */ | 993 | if (g->gckind == KGC_GEN) { /* generational mode? */ |
| 985 | res = (g->lastmajormem == 0); /* 1 if will do major collection */ | 994 | res = (g->lastmajormem == 0); /* 1 if will do major collection */ |
| 986 | luaC_step(L); /* do a single step */ | 995 | luaC_forcestep(L); /* do a single step */ |
| 987 | } | 996 | } |
| 988 | else { | 997 | else { |
| 989 | while (data-- >= 0) { | 998 | while (data-- >= 0) { |
| 990 | luaC_step(L); | 999 | luaC_forcestep(L); |
| 991 | if (g->gcstate == GCSpause) { /* end of cycle? */ | 1000 | if (g->gcstate == GCSpause) { /* end of cycle? */ |
| 992 | res = 1; /* signal it */ | 1001 | res = 1; /* signal it */ |
| 993 | break; | 1002 | break; |
| 994 | } | 1003 | } |
| 995 | } | 1004 | } |
| 996 | } | 1005 | } |
| 997 | if (stopped) /* collector was stopped? */ | ||
| 998 | stopgc(g); /* keep it that way */ | ||
| 999 | break; | 1006 | break; |
| 1000 | } | 1007 | } |
| 1001 | case LUA_GCSETPAUSE: { | 1008 | case LUA_GCSETPAUSE: { |
| @@ -1014,7 +1021,7 @@ LUA_API int lua_gc (lua_State *L, int what, int data) { · 12 unmodified lines | |||
| 1014 | break; | 1021 | break; |
| 1015 | } | 1022 | } |
| 1016 | case LUA_GCISRUNNING: { | 1023 | case LUA_GCISRUNNING: { |
| 1017 | res = !gcstopped(g); | 1024 | res = g->gcrunning; |
| 1018 | break; | 1025 | break; |
| 1019 | } | 1026 | } |
| 1020 | case LUA_GCGEN: { /* change collector to generational mode */ | 1027 | case LUA_GCGEN: { /* change collector to generational mode */ |
| @@ -1124,25 +1131,27 @@ LUA_API void *lua_newuserdata (lua_State *L, size_t size) { · 103 unmodified lines | |||
| 1124 | 1131 | ||
| 1125 | static const char *aux_upvalue (StkId fi, int n, TValue **val, | 1132 | static const char *aux_upvalue (StkId fi, int n, TValue **val, |
| 1126 | GCObject **owner) { | 1133 | GCObject **owner) { |
| 1127 | Closure *f; | 1134 | switch (ttype(fi)) { |
| 1128 | if (!ttisclosure(fi)) return NULL; | 1135 | case LUA_TCCL: { /* C closure */ |
| 1129 | f = clvalue(fi); | 1136 | CClosure *f = clCvalue(fi); |
| 1130 | if (f->c.isC) { | 1137 | if (!(1 <= n && n <= f->nupvalues)) return NULL; |
| 1131 | if (!(1 <= n && n <= f->c.nupvalues)) return NULL; | 1138 | *val = &f->upvalue[n-1]; |
| 1132 | *val = &f->c.upvalue[n-1]; | 1139 | if (owner) *owner = obj2gco(f); |
| 1133 | if (owner) *owner = obj2gco(f); | 1140 | return ""; |
| 1134 | return ""; | 1141 | } |
| 1135 | } | 1142 | case LUA_TLCL: { /* Lua closure */ |
| 1136 | else { | 1143 | LClosure *f = clLvalue(fi); |
| 1137 | const char *name; | 1144 | const char *name; |
| 1138 | Proto *p = f->l.p; | 1145 | Proto *p = f->p; |
| 1139 | if (!(1 <= n && n <= p->sizeupvalues)) return NULL; | 1146 | if (!(1 <= n && n <= p->sizeupvalues)) return NULL; |
| 1140 | *val = f->l.upvals[n-1]->v; | 1147 | *val = f->upvals[n-1]->v; |
| 1141 | if (owner) *owner = obj2gco(f->l.upvals[n - 1]); | 1148 | if (owner) *owner = obj2gco(f->upvals[n - 1]); |
| 1142 | name = getstr(p->upvalues[n-1].name); | 1149 | name = getstr(p->upvalues[n-1].name); |
| 1143 | if (name == NULL) /* no debug information? */ | 1150 | if (name == NULL) /* no debug information? */ |
| 1144 | name = ""; | 1151 | name = ""; |
| 1145 | return name; | 1152 | return name; |
| 1153 | } | ||
| 1154 | default: return NULL; /* not a closure */ | ||
| 1146 | } | 1155 | } |
| 1147 | } | 1156 | } |
| 1148 | 1157 | ||
| @@ -1180,34 +1189,39 @@ LUA_API const char *lua_setupvalue (lua_State *L, int funcindex, int n) { · 31 unmodified lines | |||
| 1180 | } | 1189 | } |
| 1181 | 1190 | ||
| 1182 | 1191 | ||
| 1183 | static UpVal **getupvalref (lua_State *L, int fidx, int n, Closure **pf) { | 1192 | static UpVal **getupvalref (lua_State *L, int fidx, int n, LClosure **pf) { |
| 1184 | Closure *f; | 1193 | LClosure *f; |
| 1185 | StkId fi = index2addr(L, fidx); | 1194 | StkId fi = index2addr(L, fidx); |
| 1186 | api_check(L, ttisclosure(fi), "Lua function expected"); | 1195 | api_check(L, ttisLclosure(fi), "Lua function expected"); |
| 1187 | f = clvalue(fi); | 1196 | f = clLvalue(fi); |
| 1188 | api_check(L, !f->c.isC, "Lua function expected"); | 1197 | api_check(L, (1 <= n && n <= f->p->sizeupvalues), "invalid upvalue index"); |
| 1189 | api_check(L, (1 <= n && n <= f->l.p->sizeupvalues), "invalid upvalue index"); | ||
| 1190 | if (pf) *pf = f; | 1198 | if (pf) *pf = f; |
| 1191 | return &f->l.upvals[n - 1]; /* get its upvalue pointer */ | 1199 | return &f->upvals[n - 1]; /* get its upvalue pointer */ |
| 1192 | } | 1200 | } |
| 1193 | 1201 | ||
| 1194 | 1202 | ||
| 1195 | LUA_API void *lua_upvalueid (lua_State *L, int fidx, int n) { | 1203 | LUA_API void *lua_upvalueid (lua_State *L, int fidx, int n) { |
| 1196 | Closure *f; | ||
| 1197 | StkId fi = index2addr(L, fidx); | 1204 | StkId fi = index2addr(L, fidx); |
| 1198 | api_check(L, ttisclosure(fi), "function expected"); | 1205 | switch (ttype(fi)) { |
| 1199 | f = clvalue(fi); | 1206 | case LUA_TLCL: { /* lua closure */ |
| 1200 | if (f->c.isC) { | 1207 | return *getupvalref(L, fidx, n, NULL); |
| 1201 | api_check(L, 1 <= n && n <= f->c.nupvalues, "invalid upvalue index"); | 1208 | } |
| 1202 | return &f->c.upvalue[n - 1]; | 1209 | case LUA_TCCL: { /* C closure */ |
| 1210 | CClosure *f = clCvalue(fi); | ||
| 1211 | api_check(L, 1 <= n && n <= f->nupvalues, "invalid upvalue index"); | ||
| 1212 | return &f->upvalue[n - 1]; | ||
| 1213 | } | ||
| 1214 | default: { | ||
| 1215 | api_check(L, 0, "closure expected"); | ||
| 1216 | return NULL; | ||
| 1217 | } | ||
| 1203 | } | 1218 | } |
| 1204 | else return *getupvalref(L, fidx, n, NULL); | ||
| 1205 | } | 1219 | } |
| 1206 | 1220 | ||
| 1207 | 1221 | ||
| 1208 | LUA_API void lua_upvaluejoin (lua_State *L, int fidx1, int n1, | 1222 | LUA_API void lua_upvaluejoin (lua_State *L, int fidx1, int n1, |
| 1209 | int fidx2, int n2) { | 1223 | int fidx2, int n2) { |
| 1210 | Closure *f1; | 1224 | LClosure *f1; |
| 1211 | UpVal **up1 = getupvalref(L, fidx1, n1, &f1); | 1225 | UpVal **up1 = getupvalref(L, fidx1, n1, &f1); |
| 1212 | UpVal **up2 = getupvalref(L, fidx2, n2, NULL); | 1226 | UpVal **up2 = getupvalref(L, fidx2, n2, NULL); |
| 1213 | *up1 = *up2; | 1227 | *up1 = *up2; |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lauxlib.c,v 1.227 2010/11/10 18:05:36 roberto Exp $ | 2 | ** $Id: lauxlib.c,v 1.232 2011/05/03 16:01:57 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 | */ |
| @@ -203,6 +203,64 @@ LUALIB_API int luaL_error (lua_State *L, const char *fmt, ...) { · 197 unmodified lines | |||
| 203 | return lua_error(L); | 203 | return lua_error(L); |
| 204 | } | 204 | } |
| 205 | 205 | ||
| 206 | |||
| 207 | LUALIB_API int luaL_fileresult (lua_State *L, int stat, const char *fname) { | ||
| 208 | int en = errno; /* calls to Lua API may change this value */ | ||
| 209 | if (stat) { | ||
| 210 | lua_pushboolean(L, 1); | ||
| 211 | return 1; | ||
| 212 | } | ||
| 213 | else { | ||
| 214 | lua_pushnil(L); | ||
| 215 | if (fname) | ||
| 216 | lua_pushfstring(L, "%s: %s", fname, strerror(en)); | ||
| 217 | else | ||
| 218 | lua_pushfstring(L, "%s", strerror(en)); | ||
| 219 | lua_pushinteger(L, en); | ||
| 220 | return 3; | ||
| 221 | } | ||
| 222 | } | ||
| 223 | |||
| 224 | |||
| 225 | #if !defined(inspectstat) /* { */ | ||
| 226 | |||
| 227 | #if defined(LUA_USE_POSIX) | ||
| 228 | |||
| 229 | #include <sys/wait.h> | ||
| 230 | |||
| 231 | /* | ||
| 232 | ** use appropriate macros to interpret 'pclose' return status | ||
| 233 | */ | ||
| 234 | #define inspectstat(stat,what) \ | ||
| 235 | if (WIFEXITED(stat)) { stat = WEXITSTATUS(stat); } \ | ||
| 236 | else if (WIFSIGNALED(stat)) { stat = WTERMSIG(stat); what = "signal"; } | ||
| 237 | |||
| 238 | #else | ||
| 239 | |||
| 240 | #define inspectstat(stat,what) /* no op */ | ||
| 241 | |||
| 242 | #endif | ||
| 243 | |||
| 244 | #endif /* } */ | ||
| 245 | |||
| 246 | |||
| 247 | LUALIB_API int luaL_execresult (lua_State *L, int stat) { | ||
| 248 | const char *what = "exit"; /* type of termination */ | ||
| 249 | if (stat == -1) /* error? */ | ||
| 250 | return luaL_fileresult(L, 0, NULL); | ||
| 251 | else { | ||
| 252 | inspectstat(stat, what); /* interpret result */ | ||
| 253 | if (*what == 'e' && stat == 0) /* successful termination? */ | ||
| 254 | return luaL_fileresult(L, 1, NULL); | ||
| 255 | else { /* return nil,what,code */ | ||
| 256 | lua_pushnil(L); | ||
| 257 | lua_pushstring(L, what); | ||
| 258 | lua_pushinteger(L, stat); | ||
| 259 | return 3; | ||
| 260 | } | ||
| 261 | } | ||
| 262 | } | ||
| 263 | |||
| 206 | /* }====================================================== */ | 264 | /* }====================================================== */ |
| 207 | 265 | ||
| 208 | 266 | ||
| @@ -384,8 +442,10 @@ LUALIB_API char *luaL_prepbuffsize (luaL_Buffer *B, size_t sz) { · 175 unmodified lines | |||
| 384 | newsize = B->n + sz; | 442 | newsize = B->n + sz; |
| 385 | if (newsize < B->n || newsize - B->n < sz) | 443 | if (newsize < B->n || newsize - B->n < sz) |
| 386 | luaL_error(L, "buffer too large"); | 444 | luaL_error(L, "buffer too large"); |
| 387 | newbuff = (char *)lua_newuserdata(L, newsize); /* create larger buffer */ | 445 | /* create larger buffer */ |
| 388 | memcpy(newbuff, B->b, B->n); /* move content to new buffer */ | 446 | newbuff = (char *)lua_newuserdata(L, newsize * sizeof(char)); |
| 447 | /* move content to new buffer */ | ||
| 448 | memcpy(newbuff, B->b, B->n * sizeof(char)); | ||
| 389 | if (buffonstack(B)) | 449 | if (buffonstack(B)) |
| 390 | lua_remove(L, -2); /* remove old buffer */ | 450 | lua_remove(L, -2); /* remove old buffer */ |
| 391 | B->b = newbuff; | 451 | B->b = newbuff; |
| @@ -397,7 +457,7 @@ LUALIB_API char *luaL_prepbuffsize (luaL_Buffer *B, size_t sz) { · 5 unmodified lines | |||
| 397 | 457 | ||
| 398 | LUALIB_API void luaL_addlstring (luaL_Buffer *B, const char *s, size_t l) { | 458 | LUALIB_API void luaL_addlstring (luaL_Buffer *B, const char *s, size_t l) { |
| 399 | char *b = luaL_prepbuffsize(B, l); | 459 | char *b = luaL_prepbuffsize(B, l); |
| 400 | memcpy(b, s, l); | 460 | memcpy(b, s, l * sizeof(char)); |
| 401 | luaL_addsize(B, l); | 461 | luaL_addsize(B, l); |
| 402 | } | 462 | } |
| 403 | 463 | ||
| @@ -700,8 +760,8 @@ LUALIB_API const char *luaL_tolstring (lua_State *L, int idx, size_t *len) { · 296 unmodified lines | |||
| 700 | */ | 760 | */ |
| 701 | #if defined(LUA_COMPAT_MODULE) | 761 | #if defined(LUA_COMPAT_MODULE) |
| 702 | 762 | ||
| 703 | static const char *luaL_findtablex (lua_State *L, int idx, | 763 | static const char *luaL_findtable (lua_State *L, int idx, |
| 704 | const char *fname, int szhint) { | 764 | const char *fname, int szhint) { |
| 705 | const char *e; | 765 | const char *e; |
| 706 | if (idx) lua_pushvalue(L, idx); | 766 | if (idx) lua_pushvalue(L, idx); |
| 707 | do { | 767 | do { |
| @@ -745,13 +805,13 @@ static int libsize (const luaL_Reg *l) { · 37 unmodified lines | |||
| 745 | */ | 805 | */ |
| 746 | LUALIB_API void luaL_pushmodule (lua_State *L, const char *modname, | 806 | LUALIB_API void luaL_pushmodule (lua_State *L, const char *modname, |
| 747 | int sizehint) { | 807 | int sizehint) { |
| 748 | luaL_findtablex(L, LUA_REGISTRYINDEX, "_LOADED", 1); /* get _LOADED table */ | 808 | luaL_findtable(L, LUA_REGISTRYINDEX, "_LOADED", 1); /* get _LOADED table */ |
| 749 | lua_getfield(L, -1, modname); /* get _LOADED[modname] */ | 809 | lua_getfield(L, -1, modname); /* get _LOADED[modname] */ |
| 750 | if (!lua_istable(L, -1)) { /* not found? */ | 810 | if (!lua_istable(L, -1)) { /* not found? */ |
| 751 | lua_pop(L, 1); /* remove previous result */ | 811 | lua_pop(L, 1); /* remove previous result */ |
| 752 | /* try global variable (and create one if it does not exist) */ | 812 | /* try global variable (and create one if it does not exist) */ |
| 753 | lua_pushglobaltable(L); | 813 | lua_pushglobaltable(L); |
| 754 | if (luaL_findtablex(L, 0, modname, sizehint) != NULL) | 814 | if (luaL_findtable(L, 0, modname, sizehint) != NULL) |
| 755 | luaL_error(L, "name conflict for module " LUA_QS, modname); | 815 | luaL_error(L, "name conflict for module " LUA_QS, modname); |
| 756 | lua_pushvalue(L, -1); | 816 | lua_pushvalue(L, -1); |
| 757 | lua_setfield(L, -3, modname); /* _LOADED[modname] = new table */ | 817 | lua_setfield(L, -3, modname); /* _LOADED[modname] = new table */ |
| @@ -767,7 +827,10 @@ LUALIB_API void luaL_openlib (lua_State *L, const char *libname, · 9 unmodified lines | |||
| 767 | luaL_pushmodule(L, libname, libsize(l)); /* get/create library table */ | 827 | luaL_pushmodule(L, libname, libsize(l)); /* get/create library table */ |
| 768 | lua_insert(L, -(nup + 1)); /* move library table to below upvalues */ | 828 | lua_insert(L, -(nup + 1)); /* move library table to below upvalues */ |
| 769 | } | 829 | } |
| 770 | luaL_setfuncs(L, l, nup); | 830 | if (l) |
| 831 | luaL_setfuncs(L, l, nup); | ||
| 832 | else | ||
| 833 | lua_pop(L, nup); /* remove upvalues */ | ||
| 771 | } | 834 | } |
| 772 | 835 | ||
| 773 | #endif | 836 | #endif |
| @@ -780,7 +843,7 @@ LUALIB_API void luaL_openlib (lua_State *L, const char *libname, · 6 unmodified lines | |||
| 780 | */ | 843 | */ |
| 781 | LUALIB_API void luaL_setfuncs (lua_State *L, const luaL_Reg *l, int nup) { | 844 | LUALIB_API void luaL_setfuncs (lua_State *L, const luaL_Reg *l, int nup) { |
| 782 | luaL_checkstack(L, nup, "too many upvalues"); | 845 | luaL_checkstack(L, nup, "too many upvalues"); |
| 783 | for (; l && l->name; l++) { /* fill the table with given functions */ | 846 | for (; l->name != NULL; l++) { /* fill the table with given functions */ |
| 784 | int i; | 847 | int i; |
| 785 | for (i = 0; i < nup; i++) /* copy upvalues to the top */ | 848 | for (i = 0; i < nup; i++) /* copy upvalues to the top */ |
| 786 | lua_pushvalue(L, -nup); | 849 | lua_pushvalue(L, -nup); |
| @@ -795,15 +858,16 @@ LUALIB_API void luaL_setfuncs (lua_State *L, const luaL_Reg *l, int nup) { · 8 unmodified lines | |||
| 795 | ** ensure that stack[idx][fname] has a table and push that table | 858 | ** ensure that stack[idx][fname] has a table and push that table |
| 796 | ** into the stack | 859 | ** into the stack |
| 797 | */ | 860 | */ |
| 798 | LUALIB_API void luaL_findtable (lua_State *L, int idx, const char *fname) { | 861 | LUALIB_API int luaL_getsubtable (lua_State *L, int idx, const char *fname) { |
| 799 | lua_getfield(L, idx, fname); | 862 | lua_getfield(L, idx, fname); |
| 800 | if (lua_istable(L, -1)) return; /* table already there */ | 863 | if (lua_istable(L, -1)) return 1; /* table already there */ |
| 801 | else { | 864 | else { |
| 802 | idx = lua_absindex(L, idx); | 865 | idx = lua_absindex(L, idx); |
| 803 | lua_pop(L, 1); /* remove previous result */ | 866 | lua_pop(L, 1); /* remove previous result */ |
| 804 | lua_newtable(L); | 867 | lua_newtable(L); |
| 805 | lua_pushvalue(L, -1); /* copy to be left at top */ | 868 | lua_pushvalue(L, -1); /* copy to be left at top */ |
| 806 | lua_setfield(L, idx, fname); /* assign new table to field */ | 869 | lua_setfield(L, idx, fname); /* assign new table to field */ |
| 870 | return 0; /* false, because did not find table there */ | ||
| 807 | } | 871 | } |
| 808 | } | 872 | } |
| 809 | 873 | ||
| @@ -819,7 +883,7 @@ LUALIB_API void luaL_requiref (lua_State *L, const char *modname, · 9 unmodified lines | |||
| 819 | lua_pushcfunction(L, openf); | 883 | lua_pushcfunction(L, openf); |
| 820 | lua_pushstring(L, modname); /* argument to open function */ | 884 | lua_pushstring(L, modname); /* argument to open function */ |
| 821 | lua_call(L, 1, 1); /* open module */ | 885 | lua_call(L, 1, 1); /* open module */ |
| 822 | luaL_findtable(L, LUA_REGISTRYINDEX, "_LOADED"); | 886 | luaL_getsubtable(L, LUA_REGISTRYINDEX, "_LOADED"); |
| 823 | lua_pushvalue(L, -2); /* make copy of module (call result) */ | 887 | lua_pushvalue(L, -2); /* make copy of module (call result) */ |
| 824 | lua_setfield(L, -2, modname); /* _LOADED[modname] = module */ | 888 | lua_setfield(L, -2, modname); /* _LOADED[modname] = module */ |
| 825 | lua_pop(L, 1); /* remove _LOADED table */ | 889 | lua_pop(L, 1); /* remove _LOADED table */ |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lauxlib.h,v 1.113 2010/11/16 19:20:01 roberto Exp $ | 2 | ** $Id: lauxlib.h,v 1.116 2011/04/08 19:17:36 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 | */ |
| @@ -62,6 +62,9 @@ LUALIB_API int (luaL_error) (lua_State *L, const char *fmt, ...); · 56 unmodified lines | |||
| 62 | LUALIB_API int (luaL_checkoption) (lua_State *L, int narg, const char *def, | 62 | LUALIB_API int (luaL_checkoption) (lua_State *L, int narg, const char *def, |
| 63 | const char *const lst[]); | 63 | const char *const lst[]); |
| 64 | 64 | ||
| 65 | LUALIB_API int (luaL_fileresult) (lua_State *L, int stat, const char *fname); | ||
| 66 | LUALIB_API int (luaL_execresult) (lua_State *L, int stat); | ||
| 67 | |||
| 65 | /* pre-defined references */ | 68 | /* pre-defined references */ |
| 66 | #define LUA_NOREF (-2) | 69 | #define LUA_NOREF (-2) |
| 67 | #define LUA_REFNIL (-1) | 70 | #define LUA_REFNIL (-1) |
| @@ -83,7 +86,7 @@ LUALIB_API const char *(luaL_gsub) (lua_State *L, const char *s, const char *p, · 15 unmodified lines | |||
| 83 | 86 | ||
| 84 | LUALIB_API void (luaL_setfuncs) (lua_State *L, const luaL_Reg *l, int nup); | 87 | LUALIB_API void (luaL_setfuncs) (lua_State *L, const luaL_Reg *l, int nup); |
| 85 | 88 | ||
| 86 | LUALIB_API void (luaL_findtable) (lua_State *L, int idx, const char *fname); | 89 | LUALIB_API int (luaL_getsubtable) (lua_State *L, int idx, const char *fname); |
| 87 | 90 | ||
| 88 | LUALIB_API void (luaL_traceback) (lua_State *L, lua_State *L1, | 91 | LUALIB_API void (luaL_traceback) (lua_State *L, lua_State *L1, |
| 89 | const char *msg, int level); | 92 | const char *msg, int level); |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lbaselib.c,v 1.251 2010/10/28 15:36:30 roberto Exp $ | 2 | ** $Id: lbaselib.c,v 1.261 2011/05/26 16:09:40 roberto Exp $ |
| 3 | ** Basic library | 3 | ** Basic library |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -32,44 +32,54 @@ static int luaB_print (lua_State *L) { · 26 unmodified lines | |||
| 32 | lua_call(L, 1, 1); | 32 | lua_call(L, 1, 1); |
| 33 | s = lua_tolstring(L, -1, &l); /* get result */ | 33 | s = lua_tolstring(L, -1, &l); /* get result */ |
| 34 | if (s == NULL) | 34 | if (s == NULL) |
| 35 | return luaL_error(L, LUA_QL("tostring") " must return a string to " | 35 | return luaL_error(L, |
| 36 | LUA_QL("print")); | 36 | LUA_QL("tostring") " must return a string to " LUA_QL("print")); |
| 37 | if (i>1) luai_writestring("\t", 1); | 37 | if (i>1) luai_writestring("\t", 1); |
| 38 | luai_writestring(s, l); | 38 | luai_writestring(s, l); |
| 39 | lua_pop(L, 1); /* pop result */ | 39 | lua_pop(L, 1); /* pop result */ |
| 40 | } | 40 | } |
| 41 | luai_writestring("\n", 1); | 41 | luai_writeline(); |
| 42 | return 0; | 42 | return 0; |
| 43 | } | 43 | } |
| 44 | 44 | ||
| 45 | 45 | ||
| 46 | #define SPACECHARS " \f\n\r\t\v" | ||
| 47 | |||
| 46 | static int luaB_tonumber (lua_State *L) { | 48 | static int luaB_tonumber (lua_State *L) { |
| 47 | int base = luaL_optint(L, 2, 10); | 49 | int base = luaL_optint(L, 2, 10); |
| 50 | luaL_argcheck(L, 2 <= base && base <= 36, 2, "base out of range"); | ||
| 48 | if (base == 10) { /* standard conversion */ | 51 | if (base == 10) { /* standard conversion */ |
| 49 | luaL_checkany(L, 1); | 52 | luaL_checkany(L, 1); |
| 50 | if (lua_isnumber(L, 1)) { | 53 | if (lua_isnumber(L, 1)) { |
| 51 | lua_pushnumber(L, lua_tonumber(L, 1)); | 54 | lua_pushnumber(L, lua_tonumber(L, 1)); |
| 52 | return 1; | 55 | return 1; |
| 53 | } | 56 | } /* else not a number */ |
| 54 | } | 57 | } |
| 55 | else { | 58 | else { |
| 56 | const char *s1 = luaL_checkstring(L, 1); | 59 | size_t l; |
| 57 | char *s2; | 60 | const char *s = luaL_checklstring(L, 1, &l); |
| 58 | unsigned long n; | 61 | const char *e = s + l; /* end point for 's' */ |
| 59 | int neg = 0; | 62 | int neg = 0; |
| 60 | luaL_argcheck(L, 2 <= base && base <= 36, 2, "base out of range"); | 63 | s += strspn(s, SPACECHARS); /* skip initial spaces */ |
| 61 | while (isspace((unsigned char)(*s1))) s1++; /* skip initial spaces */ | 64 | if (*s == '-') { s++; neg = 1; } /* handle signal */ |
| 62 | if (*s1 == '-') { s1++; neg = 1; } | 65 | else if (*s == '+') s++; |
| 63 | n = strtoul(s1, &s2, base); | 66 | if (isalnum((unsigned char)*s)) { |
| 64 | if (s1 != s2) { /* at least one valid digit? */ | 67 | lua_Number n = 0; |
| 65 | while (isspace((unsigned char)(*s2))) s2++; /* skip trailing spaces */ | 68 | do { |
| 66 | if (*s2 == '\0') { /* no invalid trailing characters? */ | 69 | int digit = (isdigit((unsigned char)*s)) ? *s - '0' |
| 67 | lua_pushnumber(L, (neg) ? -(lua_Number)n : (lua_Number)n); | 70 | : toupper((unsigned char)*s) - 'A' + 10; |
| 71 | if (digit >= base) break; /* invalid numeral; force a fail */ | ||
| 72 | n = n * (lua_Number)base + (lua_Number)digit; | ||
| 73 | s++; | ||
| 74 | } while (isalnum((unsigned char)*s)); | ||
| 75 | s += strspn(s, SPACECHARS); /* skip trailing spaces */ | ||
| 76 | if (s == e) { /* no invalid trailing characters? */ | ||
| 77 | lua_pushnumber(L, (neg) ? -n : n); | ||
| 68 | return 1; | 78 | return 1; |
| 69 | } | 79 | } /* else not a number */ |
| 70 | } | 80 | } /* else not a number */ |
| 71 | } | 81 | } |
| 72 | lua_pushnil(L); /* else not a number */ | 82 | lua_pushnil(L); /* not a number */ |
| 73 | return 1; | 83 | return 1; |
| 74 | } | 84 | } |
| 75 | 85 | ||
| @@ -110,12 +120,10 @@ static int luaB_setmetatable (lua_State *L) { · 34 unmodified lines | |||
| 110 | } | 120 | } |
| 111 | 121 | ||
| 112 | 122 | ||
| 113 | static int luaB_getfenv (lua_State *L) { | 123 | static int luaB_deprecated (lua_State *L) { |
| 114 | return luaL_error(L, "getfenv/setfenv deprecated"); | 124 | return luaL_error(L, "deprecated function"); |
| 115 | } | 125 | } |
| 116 | 126 | ||
| 117 | #define luaB_setfenv luaB_getfenv | ||
| 118 | |||
| 119 | 127 | ||
| 120 | static int luaB_rawequal (lua_State *L) { | 128 | static int luaB_rawequal (lua_State *L) { |
| 121 | luaL_checkany(L, 1); | 129 | luaL_checkany(L, 1); |
| @@ -125,6 +133,15 @@ static int luaB_rawequal (lua_State *L) { · 3 unmodified lines | |||
| 125 | } | 133 | } |
| 126 | 134 | ||
| 127 | 135 | ||
| 136 | static int luaB_rawlen (lua_State *L) { | ||
| 137 | int t = lua_type(L, 1); | ||
| 138 | luaL_argcheck(L, t == LUA_TTABLE || t == LUA_TSTRING, 1, | ||
| 139 | "table or string expected"); | ||
| 140 | lua_pushinteger(L, lua_rawlen(L, 1)); | ||
| 141 | return 1; | ||
| 142 | } | ||
| 143 | |||
| 144 | |||
| 128 | static int luaB_rawget (lua_State *L) { | 145 | static int luaB_rawget (lua_State *L) { |
| 129 | luaL_checktype(L, 1, LUA_TTABLE); | 146 | luaL_checktype(L, 1, LUA_TTABLE); |
| 130 | luaL_checkany(L, 2); | 147 | luaL_checkany(L, 2); |
| @@ -251,6 +268,11 @@ static int luaB_loadfile (lua_State *L) { · 120 unmodified lines | |||
| 251 | ** ======================================================= | 268 | ** ======================================================= |
| 252 | */ | 269 | */ |
| 253 | 270 | ||
| 271 | /* | ||
| 272 | ** check whether a chunk (prefix in 's') satisfies given 'mode' | ||
| 273 | ** ('t' for text, 'b' for binary). Returns error message (also | ||
| 274 | ** pushed on the stack) in case of errors. | ||
| 275 | */ | ||
| 254 | static const char *checkrights (lua_State *L, const char *mode, const char *s) { | 276 | static const char *checkrights (lua_State *L, const char *mode, const char *s) { |
| 255 | if (strchr(mode, 'b') == NULL && *s == LUA_SIGNATURE[0]) | 277 | if (strchr(mode, 'b') == NULL && *s == LUA_SIGNATURE[0]) |
| 256 | return lua_pushstring(L, "attempt to load a binary chunk"); | 278 | return lua_pushstring(L, "attempt to load a binary chunk"); |
| @@ -261,10 +283,11 @@ static const char *checkrights (lua_State *L, const char *mode, const char *s) { · 4 unmodified lines | |||
| 261 | 283 | ||
| 262 | 284 | ||
| 263 | /* | 285 | /* |
| 264 | ** reserves a slot, above all arguments, to hold a copy of the returned | 286 | ** reserved slot, above all arguments, to hold a copy of the returned |
| 265 | ** string to avoid it being collected while parsed | 287 | ** string to avoid it being collected while parsed. 'load' has four |
| 288 | ** optional arguments (chunk, source name, mode, and environment). | ||
| 266 | */ | 289 | */ |
| 267 | #define RESERVEDSLOT 4 | 290 | #define RESERVEDSLOT 5 |
| 268 | 291 | ||
| 269 | 292 | ||
| 270 | /* | 293 | /* |
| @@ -273,25 +296,20 @@ static const char *checkrights (lua_State *L, const char *mode, const char *s) { · 2 unmodified lines | |||
| 273 | ** stack top. Instead, it keeps its resulting string in a | 296 | ** stack top. Instead, it keeps its resulting string in a |
| 274 | ** reserved slot inside the stack. | 297 | ** reserved slot inside the stack. |
| 275 | */ | 298 | */ |
| 276 | typedef struct { /* reader state */ | ||
| 277 | int f; /* position of reader function on stack */ | ||
| 278 | const char *mode; /* allowed modes (binary/text) */ | ||
| 279 | } Readstat; | ||
| 280 | |||
| 281 | static const char *generic_reader (lua_State *L, void *ud, size_t *size) { | 299 | static const char *generic_reader (lua_State *L, void *ud, size_t *size) { |
| 282 | const char *s; | 300 | const char *s; |
| 283 | Readstat *stat = (Readstat *)ud; | 301 | const char **mode = (const char **)ud; |
| 284 | luaL_checkstack(L, 2, "too many nested functions"); | 302 | luaL_checkstack(L, 2, "too many nested functions"); |
| 285 | lua_pushvalue(L, stat->f); /* get function */ | 303 | lua_pushvalue(L, 1); /* get function */ |
| 286 | lua_call(L, 0, 1); /* call it */ | 304 | lua_call(L, 0, 1); /* call it */ |
| 287 | if (lua_isnil(L, -1)) { | 305 | if (lua_isnil(L, -1)) { |
| 288 | *size = 0; | 306 | *size = 0; |
| 289 | return NULL; | 307 | return NULL; |
| 290 | } | 308 | } |
| 291 | else if ((s = lua_tostring(L, -1)) != NULL) { | 309 | else if ((s = lua_tostring(L, -1)) != NULL) { |
| 292 | if (stat->mode != NULL) { /* first time? */ | 310 | if (*mode != NULL) { /* first time? */ |
| 293 | s = checkrights(L, stat->mode, s); /* check mode */ | 311 | s = checkrights(L, *mode, s); /* check mode */ |
| 294 | stat->mode = NULL; /* to avoid further checks */ | 312 | *mode = NULL; /* to avoid further checks */ |
| 295 | if (s) luaL_error(L, s); | 313 | if (s) luaL_error(L, s); |
| 296 | } | 314 | } |
| 297 | lua_replace(L, RESERVEDSLOT); /* save string in reserved slot */ | 315 | lua_replace(L, RESERVEDSLOT); /* save string in reserved slot */ |
| @@ -304,52 +322,38 @@ static const char *generic_reader (lua_State *L, void *ud, size_t *size) { · 6 unmodified lines | |||
| 304 | } | 322 | } |
| 305 | 323 | ||
| 306 | 324 | ||
| 307 | static int luaB_load_aux (lua_State *L, int farg) { | 325 | static int luaB_load (lua_State *L) { |
| 308 | int status; | 326 | int status; |
| 309 | Readstat stat; | ||
| 310 | size_t l; | 327 | size_t l; |
| 311 | const char *s = lua_tolstring(L, farg, &l); | 328 | int top = lua_gettop(L); |
| 312 | stat.mode = luaL_optstring(L, farg + 2, "bt"); | 329 | const char *s = lua_tolstring(L, 1, &l); |
| 330 | const char *mode = luaL_optstring(L, 3, "bt"); | ||
| 313 | if (s != NULL) { /* loading a string? */ | 331 | if (s != NULL) { /* loading a string? */ |
| 314 | const char *chunkname = luaL_optstring(L, farg + 1, s); | 332 | const char *chunkname = luaL_optstring(L, 2, s); |
| 315 | status = (checkrights(L, stat.mode, s) != NULL) | 333 | status = (checkrights(L, mode, s) != NULL) |
| 316 | || luaL_loadbuffer(L, s, l, chunkname); | 334 | || luaL_loadbuffer(L, s, l, chunkname); |
| 317 | } | 335 | } |
| 318 | else { /* loading from a reader function */ | 336 | else { /* loading from a reader function */ |
| 319 | const char *chunkname = luaL_optstring(L, farg + 1, "=(load)"); | 337 | const char *chunkname = luaL_optstring(L, 2, "=(load)"); |
| 320 | luaL_checktype(L, farg, LUA_TFUNCTION); | 338 | luaL_checktype(L, 1, LUA_TFUNCTION); |
| 321 | stat.f = farg; | ||
| 322 | lua_settop(L, RESERVEDSLOT); /* create reserved slot */ | 339 | lua_settop(L, RESERVEDSLOT); /* create reserved slot */ |
| 323 | status = lua_load(L, generic_reader, &stat, chunkname); | 340 | status = lua_load(L, generic_reader, &mode, chunkname); |
| 341 | } | ||
| 342 | if (status == LUA_OK && top >= 4) { /* is there an 'env' argument */ | ||
| 343 | lua_pushvalue(L, 4); /* environment for loaded function */ | ||
| 344 | lua_setupvalue(L, -2, 1); /* set it as 1st upvalue */ | ||
| 324 | } | 345 | } |
| 325 | return load_aux(L, status); | 346 | return load_aux(L, status); |
| 326 | } | 347 | } |
| 327 | 348 | ||
| 328 | 349 | ||
| 329 | static int luaB_load (lua_State *L) { | 350 | #if defined(LUA_COMPAT_LOADSTRING) |
| 330 | return luaB_load_aux(L, 1); | 351 | #define luaB_loadstring luaB_load |
| 331 | } | 352 | #else |
| 332 | 353 | #define luaB_loadstring luaB_deprecated | |
| 333 | 354 | #endif | |
| 334 | static int luaB_loadin (lua_State *L) { | ||
| 335 | int n; | ||
| 336 | luaL_checkany(L, 1); | ||
| 337 | n = luaB_load_aux(L, 2); | ||
| 338 | if (n == 1) { /* success? */ | ||
| 339 | lua_pushvalue(L, 1); /* environment for loaded function */ | ||
| 340 | if (lua_setupvalue(L, -2, 1) == NULL) | ||
| 341 | luaL_error(L, "loaded chunk does not have an upvalue"); | ||
| 342 | } | ||
| 343 | return n; | ||
| 344 | } | ||
| 345 | 355 | ||
| 346 | 356 | ||
| 347 | static int luaB_loadstring (lua_State *L) { | ||
| 348 | lua_settop(L, 2); | ||
| 349 | lua_pushliteral(L, "tb"); | ||
| 350 | return luaB_load(L); /* dostring(s, n) == load(s, n, "tb") */ | ||
| 351 | |||
| 352 | } | ||
| 353 | /* }====================================================== */ | 357 | /* }====================================================== */ |
| 354 | 358 | ||
| 355 | 359 | ||
| @@ -391,7 +395,7 @@ static int luaB_select (lua_State *L) { · 35 unmodified lines | |||
| 391 | 395 | ||
| 392 | 396 | ||
| 393 | static int pcallcont (lua_State *L) { | 397 | static int pcallcont (lua_State *L) { |
| 394 | int errfunc; /* call has an error function in bottom of the stack */ | 398 | int errfunc = 0; /* =0 to avoid warnings */ |
| 395 | int status = lua_getctx(L, &errfunc); | 399 | int status = lua_getctx(L, &errfunc); |
| 396 | lua_assert(status != LUA_OK); | 400 | lua_assert(status != LUA_OK); |
| 397 | lua_pushboolean(L, (status == LUA_YIELD)); /* first result (status) */ | 401 | lua_pushboolean(L, (status == LUA_YIELD)); /* first result (status) */ |
| @@ -436,55 +440,27 @@ static int luaB_tostring (lua_State *L) { · 38 unmodified lines | |||
| 436 | } | 440 | } |
| 437 | 441 | ||
| 438 | 442 | ||
| 439 | static int luaB_newproxy (lua_State *L) { | ||
| 440 | lua_settop(L, 1); | ||
| 441 | lua_newuserdata(L, 0); /* create proxy */ | ||
| 442 | if (lua_toboolean(L, 1) == 0) | ||
| 443 | return 1; /* no metatable */ | ||
| 444 | else if (lua_isboolean(L, 1)) { | ||
| 445 | lua_createtable(L, 0, 1); /* create a new metatable `m' ... */ | ||
| 446 | lua_pushboolean(L, 1); | ||
| 447 | lua_setfield(L, -2, "__gc"); /* ... m.__gc = false (HACK!!)... */ | ||
| 448 | lua_pushvalue(L, -1); /* ... and mark `m' as a valid metatable */ | ||
| 449 | lua_pushboolean(L, 1); | ||
| 450 | lua_rawset(L, lua_upvalueindex(1)); /* weaktable[m] = true */ | ||
| 451 | } | ||
| 452 | else { | ||
| 453 | int validproxy = 0; /* to check if weaktable[metatable(u)] == true */ | ||
| 454 | if (lua_getmetatable(L, 1)) { | ||
| 455 | lua_rawget(L, lua_upvalueindex(1)); | ||
| 456 | validproxy = lua_toboolean(L, -1); | ||
| 457 | lua_pop(L, 1); /* remove value */ | ||
| 458 | } | ||
| 459 | luaL_argcheck(L, validproxy, 1, "boolean or proxy expected"); | ||
| 460 | lua_getmetatable(L, 1); /* metatable is valid; get it */ | ||
| 461 | } | ||
| 462 | lua_setmetatable(L, 2); | ||
| 463 | return 1; | ||
| 464 | } | ||
| 465 | |||
| 466 | |||
| 467 | static const luaL_Reg base_funcs[] = { | 443 | static const luaL_Reg base_funcs[] = { |
| 468 | {"assert", luaB_assert}, | 444 | {"assert", luaB_assert}, |
| 469 | {"collectgarbage", luaB_collectgarbage}, | 445 | {"collectgarbage", luaB_collectgarbage}, |
| 470 | {"dofile", luaB_dofile}, | 446 | {"dofile", luaB_dofile}, |
| 471 | {"error", luaB_error}, | 447 | {"error", luaB_error}, |
| 472 | {"getfenv", luaB_getfenv}, | 448 | {"getfenv", luaB_deprecated}, |
| 473 | {"getmetatable", luaB_getmetatable}, | 449 | {"getmetatable", luaB_getmetatable}, |
| 474 | {"ipairs", luaB_ipairs}, | 450 | {"ipairs", luaB_ipairs}, |
| 475 | {"loadfile", luaB_loadfile}, | 451 | {"loadfile", luaB_loadfile}, |
| 476 | {"load", luaB_load}, | 452 | {"load", luaB_load}, |
| 477 | {"loadin", luaB_loadin}, | ||
| 478 | {"loadstring", luaB_loadstring}, | 453 | {"loadstring", luaB_loadstring}, |
| 479 | {"next", luaB_next}, | 454 | {"next", luaB_next}, |
| 480 | {"pairs", luaB_pairs}, | 455 | {"pairs", luaB_pairs}, |
| 481 | {"pcall", luaB_pcall}, | 456 | {"pcall", luaB_pcall}, |
| 482 | {"print", luaB_print}, | 457 | {"print", luaB_print}, |
| 483 | {"rawequal", luaB_rawequal}, | 458 | {"rawequal", luaB_rawequal}, |
| 459 | {"rawlen", luaB_rawlen}, | ||
| 484 | {"rawget", luaB_rawget}, | 460 | {"rawget", luaB_rawget}, |
| 485 | {"rawset", luaB_rawset}, | 461 | {"rawset", luaB_rawset}, |
| 486 | {"select", luaB_select}, | 462 | {"select", luaB_select}, |
| 487 | {"setfenv", luaB_setfenv}, | 463 | {"setfenv", luaB_deprecated}, |
| 488 | {"setmetatable", luaB_setmetatable}, | 464 | {"setmetatable", luaB_setmetatable}, |
| 489 | {"tonumber", luaB_tonumber}, | 465 | {"tonumber", luaB_tonumber}, |
| 490 | {"tostring", luaB_tostring}, | 466 | {"tostring", luaB_tostring}, |
| @@ -503,14 +479,6 @@ LUAMOD_API int luaopen_base (lua_State *L) { · 12 unmodified lines | |||
| 503 | luaL_setfuncs(L, base_funcs, 0); | 479 | luaL_setfuncs(L, base_funcs, 0); |
| 504 | lua_pushliteral(L, LUA_VERSION); | 480 | lua_pushliteral(L, LUA_VERSION); |
| 505 | lua_setfield(L, -2, "_VERSION"); /* set global _VERSION */ | 481 | lua_setfield(L, -2, "_VERSION"); /* set global _VERSION */ |
| 506 | /* `newproxy' needs a weaktable as upvalue */ | ||
| 507 | lua_createtable(L, 0, 1); /* new table `w' */ | ||
| 508 | lua_pushvalue(L, -1); /* `w' will be its own metatable */ | ||
| 509 | lua_setmetatable(L, -2); | ||
| 510 | lua_pushliteral(L, "kv"); | ||
| 511 | lua_setfield(L, -2, "__mode"); /* metatable(w).__mode = "kv" */ | ||
| 512 | lua_pushcclosure(L, luaB_newproxy, 1); | ||
| 513 | lua_setfield(L, -2, "newproxy"); /* set global `newproxy' */ | ||
| 514 | return 1; | 482 | return 1; |
| 515 | } | 483 | } |
| 516 | 484 | ||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lbitlib.c,v 1.13 2010/11/22 18:06:33 roberto Exp $ | 2 | ** $Id: lbitlib.c,v 1.15 2010/12/17 13:26:38 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 | */ |
| @@ -14,25 +14,30 @@ · 8 unmodified lines | |||
| 14 | 14 | ||
| 15 | 15 | ||
| 16 | /* number of bits to consider in a number */ | 16 | /* number of bits to consider in a number */ |
| 17 | #define NBITS 32 | 17 | #if !defined(LUA_NBITS) |
| 18 | #define LUA_NBITS 32 | ||
| 19 | #endif | ||
| 18 | 20 | ||
| 19 | #define ALLONES (~(((~(lua_Unsigned)0) << (NBITS - 1)) << 1)) | ||
| 20 | 21 | ||
| 21 | /* mask to trim extra bits */ | 22 | #define ALLONES (~(((~(lua_Unsigned)0) << (LUA_NBITS - 1)) << 1)) |
| 23 | |||
| 24 | /* macro to trim extra bits */ | ||
| 22 | #define trim(x) ((x) & ALLONES) | 25 | #define trim(x) ((x) & ALLONES) |
| 23 | 26 | ||
| 24 | 27 | ||
| 25 | typedef lua_Unsigned b_uint; | 28 | /* builds a number with 'n' ones (1 <= n <= LUA_NBITS) */ |
| 29 | #define mask(n) (~((ALLONES << 1) << ((n) - 1))) | ||
| 30 | |||
| 26 | 31 | ||
| 32 | typedef lua_Unsigned b_uint; | ||
| 27 | 33 | ||
| 28 | #define getuintarg(L,arg) luaL_checkunsigned(L,arg) | ||
| 29 | 34 | ||
| 30 | 35 | ||
| 31 | static b_uint andaux (lua_State *L) { | 36 | static b_uint andaux (lua_State *L) { |
| 32 | int i, n = lua_gettop(L); | 37 | int i, n = lua_gettop(L); |
| 33 | b_uint r = ~(b_uint)0; | 38 | b_uint r = ~(b_uint)0; |
| 34 | for (i = 1; i <= n; i++) | 39 | for (i = 1; i <= n; i++) |
| 35 | r &= getuintarg(L, i); | 40 | r &= luaL_checkunsigned(L, i); |
| 36 | return trim(r); | 41 | return trim(r); |
| 37 | } | 42 | } |
| 38 | 43 | ||
| @@ -55,7 +60,7 @@ static int b_or (lua_State *L) { · 16 unmodified lines | |||
| 55 | int i, n = lua_gettop(L); | 60 | int i, n = lua_gettop(L); |
| 56 | b_uint r = 0; | 61 | b_uint r = 0; |
| 57 | for (i = 1; i <= n; i++) | 62 | for (i = 1; i <= n; i++) |
| 58 | r |= getuintarg(L, i); | 63 | r |= luaL_checkunsigned(L, i); |
| 59 | lua_pushunsigned(L, trim(r)); | 64 | lua_pushunsigned(L, trim(r)); |
| 60 | return 1; | 65 | return 1; |
| 61 | } | 66 | } |
| @@ -65,14 +70,14 @@ static int b_xor (lua_State *L) { · 3 unmodified lines | |||
| 65 | int i, n = lua_gettop(L); | 70 | int i, n = lua_gettop(L); |
| 66 | b_uint r = 0; | 71 | b_uint r = 0; |
| 67 | for (i = 1; i <= n; i++) | 72 | for (i = 1; i <= n; i++) |
| 68 | r ^= getuintarg(L, i); | 73 | r ^= luaL_checkunsigned(L, i); |
| 69 | lua_pushunsigned(L, trim(r)); | 74 | lua_pushunsigned(L, trim(r)); |
| 70 | return 1; | 75 | return 1; |
| 71 | } | 76 | } |
| 72 | 77 | ||
| 73 | 78 | ||
| 74 | static int b_not (lua_State *L) { | 79 | static int b_not (lua_State *L) { |
| 75 | b_uint r = ~getuintarg(L, 1); | 80 | b_uint r = ~luaL_checkunsigned(L, 1); |
| 76 | lua_pushunsigned(L, trim(r)); | 81 | lua_pushunsigned(L, trim(r)); |
| 77 | return 1; | 82 | return 1; |
| 78 | } | 83 | } |
| @@ -82,11 +87,11 @@ static int b_shift (lua_State *L, b_uint r, int i) { · 3 unmodified lines | |||
| 82 | if (i < 0) { /* shift right? */ | 87 | if (i < 0) { /* shift right? */ |
| 83 | i = -i; | 88 | i = -i; |
| 84 | r = trim(r); | 89 | r = trim(r); |
| 85 | if (i >= NBITS) r = 0; | 90 | if (i >= LUA_NBITS) r = 0; |
| 86 | else r >>= i; | 91 | else r >>= i; |
| 87 | } | 92 | } |
| 88 | else { /* shift left */ | 93 | else { /* shift left */ |
| 89 | if (i >= NBITS) r = 0; | 94 | if (i >= LUA_NBITS) r = 0; |
| 90 | else r <<= i; | 95 | else r <<= i; |
| 91 | r = trim(r); | 96 | r = trim(r); |
| 92 | } | 97 | } |
| @@ -96,22 +101,22 @@ static int b_shift (lua_State *L, b_uint r, int i) { · 3 unmodified lines | |||
| 96 | 101 | ||
| 97 | 102 | ||
| 98 | static int b_lshift (lua_State *L) { | 103 | static int b_lshift (lua_State *L) { |
| 99 | return b_shift(L, getuintarg(L, 1), luaL_checkint(L, 2)); | 104 | return b_shift(L, luaL_checkunsigned(L, 1), luaL_checkint(L, 2)); |
| 100 | } | 105 | } |
| 101 | 106 | ||
| 102 | 107 | ||
| 103 | static int b_rshift (lua_State *L) { | 108 | static int b_rshift (lua_State *L) { |
| 104 | return b_shift(L, getuintarg(L, 1), -luaL_checkint(L, 2)); | 109 | return b_shift(L, luaL_checkunsigned(L, 1), -luaL_checkint(L, 2)); |
| 105 | } | 110 | } |
| 106 | 111 | ||
| 107 | 112 | ||
| 108 | static int b_arshift (lua_State *L) { | 113 | static int b_arshift (lua_State *L) { |
| 109 | b_uint r = getuintarg(L, 1); | 114 | b_uint r = luaL_checkunsigned(L, 1); |
| 110 | int i = luaL_checkint(L, 2); | 115 | int i = luaL_checkint(L, 2); |
| 111 | if (i < 0 || !(r & ((b_uint)1 << (NBITS - 1)))) | 116 | if (i < 0 || !(r & ((b_uint)1 << (LUA_NBITS - 1)))) |
| 112 | return b_shift(L, r, -i); | 117 | return b_shift(L, r, -i); |
| 113 | else { /* arithmetic shift for 'negative' number */ | 118 | else { /* arithmetic shift for 'negative' number */ |
| 114 | if (i >= NBITS) r = ALLONES; | 119 | if (i >= LUA_NBITS) r = ALLONES; |
| 115 | else | 120 | else |
| 116 | r = trim((r >> i) | ~(~(b_uint)0 >> i)); /* add signal bit */ | 121 | r = trim((r >> i) | ~(~(b_uint)0 >> i)); /* add signal bit */ |
| 117 | lua_pushunsigned(L, r); | 122 | lua_pushunsigned(L, r); |
| @@ -121,10 +126,10 @@ static int b_arshift (lua_State *L) { · 3 unmodified lines | |||
| 121 | 126 | ||
| 122 | 127 | ||
| 123 | static int b_rot (lua_State *L, int i) { | 128 | static int b_rot (lua_State *L, int i) { |
| 124 | b_uint r = getuintarg(L, 1); | 129 | b_uint r = luaL_checkunsigned(L, 1); |
| 125 | i &= (NBITS - 1); /* i = i % NBITS */ | 130 | i &= (LUA_NBITS - 1); /* i = i % NBITS */ |
| 126 | r = trim(r); | 131 | r = trim(r); |
| 127 | r = (r << i) | (r >> (NBITS - i)); | 132 | r = (r << i) | (r >> (LUA_NBITS - i)); |
| 128 | lua_pushunsigned(L, trim(r)); | 133 | lua_pushunsigned(L, trim(r)); |
| 129 | return 1; | 134 | return 1; |
| 130 | } | 135 | } |
| @@ -140,17 +145,58 @@ static int b_rrot (lua_State *L) { · 9 unmodified lines | |||
| 140 | } | 145 | } |
| 141 | 146 | ||
| 142 | 147 | ||
| 148 | /* | ||
| 149 | ** get field and width arguments for field-manipulation functions, | ||
| 150 | ** checking whether they are valid | ||
| 151 | */ | ||
| 152 | static int fieldargs (lua_State *L, int farg, int *width) { | ||
| 153 | int f = luaL_checkint(L, farg); | ||
| 154 | int w = luaL_optint(L, farg + 1, 1); | ||
| 155 | luaL_argcheck(L, 0 <= f, farg, "field cannot be netative"); | ||
| 156 | luaL_argcheck(L, 0 < w, farg + 1, "width must be positive"); | ||
| 157 | if (f + w > LUA_NBITS) | ||
| 158 | luaL_error(L, "trying to access non-existent bits"); | ||
| 159 | *width = w; | ||
| 160 | return f; | ||
| 161 | } | ||
| 162 | |||
| 163 | |||
| 164 | static int b_extract (lua_State *L) { | ||
| 165 | int w; | ||
| 166 | b_uint r = luaL_checkunsigned(L, 1); | ||
| 167 | int f = fieldargs(L, 2, &w); | ||
| 168 | r = (r >> f) & mask(w); | ||
| 169 | lua_pushunsigned(L, r); | ||
| 170 | return 1; | ||
| 171 | } | ||
| 172 | |||
| 173 | |||
| 174 | static int b_replace (lua_State *L) { | ||
| 175 | int w; | ||
| 176 | b_uint r = luaL_checkunsigned(L, 1); | ||
| 177 | b_uint v = luaL_checkunsigned(L, 2); | ||
| 178 | int f = fieldargs(L, 3, &w); | ||
| 179 | int m = mask(w); | ||
| 180 | v &= m; /* erase bits outside given width */ | ||
| 181 | r = (r & ~(m << f)) | (v << f); | ||
| 182 | lua_pushunsigned(L, r); | ||
| 183 | return 1; | ||
| 184 | } | ||
| 185 | |||
| 186 | |||
| 143 | static const luaL_Reg bitlib[] = { | 187 | static const luaL_Reg bitlib[] = { |
| 144 | {"arshift", b_arshift}, | 188 | {"arshift", b_arshift}, |
| 145 | {"band", b_and}, | 189 | {"band", b_and}, |
| 146 | {"bnot", b_not}, | 190 | {"bnot", b_not}, |
| 147 | {"bor", b_or}, | 191 | {"bor", b_or}, |
| 148 | {"bxor", b_xor}, | 192 | {"bxor", b_xor}, |
| 193 | {"btest", b_test}, | ||
| 194 | {"extract", b_extract}, | ||
| 149 | {"lrotate", b_lrot}, | 195 | {"lrotate", b_lrot}, |
| 150 | {"lshift", b_lshift}, | 196 | {"lshift", b_lshift}, |
| 197 | {"replace", b_replace}, | ||
| 151 | {"rrotate", b_rrot}, | 198 | {"rrotate", b_rrot}, |
| 152 | {"rshift", b_rshift}, | 199 | {"rshift", b_rshift}, |
| 153 | {"btest", b_test}, | ||
| 154 | {NULL, NULL} | 200 | {NULL, NULL} |
| 155 | }; | 201 | }; |
| 156 | 202 | ||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lcode.c,v 2.49 2010/07/07 16:27:29 roberto Exp $ | 2 | ** $Id: lcode.c,v 2.56 2011/05/31 18:27:56 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 | */ |
| @@ -23,6 +23,7 @@ · 17 unmodified lines | |||
| 23 | #include "lparser.h" | 23 | #include "lparser.h" |
| 24 | #include "lstring.h" | 24 | #include "lstring.h" |
| 25 | #include "ltable.h" | 25 | #include "ltable.h" |
| 26 | #include "lvm.h" | ||
| 26 | 27 | ||
| 27 | 28 | ||
| 28 | #define hasjumps(e) ((e)->t != (e)->f) | 29 | #define hasjumps(e) ((e)->t != (e)->f) |
| @@ -35,19 +36,23 @@ static int isnumeral(expdesc *e) { · 6 unmodified lines | |||
| 35 | 36 | ||
| 36 | void luaK_nil (FuncState *fs, int from, int n) { | 37 | void luaK_nil (FuncState *fs, int from, int n) { |
| 37 | Instruction *previous; | 38 | Instruction *previous; |
| 39 | int l = from + n - 1; /* last register to set nil */ | ||
| 38 | if (fs->pc > fs->lasttarget) { /* no jumps to current position? */ | 40 | if (fs->pc > fs->lasttarget) { /* no jumps to current position? */ |
| 39 | previous = &fs->f->code[fs->pc-1]; | 41 | previous = &fs->f->code[fs->pc-1]; |
| 40 | if (GET_OPCODE(*previous) == OP_LOADNIL) { | 42 | if (GET_OPCODE(*previous) == OP_LOADNIL) { |
| 41 | int pfrom = GETARG_A(*previous); | 43 | int pfrom = GETARG_A(*previous); |
| 42 | int pto = GETARG_B(*previous); | 44 | int pl = pfrom + GETARG_B(*previous); |
| 43 | if (pfrom <= from && from <= pto+1) { /* can connect both? */ | 45 | if ((pfrom <= from && from <= pl + 1) || |
| 44 | if (from+n-1 > pto) | 46 | (from <= pfrom && pfrom <= l + 1)) { /* can connect both? */ |
| 45 | SETARG_B(*previous, from+n-1); | 47 | if (pfrom < from) from = pfrom; /* from = min(from, pfrom) */ |
| 48 | if (pl > l) l = pl; /* l = max(l, pl) */ | ||
| 49 | SETARG_A(*previous, from); | ||
| 50 | SETARG_B(*previous, l - from); | ||
| 46 | return; | 51 | return; |
| 47 | } | 52 | } |
| 48 | } | 53 | } /* else go through */ |
| 49 | } | 54 | } |
| 50 | luaK_codeABC(fs, OP_LOADNIL, from, from+n-1, 0); /* else no optimization */ | 55 | luaK_codeABC(fs, OP_LOADNIL, from, n - 1, 0); /* else no optimization */ |
| 51 | } | 56 | } |
| 52 | 57 | ||
| 53 | 58 | ||
| @@ -171,6 +176,19 @@ void luaK_patchlist (FuncState *fs, int list, int target) { · 117 unmodified lines | |||
| 171 | } | 176 | } |
| 172 | 177 | ||
| 173 | 178 | ||
| 179 | LUAI_FUNC void luaK_patchclose (FuncState *fs, int list, int level) { | ||
| 180 | level++; /* argument is +1 to reserve 0 as non-op */ | ||
| 181 | while (list != NO_JUMP) { | ||
| 182 | int next = getjump(fs, list); | ||
| 183 | lua_assert(GET_OPCODE(fs->f->code[list]) == OP_JMP && | ||
| 184 | (GETARG_A(fs->f->code[list]) == 0 || | ||
| 185 | GETARG_A(fs->f->code[list]) >= level)); | ||
| 186 | SETARG_A(fs->f->code[list], level); | ||
| 187 | list = next; | ||
| 188 | } | ||
| 189 | } | ||
| 190 | |||
| 191 | |||
| 174 | void luaK_patchtohere (FuncState *fs, int list) { | 192 | void luaK_patchtohere (FuncState *fs, int list) { |
| 175 | luaK_getlabel(fs); | 193 | luaK_getlabel(fs); |
| 176 | luaK_concat(fs, &fs->jpc, list); | 194 | luaK_concat(fs, &fs->jpc, list); |
| @@ -229,11 +247,11 @@ static int codeextraarg (FuncState *fs, int a) { · 52 unmodified lines | |||
| 229 | } | 247 | } |
| 230 | 248 | ||
| 231 | 249 | ||
| 232 | int luaK_codeABxX (FuncState *fs, OpCode o, int reg, int k) { | 250 | int luaK_codek (FuncState *fs, int reg, int k) { |
| 233 | if (k < MAXARG_Bx) | 251 | if (k <= MAXARG_Bx) |
| 234 | return luaK_codeABx(fs, o, reg, k + 1); | 252 | return luaK_codeABx(fs, OP_LOADK, reg, k); |
| 235 | else { | 253 | else { |
| 236 | int p = luaK_codeABx(fs, o, reg, 0); | 254 | int p = luaK_codeABx(fs, OP_LOADKX, reg, 0); |
| 237 | codeextraarg(fs, k); | 255 | codeextraarg(fs, k); |
| 238 | return p; | 256 | return p; |
| 239 | } | 257 | } |
| @@ -278,7 +296,7 @@ static int addk (FuncState *fs, TValue *key, TValue *v) { · 38 unmodified lines | |||
| 278 | if (ttisnumber(idx)) { | 296 | if (ttisnumber(idx)) { |
| 279 | lua_Number n = nvalue(idx); | 297 | lua_Number n = nvalue(idx); |
| 280 | lua_number2int(k, n); | 298 | lua_number2int(k, n); |
| 281 | if (luaO_rawequalObj(&f->k[k], v)) | 299 | if (luaV_rawequalobj(&f->k[k], v)) |
| 282 | return k; | 300 | return k; |
| 283 | /* else may be a collision (e.g., between 0.0 and "\0\0\0\0\0\0\0\0"); | 301 | /* else may be a collision (e.g., between 0.0 and "\0\0\0\0\0\0\0\0"); |
| 284 | go through and create a new entry for this value */ | 302 | go through and create a new entry for this value */ |
| @@ -564,15 +582,15 @@ void luaK_storevar (FuncState *fs, expdesc *var, expdesc *ex) { · 279 unmodified lines | |||
| 564 | 582 | ||
| 565 | 583 | ||
| 566 | void luaK_self (FuncState *fs, expdesc *e, expdesc *key) { | 584 | void luaK_self (FuncState *fs, expdesc *e, expdesc *key) { |
| 567 | int func; | 585 | int ereg; |
| 568 | luaK_exp2anyreg(fs, e); | 586 | luaK_exp2anyreg(fs, e); |
| 587 | ereg = e->u.info; /* register where 'e' was placed */ | ||
| 569 | freeexp(fs, e); | 588 | freeexp(fs, e); |
| 570 | func = fs->freereg; | 589 | e->u.info = fs->freereg; /* base register for op_self */ |
| 571 | luaK_codeABC(fs, OP_SELF, func, e->u.info, luaK_exp2RK(fs, key)); | ||
| 572 | freeexp(fs, key); | ||
| 573 | luaK_reserveregs(fs, 2); | ||
| 574 | e->u.info = func; | ||
| 575 | e->k = VNONRELOC; | 590 | e->k = VNONRELOC; |
| 591 | luaK_reserveregs(fs, 2); /* function and 'self' produced by op_self */ | ||
| 592 | luaK_codeABC(fs, OP_SELF, e->u.info, ereg, luaK_exp2RK(fs, key)); | ||
| 593 | freeexp(fs, key); | ||
| 576 | } | 594 | } |
| 577 | 595 | ||
| 578 | 596 | ||
| @@ -603,21 +621,14 @@ void luaK_goiftrue (FuncState *fs, expdesc *e) { · 24 unmodified lines | |||
| 603 | int pc; /* pc of last jump */ | 621 | int pc; /* pc of last jump */ |
| 604 | luaK_dischargevars(fs, e); | 622 | luaK_dischargevars(fs, e); |
| 605 | switch (e->k) { | 623 | switch (e->k) { |
| 606 | case VK: case VKNUM: case VTRUE: { | ||
| 607 | pc = NO_JUMP; /* always true; do nothing */ | ||
| 608 | break; | ||
| 609 | } | ||
| 610 | case VJMP: { | 624 | case VJMP: { |
| 611 | invertjump(fs, e); | 625 | invertjump(fs, e); |
| 612 | pc = e->u.info; | 626 | pc = e->u.info; |
| 613 | break; | 627 | break; |
| 614 | } | 628 | } |
| 615 | case VFALSE: { | 629 | case VK: case VKNUM: case VTRUE: { |
| 616 | if (!hasjumps(e)) { | 630 | pc = NO_JUMP; /* always true; do nothing */ |
| 617 | pc = luaK_jump(fs); /* always jump */ | 631 | break; |
| 618 | break; | ||
| 619 | } | ||
| 620 | /* else go through */ | ||
| 621 | } | 632 | } |
| 622 | default: { | 633 | default: { |
| 623 | pc = jumponcond(fs, e, 0); | 634 | pc = jumponcond(fs, e, 0); |
| @@ -634,20 +645,13 @@ static void luaK_goiffalse (FuncState *fs, expdesc *e) { · 10 unmodified lines | |||
| 634 | int pc; /* pc of last jump */ | 645 | int pc; /* pc of last jump */ |
| 635 | luaK_dischargevars(fs, e); | 646 | luaK_dischargevars(fs, e); |
| 636 | switch (e->k) { | 647 | switch (e->k) { |
| 637 | case VNIL: case VFALSE: { | ||
| 638 | pc = NO_JUMP; /* always false; do nothing */ | ||
| 639 | break; | ||
| 640 | } | ||
| 641 | case VJMP: { | 648 | case VJMP: { |
| 642 | pc = e->u.info; | 649 | pc = e->u.info; |
| 643 | break; | 650 | break; |
| 644 | } | 651 | } |
| 645 | case VTRUE: { | 652 | case VNIL: case VFALSE: { |
| 646 | if (!hasjumps(e)) { | 653 | pc = NO_JUMP; /* always false; do nothing */ |
| 647 | pc = luaK_jump(fs); /* always jump */ | 654 | break; |
| 648 | break; | ||
| 649 | } | ||
| 650 | /* else go through */ | ||
| 651 | } | 655 | } |
| 652 | default: { | 656 | default: { |
| 653 | pc = jumponcond(fs, e, 1); | 657 | pc = jumponcond(fs, e, 1); |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lcode.h,v 1.55 2010/07/02 20:42:40 roberto Exp $ | 2 | ** $Id: lcode.h,v 1.57 2011/04/07 18:14:12 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 | */ |
| @@ -44,11 +44,9 @@ typedef enum UnOpr { OPR_MINUS, OPR_NOT, OPR_LEN, OPR_NOUNOPR } UnOpr; · 38 unmodified lines | |||
| 44 | 44 | ||
| 45 | #define luaK_jumpto(fs,t) luaK_patchlist(fs, luaK_jump(fs), t) | 45 | #define luaK_jumpto(fs,t) luaK_patchlist(fs, luaK_jump(fs), t) |
| 46 | 46 | ||
| 47 | #define luaK_codek(fs,reg,k) luaK_codeABxX(fs, OP_LOADK, reg, k) | ||
| 48 | |||
| 49 | LUAI_FUNC int luaK_codeABx (FuncState *fs, OpCode o, int A, unsigned int Bx); | 47 | LUAI_FUNC int luaK_codeABx (FuncState *fs, OpCode o, int A, unsigned int Bx); |
| 50 | LUAI_FUNC int luaK_codeABC (FuncState *fs, OpCode o, int A, int B, int C); | 48 | LUAI_FUNC int luaK_codeABC (FuncState *fs, OpCode o, int A, int B, int C); |
| 51 | LUAI_FUNC int luaK_codeABxX (FuncState *fs, OpCode o, int reg, int k); | 49 | LUAI_FUNC int luaK_codek (FuncState *fs, int reg, int k); |
| 52 | LUAI_FUNC void luaK_fixline (FuncState *fs, int line); | 50 | LUAI_FUNC void luaK_fixline (FuncState *fs, int line); |
| 53 | LUAI_FUNC void luaK_nil (FuncState *fs, int from, int n); | 51 | LUAI_FUNC void luaK_nil (FuncState *fs, int from, int n); |
| 54 | LUAI_FUNC void luaK_reserveregs (FuncState *fs, int n); | 52 | LUAI_FUNC void luaK_reserveregs (FuncState *fs, int n); |
| @@ -71,6 +69,7 @@ LUAI_FUNC int luaK_jump (FuncState *fs); · 16 unmodified lines | |||
| 71 | LUAI_FUNC void luaK_ret (FuncState *fs, int first, int nret); | 69 | LUAI_FUNC void luaK_ret (FuncState *fs, int first, int nret); |
| 72 | LUAI_FUNC void luaK_patchlist (FuncState *fs, int list, int target); | 70 | LUAI_FUNC void luaK_patchlist (FuncState *fs, int list, int target); |
| 73 | LUAI_FUNC void luaK_patchtohere (FuncState *fs, int list); | 71 | LUAI_FUNC void luaK_patchtohere (FuncState *fs, int list); |
| 72 | LUAI_FUNC void luaK_patchclose (FuncState *fs, int list, int level); | ||
| 74 | LUAI_FUNC void luaK_concat (FuncState *fs, int *l1, int l2); | 73 | LUAI_FUNC void luaK_concat (FuncState *fs, int *l1, int l2); |
| 75 | LUAI_FUNC int luaK_getlabel (FuncState *fs); | 74 | LUAI_FUNC int luaK_getlabel (FuncState *fs); |
| 76 | LUAI_FUNC void luaK_prefix (FuncState *fs, UnOpr op, expdesc *v, int line); | 75 | LUAI_FUNC void luaK_prefix (FuncState *fs, UnOpr op, expdesc *v, int line); |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: ldblib.c,v 1.126 2010/11/16 18:01:28 roberto Exp $ | 2 | ** $Id: ldblib.c,v 1.130 2011/04/08 19:17:36 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 | */ |
| @@ -18,6 +18,9 @@ · 12 unmodified lines | |||
| 18 | #include "lualib.h" | 18 | #include "lualib.h" |
| 19 | 19 | ||
| 20 | 20 | ||
| 21 | #define HOOKKEY "_HKEY" | ||
| 22 | |||
| 23 | |||
| 21 | 24 | ||
| 22 | static int db_getregistry (lua_State *L) { | 25 | static int db_getregistry (lua_State *L) { |
| 23 | lua_pushvalue(L, LUA_REGISTRYINDEX); | 26 | lua_pushvalue(L, LUA_REGISTRYINDEX); |
| @@ -39,8 +42,8 @@ static int db_setmetatable (lua_State *L) { · 15 unmodified lines | |||
| 39 | luaL_argcheck(L, t == LUA_TNIL || t == LUA_TTABLE, 2, | 42 | luaL_argcheck(L, t == LUA_TNIL || t == LUA_TTABLE, 2, |
| 40 | "nil or table expected"); | 43 | "nil or table expected"); |
| 41 | lua_settop(L, 2); | 44 | lua_settop(L, 2); |
| 42 | lua_pushboolean(L, lua_setmetatable(L, 1)); | 45 | lua_setmetatable(L, 1); |
| 43 | return 1; | 46 | return 1; /* return 1st argument */ |
| 44 | } | 47 | } |
| 45 | 48 | ||
| 46 | 49 | ||
| @@ -250,14 +253,13 @@ static int db_upvaluejoin (lua_State *L) { · 203 unmodified lines | |||
| 250 | } | 253 | } |
| 251 | 254 | ||
| 252 | 255 | ||
| 253 | static const char KEY_HOOK = 'h'; | 256 | #define gethooktable(L) luaL_getsubtable(L, LUA_REGISTRYINDEX, HOOKKEY); |
| 254 | 257 | ||
| 255 | 258 | ||
| 256 | static void hookf (lua_State *L, lua_Debug *ar) { | 259 | static void hookf (lua_State *L, lua_Debug *ar) { |
| 257 | static const char *const hooknames[] = | 260 | static const char *const hooknames[] = |
| 258 | {"call", "return", "line", "count", "tail call"}; | 261 | {"call", "return", "line", "count", "tail call"}; |
| 259 | lua_pushlightuserdata(L, (void *)&KEY_HOOK); | 262 | gethooktable(L); |
| 260 | lua_rawget(L, LUA_REGISTRYINDEX); | ||
| 261 | lua_pushlightuserdata(L, L); | 263 | lua_pushlightuserdata(L, L); |
| 262 | lua_rawget(L, -2); | 264 | lua_rawget(L, -2); |
| 263 | if (lua_isfunction(L, -1)) { | 265 | if (lua_isfunction(L, -1)) { |
| @@ -291,19 +293,6 @@ static char *unmakemask (int mask, char *smask) { · 27 unmodified lines | |||
| 291 | } | 293 | } |
| 292 | 294 | ||
| 293 | 295 | ||
| 294 | static void gethooktable (lua_State *L) { | ||
| 295 | lua_pushlightuserdata(L, (void *)&KEY_HOOK); | ||
| 296 | lua_rawget(L, LUA_REGISTRYINDEX); | ||
| 297 | if (!lua_istable(L, -1)) { | ||
| 298 | lua_pop(L, 1); | ||
| 299 | lua_createtable(L, 0, 1); | ||
| 300 | lua_pushlightuserdata(L, (void *)&KEY_HOOK); | ||
| 301 | lua_pushvalue(L, -2); | ||
| 302 | lua_rawset(L, LUA_REGISTRYINDEX); | ||
| 303 | } | ||
| 304 | } | ||
| 305 | |||
| 306 | |||
| 307 | static int db_sethook (lua_State *L) { | 296 | static int db_sethook (lua_State *L) { |
| 308 | int arg, mask, count; | 297 | int arg, mask, count; |
| 309 | lua_Hook func; | 298 | lua_Hook func; |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: ldebug.c,v 2.74 2010/10/11 20:24:42 roberto Exp $ | 2 | ** $Id: ldebug.c,v 2.82 2011/06/02 19:31:40 roberto Exp $ |
| 3 | ** Debug Interface | 3 | ** Debug Interface |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -35,12 +35,12 @@ static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name); · 29 unmodified lines | |||
| 35 | 35 | ||
| 36 | static int currentpc (CallInfo *ci) { | 36 | static int currentpc (CallInfo *ci) { |
| 37 | lua_assert(isLua(ci)); | 37 | lua_assert(isLua(ci)); |
| 38 | return pcRel(ci->u.l.savedpc, ci_func(ci)->l.p); | 38 | return pcRel(ci->u.l.savedpc, ci_func(ci)->p); |
| 39 | } | 39 | } |
| 40 | 40 | ||
| 41 | 41 | ||
| 42 | static int currentline (CallInfo *ci) { | 42 | static int currentline (CallInfo *ci) { |
| 43 | return getfuncline(ci_func(ci)->l.p, currentpc(ci)); | 43 | return getfuncline(ci_func(ci)->p, currentpc(ci)); |
| 44 | } | 44 | } |
| 45 | 45 | ||
| 46 | 46 | ||
| @@ -94,13 +94,28 @@ LUA_API int lua_getstack (lua_State *L, int level, lua_Debug *ar) { · 47 unmodified lines | |||
| 94 | } | 94 | } |
| 95 | 95 | ||
| 96 | 96 | ||
| 97 | static const char *findvararg (CallInfo *ci, int n, StkId *pos) { | ||
| 98 | int nparams = clLvalue(ci->func)->p->numparams; | ||
| 99 | if (n >= ci->u.l.base - ci->func - nparams) | ||
| 100 | return NULL; /* no such vararg */ | ||
| 101 | else { | ||
| 102 | *pos = ci->func + nparams + n; | ||
| 103 | return "(*vararg)"; /* generic name for any vararg */ | ||
| 104 | } | ||
| 105 | } | ||
| 106 | |||
| 107 | |||
| 97 | static const char *findlocal (lua_State *L, CallInfo *ci, int n, | 108 | static const char *findlocal (lua_State *L, CallInfo *ci, int n, |
| 98 | StkId *pos) { | 109 | StkId *pos) { |
| 99 | const char *name = NULL; | 110 | const char *name = NULL; |
| 100 | StkId base; | 111 | StkId base; |
| 101 | if (isLua(ci)) { | 112 | if (isLua(ci)) { |
| 102 | base = ci->u.l.base; | 113 | if (n < 0) /* access to vararg values? */ |
| 103 | name = luaF_getlocalname(ci_func(ci)->l.p, n, currentpc(ci)); | 114 | return findvararg(ci, -n, pos); |
| 115 | else { | ||
| 116 | base = ci->u.l.base; | ||
| 117 | name = luaF_getlocalname(ci_func(ci)->p, n, currentpc(ci)); | ||
| 118 | } | ||
| 104 | } | 119 | } |
| 105 | else | 120 | else |
| 106 | base = ci->func + 1; | 121 | base = ci->func + 1; |
| @@ -108,10 +123,8 @@ static const char *findlocal (lua_State *L, CallInfo *ci, int n, · 1 unmodified line | |||
| 108 | StkId limit = (ci == L->ci) ? L->top : ci->next->func; | 123 | StkId limit = (ci == L->ci) ? L->top : ci->next->func; |
| 109 | if (limit - base >= n && n > 0) /* is 'n' inside 'ci' stack? */ | 124 | if (limit - base >= n && n > 0) /* is 'n' inside 'ci' stack? */ |
| 110 | name = "(*temporary)"; /* generic name for any valid slot */ | 125 | name = "(*temporary)"; /* generic name for any valid slot */ |
| 111 | else { | 126 | else |
| 112 | *pos = base; /* to avoid warnings */ | ||
| 113 | return NULL; /* no name */ | 127 | return NULL; /* no name */ |
| 114 | } | ||
| 115 | } | 128 | } |
| 116 | *pos = base + (n - 1); | 129 | *pos = base + (n - 1); |
| 117 | return name; | 130 | return name; |
| @@ -125,10 +138,10 @@ LUA_API const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n) { · 7 unmodified lines | |||
| 125 | if (!isLfunction(L->top - 1)) /* not a Lua function? */ | 138 | if (!isLfunction(L->top - 1)) /* not a Lua function? */ |
| 126 | name = NULL; | 139 | name = NULL; |
| 127 | else /* consider live variables at function start (parameters) */ | 140 | else /* consider live variables at function start (parameters) */ |
| 128 | name = luaF_getlocalname(clvalue(L->top - 1)->l.p, n, 0); | 141 | name = luaF_getlocalname(clLvalue(L->top - 1)->p, n, 0); |
| 129 | } | 142 | } |
| 130 | else { /* active function; get information through 'ar' */ | 143 | else { /* active function; get information through 'ar' */ |
| 131 | StkId pos; | 144 | StkId pos = 0; /* to avoid warnings */ |
| 132 | name = findlocal(L, ar->i_ci, n, &pos); | 145 | name = findlocal(L, ar->i_ci, n, &pos); |
| 133 | if (name) { | 146 | if (name) { |
| 134 | setobj2s(L, L->top, pos); | 147 | setobj2s(L, L->top, pos); |
| @@ -141,11 +154,11 @@ LUA_API const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n) { · 6 unmodified lines | |||
| 141 | 154 | ||
| 142 | 155 | ||
| 143 | LUA_API const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int n) { | 156 | LUA_API const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int n) { |
| 144 | StkId pos; | 157 | StkId pos = 0; /* to avoid warnings */ |
| 145 | const char *name = findlocal(L, ar->i_ci, n, &pos); | 158 | const char *name = findlocal(L, ar->i_ci, n, &pos); |
| 146 | lua_lock(L); | 159 | lua_lock(L); |
| 147 | if (name) | 160 | if (name) |
| 148 | setobjs2s(L, pos, L->top - 1); | 161 | setobjs2s(L, pos, L->top - 1); |
| 149 | L->top--; /* pop value */ | 162 | L->top--; /* pop value */ |
| 150 | lua_unlock(L); | 163 | lua_unlock(L); |
| 151 | return name; | 164 | return name; |
| @@ -243,7 +256,7 @@ LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar) { · 91 unmodified lines | |||
| 243 | if (*what == '>') { | 256 | if (*what == '>') { |
| 244 | ci = NULL; | 257 | ci = NULL; |
| 245 | func = L->top - 1; | 258 | func = L->top - 1; |
| 246 | luai_apicheck(L, ttisfunction(func)); | 259 | api_check(L, ttisfunction(func), "function expected"); |
| 247 | what++; /* skip the '>' */ | 260 | what++; /* skip the '>' */ |
| 248 | L->top--; /* pop function */ | 261 | L->top--; /* pop function */ |
| 249 | } | 262 | } |
| @@ -271,21 +284,38 @@ LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar) { · 21 unmodified lines | |||
| 271 | ** ======================================================= | 284 | ** ======================================================= |
| 272 | */ | 285 | */ |
| 273 | 286 | ||
| 287 | static const char *getobjname (lua_State *L, CallInfo *ci, int reg, | ||
| 288 | const char **name); | ||
| 274 | 289 | ||
| 275 | static void kname (Proto *p, int c, int reg, const char *what, | 290 | |
| 276 | const char **name) { | 291 | /* |
| 277 | if (c == reg && what && *what == 'c') | 292 | ** find a "name" for the RK value 'c' |
| 278 | return; /* index is a constant; name already correct */ | 293 | */ |
| 279 | else if (ISK(c) && ttisstring(&p->k[INDEXK(c)])) | 294 | static void kname (lua_State *L, CallInfo *ci, int c, int oreg, |
| 280 | *name = svalue(&p->k[INDEXK(c)]); | 295 | const char *what, const char **name) { |
| 281 | else | 296 | if (ISK(c)) { /* is 'c' a constant? */ |
| 282 | *name = "?"; | 297 | TValue *kvalue = &ci_func(ci)->p->k[INDEXK(c)]; |
| 298 | if (ttisstring(kvalue)) { /* literal constant? */ | ||
| 299 | *name = svalue(kvalue); /* it is its own name */ | ||
| 300 | return; | ||
| 301 | } | ||
| 302 | /* else no reasonable name found */ | ||
| 303 | } | ||
| 304 | else { /* 'c' is a register */ | ||
| 305 | if (c != oreg) /* not the original register? */ | ||
| 306 | what = getobjname(L, ci, c, name); /* search for 'c' */ | ||
| 307 | if (what && *what == 'c') { /* found a constant name? */ | ||
| 308 | return; /* 'name' already filled */ | ||
| 309 | } | ||
| 310 | /* else no reasonable name found */ | ||
| 311 | } | ||
| 312 | *name = "?"; /* no reasonable name found */ | ||
| 283 | } | 313 | } |
| 284 | 314 | ||
| 285 | 315 | ||
| 286 | static const char *getobjname (lua_State *L, CallInfo *ci, int reg, | 316 | static const char *getobjname (lua_State *L, CallInfo *ci, int reg, |
| 287 | const char **name) { | 317 | const char **name) { |
| 288 | Proto *p = ci_func(ci)->l.p; | 318 | Proto *p = ci_func(ci)->p; |
| 289 | const char *what = NULL; | 319 | const char *what = NULL; |
| 290 | int lastpc = currentpc(ci); | 320 | int lastpc = currentpc(ci); |
| 291 | int pc; | 321 | int pc; |
| @@ -312,10 +342,10 @@ static const char *getobjname (lua_State *L, CallInfo *ci, int reg, · 20 unmodified lines | |||
| 312 | if (reg == a) { | 342 | if (reg == a) { |
| 313 | int k = GETARG_C(i); /* key index */ | 343 | int k = GETARG_C(i); /* key index */ |
| 314 | int t = GETARG_B(i); | 344 | int t = GETARG_B(i); |
| 315 | const char *vn = (op == OP_GETTABLE) /* name of indexed variable */ | 345 | const char *vn = (op == OP_GETTABLE) /* name of indexed variable */ |
| 316 | ? luaF_getlocalname(p, t + 1, pc) | 346 | ? luaF_getlocalname(p, t + 1, pc) |
| 317 | : getstr(p->upvalues[t].name); | 347 | : getstr(p->upvalues[t].name); |
| 318 | kname(p, k, a, what, name); | 348 | kname(L, ci, k, a, what, name); |
| 319 | what = (vn && strcmp(vn, LUA_ENV) == 0) ? "global" : "field"; | 349 | what = (vn && strcmp(vn, LUA_ENV) == 0) ? "global" : "field"; |
| 320 | } | 350 | } |
| 321 | break; | 351 | break; |
| @@ -329,10 +359,11 @@ static const char *getobjname (lua_State *L, CallInfo *ci, int reg, · 7 unmodified lines | |||
| 329 | } | 359 | } |
| 330 | break; | 360 | break; |
| 331 | } | 361 | } |
| 332 | case OP_LOADK: { | 362 | case OP_LOADK: |
| 363 | case OP_LOADKX: { | ||
| 333 | if (reg == a) { | 364 | if (reg == a) { |
| 334 | int b = GETARG_Bx(i); | 365 | int b = (op == OP_LOADK) ? GETARG_Bx(i) |
| 335 | b = (b > 0) ? b - 1 : GETARG_Ax(p->code[pc + 1]); | 366 | : GETARG_Ax(p->code[pc + 1]); |
| 336 | if (ttisstring(&p->k[b])) { | 367 | if (ttisstring(&p->k[b])) { |
| 337 | what = "constant"; | 368 | what = "constant"; |
| 338 | *name = svalue(&p->k[b]); | 369 | *name = svalue(&p->k[b]); |
| @@ -341,15 +372,15 @@ static const char *getobjname (lua_State *L, CallInfo *ci, int reg, · 2 unmodified lines | |||
| 341 | break; | 372 | break; |
| 342 | } | 373 | } |
| 343 | case OP_LOADNIL: { | 374 | case OP_LOADNIL: { |
| 344 | int b = GETARG_B(i); /* move from 'b' to 'a' */ | 375 | int b = GETARG_B(i); |
| 345 | if (a <= reg && reg <= b) /* set registers from 'a' to 'b' */ | 376 | if (a <= reg && reg <= a + b) /* set registers from 'a' to 'a+b' */ |
| 346 | what = NULL; | 377 | what = NULL; |
| 347 | break; | 378 | break; |
| 348 | } | 379 | } |
| 349 | case OP_SELF: { | 380 | case OP_SELF: { |
| 350 | if (reg == a) { | 381 | if (reg == a) { |
| 351 | int k = GETARG_C(i); /* key index */ | 382 | int k = GETARG_C(i); /* key index */ |
| 352 | kname(p, k, a, what, name); | 383 | kname(L, ci, k, a, what, name); |
| 353 | what = "method"; | 384 | what = "method"; |
| 354 | } | 385 | } |
| 355 | break; | 386 | break; |
| @@ -371,6 +402,10 @@ static const char *getobjname (lua_State *L, CallInfo *ci, int reg, · 15 unmodified lines | |||
| 371 | pc += b; /* do the jump */ | 402 | pc += b; /* do the jump */ |
| 372 | break; | 403 | break; |
| 373 | } | 404 | } |
| 405 | case OP_TEST: { | ||
| 406 | if (reg == a) what = NULL; /* jumped code can change 'a' */ | ||
| 407 | break; | ||
| 408 | } | ||
| 374 | default: | 409 | default: |
| 375 | if (testAMode(op) && reg == a) what = NULL; | 410 | if (testAMode(op) && reg == a) what = NULL; |
| 376 | break; | 411 | break; |
| @@ -386,9 +421,9 @@ static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name) { · 9 unmodified lines | |||
| 386 | if ((ci->callstatus & CIST_TAIL) || !isLua(ci->previous)) | 421 | if ((ci->callstatus & CIST_TAIL) || !isLua(ci->previous)) |
| 387 | return NULL; /* calling function is not Lua (or is unknown) */ | 422 | return NULL; /* calling function is not Lua (or is unknown) */ |
| 388 | ci = ci->previous; /* calling function */ | 423 | ci = ci->previous; /* calling function */ |
| 389 | i = ci_func(ci)->l.p->code[currentpc(ci)]; | 424 | i = ci_func(ci)->p->code[currentpc(ci)]; |
| 390 | if (GET_OPCODE(i) == OP_EXTRAARG) /* extra argument? */ | 425 | if (GET_OPCODE(i) == OP_EXTRAARG) /* extra argument? */ |
| 391 | i = ci_func(ci)->l.p->code[currentpc(ci) - 1]; /* get 'real' instruction */ | 426 | i = ci_func(ci)->p->code[currentpc(ci) - 1]; /* get 'real' instruction */ |
| 392 | switch (GET_OPCODE(i)) { | 427 | switch (GET_OPCODE(i)) { |
| 393 | case OP_CALL: | 428 | case OP_CALL: |
| 394 | case OP_TAILCALL: | 429 | case OP_TAILCALL: |
| @@ -425,7 +460,10 @@ static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name) { · 30 unmodified lines | |||
| 425 | 460 | ||
| 426 | 461 | ||
| 427 | 462 | ||
| 428 | /* only ANSI way to check whether a pointer points to an array */ | 463 | /* |
| 464 | ** only ANSI way to check whether a pointer points to an array | ||
| 465 | ** (used only for error messages, so efficiency is not a big concern) | ||
| 466 | */ | ||
| 429 | static int isinstack (CallInfo *ci, const TValue *o) { | 467 | static int isinstack (CallInfo *ci, const TValue *o) { |
| 430 | StkId p; | 468 | StkId p; |
| 431 | for (p = ci->u.l.base; p < ci->top; p++) | 469 | for (p = ci->u.l.base; p < ci->top; p++) |
| @@ -436,7 +474,7 @@ static int isinstack (CallInfo *ci, const TValue *o) { · 4 unmodified lines | |||
| 436 | 474 | ||
| 437 | static const char *getupvalname (CallInfo *ci, const TValue *o, | 475 | static const char *getupvalname (CallInfo *ci, const TValue *o, |
| 438 | const char **name) { | 476 | const char **name) { |
| 439 | LClosure *c = &ci_func(ci)->l; | 477 | LClosure *c = ci_func(ci); |
| 440 | int i; | 478 | int i; |
| 441 | for (i = 0; i < c->nupvalues; i++) { | 479 | for (i = 0; i < c->nupvalues; i++) { |
| 442 | if (c->upvals[i]->v == o) { | 480 | if (c->upvals[i]->v == o) { |
| @@ -455,7 +493,7 @@ void luaG_typeerror (lua_State *L, const TValue *o, const char *op) { · 12 unmodified lines | |||
| 455 | const char *kind = NULL; | 493 | const char *kind = NULL; |
| 456 | if (isLua(ci)) { | 494 | if (isLua(ci)) { |
| 457 | kind = getupvalname(ci, o, &name); /* check whether 'o' is an upvalue */ | 495 | kind = getupvalname(ci, o, &name); /* check whether 'o' is an upvalue */ |
| 458 | if (!kind && isinstack(ci, o)) /* no? try a register */ | 496 | if (!kind && isinstack(ci, o)) /* no? try a register */ |
| 459 | kind = getobjname(L, ci, cast_int(o - ci->u.l.base), &name); | 497 | kind = getobjname(L, ci, cast_int(o - ci->u.l.base), &name); |
| 460 | } | 498 | } |
| 461 | if (kind) | 499 | if (kind) |
| @@ -497,7 +535,7 @@ static void addinfo (lua_State *L, const char *msg) { · 35 unmodified lines | |||
| 497 | if (isLua(ci)) { /* is Lua code? */ | 535 | if (isLua(ci)) { /* is Lua code? */ |
| 498 | char buff[LUA_IDSIZE]; /* add file:line information */ | 536 | char buff[LUA_IDSIZE]; /* add file:line information */ |
| 499 | int line = currentline(ci); | 537 | int line = currentline(ci); |
| 500 | TString *src = ci_func(ci)->l.p->source; | 538 | TString *src = ci_func(ci)->p->source; |
| 501 | if (src) | 539 | if (src) |
| 502 | luaO_chunkid(buff, getstr(src), LUA_IDSIZE); | 540 | luaO_chunkid(buff, getstr(src), LUA_IDSIZE); |
| 503 | else { /* no source available; use "?" instead */ | 541 | else { /* no source available; use "?" instead */ |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: ldebug.h,v 2.5 2009/06/10 16:57:53 roberto Exp $ | 2 | ** $Id: ldebug.h,v 2.6 2011/06/02 19:31:40 roberto Exp $ |
| 3 | ** Auxiliary functions from Debug Interface module | 3 | ** Auxiliary functions from Debug Interface module |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -17,6 +17,9 @@ · 11 unmodified lines | |||
| 17 | 17 | ||
| 18 | #define resethookcount(L) (L->hookcount = L->basehookcount) | 18 | #define resethookcount(L) (L->hookcount = L->basehookcount) |
| 19 | 19 | ||
| 20 | /* Active Lua function (given call info) */ | ||
| 21 | #define ci_func(ci) (clLvalue((ci)->func)) | ||
| 22 | |||
| 20 | 23 | ||
| 21 | LUAI_FUNC void luaG_typeerror (lua_State *L, const TValue *o, | 24 | LUAI_FUNC void luaG_typeerror (lua_State *L, const TValue *o, |
| 22 | const char *opname); | 25 | const char *opname); |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: ldo.c,v 2.90 2010/10/25 19:01:37 roberto Exp $ | 2 | ** $Id: ldo.c,v 2.95 2011/06/02 19:31:40 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 | */ |
| @@ -293,65 +293,59 @@ static StkId tryfuncTM (lua_State *L, StkId func) { · 287 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 | Closure *cl; | ||
| 297 | lua_CFunction f; | 296 | lua_CFunction f; |
| 298 | ptrdiff_t funcr; | 297 | CallInfo *ci; |
| 299 | if (!ttisfunction(func)) /* `func' is not a function? */ | 298 | int n; /* number of arguments (Lua) or returns (C) */ |
| 300 | func = tryfuncTM(L, func); /* check the `function' tag method */ | 299 | ptrdiff_t funcr = savestack(L, func); |
| 301 | funcr = savestack(L, func); | 300 | switch (ttype(func)) { |
| 302 | if (ttislcf(func)) { /* light C function? */ | 301 | case LUA_TLCF: /* light C function */ |
| 303 | f = fvalue(func); /* get it */ | 302 | f = fvalue(func); |
| 304 | goto isCfunc; /* go to call it */ | 303 | goto Cfunc; |
| 305 | } | 304 | case LUA_TCCL: { /* C closure */ |
| 306 | cl = clvalue(func); | 305 | f = clCvalue(func)->f; |
| 307 | if (cl->c.isC) { /* C closure? */ | 306 | Cfunc: |
| 308 | CallInfo *ci; | 307 | luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */ |
| 309 | int n; | 308 | ci = next_ci(L); /* now 'enter' new function */ |
| 310 | f = cl->c.f; | 309 | ci->nresults = nresults; |
| 311 | isCfunc: /* call C function 'f' */ | 310 | ci->func = restorestack(L, funcr); |
| 312 | luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */ | 311 | ci->top = L->top + LUA_MINSTACK; |
| 313 | ci = next_ci(L); /* now 'enter' new function */ | 312 | lua_assert(ci->top <= L->stack_last); |
| 314 | ci->nresults = nresults; | 313 | ci->callstatus = 0; |
| 315 | ci->func = restorestack(L, funcr); | 314 | if (L->hookmask & LUA_MASKCALL) |
| 316 | ci->top = L->top + LUA_MINSTACK; | 315 | luaD_hook(L, LUA_HOOKCALL, -1); |
| 317 | lua_assert(ci->top <= L->stack_last); | 316 | lua_unlock(L); |
| 318 | ci->callstatus = 0; | 317 | n = (*f)(L); /* do the actual call */ |
| 319 | if (L->hookmask & LUA_MASKCALL) | 318 | lua_lock(L); |
| 320 | luaD_hook(L, LUA_HOOKCALL, -1); | 319 | api_checknelems(L, n); |
| 321 | lua_unlock(L); | 320 | luaD_poscall(L, L->top - n); |
| 322 | n = (*f)(L); /* do the actual call */ | 321 | return 1; |
| 323 | lua_lock(L); | 322 | } |
| 324 | api_checknelems(L, n); | 323 | case LUA_TLCL: { /* Lua function: prepare its call */ |
| 325 | luaD_poscall(L, L->top - n); | 324 | StkId base; |
| 326 | return 1; | 325 | Proto *p = clLvalue(func)->p; |
| 327 | } | 326 | luaD_checkstack(L, p->maxstacksize); |
| 328 | else { /* Lua function: prepare its call */ | 327 | func = restorestack(L, funcr); |
| 329 | CallInfo *ci; | 328 | n = cast_int(L->top - func) - 1; /* number of real arguments */ |
| 330 | int nparams, nargs; | 329 | for (; n < p->numparams; n++) |
| 331 | StkId base; | 330 | setnilvalue(L->top++); /* complete missing arguments */ |
| 332 | Proto *p = cl->l.p; | 331 | base = (!p->is_vararg) ? func + 1 : adjust_varargs(L, p, n); |
| 333 | luaD_checkstack(L, p->maxstacksize); | 332 | ci = next_ci(L); /* now 'enter' new function */ |
| 334 | func = restorestack(L, funcr); | 333 | ci->nresults = nresults; |
| 335 | nargs = cast_int(L->top - func) - 1; /* number of real arguments */ | 334 | ci->func = func; |
| 336 | nparams = p->numparams; /* number of expected parameters */ | 335 | ci->u.l.base = base; |
| 337 | for (; nargs < nparams; nargs++) | 336 | ci->top = base + p->maxstacksize; |
| 338 | setnilvalue(L->top++); /* complete missing arguments */ | 337 | lua_assert(ci->top <= L->stack_last); |
| 339 | if (!p->is_vararg) /* no varargs? */ | 338 | ci->u.l.savedpc = p->code; /* starting point */ |
| 340 | base = func + 1; | 339 | ci->callstatus = CIST_LUA; |
| 341 | else /* vararg function */ | 340 | L->top = ci->top; |
| 342 | base = adjust_varargs(L, p, nargs); | 341 | if (L->hookmask & LUA_MASKCALL) |
| 343 | ci = next_ci(L); /* now 'enter' new function */ | 342 | callhook(L, ci); |
| 344 | ci->nresults = nresults; | 343 | return 0; |
| 345 | ci->func = func; | 344 | } |
| 346 | ci->u.l.base = base; | 345 | default: { /* not a function */ |
| 347 | ci->top = base + p->maxstacksize; | 346 | func = tryfuncTM(L, func); /* retry with 'function' tag method */ |
| 348 | lua_assert(ci->top <= L->stack_last); | 347 | return luaD_precall(L, func, nresults); |
| 349 | ci->u.l.savedpc = p->code; /* starting point */ | 348 | } |
| 350 | ci->callstatus = CIST_LUA; | ||
| 351 | L->top = ci->top; | ||
| 352 | if (L->hookmask & LUA_MASKCALL) | ||
| 353 | callhook(L, ci); | ||
| 354 | return 0; | ||
| 355 | } | 349 | } |
| 356 | } | 350 | } |
| 357 | 351 | ||
| @@ -615,8 +609,8 @@ int luaD_pcall (lua_State *L, Pfunc func, void *u, · 257 unmodified lines | |||
| 615 | */ | 609 | */ |
| 616 | struct SParser { /* data to `f_parser' */ | 610 | struct SParser { /* data to `f_parser' */ |
| 617 | ZIO *z; | 611 | ZIO *z; |
| 618 | Mbuffer buff; /* buffer to be used by the scanner */ | 612 | Mbuffer buff; /* dynamic structure used by the scanner */ |
| 619 | Varlist varl; /* list of local variables (to be used by the parser) */ | 613 | Dyndata dyd; /* dynamic structures used by the parser */ |
| 620 | const char *name; | 614 | const char *name; |
| 621 | }; | 615 | }; |
| 622 | 616 | ||
| @@ -625,14 +619,14 @@ static void f_parser (lua_State *L, void *ud) { · 2 unmodified lines | |||
| 625 | Proto *tf; | 619 | Proto *tf; |
| 626 | Closure *cl; | 620 | Closure *cl; |
| 627 | struct SParser *p = cast(struct SParser *, ud); | 621 | struct SParser *p = cast(struct SParser *, ud); |
| 628 | int c = luaZ_lookahead(p->z); | 622 | int c = zgetc(p->z); /* read first character */ |
| 629 | tf = (c == LUA_SIGNATURE[0]) | 623 | tf = (c == LUA_SIGNATURE[0]) |
| 630 | ? luaU_undump(L, p->z, &p->buff, p->name) | 624 | ? luaU_undump(L, p->z, &p->buff, p->name) |
| 631 | : luaY_parser(L, p->z, &p->buff, &p->varl, p->name); | 625 | : luaY_parser(L, p->z, &p->buff, &p->dyd, p->name, c); |
| 632 | setptvalue2s(L, L->top, tf); | 626 | setptvalue2s(L, L->top, tf); |
| 633 | incr_top(L); | 627 | incr_top(L); |
| 634 | cl = luaF_newLclosure(L, tf); | 628 | cl = luaF_newLclosure(L, tf); |
| 635 | setclvalue(L, L->top - 1, cl); | 629 | setclLvalue(L, L->top - 1, cl); |
| 636 | for (i = 0; i < tf->sizeupvalues; i++) /* initialize upvalues */ | 630 | for (i = 0; i < tf->sizeupvalues; i++) /* initialize upvalues */ |
| 637 | cl->l.upvals[i] = luaF_newupval(L); | 631 | cl->l.upvals[i] = luaF_newupval(L); |
| 638 | } | 632 | } |
| @@ -643,11 +637,15 @@ int luaD_protectedparser (lua_State *L, ZIO *z, const char *name) { · 4 unmodified lines | |||
| 643 | int status; | 637 | int status; |
| 644 | L->nny++; /* cannot yield during parsing */ | 638 | L->nny++; /* cannot yield during parsing */ |
| 645 | p.z = z; p.name = name; | 639 | p.z = z; p.name = name; |
| 646 | p.varl.actvar = NULL; p.varl.nactvar = p.varl.actvarsize = 0; | 640 | p.dyd.actvar.arr = NULL; p.dyd.actvar.size = 0; |
| 641 | p.dyd.gt.arr = NULL; p.dyd.gt.size = 0; | ||
| 642 | p.dyd.label.arr = NULL; p.dyd.label.size = 0; | ||
| 647 | luaZ_initbuffer(L, &p.buff); | 643 | luaZ_initbuffer(L, &p.buff); |
| 648 | status = luaD_pcall(L, f_parser, &p, savestack(L, L->top), L->errfunc); | 644 | status = luaD_pcall(L, f_parser, &p, savestack(L, L->top), L->errfunc); |
| 649 | luaZ_freebuffer(L, &p.buff); | 645 | luaZ_freebuffer(L, &p.buff); |
| 650 | luaM_freearray(L, p.varl.actvar, p.varl.actvarsize); | 646 | luaM_freearray(L, p.dyd.actvar.arr, p.dyd.actvar.size); |
| 647 | luaM_freearray(L, p.dyd.gt.arr, p.dyd.gt.size); | ||
| 648 | luaM_freearray(L, p.dyd.label.arr, p.dyd.label.size); | ||
| 651 | L->nny--; | 649 | L->nny--; |
| 652 | return status; | 650 | return status; |
| 653 | } | 651 | } |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: ldump.c,v 1.17 2010/10/13 21:04:52 lhf Exp $ | 2 | ** $Id: ldump.c,v 1.18 2011/05/06 13:35:17 lhf 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 | */ |
| @@ -69,7 +69,7 @@ static void DumpString(const TString* s, DumpState* D) · 63 unmodified lines | |||
| 69 | { | 69 | { |
| 70 | size_t size=s->tsv.len+1; /* include trailing '\0' */ | 70 | size_t size=s->tsv.len+1; /* include trailing '\0' */ |
| 71 | DumpVar(size,D); | 71 | DumpVar(size,D); |
| 72 | DumpBlock(getstr(s),size,D); | 72 | DumpBlock(getstr(s),size*sizeof(char),D); |
| 73 | } | 73 | } |
| 74 | } | 74 | } |
| 75 | 75 | ||
| @@ -150,7 +150,7 @@ static void DumpFunction(const Proto* f, DumpState* D) · 74 unmodified lines | |||
| 150 | 150 | ||
| 151 | static void DumpHeader(DumpState* D) | 151 | static void DumpHeader(DumpState* D) |
| 152 | { | 152 | { |
| 153 | char h[LUAC_HEADERSIZE]; | 153 | lu_byte h[LUAC_HEADERSIZE]; |
| 154 | luaU_header(h); | 154 | luaU_header(h); |
| 155 | DumpBlock(h,LUAC_HEADERSIZE,D); | 155 | DumpBlock(h,LUAC_HEADERSIZE,D); |
| 156 | } | 156 | } |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lgc.c,v 2.103 2010/10/25 19:01:37 roberto Exp $ | 2 | ** $Id: lgc.c,v 2.109 2011/05/05 19:42:25 roberto Exp $ |
| 3 | ** Garbage Collector | 3 | ** Garbage Collector |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -51,7 +51,7 @@ · 45 unmodified lines | |||
| 51 | ** standard negative debt for GC; a reasonable "time" to wait before | 51 | ** standard negative debt for GC; a reasonable "time" to wait before |
| 52 | ** starting a new cycle | 52 | ** starting a new cycle |
| 53 | */ | 53 | */ |
| 54 | #define stddebt(g) (-cast(l_mem, g->totalbytes/100) * g->gcpause) | 54 | #define stddebt(g) (-cast(l_mem, gettotalbytes(g)/100) * g->gcpause) |
| 55 | 55 | ||
| 56 | 56 | ||
| 57 | /* | 57 | /* |
| @@ -68,11 +68,15 @@ · 10 unmodified lines | |||
| 68 | #define stringmark(s) ((void)((s) && resetbits((s)->tsv.marked, WHITEBITS))) | 68 | #define stringmark(s) ((void)((s) && resetbits((s)->tsv.marked, WHITEBITS))) |
| 69 | 69 | ||
| 70 | 70 | ||
| 71 | #define isfinalized(u) testbit((u)->marked, FINALIZEDBIT) | 71 | #define isfinalized(x) testbit(gch(x)->marked, FINALIZEDBIT) |
| 72 | 72 | ||
| 73 | #define checkdeadkey(n) lua_assert(!ttisdeadkey(gkey(n)) || ttisnil(gval(n))) | 73 | #define checkdeadkey(n) lua_assert(!ttisdeadkey(gkey(n)) || ttisnil(gval(n))) |
| 74 | 74 | ||
| 75 | 75 | ||
| 76 | #define checkconsistency(obj) \ | ||
| 77 | lua_longassert(!iscollectable(obj) || righttt(obj)) | ||
| 78 | |||
| 79 | |||
| 76 | #define markvalue(g,o) { checkconsistency(o); \ | 80 | #define markvalue(g,o) { checkconsistency(o); \ |
| 77 | if (valiswhite(o)) reallymarkobject(g,gcvalue(o)); } | 81 | if (valiswhite(o)) reallymarkobject(g,gcvalue(o)); } |
| 78 | 82 | ||
| @@ -114,12 +118,11 @@ static void removeentry (Node *n) { · 35 unmodified lines | |||
| 114 | */ | 118 | */ |
| 115 | static int iscleared (const TValue *o, int iskey) { | 119 | static int iscleared (const TValue *o, int iskey) { |
| 116 | if (!iscollectable(o)) return 0; | 120 | if (!iscollectable(o)) return 0; |
| 117 | if (ttisstring(o)) { | 121 | else if (ttisstring(o)) { |
| 118 | stringmark(rawtsvalue(o)); /* strings are `values', so are never weak */ | 122 | stringmark(rawtsvalue(o)); /* strings are `values', so are never weak */ |
| 119 | return 0; | 123 | return 0; |
| 120 | } | 124 | } |
| 121 | return iswhite(gcvalue(o)) || | 125 | else return iswhite(gcvalue(o)) || (!iskey && isfinalized(gcvalue(o))); |
| 122 | (ttisuserdata(o) && (!iskey && isfinalized(uvalue(o)))); | ||
| 123 | } | 126 | } |
| 124 | 127 | ||
| 125 | 128 | ||
| @@ -319,8 +322,7 @@ static void remarkupvals (global_State *g) { · 193 unmodified lines | |||
| 319 | ** mark root set and reset all gray lists, to start a new | 322 | ** mark root set and reset all gray lists, to start a new |
| 320 | ** incremental (or full) collection | 323 | ** incremental (or full) collection |
| 321 | */ | 324 | */ |
| 322 | static void markroot (lua_State *L) { | 325 | static void markroot (global_State *g) { |
| 323 | global_State *g = G(L); | ||
| 324 | g->gray = g->grayagain = NULL; | 326 | g->gray = g->grayagain = NULL; |
| 325 | g->weak = g->allweak = g->ephemeron = NULL; | 327 | g->weak = g->allweak = g->ephemeron = NULL; |
| 326 | markobject(g, g->mainthread); | 328 | markobject(g, g->mainthread); |
| @@ -635,6 +637,7 @@ static GCObject **sweeplist (lua_State *L, GCObject **p, lu_mem count) { · 308 unmodified lines | |||
| 635 | int ow = otherwhite(g); | 637 | int ow = otherwhite(g); |
| 636 | int toclear, toset; /* bits to clear and to set in all live objects */ | 638 | int toclear, toset; /* bits to clear and to set in all live objects */ |
| 637 | int tostop; /* stop sweep when this is true */ | 639 | int tostop; /* stop sweep when this is true */ |
| 640 | l_mem debt = g->GCdebt; /* current debt */ | ||
| 638 | if (isgenerational(g)) { /* generational mode? */ | 641 | if (isgenerational(g)) { /* generational mode? */ |
| 639 | toclear = ~0; /* clear nothing */ | 642 | toclear = ~0; /* clear nothing */ |
| 640 | toset = bitmask(OLDBIT); /* set the old bit of all surviving objects */ | 643 | toset = bitmask(OLDBIT); /* set the old bit of all surviving objects */ |
| @@ -657,13 +660,15 @@ static GCObject **sweeplist (lua_State *L, GCObject **p, lu_mem count) { · 16 unmodified lines | |||
| 657 | sweepthread(L, gco2th(curr)); /* sweep thread's upvalues */ | 660 | sweepthread(L, gco2th(curr)); /* sweep thread's upvalues */ |
| 658 | if (testbits(marked, tostop)) { | 661 | if (testbits(marked, tostop)) { |
| 659 | static GCObject *nullp = NULL; | 662 | static GCObject *nullp = NULL; |
| 660 | return &nullp; /* stop sweeping this list */ | 663 | p = &nullp; /* stop sweeping this list */ |
| 664 | break; | ||
| 661 | } | 665 | } |
| 662 | /* update marks */ | 666 | /* update marks */ |
| 663 | gch(curr)->marked = cast_byte((marked & toclear) | toset); | 667 | gch(curr)->marked = cast_byte((marked & toclear) | toset); |
| 664 | p = &gch(curr)->next; /* go to next element */ | 668 | p = &gch(curr)->next; /* go to next element */ |
| 665 | } | 669 | } |
| 666 | } | 670 | } |
| 671 | luaE_setdebt(g, debt); /* sweeping should not change debt */ | ||
| 667 | return p; | 672 | return p; |
| 668 | } | 673 | } |
| 669 | 674 | ||
| @@ -687,19 +692,17 @@ static void checkSizes (lua_State *L) { · 17 unmodified lines | |||
| 687 | } | 692 | } |
| 688 | 693 | ||
| 689 | 694 | ||
| 690 | static Udata *udata2finalize (global_State *g) { | 695 | static GCObject *udata2finalize (global_State *g) { |
| 691 | GCObject *o = g->tobefnz; /* get first element */ | 696 | GCObject *o = g->tobefnz; /* get first element */ |
| 692 | Udata *u = rawgco2u(o); | 697 | lua_assert(isfinalized(o)); |
| 693 | lua_assert(isfinalized(&u->uv)); | 698 | g->tobefnz = gch(o)->next; /* remove it from 'tobefnz' list */ |
| 694 | lua_assert(!isold(o)); | 699 | gch(o)->next = g->allgc; /* return it to 'allgc' list */ |
| 695 | g->tobefnz = u->uv.next; /* remove it from 'tobefnz' list */ | ||
| 696 | u->uv.next = g->allgc; /* return it to 'allgc' list */ | ||
| 697 | g->allgc = o; | 700 | g->allgc = o; |
| 698 | resetbit(u->uv.marked, SEPARATED); /* mark that it is not in 'tobefnz' */ | 701 | resetbit(gch(o)->marked, SEPARATED); /* mark that it is not in 'tobefnz' */ |
| 699 | resetoldbit(o); /* see MOVE OLD rule */ | 702 | lua_assert(!isold(o)); /* see MOVE OLD rule */ |
| 700 | if (!keepinvariant(g)) /* not keeping invariant? */ | 703 | if (!keepinvariant(g)) /* not keeping invariant? */ |
| 701 | makewhite(g, o); /* "sweep" object */ | 704 | makewhite(g, o); /* "sweep" object */ |
| 702 | return u; | 705 | return o; |
| 703 | } | 706 | } |
| 704 | 707 | ||
| 705 | 708 | ||
| @@ -711,20 +714,22 @@ static void dothecall (lua_State *L, void *ud) { · 5 unmodified lines | |||
| 711 | 714 | ||
| 712 | static void GCTM (lua_State *L, int propagateerrors) { | 715 | static void GCTM (lua_State *L, int propagateerrors) { |
| 713 | global_State *g = G(L); | 716 | global_State *g = G(L); |
| 714 | Udata *udata = udata2finalize(g); | 717 | const TValue *tm; |
| 715 | const TValue *tm = gfasttm(g, udata->uv.metatable, TM_GC); | 718 | TValue v; |
| 719 | setgcovalue(L, &v, udata2finalize(g)); | ||
| 720 | tm = luaT_gettmbyobj(L, &v, TM_GC); | ||
| 716 | if (tm != NULL && ttisfunction(tm)) { /* is there a finalizer? */ | 721 | if (tm != NULL && ttisfunction(tm)) { /* is there a finalizer? */ |
| 717 | int status; | 722 | int status; |
| 718 | lu_byte oldah = L->allowhook; | 723 | lu_byte oldah = L->allowhook; |
| 719 | lu_mem oldd = g->GCdebt; | 724 | int running = g->gcrunning; |
| 720 | L->allowhook = 0; /* stop debug hooks during GC tag method */ | 725 | L->allowhook = 0; /* stop debug hooks during GC tag method */ |
| 721 | stopgc(g); /* avoid GC steps */ | 726 | g->gcrunning = 0; /* avoid GC steps */ |
| 722 | setobj2s(L, L->top, tm); /* push finalizer... */ | 727 | setobj2s(L, L->top, tm); /* push finalizer... */ |
| 723 | setuvalue(L, L->top+1, udata); /* ... and its argument */ | 728 | setobj2s(L, L->top + 1, &v); /* ... and its argument */ |
| 724 | L->top += 2; /* and (next line) call the finalizer */ | 729 | L->top += 2; /* and (next line) call the finalizer */ |
| 725 | status = luaD_pcall(L, dothecall, NULL, savestack(L, L->top - 2), 0); | 730 | status = luaD_pcall(L, dothecall, NULL, savestack(L, L->top - 2), 0); |
| 726 | L->allowhook = oldah; /* restore hooks */ | 731 | L->allowhook = oldah; /* restore hooks */ |
| 727 | g->GCdebt = oldd; /* restore threshold */ | 732 | g->gcrunning = running; /* restore state */ |
| 728 | if (status != LUA_OK && propagateerrors) { /* error while running __gc? */ | 733 | if (status != LUA_OK && propagateerrors) { /* error while running __gc? */ |
| 729 | if (status == LUA_ERRRUN) { /* is there an error msg.? */ | 734 | if (status == LUA_ERRRUN) { /* is there an error msg.? */ |
| 730 | luaO_pushfstring(L, "error in __gc tag method (%s)", | 735 | luaO_pushfstring(L, "error in __gc tag method (%s)", |
| @@ -738,25 +743,25 @@ static void GCTM (lua_State *L, int propagateerrors) { · 7 unmodified lines | |||
| 738 | 743 | ||
| 739 | 744 | ||
| 740 | /* | 745 | /* |
| 741 | ** move all unreachable udata that need finalization from list 'udgc' to | 746 | ** move all unreachable objects that need finalization from list 'finobj' |
| 742 | ** list 'tobefnz' | 747 | ** to list 'tobefnz' |
| 743 | */ | 748 | */ |
| 744 | void luaC_separateudata (lua_State *L, int all) { | 749 | void luaC_separateudata (lua_State *L, int all) { |
| 745 | global_State *g = G(L); | 750 | global_State *g = G(L); |
| 746 | GCObject **p = &g->udgc; | 751 | GCObject **p = &g->finobj; |
| 747 | GCObject *curr; | 752 | GCObject *curr; |
| 748 | GCObject **lastnext = &g->tobefnz; | 753 | GCObject **lastnext = &g->tobefnz; |
| 749 | /* find last 'next' field in 'tobefnz' list (to add elements in its end) */ | 754 | /* find last 'next' field in 'tobefnz' list (to add elements in its end) */ |
| 750 | while (*lastnext != NULL) | 755 | while (*lastnext != NULL) |
| 751 | lastnext = &gch(*lastnext)->next; | 756 | lastnext = &gch(*lastnext)->next; |
| 752 | while ((curr = *p) != NULL) { /* traverse all finalizable objects */ | 757 | while ((curr = *p) != NULL) { /* traverse all finalizable objects */ |
| 753 | lua_assert(gch(curr)->tt == LUA_TUSERDATA && !isfinalized(gco2u(curr))); | 758 | lua_assert(!isfinalized(curr)); |
| 754 | lua_assert(testbit(gch(curr)->marked, SEPARATED)); | 759 | lua_assert(testbit(gch(curr)->marked, SEPARATED)); |
| 755 | if (!(all || iswhite(curr))) /* not being collected? */ | 760 | if (!(all || iswhite(curr))) /* not being collected? */ |
| 756 | p = &gch(curr)->next; /* don't bother with it */ | 761 | p = &gch(curr)->next; /* don't bother with it */ |
| 757 | else { | 762 | else { |
| 758 | l_setbit(gch(curr)->marked, FINALIZEDBIT); /* won't be finalized again */ | 763 | l_setbit(gch(curr)->marked, FINALIZEDBIT); /* won't be finalized again */ |
| 759 | *p = gch(curr)->next; /* remove 'curr' from 'udgc' list */ | 764 | *p = gch(curr)->next; /* remove 'curr' from 'finobj' list */ |
| 760 | gch(curr)->next = *lastnext; /* link at the end of 'tobefnz' list */ | 765 | gch(curr)->next = *lastnext; /* link at the end of 'tobefnz' list */ |
| 761 | *lastnext = curr; | 766 | *lastnext = curr; |
| 762 | lastnext = &gch(curr)->next; | 767 | lastnext = &gch(curr)->next; |
| @@ -766,23 +771,23 @@ void luaC_separateudata (lua_State *L, int all) { · 3 unmodified lines | |||
| 766 | 771 | ||
| 767 | 772 | ||
| 768 | /* | 773 | /* |
| 769 | ** if userdata 'u' has a finalizer, remove it from 'allgc' list (must | 774 | ** if object 'o' has a finalizer, remove it from 'allgc' list (must |
| 770 | ** search the list to find it) and link it in 'udgc' list. | 775 | ** search the list to find it) and link it in 'finobj' list. |
| 771 | */ | 776 | */ |
| 772 | void luaC_checkfinalizer (lua_State *L, Udata *u) { | 777 | void luaC_checkfinalizer (lua_State *L, GCObject *o, Table *mt) { |
| 773 | global_State *g = G(L); | 778 | global_State *g = G(L); |
| 774 | if (testbit(u->uv.marked, SEPARATED) || /* udata is already separated... */ | 779 | if (testbit(gch(o)->marked, SEPARATED) || /* obj. is already separated... */ |
| 775 | isfinalized(&u->uv) || /* ... or is finalized... */ | 780 | isfinalized(o) || /* ... or is finalized... */ |
| 776 | gfasttm(g, u->uv.metatable, TM_GC) == NULL) /* or has no finalizer? */ | 781 | gfasttm(g, mt, TM_GC) == NULL) /* or has no finalizer? */ |
| 777 | return; /* nothing to be done */ | 782 | return; /* nothing to be done */ |
| 778 | else { /* move 'u' to 'udgc' list */ | 783 | else { /* move 'o' to 'finobj' list */ |
| 779 | GCObject **p; | 784 | GCObject **p; |
| 780 | for (p = &g->allgc; *p != obj2gco(u); p = &gch(*p)->next) ; | 785 | for (p = &g->allgc; *p != o; p = &gch(*p)->next) ; |
| 781 | *p = u->uv.next; /* remove 'u' from root list */ | 786 | *p = gch(o)->next; /* remove 'o' from root list */ |
| 782 | u->uv.next = g->udgc; /* link it in list 'udgc' */ | 787 | gch(o)->next = g->finobj; /* link it in list 'finobj' */ |
| 783 | g->udgc = obj2gco(u); | 788 | g->finobj = o; |
| 784 | l_setbit(u->uv.marked, SEPARATED); /* mark it as such */ | 789 | l_setbit(gch(o)->marked, SEPARATED); /* mark it as such */ |
| 785 | resetoldbit(obj2gco(u)); /* see MOVE OLD rule */ | 790 | resetoldbit(o); /* see MOVE OLD rule */ |
| 786 | } | 791 | } |
| 787 | } | 792 | } |
| 788 | 793 | ||
| @@ -808,7 +813,7 @@ void luaC_changemode (lua_State *L, int mode) { · 19 unmodified lines | |||
| 808 | if (mode == KGC_GEN) { /* change to generational mode */ | 813 | if (mode == KGC_GEN) { /* change to generational mode */ |
| 809 | /* make sure gray lists are consistent */ | 814 | /* make sure gray lists are consistent */ |
| 810 | luaC_runtilstate(L, bitmask(GCSpropagate)); | 815 | luaC_runtilstate(L, bitmask(GCSpropagate)); |
| 811 | g->lastmajormem = g->totalbytes; | 816 | g->lastmajormem = gettotalbytes(g); |
| 812 | g->gckind = KGC_GEN; | 817 | g->gckind = KGC_GEN; |
| 813 | } | 818 | } |
| 814 | else { /* change to incremental mode */ | 819 | else { /* change to incremental mode */ |
| @@ -823,10 +828,14 @@ void luaC_changemode (lua_State *L, int mode) { · 8 unmodified lines | |||
| 823 | 828 | ||
| 824 | 829 | ||
| 825 | /* | 830 | /* |
| 826 | ** call all pending finalizers */ | 831 | ** call all pending finalizers |
| 832 | */ | ||
| 827 | static void callallpendingfinalizers (lua_State *L, int propagateerrors) { | 833 | static void callallpendingfinalizers (lua_State *L, int propagateerrors) { |
| 828 | global_State *g = G(L); | 834 | global_State *g = G(L); |
| 829 | while (g->tobefnz) GCTM(L, propagateerrors); | 835 | while (g->tobefnz) { |
| 836 | resetoldbit(g->tobefnz); | ||
| 837 | GCTM(L, propagateerrors); | ||
| 838 | } | ||
| 830 | } | 839 | } |
| 831 | 840 | ||
| 832 | 841 | ||
| @@ -837,8 +846,8 @@ void luaC_freeallobjects (lua_State *L) { · 4 unmodified lines | |||
| 837 | /* following "white" makes all objects look dead */ | 846 | /* following "white" makes all objects look dead */ |
| 838 | g->currentwhite = WHITEBITS; | 847 | g->currentwhite = WHITEBITS; |
| 839 | g->gckind = KGC_NORMAL; | 848 | g->gckind = KGC_NORMAL; |
| 840 | sweepwholelist(L, &g->udgc); | 849 | sweepwholelist(L, &g->finobj); |
| 841 | lua_assert(g->udgc == NULL); | 850 | lua_assert(g->finobj == NULL); |
| 842 | sweepwholelist(L, &g->allgc); | 851 | sweepwholelist(L, &g->allgc); |
| 843 | lua_assert(g->allgc == NULL); | 852 | lua_assert(g->allgc == NULL); |
| 844 | for (i = 0; i < g->strt.size; i++) /* free all string lists */ | 853 | for (i = 0; i < g->strt.size; i++) /* free all string lists */ |
| @@ -883,7 +892,7 @@ static l_mem singlestep (lua_State *L) { · 38 unmodified lines | |||
| 883 | switch (g->gcstate) { | 892 | switch (g->gcstate) { |
| 884 | case GCSpause: { | 893 | case GCSpause: { |
| 885 | if (!isgenerational(g)) | 894 | if (!isgenerational(g)) |
| 886 | markroot(L); /* start a new collection */ | 895 | markroot(g); /* start a new collection */ |
| 887 | /* in any case, root must be marked */ | 896 | /* in any case, root must be marked */ |
| 888 | lua_assert(!iswhite(obj2gco(g->mainthread)) | 897 | lua_assert(!iswhite(obj2gco(g->mainthread)) |
| 889 | && !iswhite(gcvalue(&g->l_registry))); | 898 | && !iswhite(gcvalue(&g->l_registry))); |
| @@ -905,7 +914,7 @@ static l_mem singlestep (lua_State *L) { · 15 unmodified lines | |||
| 905 | return GCSWEEPCOST; | 914 | return GCSWEEPCOST; |
| 906 | } | 915 | } |
| 907 | else { /* no more strings to sweep */ | 916 | else { /* no more strings to sweep */ |
| 908 | g->sweepgc = &g->udgc; /* prepare to sweep userdata */ | 917 | g->sweepgc = &g->finobj; /* prepare to sweep finalizable objects */ |
| 909 | g->gcstate = GCSsweepudata; | 918 | g->gcstate = GCSsweepudata; |
| 910 | return 0; | 919 | return 0; |
| 911 | } | 920 | } |
| @@ -955,15 +964,15 @@ static void generationalcollection (lua_State *L) { · 43 unmodified lines | |||
| 955 | global_State *g = G(L); | 964 | global_State *g = G(L); |
| 956 | if (g->lastmajormem == 0) { /* signal for another major collection? */ | 965 | if (g->lastmajormem == 0) { /* signal for another major collection? */ |
| 957 | luaC_fullgc(L, 0); /* perform a full regular collection */ | 966 | luaC_fullgc(L, 0); /* perform a full regular collection */ |
| 958 | g->lastmajormem = g->totalbytes; /* update control */ | 967 | g->lastmajormem = gettotalbytes(g); /* update control */ |
| 959 | } | 968 | } |
| 960 | else { | 969 | else { |
| 961 | luaC_runtilstate(L, ~bitmask(GCSpause)); /* run complete cycle */ | 970 | luaC_runtilstate(L, ~bitmask(GCSpause)); /* run complete cycle */ |
| 962 | luaC_runtilstate(L, bitmask(GCSpause)); | 971 | luaC_runtilstate(L, bitmask(GCSpause)); |
| 963 | if (g->totalbytes > g->lastmajormem/100 * g->gcmajorinc) | 972 | if (gettotalbytes(g) > g->lastmajormem/100 * g->gcmajorinc) |
| 964 | g->lastmajormem = 0; /* signal for a major collection */ | 973 | g->lastmajormem = 0; /* signal for a major collection */ |
| 965 | } | 974 | } |
| 966 | g->GCdebt = stddebt(g); | 975 | luaE_setdebt(g, stddebt(g)); |
| 967 | } | 976 | } |
| 968 | 977 | ||
| 969 | 978 | ||
| @@ -974,21 +983,33 @@ static void step (lua_State *L) { · 4 unmodified lines | |||
| 974 | lim -= singlestep(L); | 983 | lim -= singlestep(L); |
| 975 | } while (lim > 0 && g->gcstate != GCSpause); | 984 | } while (lim > 0 && g->gcstate != GCSpause); |
| 976 | if (g->gcstate != GCSpause) | 985 | if (g->gcstate != GCSpause) |
| 977 | g->GCdebt -= GCSTEPSIZE; | 986 | luaE_setdebt(g, g->GCdebt - GCSTEPSIZE); |
| 978 | else | 987 | else |
| 979 | g->GCdebt = stddebt(g); | 988 | luaE_setdebt(g, stddebt(g)); |
| 980 | } | 989 | } |
| 981 | 990 | ||
| 982 | 991 | ||
| 983 | void luaC_step (lua_State *L) { | 992 | /* |
| 993 | ** performs a basic GC step even if the collector is stopped | ||
| 994 | */ | ||
| 995 | void luaC_forcestep (lua_State *L) { | ||
| 996 | global_State *g = G(L); | ||
| 984 | int i; | 997 | int i; |
| 985 | if (isgenerational(G(L))) generationalcollection(L); | 998 | if (isgenerational(g)) generationalcollection(L); |
| 986 | else step(L); | 999 | else step(L); |
| 987 | for (i = 0; i < GCFINALIZENUM && G(L)->tobefnz; i++) | 1000 | for (i = 0; i < GCFINALIZENUM && g->tobefnz; i++) |
| 988 | GCTM(L, 1); /* Call a few pending finalizers */ | 1001 | GCTM(L, 1); /* Call a few pending finalizers */ |
| 989 | } | 1002 | } |
| 990 | 1003 | ||
| 991 | 1004 | ||
| 1005 | /* | ||
| 1006 | ** performs a basic GC step only if collector is running | ||
| 1007 | */ | ||
| 1008 | void luaC_step (lua_State *L) { | ||
| 1009 | if (G(L)->gcrunning) luaC_forcestep(L); | ||
| 1010 | } | ||
| 1011 | |||
| 1012 | |||
| 992 | /* | 1013 | /* |
| 993 | ** performs a full GC cycle; if "isemergency", does not call | 1014 | ** performs a full GC cycle; if "isemergency", does not call |
| 994 | ** finalizers (which could change stack positions) | 1015 | ** finalizers (which could change stack positions) |
| @@ -1016,7 +1037,7 @@ void luaC_fullgc (lua_State *L, int isemergency) { · 21 unmodified lines | |||
| 1016 | luaC_runtilstate(L, bitmask(GCSpropagate)); | 1037 | luaC_runtilstate(L, bitmask(GCSpropagate)); |
| 1017 | } | 1038 | } |
| 1018 | g->gckind = origkind; | 1039 | g->gckind = origkind; |
| 1019 | g->GCdebt = stddebt(g); | 1040 | luaE_setdebt(g, stddebt(g)); |
| 1020 | if (!isemergency) /* do not run finalizers during emergency GC */ | 1041 | if (!isemergency) /* do not run finalizers during emergency GC */ |
| 1021 | callallpendingfinalizers(L, 1); | 1042 | callallpendingfinalizers(L, 1); |
| 1022 | } | 1043 | } |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lgc.h,v 2.44 2010/06/30 14:11:17 roberto Exp $ | 2 | ** $Id: lgc.h,v 2.50 2011/01/26 16:30:02 roberto Exp $ |
| 3 | ** Garbage Collector | 3 | ** Garbage Collector |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -52,10 +52,6 @@ · 46 unmodified lines | |||
| 52 | #define keepinvariant(g) (isgenerational(g) || g->gcstate <= GCSatomic) | 52 | #define keepinvariant(g) (isgenerational(g) || g->gcstate <= GCSatomic) |
| 53 | 53 | ||
| 54 | 54 | ||
| 55 | #define gcstopped(g) ((g)->GCdebt == MIN_LMEM) | ||
| 56 | #define stopgc(g) ((g)->GCdebt = MIN_LMEM) | ||
| 57 | |||
| 58 | |||
| 59 | /* | 55 | /* |
| 60 | ** some useful bit tricks | 56 | ** some useful bit tricks |
| 61 | */ | 57 | */ |
| @@ -76,8 +72,8 @@ · 14 unmodified lines | |||
| 76 | #define WHITE0BIT 0 /* object is white (type 0) */ | 72 | #define WHITE0BIT 0 /* object is white (type 0) */ |
| 77 | #define WHITE1BIT 1 /* object is white (type 1) */ | 73 | #define WHITE1BIT 1 /* object is white (type 1) */ |
| 78 | #define BLACKBIT 2 /* object is black */ | 74 | #define BLACKBIT 2 /* object is black */ |
| 79 | #define FINALIZEDBIT 3 /* for userdata: has been finalized */ | 75 | #define FINALIZEDBIT 3 /* object has been separated for finalization */ |
| 80 | #define SEPARATED 4 /* " ": it's in 'udgc' list or in 'tobefnz' */ | 76 | #define SEPARATED 4 /* object is in 'finobj' list or in 'tobefnz' */ |
| 81 | #define FIXEDBIT 5 /* object is fixed (should not be collected) */ | 77 | #define FIXEDBIT 5 /* object is fixed (should not be collected) */ |
| 82 | #define OLDBIT 6 /* object is old (only in generational mode) */ | 78 | #define OLDBIT 6 /* object is old (only in generational mode) */ |
| 83 | /* bit 7 is currently used by tests (luaL_checkmemory) */ | 79 | /* bit 7 is currently used by tests (luaL_checkmemory) */ |
| @@ -108,7 +104,9 @@ · 24 unmodified lines | |||
| 108 | #define luaC_white(g) cast(lu_byte, (g)->currentwhite & WHITEBITS) | 104 | #define luaC_white(g) cast(lu_byte, (g)->currentwhite & WHITEBITS) |
| 109 | 105 | ||
| 110 | 106 | ||
| 111 | #define luaC_checkGC(L) {condchangemem(L); if (G(L)->GCdebt > 0) luaC_step(L);} | 107 | #define luaC_condGC(L,c) \ |
| 108 | {if (G(L)->GCdebt > 0) {c;}; condchangemem(L);} | ||
| 109 | #define luaC_checkGC(L) luaC_condGC(L, luaC_step(L);) | ||
| 112 | 110 | ||
| 113 | 111 | ||
| 114 | #define luaC_barrier(L,p,v) { if (valiswhite(v) && isblack(obj2gco(p))) \ | 112 | #define luaC_barrier(L,p,v) { if (valiswhite(v) && isblack(obj2gco(p))) \ |
| @@ -130,6 +128,7 @@ · 15 unmodified lines | |||
| 130 | LUAI_FUNC void luaC_separateudata (lua_State *L, int all); | 128 | LUAI_FUNC void luaC_separateudata (lua_State *L, int all); |
| 131 | LUAI_FUNC void luaC_freeallobjects (lua_State *L); | 129 | LUAI_FUNC void luaC_freeallobjects (lua_State *L); |
| 132 | LUAI_FUNC void luaC_step (lua_State *L); | 130 | LUAI_FUNC void luaC_step (lua_State *L); |
| 131 | LUAI_FUNC void luaC_forcestep (lua_State *L); | ||
| 133 | LUAI_FUNC void luaC_runtilstate (lua_State *L, int statesmask); | 132 | LUAI_FUNC void luaC_runtilstate (lua_State *L, int statesmask); |
| 134 | LUAI_FUNC void luaC_fullgc (lua_State *L, int isemergency); | 133 | LUAI_FUNC void luaC_fullgc (lua_State *L, int isemergency); |
| 135 | LUAI_FUNC GCObject *luaC_newobj (lua_State *L, int tt, size_t sz, | 134 | LUAI_FUNC GCObject *luaC_newobj (lua_State *L, int tt, size_t sz, |
| @@ -137,7 +136,7 @@ LUAI_FUNC GCObject *luaC_newobj (lua_State *L, int tt, size_t sz, · 1 unmodified line | |||
| 137 | LUAI_FUNC void luaC_barrier_ (lua_State *L, GCObject *o, GCObject *v); | 136 | LUAI_FUNC void luaC_barrier_ (lua_State *L, GCObject *o, GCObject *v); |
| 138 | LUAI_FUNC void luaC_barrierback_ (lua_State *L, GCObject *o); | 137 | LUAI_FUNC void luaC_barrierback_ (lua_State *L, GCObject *o); |
| 139 | LUAI_FUNC void luaC_barrierproto_ (lua_State *L, Proto *p, Closure *c); | 138 | LUAI_FUNC void luaC_barrierproto_ (lua_State *L, Proto *p, Closure *c); |
| 140 | LUAI_FUNC void luaC_checkfinalizer (lua_State *L, Udata *u); | 139 | LUAI_FUNC void luaC_checkfinalizer (lua_State *L, GCObject *o, Table *mt); |
| 141 | LUAI_FUNC void luaC_checkupvalcolor (global_State *g, UpVal *uv); | 140 | LUAI_FUNC void luaC_checkupvalcolor (global_State *g, UpVal *uv); |
| 142 | LUAI_FUNC void luaC_changemode (lua_State *L, int mode); | 141 | LUAI_FUNC void luaC_changemode (lua_State *L, int mode); |
| 143 | 142 | ||
| @@ -1,16 +1,16 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: linit.c,v 1.30 2010/11/12 15:48:30 roberto Exp $ | 2 | ** $Id: linit.c,v 1.32 2011/04/08 19:17:36 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 | */ |
| 6 | 6 | ||
| 7 | 7 | ||
| 8 | /* | 8 | /* |
| 9 | ** If you embed Lua in your program and need to open the standard | 9 | ** If you embed Lua in your program and need to open the standard |
| 10 | ** libraries, call luaL_openlibs in your program. If you need a | 10 | ** libraries, call luaL_openlibs in your program. If you need a |
| 11 | ** different set of libraries, copy this file to your project and edit | 11 | ** different set of libraries, copy this file to your project and edit |
| 12 | ** it to suit your needs. | 12 | ** it to suit your needs. |
| 13 | */ | 13 | */ |
| 14 | 14 | ||
| 15 | 15 | ||
| 16 | #define linit_c | 16 | #define linit_c |
| @@ -57,7 +57,7 @@ LUALIB_API void luaL_openlibs (lua_State *L) { · 40 unmodified lines | |||
| 57 | lua_pop(L, 1); /* remove lib */ | 57 | lua_pop(L, 1); /* remove lib */ |
| 58 | } | 58 | } |
| 59 | /* add open functions from 'preloadedlibs' into 'package.preload' table */ | 59 | /* add open functions from 'preloadedlibs' into 'package.preload' table */ |
| 60 | luaL_findtable(L, LUA_REGISTRYINDEX, "_PRELOAD"); | 60 | luaL_getsubtable(L, LUA_REGISTRYINDEX, "_PRELOAD"); |
| 61 | for (lib = preloadedlibs; lib->func; lib++) { | 61 | for (lib = preloadedlibs; lib->func; lib++) { |
| 62 | lua_pushcfunction(L, lib->func); | 62 | lua_pushcfunction(L, lib->func); |
| 63 | lua_setfield(L, -2, lib->name); | 63 | lua_setfield(L, -2, lib->name); |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: liolib.c,v 2.95 2010/11/10 18:05:36 roberto Exp $ | 2 | ** $Id: liolib.c,v 2.99 2011/03/03 16:34:46 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 | */ |
| @@ -26,28 +26,29 @@ · 20 unmodified lines | |||
| 26 | ** lua_popen spawns a new process connected to the current one through | 26 | ** lua_popen spawns a new process connected to the current one through |
| 27 | ** the file streams. | 27 | ** the file streams. |
| 28 | */ | 28 | */ |
| 29 | #if !defined(lua_popen) | 29 | #if !defined(lua_popen) /* { */ |
| 30 | 30 | ||
| 31 | #if defined(LUA_USE_POPEN) | 31 | #if defined(LUA_USE_POPEN) /* { */ |
| 32 | 32 | ||
| 33 | #define lua_popen(L,c,m) ((void)L, fflush(NULL), popen(c,m)) | 33 | #define lua_popen(L,c,m) ((void)L, fflush(NULL), popen(c,m)) |
| 34 | #define lua_pclose(L,file) ((void)L, pclose(file)) | 34 | #define lua_pclose(L,file) ((void)L, pclose(file)) |
| 35 | 35 | ||
| 36 | #elif defined(LUA_WIN) | 36 | #elif defined(LUA_WIN) /* }{ */ |
| 37 | 37 | ||
| 38 | #define lua_popen(L,c,m) ((void)L, _popen(c,m)) | 38 | #define lua_popen(L,c,m) ((void)L, _popen(c,m)) |
| 39 | #define lua_pclose(L,file) ((void)L, _pclose(file)) | 39 | #define lua_pclose(L,file) ((void)L, _pclose(file)) |
| 40 | 40 | ||
| 41 | #else | ||
| 42 | 41 | ||
| 43 | #define lua_popen(L,c,m) ((void)((void)c, m), \ | 42 | #else /* }{ */ |
| 44 | luaL_error(L, LUA_QL("popen") " not supported"), (FILE*)0) | ||
| 45 | #define lua_pclose(L,file) ((void)((void)L, file), -1) | ||
| 46 | 43 | ||
| 47 | #endif | 44 | #define lua_popen(L,c,m) ((void)((void)c, m), \ |
| 45 | luaL_error(L, LUA_QL("popen") " not supported"), (FILE*)0) | ||
| 46 | #define lua_pclose(L,file) ((void)((void)L, file), -1) | ||
| 48 | 47 | ||
| 49 | #endif | ||
| 50 | 48 | ||
| 49 | #endif /* } */ | ||
| 50 | |||
| 51 | #endif /* } */ | ||
| 51 | 52 | ||
| 52 | 53 | ||
| 53 | #define IO_INPUT 1 | 54 | #define IO_INPUT 1 |
| @@ -57,24 +58,6 @@ · 3 unmodified lines | |||
| 57 | static const char *const fnames[] = {"input", "output"}; | 58 | static const char *const fnames[] = {"input", "output"}; |
| 58 | 59 | ||
| 59 | 60 | ||
| 60 | static int pushresult (lua_State *L, int i, const char *filename) { | ||
| 61 | int en = errno; /* calls to Lua API may change this value */ | ||
| 62 | if (i) { | ||
| 63 | lua_pushboolean(L, 1); | ||
| 64 | return 1; | ||
| 65 | } | ||
| 66 | else { | ||
| 67 | lua_pushnil(L); | ||
| 68 | if (filename) | ||
| 69 | lua_pushfstring(L, "%s: %s", filename, strerror(en)); | ||
| 70 | else | ||
| 71 | lua_pushfstring(L, "%s", strerror(en)); | ||
| 72 | lua_pushinteger(L, en); | ||
| 73 | return 3; | ||
| 74 | } | ||
| 75 | } | ||
| 76 | |||
| 77 | |||
| 78 | static void fileerror (lua_State *L, int arg, const char *filename) { | 61 | static void fileerror (lua_State *L, int arg, const char *filename) { |
| 79 | lua_pushfstring(L, "%s: %s", filename, strerror(errno)); | 62 | lua_pushfstring(L, "%s: %s", filename, strerror(errno)); |
| 80 | luaL_argerror(L, arg, lua_tostring(L, -1)); | 63 | luaL_argerror(L, arg, lua_tostring(L, -1)); |
| @@ -143,13 +126,8 @@ static int io_noclose (lua_State *L) { · 62 unmodified lines | |||
| 143 | static int io_pclose (lua_State *L) { | 126 | static int io_pclose (lua_State *L) { |
| 144 | FILE **p = tofilep(L); | 127 | FILE **p = tofilep(L); |
| 145 | int stat = lua_pclose(L, *p); | 128 | int stat = lua_pclose(L, *p); |
| 146 | *p = NULL; | 129 | *p = NULL; /* mark stream as closed (for GC) */ |
| 147 | if (stat == -1) /* error? */ | 130 | return luaL_execresult(L, stat); |
| 148 | return pushresult(L, 0, NULL); | ||
| 149 | else { | ||
| 150 | lua_pushinteger(L, stat); | ||
| 151 | return 1; /* return status */ | ||
| 152 | } | ||
| 153 | } | 131 | } |
| 154 | 132 | ||
| 155 | 133 | ||
| @@ -159,8 +137,8 @@ static int io_pclose (lua_State *L) { · 3 unmodified lines | |||
| 159 | static int io_fclose (lua_State *L) { | 137 | static int io_fclose (lua_State *L) { |
| 160 | FILE **p = tofilep(L); | 138 | FILE **p = tofilep(L); |
| 161 | int ok = (fclose(*p) == 0); | 139 | int ok = (fclose(*p) == 0); |
| 162 | *p = NULL; | 140 | *p = NULL; /* mark stream as closed (for GC) */ |
| 163 | return pushresult(L, ok, NULL); | 141 | return luaL_fileresult(L, ok, NULL); |
| 164 | } | 142 | } |
| 165 | 143 | ||
| 166 | 144 | ||
| @@ -181,8 +159,7 @@ static int io_close (lua_State *L) { · 14 unmodified lines | |||
| 181 | 159 | ||
| 182 | static int io_gc (lua_State *L) { | 160 | static int io_gc (lua_State *L) { |
| 183 | FILE *f = *tofilep(L); | 161 | FILE *f = *tofilep(L); |
| 184 | /* ignore closed files */ | 162 | if (f != NULL) /* ignore closed files */ |
| 185 | if (f != NULL) | ||
| 186 | aux_close(L); | 163 | aux_close(L); |
| 187 | return 0; | 164 | return 0; |
| 188 | } | 165 | } |
| @@ -205,14 +182,14 @@ static int io_open (lua_State *L) { · 16 unmodified lines | |||
| 205 | int i = 0; | 182 | int i = 0; |
| 206 | /* check whether 'mode' matches '[rwa]%+?b?' */ | 183 | /* check whether 'mode' matches '[rwa]%+?b?' */ |
| 207 | if (!(mode[i] != '\0' && strchr("rwa", mode[i++]) != NULL && | 184 | if (!(mode[i] != '\0' && strchr("rwa", mode[i++]) != NULL && |
| 208 | (mode[i] != '+' || ++i) && /* skip if char is '+' */ | 185 | (mode[i] != '+' || ++i) && /* skip if char is '+' */ |
| 209 | (mode[i] != 'b' || ++i) && /* skip if char is 'b' */ | 186 | (mode[i] != 'b' || ++i) && /* skip if char is 'b' */ |
| 210 | (mode[i] == '\0'))) | 187 | (mode[i] == '\0'))) |
| 211 | luaL_error(L, "invalid mode " LUA_QL("%s") | 188 | luaL_error(L, "invalid mode " LUA_QL("%s") |
| 212 | " (should match " LUA_QL("[rwa]%%+?b?") ")", mode); | 189 | " (should match " LUA_QL("[rwa]%%+?b?") ")", mode); |
| 213 | pf = newfile(L); | 190 | pf = newfile(L); |
| 214 | *pf = fopen(filename, mode); | 191 | *pf = fopen(filename, mode); |
| 215 | return (*pf == NULL) ? pushresult(L, 0, filename) : 1; | 192 | return (*pf == NULL) ? luaL_fileresult(L, 0, filename) : 1; |
| 216 | } | 193 | } |
| 217 | 194 | ||
| 218 | 195 | ||
| @@ -225,14 +202,14 @@ static int io_popen (lua_State *L) { · 6 unmodified lines | |||
| 225 | const char *mode = luaL_optstring(L, 2, "r"); | 202 | const char *mode = luaL_optstring(L, 2, "r"); |
| 226 | FILE **pf = newfile(L); | 203 | FILE **pf = newfile(L); |
| 227 | *pf = lua_popen(L, filename, mode); | 204 | *pf = lua_popen(L, filename, mode); |
| 228 | return (*pf == NULL) ? pushresult(L, 0, filename) : 1; | 205 | return (*pf == NULL) ? luaL_fileresult(L, 0, filename) : 1; |
| 229 | } | 206 | } |
| 230 | 207 | ||
| 231 | 208 | ||
| 232 | static int io_tmpfile (lua_State *L) { | 209 | static int io_tmpfile (lua_State *L) { |
| 233 | FILE **pf = newfile(L); | 210 | FILE **pf = newfile(L); |
| 234 | *pf = tmpfile(); | 211 | *pf = tmpfile(); |
| 235 | return (*pf == NULL) ? pushresult(L, 0, NULL) : 1; | 212 | return (*pf == NULL) ? luaL_fileresult(L, 0, NULL) : 1; |
| 236 | } | 213 | } |
| 237 | 214 | ||
| 238 | 215 | ||
| @@ -305,7 +282,7 @@ static int io_lines (lua_State *L) { · 66 unmodified lines | |||
| 305 | if (lua_isnone(L, 1)) lua_pushnil(L); /* at least one argument */ | 282 | if (lua_isnone(L, 1)) lua_pushnil(L); /* at least one argument */ |
| 306 | if (lua_isnil(L, 1)) { /* no file name? */ | 283 | if (lua_isnil(L, 1)) { /* no file name? */ |
| 307 | lua_rawgeti(L, lua_upvalueindex(1), IO_INPUT); /* get default input */ | 284 | lua_rawgeti(L, lua_upvalueindex(1), IO_INPUT); /* get default input */ |
| 308 | lua_replace(L, 1); /* put it at index 1 */ | 285 | lua_replace(L, 1); /* put it at index 1 */ |
| 309 | tofile(L); /* check that it's a valid file handle */ | 286 | tofile(L); /* check that it's a valid file handle */ |
| 310 | toclose = 0; /* do not close it after iteration */ | 287 | toclose = 0; /* do not close it after iteration */ |
| 311 | } | 288 | } |
| @@ -315,7 +292,7 @@ static int io_lines (lua_State *L) { · 3 unmodified lines | |||
| 315 | *pf = fopen(filename, "r"); | 292 | *pf = fopen(filename, "r"); |
| 316 | if (*pf == NULL) | 293 | if (*pf == NULL) |
| 317 | fileerror(L, 1, filename); | 294 | fileerror(L, 1, filename); |
| 318 | lua_replace(L, 1); /* put file at index 1 */ | 295 | lua_replace(L, 1); /* put file at index 1 */ |
| 319 | toclose = 1; /* close it after iteration */ | 296 | toclose = 1; /* close it after iteration */ |
| 320 | } | 297 | } |
| 321 | aux_lines(L, toclose); | 298 | aux_lines(L, toclose); |
| @@ -443,7 +420,7 @@ static int g_read (lua_State *L, FILE *f, int first) { · 121 unmodified lines | |||
| 443 | } | 420 | } |
| 444 | } | 421 | } |
| 445 | if (ferror(f)) | 422 | if (ferror(f)) |
| 446 | return pushresult(L, 0, NULL); | 423 | return luaL_fileresult(L, 0, NULL); |
| 447 | if (!success) { | 424 | if (!success) { |
| 448 | lua_pop(L, 1); /* remove last result */ | 425 | lua_pop(L, 1); /* remove last result */ |
| 449 | lua_pushnil(L); /* push nil instead */ | 426 | lua_pushnil(L); /* push nil instead */ |
| @@ -507,7 +484,7 @@ static int g_write (lua_State *L, FILE *f, int arg) { · 57 unmodified lines | |||
| 507 | } | 484 | } |
| 508 | } | 485 | } |
| 509 | if (status) return 1; /* file handle already on stack top */ | 486 | if (status) return 1; /* file handle already on stack top */ |
| 510 | else return pushresult(L, status, NULL); | 487 | else return luaL_fileresult(L, status, NULL); |
| 511 | } | 488 | } |
| 512 | 489 | ||
| 513 | 490 | ||
| @@ -517,7 +494,7 @@ static int io_write (lua_State *L) { · 3 unmodified lines | |||
| 517 | 494 | ||
| 518 | 495 | ||
| 519 | static int f_write (lua_State *L) { | 496 | static int f_write (lua_State *L) { |
| 520 | FILE * f = tofile(L); | 497 | FILE * f = tofile(L); |
| 521 | lua_pushvalue(L, 1); /* push file at the stack top (to be returned) */ | 498 | lua_pushvalue(L, 1); /* push file at the stack top (to be returned) */ |
| 522 | return g_write(L, f, 2); | 499 | return g_write(L, f, 2); |
| 523 | } | 500 | } |
| @@ -531,7 +508,7 @@ static int f_seek (lua_State *L) { · 7 unmodified lines | |||
| 531 | long offset = luaL_optlong(L, 3, 0); | 508 | long offset = luaL_optlong(L, 3, 0); |
| 532 | op = fseek(f, offset, mode[op]); | 509 | op = fseek(f, offset, mode[op]); |
| 533 | if (op) | 510 | if (op) |
| 534 | return pushresult(L, 0, NULL); /* error */ | 511 | return luaL_fileresult(L, 0, NULL); /* error */ |
| 535 | else { | 512 | else { |
| 536 | lua_pushinteger(L, ftell(f)); | 513 | lua_pushinteger(L, ftell(f)); |
| 537 | return 1; | 514 | return 1; |
| @@ -546,18 +523,18 @@ static int f_setvbuf (lua_State *L) { · 8 unmodified lines | |||
| 546 | int op = luaL_checkoption(L, 2, NULL, modenames); | 523 | int op = luaL_checkoption(L, 2, NULL, modenames); |
| 547 | lua_Integer sz = luaL_optinteger(L, 3, LUAL_BUFFERSIZE); | 524 | lua_Integer sz = luaL_optinteger(L, 3, LUAL_BUFFERSIZE); |
| 548 | int res = setvbuf(f, NULL, mode[op], sz); | 525 | int res = setvbuf(f, NULL, mode[op], sz); |
| 549 | return pushresult(L, res == 0, NULL); | 526 | return luaL_fileresult(L, res == 0, NULL); |
| 550 | } | 527 | } |
| 551 | 528 | ||
| 552 | 529 | ||
| 553 | 530 | ||
| 554 | static int io_flush (lua_State *L) { | 531 | static int io_flush (lua_State *L) { |
| 555 | return pushresult(L, fflush(getiofile(L, IO_OUTPUT)) == 0, NULL); | 532 | return luaL_fileresult(L, fflush(getiofile(L, IO_OUTPUT)) == 0, NULL); |
| 556 | } | 533 | } |
| 557 | 534 | ||
| 558 | 535 | ||
| 559 | static int f_flush (lua_State *L) { | 536 | static int f_flush (lua_State *L) { |
| 560 | return pushresult(L, fflush(tofile(L)) == 0, NULL); | 537 | return luaL_fileresult(L, fflush(tofile(L)) == 0, NULL); |
| 561 | } | 538 | } |
| 562 | 539 | ||
| 563 | 540 | ||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: llex.c,v 2.41 2010/11/18 18:38:44 roberto Exp $ | 2 | ** $Id: llex.c,v 2.47 2011/05/03 15:51:16 roberto Exp $ |
| 3 | ** Lexical Analyzer | 3 | ** Lexical Analyzer |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -35,7 +35,7 @@ · 29 unmodified lines | |||
| 35 | /* ORDER RESERVED */ | 35 | /* ORDER RESERVED */ |
| 36 | static const char *const luaX_tokens [] = { | 36 | static const char *const luaX_tokens [] = { |
| 37 | "and", "break", "do", "else", "elseif", | 37 | "and", "break", "do", "else", "elseif", |
| 38 | "end", "false", "for", "function", "if", | 38 | "end", "false", "for", "function", "goto", "if", |
| 39 | "in", "local", "nil", "not", "or", "repeat", | 39 | "in", "local", "nil", "not", "or", "repeat", |
| 40 | "return", "then", "true", "until", "while", | 40 | "return", "then", "true", "until", "while", |
| 41 | "..", "...", "==", ">=", "<=", "~=", "<eof>", | 41 | "..", "...", "==", ">=", "<=", "~=", "<eof>", |
| @@ -67,7 +67,6 @@ void luaX_init (lua_State *L) { · 25 unmodified lines | |||
| 67 | for (i=0; i<NUM_RESERVED; i++) { | 67 | for (i=0; i<NUM_RESERVED; i++) { |
| 68 | TString *ts = luaS_new(L, luaX_tokens[i]); | 68 | TString *ts = luaS_new(L, luaX_tokens[i]); |
| 69 | luaS_fix(ts); /* reserved words are never collected */ | 69 | luaS_fix(ts); /* reserved words are never collected */ |
| 70 | lua_assert(strlen(luaX_tokens[i])+1 <= TOKEN_LEN); | ||
| 71 | ts->tsv.reserved = cast_byte(i+1); /* reserved word */ | 70 | ts->tsv.reserved = cast_byte(i+1); /* reserved word */ |
| 72 | } | 71 | } |
| 73 | } | 72 | } |
| @@ -127,7 +126,7 @@ TString *luaX_newstring (LexState *ls, const char *str, size_t l) { · 53 unmodified lines | |||
| 127 | TValue *o; /* entry for `str' */ | 126 | TValue *o; /* entry for `str' */ |
| 128 | TString *ts = luaS_newlstr(L, str, l); /* create new string */ | 127 | TString *ts = luaS_newlstr(L, str, l); /* create new string */ |
| 129 | setsvalue2s(L, L->top++, ts); /* temporarily anchor it in stack */ | 128 | setsvalue2s(L, L->top++, ts); /* temporarily anchor it in stack */ |
| 130 | o = luaH_setstr(L, ls->fs->h, ts); | 129 | o = luaH_setstr(L, ls->fs->h, ts); |
| 131 | if (ttisnil(o)) { | 130 | if (ttisnil(o)) { |
| 132 | setbvalue(o, 1); /* t[string] = true */ | 131 | setbvalue(o, 1); /* t[string] = true */ |
| 133 | luaC_checkGC(L); | 132 | luaC_checkGC(L); |
| @@ -152,9 +151,11 @@ static void inclinenumber (LexState *ls) { · 18 unmodified lines | |||
| 152 | } | 151 | } |
| 153 | 152 | ||
| 154 | 153 | ||
| 155 | void luaX_setinput (lua_State *L, LexState *ls, ZIO *z, TString *source) { | 154 | void luaX_setinput (lua_State *L, LexState *ls, ZIO *z, TString *source, |
| 155 | int firstchar) { | ||
| 156 | ls->decpoint = '.'; | 156 | ls->decpoint = '.'; |
| 157 | ls->L = L; | 157 | ls->L = L; |
| 158 | ls->current = firstchar; | ||
| 158 | ls->lookahead.token = TK_EOS; /* no look-ahead token */ | 159 | ls->lookahead.token = TK_EOS; /* no look-ahead token */ |
| 159 | ls->z = z; | 160 | ls->z = z; |
| 160 | ls->fs = NULL; | 161 | ls->fs = NULL; |
| @@ -164,7 +165,6 @@ void luaX_setinput (lua_State *L, LexState *ls, ZIO *z, TString *source) { · 3 unmodified lines | |||
| 164 | ls->envn = luaS_new(L, LUA_ENV); /* create env name */ | 165 | ls->envn = luaS_new(L, LUA_ENV); /* create env name */ |
| 165 | luaS_fix(ls->envn); /* never collect this name */ | 166 | luaS_fix(ls->envn); /* never collect this name */ |
| 166 | luaZ_resizebuffer(ls->L, ls->buff, LUA_MINBUFFER); /* initialize buffer */ | 167 | luaZ_resizebuffer(ls->L, ls->buff, LUA_MINBUFFER); /* initialize buffer */ |
| 167 | next(ls); /* read first char */ | ||
| 168 | } | 168 | } |
| 169 | 169 | ||
| 170 | 170 | ||
| @@ -185,7 +185,7 @@ static int check_next (LexState *ls, const char *set) { · 14 unmodified lines | |||
| 185 | } | 185 | } |
| 186 | 186 | ||
| 187 | 187 | ||
| 188 | /* | 188 | /* |
| 189 | ** change all characters 'from' in buffer to 'to' | 189 | ** change all characters 'from' in buffer to 'to' |
| 190 | */ | 190 | */ |
| 191 | static void buffreplace (LexState *ls, char from, char to) { | 191 | static void buffreplace (LexState *ls, char from, char to) { |
| @@ -200,6 +200,9 @@ static void buffreplace (LexState *ls, char from, char to) { · 8 unmodified lines | |||
| 200 | #define getlocaledecpoint() (localeconv()->decimal_point[0]) | 200 | #define getlocaledecpoint() (localeconv()->decimal_point[0]) |
| 201 | #endif | 201 | #endif |
| 202 | 202 | ||
| 203 | |||
| 204 | #define buff2d(b,e) luaO_str2d(luaZ_buffer(b), luaZ_bufflen(b) - 1, e) | ||
| 205 | |||
| 203 | /* | 206 | /* |
| 204 | ** in case of format error, try to change decimal point separator to | 207 | ** in case of format error, try to change decimal point separator to |
| 205 | ** the one defined in the current locale and check again | 208 | ** the one defined in the current locale and check again |
| @@ -208,7 +211,7 @@ static void trydecpoint (LexState *ls, SemInfo *seminfo) { · 2 unmodified lines | |||
| 208 | char old = ls->decpoint; | 211 | char old = ls->decpoint; |
| 209 | ls->decpoint = getlocaledecpoint(); | 212 | ls->decpoint = getlocaledecpoint(); |
| 210 | buffreplace(ls, old, ls->decpoint); /* try new decimal separator */ | 213 | buffreplace(ls, old, ls->decpoint); /* try new decimal separator */ |
| 211 | if (!luaO_str2d(luaZ_buffer(ls->buff), &seminfo->r)) { | 214 | if (!buff2d(ls->buff, &seminfo->r)) { |
| 212 | /* format error with correct decimal point: no more options */ | 215 | /* format error with correct decimal point: no more options */ |
| 213 | buffreplace(ls, ls->decpoint, '.'); /* undo change (for error message) */ | 216 | buffreplace(ls, ls->decpoint, '.'); /* undo change (for error message) */ |
| 214 | lexerror(ls, "malformed number", TK_NUMBER); | 217 | lexerror(ls, "malformed number", TK_NUMBER); |
| @@ -226,7 +229,7 @@ static void read_numeral (LexState *ls, SemInfo *seminfo) { · 11 unmodified lines | |||
| 226 | } while (lislalnum(ls->current) || ls->current == '.'); | 229 | } while (lislalnum(ls->current) || ls->current == '.'); |
| 227 | save(ls, '\0'); | 230 | save(ls, '\0'); |
| 228 | buffreplace(ls, '.', ls->decpoint); /* follow locale for decimal point */ | 231 | buffreplace(ls, '.', ls->decpoint); /* follow locale for decimal point */ |
| 229 | if (!luaO_str2d(luaZ_buffer(ls->buff), &seminfo->r)) /* format error? */ | 232 | if (!buff2d(ls->buff, &seminfo->r)) /* format error? */ |
| 230 | trydecpoint(ls, seminfo); /* try to update decimal point separator */ | 233 | trydecpoint(ls, seminfo); /* try to update decimal point separator */ |
| 231 | } | 234 | } |
| 232 | 235 | ||
| @@ -283,13 +286,6 @@ static void read_long_string (LexState *ls, SemInfo *seminfo, int sep) { · 50 unmodified lines | |||
| 283 | } | 286 | } |
| 284 | 287 | ||
| 285 | 288 | ||
| 286 | static int hexavalue (int c) { | ||
| 287 | if (lisdigit(c)) return c - '0'; | ||
| 288 | else if (lisupper(c)) return c - 'A' + 10; | ||
| 289 | else return c - 'a' + 10; | ||
| 290 | } | ||
| 291 | |||
| 292 | |||
| 293 | static int readhexaesc (LexState *ls) { | 289 | static int readhexaesc (LexState *ls) { |
| 294 | int c1, c2 = EOZ; | 290 | int c1, c2 = EOZ; |
| 295 | if (!lisxdigit(c1 = next(ls)) || !lisxdigit(c2 = next(ls))) { | 291 | if (!lisxdigit(c1 = next(ls)) || !lisxdigit(c2 = next(ls))) { |
| @@ -299,7 +295,7 @@ static int readhexaesc (LexState *ls) { · 3 unmodified lines | |||
| 299 | if (c2 != EOZ) save(ls, c2); | 295 | if (c2 != EOZ) save(ls, c2); |
| 300 | lexerror(ls, "hexadecimal digit expected", TK_STRING); | 296 | lexerror(ls, "hexadecimal digit expected", TK_STRING); |
| 301 | } | 297 | } |
| 302 | return (hexavalue(c1) << 4) + hexavalue(c2); | 298 | return (luaO_hexavalue(c1) << 4) + luaO_hexavalue(c2); |
| 303 | } | 299 | } |
| 304 | 300 | ||
| 305 | 301 | ||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: llex.h,v 1.65 2010/04/05 16:35:37 roberto Exp $ | 2 | ** $Id: llex.h,v 1.70 2011/05/03 15:51:16 roberto Exp $ |
| 3 | ** Lexical Analyzer | 3 | ** Lexical Analyzer |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -13,8 +13,6 @@ · 7 unmodified lines | |||
| 13 | 13 | ||
| 14 | #define FIRST_RESERVED 257 | 14 | #define FIRST_RESERVED 257 |
| 15 | 15 | ||
| 16 | /* maximum length of a reserved word */ | ||
| 17 | #define TOKEN_LEN (sizeof("function")/sizeof(char)) | ||
| 18 | 16 | ||
| 19 | 17 | ||
| 20 | /* | 18 | /* |
| @@ -25,7 +23,7 @@ enum RESERVED { · 4 unmodified lines | |||
| 25 | /* terminal symbols denoted by reserved words */ | 23 | /* terminal symbols denoted by reserved words */ |
| 26 | TK_AND = FIRST_RESERVED, TK_BREAK, | 24 | TK_AND = FIRST_RESERVED, TK_BREAK, |
| 27 | TK_DO, TK_ELSE, TK_ELSEIF, TK_END, TK_FALSE, TK_FOR, TK_FUNCTION, | 25 | TK_DO, TK_ELSE, TK_ELSEIF, TK_END, TK_FALSE, TK_FOR, TK_FUNCTION, |
| 28 | TK_IF, TK_IN, TK_LOCAL, TK_NIL, TK_NOT, TK_OR, TK_REPEAT, | 26 | TK_GOTO, TK_IF, TK_IN, TK_LOCAL, TK_NIL, TK_NOT, TK_OR, TK_REPEAT, |
| 29 | TK_RETURN, TK_THEN, TK_TRUE, TK_UNTIL, TK_WHILE, | 27 | TK_RETURN, TK_THEN, TK_TRUE, TK_UNTIL, TK_WHILE, |
| 30 | /* other terminal symbols */ | 28 | /* other terminal symbols */ |
| 31 | TK_CONCAT, TK_DOTS, TK_EQ, TK_GE, TK_LE, TK_NE, TK_EOS, | 29 | TK_CONCAT, TK_DOTS, TK_EQ, TK_GE, TK_LE, TK_NE, TK_EOS, |
| @@ -48,17 +46,19 @@ typedef struct Token { · 16 unmodified lines | |||
| 48 | } Token; | 46 | } Token; |
| 49 | 47 | ||
| 50 | 48 | ||
| 49 | /* state of the lexer plus state of the parser when shared by all | ||
| 50 | functions */ | ||
| 51 | typedef struct LexState { | 51 | typedef struct LexState { |
| 52 | int current; /* current character (charint) */ | 52 | int current; /* current character (charint) */ |
| 53 | int linenumber; /* input line counter */ | 53 | int linenumber; /* input line counter */ |
| 54 | int lastline; /* line of last token `consumed' */ | 54 | int lastline; /* line of last token `consumed' */ |
| 55 | Token t; /* current token */ | 55 | Token t; /* current token */ |
| 56 | Token lookahead; /* look ahead token */ | 56 | Token lookahead; /* look ahead token */ |
| 57 | struct FuncState *fs; /* `FuncState' is private to the parser */ | 57 | struct FuncState *fs; /* current function (parser) */ |
| 58 | struct lua_State *L; | 58 | struct lua_State *L; |
| 59 | ZIO *z; /* input stream */ | 59 | ZIO *z; /* input stream */ |
| 60 | Mbuffer *buff; /* buffer for tokens */ | 60 | Mbuffer *buff; /* buffer for tokens */ |
| 61 | struct Varlist *varl; /* list of all active local variables */ | 61 | struct Dyndata *dyd; /* dynamic structures used by the parser */ |
| 62 | TString *source; /* current source name */ | 62 | TString *source; /* current source name */ |
| 63 | TString *envn; /* environment variable name */ | 63 | TString *envn; /* environment variable name */ |
| 64 | char decpoint; /* locale decimal point */ | 64 | char decpoint; /* locale decimal point */ |
| @@ -67,7 +67,7 @@ typedef struct LexState { · 2 unmodified lines | |||
| 67 | 67 | ||
| 68 | LUAI_FUNC void luaX_init (lua_State *L); | 68 | LUAI_FUNC void luaX_init (lua_State *L); |
| 69 | LUAI_FUNC void luaX_setinput (lua_State *L, LexState *ls, ZIO *z, | 69 | LUAI_FUNC void luaX_setinput (lua_State *L, LexState *ls, ZIO *z, |
| 70 | TString *source); | 70 | TString *source, int firstchar); |
| 71 | LUAI_FUNC TString *luaX_newstring (LexState *ls, const char *str, size_t l); | 71 | LUAI_FUNC TString *luaX_newstring (LexState *ls, const char *str, size_t l); |
| 72 | LUAI_FUNC void luaX_next (LexState *ls); | 72 | LUAI_FUNC void luaX_next (LexState *ls); |
| 73 | LUAI_FUNC int luaX_lookahead (LexState *ls); | 73 | LUAI_FUNC int luaX_lookahead (LexState *ls); |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: llimits.h,v 1.84 2010/11/08 16:33:20 roberto Exp $ | 2 | ** $Id: llimits.h,v 1.89 2011/05/05 19:43:14 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 | */ |
| @@ -59,9 +59,12 @@ typedef LUAI_UACNUMBER l_uacNumber; · 53 unmodified lines | |||
| 59 | /* internal assertions for in-house debugging */ | 59 | /* internal assertions for in-house debugging */ |
| 60 | #if defined(lua_assert) | 60 | #if defined(lua_assert) |
| 61 | #define check_exp(c,e) (lua_assert(c), (e)) | 61 | #define check_exp(c,e) (lua_assert(c), (e)) |
| 62 | /* to avoid problems with conditions too long */ | ||
| 63 | #define lua_longassert(c) { if (!(c)) lua_assert(0); } | ||
| 62 | #else | 64 | #else |
| 63 | #define lua_assert(c) /* empty */ | 65 | #define lua_assert(c) /* empty */ |
| 64 | #define check_exp(c,e) (e) | 66 | #define check_exp(c,e) (e) |
| 67 | #define lua_longassert(c) /* empty */ | ||
| 65 | #endif | 68 | #endif |
| 66 | 69 | ||
| 67 | /* | 70 | /* |
| @@ -87,6 +90,7 @@ typedef LUAI_UACNUMBER l_uacNumber; · 19 unmodified lines | |||
| 87 | #define cast_byte(i) cast(lu_byte, (i)) | 90 | #define cast_byte(i) cast(lu_byte, (i)) |
| 88 | #define cast_num(i) cast(lua_Number, (i)) | 91 | #define cast_num(i) cast(lua_Number, (i)) |
| 89 | #define cast_int(i) cast(int, (i)) | 92 | #define cast_int(i) cast(int, (i)) |
| 93 | #define cast_uchar(i) cast(unsigned char, (i)) | ||
| 90 | 94 | ||
| 91 | 95 | ||
| 92 | /* | 96 | /* |
| @@ -173,6 +177,9 @@ typedef lu_int32 Instruction; · 80 unmodified lines | |||
| 173 | ** lua_number2integer is a macro to convert lua_Number to lua_Integer. | 177 | ** lua_number2integer is a macro to convert lua_Number to lua_Integer. |
| 174 | ** lua_number2unsigned is a macro to convert a lua_Number to a lua_Unsigned. | 178 | ** lua_number2unsigned is a macro to convert a lua_Number to a lua_Unsigned. |
| 175 | ** lua_unsigned2number is a macro to convert a lua_Unsigned to a lua_Number. | 179 | ** lua_unsigned2number is a macro to convert a lua_Unsigned to a lua_Number. |
| 180 | ** luai_hashnum is a macro to hash a lua_Number value into an integer. | ||
| 181 | ** The hash must be deterministic and give reasonable values for | ||
| 182 | ** both small and large values (outside the range of integers). | ||
| 176 | */ | 183 | */ |
| 177 | 184 | ||
| 178 | #if defined(MS_ASMTRICK) /* { */ | 185 | #if defined(MS_ASMTRICK) /* { */ |
| @@ -203,6 +210,10 @@ union luai_Cast { double l_d; LUA_INT32 l_p[2]; }; · 24 unmodified lines | |||
| 203 | volatile union luai_Cast u; u.l_d = (n) + 6755399441055744.0; \ | 210 | volatile union luai_Cast u; u.l_d = (n) + 6755399441055744.0; \ |
| 204 | (i) = (t)u.l_p[LUA_IEEEENDIAN]; } | 211 | (i) = (t)u.l_p[LUA_IEEEENDIAN]; } |
| 205 | 212 | ||
| 213 | #define luai_hashnum(i,n) \ | ||
| 214 | { volatile union luai_Cast u; u.l_d = (n) + 1.0; /* avoid -0 */ \ | ||
| 215 | (i) = u.l_p[0] + u.l_p[1]; } /* add double bits for his hash */ | ||
| 216 | |||
| 206 | #define lua_number2int(i,n) lua_number2int32(i, n, int) | 217 | #define lua_number2int(i,n) lua_number2int32(i, n, int) |
| 207 | #define lua_number2integer(i,n) lua_number2int32(i, n, lua_Integer) | 218 | #define lua_number2integer(i,n) lua_number2int32(i, n, lua_Integer) |
| 208 | #define lua_number2unsigned(i,n) lua_number2int32(i, n, lua_Unsigned) | 219 | #define lua_number2unsigned(i,n) lua_number2int32(i, n, lua_Unsigned) |
| @@ -241,14 +252,8 @@ union luai_Cast { double l_d; LUA_INT32 l_p[2]; }; · 32 unmodified lines | |||
| 241 | #endif | 252 | #endif |
| 242 | 253 | ||
| 243 | 254 | ||
| 244 | /* | ||
| 245 | ** luai_hashnum is a macro do hash a lua_Number value into an integer. | ||
| 246 | ** The hash must be deterministic and give reasonable values for | ||
| 247 | ** both small and large values (outside the range of integers). | ||
| 248 | ** It is used only in ltable.c. | ||
| 249 | */ | ||
| 250 | 255 | ||
| 251 | #if !defined(luai_hashnum) /* { */ | 256 | #if (defined(ltable_c) || defined(luaall_c)) && !defined(luai_hashnum) |
| 252 | 257 | ||
| 253 | #include <float.h> | 258 | #include <float.h> |
| 254 | #include <math.h> | 259 | #include <math.h> |
| @@ -257,7 +262,7 @@ union luai_Cast { double l_d; LUA_INT32 l_p[2]; }; · 2 unmodified lines | |||
| 257 | n = frexp(n, &e) * (lua_Number)(INT_MAX - DBL_MAX_EXP); \ | 262 | n = frexp(n, &e) * (lua_Number)(INT_MAX - DBL_MAX_EXP); \ |
| 258 | lua_number2int(i, n); i += e; } | 263 | lua_number2int(i, n); i += e; } |
| 259 | 264 | ||
| 260 | #endif /* } */ | 265 | #endif |
| 261 | 266 | ||
| 262 | 267 | ||
| 263 | 268 | ||
| @@ -275,7 +280,7 @@ union luai_Cast { double l_d; LUA_INT32 l_p[2]; }; · 11 unmodified lines | |||
| 275 | #define condchangemem(L) condmovestack(L) | 280 | #define condchangemem(L) condmovestack(L) |
| 276 | #else | 281 | #else |
| 277 | #define condchangemem(L) \ | 282 | #define condchangemem(L) \ |
| 278 | ((void)(gcstopped(G(L)) || (luaC_fullgc(L, 0), 1))) | 283 | ((void)(!(G(L)->gcrunning) || (luaC_fullgc(L, 0), 1))) |
| 279 | #endif | 284 | #endif |
| 280 | 285 | ||
| 281 | #endif | 286 | #endif |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lmem.c,v 1.79 2010/05/05 18:49:56 roberto Exp $ | 2 | ** $Id: lmem.c,v 1.81 2010/12/20 19:40:07 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,14 +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 && !gcstopped(g)) | 82 | if (nsize > realosize && g->gcrunning) |
| 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 | api_check(L, nsize > realosize, | 87 | api_check(L, nsize > realosize, |
| 88 | "realloc cannot fail when shrinking a block"); | 88 | "realloc cannot fail when shrinking a block"); |
| 89 | if (!gcstopped(g)) { | 89 | if (g->gcrunning) { |
| 90 | luaC_fullgc(L, 1); /* try to free some memory... */ | 90 | luaC_fullgc(L, 1); /* try to free some memory... */ |
| 91 | newblock = (*g->frealloc)(g->ud, block, osize, nsize); /* try again */ | 91 | newblock = (*g->frealloc)(g->ud, block, osize, nsize); /* try again */ |
| 92 | } | 92 | } |
| @@ -94,9 +94,7 @@ void *luaM_realloc_ (lua_State *L, void *block, size_t osize, size_t nsize) { · 1 unmodified line | |||
| 94 | luaD_throw(L, LUA_ERRMEM); | 94 | luaD_throw(L, LUA_ERRMEM); |
| 95 | } | 95 | } |
| 96 | lua_assert((nsize == 0) == (newblock == NULL)); | 96 | lua_assert((nsize == 0) == (newblock == NULL)); |
| 97 | g->totalbytes = (g->totalbytes - realosize) + nsize; | 97 | g->GCdebt = (g->GCdebt + nsize) - realosize; |
| 98 | if (!gcstopped(g)) | ||
| 99 | g->GCdebt += nsize; /* give some credit to garbage collector */ | ||
| 100 | #if defined(TRACEMEM) | 98 | #if defined(TRACEMEM) |
| 101 | { /* auxiliary patch to monitor garbage collection. | 99 | { /* auxiliary patch to monitor garbage collection. |
| 102 | ** To plot, gnuplot with following command: | 100 | ** To plot, gnuplot with following command: |
| @@ -108,9 +106,7 @@ void *luaM_realloc_ (lua_State *L, void *block, size_t osize, size_t nsize) { · 5 unmodified lines | |||
| 108 | if ((total % 200) == 0) { | 106 | if ((total % 200) == 0) { |
| 109 | if (f == NULL) f = fopen(TRACEMEM, "w"); | 107 | if (f == NULL) f = fopen(TRACEMEM, "w"); |
| 110 | fprintf(f, "%lu %u %d %d\n", total, | 108 | fprintf(f, "%lu %u %d %d\n", total, |
| 111 | g->totalbytes, | 109 | g->totalbytes, g->GCdebt, g->gcstate * 1000); |
| 112 | gcstopped(g) ? 0 : g->GCdebt, | ||
| 113 | g->gcstate * 1000); | ||
| 114 | } | 110 | } |
| 115 | } | 111 | } |
| 116 | #endif | 112 | #endif |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: loadlib.c,v 1.94 2010/11/10 20:00:04 roberto Exp $ | 2 | ** $Id: loadlib.c,v 1.98 2011/04/08 19:17:36 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 | ** |
| @@ -164,7 +164,7 @@ static void pusherror (lua_State *L) { · 158 unmodified lines | |||
| 164 | int error = GetLastError(); | 164 | int error = GetLastError(); |
| 165 | char buffer[128]; | 165 | char buffer[128]; |
| 166 | if (FormatMessageA(FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_SYSTEM, | 166 | if (FormatMessageA(FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_SYSTEM, |
| 167 | NULL, error, 0, buffer, sizeof(buffer), NULL)) | 167 | NULL, error, 0, buffer, sizeof(buffer)/sizeof(char), NULL)) |
| 168 | lua_pushstring(L, buffer); | 168 | lua_pushstring(L, buffer); |
| 169 | else | 169 | else |
| 170 | lua_pushfstring(L, "system error %d\n", error); | 170 | lua_pushfstring(L, "system error %d\n", error); |
| @@ -321,8 +321,10 @@ static const char *pushnexttemplate (lua_State *L, const char *path) { · 150 unmodified lines | |||
| 321 | 321 | ||
| 322 | 322 | ||
| 323 | static const char *searchpath (lua_State *L, const char *name, | 323 | static const char *searchpath (lua_State *L, const char *name, |
| 324 | const char *path) { | 324 | const char *path, |
| 325 | name = luaL_gsub(L, name, ".", LUA_DIRSEP); | 325 | const char *sep) { |
| 326 | if (*sep != '\0') /* non-empty separator? */ | ||
| 327 | name = luaL_gsub(L, name, sep, LUA_DIRSEP); /* replace it by proper one */ | ||
| 326 | lua_pushliteral(L, ""); /* error accumulator */ | 328 | lua_pushliteral(L, ""); /* error accumulator */ |
| 327 | while ((path = pushnexttemplate(L, path)) != NULL) { | 329 | while ((path = pushnexttemplate(L, path)) != NULL) { |
| 328 | const char *filename = luaL_gsub(L, lua_tostring(L, -1), | 330 | const char *filename = luaL_gsub(L, lua_tostring(L, -1), |
| @@ -339,7 +341,9 @@ static const char *searchpath (lua_State *L, const char *name, · 10 unmodified lines | |||
| 339 | 341 | ||
| 340 | 342 | ||
| 341 | static int ll_searchpath (lua_State *L) { | 343 | static int ll_searchpath (lua_State *L) { |
| 342 | const char *f = searchpath(L, luaL_checkstring(L, 1), luaL_checkstring(L, 2)); | 344 | const char *f = searchpath(L, luaL_checkstring(L, 1), |
| 345 | luaL_checkstring(L, 2), | ||
| 346 | luaL_optstring(L, 3, ".")); | ||
| 343 | if (f != NULL) return 1; | 347 | if (f != NULL) return 1; |
| 344 | else { /* error message is on top of the stack */ | 348 | else { /* error message is on top of the stack */ |
| 345 | lua_pushnil(L); | 349 | lua_pushnil(L); |
| @@ -356,13 +360,19 @@ static const char *findfile (lua_State *L, const char *name, · 10 unmodified lines | |||
| 356 | path = lua_tostring(L, -1); | 360 | path = lua_tostring(L, -1); |
| 357 | if (path == NULL) | 361 | if (path == NULL) |
| 358 | luaL_error(L, LUA_QL("package.%s") " must be a string", pname); | 362 | luaL_error(L, LUA_QL("package.%s") " must be a string", pname); |
| 359 | return searchpath(L, name, path); | 363 | return searchpath(L, name, path, "."); |
| 360 | } | 364 | } |
| 361 | 365 | ||
| 362 | 366 | ||
| 363 | static void loaderror (lua_State *L, const char *filename) { | 367 | static int checkload (lua_State *L, int stat, const char *filename) { |
| 364 | luaL_error(L, "error loading module " LUA_QS " from file " LUA_QS ":\n\t%s", | 368 | if (stat) { /* module loaded successfully? */ |
| 365 | lua_tostring(L, 1), filename, lua_tostring(L, -1)); | 369 | lua_pushstring(L, filename); /* will be 2nd argument to module */ |
| 370 | return 2; /* return open function and file name */ | ||
| 371 | } | ||
| 372 | else | ||
| 373 | return luaL_error(L, "error loading module " LUA_QS | ||
| 374 | " from file " LUA_QS ":\n\t%s", | ||
| 375 | lua_tostring(L, 1), filename, lua_tostring(L, -1)); | ||
| 366 | } | 376 | } |
| 367 | 377 | ||
| 368 | 378 | ||
| @@ -370,10 +380,8 @@ static int loader_Lua (lua_State *L) { · 1 unmodified line | |||
| 370 | const char *filename; | 380 | const char *filename; |
| 371 | const char *name = luaL_checkstring(L, 1); | 381 | const char *name = luaL_checkstring(L, 1); |
| 372 | filename = findfile(L, name, "path"); | 382 | filename = findfile(L, name, "path"); |
| 373 | if (filename == NULL) return 1; /* library not found in this path */ | 383 | if (filename == NULL) return 1; /* module not found in this path */ |
| 374 | if (luaL_loadfile(L, filename) != LUA_OK) | 384 | return checkload(L, (luaL_loadfile(L, filename) == LUA_OK), filename); |
| 375 | loaderror(L, filename); | ||
| 376 | return 1; /* library loaded successfully */ | ||
| 377 | } | 385 | } |
| 378 | 386 | ||
| 379 | 387 | ||
| @@ -398,10 +406,8 @@ static int loadfunc (lua_State *L, const char *filename, const char *modname) { · 18 unmodified lines | |||
| 398 | static int loader_C (lua_State *L) { | 406 | static int loader_C (lua_State *L) { |
| 399 | const char *name = luaL_checkstring(L, 1); | 407 | const char *name = luaL_checkstring(L, 1); |
| 400 | const char *filename = findfile(L, name, "cpath"); | 408 | const char *filename = findfile(L, name, "cpath"); |
| 401 | if (filename == NULL) return 1; /* library not found in this path */ | 409 | if (filename == NULL) return 1; /* module not found in this path */ |
| 402 | if (loadfunc(L, filename, name) != 0) | 410 | return checkload(L, (loadfunc(L, filename, name) == 0), filename); |
| 403 | loaderror(L, filename); | ||
| 404 | return 1; /* library loaded successfully */ | ||
| 405 | } | 411 | } |
| 406 | 412 | ||
| 407 | 413 | ||
| @@ -415,12 +421,16 @@ static int loader_Croot (lua_State *L) { · 7 unmodified lines | |||
| 415 | filename = findfile(L, lua_tostring(L, -1), "cpath"); | 421 | filename = findfile(L, lua_tostring(L, -1), "cpath"); |
| 416 | if (filename == NULL) return 1; /* root not found */ | 422 | if (filename == NULL) return 1; /* root not found */ |
| 417 | if ((stat = loadfunc(L, filename, name)) != 0) { | 423 | if ((stat = loadfunc(L, filename, name)) != 0) { |
| 418 | if (stat != ERRFUNC) loaderror(L, filename); /* real error */ | 424 | if (stat != ERRFUNC) |
| 419 | lua_pushfstring(L, "\n\tno module " LUA_QS " in file " LUA_QS, | 425 | return checkload(L, 0, filename); /* real error */ |
| 420 | name, filename); | 426 | else { /* open function not found */ |
| 421 | return 1; /* function not found */ | 427 | lua_pushfstring(L, "\n\tno module " LUA_QS " in file " LUA_QS, |
| 428 | name, filename); | ||
| 429 | return 1; | ||
| 430 | } | ||
| 422 | } | 431 | } |
| 423 | return 1; | 432 | lua_pushstring(L, filename); /* will be 2nd argument to module */ |
| 433 | return 2; | ||
| 424 | } | 434 | } |
| 425 | 435 | ||
| 426 | 436 | ||
| @@ -453,16 +463,19 @@ static int ll_require (lua_State *L) { · 26 unmodified lines | |||
| 453 | luaL_error(L, "module " LUA_QS " not found:%s", | 463 | luaL_error(L, "module " LUA_QS " not found:%s", |
| 454 | name, lua_tostring(L, -2)); | 464 | name, lua_tostring(L, -2)); |
| 455 | lua_pushstring(L, name); | 465 | lua_pushstring(L, name); |
| 456 | lua_call(L, 1, 1); /* call it */ | 466 | lua_call(L, 1, 2); /* call it */ |
| 457 | if (lua_isfunction(L, -1)) /* did it find module? */ | 467 | if (lua_isfunction(L, -2)) /* did it find module? */ |
| 458 | break; /* module loaded successfully */ | 468 | break; /* module loaded successfully */ |
| 459 | else if (lua_isstring(L, -1)) /* loader returned error message? */ | 469 | else if (lua_isstring(L, -2)) { /* loader returned error message? */ |
| 460 | lua_concat(L, 2); /* accumulate it */ | 470 | lua_pop(L, 1); /* remove extra return */ |
| 471 | lua_concat(L, 2); /* accumulate error message */ | ||
| 472 | } | ||
| 461 | else | 473 | else |
| 462 | lua_pop(L, 1); | 474 | lua_pop(L, 2); /* remove both returns */ |
| 463 | } | 475 | } |
| 464 | lua_pushstring(L, name); /* pass name as argument to module */ | 476 | lua_pushstring(L, name); /* pass name as argument to module */ |
| 465 | lua_call(L, 1, 1); /* run loaded module */ | 477 | lua_insert(L, -2); /* name is 1st argument (before search data) */ |
| 478 | lua_call(L, 2, 1); /* run loaded module */ | ||
| 466 | if (!lua_isnil(L, -1)) /* non-nil return? */ | 479 | if (!lua_isnil(L, -1)) /* non-nil return? */ |
| 467 | lua_setfield(L, 2, name); /* _LOADED[name] = returned value */ | 480 | lua_setfield(L, 2, name); /* _LOADED[name] = returned value */ |
| 468 | lua_getfield(L, 2, name); | 481 | lua_getfield(L, 2, name); |
| @@ -639,10 +652,10 @@ LUAMOD_API int luaopen_package (lua_State *L) { · 170 unmodified lines | |||
| 639 | LUA_EXEC_DIR "\n" LUA_IGMARK "\n"); | 652 | LUA_EXEC_DIR "\n" LUA_IGMARK "\n"); |
| 640 | lua_setfield(L, -2, "config"); | 653 | lua_setfield(L, -2, "config"); |
| 641 | /* set field `loaded' */ | 654 | /* set field `loaded' */ |
| 642 | luaL_findtable(L, LUA_REGISTRYINDEX, "_LOADED"); | 655 | luaL_getsubtable(L, LUA_REGISTRYINDEX, "_LOADED"); |
| 643 | lua_setfield(L, -2, "loaded"); | 656 | lua_setfield(L, -2, "loaded"); |
| 644 | /* set field `preload' */ | 657 | /* set field `preload' */ |
| 645 | luaL_findtable(L, LUA_REGISTRYINDEX, "_PRELOAD"); | 658 | luaL_getsubtable(L, LUA_REGISTRYINDEX, "_PRELOAD"); |
| 646 | lua_setfield(L, -2, "preload"); | 659 | lua_setfield(L, -2, "preload"); |
| 647 | lua_pushglobaltable(L); | 660 | lua_pushglobaltable(L); |
| 648 | lua_pushvalue(L, -2); /* set 'package' as upvalue for next lib */ | 661 | lua_pushvalue(L, -2); /* set 'package' as upvalue for next lib */ |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lobject.c,v 2.43 2010/10/29 15:54:55 roberto Exp $ | 2 | ** $Id: lobject.c,v 2.49 2011/05/31 18:24:36 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 | */ |
| @@ -70,28 +70,6 @@ int luaO_ceillog2 (unsigned int x) { · 64 unmodified lines | |||
| 70 | } | 70 | } |
| 71 | 71 | ||
| 72 | 72 | ||
| 73 | int luaO_rawequalObj (const TValue *t1, const TValue *t2) { | ||
| 74 | if (ttype(t1) != ttype(t2)) return 0; | ||
| 75 | else switch (ttype(t1)) { | ||
| 76 | case LUA_TNIL: | ||
| 77 | return 1; | ||
| 78 | case LUA_TNUMBER: | ||
| 79 | return luai_numeq(nvalue(t1), nvalue(t2)); | ||
| 80 | case LUA_TBOOLEAN: | ||
| 81 | return bvalue(t1) == bvalue(t2); /* boolean true must be 1 !! */ | ||
| 82 | case LUA_TLIGHTUSERDATA: | ||
| 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); | ||
| 88 | default: | ||
| 89 | lua_assert(iscollectable(t1)); | ||
| 90 | return gcvalue(t1) == gcvalue(t2); | ||
| 91 | } | ||
| 92 | } | ||
| 93 | |||
| 94 | |||
| 95 | lua_Number luaO_arith (int op, lua_Number v1, lua_Number v2) { | 73 | lua_Number luaO_arith (int op, lua_Number v1, lua_Number v2) { |
| 96 | switch (op) { | 74 | switch (op) { |
| 97 | case LUA_OPADD: return luai_numadd(NULL, v1, v2); | 75 | case LUA_OPADD: return luai_numadd(NULL, v1, v2); |
| @@ -106,19 +84,87 @@ lua_Number luaO_arith (int op, lua_Number v1, lua_Number v2) { · 8 unmodified lines | |||
| 106 | } | 84 | } |
| 107 | 85 | ||
| 108 | 86 | ||
| 109 | static int checkend (const char *s, const char *endptr) { | 87 | int luaO_hexavalue (int c) { |
| 110 | if (endptr == s) return 0; /* no characters converted */ | 88 | if (lisdigit(c)) return c - '0'; |
| 111 | while (lisspace(cast(unsigned char, *endptr))) endptr++; | 89 | else if (lisupper(c)) return c - 'A' + 10; |
| 112 | return (*endptr == '\0'); /* OK if no trailing characters */ | 90 | else return c - 'a' + 10; |
| 91 | } | ||
| 92 | |||
| 93 | |||
| 94 | #if !defined(lua_strx2number) | ||
| 95 | |||
| 96 | #include <math.h> | ||
| 97 | |||
| 98 | |||
| 99 | static int isneg (const char **s) { | ||
| 100 | if (**s == '-') { (*s)++; return 1; } | ||
| 101 | else if (**s == '+') (*s)++; | ||
| 102 | return 0; | ||
| 113 | } | 103 | } |
| 114 | 104 | ||
| 115 | 105 | ||
| 116 | int luaO_str2d (const char *s, lua_Number *result) { | 106 | static lua_Number readhexa (const char **s, lua_Number r, int *count) { |
| 107 | while (lisxdigit(cast_uchar(**s))) { /* read integer part */ | ||
| 108 | r = (r * 16.0) + (double)luaO_hexavalue(*(*s)++); | ||
| 109 | (*count)++; | ||
| 110 | } | ||
| 111 | return r; | ||
| 112 | } | ||
| 113 | |||
| 114 | |||
| 115 | /* | ||
| 116 | ** convert an hexadecimal numeric string to a number, following | ||
| 117 | ** C99 specification for 'strtod' | ||
| 118 | */ | ||
| 119 | static lua_Number lua_strx2number (const char *s, char **endptr) { | ||
| 120 | lua_Number r = 0.0; | ||
| 121 | int e = 0, i = 0; | ||
| 122 | int neg = 0; /* 1 if number is negative */ | ||
| 123 | *endptr = cast(char *, s); /* nothing is valid yet */ | ||
| 124 | while (lisspace(cast_uchar(*s))) s++; /* skip initial spaces */ | ||
| 125 | neg = isneg(&s); /* check signal */ | ||
| 126 | if (!(*s == '0' && (*(s + 1) == 'x' || *(s + 1) == 'X'))) /* check '0x' */ | ||
| 127 | return 0.0; /* invalid format (no '0x') */ | ||
| 128 | s += 2; /* skip '0x' */ | ||
| 129 | r = readhexa(&s, r, &i); /* read integer part */ | ||
| 130 | if (*s == '.') { | ||
| 131 | s++; /* skip dot */ | ||
| 132 | r = readhexa(&s, r, &e); /* read fractional part */ | ||
| 133 | } | ||
| 134 | if (i == 0 && e == 0) | ||
| 135 | return 0.0; /* invalid format (no digit) */ | ||
| 136 | e *= -4; /* each fractional digit divides value by 2^-4 */ | ||
| 137 | *endptr = cast(char *, s); /* valid up to here */ | ||
| 138 | if (*s == 'p' || *s == 'P') { /* exponent part? */ | ||
| 139 | int exp1 = 0; | ||
| 140 | int neg1; | ||
| 141 | s++; /* skip 'p' */ | ||
| 142 | neg1 = isneg(&s); /* signal */ | ||
| 143 | if (!lisdigit(cast_uchar(*s))) | ||
| 144 | goto ret; /* must have at least one digit */ | ||
| 145 | while (lisdigit(cast_uchar(*s))) /* read exponent */ | ||
| 146 | exp1 = exp1 * 10 + *(s++) - '0'; | ||
| 147 | if (neg1) exp1 = -exp1; | ||
| 148 | e += exp1; | ||
| 149 | } | ||
| 150 | *endptr = cast(char *, s); /* valid up to here */ | ||
| 151 | ret: | ||
| 152 | if (neg) r = -r; | ||
| 153 | return ldexp(r, e); | ||
| 154 | } | ||
| 155 | |||
| 156 | #endif | ||
| 157 | |||
| 158 | |||
| 159 | int luaO_str2d (const char *s, size_t len, lua_Number *result) { | ||
| 117 | char *endptr; | 160 | char *endptr; |
| 118 | *result = lua_str2number(s, &endptr); | 161 | if (strpbrk(s, "xX")) /* hexa? */ |
| 119 | if (checkend(s, endptr)) return 1; /* conversion OK? */ | 162 | *result = lua_strx2number(s, &endptr); |
| 120 | *result = cast_num(strtoul(s, &endptr, 0)); /* try hexadecimal */ | 163 | else |
| 121 | return checkend(s, endptr); | 164 | *result = lua_str2number(s, &endptr); |
| 165 | if (endptr == s) return 0; /* nothing recognized */ | ||
| 166 | while (lisspace(cast_uchar(*endptr))) endptr++; | ||
| 167 | return (endptr == s + len); /* OK if no trailing characters */ | ||
| 122 | } | 168 | } |
| 123 | 169 | ||
| 124 | 170 | ||
| @@ -196,19 +242,20 @@ const char *luaO_pushfstring (lua_State *L, const char *fmt, ...) { · 71 unmodified lines | |||
| 196 | } | 242 | } |
| 197 | 243 | ||
| 198 | 244 | ||
| 245 | /* number of chars of a literal string without the ending \0 */ | ||
| 246 | #define LL(x) (sizeof(x)/sizeof(char) - 1) | ||
| 199 | 247 | ||
| 200 | #define LL(x) (sizeof(x) - 1) | ||
| 201 | #define RETS "..." | 248 | #define RETS "..." |
| 202 | #define PRE "[string \"" | 249 | #define PRE "[string \"" |
| 203 | #define POS "\"]" | 250 | #define POS "\"]" |
| 204 | 251 | ||
| 205 | #define addstr(a,b,l) ( memcpy(a,b,l), a += (l) ) | 252 | #define addstr(a,b,l) ( memcpy(a,b,(l) * sizeof(char)), a += (l) ) |
| 206 | 253 | ||
| 207 | void luaO_chunkid (char *out, const char *source, size_t bufflen) { | 254 | void luaO_chunkid (char *out, const char *source, size_t bufflen) { |
| 208 | size_t l = strlen(source); | 255 | size_t l = strlen(source); |
| 209 | if (*source == '=') { /* 'literal' source */ | 256 | if (*source == '=') { /* 'literal' source */ |
| 210 | if (l <= bufflen) /* small enough? */ | 257 | if (l <= bufflen) /* small enough? */ |
| 211 | memcpy(out, source + 1, l); | 258 | memcpy(out, source + 1, l * sizeof(char)); |
| 212 | else { /* truncate it */ | 259 | else { /* truncate it */ |
| 213 | addstr(out, source + 1, bufflen - 1); | 260 | addstr(out, source + 1, bufflen - 1); |
| 214 | *out = '\0'; | 261 | *out = '\0'; |
| @@ -216,11 +263,11 @@ void luaO_chunkid (char *out, const char *source, size_t bufflen) { · 1 unmodified line | |||
| 216 | } | 263 | } |
| 217 | else if (*source == '@') { /* file name */ | 264 | else if (*source == '@') { /* file name */ |
| 218 | if (l <= bufflen) /* small enough? */ | 265 | if (l <= bufflen) /* small enough? */ |
| 219 | memcpy(out, source + 1, l); | 266 | memcpy(out, source + 1, l * sizeof(char)); |
| 220 | else { /* add '...' before rest of name */ | 267 | else { /* add '...' before rest of name */ |
| 221 | addstr(out, RETS, LL(RETS)); | 268 | addstr(out, RETS, LL(RETS)); |
| 222 | bufflen -= LL(RETS); | 269 | bufflen -= LL(RETS); |
| 223 | memcpy(out, source + 1 + l - bufflen, bufflen); | 270 | memcpy(out, source + 1 + l - bufflen, bufflen * sizeof(char)); |
| 224 | } | 271 | } |
| 225 | } | 272 | } |
| 226 | else { /* string; format as [string "source"] */ | 273 | else { /* string; format as [string "source"] */ |
| @@ -236,6 +283,7 @@ void luaO_chunkid (char *out, const char *source, size_t bufflen) { · 9 unmodified lines | |||
| 236 | addstr(out, source, l); | 283 | addstr(out, source, l); |
| 237 | addstr(out, RETS, LL(RETS)); | 284 | addstr(out, RETS, LL(RETS)); |
| 238 | } | 285 | } |
| 239 | memcpy(out, POS, LL(POS) + 1); | 286 | memcpy(out, POS, (LL(POS) + 1) * sizeof(char)); |
| 240 | } | 287 | } |
| 241 | } | 288 | } |
| 289 | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lobject.h,v 2.42 2010/07/26 15:53:23 roberto Exp $ | 2 | ** $Id: lobject.h,v 2.60 2011/06/13 14:13:06 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 | */ |
| @@ -23,12 +23,38 @@ · 17 unmodified lines | |||
| 23 | #define LUA_TUPVAL (LUA_NUMTAGS+1) | 23 | #define LUA_TUPVAL (LUA_NUMTAGS+1) |
| 24 | #define LUA_TDEADKEY (LUA_NUMTAGS+2) | 24 | #define LUA_TDEADKEY (LUA_NUMTAGS+2) |
| 25 | 25 | ||
| 26 | /* | ||
| 27 | ** number of all possible tags (including LUA_TNONE but excluding DEADKEY) | ||
| 28 | */ | ||
| 29 | #define LUA_TOTALTAGS (LUA_TUPVAL+2) | ||
| 30 | |||
| 31 | |||
| 32 | /* | ||
| 33 | ** tags for Tagged Values have the following use of bits: | ||
| 34 | ** bits 0-3: actual tag (a LUA_T* value) | ||
| 35 | ** bits 4-5: variant bits | ||
| 36 | ** bit 6: whether value is collectable | ||
| 37 | */ | ||
| 26 | 38 | ||
| 27 | /* | 39 | /* |
| 28 | ** Variant tag for light C functions (negative to be considered | 40 | ** LUA_TFUNCTION variants: |
| 29 | ** non collectable by 'iscollectable') | 41 | ** 0 - Lua function |
| 42 | ** 1 - light C function | ||
| 43 | ** 2 - regular C function (closure) | ||
| 30 | */ | 44 | */ |
| 31 | #define LUA_TLCF (~0x0F | LUA_TFUNCTION) | 45 | |
| 46 | /* Variant tags for functions */ | ||
| 47 | #define LUA_TLCL (LUA_TFUNCTION | (0 << 4)) /* Lua closure */ | ||
| 48 | #define LUA_TLCF (LUA_TFUNCTION | (1 << 4)) /* light C function */ | ||
| 49 | #define LUA_TCCL (LUA_TFUNCTION | (2 << 4)) /* C closure */ | ||
| 50 | |||
| 51 | |||
| 52 | /* Bit mark for collectable types */ | ||
| 53 | #define BIT_ISCOLLECTABLE (1 << 6) | ||
| 54 | |||
| 55 | /* mark a tag as collectable */ | ||
| 56 | #define ctb(t) ((t) | BIT_ISCOLLECTABLE) | ||
| 57 | |||
| 32 | 58 | ||
| 33 | /* | 59 | /* |
| 34 | ** Union of all collectable objects | 60 | ** Union of all collectable objects |
| @@ -55,13 +81,10 @@ typedef struct GCheader { · 20 unmodified lines | |||
| 55 | /* | 81 | /* |
| 56 | ** Union of all Lua values | 82 | ** Union of all Lua values |
| 57 | */ | 83 | */ |
| 58 | typedef union { | 84 | typedef union Value Value; |
| 59 | GCObject *gc; /* collectable objects */ | 85 | |
| 60 | void *p; /* light userdata */ | 86 | |
| 61 | lua_Number n; /* numbers */ | 87 | #define numfield lua_Number n; /* numbers */ |
| 62 | int b; /* booleans */ | ||
| 63 | lua_CFunction f; /* light C functions */ | ||
| 64 | } Value; | ||
| 65 | 88 | ||
| 66 | 89 | ||
| 67 | 90 | ||
| @@ -72,125 +95,143 @@ typedef union { · 4 unmodified lines | |||
| 72 | 95 | ||
| 73 | #define TValuefields Value value_; int tt_ | 96 | #define TValuefields Value value_; int tt_ |
| 74 | 97 | ||
| 75 | typedef struct lua_TValue { | 98 | typedef struct lua_TValue TValue; |
| 76 | TValuefields; | ||
| 77 | } TValue; | ||
| 78 | 99 | ||
| 79 | 100 | ||
| 80 | /* macro defining a nil value */ | 101 | /* macro defining a nil value */ |
| 81 | #define NILCONSTANT {NULL}, LUA_TNIL | 102 | #define NILCONSTANT {NULL}, LUA_TNIL |
| 82 | 103 | ||
| 83 | 104 | ||
| 84 | /* | 105 | #define val_(o) ((o)->value_) |
| 85 | ** type tag of a TValue | 106 | #define num_(o) (val_(o).n) |
| 86 | */ | ||
| 87 | #define ttype(o) ((o)->tt_) | ||
| 88 | 107 | ||
| 89 | 108 | ||
| 90 | /* | 109 | /* raw type tag of a TValue */ |
| 91 | ** type tag of a TValue with no variants | 110 | #define rttype(o) ((o)->tt_) |
| 92 | */ | 111 | |
| 93 | #define ttypenv(o) (ttype(o) & 0x0F) | 112 | /* type tag of a TValue (bits 0-3 for tags + variant bits 4-5) */ |
| 113 | #define ttype(o) (rttype(o) & 0x3F) | ||
| 114 | |||
| 115 | |||
| 116 | /* type tag of a TValue with no variants (bits 0-3) */ | ||
| 117 | #define ttypenv(o) (rttype(o) & 0x0F) | ||
| 94 | 118 | ||
| 95 | 119 | ||
| 96 | /* Macros to test type */ | 120 | /* Macros to test type */ |
| 97 | #define ttisnil(o) (ttype(o) == LUA_TNIL) | 121 | #define checktag(o,t) (rttype(o) == (t)) |
| 98 | #define ttisnumber(o) (ttype(o) == LUA_TNUMBER) | 122 | #define ttisnumber(o) checktag((o), LUA_TNUMBER) |
| 99 | #define ttisstring(o) (ttype(o) == LUA_TSTRING) | 123 | #define ttisnil(o) checktag((o), LUA_TNIL) |
| 100 | #define ttistable(o) (ttype(o) == LUA_TTABLE) | 124 | #define ttisboolean(o) checktag((o), LUA_TBOOLEAN) |
| 101 | #define ttisfunction(o) (ttypenv(o) == LUA_TFUNCTION) | 125 | #define ttislightuserdata(o) checktag((o), LUA_TLIGHTUSERDATA) |
| 102 | #define ttisclosure(o) (ttype(o) == LUA_TFUNCTION) | 126 | #define ttisstring(o) checktag((o), ctb(LUA_TSTRING)) |
| 103 | #define ttislcf(o) (ttype(o) == LUA_TLCF) | 127 | #define ttistable(o) checktag((o), ctb(LUA_TTABLE)) |
| 104 | #define ttisboolean(o) (ttype(o) == LUA_TBOOLEAN) | 128 | #define ttisfunction(o) (ttypenv(o) == LUA_TFUNCTION) |
| 105 | #define ttisuserdata(o) (ttype(o) == LUA_TUSERDATA) | 129 | #define ttisclosure(o) ((rttype(o) & 0x1F) == LUA_TFUNCTION) |
| 106 | #define ttisthread(o) (ttype(o) == LUA_TTHREAD) | 130 | #define ttisCclosure(o) checktag((o), ctb(LUA_TCCL)) |
| 107 | #define ttislightuserdata(o) (ttype(o) == LUA_TLIGHTUSERDATA) | 131 | #define ttisLclosure(o) checktag((o), ctb(LUA_TLCL)) |
| 108 | #define ttisdeadkey(o) (ttype(o) == LUA_TDEADKEY) | 132 | #define ttislcf(o) checktag((o), LUA_TLCF) |
| 133 | #define ttisuserdata(o) checktag((o), ctb(LUA_TUSERDATA)) | ||
| 134 | #define ttisthread(o) checktag((o), ctb(LUA_TTHREAD)) | ||
| 135 | #define ttisdeadkey(o) checktag((o), ctb(LUA_TDEADKEY)) | ||
| 136 | |||
| 137 | #define ttisequal(o1,o2) (rttype(o1) == rttype(o2)) | ||
| 109 | 138 | ||
| 110 | /* Macros to access values */ | 139 | /* Macros to access values */ |
| 111 | #define gcvalue(o) check_exp(iscollectable(o), (o)->value_.gc) | 140 | #define nvalue(o) check_exp(ttisnumber(o), num_(o)) |
| 112 | #define pvalue(o) check_exp(ttislightuserdata(o), (o)->value_.p) | 141 | #define gcvalue(o) check_exp(iscollectable(o), val_(o).gc) |
| 113 | #define nvalue(o) check_exp(ttisnumber(o), (o)->value_.n) | 142 | #define pvalue(o) check_exp(ttislightuserdata(o), val_(o).p) |
| 114 | #define rawtsvalue(o) check_exp(ttisstring(o), &(o)->value_.gc->ts) | 143 | #define rawtsvalue(o) check_exp(ttisstring(o), &val_(o).gc->ts) |
| 115 | #define tsvalue(o) (&rawtsvalue(o)->tsv) | 144 | #define tsvalue(o) (&rawtsvalue(o)->tsv) |
| 116 | #define rawuvalue(o) check_exp(ttisuserdata(o), &(o)->value_.gc->u) | 145 | #define rawuvalue(o) check_exp(ttisuserdata(o), &val_(o).gc->u) |
| 117 | #define uvalue(o) (&rawuvalue(o)->uv) | 146 | #define uvalue(o) (&rawuvalue(o)->uv) |
| 118 | #define clvalue(o) check_exp(ttisclosure(o), &(o)->value_.gc->cl) | 147 | #define clvalue(o) check_exp(ttisclosure(o), &val_(o).gc->cl) |
| 119 | #define fvalue(o) check_exp(ttislcf(o), (o)->value_.f) | 148 | #define clLvalue(o) check_exp(ttisLclosure(o), &val_(o).gc->cl.l) |
| 120 | #define hvalue(o) check_exp(ttistable(o), &(o)->value_.gc->h) | 149 | #define clCvalue(o) check_exp(ttisCclosure(o), &val_(o).gc->cl.c) |
| 121 | #define bvalue(o) check_exp(ttisboolean(o), (o)->value_.b) | 150 | #define fvalue(o) check_exp(ttislcf(o), val_(o).f) |
| 122 | #define thvalue(o) check_exp(ttisthread(o), &(o)->value_.gc->th) | 151 | #define hvalue(o) check_exp(ttistable(o), &val_(o).gc->h) |
| 152 | #define bvalue(o) check_exp(ttisboolean(o), val_(o).b) | ||
| 153 | #define thvalue(o) check_exp(ttisthread(o), &val_(o).gc->th) | ||
| 123 | 154 | ||
| 124 | #define l_isfalse(o) (ttisnil(o) || (ttisboolean(o) && bvalue(o) == 0)) | 155 | #define l_isfalse(o) (ttisnil(o) || (ttisboolean(o) && bvalue(o) == 0)) |
| 125 | 156 | ||
| 126 | 157 | ||
| 127 | #define iscollectable(o) (ttype(o) >= LUA_TSTRING) | 158 | #define iscollectable(o) (rttype(o) & BIT_ISCOLLECTABLE) |
| 128 | 159 | ||
| 129 | 160 | ||
| 130 | /* Macros for internal tests */ | 161 | /* Macros for internal tests */ |
| 131 | #define righttt(obj) (ttype(obj) == gcvalue(obj)->gch.tt) | 162 | #define righttt(obj) (ttypenv(obj) == gcvalue(obj)->gch.tt) |
| 132 | |||
| 133 | #define checkconsistency(obj) lua_assert(!iscollectable(obj) || righttt(obj)) | ||
| 134 | 163 | ||
| 135 | #define checkliveness(g,obj) \ | 164 | #define checkliveness(g,obj) \ |
| 136 | lua_assert(!iscollectable(obj) || (righttt(obj) && !isdead(g,gcvalue(obj)))) | 165 | lua_longassert(!iscollectable(obj) || \ |
| 166 | (righttt(obj) && !isdead(g,gcvalue(obj)))) | ||
| 137 | 167 | ||
| 138 | 168 | ||
| 139 | /* Macros to set values */ | 169 | /* Macros to set values */ |
| 140 | #define setnilvalue(obj) ((obj)->tt_=LUA_TNIL) | 170 | #define settt_(o,t) ((o)->tt_=(t)) |
| 141 | 171 | ||
| 142 | #define setnvalue(obj,x) \ | 172 | #define setnvalue(obj,x) \ |
| 143 | { TValue *i_o=(obj); i_o->value_.n=(x); i_o->tt_=LUA_TNUMBER; } | 173 | { TValue *io=(obj); num_(io)=(x); settt_(io, LUA_TNUMBER); } |
| 144 | 174 | ||
| 145 | #define setfvalue(obj,x) \ | 175 | #define changenvalue(o,x) check_exp(ttisnumber(o), num_(o)=(x)) |
| 146 | { TValue *i_o=(obj); i_o->value_.f=(x); i_o->tt_=LUA_TLCF; } | ||
| 147 | 176 | ||
| 148 | #define changenvalue(o,x) check_exp((o)->tt_==LUA_TNUMBER, (o)->value_.n=(x)) | 177 | #define setnilvalue(obj) settt_(obj, LUA_TNIL) |
| 178 | |||
| 179 | #define setfvalue(obj,x) \ | ||
| 180 | { TValue *io=(obj); val_(io).f=(x); settt_(io, LUA_TLCF); } | ||
| 149 | 181 | ||
| 150 | #define setpvalue(obj,x) \ | 182 | #define setpvalue(obj,x) \ |
| 151 | { TValue *i_o=(obj); i_o->value_.p=(x); i_o->tt_=LUA_TLIGHTUSERDATA; } | 183 | { TValue *io=(obj); val_(io).p=(x); settt_(io, LUA_TLIGHTUSERDATA); } |
| 152 | 184 | ||
| 153 | #define setbvalue(obj,x) \ | 185 | #define setbvalue(obj,x) \ |
| 154 | { TValue *i_o=(obj); i_o->value_.b=(x); i_o->tt_=LUA_TBOOLEAN; } | 186 | { TValue *io=(obj); val_(io).b=(x); settt_(io, LUA_TBOOLEAN); } |
| 187 | |||
| 188 | #define setgcovalue(L,obj,x) \ | ||
| 189 | { TValue *io=(obj); GCObject *i_g=(x); \ | ||
| 190 | val_(io).gc=i_g; settt_(io, ctb(gch(i_g)->tt)); } | ||
| 155 | 191 | ||
| 156 | #define setsvalue(L,obj,x) \ | 192 | #define setsvalue(L,obj,x) \ |
| 157 | { TValue *i_o=(obj); \ | 193 | { TValue *io=(obj); \ |
| 158 | i_o->value_.gc=cast(GCObject *, (x)); i_o->tt_=LUA_TSTRING; \ | 194 | val_(io).gc=cast(GCObject *, (x)); settt_(io, ctb(LUA_TSTRING)); \ |
| 159 | checkliveness(G(L),i_o); } | 195 | checkliveness(G(L),io); } |
| 160 | 196 | ||
| 161 | #define setuvalue(L,obj,x) \ | 197 | #define setuvalue(L,obj,x) \ |
| 162 | { TValue *i_o=(obj); \ | 198 | { TValue *io=(obj); \ |
| 163 | i_o->value_.gc=cast(GCObject *, (x)); i_o->tt_=LUA_TUSERDATA; \ | 199 | val_(io).gc=cast(GCObject *, (x)); settt_(io, ctb(LUA_TUSERDATA)); \ |
| 164 | checkliveness(G(L),i_o); } | 200 | checkliveness(G(L),io); } |
| 165 | 201 | ||
| 166 | #define setthvalue(L,obj,x) \ | 202 | #define setthvalue(L,obj,x) \ |
| 167 | { TValue *i_o=(obj); \ | 203 | { TValue *io=(obj); \ |
| 168 | i_o->value_.gc=cast(GCObject *, (x)); i_o->tt_=LUA_TTHREAD; \ | 204 | val_(io).gc=cast(GCObject *, (x)); settt_(io, ctb(LUA_TTHREAD)); \ |
| 169 | checkliveness(G(L),i_o); } | 205 | checkliveness(G(L),io); } |
| 206 | |||
| 207 | #define setclLvalue(L,obj,x) \ | ||
| 208 | { TValue *io=(obj); \ | ||
| 209 | val_(io).gc=cast(GCObject *, (x)); settt_(io, ctb(LUA_TLCL)); \ | ||
| 210 | checkliveness(G(L),io); } | ||
| 170 | 211 | ||
| 171 | #define setclvalue(L,obj,x) \ | 212 | #define setclCvalue(L,obj,x) \ |
| 172 | { TValue *i_o=(obj); \ | 213 | { TValue *io=(obj); \ |
| 173 | i_o->value_.gc=cast(GCObject *, (x)); i_o->tt_=LUA_TFUNCTION; \ | 214 | val_(io).gc=cast(GCObject *, (x)); settt_(io, ctb(LUA_TCCL)); \ |
| 174 | checkliveness(G(L),i_o); } | 215 | checkliveness(G(L),io); } |
| 175 | 216 | ||
| 176 | #define sethvalue(L,obj,x) \ | 217 | #define sethvalue(L,obj,x) \ |
| 177 | { TValue *i_o=(obj); \ | 218 | { TValue *io=(obj); \ |
| 178 | i_o->value_.gc=cast(GCObject *, (x)); i_o->tt_=LUA_TTABLE; \ | 219 | val_(io).gc=cast(GCObject *, (x)); settt_(io, ctb(LUA_TTABLE)); \ |
| 179 | checkliveness(G(L),i_o); } | 220 | checkliveness(G(L),io); } |
| 180 | 221 | ||
| 181 | #define setptvalue(L,obj,x) \ | 222 | #define setptvalue(L,obj,x) \ |
| 182 | { TValue *i_o=(obj); \ | 223 | { TValue *io=(obj); \ |
| 183 | i_o->value_.gc=cast(GCObject *, (x)); i_o->tt_=LUA_TPROTO; \ | 224 | val_(io).gc=cast(GCObject *, (x)); settt_(io, ctb(LUA_TPROTO)); \ |
| 184 | checkliveness(G(L),i_o); } | 225 | checkliveness(G(L),io); } |
| 185 | 226 | ||
| 186 | #define setdeadvalue(obj) ((obj)->tt_=LUA_TDEADKEY) | 227 | #define setdeadvalue(obj) settt_(obj, ctb(LUA_TDEADKEY)) |
| 187 | 228 | ||
| 188 | 229 | ||
| 189 | 230 | ||
| 190 | #define setobj(L,obj1,obj2) \ | 231 | #define setobj(L,obj1,obj2) \ |
| 191 | { const TValue *o2=(obj2); TValue *o1=(obj1); \ | 232 | { const TValue *io2=(obj2); TValue *io1=(obj1); \ |
| 192 | o1->value_ = o2->value_; o1->tt_=o2->tt_; \ | 233 | io1->value_ = io2->value_; io1->tt_ = io2->tt_; \ |
| 193 | checkliveness(G(L),o1); } | 234 | checkliveness(G(L),io1); } |
| 194 | 235 | ||
| 195 | 236 | ||
| 196 | /* | 237 | /* |
| @@ -214,9 +255,121 @@ typedef struct lua_TValue { · 17 unmodified lines | |||
| 214 | 255 | ||
| 215 | 256 | ||
| 216 | 257 | ||
| 258 | |||
| 259 | /* | ||
| 260 | ** {====================================================== | ||
| 261 | ** NaN Trick | ||
| 262 | ** ======================================================= | ||
| 263 | */ | ||
| 264 | |||
| 265 | #if defined(LUA_NANTRICKLE) || defined(LUA_NANTRICKBE) | ||
| 266 | |||
| 267 | /* | ||
| 268 | ** numbers are represented in the 'd_' field. All other values have the | ||
| 269 | ** value (NNMARK | tag) in 'tt_'. A number with such pattern would be | ||
| 270 | ** a "signaled NaN", which is never generated by regular operations by | ||
| 271 | ** the CPU (nor by 'strtod') | ||
| 272 | */ | ||
| 273 | #if !defined(NNMARK) | ||
| 274 | #define NNMARK 0x7FF7A500 | ||
| 275 | #endif | ||
| 276 | |||
| 277 | #undef TValuefields | ||
| 278 | #if defined(LUA_NANTRICKLE) | ||
| 279 | /* little endian */ | ||
| 280 | #define TValuefields \ | ||
| 281 | union { struct { Value v_; int tt_; } i; double d_; } u | ||
| 282 | #else | ||
| 283 | /* big endian */ | ||
| 284 | #define TValuefields \ | ||
| 285 | union { struct { int tt_; Value v_; } i; double d_; } u | ||
| 286 | #endif | ||
| 287 | |||
| 288 | #undef numfield | ||
| 289 | #define numfield /* no such field; numbers are the entire struct */ | ||
| 290 | |||
| 291 | /* basic check to distinguish numbers from non-numbers */ | ||
| 292 | #undef ttisnumber | ||
| 293 | #define ttisnumber(o) (((o)->u.i.tt_ & 0x7fffff00) != NNMARK) | ||
| 294 | |||
| 295 | #define tag2tt(t) (NNMARK | (t)) | ||
| 296 | |||
| 297 | #undef NILCONSTANT | ||
| 298 | #define NILCONSTANT {{{NULL}, tag2tt(LUA_TNIL)}} | ||
| 299 | |||
| 300 | #undef val_ | ||
| 301 | #define val_(o) ((o)->u.i.v_) | ||
| 302 | #undef num_ | ||
| 303 | #define num_(o) ((o)->u.d_) | ||
| 304 | |||
| 305 | #undef rttype | ||
| 306 | #define rttype(o) (ttisnumber(o) ? LUA_TNUMBER : (o)->u.i.tt_ & 0xff) | ||
| 307 | |||
| 308 | #undef settt_ | ||
| 309 | #define settt_(o,t) ((o)->u.i.tt_=tag2tt(t)) | ||
| 310 | |||
| 311 | #undef setnvalue | ||
| 312 | #define setnvalue(obj,x) \ | ||
| 313 | { TValue *io_=(obj); num_(io_)=(x); lua_assert(ttisnumber(io_)); } | ||
| 314 | |||
| 315 | #undef setobj | ||
| 316 | #define setobj(L,obj1,obj2) \ | ||
| 317 | { const TValue *o2_=(obj2); TValue *o1_=(obj1); \ | ||
| 318 | o1_->u = o2_->u; \ | ||
| 319 | checkliveness(G(L),o1_); } | ||
| 320 | |||
| 321 | |||
| 322 | /* | ||
| 323 | ** these redefinitions are not mandatory, but these forms are more efficient | ||
| 324 | */ | ||
| 325 | |||
| 326 | #undef checktag | ||
| 327 | #define checktag(o,t) ((o)->u.i.tt_ == tag2tt(t)) | ||
| 328 | |||
| 329 | #undef ttisequal | ||
| 330 | #define ttisequal(o1,o2) \ | ||
| 331 | (ttisnumber(o1) ? ttisnumber(o2) : ((o1)->u.i.tt_ == (o2)->u.i.tt_)) | ||
| 332 | |||
| 333 | |||
| 334 | |||
| 335 | #define luai_checknum(L,o,c) { if (!ttisnumber(o)) c; } | ||
| 336 | |||
| 337 | |||
| 338 | #else | ||
| 339 | |||
| 340 | #define luai_checknum(L,o,c) { /* empty */ } | ||
| 341 | |||
| 342 | #endif | ||
| 343 | /* }====================================================== */ | ||
| 344 | |||
| 345 | |||
| 346 | |||
| 347 | /* | ||
| 348 | ** {====================================================== | ||
| 349 | ** types and prototypes | ||
| 350 | ** ======================================================= | ||
| 351 | */ | ||
| 352 | |||
| 353 | |||
| 354 | union Value { | ||
| 355 | GCObject *gc; /* collectable objects */ | ||
| 356 | void *p; /* light userdata */ | ||
| 357 | int b; /* booleans */ | ||
| 358 | lua_CFunction f; /* light C functions */ | ||
| 359 | numfield /* numbers */ | ||
| 360 | }; | ||
| 361 | |||
| 362 | |||
| 363 | struct lua_TValue { | ||
| 364 | TValuefields; | ||
| 365 | }; | ||
| 366 | |||
| 367 | |||
| 217 | typedef TValue *StkId; /* index to stack elements */ | 368 | typedef TValue *StkId; /* index to stack elements */ |
| 218 | 369 | ||
| 219 | 370 | ||
| 371 | |||
| 372 | |||
| 220 | /* | 373 | /* |
| 221 | ** Header for string value; string bytes follow the end of this structure | 374 | ** Header for string value; string bytes follow the end of this structure |
| 222 | */ | 375 | */ |
| @@ -226,7 +379,7 @@ typedef union TString { · 3 unmodified lines | |||
| 226 | CommonHeader; | 379 | CommonHeader; |
| 227 | lu_byte reserved; | 380 | lu_byte reserved; |
| 228 | unsigned int hash; | 381 | unsigned int hash; |
| 229 | size_t len; | 382 | size_t len; /* number of characters in string */ |
| 230 | } tsv; | 383 | } tsv; |
| 231 | } TString; | 384 | } TString; |
| 232 | 385 | ||
| @@ -247,7 +400,7 @@ typedef union Udata { · 14 unmodified lines | |||
| 247 | CommonHeader; | 400 | CommonHeader; |
| 248 | struct Table *metatable; | 401 | struct Table *metatable; |
| 249 | struct Table *env; | 402 | struct Table *env; |
| 250 | size_t len; | 403 | size_t len; /* number of bytes */ |
| 251 | } uv; | 404 | } uv; |
| 252 | } Udata; | 405 | } Udata; |
| 253 | 406 | ||
| @@ -346,9 +499,9 @@ typedef union Closure { · 92 unmodified lines | |||
| 346 | } Closure; | 499 | } Closure; |
| 347 | 500 | ||
| 348 | 501 | ||
| 349 | #define isLfunction(o) (ttisclosure(o) && !clvalue(o)->c.isC) | 502 | #define isLfunction(o) ttisLclosure(o) |
| 350 | 503 | ||
| 351 | #define getproto(o) (clvalue(o)->l.p) | 504 | #define getproto(o) (clLvalue(o)->p) |
| 352 | 505 | ||
| 353 | 506 | ||
| 354 | /* | 507 | /* |
| @@ -403,12 +556,13 @@ typedef struct Table { · 48 unmodified lines | |||
| 403 | 556 | ||
| 404 | LUAI_DDEC const TValue luaO_nilobject_; | 557 | LUAI_DDEC const TValue luaO_nilobject_; |
| 405 | 558 | ||
| 559 | |||
| 406 | LUAI_FUNC int luaO_int2fb (unsigned int x); | 560 | LUAI_FUNC int luaO_int2fb (unsigned int x); |
| 407 | LUAI_FUNC int luaO_fb2int (int x); | 561 | LUAI_FUNC int luaO_fb2int (int x); |
| 408 | LUAI_FUNC int luaO_ceillog2 (lu_int32 x); | 562 | LUAI_FUNC int luaO_ceillog2 (unsigned int x); |
| 409 | LUAI_FUNC lua_Number luaO_arith (int op, lua_Number v1, lua_Number v2); | 563 | LUAI_FUNC lua_Number luaO_arith (int op, lua_Number v1, lua_Number v2); |
| 410 | LUAI_FUNC int luaO_rawequalObj (const TValue *t1, const TValue *t2); | 564 | LUAI_FUNC int luaO_str2d (const char *s, size_t len, lua_Number *result); |
| 411 | LUAI_FUNC int luaO_str2d (const char *s, lua_Number *result); | 565 | LUAI_FUNC int luaO_hexavalue (int c); |
| 412 | LUAI_FUNC const char *luaO_pushvfstring (lua_State *L, const char *fmt, | 566 | LUAI_FUNC const char *luaO_pushvfstring (lua_State *L, const char *fmt, |
| 413 | va_list argp); | 567 | va_list argp); |
| 414 | LUAI_FUNC const char *luaO_pushfstring (lua_State *L, const char *fmt, ...); | 568 | LUAI_FUNC const char *luaO_pushfstring (lua_State *L, const char *fmt, ...); |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lopcodes.c,v 1.44 2010/10/13 16:45:54 roberto Exp $ | 2 | ** $Id: lopcodes.c,v 1.48 2011/04/19 16:22:13 roberto Exp $ |
| 3 | ** See Copyright Notice in lua.h | 3 | ** See Copyright Notice in lua.h |
| 4 | */ | 4 | */ |
| 5 | 5 | ||
| @@ -16,6 +16,7 @@ · 10 unmodified lines | |||
| 16 | LUAI_DDEF const char *const luaP_opnames[NUM_OPCODES+1] = { | 16 | LUAI_DDEF const char *const luaP_opnames[NUM_OPCODES+1] = { |
| 17 | "MOVE", | 17 | "MOVE", |
| 18 | "LOADK", | 18 | "LOADK", |
| 19 | "LOADKX", | ||
| 19 | "LOADBOOL", | 20 | "LOADBOOL", |
| 20 | "LOADNIL", | 21 | "LOADNIL", |
| 21 | "GETUPVAL", | 22 | "GETUPVAL", |
| @@ -50,7 +51,6 @@ LUAI_DDEF const char *const luaP_opnames[NUM_OPCODES+1] = { · 28 unmodified lines | |||
| 50 | "TFORCALL", | 51 | "TFORCALL", |
| 51 | "TFORLOOP", | 52 | "TFORLOOP", |
| 52 | "SETLIST", | 53 | "SETLIST", |
| 53 | "CLOSE", | ||
| 54 | "CLOSURE", | 54 | "CLOSURE", |
| 55 | "VARARG", | 55 | "VARARG", |
| 56 | "EXTRAARG", | 56 | "EXTRAARG", |
| @@ -64,8 +64,9 @@ LUAI_DDEF const lu_byte luaP_opmodes[NUM_OPCODES] = { · 7 unmodified lines | |||
| 64 | /* T A B C mode opcode */ | 64 | /* T A B C mode opcode */ |
| 65 | opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_MOVE */ | 65 | opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_MOVE */ |
| 66 | ,opmode(0, 1, OpArgK, OpArgN, iABx) /* OP_LOADK */ | 66 | ,opmode(0, 1, OpArgK, OpArgN, iABx) /* OP_LOADK */ |
| 67 | ,opmode(0, 1, OpArgN, OpArgN, iABx) /* OP_LOADKX */ | ||
| 67 | ,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_LOADBOOL */ | 68 | ,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_LOADBOOL */ |
| 68 | ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_LOADNIL */ | 69 | ,opmode(0, 1, OpArgU, OpArgN, iABC) /* OP_LOADNIL */ |
| 69 | ,opmode(0, 1, OpArgU, OpArgN, iABC) /* OP_GETUPVAL */ | 70 | ,opmode(0, 1, OpArgU, OpArgN, iABC) /* OP_GETUPVAL */ |
| 70 | ,opmode(0, 1, OpArgU, OpArgK, iABC) /* OP_GETTABUP */ | 71 | ,opmode(0, 1, OpArgU, OpArgK, iABC) /* OP_GETTABUP */ |
| 71 | ,opmode(0, 1, OpArgR, OpArgK, iABC) /* OP_GETTABLE */ | 72 | ,opmode(0, 1, OpArgR, OpArgK, iABC) /* OP_GETTABLE */ |
| @@ -88,7 +89,7 @@ LUAI_DDEF const lu_byte luaP_opmodes[NUM_OPCODES] = { · 16 unmodified lines | |||
| 88 | ,opmode(1, 0, OpArgK, OpArgK, iABC) /* OP_EQ */ | 89 | ,opmode(1, 0, OpArgK, OpArgK, iABC) /* OP_EQ */ |
| 89 | ,opmode(1, 0, OpArgK, OpArgK, iABC) /* OP_LT */ | 90 | ,opmode(1, 0, OpArgK, OpArgK, iABC) /* OP_LT */ |
| 90 | ,opmode(1, 0, OpArgK, OpArgK, iABC) /* OP_LE */ | 91 | ,opmode(1, 0, OpArgK, OpArgK, iABC) /* OP_LE */ |
| 91 | ,opmode(1, 1, OpArgR, OpArgU, iABC) /* OP_TEST */ | 92 | ,opmode(1, 0, OpArgN, OpArgU, iABC) /* OP_TEST */ |
| 92 | ,opmode(1, 1, OpArgR, OpArgU, iABC) /* OP_TESTSET */ | 93 | ,opmode(1, 1, OpArgR, OpArgU, iABC) /* OP_TESTSET */ |
| 93 | ,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_CALL */ | 94 | ,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_CALL */ |
| 94 | ,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_TAILCALL */ | 95 | ,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_TAILCALL */ |
| @@ -98,7 +99,6 @@ LUAI_DDEF const lu_byte luaP_opmodes[NUM_OPCODES] = { · 3 unmodified lines | |||
| 98 | ,opmode(0, 0, OpArgN, OpArgU, iABC) /* OP_TFORCALL */ | 99 | ,opmode(0, 0, OpArgN, OpArgU, iABC) /* OP_TFORCALL */ |
| 99 | ,opmode(0, 1, OpArgR, OpArgN, iAsBx) /* OP_TFORLOOP */ | 100 | ,opmode(0, 1, OpArgR, OpArgN, iAsBx) /* OP_TFORLOOP */ |
| 100 | ,opmode(0, 0, OpArgU, OpArgU, iABC) /* OP_SETLIST */ | 101 | ,opmode(0, 0, OpArgU, OpArgU, iABC) /* OP_SETLIST */ |
| 101 | ,opmode(0, 0, OpArgN, OpArgN, iABC) /* OP_CLOSE */ | ||
| 102 | ,opmode(0, 1, OpArgU, OpArgN, iABx) /* OP_CLOSURE */ | 102 | ,opmode(0, 1, OpArgU, OpArgN, iABx) /* OP_CLOSURE */ |
| 103 | ,opmode(0, 1, OpArgU, OpArgN, iABC) /* OP_VARARG */ | 103 | ,opmode(0, 1, OpArgU, OpArgN, iABC) /* OP_VARARG */ |
| 104 | ,opmode(0, 0, OpArgU, OpArgU, iAx) /* OP_EXTRAARG */ | 104 | ,opmode(0, 0, OpArgU, OpArgU, iAx) /* OP_EXTRAARG */ |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lopcodes.h,v 1.137 2010/10/25 12:24:55 roberto Exp $ | 2 | ** $Id: lopcodes.h,v 1.141 2011/04/19 16:22:13 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 | */ |
| @@ -167,9 +167,10 @@ typedef enum { · 161 unmodified lines | |||
| 167 | name args description | 167 | name args description |
| 168 | ------------------------------------------------------------------------*/ | 168 | ------------------------------------------------------------------------*/ |
| 169 | OP_MOVE,/* A B R(A) := R(B) */ | 169 | OP_MOVE,/* A B R(A) := R(B) */ |
| 170 | OP_LOADK,/* A Bx R(A) := Kst(Bx - 1) */ | 170 | OP_LOADK,/* A Bx R(A) := Kst(Bx) */ |
| 171 | OP_LOADKX,/* A R(A) := Kst(extra arg) */ | ||
| 171 | OP_LOADBOOL,/* A B C R(A) := (Bool)B; if (C) pc++ */ | 172 | OP_LOADBOOL,/* A B C R(A) := (Bool)B; if (C) pc++ */ |
| 172 | OP_LOADNIL,/* A B R(A) := ... := R(B) := nil */ | 173 | OP_LOADNIL,/* A B R(A), R(A+1), ..., R(A+B) := nil */ |
| 173 | OP_GETUPVAL,/* A B R(A) := UpValue[B] */ | 174 | OP_GETUPVAL,/* A B R(A) := UpValue[B] */ |
| 174 | 175 | ||
| 175 | OP_GETTABUP,/* A B C R(A) := UpValue[B][RK(C)] */ | 176 | OP_GETTABUP,/* A B C R(A) := UpValue[B][RK(C)] */ |
| @@ -195,8 +196,7 @@ OP_LEN,/* A B R(A) := length of R(B) */ · 19 unmodified lines | |||
| 195 | 196 | ||
| 196 | OP_CONCAT,/* A B C R(A) := R(B).. ... ..R(C) */ | 197 | OP_CONCAT,/* A B C R(A) := R(B).. ... ..R(C) */ |
| 197 | 198 | ||
| 198 | OP_JMP,/* sBx pc+=sBx */ | 199 | OP_JMP,/* A sBx pc+=sBx; if (A) close all upvalues >= R(A) + 1 */ |
| 199 | |||
| 200 | OP_EQ,/* A B C if ((RK(B) == RK(C)) ~= A) then pc++ */ | 200 | OP_EQ,/* A B C if ((RK(B) == RK(C)) ~= A) then pc++ */ |
| 201 | OP_LT,/* A B C if ((RK(B) < RK(C)) ~= A) then pc++ */ | 201 | OP_LT,/* A B C if ((RK(B) < RK(C)) ~= A) then pc++ */ |
| 202 | OP_LE,/* A B C if ((RK(B) <= RK(C)) ~= A) then pc++ */ | 202 | OP_LE,/* A B C if ((RK(B) <= RK(C)) ~= A) then pc++ */ |
| @@ -217,7 +217,6 @@ OP_TFORLOOP,/* A sBx if R(A+1) ~= nil then { R(A)=R(A+1); pc += sBx }*/ · 14 unmodified lines | |||
| 217 | 217 | ||
| 218 | OP_SETLIST,/* A B C R(A)[(C-1)*FPF+i] := R(A+i), 1 <= i <= B */ | 218 | OP_SETLIST,/* A B C R(A)[(C-1)*FPF+i] := R(A+i), 1 <= i <= B */ |
| 219 | 219 | ||
| 220 | OP_CLOSE,/* A close all variables in the stack up to (>=) R(A)*/ | ||
| 221 | OP_CLOSURE,/* A Bx R(A) := closure(KPROTO[Bx]) */ | 220 | OP_CLOSURE,/* A Bx R(A) := closure(KPROTO[Bx]) */ |
| 222 | 221 | ||
| 223 | OP_VARARG,/* A B R(A), R(A+1), ..., R(A+B-2) = vararg */ | 222 | OP_VARARG,/* A B R(A), R(A+1), ..., R(A+B-2) = vararg */ |
| @@ -244,7 +243,7 @@ OP_EXTRAARG/* Ax extra (larger) argument for previous opcode */ · 20 unmodified lines | |||
| 244 | (*) 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 |
| 245 | 'instruction' is EXTRAARG(real C). | 244 | 'instruction' is EXTRAARG(real C). |
| 246 | 245 | ||
| 247 | (*) In OP_LOADK, if (Bx == 0) then next 'instruction' is EXTRAARG(real Bx). | 246 | (*) In OP_LOADKX, the next 'instruction' is always EXTRAARG. |
| 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: loslib.c,v 1.32 2010/10/05 12:18:03 roberto Exp $ | 2 | ** $Id: loslib.c,v 1.34 2011/03/03 16:34:46 roberto Exp $ |
| 3 | ** Standard Operating System library | 3 | ** Standard Operating System library |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -59,37 +59,28 @@ · 53 unmodified lines | |||
| 59 | 59 | ||
| 60 | 60 | ||
| 61 | 61 | ||
| 62 | static int os_pushresult (lua_State *L, int i, const char *filename) { | 62 | static int os_execute (lua_State *L) { |
| 63 | int en = errno; /* calls to Lua API may change this value */ | 63 | const char *cmd = luaL_optstring(L, 1, NULL); |
| 64 | if (i) { | 64 | int stat = system(cmd); |
| 65 | lua_pushboolean(L, 1); | 65 | if (cmd != NULL) |
| 66 | return 1; | 66 | return luaL_execresult(L, stat); |
| 67 | } | ||
| 68 | else { | 67 | else { |
| 69 | lua_pushnil(L); | 68 | lua_pushboolean(L, stat); /* true if there is a shell */ |
| 70 | lua_pushfstring(L, "%s: %s", filename, strerror(en)); | 69 | return 1; |
| 71 | lua_pushinteger(L, en); | ||
| 72 | return 3; | ||
| 73 | } | 70 | } |
| 74 | } | 71 | } |
| 75 | 72 | ||
| 76 | 73 | ||
| 77 | static int os_execute (lua_State *L) { | ||
| 78 | lua_pushinteger(L, system(luaL_optstring(L, 1, NULL))); | ||
| 79 | return 1; | ||
| 80 | } | ||
| 81 | |||
| 82 | |||
| 83 | static int os_remove (lua_State *L) { | 74 | static int os_remove (lua_State *L) { |
| 84 | const char *filename = luaL_checkstring(L, 1); | 75 | const char *filename = luaL_checkstring(L, 1); |
| 85 | return os_pushresult(L, remove(filename) == 0, filename); | 76 | return luaL_fileresult(L, remove(filename) == 0, filename); |
| 86 | } | 77 | } |
| 87 | 78 | ||
| 88 | 79 | ||
| 89 | static int os_rename (lua_State *L) { | 80 | static int os_rename (lua_State *L) { |
| 90 | const char *fromname = luaL_checkstring(L, 1); | 81 | const char *fromname = luaL_checkstring(L, 1); |
| 91 | const char *toname = luaL_checkstring(L, 2); | 82 | const char *toname = luaL_checkstring(L, 2); |
| 92 | return os_pushresult(L, rename(fromname, toname) == 0, fromname); | 83 | return luaL_fileresult(L, rename(fromname, toname) == 0, fromname); |
| 93 | } | 84 | } |
| 94 | 85 | ||
| 95 | 86 | ||
| @@ -182,7 +173,7 @@ static const char *checkoption (lua_State *L, const char *conv, char *buff) { · 86 unmodified lines | |||
| 182 | return conv; /* to avoid warnings */ | 173 | return conv; /* to avoid warnings */ |
| 183 | } | 174 | } |
| 184 | 175 | ||
| 185 | 176 | ||
| 186 | static int os_date (lua_State *L) { | 177 | static int os_date (lua_State *L) { |
| 187 | const char *s = luaL_optstring(L, 1, "%c"); | 178 | const char *s = luaL_optstring(L, 1, "%c"); |
| 188 | time_t t = luaL_opt(L, (time_t)luaL_checknumber, 2, time(NULL)); | 179 | time_t t = luaL_opt(L, (time_t)luaL_checknumber, 2, time(NULL)); |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lparser.c,v 2.92 2010/09/07 19:21:39 roberto Exp $ | 2 | ** $Id: lparser.c,v 2.109 2011/05/02 17:33:01 roberto Exp $ |
| 3 | ** Lua Parser | 3 | ** Lua Parser |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -41,10 +41,11 @@ · 35 unmodified lines | |||
| 41 | */ | 41 | */ |
| 42 | typedef struct BlockCnt { | 42 | typedef struct BlockCnt { |
| 43 | struct BlockCnt *previous; /* chain */ | 43 | struct BlockCnt *previous; /* chain */ |
| 44 | int breaklist; /* list of jumps out of this loop */ | 44 | int firstlabel; /* index of first label in this block */ |
| 45 | lu_byte nactvar; /* # active locals outside the breakable structure */ | 45 | int firstgoto; /* index of first pending goto in this block */ |
| 46 | lu_byte nactvar; /* # active locals outside the block */ | ||
| 46 | lu_byte upval; /* true if some variable in the block is an upvalue */ | 47 | lu_byte upval; /* true if some variable in the block is an upvalue */ |
| 47 | lu_byte isbreakable; /* true if `block' is a loop */ | 48 | lu_byte isloop; /* true if `block' is a loop */ |
| 48 | } BlockCnt; | 49 | } BlockCnt; |
| 49 | 50 | ||
| 50 | 51 | ||
| @@ -52,7 +53,7 @@ typedef struct BlockCnt { · 1 unmodified line | |||
| 52 | /* | 53 | /* |
| 53 | ** prototypes for recursive non-terminal functions | 54 | ** prototypes for recursive non-terminal functions |
| 54 | */ | 55 | */ |
| 55 | static void chunk (LexState *ls); | 56 | static void statement (LexState *ls); |
| 56 | static void expr (LexState *ls, expdesc *v); | 57 | static void expr (LexState *ls, expdesc *v); |
| 57 | 58 | ||
| 58 | 59 | ||
| @@ -66,6 +67,13 @@ static void anchor_token (LexState *ls) { · 7 unmodified lines | |||
| 66 | } | 67 | } |
| 67 | 68 | ||
| 68 | 69 | ||
| 70 | /* semantic error */ | ||
| 71 | static void semerror (LexState *ls, const char *msg) { | ||
| 72 | ls->t.token = 0; /* remove 'near to' from final message */ | ||
| 73 | luaX_syntaxerror(ls, msg); | ||
| 74 | } | ||
| 75 | |||
| 76 | |||
| 69 | static void error_expected (LexState *ls, int token) { | 77 | static void error_expected (LexState *ls, int token) { |
| 70 | luaX_syntaxerror(ls, | 78 | luaX_syntaxerror(ls, |
| 71 | luaO_pushfstring(ls->L, "%s expected", luaX_token2str(ls, token))); | 79 | luaO_pushfstring(ls->L, "%s expected", luaX_token2str(ls, token))); |
| @@ -103,6 +111,7 @@ static void check (LexState *ls, int c) { · 31 unmodified lines | |||
| 103 | error_expected(ls, c); | 111 | error_expected(ls, c); |
| 104 | } | 112 | } |
| 105 | 113 | ||
| 114 | |||
| 106 | static void checknext (LexState *ls, int c) { | 115 | static void checknext (LexState *ls, int c) { |
| 107 | check(ls, c); | 116 | check(ls, c); |
| 108 | luaX_next(ls); | 117 | luaX_next(ls); |
| @@ -167,13 +176,13 @@ static int registerlocalvar (LexState *ls, TString *varname) { · 58 unmodified lines | |||
| 167 | 176 | ||
| 168 | static void new_localvar (LexState *ls, TString *name) { | 177 | static void new_localvar (LexState *ls, TString *name) { |
| 169 | FuncState *fs = ls->fs; | 178 | FuncState *fs = ls->fs; |
| 170 | Varlist *vl = ls->varl; | 179 | Dyndata *dyd = ls->dyd; |
| 171 | int reg = registerlocalvar(ls, name); | 180 | int reg = registerlocalvar(ls, name); |
| 172 | checklimit(fs, vl->nactvar + 1 - fs->firstlocal, | 181 | checklimit(fs, dyd->actvar.n + 1 - fs->firstlocal, |
| 173 | MAXVARS, "local variables"); | 182 | MAXVARS, "local variables"); |
| 174 | luaM_growvector(ls->L, vl->actvar, vl->nactvar + 1, | 183 | luaM_growvector(ls->L, dyd->actvar.arr, dyd->actvar.n + 1, |
| 175 | vl->actvarsize, vardesc, MAX_INT, "local variables"); | 184 | dyd->actvar.size, Vardesc, MAX_INT, "local variables"); |
| 176 | vl->actvar[vl->nactvar++].idx = cast(unsigned short, reg); | 185 | dyd->actvar.arr[dyd->actvar.n++].idx = cast(unsigned short, reg); |
| 177 | } | 186 | } |
| 178 | 187 | ||
| 179 | 188 | ||
| @@ -186,7 +195,7 @@ static void new_localvarliteral_ (LexState *ls, const char *name, size_t sz) { · 6 unmodified lines | |||
| 186 | 195 | ||
| 187 | 196 | ||
| 188 | static LocVar *getlocvar (FuncState *fs, int i) { | 197 | static LocVar *getlocvar (FuncState *fs, int i) { |
| 189 | int idx = fs->ls->varl->actvar[fs->firstlocal + i].idx; | 198 | int idx = fs->ls->dyd->actvar.arr[fs->firstlocal + i].idx; |
| 190 | lua_assert(idx < fs->nlocvars); | 199 | lua_assert(idx < fs->nlocvars); |
| 191 | return &fs->f->locvars[idx]; | 200 | return &fs->f->locvars[idx]; |
| 192 | } | 201 | } |
| @@ -202,7 +211,7 @@ static void adjustlocalvars (LexState *ls, int nvars) { · 9 unmodified lines | |||
| 202 | 211 | ||
| 203 | 212 | ||
| 204 | static void removevars (FuncState *fs, int tolevel) { | 213 | static void removevars (FuncState *fs, int tolevel) { |
| 205 | fs->ls->varl->nactvar -= (fs->nactvar - tolevel); | 214 | fs->ls->dyd->actvar.n -= (fs->nactvar - tolevel); |
| 206 | while (fs->nactvar > tolevel) | 215 | while (fs->nactvar > tolevel) |
| 207 | getlocvar(fs, --fs->nactvar)->endpc = fs->pc; | 216 | getlocvar(fs, --fs->nactvar)->endpc = fs->pc; |
| 208 | } | 217 | } |
| @@ -245,12 +254,12 @@ static int searchvar (FuncState *fs, TString *n) { · 36 unmodified lines | |||
| 245 | 254 | ||
| 246 | /* | 255 | /* |
| 247 | Mark block where variable at given level was defined | 256 | Mark block where variable at given level was defined |
| 248 | (to emit OP_CLOSE later). | 257 | (to emit close instructions later). |
| 249 | */ | 258 | */ |
| 250 | static void markupval (FuncState *fs, int level) { | 259 | static void markupval (FuncState *fs, int level) { |
| 251 | BlockCnt *bl = fs->bl; | 260 | BlockCnt *bl = fs->bl; |
| 252 | while (bl && bl->nactvar > level) bl = bl->previous; | 261 | while (bl->nactvar > level) bl = bl->previous; |
| 253 | if (bl) bl->upval = 1; | 262 | bl->upval = 1; |
| 254 | } | 263 | } |
| 255 | 264 | ||
| 256 | 265 | ||
| @@ -327,10 +336,107 @@ static void enterlevel (LexState *ls) { · 70 unmodified lines | |||
| 327 | #define leavelevel(ls) (G((ls)->L)->nCcalls--) | 336 | #define leavelevel(ls) (G((ls)->L)->nCcalls--) |
| 328 | 337 | ||
| 329 | 338 | ||
| 330 | static void enterblock (FuncState *fs, BlockCnt *bl, lu_byte isbreakable) { | 339 | static void closegoto (LexState *ls, int g, Labeldesc *label) { |
| 331 | bl->breaklist = NO_JUMP; | 340 | int i; |
| 332 | bl->isbreakable = isbreakable; | 341 | FuncState *fs = ls->fs; |
| 342 | Labellist *gl = &ls->dyd->gt; | ||
| 343 | Labeldesc *gt = &gl->arr[g]; | ||
| 344 | lua_assert(eqstr(gt->name, label->name)); | ||
| 345 | if (gt->nactvar < label->nactvar) { | ||
| 346 | const char *msg = luaO_pushfstring(ls->L, | ||
| 347 | "<goto %s> at line %d jumps into the scope of local " LUA_QS, | ||
| 348 | getstr(gt->name), gt->line, getstr(getlocvar(fs, gt->nactvar)->varname)); | ||
| 349 | semerror(ls, msg); | ||
| 350 | } | ||
| 351 | luaK_patchlist(fs, gt->pc, label->pc); | ||
| 352 | /* remove goto from pending list */ | ||
| 353 | for (i = g; i < gl->n - 1; i++) | ||
| 354 | gl->arr[i] = gl->arr[i + 1]; | ||
| 355 | gl->n--; | ||
| 356 | } | ||
| 357 | |||
| 358 | |||
| 359 | /* | ||
| 360 | ** try to close a goto with existing labels; this solves backward jumps | ||
| 361 | */ | ||
| 362 | static int findlabel (LexState *ls, int g) { | ||
| 363 | int i; | ||
| 364 | BlockCnt *bl = ls->fs->bl; | ||
| 365 | Dyndata *dyd = ls->dyd; | ||
| 366 | Labeldesc *gt = &dyd->gt.arr[g]; | ||
| 367 | /* check labels in current block for a match */ | ||
| 368 | for (i = bl->firstlabel; i < dyd->label.n; i++) { | ||
| 369 | Labeldesc *lb = &dyd->label.arr[i]; | ||
| 370 | if (eqstr(lb->name, gt->name)) { /* correct label? */ | ||
| 371 | if (gt->nactvar > lb->nactvar && | ||
| 372 | (bl->upval || dyd->label.n > bl->firstlabel)) | ||
| 373 | luaK_patchclose(ls->fs, gt->pc, lb->nactvar); | ||
| 374 | closegoto(ls, g, lb); /* close it */ | ||
| 375 | return 1; | ||
| 376 | } | ||
| 377 | } | ||
| 378 | return 0; /* label not found; cannot close goto */ | ||
| 379 | } | ||
| 380 | |||
| 381 | |||
| 382 | static int newlabelentry (LexState *ls, Labellist *l, TString *name, | ||
| 383 | int line, int pc) { | ||
| 384 | int n = l->n; | ||
| 385 | luaM_growvector(ls->L, l->arr, n, l->size, Labeldesc, MAX_INT, "labels"); | ||
| 386 | l->arr[n].name = name; | ||
| 387 | l->arr[n].line = line; | ||
| 388 | l->arr[n].nactvar = ls->fs->nactvar; | ||
| 389 | l->arr[n].pc = pc; | ||
| 390 | l->n++; | ||
| 391 | return n; | ||
| 392 | } | ||
| 393 | |||
| 394 | |||
| 395 | /* | ||
| 396 | ** check whether new label 'lb' matches any pending gotos in current | ||
| 397 | ** block; solves forward jumps | ||
| 398 | */ | ||
| 399 | static void findgotos (LexState *ls, Labeldesc *lb) { | ||
| 400 | Labellist *gl = &ls->dyd->gt; | ||
| 401 | int i = ls->fs->bl->firstgoto; | ||
| 402 | while (i < gl->n) { | ||
| 403 | if (eqstr(gl->arr[i].name, lb->name)) | ||
| 404 | closegoto(ls, i, lb); | ||
| 405 | else | ||
| 406 | i++; | ||
| 407 | } | ||
| 408 | } | ||
| 409 | |||
| 410 | |||
| 411 | /* | ||
| 412 | ** "export" pending gotos to outer level, to check them against | ||
| 413 | ** outer labels; if the block being exited has upvalues, and | ||
| 414 | ** the goto exists the scope of any variable (which can be the | ||
| 415 | ** upvalue), close those variables being exited. | ||
| 416 | */ | ||
| 417 | static void movegotosout (FuncState *fs, BlockCnt *bl) { | ||
| 418 | int i = bl->firstgoto; | ||
| 419 | Labellist *gl = &fs->ls->dyd->gt; | ||
| 420 | /* correct pending gotos to current block and try to close it | ||
| 421 | with visible labels */ | ||
| 422 | while (i < gl->n) { | ||
| 423 | Labeldesc *gt = &gl->arr[i]; | ||
| 424 | if (gt->nactvar > bl->nactvar) { | ||
| 425 | if (bl->upval) | ||
| 426 | luaK_patchclose(fs, gt->pc, bl->nactvar); | ||
| 427 | gt->nactvar = bl->nactvar; | ||
| 428 | } | ||
| 429 | if (!findlabel(fs->ls, i)) | ||
| 430 | i++; /* move to next one */ | ||
| 431 | } | ||
| 432 | } | ||
| 433 | |||
| 434 | |||
| 435 | static void enterblock (FuncState *fs, BlockCnt *bl, lu_byte isloop) { | ||
| 436 | bl->isloop = isloop; | ||
| 333 | bl->nactvar = fs->nactvar; | 437 | bl->nactvar = fs->nactvar; |
| 438 | bl->firstlabel = fs->ls->dyd->label.n; | ||
| 439 | bl->firstgoto = fs->ls->dyd->gt.n; | ||
| 334 | bl->upval = 0; | 440 | bl->upval = 0; |
| 335 | bl->previous = fs->bl; | 441 | bl->previous = fs->bl; |
| 336 | fs->bl = bl; | 442 | fs->bl = bl; |
| @@ -338,17 +444,48 @@ static void enterblock (FuncState *fs, BlockCnt *bl, lu_byte isbreakable) { · 1 unmodified line | |||
| 338 | } | 444 | } |
| 339 | 445 | ||
| 340 | 446 | ||
| 447 | /* | ||
| 448 | ** create a label named "break" to resolve break statements | ||
| 449 | */ | ||
| 450 | static void breaklabel (LexState *ls) { | ||
| 451 | TString *n = luaS_new(ls->L, "break"); | ||
| 452 | int l = newlabelentry(ls, &ls->dyd->label, n, 0, ls->fs->pc); | ||
| 453 | findgotos(ls, &ls->dyd->label.arr[l]); | ||
| 454 | } | ||
| 455 | |||
| 456 | /* | ||
| 457 | ** generates an error for an undefined 'goto'; choose appropriate | ||
| 458 | ** message when label name is a reserved word (which can only be 'break') | ||
| 459 | */ | ||
| 460 | static void undefgoto (LexState *ls, Labeldesc *gt) { | ||
| 461 | const char *msg = (gt->name->tsv.reserved > 0) | ||
| 462 | ? "<%s> at line %d not inside a loop" | ||
| 463 | : "label " LUA_QS " (<goto> at line %d) undefined"; | ||
| 464 | msg = luaO_pushfstring(ls->L, msg, getstr(gt->name), gt->line); | ||
| 465 | semerror(ls, msg); | ||
| 466 | } | ||
| 467 | |||
| 468 | |||
| 341 | static void leaveblock (FuncState *fs) { | 469 | static void leaveblock (FuncState *fs) { |
| 342 | BlockCnt *bl = fs->bl; | 470 | BlockCnt *bl = fs->bl; |
| 471 | LexState *ls = fs->ls; | ||
| 472 | if (bl->previous && bl->upval) { | ||
| 473 | /* create a 'jump to here' to close upvalues */ | ||
| 474 | int j = luaK_jump(fs); | ||
| 475 | luaK_patchclose(fs, j, bl->nactvar); | ||
| 476 | luaK_patchtohere(fs, j); | ||
| 477 | } | ||
| 478 | if (bl->isloop) | ||
| 479 | breaklabel(ls); /* close pending breaks */ | ||
| 343 | fs->bl = bl->previous; | 480 | fs->bl = bl->previous; |
| 344 | removevars(fs, bl->nactvar); | 481 | removevars(fs, bl->nactvar); |
| 345 | if (bl->upval) | ||
| 346 | luaK_codeABC(fs, OP_CLOSE, bl->nactvar, 0, 0); | ||
| 347 | /* a block either controls scope or breaks (never both) */ | ||
| 348 | lua_assert(!bl->isbreakable || !bl->upval); | ||
| 349 | lua_assert(bl->nactvar == fs->nactvar); | 482 | lua_assert(bl->nactvar == fs->nactvar); |
| 350 | fs->freereg = fs->nactvar; /* free registers */ | 483 | fs->freereg = fs->nactvar; /* free registers */ |
| 351 | luaK_patchtohere(fs, bl->breaklist); | 484 | ls->dyd->label.n = bl->firstlabel; /* remove local labels */ |
| 485 | if (bl->previous) /* inner block? */ | ||
| 486 | movegotosout(fs, bl); /* update pending gotos to outer block */ | ||
| 487 | else if (bl->firstgoto < ls->dyd->gt.n) /* pending gotos in outer block? */ | ||
| 488 | undefgoto(ls, &ls->dyd->gt.arr[bl->firstgoto]); /* error */ | ||
| 352 | } | 489 | } |
| 353 | 490 | ||
| 354 | 491 | ||
| @@ -368,10 +505,11 @@ static void codeclosure (LexState *ls, Proto *clp, expdesc *v) { · 13 unmodified lines | |||
| 368 | f->p[fs->np++] = clp; | 505 | f->p[fs->np++] = clp; |
| 369 | luaC_objbarrier(ls->L, f, clp); | 506 | luaC_objbarrier(ls->L, f, clp); |
| 370 | init_exp(v, VRELOCABLE, luaK_codeABx(fs, OP_CLOSURE, 0, fs->np-1)); | 507 | init_exp(v, VRELOCABLE, luaK_codeABx(fs, OP_CLOSURE, 0, fs->np-1)); |
| 508 | luaK_exp2nextreg(fs, v); /* fix it at stack top (for GC) */ | ||
| 371 | } | 509 | } |
| 372 | 510 | ||
| 373 | 511 | ||
| 374 | static void open_func (LexState *ls, FuncState *fs) { | 512 | static void open_func (LexState *ls, FuncState *fs, BlockCnt *bl) { |
| 375 | lua_State *L = ls->L; | 513 | lua_State *L = ls->L; |
| 376 | Proto *f; | 514 | Proto *f; |
| 377 | fs->prev = ls->fs; /* linked list of funcstates */ | 515 | fs->prev = ls->fs; /* linked list of funcstates */ |
| @@ -387,7 +525,7 @@ static void open_func (LexState *ls, FuncState *fs) { · 9 unmodified lines | |||
| 387 | fs->nups = 0; | 525 | fs->nups = 0; |
| 388 | fs->nlocvars = 0; | 526 | fs->nlocvars = 0; |
| 389 | fs->nactvar = 0; | 527 | fs->nactvar = 0; |
| 390 | fs->firstlocal = ls->varl->nactvar; | 528 | fs->firstlocal = ls->dyd->actvar.n; |
| 391 | fs->bl = NULL; | 529 | fs->bl = NULL; |
| 392 | f = luaF_newproto(L); | 530 | f = luaF_newproto(L); |
| 393 | fs->f = f; | 531 | fs->f = f; |
| @@ -400,6 +538,7 @@ static void open_func (LexState *ls, FuncState *fs) { · 6 unmodified lines | |||
| 400 | /* anchor table of constants (to avoid being collected) */ | 538 | /* anchor table of constants (to avoid being collected) */ |
| 401 | sethvalue2s(L, L->top, fs->h); | 539 | sethvalue2s(L, L->top, fs->h); |
| 402 | incr_top(L); | 540 | incr_top(L); |
| 541 | enterblock(fs, bl, 0); | ||
| 403 | } | 542 | } |
| 404 | 543 | ||
| 405 | 544 | ||
| @@ -408,7 +547,7 @@ static void close_func (LexState *ls) { · 2 unmodified lines | |||
| 408 | FuncState *fs = ls->fs; | 547 | FuncState *fs = ls->fs; |
| 409 | Proto *f = fs->f; | 548 | Proto *f = fs->f; |
| 410 | luaK_ret(fs, 0, 0); /* final return */ | 549 | luaK_ret(fs, 0, 0); /* final return */ |
| 411 | removevars(fs, 0); | 550 | leaveblock(fs); |
| 412 | luaM_reallocvector(L, f->code, f->sizecode, fs->pc, Instruction); | 551 | luaM_reallocvector(L, f->code, f->sizecode, fs->pc, Instruction); |
| 413 | f->sizecode = fs->pc; | 552 | f->sizecode = fs->pc; |
| 414 | luaM_reallocvector(L, f->lineinfo, f->sizelineinfo, fs->pc, int); | 553 | luaM_reallocvector(L, f->lineinfo, f->sizelineinfo, fs->pc, int); |
| @@ -435,42 +574,49 @@ static void close_func (LexState *ls) { · 20 unmodified lines | |||
| 435 | ** opens the main function, which is a regular vararg function with an | 574 | ** opens the main function, which is a regular vararg function with an |
| 436 | ** upvalue named LUA_ENV | 575 | ** upvalue named LUA_ENV |
| 437 | */ | 576 | */ |
| 438 | static void open_mainfunc (LexState *ls, FuncState *fs) { | 577 | static void open_mainfunc (LexState *ls, FuncState *fs, BlockCnt *bl) { |
| 439 | expdesc v; | 578 | expdesc v; |
| 440 | open_func(ls, fs); | 579 | open_func(ls, fs, bl); |
| 441 | fs->f->is_vararg = 1; /* main function is always vararg */ | 580 | fs->f->is_vararg = 1; /* main function is always vararg */ |
| 442 | init_exp(&v, VLOCAL, 0); | 581 | init_exp(&v, VLOCAL, 0); |
| 443 | newupvalue(fs, ls->envn, &v); /* create environment upvalue */ | 582 | newupvalue(fs, ls->envn, &v); /* create environment upvalue */ |
| 444 | } | 583 | } |
| 445 | 584 | ||
| 446 | 585 | ||
| 447 | Proto *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff, Varlist *varl, | ||
| 448 | const char *name) { | ||
| 449 | LexState lexstate; | ||
| 450 | FuncState funcstate; | ||
| 451 | TString *tname = luaS_new(L, name); | ||
| 452 | setsvalue2s(L, L->top, tname); /* push name to protect it */ | ||
| 453 | incr_top(L); | ||
| 454 | lexstate.buff = buff; | ||
| 455 | lexstate.varl = varl; | ||
| 456 | luaX_setinput(L, &lexstate, z, tname); | ||
| 457 | open_mainfunc(&lexstate, &funcstate); | ||
| 458 | luaX_next(&lexstate); /* read first token */ | ||
| 459 | chunk(&lexstate); /* read main chunk */ | ||
| 460 | check(&lexstate, TK_EOS); | ||
| 461 | close_func(&lexstate); | ||
| 462 | L->top--; /* pop name */ | ||
| 463 | lua_assert(!funcstate.prev && funcstate.nups == 1 && !lexstate.fs); | ||
| 464 | return funcstate.f; | ||
| 465 | } | ||
| 466 | |||
| 467 | |||
| 468 | 586 | ||
| 469 | /*============================================================*/ | 587 | /*============================================================*/ |
| 470 | /* GRAMMAR RULES */ | 588 | /* GRAMMAR RULES */ |
| 471 | /*============================================================*/ | 589 | /*============================================================*/ |
| 472 | 590 | ||
| 473 | 591 | ||
| 592 | /* | ||
| 593 | ** check whether current token is in the follow set of a block. | ||
| 594 | ** 'until' closes syntactical blocks, but do not close scope, | ||
| 595 | ** so it handled in separate. | ||
| 596 | */ | ||
| 597 | static int block_follow (LexState *ls, int withuntil) { | ||
| 598 | switch (ls->t.token) { | ||
| 599 | case TK_ELSE: case TK_ELSEIF: | ||
| 600 | case TK_END: case TK_EOS: | ||
| 601 | return 1; | ||
| 602 | case TK_UNTIL: return withuntil; | ||
| 603 | default: return 0; | ||
| 604 | } | ||
| 605 | } | ||
| 606 | |||
| 607 | |||
| 608 | static void statlist (LexState *ls) { | ||
| 609 | /* statlist -> { stat [`;'] } */ | ||
| 610 | while (!block_follow(ls, 1)) { | ||
| 611 | if (ls->t.token == TK_RETURN) { | ||
| 612 | statement(ls); | ||
| 613 | return; /* 'return' must be last statement */ | ||
| 614 | } | ||
| 615 | statement(ls); | ||
| 616 | } | ||
| 617 | } | ||
| 618 | |||
| 619 | |||
| 474 | static void fieldsel (LexState *ls, expdesc *v) { | 620 | static void fieldsel (LexState *ls, expdesc *v) { |
| 475 | /* fieldsel -> ['.' | ':'] NAME */ | 621 | /* fieldsel -> ['.' | ':'] NAME */ |
| 476 | FuncState *fs = ls->fs; | 622 | FuncState *fs = ls->fs; |
| @@ -586,7 +732,7 @@ static void field (LexState *ls, struct ConsControl *cc) { · 109 unmodified lines | |||
| 586 | 732 | ||
| 587 | 733 | ||
| 588 | static void constructor (LexState *ls, expdesc *t) { | 734 | static void constructor (LexState *ls, expdesc *t) { |
| 589 | /* constructor -> '{' [ field { sep field } [sep] ] '}' | 735 | /* constructor -> '{' [ field { sep field } [sep] ] '}' |
| 590 | sep -> ',' | ';' */ | 736 | sep -> ',' | ';' */ |
| 591 | FuncState *fs = ls->fs; | 737 | FuncState *fs = ls->fs; |
| 592 | int line = ls->linenumber; | 738 | int line = ls->linenumber; |
| @@ -596,7 +742,7 @@ static void constructor (LexState *ls, expdesc *t) { · 3 unmodified lines | |||
| 596 | cc.t = t; | 742 | cc.t = t; |
| 597 | init_exp(t, VRELOCABLE, pc); | 743 | init_exp(t, VRELOCABLE, pc); |
| 598 | init_exp(&cc.v, VVOID, 0); /* no value (yet) */ | 744 | init_exp(&cc.v, VVOID, 0); /* no value (yet) */ |
| 599 | luaK_exp2nextreg(ls->fs, t); /* fix it at stack top (for gc) */ | 745 | luaK_exp2nextreg(ls->fs, t); /* fix it at stack top */ |
| 600 | checknext(ls, '{'); | 746 | checknext(ls, '{'); |
| 601 | do { | 747 | do { |
| 602 | lua_assert(cc.v.k == VVOID || cc.tostore > 0); | 748 | lua_assert(cc.v.k == VVOID || cc.tostore > 0); |
| @@ -643,19 +789,20 @@ static void parlist (LexState *ls) { · 40 unmodified lines | |||
| 643 | } | 789 | } |
| 644 | 790 | ||
| 645 | 791 | ||
| 646 | static void body (LexState *ls, expdesc *e, int needself, int line) { | 792 | static void body (LexState *ls, expdesc *e, int ismethod, int line) { |
| 647 | /* body -> `(' parlist `)' chunk END */ | 793 | /* body -> `(' parlist `)' block END */ |
| 648 | FuncState new_fs; | 794 | FuncState new_fs; |
| 649 | open_func(ls, &new_fs); | 795 | BlockCnt bl; |
| 796 | open_func(ls, &new_fs, &bl); | ||
| 650 | new_fs.f->linedefined = line; | 797 | new_fs.f->linedefined = line; |
| 651 | checknext(ls, '('); | 798 | checknext(ls, '('); |
| 652 | if (needself) { | 799 | if (ismethod) { |
| 653 | new_localvarliteral(ls, "self"); | 800 | new_localvarliteral(ls, "self"); /* create 'self' parameter */ |
| 654 | adjustlocalvars(ls, 1); | 801 | adjustlocalvars(ls, 1); |
| 655 | } | 802 | } |
| 656 | parlist(ls); | 803 | parlist(ls); |
| 657 | checknext(ls, ')'); | 804 | checknext(ls, ')'); |
| 658 | chunk(ls); | 805 | statlist(ls); |
| 659 | new_fs.f->lastlinedefined = ls->linenumber; | 806 | new_fs.f->lastlinedefined = ls->linenumber; |
| 660 | check_match(ls, TK_END, TK_FUNCTION, line); | 807 | check_match(ls, TK_END, TK_FUNCTION, line); |
| 661 | codeclosure(ls, new_fs.f, e); | 808 | codeclosure(ls, new_fs.f, e); |
| @@ -663,8 +810,8 @@ static void body (LexState *ls, expdesc *e, int needself, int line) { · 1 unmodified line | |||
| 663 | } | 810 | } |
| 664 | 811 | ||
| 665 | 812 | ||
| 666 | static int explist1 (LexState *ls, expdesc *v) { | 813 | static int explist (LexState *ls, expdesc *v) { |
| 667 | /* explist1 -> expr { `,' expr } */ | 814 | /* explist -> expr { `,' expr } */ |
| 668 | int n = 1; /* at least one expression */ | 815 | int n = 1; /* at least one expression */ |
| 669 | expr(ls, v); | 816 | expr(ls, v); |
| 670 | while (testnext(ls, ',')) { | 817 | while (testnext(ls, ',')) { |
| @@ -681,12 +828,12 @@ static void funcargs (LexState *ls, expdesc *f, int line) { · 10 unmodified lines | |||
| 681 | expdesc args; | 828 | expdesc args; |
| 682 | int base, nparams; | 829 | int base, nparams; |
| 683 | switch (ls->t.token) { | 830 | switch (ls->t.token) { |
| 684 | case '(': { /* funcargs -> `(' [ explist1 ] `)' */ | 831 | case '(': { /* funcargs -> `(' [ explist ] `)' */ |
| 685 | luaX_next(ls); | 832 | luaX_next(ls); |
| 686 | if (ls->t.token == ')') /* arg list is empty? */ | 833 | if (ls->t.token == ')') /* arg list is empty? */ |
| 687 | args.k = VVOID; | 834 | args.k = VVOID; |
| 688 | else { | 835 | else { |
| 689 | explist1(ls, &args); | 836 | explist(ls, &args); |
| 690 | luaK_setmultret(fs, &args); | 837 | luaK_setmultret(fs, &args); |
| 691 | } | 838 | } |
| 692 | check_match(ls, ')', '(', line); | 839 | check_match(ls, ')', '(', line); |
| @@ -937,23 +1084,12 @@ static void expr (LexState *ls, expdesc *v) { · 244 unmodified lines | |||
| 937 | */ | 1084 | */ |
| 938 | 1085 | ||
| 939 | 1086 | ||
| 940 | static int block_follow (int token) { | ||
| 941 | switch (token) { | ||
| 942 | case TK_ELSE: case TK_ELSEIF: case TK_END: | ||
| 943 | case TK_UNTIL: case TK_EOS: | ||
| 944 | return 1; | ||
| 945 | default: return 0; | ||
| 946 | } | ||
| 947 | } | ||
| 948 | |||
| 949 | |||
| 950 | static void block (LexState *ls) { | 1087 | static void block (LexState *ls) { |
| 951 | /* block -> chunk */ | 1088 | /* block -> statlist */ |
| 952 | FuncState *fs = ls->fs; | 1089 | FuncState *fs = ls->fs; |
| 953 | BlockCnt bl; | 1090 | BlockCnt bl; |
| 954 | enterblock(fs, &bl, 0); | 1091 | enterblock(fs, &bl, 0); |
| 955 | chunk(ls); | 1092 | statlist(ls); |
| 956 | lua_assert(bl.breaklist == NO_JUMP); | ||
| 957 | leaveblock(fs); | 1093 | leaveblock(fs); |
| 958 | } | 1094 | } |
| 959 | 1095 | ||
| @@ -1012,10 +1148,10 @@ static void assignment (LexState *ls, struct LHS_assign *lh, int nvars) { · 52 unmodified lines | |||
| 1012 | "variable names"); | 1148 | "variable names"); |
| 1013 | assignment(ls, &nv, nvars+1); | 1149 | assignment(ls, &nv, nvars+1); |
| 1014 | } | 1150 | } |
| 1015 | else { /* assignment -> `=' explist1 */ | 1151 | else { /* assignment -> `=' explist */ |
| 1016 | int nexps; | 1152 | int nexps; |
| 1017 | checknext(ls, '='); | 1153 | checknext(ls, '='); |
| 1018 | nexps = explist1(ls, &e); | 1154 | nexps = explist(ls, &e); |
| 1019 | if (nexps != nvars) { | 1155 | if (nexps != nvars) { |
| 1020 | adjust_assign(ls, nvars, nexps, &e); | 1156 | adjust_assign(ls, nvars, nexps, &e); |
| 1021 | if (nexps > nvars) | 1157 | if (nexps > nvars) |
| @@ -1042,19 +1178,38 @@ static int cond (LexState *ls) { · 20 unmodified lines | |||
| 1042 | } | 1178 | } |
| 1043 | 1179 | ||
| 1044 | 1180 | ||
| 1045 | static void breakstat (LexState *ls) { | 1181 | static void gotostat (LexState *ls, TString *label, int line) { |
| 1182 | /* create new entry for this goto */ | ||
| 1183 | int g = newlabelentry(ls, &ls->dyd->gt, label, line, luaK_jump(ls->fs)); | ||
| 1184 | findlabel(ls, g); | ||
| 1185 | } | ||
| 1186 | |||
| 1187 | |||
| 1188 | static void labelstat (LexState *ls, TString *label, int line) { | ||
| 1189 | /* label -> '@' NAME ':' */ | ||
| 1046 | FuncState *fs = ls->fs; | 1190 | FuncState *fs = ls->fs; |
| 1047 | BlockCnt *bl = fs->bl; | 1191 | Labellist *ll = &ls->dyd->label; |
| 1048 | int upval = 0; | 1192 | int l, i; /* index of new label being created */ |
| 1049 | while (bl && !bl->isbreakable) { | 1193 | /* check for repeated labels on the same block */ |
| 1050 | upval |= bl->upval; | 1194 | for (i = ls->fs->bl->firstlabel; i < ll->n; i++) { |
| 1051 | bl = bl->previous; | 1195 | if (eqstr(label, ll->arr[i].name)) { |
| 1196 | const char *msg = luaO_pushfstring(ls->L, | ||
| 1197 | "label " LUA_QS " already defined on line %d", | ||
| 1198 | getstr(label), ll->arr[i].line); | ||
| 1199 | semerror(ls, msg); | ||
| 1200 | } | ||
| 1052 | } | 1201 | } |
| 1053 | if (!bl) | 1202 | checknext(ls, ':'); /* skip colon */ |
| 1054 | luaX_syntaxerror(ls, "no loop to break"); | 1203 | /* create new entry for this label */ |
| 1055 | if (upval) | 1204 | l = newlabelentry(ls, ll, label, line, fs->pc); |
| 1056 | luaK_codeABC(fs, OP_CLOSE, bl->nactvar, 0, 0); | 1205 | /* skip other no-op statements */ |
| 1057 | luaK_concat(fs, &bl->breaklist, luaK_jump(fs)); | 1206 | while (ls->t.token == ';' || ls->t.token == '@') |
| 1207 | statement(ls); | ||
| 1208 | if (block_follow(ls, 0)) { /* label is last no-op statement in the block? */ | ||
| 1209 | /* assume that locals are already out of scope */ | ||
| 1210 | ll->arr[l].nactvar = fs->bl->nactvar; | ||
| 1211 | } | ||
| 1212 | findgotos(ls, &ll->arr[l]); | ||
| 1058 | } | 1213 | } |
| 1059 | 1214 | ||
| 1060 | 1215 | ||
| @@ -1086,19 +1241,13 @@ static void repeatstat (LexState *ls, int line) { · 25 unmodified lines | |||
| 1086 | enterblock(fs, &bl1, 1); /* loop block */ | 1241 | enterblock(fs, &bl1, 1); /* loop block */ |
| 1087 | enterblock(fs, &bl2, 0); /* scope block */ | 1242 | enterblock(fs, &bl2, 0); /* scope block */ |
| 1088 | luaX_next(ls); /* skip REPEAT */ | 1243 | luaX_next(ls); /* skip REPEAT */ |
| 1089 | chunk(ls); | 1244 | statlist(ls); |
| 1090 | check_match(ls, TK_UNTIL, TK_REPEAT, line); | 1245 | check_match(ls, TK_UNTIL, TK_REPEAT, line); |
| 1091 | condexit = cond(ls); /* read condition (inside scope block) */ | 1246 | condexit = cond(ls); /* read condition (inside scope block) */ |
| 1092 | if (!bl2.upval) { /* no upvalues? */ | 1247 | if (bl2.upval) /* upvalues? */ |
| 1093 | leaveblock(fs); /* finish scope */ | 1248 | luaK_patchclose(fs, condexit, bl2.nactvar); |
| 1094 | luaK_patchlist(fs, condexit, repeat_init); /* close the loop */ | 1249 | leaveblock(fs); /* finish scope */ |
| 1095 | } | 1250 | luaK_patchlist(fs, condexit, repeat_init); /* close the loop */ |
| 1096 | else { /* complete semantics when there are upvalues */ | ||
| 1097 | breakstat(ls); /* if condition then break */ | ||
| 1098 | luaK_patchtohere(ls->fs, condexit); /* else... */ | ||
| 1099 | leaveblock(fs); /* finish scope... */ | ||
| 1100 | luaK_jumpto(fs, repeat_init); /* and repeat */ | ||
| 1101 | } | ||
| 1102 | leaveblock(fs); /* finish loop */ | 1251 | leaveblock(fs); /* finish loop */ |
| 1103 | } | 1252 | } |
| 1104 | 1253 | ||
| @@ -1163,7 +1312,7 @@ static void fornum (LexState *ls, TString *varname, int line) { · 58 unmodified lines | |||
| 1163 | 1312 | ||
| 1164 | 1313 | ||
| 1165 | static void forlist (LexState *ls, TString *indexname) { | 1314 | static void forlist (LexState *ls, TString *indexname) { |
| 1166 | /* forlist -> NAME {,NAME} IN explist1 forbody */ | 1315 | /* forlist -> NAME {,NAME} IN explist forbody */ |
| 1167 | FuncState *fs = ls->fs; | 1316 | FuncState *fs = ls->fs; |
| 1168 | expdesc e; | 1317 | expdesc e; |
| 1169 | int nvars = 4; /* gen, state, control, plus at least one declared var */ | 1318 | int nvars = 4; /* gen, state, control, plus at least one declared var */ |
| @@ -1181,7 +1330,7 @@ static void forlist (LexState *ls, TString *indexname) { · 11 unmodified lines | |||
| 1181 | } | 1330 | } |
| 1182 | checknext(ls, TK_IN); | 1331 | checknext(ls, TK_IN); |
| 1183 | line = ls->linenumber; | 1332 | line = ls->linenumber; |
| 1184 | adjust_assign(ls, 3, explist1(ls, &e), &e); | 1333 | adjust_assign(ls, 3, explist(ls, &e), &e); |
| 1185 | luaK_checkstack(fs, 3); /* extra space to call generator */ | 1334 | luaK_checkstack(fs, 3); /* extra space to call generator */ |
| 1186 | forbody(ls, base, line, nvars - 3, 0); | 1335 | forbody(ls, base, line, nvars - 3, 0); |
| 1187 | } | 1336 | } |
| @@ -1241,19 +1390,20 @@ static void ifstat (LexState *ls, int line) { · 53 unmodified lines | |||
| 1241 | 1390 | ||
| 1242 | 1391 | ||
| 1243 | static void localfunc (LexState *ls) { | 1392 | static void localfunc (LexState *ls) { |
| 1244 | expdesc v, b; | 1393 | expdesc b; |
| 1245 | FuncState *fs = ls->fs; | 1394 | FuncState *fs = ls->fs; |
| 1246 | new_localvar(ls, str_checkname(ls)); | 1395 | int varidx = fs->nactvar; /* index of new local variable */ |
| 1247 | init_exp(&v, VLOCAL, fs->freereg); | 1396 | new_localvar(ls, str_checkname(ls)); /* new local variable */ |
| 1248 | luaK_reserveregs(fs, 1); | 1397 | adjustlocalvars(ls, 1); /* enter its scope */ |
| 1249 | adjustlocalvars(ls, 1); | 1398 | body(ls, &b, 0, ls->linenumber); /* function created in next register */ |
| 1250 | body(ls, &b, 0, ls->linenumber); | 1399 | lua_assert(b.k == VNONRELOC && b.u.ind.idx == varidx); |
| 1251 | luaK_storevar(fs, &v, &b); | 1400 | /* debug information will only see the variable after this point! */ |
| 1401 | getlocvar(fs, varidx)->startpc = fs->pc; | ||
| 1252 | } | 1402 | } |
| 1253 | 1403 | ||
| 1254 | 1404 | ||
| 1255 | static void localstat (LexState *ls) { | 1405 | static void localstat (LexState *ls) { |
| 1256 | /* stat -> LOCAL NAME {`,' NAME} [`=' explist1] */ | 1406 | /* stat -> LOCAL NAME {`,' NAME} [`=' explist] */ |
| 1257 | int nvars = 0; | 1407 | int nvars = 0; |
| 1258 | int nexps; | 1408 | int nexps; |
| 1259 | expdesc e; | 1409 | expdesc e; |
| @@ -1262,7 +1412,7 @@ static void localstat (LexState *ls) { · 2 unmodified lines | |||
| 1262 | nvars++; | 1412 | nvars++; |
| 1263 | } while (testnext(ls, ',')); | 1413 | } while (testnext(ls, ',')); |
| 1264 | if (testnext(ls, '=')) | 1414 | if (testnext(ls, '=')) |
| 1265 | nexps = explist1(ls, &e); | 1415 | nexps = explist(ls, &e); |
| 1266 | else { | 1416 | else { |
| 1267 | e.k = VVOID; | 1417 | e.k = VVOID; |
| 1268 | nexps = 0; | 1418 | nexps = 0; |
| @@ -1274,25 +1424,25 @@ static void localstat (LexState *ls) { · 5 unmodified lines | |||
| 1274 | 1424 | ||
| 1275 | static int funcname (LexState *ls, expdesc *v) { | 1425 | static int funcname (LexState *ls, expdesc *v) { |
| 1276 | /* funcname -> NAME {fieldsel} [`:' NAME] */ | 1426 | /* funcname -> NAME {fieldsel} [`:' NAME] */ |
| 1277 | int needself = 0; | 1427 | int ismethod = 0; |
| 1278 | singlevar(ls, v); | 1428 | singlevar(ls, v); |
| 1279 | while (ls->t.token == '.') | 1429 | while (ls->t.token == '.') |
| 1280 | fieldsel(ls, v); | 1430 | fieldsel(ls, v); |
| 1281 | if (ls->t.token == ':') { | 1431 | if (ls->t.token == ':') { |
| 1282 | needself = 1; | 1432 | ismethod = 1; |
| 1283 | fieldsel(ls, v); | 1433 | fieldsel(ls, v); |
| 1284 | } | 1434 | } |
| 1285 | return needself; | 1435 | return ismethod; |
| 1286 | } | 1436 | } |
| 1287 | 1437 | ||
| 1288 | 1438 | ||
| 1289 | static void funcstat (LexState *ls, int line) { | 1439 | static void funcstat (LexState *ls, int line) { |
| 1290 | /* funcstat -> FUNCTION funcname body */ | 1440 | /* funcstat -> FUNCTION funcname body */ |
| 1291 | int needself; | 1441 | int ismethod; |
| 1292 | expdesc v, b; | 1442 | expdesc v, b; |
| 1293 | luaX_next(ls); /* skip FUNCTION */ | 1443 | luaX_next(ls); /* skip FUNCTION */ |
| 1294 | needself = funcname(ls, &v); | 1444 | ismethod = funcname(ls, &v); |
| 1295 | body(ls, &b, needself, line); | 1445 | body(ls, &b, ismethod, line); |
| 1296 | luaK_storevar(ls->fs, &v, &b); | 1446 | luaK_storevar(ls->fs, &v, &b); |
| 1297 | luaK_fixline(ls->fs, line); /* definition `happens' in the first line */ | 1447 | luaK_fixline(ls->fs, line); /* definition `happens' in the first line */ |
| 1298 | } | 1448 | } |
| @@ -1313,14 +1463,14 @@ static void exprstat (LexState *ls) { · 14 unmodified lines | |||
| 1313 | 1463 | ||
| 1314 | 1464 | ||
| 1315 | static void retstat (LexState *ls) { | 1465 | static void retstat (LexState *ls) { |
| 1316 | /* stat -> RETURN explist */ | 1466 | /* stat -> RETURN [explist] [';'] */ |
| 1317 | FuncState *fs = ls->fs; | 1467 | FuncState *fs = ls->fs; |
| 1318 | expdesc e; | 1468 | expdesc e; |
| 1319 | int first, nret; /* registers with returned values */ | 1469 | int first, nret; /* registers with returned values */ |
| 1320 | if (block_follow(ls->t.token) || ls->t.token == ';') | 1470 | if (block_follow(ls, 1) || ls->t.token == ';') |
| 1321 | first = nret = 0; /* return no values */ | 1471 | first = nret = 0; /* return no values */ |
| 1322 | else { | 1472 | else { |
| 1323 | nret = explist1(ls, &e); /* optional return values */ | 1473 | nret = explist(ls, &e); /* optional return values */ |
| 1324 | if (hasmultret(e.k)) { | 1474 | if (hasmultret(e.k)) { |
| 1325 | luaK_setmultret(fs, &e); | 1475 | luaK_setmultret(fs, &e); |
| 1326 | if (e.k == VCALL && nret == 1) { /* tail call? */ | 1476 | if (e.k == VCALL && nret == 1) { /* tail call? */ |
| @@ -1341,41 +1491,43 @@ static void retstat (LexState *ls) { · 14 unmodified lines | |||
| 1341 | } | 1491 | } |
| 1342 | } | 1492 | } |
| 1343 | luaK_ret(fs, first, nret); | 1493 | luaK_ret(fs, first, nret); |
| 1494 | testnext(ls, ';'); /* skip optional semicolon */ | ||
| 1344 | } | 1495 | } |
| 1345 | 1496 | ||
| 1346 | 1497 | ||
| 1347 | static int statement (LexState *ls) { | 1498 | static void statement (LexState *ls) { |
| 1348 | int line = ls->linenumber; /* may be needed for error messages */ | 1499 | int line = ls->linenumber; /* may be needed for error messages */ |
| 1500 | enterlevel(ls); | ||
| 1349 | switch (ls->t.token) { | 1501 | switch (ls->t.token) { |
| 1350 | case ';': { /* stat -> ';' (empty statement) */ | 1502 | case ';': { /* stat -> ';' (empty statement) */ |
| 1351 | luaX_next(ls); /* skip ';' */ | 1503 | luaX_next(ls); /* skip ';' */ |
| 1352 | return 0; | 1504 | break; |
| 1353 | } | 1505 | } |
| 1354 | case TK_IF: { /* stat -> ifstat */ | 1506 | case TK_IF: { /* stat -> ifstat */ |
| 1355 | ifstat(ls, line); | 1507 | ifstat(ls, line); |
| 1356 | return 0; | 1508 | break; |
| 1357 | } | 1509 | } |
| 1358 | case TK_WHILE: { /* stat -> whilestat */ | 1510 | case TK_WHILE: { /* stat -> whilestat */ |
| 1359 | whilestat(ls, line); | 1511 | whilestat(ls, line); |
| 1360 | return 0; | 1512 | break; |
| 1361 | } | 1513 | } |
| 1362 | case TK_DO: { /* stat -> DO block END */ | 1514 | case TK_DO: { /* stat -> DO block END */ |
| 1363 | luaX_next(ls); /* skip DO */ | 1515 | luaX_next(ls); /* skip DO */ |
| 1364 | block(ls); | 1516 | block(ls); |
| 1365 | check_match(ls, TK_END, TK_DO, line); | 1517 | check_match(ls, TK_END, TK_DO, line); |
| 1366 | return 0; | 1518 | break; |
| 1367 | } | 1519 | } |
| 1368 | case TK_FOR: { /* stat -> forstat */ | 1520 | case TK_FOR: { /* stat -> forstat */ |
| 1369 | forstat(ls, line); | 1521 | forstat(ls, line); |
| 1370 | return 0; | 1522 | break; |
| 1371 | } | 1523 | } |
| 1372 | case TK_REPEAT: { /* stat -> repeatstat */ | 1524 | case TK_REPEAT: { /* stat -> repeatstat */ |
| 1373 | repeatstat(ls, line); | 1525 | repeatstat(ls, line); |
| 1374 | return 0; | 1526 | break; |
| 1375 | } | 1527 | } |
| 1376 | case TK_FUNCTION: { /* stat -> funcstat */ | 1528 | case TK_FUNCTION: { /* stat -> funcstat */ |
| 1377 | funcstat(ls, line); | 1529 | funcstat(ls, line); |
| 1378 | return 0; | 1530 | break; |
| 1379 | } | 1531 | } |
| 1380 | case TK_LOCAL: { /* stat -> localstat */ | 1532 | case TK_LOCAL: { /* stat -> localstat */ |
| 1381 | luaX_next(ls); /* skip LOCAL */ | 1533 | luaX_next(ls); /* skip LOCAL */ |
| @@ -1383,39 +1535,62 @@ static int statement (LexState *ls) { · 1 unmodified line | |||
| 1383 | localfunc(ls); | 1535 | localfunc(ls); |
| 1384 | else | 1536 | else |
| 1385 | localstat(ls); | 1537 | localstat(ls); |
| 1386 | return 0; | 1538 | break; |
| 1539 | } | ||
| 1540 | case '@': { /* stat -> label */ | ||
| 1541 | luaX_next(ls); /* skip '@' */ | ||
| 1542 | labelstat(ls, str_checkname(ls), line); | ||
| 1543 | break; | ||
| 1387 | } | 1544 | } |
| 1388 | case TK_RETURN: { /* stat -> retstat */ | 1545 | case TK_RETURN: { /* stat -> retstat */ |
| 1389 | luaX_next(ls); /* skip RETURN */ | 1546 | luaX_next(ls); /* skip RETURN */ |
| 1390 | retstat(ls); | 1547 | retstat(ls); |
| 1391 | return 1; /* must be last statement */ | 1548 | break; |
| 1392 | } | 1549 | } |
| 1393 | case TK_BREAK: { /* stat -> breakstat */ | 1550 | case TK_BREAK: { /* stat -> breakstat */ |
| 1394 | luaX_next(ls); /* skip BREAK */ | 1551 | luaX_next(ls); /* skip BREAK */ |
| 1395 | breakstat(ls); | 1552 | /* code it as "goto 'break'" */ |
| 1396 | return 1; /* must be last statement */ | 1553 | gotostat(ls, luaS_new(ls->L, "break"), line); |
| 1554 | break; | ||
| 1555 | } | ||
| 1556 | case TK_GOTO: { /* stat -> 'goto' NAME */ | ||
| 1557 | luaX_next(ls); /* skip GOTO */ | ||
| 1558 | gotostat(ls, str_checkname(ls), line); | ||
| 1559 | break; | ||
| 1397 | } | 1560 | } |
| 1398 | default: { /* stat -> func | assignment */ | 1561 | default: { /* stat -> func | assignment */ |
| 1399 | exprstat(ls); | 1562 | exprstat(ls); |
| 1400 | return 0; | 1563 | break; |
| 1401 | } | 1564 | } |
| 1402 | } | 1565 | } |
| 1566 | lua_assert(ls->fs->f->maxstacksize >= ls->fs->freereg && | ||
| 1567 | ls->fs->freereg >= ls->fs->nactvar); | ||
| 1568 | ls->fs->freereg = ls->fs->nactvar; /* free registers */ | ||
| 1569 | leavelevel(ls); | ||
| 1403 | } | 1570 | } |
| 1404 | 1571 | ||
| 1572 | /* }====================================================================== */ | ||
| 1405 | 1573 | ||
| 1406 | static void chunk (LexState *ls) { | 1574 | |
| 1407 | /* chunk -> { stat [`;'] } */ | 1575 | Proto *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff, |
| 1408 | int islast = 0; | 1576 | Dyndata *dyd, const char *name, int firstchar) { |
| 1409 | enterlevel(ls); | 1577 | LexState lexstate; |
| 1410 | while (!islast && !block_follow(ls->t.token)) { | 1578 | FuncState funcstate; |
| 1411 | islast = statement(ls); | 1579 | BlockCnt bl; |
| 1412 | if (islast) | 1580 | TString *tname = luaS_new(L, name); |
| 1413 | testnext(ls, ';'); | 1581 | setsvalue2s(L, L->top, tname); /* push name to protect it */ |
| 1414 | lua_assert(ls->fs->f->maxstacksize >= ls->fs->freereg && | 1582 | incr_top(L); |
| 1415 | ls->fs->freereg >= ls->fs->nactvar); | 1583 | lexstate.buff = buff; |
| 1416 | ls->fs->freereg = ls->fs->nactvar; /* free registers */ | 1584 | lexstate.dyd = dyd; |
| 1417 | } | 1585 | dyd->actvar.n = dyd->gt.n = dyd->label.n = 0; |
| 1418 | leavelevel(ls); | 1586 | luaX_setinput(L, &lexstate, z, tname, firstchar); |
| 1587 | open_mainfunc(&lexstate, &funcstate, &bl); | ||
| 1588 | luaX_next(&lexstate); /* read first token */ | ||
| 1589 | statlist(&lexstate); /* main body */ | ||
| 1590 | check(&lexstate, TK_EOS); | ||
| 1591 | close_func(&lexstate); | ||
| 1592 | L->top--; /* pop name */ | ||
| 1593 | lua_assert(!funcstate.prev && funcstate.nups == 1 && !lexstate.fs); | ||
| 1594 | return funcstate.f; | ||
| 1419 | } | 1595 | } |
| 1420 | 1596 | ||
| 1421 | /* }====================================================================== */ | ||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lparser.h,v 1.65 2010/07/07 16:27:29 roberto Exp $ | 2 | ** $Id: lparser.h,v 1.68 2011/02/23 13:13:10 roberto Exp $ |
| 3 | ** Lua Parser | 3 | ** Lua Parser |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -53,19 +53,42 @@ typedef struct expdesc { · 47 unmodified lines | |||
| 53 | } expdesc; | 53 | } expdesc; |
| 54 | 54 | ||
| 55 | 55 | ||
| 56 | typedef struct vardesc { | 56 | /* description of active local variable */ |
| 57 | unsigned short idx; | 57 | typedef struct Vardesc { |
| 58 | } vardesc; | 58 | unsigned short idx; /* variable index in stack */ |
| 59 | } Vardesc; | ||
| 59 | 60 | ||
| 60 | 61 | ||
| 61 | /* list of all active local variables */ | 62 | /* description of pending goto statements and label statements */ |
| 62 | typedef struct Varlist { | 63 | typedef struct Labeldesc { |
| 63 | vardesc *actvar; | 64 | TString *name; /* label identifier */ |
| 64 | int nactvar; | 65 | int pc; /* position in code */ |
| 65 | int actvarsize; | 66 | int line; /* line where it appeared */ |
| 66 | } Varlist; | 67 | lu_byte nactvar; /* local level where it appears in current block */ |
| 68 | } Labeldesc; | ||
| 67 | 69 | ||
| 68 | 70 | ||
| 71 | /* list of labels or gotos */ | ||
| 72 | typedef struct Labellist { | ||
| 73 | Labeldesc *arr; /* array */ | ||
| 74 | int n; /* number of entries in use */ | ||
| 75 | int size; /* array size */ | ||
| 76 | } Labellist; | ||
| 77 | |||
| 78 | |||
| 79 | /* dynamic structures used by the parser */ | ||
| 80 | typedef struct Dyndata { | ||
| 81 | struct { /* list of active local variables */ | ||
| 82 | Vardesc *arr; | ||
| 83 | int n; | ||
| 84 | int size; | ||
| 85 | } actvar; | ||
| 86 | Labellist gt; /* list of pending gotos */ | ||
| 87 | Labellist label; /* list of active labels */ | ||
| 88 | } Dyndata; | ||
| 89 | |||
| 90 | |||
| 91 | /* control of blocks */ | ||
| 69 | struct BlockCnt; /* defined in lparser.c */ | 92 | struct BlockCnt; /* defined in lparser.c */ |
| 70 | 93 | ||
| 71 | 94 | ||
| @@ -91,7 +114,7 @@ typedef struct FuncState { · 19 unmodified lines | |||
| 91 | 114 | ||
| 92 | 115 | ||
| 93 | LUAI_FUNC Proto *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff, | 116 | LUAI_FUNC Proto *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff, |
| 94 | Varlist *varl, const char *name); | 117 | Dyndata *dyd, const char *name, int firstchar); |
| 95 | 118 | ||
| 96 | 119 | ||
| 97 | #endif | 120 | #endif |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lstate.c,v 2.86 2010/09/03 14:14:01 roberto Exp $ | 2 | ** $Id: lstate.c,v 2.89 2010/12/20 19:40:07 roberto Exp $ |
| 3 | ** Global State | 3 | ** Global State |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -65,11 +65,14 @@ typedef struct LG { · 59 unmodified lines | |||
| 65 | #define fromstate(L) (cast(LX *, cast(lu_byte *, (L)) - offsetof(LX, l))) | 65 | #define fromstate(L) (cast(LX *, cast(lu_byte *, (L)) - offsetof(LX, l))) |
| 66 | 66 | ||
| 67 | 67 | ||
| 68 | |||
| 69 | /* | 68 | /* |
| 70 | ** maximum number of nested calls made by error-handling function | 69 | ** set GCdebt to a new value keeping the value (totalbytes + GCdebt) |
| 70 | ** invariant | ||
| 71 | */ | 71 | */ |
| 72 | #define LUAI_EXTRACALLS 10 | 72 | void luaE_setdebt (global_State *g, l_mem debt) { |
| 73 | g->totalbytes -= (debt - g->GCdebt); | ||
| 74 | g->GCdebt = debt; | ||
| 75 | } | ||
| 73 | 76 | ||
| 74 | 77 | ||
| 75 | CallInfo *luaE_extendCI (lua_State *L) { | 78 | CallInfo *luaE_extendCI (lua_State *L) { |
| @@ -154,7 +157,7 @@ static void f_luaopen (lua_State *L, void *ud) { · 78 unmodified lines | |||
| 154 | /* pre-create memory-error message */ | 157 | /* pre-create memory-error message */ |
| 155 | g->memerrmsg = luaS_newliteral(L, MEMERRMSG); | 158 | g->memerrmsg = luaS_newliteral(L, MEMERRMSG); |
| 156 | luaS_fix(g->memerrmsg); /* it should never be collected */ | 159 | luaS_fix(g->memerrmsg); /* it should never be collected */ |
| 157 | g->GCdebt = 0; | 160 | g->gcrunning = 1; /* allow gc */ |
| 158 | } | 161 | } |
| 159 | 162 | ||
| 160 | 163 | ||
| @@ -187,7 +190,7 @@ static void close_state (lua_State *L) { · 26 unmodified lines | |||
| 187 | luaM_freearray(L, G(L)->strt.hash, G(L)->strt.size); | 190 | luaM_freearray(L, G(L)->strt.hash, G(L)->strt.size); |
| 188 | luaZ_freebuffer(L, &g->buff); | 191 | luaZ_freebuffer(L, &g->buff); |
| 189 | freestack(L); | 192 | freestack(L); |
| 190 | lua_assert(g->totalbytes == sizeof(LG)); | 193 | lua_assert(gettotalbytes(g) == sizeof(LG)); |
| 191 | (*g->frealloc)(g->ud, fromstate(L), sizeof(LG), 0); | 194 | (*g->frealloc)(g->ud, fromstate(L), sizeof(LG), 0); |
| 192 | } | 195 | } |
| 193 | 196 | ||
| @@ -241,7 +244,7 @@ LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) { · 47 unmodified lines | |||
| 241 | g->mainthread = L; | 244 | g->mainthread = L; |
| 242 | g->uvhead.u.l.prev = &g->uvhead; | 245 | g->uvhead.u.l.prev = &g->uvhead; |
| 243 | g->uvhead.u.l.next = &g->uvhead; | 246 | g->uvhead.u.l.next = &g->uvhead; |
| 244 | stopgc(g); /* no GC while building state */ | 247 | g->gcrunning = 0; /* no GC while building state */ |
| 245 | g->lastmajormem = 0; | 248 | g->lastmajormem = 0; |
| 246 | g->strt.size = 0; | 249 | g->strt.size = 0; |
| 247 | g->strt.nuse = 0; | 250 | g->strt.nuse = 0; |
| @@ -252,11 +255,12 @@ LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) { · 4 unmodified lines | |||
| 252 | g->version = lua_version(NULL); | 255 | g->version = lua_version(NULL); |
| 253 | g->gcstate = GCSpause; | 256 | g->gcstate = GCSpause; |
| 254 | g->allgc = NULL; | 257 | g->allgc = NULL; |
| 255 | g->udgc = NULL; | 258 | g->finobj = NULL; |
| 256 | g->tobefnz = NULL; | 259 | g->tobefnz = NULL; |
| 257 | g->gray = g->grayagain = NULL; | 260 | g->gray = g->grayagain = NULL; |
| 258 | g->weak = g->ephemeron = g->allweak = NULL; | 261 | g->weak = g->ephemeron = g->allweak = NULL; |
| 259 | g->totalbytes = sizeof(LG); | 262 | g->totalbytes = sizeof(LG); |
| 263 | g->GCdebt = 0; | ||
| 260 | g->gcpause = LUAI_GCPAUSE; | 264 | g->gcpause = LUAI_GCPAUSE; |
| 261 | g->gcmajorinc = LUAI_GCMAJOR; | 265 | g->gcmajorinc = LUAI_GCMAJOR; |
| 262 | g->gcstepmul = LUAI_GCMUL; | 266 | g->gcstepmul = LUAI_GCMUL; |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lstate.h,v 2.68 2010/10/29 17:52:46 roberto Exp $ | 2 | ** $Id: lstate.h,v 2.72 2011/06/02 19:31:40 roberto Exp $ |
| 3 | ** Global State | 3 | ** Global State |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -32,9 +32,9 @@ · 26 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->udgc. | 35 | ** Objects with finalizers are kept in the list g->finobj. |
| 36 | ** | 36 | ** |
| 37 | ** The list g->tobefnz links all userdata being finalized. | 37 | ** The list g->tobefnz links all objects being finalized. |
| 38 | 38 | ||
| 39 | */ | 39 | */ |
| 40 | 40 | ||
| @@ -104,7 +104,6 @@ typedef struct CallInfo { · 63 unmodified lines | |||
| 104 | #define CIST_TAIL (1<<6) /* call was tail called */ | 104 | #define CIST_TAIL (1<<6) /* call was tail called */ |
| 105 | 105 | ||
| 106 | 106 | ||
| 107 | #define ci_func(ci) (clvalue((ci)->func)) | ||
| 108 | #define isLua(ci) ((ci)->callstatus & CIST_LUA) | 107 | #define isLua(ci) ((ci)->callstatus & CIST_LUA) |
| 109 | 108 | ||
| 110 | 109 | ||
| @@ -114,8 +113,8 @@ typedef struct CallInfo { · 3 unmodified lines | |||
| 114 | typedef struct global_State { | 113 | typedef struct global_State { |
| 115 | lua_Alloc frealloc; /* function to reallocate memory */ | 114 | lua_Alloc frealloc; /* function to reallocate memory */ |
| 116 | void *ud; /* auxiliary data to `frealloc' */ | 115 | void *ud; /* auxiliary data to `frealloc' */ |
| 117 | lu_mem totalbytes; /* number of bytes currently allocated */ | 116 | lu_mem totalbytes; /* number of bytes currently allocated - GCdebt */ |
| 118 | l_mem GCdebt; /* when positive, run a GC step */ | 117 | l_mem GCdebt; /* bytes allocated not yet compensated by the collector */ |
| 119 | lu_mem lastmajormem; /* memory in use after last major collection */ | 118 | lu_mem lastmajormem; /* memory in use after last major collection */ |
| 120 | stringtable strt; /* hash table for strings */ | 119 | stringtable strt; /* hash table for strings */ |
| 121 | TValue l_registry; | 120 | TValue l_registry; |
| @@ -123,9 +122,10 @@ typedef struct global_State { · 1 unmodified line | |||
| 123 | lu_byte currentwhite; | 122 | lu_byte currentwhite; |
| 124 | lu_byte gcstate; /* state of garbage collector */ | 123 | lu_byte gcstate; /* state of garbage collector */ |
| 125 | lu_byte gckind; /* kind of GC running */ | 124 | lu_byte gckind; /* kind of GC running */ |
| 125 | lu_byte gcrunning; /* true if GC is running */ | ||
| 126 | int sweepstrgc; /* position of sweep in `strt' */ | 126 | int sweepstrgc; /* position of sweep in `strt' */ |
| 127 | GCObject *allgc; /* list of all collectable objects */ | 127 | GCObject *allgc; /* list of all collectable objects */ |
| 128 | GCObject *udgc; /* list of collectable userdata with finalizers */ | 128 | GCObject *finobj; /* list of collectable objects with finalizers */ |
| 129 | GCObject **sweepgc; /* current position of sweep */ | 129 | GCObject **sweepgc; /* current position of sweep */ |
| 130 | GCObject *gray; /* list of gray objects */ | 130 | GCObject *gray; /* list of gray objects */ |
| 131 | GCObject *grayagain; /* list of objects to be traversed atomically */ | 131 | GCObject *grayagain; /* list of objects to be traversed atomically */ |
| @@ -209,6 +209,10 @@ union GCObject { · 77 unmodified lines | |||
| 209 | #define obj2gco(v) (cast(GCObject *, (v))) | 209 | #define obj2gco(v) (cast(GCObject *, (v))) |
| 210 | 210 | ||
| 211 | 211 | ||
| 212 | /* actual number of total bytes allocated */ | ||
| 213 | #define gettotalbytes(g) ((g)->totalbytes + (g)->GCdebt) | ||
| 214 | |||
| 215 | LUAI_FUNC void luaE_setdebt (global_State *g, l_mem debt); | ||
| 212 | LUAI_FUNC void luaE_freethread (lua_State *L, lua_State *L1); | 216 | LUAI_FUNC void luaE_freethread (lua_State *L, lua_State *L1); |
| 213 | LUAI_FUNC CallInfo *luaE_extendCI (lua_State *L); | 217 | LUAI_FUNC CallInfo *luaE_extendCI (lua_State *L); |
| 214 | LUAI_FUNC void luaE_freeCI (lua_State *L); | 218 | LUAI_FUNC void luaE_freeCI (lua_State *L); |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lstring.c,v 2.18 2010/05/10 18:23:45 roberto Exp $ | 2 | ** $Id: lstring.c,v 2.19 2011/05/03 16:01:57 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 | */ |
| @@ -84,8 +84,9 @@ TString *luaS_newlstr (lua_State *L, const char *str, size_t l) { · 78 unmodified lines | |||
| 84 | o != NULL; | 84 | o != NULL; |
| 85 | o = gch(o)->next) { | 85 | o = gch(o)->next) { |
| 86 | TString *ts = rawgco2ts(o); | 86 | TString *ts = rawgco2ts(o); |
| 87 | if (h == ts->tsv.hash && ts->tsv.len == l && | 87 | if (h == ts->tsv.hash && |
| 88 | (memcmp(str, getstr(ts), l) == 0)) { | 88 | ts->tsv.len == l && |
| 89 | (memcmp(str, getstr(ts), l * sizeof(char)) == 0)) { | ||
| 89 | if (isdead(G(L), o)) /* string is dead (but was not collected yet)? */ | 90 | if (isdead(G(L), o)) /* string is dead (but was not collected yet)? */ |
| 90 | changewhite(o); /* resurrect it */ | 91 | changewhite(o); /* resurrect it */ |
| 91 | return ts; | 92 | return ts; |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lstrlib.c,v 1.159 2010/11/19 16:25:51 roberto Exp $ | 2 | ** $Id: lstrlib.c,v 1.168 2011/06/09 18:22:47 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 | */ |
| @@ -45,7 +45,7 @@ static int str_len (lua_State *L) { · 39 unmodified lines | |||
| 45 | /* translate a relative string position: negative means back from end */ | 45 | /* translate a relative string position: negative means back from end */ |
| 46 | static size_t posrelat (ptrdiff_t pos, size_t len) { | 46 | static size_t posrelat (ptrdiff_t pos, size_t len) { |
| 47 | if (pos >= 0) return (size_t)pos; | 47 | if (pos >= 0) return (size_t)pos; |
| 48 | else if (pos == -pos || (size_t)-pos > len) return 0; | 48 | else if (-(size_t)pos > len) return 0; |
| 49 | else return len - ((size_t)-pos) + 1; | 49 | else return len - ((size_t)-pos) + 1; |
| 50 | } | 50 | } |
| 51 | 51 | ||
| @@ -101,15 +101,29 @@ static int str_upper (lua_State *L) { · 49 unmodified lines | |||
| 101 | return 1; | 101 | return 1; |
| 102 | } | 102 | } |
| 103 | 103 | ||
| 104 | |||
| 105 | /* reasonable limit to avoid arithmetic overflow */ | ||
| 106 | #define MAXSIZE ((~(size_t)0) >> 1) | ||
| 107 | |||
| 104 | static int str_rep (lua_State *L) { | 108 | static int str_rep (lua_State *L) { |
| 105 | size_t l; | 109 | size_t l, lsep; |
| 106 | luaL_Buffer b; | ||
| 107 | const char *s = luaL_checklstring(L, 1, &l); | 110 | const char *s = luaL_checklstring(L, 1, &l); |
| 108 | int n = luaL_checkint(L, 2); | 111 | int n = luaL_checkint(L, 2); |
| 109 | luaL_buffinit(L, &b); | 112 | const char *sep = luaL_optlstring(L, 3, "", &lsep); |
| 110 | while (n-- > 0) | 113 | if (n <= 0) lua_pushliteral(L, ""); |
| 111 | luaL_addlstring(&b, s, l); | 114 | else if (l + lsep < l || l + lsep >= MAXSIZE / n) /* may overflow? */ |
| 112 | luaL_pushresult(&b); | 115 | return luaL_error(L, "resulting string too large"); |
| 116 | else { | ||
| 117 | size_t totallen = n * l + (n - 1) * lsep; | ||
| 118 | luaL_Buffer b; | ||
| 119 | char *p = luaL_buffinitsize(L, &b, totallen); | ||
| 120 | while (n-- > 1) { /* first n-1 copies (followed by separator) */ | ||
| 121 | memcpy(p, s, l * sizeof(char)); p += l; | ||
| 122 | memcpy(p, sep, lsep * sizeof(char)); p += lsep; | ||
| 123 | } | ||
| 124 | memcpy(p, s, l * sizeof(char)); /* last copy (not followed by separator) */ | ||
| 125 | luaL_pushresultsize(&b, totallen); | ||
| 126 | } | ||
| 113 | return 1; | 127 | return 1; |
| 114 | } | 128 | } |
| 115 | 129 | ||
| @@ -125,7 +139,7 @@ static int str_byte (lua_State *L) { · 9 unmodified lines | |||
| 125 | if (posi > pose) return 0; /* empty interval; return no values */ | 139 | if (posi > pose) return 0; /* empty interval; return no values */ |
| 126 | n = (int)(pose - posi + 1); | 140 | n = (int)(pose - posi + 1); |
| 127 | if (posi + n <= pose) /* overflow? */ | 141 | if (posi + n <= pose) /* overflow? */ |
| 128 | luaL_error(L, "string slice too long"); | 142 | return luaL_error(L, "string slice too long"); |
| 129 | luaL_checkstack(L, n, "string slice too long"); | 143 | luaL_checkstack(L, n, "string slice too long"); |
| 130 | for (i=0; i<n; i++) | 144 | for (i=0; i<n; i++) |
| 131 | lua_pushinteger(L, uchar(s[posi+i-1])); | 145 | lua_pushinteger(L, uchar(s[posi+i-1])); |
| @@ -161,7 +175,7 @@ static int str_dump (lua_State *L) { · 29 unmodified lines | |||
| 161 | lua_settop(L, 1); | 175 | lua_settop(L, 1); |
| 162 | luaL_buffinit(L,&b); | 176 | luaL_buffinit(L,&b); |
| 163 | if (lua_dump(L, writer, &b) != 0) | 177 | if (lua_dump(L, writer, &b) != 0) |
| 164 | luaL_error(L, "unable to dump given function"); | 178 | return luaL_error(L, "unable to dump given function"); |
| 165 | luaL_pushresult(&b); | 179 | luaL_pushresult(&b); |
| 166 | return 1; | 180 | return 1; |
| 167 | } | 181 | } |
| @@ -510,7 +524,7 @@ static int nospecials (const char *p, size_t l) { · 342 unmodified lines | |||
| 510 | size_t upto = 0; | 524 | size_t upto = 0; |
| 511 | do { | 525 | do { |
| 512 | if (strpbrk(p + upto, SPECIALS)) | 526 | if (strpbrk(p + upto, SPECIALS)) |
| 513 | return 0; /* pattern has a special character */ | 527 | return 0; /* pattern has a special character */ |
| 514 | upto += strlen(p + upto) + 1; /* may have more after \0 */ | 528 | upto += strlen(p + upto) + 1; /* may have more after \0 */ |
| 515 | } while (upto <= l); | 529 | } while (upto <= l); |
| 516 | return 1; /* no special chars found */ | 530 | return 1; /* no special chars found */ |
| @@ -729,7 +743,7 @@ static int str_gsub (lua_State *L) { · 212 unmodified lines | |||
| 729 | ** the previous length | 743 | ** the previous length |
| 730 | */ | 744 | */ |
| 731 | #if !defined(LUA_INTFRMLEN) /* { */ | 745 | #if !defined(LUA_INTFRMLEN) /* { */ |
| 732 | #if defined(LUA_USELONGLONG) | 746 | #if defined(LUA_USE_LONGLONG) |
| 733 | 747 | ||
| 734 | #define LUA_INTFRMLEN "ll" | 748 | #define LUA_INTFRMLEN "ll" |
| 735 | #define LUA_INTFRM_T long long | 749 | #define LUA_INTFRM_T long long |
| @@ -794,7 +808,7 @@ static void addquoted (lua_State *L, luaL_Buffer *b, int arg) { · 58 unmodified lines | |||
| 794 | static const char *scanformat (lua_State *L, const char *strfrmt, char *form) { | 808 | static const char *scanformat (lua_State *L, const char *strfrmt, char *form) { |
| 795 | const char *p = strfrmt; | 809 | const char *p = strfrmt; |
| 796 | while (*p != '\0' && strchr(FLAGS, *p) != NULL) p++; /* skip flags */ | 810 | while (*p != '\0' && strchr(FLAGS, *p) != NULL) p++; /* skip flags */ |
| 797 | if ((size_t)(p - strfrmt) >= sizeof(FLAGS)) | 811 | if ((size_t)(p - strfrmt) >= sizeof(FLAGS)/sizeof(char)) |
| 798 | luaL_error(L, "invalid format (repeated flags)"); | 812 | luaL_error(L, "invalid format (repeated flags)"); |
| 799 | if (isdigit(uchar(*p))) p++; /* skip width */ | 813 | if (isdigit(uchar(*p))) p++; /* skip width */ |
| 800 | if (isdigit(uchar(*p))) p++; /* (2 digits at most) */ | 814 | if (isdigit(uchar(*p))) p++; /* (2 digits at most) */ |
| @@ -806,7 +820,7 @@ static const char *scanformat (lua_State *L, const char *strfrmt, char *form) { · 5 unmodified lines | |||
| 806 | if (isdigit(uchar(*p))) | 820 | if (isdigit(uchar(*p))) |
| 807 | luaL_error(L, "invalid format (width or precision too long)"); | 821 | luaL_error(L, "invalid format (width or precision too long)"); |
| 808 | *(form++) = '%'; | 822 | *(form++) = '%'; |
| 809 | memcpy(form, strfrmt, p - strfrmt + 1); | 823 | memcpy(form, strfrmt, (p - strfrmt + 1) * sizeof(char)); |
| 810 | form += p - strfrmt + 1; | 824 | form += p - strfrmt + 1; |
| 811 | *form = '\0'; | 825 | *form = '\0'; |
| 812 | return p; | 826 | return p; |
| @@ -861,6 +875,9 @@ static int str_format (lua_State *L) { · 48 unmodified lines | |||
| 861 | break; | 875 | break; |
| 862 | } | 876 | } |
| 863 | case 'e': case 'E': case 'f': | 877 | case 'e': case 'E': case 'f': |
| 878 | #if defined(LUA_USE_AFORMAT) | ||
| 879 | case 'a': case 'A': | ||
| 880 | #endif | ||
| 864 | case 'g': case 'G': { | 881 | case 'g': case 'G': { |
| 865 | addlenmod(form, LUA_FLTFRMLEN); | 882 | addlenmod(form, LUA_FLTFRMLEN); |
| 866 | nb = sprintf(buff, form, (LUA_FLTFRM_T)luaL_checknumber(L, arg)); | 883 | nb = sprintf(buff, form, (LUA_FLTFRM_T)luaL_checknumber(L, arg)); |
| @@ -872,16 +889,16 @@ static int str_format (lua_State *L) { · 5 unmodified lines | |||
| 872 | } | 889 | } |
| 873 | case 's': { | 890 | case 's': { |
| 874 | size_t l; | 891 | size_t l; |
| 875 | const char *s = luaL_checklstring(L, arg, &l); | 892 | const char *s = luaL_tolstring(L, arg, &l); |
| 876 | if (!strchr(form, '.') && l >= 100) { | 893 | if (!strchr(form, '.') && l >= 100) { |
| 877 | /* no precision and string is too long to be formatted; | 894 | /* no precision and string is too long to be formatted; |
| 878 | keep original string */ | 895 | keep original string */ |
| 879 | lua_pushvalue(L, arg); | ||
| 880 | luaL_addvalue(&b); | 896 | luaL_addvalue(&b); |
| 881 | break; | 897 | break; |
| 882 | } | 898 | } |
| 883 | else { | 899 | else { |
| 884 | nb = sprintf(buff, form, s); | 900 | nb = sprintf(buff, form, s); |
| 901 | lua_pop(L, 1); /* remove result from 'luaL_tolstring' */ | ||
| 885 | break; | 902 | break; |
| 886 | } | 903 | } |
| 887 | } | 904 | } |
| @@ -900,6 +917,15 @@ static int str_format (lua_State *L) { · 12 unmodified lines | |||
| 900 | /* }====================================================== */ | 917 | /* }====================================================== */ |
| 901 | 918 | ||
| 902 | 919 | ||
| 920 | static int noindex (lua_State *L) { | ||
| 921 | const char *f = lua_tostring(L, 2); | ||
| 922 | if (f) | ||
| 923 | return luaL_error(L, "no field '%s' in strings", f); | ||
| 924 | else | ||
| 925 | return luaL_error(L, "no such field in strings"); | ||
| 926 | } | ||
| 927 | |||
| 928 | |||
| 903 | static const luaL_Reg strlib[] = { | 929 | static const luaL_Reg strlib[] = { |
| 904 | {"byte", str_byte}, | 930 | {"byte", str_byte}, |
| 905 | {"char", str_char}, | 931 | {"char", str_char}, |
| @@ -915,19 +941,22 @@ static const luaL_Reg strlib[] = { · 9 unmodified lines | |||
| 915 | {"reverse", str_reverse}, | 941 | {"reverse", str_reverse}, |
| 916 | {"sub", str_sub}, | 942 | {"sub", str_sub}, |
| 917 | {"upper", str_upper}, | 943 | {"upper", str_upper}, |
| 944 | {"__index", noindex}, | ||
| 918 | {NULL, NULL} | 945 | {NULL, NULL} |
| 919 | }; | 946 | }; |
| 920 | 947 | ||
| 921 | 948 | ||
| 922 | static void createmetatable (lua_State *L) { | 949 | static void createmetatable (lua_State *L) { |
| 923 | lua_createtable(L, 0, 1); /* create metatable for strings */ | 950 | /* setmetatable("", {__index = string}) */ |
| 924 | lua_pushliteral(L, ""); /* dummy string */ | 951 | lua_pushliteral(L, ""); /* dummy string */ |
| 925 | lua_pushvalue(L, -2); | 952 | lua_createtable(L, 0, 1); /* create metatable for strings */ |
| 926 | lua_setmetatable(L, -2); /* set string metatable */ | 953 | lua_pushvalue(L, -3); /* set the string library... */ |
| 954 | lua_setfield(L, -2, "__index"); /* ...as the __index metamethod */ | ||
| 955 | lua_setmetatable(L, -2); /* set metatable for strings */ | ||
| 927 | lua_pop(L, 1); /* pop dummy string */ | 956 | lua_pop(L, 1); /* pop dummy string */ |
| 928 | lua_pushvalue(L, -2); /* string library... */ | 957 | /* setmetatable(string, string) */ |
| 929 | lua_setfield(L, -2, "__index"); /* ...is the __index metamethod */ | 958 | lua_pushvalue(L, -1); /* push string library */ |
| 930 | lua_pop(L, 1); /* pop metatable */ | 959 | lua_setmetatable(L, -2); /* set it as its own metatable */ |
| 931 | } | 960 | } |
| 932 | 961 | ||
| 933 | 962 | ||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: ltable.c,v 2.53 2010/11/11 15:38:43 roberto Exp $ | 2 | ** $Id: ltable.c,v 2.59 2011/06/09 18:23:27 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 | */ |
| @@ -33,6 +33,7 @@ · 27 unmodified lines | |||
| 33 | #include "lstate.h" | 33 | #include "lstate.h" |
| 34 | #include "lstring.h" | 34 | #include "lstring.h" |
| 35 | #include "ltable.h" | 35 | #include "ltable.h" |
| 36 | #include "lvm.h" | ||
| 36 | 37 | ||
| 37 | 38 | ||
| 38 | /* | 39 | /* |
| @@ -87,8 +88,9 @@ static Node *hashnum (const Table *t, lua_Number n) { · 48 unmodified lines | |||
| 87 | int i; | 88 | int i; |
| 88 | luai_hashnum(i, n); | 89 | luai_hashnum(i, n); |
| 89 | if (i < 0) { | 90 | if (i < 0) { |
| 90 | i = -i; /* must be a positive value */ | 91 | if ((unsigned int)i == -(unsigned int)i) |
| 91 | if (i < 0) i = 0; /* handle INT_MIN */ | 92 | i = 0; /* handle INT_MIN */ |
| 93 | i = -i; /* must be a positive value */ | ||
| 92 | } | 94 | } |
| 93 | return hashmod(t, i); | 95 | return hashmod(t, i); |
| 94 | } | 96 | } |
| @@ -148,8 +150,8 @@ static int findindex (lua_State *L, Table *t, StkId key) { · 53 unmodified lines | |||
| 148 | Node *n = mainposition(t, key); | 150 | Node *n = mainposition(t, key); |
| 149 | do { /* check whether `key' is somewhere in the chain */ | 151 | do { /* check whether `key' is somewhere in the chain */ |
| 150 | /* key may be dead already, but it is ok to use it in `next' */ | 152 | /* key may be dead already, but it is ok to use it in `next' */ |
| 151 | if (luaO_rawequalObj(gkey(n), key) || | 153 | if (luaV_rawequalobj(gkey(n), key) || |
| 152 | (ttype(gkey(n)) == LUA_TDEADKEY && iscollectable(key) && | 154 | (ttisdeadkey(gkey(n)) && iscollectable(key) && |
| 153 | gcvalue(gkey(n)) == gcvalue(key))) { | 155 | gcvalue(gkey(n)) == gcvalue(key))) { |
| 154 | i = cast_int(n - gnode(t, 0)); /* key index in hash table */ | 156 | i = cast_int(n - gnode(t, 0)); /* key index in hash table */ |
| 155 | /* hash elements are numbered after array ones */ | 157 | /* hash elements are numbered after array ones */ |
| @@ -336,7 +338,7 @@ void luaH_resizearray (lua_State *L, Table *t, int nasize) { · 180 unmodified lines | |||
| 336 | 338 | ||
| 337 | static void rehash (lua_State *L, Table *t, const TValue *ek) { | 339 | static void rehash (lua_State *L, Table *t, const TValue *ek) { |
| 338 | int nasize, na; | 340 | int nasize, na; |
| 339 | int nums[MAXBITS+1]; /* nums[i] = number of keys between 2^(i-1) and 2^i */ | 341 | int nums[MAXBITS+1]; /* nums[i] = number of keys with 2^(i-1) < k <= 2^i */ |
| 340 | int i; | 342 | int i; |
| 341 | int totaluse; | 343 | int totaluse; |
| 342 | for (i=0; i<=MAXBITS; i++) nums[i] = 0; /* reset counts */ | 344 | for (i=0; i<=MAXBITS; i++) nums[i] = 0; /* reset counts */ |
| @@ -467,7 +469,7 @@ const TValue *luaH_getstr (Table *t, TString *key) { · 124 unmodified lines | |||
| 467 | ** main search function | 469 | ** main search function |
| 468 | */ | 470 | */ |
| 469 | const TValue *luaH_get (Table *t, const TValue *key) { | 471 | const TValue *luaH_get (Table *t, const TValue *key) { |
| 470 | switch (ttype(key)) { | 472 | switch (ttypenv(key)) { |
| 471 | case LUA_TNIL: return luaO_nilobject; | 473 | case LUA_TNIL: return luaO_nilobject; |
| 472 | case LUA_TSTRING: return luaH_getstr(t, rawtsvalue(key)); | 474 | case LUA_TSTRING: return luaH_getstr(t, rawtsvalue(key)); |
| 473 | case LUA_TNUMBER: { | 475 | case LUA_TNUMBER: { |
| @@ -481,7 +483,7 @@ const TValue *luaH_get (Table *t, const TValue *key) { · 7 unmodified lines | |||
| 481 | default: { | 483 | default: { |
| 482 | Node *n = mainposition(t, key); | 484 | Node *n = mainposition(t, key); |
| 483 | do { /* check whether `key' is somewhere in the chain */ | 485 | do { /* check whether `key' is somewhere in the chain */ |
| 484 | if (luaO_rawequalObj(gkey(n), key)) | 486 | if (luaV_rawequalobj(gkey(n), key)) |
| 485 | return gval(n); /* that's it */ | 487 | return gval(n); /* that's it */ |
| 486 | else n = gnext(n); | 488 | else n = gnext(n); |
| 487 | } while (n); | 489 | } while (n); |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: ltablib.c,v 1.58 2010/11/23 17:21:14 roberto Exp $ | 2 | ** $Id: ltablib.c,v 1.59 2010/12/17 12:15:34 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 | */ |
| @@ -17,7 +17,7 @@ · 11 unmodified lines | |||
| 17 | 17 | ||
| 18 | 18 | ||
| 19 | #define aux_getn(L,n) \ | 19 | #define aux_getn(L,n) \ |
| 20 | (luaL_checktype(L, n, LUA_TTABLE), (int)lua_rawlen(L, n)) | 20 | (luaL_checktype(L, n, LUA_TTABLE), luaL_len(L, n)) |
| 21 | 21 | ||
| 22 | 22 | ||
| 23 | static int deprecatedfunc (lua_State *L) { | 23 | static int deprecatedfunc (lua_State *L) { |
| @@ -104,7 +104,7 @@ static int tconcat (lua_State *L) { · 80 unmodified lines | |||
| 104 | const char *sep = luaL_optlstring(L, 2, "", &lsep); | 104 | const char *sep = luaL_optlstring(L, 2, "", &lsep); |
| 105 | luaL_checktype(L, 1, LUA_TTABLE); | 105 | luaL_checktype(L, 1, LUA_TTABLE); |
| 106 | i = luaL_optint(L, 3, 1); | 106 | i = luaL_optint(L, 3, 1); |
| 107 | last = luaL_opt(L, luaL_checkint, 4, (int)lua_rawlen(L, 1)); | 107 | last = luaL_opt(L, luaL_checkint, 4, luaL_len(L, 1)); |
| 108 | luaL_buffinit(L, &b); | 108 | luaL_buffinit(L, &b); |
| 109 | for (; i < last; i++) { | 109 | for (; i < last; i++) { |
| 110 | addfield(L, &b, i); | 110 | addfield(L, &b, i); |
| @@ -143,7 +143,7 @@ static int unpack (lua_State *L) { · 32 unmodified lines | |||
| 143 | int i, e, n; | 143 | int i, e, n; |
| 144 | luaL_checktype(L, 1, LUA_TTABLE); | 144 | luaL_checktype(L, 1, LUA_TTABLE); |
| 145 | i = luaL_optint(L, 2, 1); | 145 | i = luaL_optint(L, 2, 1); |
| 146 | e = luaL_opt(L, luaL_checkint, 3, (int)lua_rawlen(L, 1)); | 146 | e = luaL_opt(L, luaL_checkint, 3, luaL_len(L, 1)); |
| 147 | if (i > e) return 0; /* empty range */ | 147 | if (i > e) return 0; /* empty range */ |
| 148 | n = e - i + 1; /* number of elements */ | 148 | n = e - i + 1; /* number of elements */ |
| 149 | if (n <= 0 || !lua_checkstack(L, n)) /* n <= 0 means arith. overflow */ | 149 | if (n <= 0 || !lua_checkstack(L, n)) /* n <= 0 means arith. overflow */ |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: ltm.c,v 2.12 2010/04/13 20:48:12 roberto Exp $ | 2 | ** $Id: ltm.c,v 2.14 2011/06/02 19:31:40 roberto Exp $ |
| 3 | ** Tag methods | 3 | ** Tag methods |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -21,11 +21,11 @@ · 15 unmodified lines | |||
| 21 | 21 | ||
| 22 | static const char udatatypename[] = "userdata"; | 22 | static const char udatatypename[] = "userdata"; |
| 23 | 23 | ||
| 24 | LUAI_DDEF const char *const luaT_typenames_[] = { | 24 | LUAI_DDEF const char *const luaT_typenames_[LUA_TOTALTAGS] = { |
| 25 | "no value", | 25 | "no value", |
| 26 | "nil", "boolean", udatatypename, "number", | 26 | "nil", "boolean", udatatypename, "number", |
| 27 | "string", "table", "function", udatatypename, "thread", | 27 | "string", "table", "function", udatatypename, "thread", |
| 28 | "proto", "upval" | 28 | "proto", "upval" /* these last two cases are used for tests only */ |
| 29 | }; | 29 | }; |
| 30 | 30 | ||
| 31 | 31 | ||
| @@ -62,7 +62,7 @@ const TValue *luaT_gettm (Table *events, TMS event, TString *ename) { · 30 unmodified lines | |||
| 62 | 62 | ||
| 63 | const TValue *luaT_gettmbyobj (lua_State *L, const TValue *o, TMS event) { | 63 | const TValue *luaT_gettmbyobj (lua_State *L, const TValue *o, TMS event) { |
| 64 | Table *mt; | 64 | Table *mt; |
| 65 | switch (ttype(o)) { | 65 | switch (ttypenv(o)) { |
| 66 | case LUA_TTABLE: | 66 | case LUA_TTABLE: |
| 67 | mt = hvalue(o)->metatable; | 67 | mt = hvalue(o)->metatable; |
| 68 | break; | 68 | break; |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: ltm.h,v 2.10 2010/04/13 20:48:12 roberto Exp $ | 2 | ** $Id: ltm.h,v 2.11 2011/02/28 17:32:10 roberto Exp $ |
| 3 | ** Tag methods | 3 | ** Tag methods |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -46,7 +46,7 @@ typedef enum { · 40 unmodified lines | |||
| 46 | #define ttypename(x) luaT_typenames_[(x) + 1] | 46 | #define ttypename(x) luaT_typenames_[(x) + 1] |
| 47 | #define objtypename(x) ttypename(ttypenv(x)) | 47 | #define objtypename(x) ttypename(ttypenv(x)) |
| 48 | 48 | ||
| 49 | LUAI_DDEC const char *const luaT_typenames_[]; | 49 | LUAI_DDEC const char *const luaT_typenames_[LUA_TOTALTAGS]; |
| 50 | 50 | ||
| 51 | 51 | ||
| 52 | LUAI_FUNC const TValue *luaT_gettm (Table *events, TMS event, TString *ename); | 52 | LUAI_FUNC const TValue *luaT_gettm (Table *events, TMS event, TString *ename); |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lua.c,v 1.194 2010/10/25 19:01:37 roberto Exp $ | 2 | ** $Id: lua.c,v 1.199 2011/05/26 16:09:40 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 | */ |
| @@ -106,13 +106,11 @@ static void laction (int i) { · 100 unmodified lines | |||
| 106 | 106 | ||
| 107 | 107 | ||
| 108 | static void print_usage (const char *badoption) { | 108 | static void print_usage (const char *badoption) { |
| 109 | if (badoption[1] == 'e' || badoption[1] == 'l') { | 109 | luai_writestringerror("%s: ", progname); |
| 110 | luai_writestringerror("%s: ", progname); | 110 | if (badoption[1] == 'e' || badoption[1] == 'l') |
| 111 | luai_writestringerror("'%s' needs argument\n", badoption); | 111 | luai_writestringerror("'%s' needs argument\n", badoption); |
| 112 | } else { | 112 | else |
| 113 | luai_writestringerror("%s: ", progname); | ||
| 114 | luai_writestringerror("unrecognized option '%s'\n", badoption); | 113 | luai_writestringerror("unrecognized option '%s'\n", badoption); |
| 115 | } | ||
| 116 | luai_writestringerror( | 114 | luai_writestringerror( |
| 117 | "usage: %s [options] [script [args]]\n" | 115 | "usage: %s [options] [script [args]]\n" |
| 118 | "Available options are:\n" | 116 | "Available options are:\n" |
| @@ -185,7 +183,8 @@ static int docall (lua_State *L, int narg, int nres) { · 66 unmodified lines | |||
| 185 | 183 | ||
| 186 | 184 | ||
| 187 | static void print_version (void) { | 185 | static void print_version (void) { |
| 188 | printf("%s\n", LUA_COPYRIGHT); | 186 | luai_writestring(LUA_COPYRIGHT, sizeof(LUA_COPYRIGHT)); |
| 187 | luai_writeline(); | ||
| 189 | } | 188 | } |
| 190 | 189 | ||
| 191 | 190 | ||
| @@ -247,14 +246,14 @@ static const char *get_prompt (lua_State *L, int firstline) { · 55 unmodified lines | |||
| 247 | } | 246 | } |
| 248 | 247 | ||
| 249 | /* mark in error messages for incomplete statements */ | 248 | /* mark in error messages for incomplete statements */ |
| 250 | #define mark "<eof>" | 249 | #define EOFMARK "<eof>" |
| 251 | #define marklen (sizeof(mark) - 1) | 250 | #define marklen (sizeof(EOFMARK)/sizeof(char) - 1) |
| 252 | 251 | ||
| 253 | static int incomplete (lua_State *L, int status) { | 252 | static int incomplete (lua_State *L, int status) { |
| 254 | if (status == LUA_ERRSYNTAX) { | 253 | if (status == LUA_ERRSYNTAX) { |
| 255 | size_t lmsg; | 254 | size_t lmsg; |
| 256 | const char *msg = lua_tolstring(L, -1, &lmsg); | 255 | const char *msg = lua_tolstring(L, -1, &lmsg); |
| 257 | if (lmsg >= marklen && strcmp(msg + lmsg - marklen, mark) == 0) { | 256 | if (lmsg >= marklen && strcmp(msg + lmsg - marklen, EOFMARK) == 0) { |
| 258 | lua_pop(L, 1); | 257 | lua_pop(L, 1); |
| 259 | return 1; | 258 | return 1; |
| 260 | } | 259 | } |
| @@ -322,7 +321,7 @@ static void dotty (lua_State *L) { · 61 unmodified lines | |||
| 322 | } | 321 | } |
| 323 | } | 322 | } |
| 324 | lua_settop(L, 0); /* clear stack */ | 323 | lua_settop(L, 0); /* clear stack */ |
| 325 | luai_writestring("\n", 1); | 324 | luai_writeline(); |
| 326 | progname = oldprogname; | 325 | progname = oldprogname; |
| 327 | } | 326 | } |
| 328 | 327 | ||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lua.h,v 1.276 2010/10/26 19:32:19 roberto Exp $ | 2 | ** $Id: lua.h,v 1.277 2011/04/18 14:15:48 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 |
| @@ -18,12 +18,12 @@ · 12 unmodified lines | |||
| 18 | 18 | ||
| 19 | #define LUA_VERSION_MAJOR "5" | 19 | #define LUA_VERSION_MAJOR "5" |
| 20 | #define LUA_VERSION_MINOR "2" | 20 | #define LUA_VERSION_MINOR "2" |
| 21 | #define LUA_VERSION_RELEASE "0" " (alpha)" | 21 | #define LUA_VERSION_RELEASE "0" " (beta)" |
| 22 | 22 | ||
| 23 | #define LUA_VERSION "Lua " LUA_VERSION_MAJOR "." LUA_VERSION_MINOR | 23 | #define LUA_VERSION "Lua " LUA_VERSION_MAJOR "." LUA_VERSION_MINOR |
| 24 | #define LUA_RELEASE LUA_VERSION "." LUA_VERSION_RELEASE | 24 | #define LUA_RELEASE LUA_VERSION "." LUA_VERSION_RELEASE |
| 25 | #define LUA_VERSION_NUM 502 | 25 | #define LUA_VERSION_NUM 502 |
| 26 | #define LUA_COPYRIGHT LUA_RELEASE " Copyright (C) 1994-2010 Lua.org, PUC-Rio" | 26 | #define LUA_COPYRIGHT LUA_RELEASE " Copyright (C) 1994-2011 Lua.org, PUC-Rio" |
| 27 | #define LUA_AUTHORS "R. Ierusalimschy, L. H. de Figueiredo, W. Celes" | 27 | #define LUA_AUTHORS "R. Ierusalimschy, L. H. de Figueiredo, W. Celes" |
| 28 | 28 | ||
| 29 | 29 | ||
| @@ -415,7 +415,7 @@ struct lua_Debug { · 385 unmodified lines | |||
| 415 | 415 | ||
| 416 | 416 | ||
| 417 | /****************************************************************************** | 417 | /****************************************************************************** |
| 418 | * Copyright (C) 1994-2010 Lua.org, PUC-Rio. All rights reserved. | 418 | * Copyright (C) 1994-2011 Lua.org, PUC-Rio. All rights reserved. |
| 419 | * | 419 | * |
| 420 | * Permission is hereby granted, free of charge, to any person obtaining | 420 | * Permission is hereby granted, free of charge, to any person obtaining |
| 421 | * a copy of this software and associated documentation files (the | 421 | * a copy of this software and associated documentation files (the |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: luac.c,v 1.65 2010/10/26 09:07:52 lhf Exp $ | 2 | ** $Id: luac.c,v 1.66 2011/05/10 01:08:57 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 | */ |
| @@ -143,9 +143,12 @@ static const Proto* combine(lua_State* L, int n) · 137 unmodified lines | |||
| 143 | int i=n; | 143 | int i=n; |
| 144 | if (lua_load(L,reader,&i,"=(" PROGNAME ")")!=LUA_OK) fatal(lua_tostring(L,-1)); | 144 | if (lua_load(L,reader,&i,"=(" PROGNAME ")")!=LUA_OK) fatal(lua_tostring(L,-1)); |
| 145 | f=toproto(L,-1); | 145 | f=toproto(L,-1); |
| 146 | for (i=0; i<n; i++) f->p[i]=toproto(L,i-n-1); | 146 | for (i=0; i<n; i++) |
| 147 | { | ||
| 148 | f->p[i]=toproto(L,i-n-1); | ||
| 149 | if (f->p[i]->sizeupvalues>0) f->p[i]->upvalues[0].instack=0; | ||
| 150 | } | ||
| 147 | f->sizelineinfo=0; | 151 | f->sizelineinfo=0; |
| 148 | f->sizeupvalues=0; | ||
| 149 | return f; | 152 | return f; |
| 150 | } | 153 | } |
| 151 | } | 154 | } |
| @@ -200,7 +203,7 @@ int main(int argc, char* argv[]) · 48 unmodified lines | |||
| 200 | } | 203 | } |
| 201 | 204 | ||
| 202 | /* | 205 | /* |
| 203 | ** $Id: print.c,v 1.66 2010/10/26 09:07:52 lhf Exp $ | 206 | ** $Id: print.c,v 1.67 2011/05/06 13:37:15 lhf Exp $ |
| 204 | ** print bytecodes | 207 | ** print bytecodes |
| 205 | ** See Copyright Notice in lua.h | 208 | ** See Copyright Notice in lua.h |
| 206 | */ | 209 | */ |
| @@ -270,6 +273,7 @@ static void PrintConstant(const Proto* f, int i) · 63 unmodified lines | |||
| 270 | } | 273 | } |
| 271 | 274 | ||
| 272 | #define UPVALNAME(x) ((f->upvalues[x].name) ? getstr(f->upvalues[x].name) : "-") | 275 | #define UPVALNAME(x) ((f->upvalues[x].name) ? getstr(f->upvalues[x].name) : "-") |
| 276 | #define MYK(x) (-1-(x)) | ||
| 273 | 277 | ||
| 274 | static void PrintCode(const Proto* f) | 278 | static void PrintCode(const Proto* f) |
| 275 | { | 279 | { |
| @@ -293,23 +297,25 @@ static void PrintCode(const Proto* f) · 17 unmodified lines | |||
| 293 | { | 297 | { |
| 294 | case iABC: | 298 | case iABC: |
| 295 | printf("%d",a); | 299 | printf("%d",a); |
| 296 | if (getBMode(o)!=OpArgN) printf(" %d",ISK(b) ? (-1-INDEXK(b)) : b); | 300 | if (getBMode(o)!=OpArgN) printf(" %d",ISK(b) ? (MYK(INDEXK(b))) : b); |
| 297 | if (getCMode(o)!=OpArgN) printf(" %d",ISK(c) ? (-1-INDEXK(c)) : c); | 301 | if (getCMode(o)!=OpArgN) printf(" %d",ISK(c) ? (MYK(INDEXK(c))) : c); |
| 298 | break; | 302 | break; |
| 299 | case iABx: | 303 | case iABx: |
| 300 | if (getBMode(o)==OpArgK) printf("%d %d",a,-bx); else printf("%d %d",a,bx); | 304 | printf("%d",a); |
| 305 | if (getBMode(o)==OpArgK) printf(" %d",MYK(bx)); | ||
| 306 | if (getBMode(o)==OpArgU) printf(" %d",bx); | ||
| 301 | break; | 307 | break; |
| 302 | case iAsBx: | 308 | case iAsBx: |
| 303 | if (o==OP_JMP) printf("%d",sbx); else printf("%d %d",a,sbx); | 309 | printf("%d %d",a,sbx); |
| 304 | break; | 310 | break; |
| 305 | case iAx: | 311 | case iAx: |
| 306 | printf("%d",-1-ax); | 312 | printf("%d",MYK(ax)); |
| 307 | break; | 313 | break; |
| 308 | } | 314 | } |
| 309 | switch (o) | 315 | switch (o) |
| 310 | { | 316 | { |
| 311 | case OP_LOADK: | 317 | case OP_LOADK: |
| 312 | if (bx>0) { printf("\t; "); PrintConstant(f,bx-1); } | 318 | printf("\t; "); PrintConstant(f,bx); |
| 313 | break; | 319 | break; |
| 314 | case OP_GETUPVAL: | 320 | case OP_GETUPVAL: |
| 315 | case OP_SETUPVAL: | 321 | case OP_SETUPVAL: |
| @@ -355,8 +361,7 @@ static void PrintCode(const Proto* f) · 39 unmodified lines | |||
| 355 | printf("\t; %p",VOID(f->p[bx])); | 361 | printf("\t; %p",VOID(f->p[bx])); |
| 356 | break; | 362 | break; |
| 357 | case OP_SETLIST: | 363 | case OP_SETLIST: |
| 358 | if (c==0) printf("\t; %d",(int)code[++pc]); | 364 | if (c==0) printf("\t; %d",(int)code[++pc]); else printf("\t; %d",c); |
| 359 | else printf("\t; %d",c); | ||
| 360 | break; | 365 | break; |
| 361 | case OP_EXTRAARG: | 366 | case OP_EXTRAARG: |
| 362 | printf("\t; "); PrintConstant(f,ax); | 367 | printf("\t; "); PrintConstant(f,ax); |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: luaconf.h,v 1.151 2010/11/12 15:48:30 roberto Exp $ | 2 | ** $Id: luaconf.h,v 1.159 2011/06/13 14:13:06 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 | */ |
| @@ -35,6 +35,7 @@ · 29 unmodified lines | |||
| 35 | 35 | ||
| 36 | #if defined(LUA_WIN) | 36 | #if defined(LUA_WIN) |
| 37 | #define LUA_DL_DLL | 37 | #define LUA_DL_DLL |
| 38 | #define LUA_USE_AFORMAT /* assume 'printf' handles 'aA' specifiers */ | ||
| 38 | #endif | 39 | #endif |
| 39 | 40 | ||
| 40 | 41 | ||
| @@ -43,12 +44,18 @@ · 2 unmodified lines | |||
| 43 | #define LUA_USE_POSIX | 44 | #define LUA_USE_POSIX |
| 44 | #define LUA_USE_DLOPEN /* needs an extra library: -ldl */ | 45 | #define LUA_USE_DLOPEN /* needs an extra library: -ldl */ |
| 45 | #define LUA_USE_READLINE /* needs some extra libraries */ | 46 | #define LUA_USE_READLINE /* needs some extra libraries */ |
| 47 | #define LUA_USE_STRTODHEX /* assume 'strtod' handles hexa formats */ | ||
| 48 | #define LUA_USE_AFORMAT /* assume 'printf' handles 'aA' specifiers */ | ||
| 49 | #define LUA_USE_LONGLONG /* assume support for long long */ | ||
| 46 | #endif | 50 | #endif |
| 47 | 51 | ||
| 48 | #if defined(LUA_USE_MACOSX) | 52 | #if defined(LUA_USE_MACOSX) |
| 49 | #define LUA_USE_POSIX | 53 | #define LUA_USE_POSIX |
| 50 | #define LUA_USE_DLOPEN /* does not need -ldl */ | 54 | #define LUA_USE_DLOPEN /* does not need -ldl */ |
| 51 | #define LUA_USE_READLINE /* needs an extra library: -lreadline */ | 55 | #define LUA_USE_READLINE /* needs an extra library: -lreadline */ |
| 56 | #define LUA_USE_STRTODHEX /* assume 'strtod' handles hexa formats */ | ||
| 57 | #define LUA_USE_AFORMAT /* assume 'printf' handles 'aA' specifiers */ | ||
| 58 | #define LUA_USE_LONGLONG /* assume support for long long */ | ||
| 52 | #endif | 59 | #endif |
| 53 | 60 | ||
| 54 | 61 | ||
| @@ -202,10 +209,11 @@ · 147 unmodified lines | |||
| 202 | 209 | ||
| 203 | 210 | ||
| 204 | /* | 211 | /* |
| 205 | @@ luai_writestring defines how 'print' prints its results. | 212 | @@ luai_writestring/luai_writeline define how 'print' prints its results. |
| 206 | */ | 213 | */ |
| 207 | #include <stdio.h> | 214 | #include <stdio.h> |
| 208 | #define luai_writestring(s,l) fwrite((s), sizeof(char), (l), stdout) | 215 | #define luai_writestring(s,l) fwrite((s), sizeof(char), (l), stdout) |
| 216 | #define luai_writeline() (luai_writestring("\n", 1), fflush(stdout)) | ||
| 209 | 217 | ||
| 210 | /* | 218 | /* |
| 211 | @@ luai_writestringerror defines how to print error messages. | 219 | @@ luai_writestringerror defines how to print error messages. |
| @@ -253,6 +261,12 @@ · 41 unmodified lines | |||
| 253 | */ | 261 | */ |
| 254 | #define LUA_COMPAT_LOG10 | 262 | #define LUA_COMPAT_LOG10 |
| 255 | 263 | ||
| 264 | /* | ||
| 265 | @@ LUA_COMPAT_LOADSTRING defines the function 'loadstring' in the base | ||
| 266 | ** library. You can rewrite 'loadstring(s)' as 'load(s)'. | ||
| 267 | */ | ||
| 268 | #define LUA_COMPAT_LOADSTRING | ||
| 269 | |||
| 256 | /* | 270 | /* |
| 257 | @@ LUA_COMPAT_MAXN defines the function 'maxn' in the table library. | 271 | @@ LUA_COMPAT_MAXN defines the function 'maxn' in the table library. |
| 258 | */ | 272 | */ |
| @@ -371,14 +385,27 @@ · 112 unmodified lines | |||
| 371 | @@ LUA_NUMBER_FMT is the format for writing numbers. | 385 | @@ LUA_NUMBER_FMT is the format for writing numbers. |
| 372 | @@ lua_number2str converts a number to a string. | 386 | @@ lua_number2str converts a number to a string. |
| 373 | @@ LUAI_MAXNUMBER2STR is maximum size of previous conversion. | 387 | @@ LUAI_MAXNUMBER2STR is maximum size of previous conversion. |
| 374 | @@ lua_str2number converts a string to a number. | ||
| 375 | */ | 388 | */ |
| 376 | #define LUA_NUMBER_SCAN "%lf" | 389 | #define LUA_NUMBER_SCAN "%lf" |
| 377 | #define LUA_NUMBER_FMT "%.14g" | 390 | #define LUA_NUMBER_FMT "%.14g" |
| 378 | #define lua_number2str(s,n) sprintf((s), LUA_NUMBER_FMT, (n)) | 391 | #define lua_number2str(s,n) sprintf((s), LUA_NUMBER_FMT, (n)) |
| 379 | #define LUAI_MAXNUMBER2STR 32 /* 16 digits, sign, point, and \0 */ | 392 | #define LUAI_MAXNUMBER2STR 32 /* 16 digits, sign, point, and \0 */ |
| 393 | |||
| 394 | |||
| 395 | /* | ||
| 396 | @@ lua_str2number converts a decimal numeric string to a number. | ||
| 397 | @@ lua_strx2number converts an hexadecimal numeric string to a number. | ||
| 398 | ** In C99, 'strtod' do both conversions. C89, however, has no function | ||
| 399 | ** to convert floating hexadecimal strings to numbers. For these | ||
| 400 | ** systems, you can leave 'lua_strx2number' undefined and Lua will | ||
| 401 | ** provide its own implementation. | ||
| 402 | */ | ||
| 380 | #define lua_str2number(s,p) strtod((s), (p)) | 403 | #define lua_str2number(s,p) strtod((s), (p)) |
| 381 | 404 | ||
| 405 | #if defined(LUA_USE_STRTODHEX) | ||
| 406 | #define lua_strx2number(s,p) strtod((s), (p)) | ||
| 407 | #endif | ||
| 408 | |||
| 382 | 409 | ||
| 383 | /* | 410 | /* |
| 384 | @@ The luai_num* macros define the primitive operations over numbers. | 411 | @@ The luai_num* macros define the primitive operations over numbers. |
| @@ -438,11 +465,11 @@ · 53 unmodified lines | |||
| 438 | 465 | ||
| 439 | /* | 466 | /* |
| 440 | @@ LUA_IEEEENDIAN is the endianness of doubles in your machine | 467 | @@ LUA_IEEEENDIAN is the endianness of doubles in your machine |
| 441 | @@ (0 for little endian, 1 for big endian); if not defined, Lua will | 468 | ** (0 for little endian, 1 for big endian); if not defined, Lua will |
| 442 | @@ check it dynamically. | 469 | ** check it dynamically. |
| 443 | */ | 470 | */ |
| 444 | /* check for known architectures */ | 471 | /* check for known architectures */ |
| 445 | #if defined(__i386__) || defined(__i386) || defined(i386) || \ | 472 | #if defined(__i386__) || defined(__i386) || defined(__X86__) || \ |
| 446 | defined (__x86_64) | 473 | defined (__x86_64) |
| 447 | #define LUA_IEEEENDIAN 0 | 474 | #define LUA_IEEEENDIAN 0 |
| 448 | #elif defined(__POWERPC__) || defined(__ppc__) | 475 | #elif defined(__POWERPC__) || defined(__ppc__) |
| @@ -458,6 +485,30 @@ · 9 unmodified lines | |||
| 458 | /* }================================================================== */ | 485 | /* }================================================================== */ |
| 459 | 486 | ||
| 460 | 487 | ||
| 488 | /* | ||
| 489 | @@ LUA_NANTRICKLE/LUA_NANTRICKBE controls the use of a trick to pack all | ||
| 490 | ** types into a single double value, using NaN values to represent | ||
| 491 | ** non-number values. The trick only works on 32-bit machines (ints and | ||
| 492 | ** pointers are 32-bit values) with numbers represented as IEEE 754-2008 | ||
| 493 | ** doubles with conventional endianess (12345678 or 87654321), in CPUs | ||
| 494 | ** that do not produce signaling NaN values (all NaNs are quiet). | ||
| 495 | */ | ||
| 496 | #if defined(LUA_CORE) /* { */ | ||
| 497 | |||
| 498 | #if defined(LUA_NUMBER_DOUBLE) && !defined(LUA_ANSI) /* { */ | ||
| 499 | |||
| 500 | /* little-endian architectures that satisfy those conditions */ | ||
| 501 | #if defined(__i386__) || defined(__i386) || defined(__X86__) | ||
| 502 | |||
| 503 | #define LUA_NANTRICKLE | ||
| 504 | |||
| 505 | #endif | ||
| 506 | |||
| 507 | #endif /* } */ | ||
| 508 | |||
| 509 | #endif /* } */ | ||
| 510 | |||
| 511 | |||
| 461 | 512 | ||
| 462 | 513 | ||
| 463 | /* =================================================================== */ | 514 | /* =================================================================== */ |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lualib.h,v 1.41 2010/10/25 14:32:36 roberto Exp $ | 2 | ** $Id: lualib.h,v 1.42 2011/05/25 14:12:28 roberto Exp $ |
| 3 | ** Lua standard libraries | 3 | ** Lua standard libraries |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -50,7 +50,7 @@ LUALIB_API void (luaL_openlibs) (lua_State *L); · 44 unmodified lines | |||
| 50 | 50 | ||
| 51 | 51 | ||
| 52 | 52 | ||
| 53 | #ifndef lua_assert | 53 | #if !defined(lua_assert) |
| 54 | #define lua_assert(x) ((void)0) | 54 | #define lua_assert(x) ((void)0) |
| 55 | #endif | 55 | #endif |
| 56 | 56 | ||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lundump.c,v 1.68 2010/10/26 00:23:46 lhf Exp $ | 2 | ** $Id: lundump.c,v 1.69 2011/05/06 13:35:17 lhf 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 | */ |
| @@ -38,6 +38,10 @@ static void error(LoadState* S, const char* why) · 32 unmodified lines | |||
| 38 | #define LoadVar(S,x) LoadMem(S,&x,1,sizeof(x)) | 38 | #define LoadVar(S,x) LoadMem(S,&x,1,sizeof(x)) |
| 39 | #define LoadVector(S,b,n,size) LoadMem(S,b,n,size) | 39 | #define LoadVector(S,b,n,size) LoadMem(S,b,n,size) |
| 40 | 40 | ||
| 41 | #if !defined(luai_verifycode) | ||
| 42 | #define luai_verifycode(L,b,f) (f) | ||
| 43 | #endif | ||
| 44 | |||
| 41 | static void LoadBlock(LoadState* S, void* b, size_t size) | 45 | static void LoadBlock(LoadState* S, void* b, size_t size) |
| 42 | { | 46 | { |
| 43 | if (luaZ_read(S->Z,b,size)!=0) error(S,"corrupted"); | 47 | if (luaZ_read(S->Z,b,size)!=0) error(S,"corrupted"); |
| @@ -54,6 +58,7 @@ static int LoadInt(LoadState* S) · 10 unmodified lines | |||
| 54 | { | 58 | { |
| 55 | int x; | 59 | int x; |
| 56 | LoadVar(S,x); | 60 | LoadVar(S,x); |
| 61 | if (x<0) error(S,"corrupted"); | ||
| 57 | return x; | 62 | return x; |
| 58 | } | 63 | } |
| 59 | 64 | ||
| @@ -73,7 +78,7 @@ static TString* LoadString(LoadState* S) · 13 unmodified lines | |||
| 73 | else | 78 | else |
| 74 | { | 79 | { |
| 75 | char* s=luaZ_openspace(S->L,S->b,size); | 80 | char* s=luaZ_openspace(S->L,S->b,size); |
| 76 | LoadBlock(S,s,size); | 81 | LoadBlock(S,s,size*sizeof(char)); |
| 77 | return luaS_newlstr(S->L,s,size-1); /* remove trailing '\0' */ | 82 | return luaS_newlstr(S->L,s,size-1); /* remove trailing '\0' */ |
| 78 | } | 83 | } |
| 79 | } | 84 | } |
| @@ -177,16 +182,17 @@ static Proto* LoadFunction(LoadState* S) · 97 unmodified lines | |||
| 177 | 182 | ||
| 178 | /* the code below must be consistent with the code in luaU_header */ | 183 | /* the code below must be consistent with the code in luaU_header */ |
| 179 | #define N0 LUAC_HEADERSIZE | 184 | #define N0 LUAC_HEADERSIZE |
| 180 | #define N1 (sizeof(LUA_SIGNATURE)-1) | 185 | #define N1 (sizeof(LUA_SIGNATURE)-sizeof(char)) |
| 181 | #define N2 N1+2 | 186 | #define N2 N1+2 |
| 182 | #define N3 N2+6 | 187 | #define N3 N2+6 |
| 183 | 188 | ||
| 184 | static void LoadHeader(LoadState* S) | 189 | static void LoadHeader(LoadState* S) |
| 185 | { | 190 | { |
| 186 | char h[LUAC_HEADERSIZE]; | 191 | lu_byte h[LUAC_HEADERSIZE]; |
| 187 | char s[LUAC_HEADERSIZE]; | 192 | lu_byte s[LUAC_HEADERSIZE]; |
| 188 | luaU_header(h); | 193 | luaU_header(h); |
| 189 | LoadBlock(S,s,LUAC_HEADERSIZE); | 194 | memcpy(s,h,sizeof(char)); /* first char already read */ |
| 195 | LoadBlock(S,s+sizeof(char),LUAC_HEADERSIZE-sizeof(char)); | ||
| 190 | if (memcmp(h,s,N0)==0) return; | 196 | if (memcmp(h,s,N0)==0) return; |
| 191 | if (memcmp(h,s,N1)!=0) error(S,"not a"); | 197 | if (memcmp(h,s,N1)!=0) error(S,"not a"); |
| 192 | if (memcmp(h,s,N2)!=0) error(S,"version mismatch in"); | 198 | if (memcmp(h,s,N2)!=0) error(S,"version mismatch in"); |
| @@ -209,29 +215,30 @@ Proto* luaU_undump (lua_State* L, ZIO* Z, Mbuffer* buff, const char* name) · 16 unmodified lines | |||
| 209 | S.Z=Z; | 215 | S.Z=Z; |
| 210 | S.b=buff; | 216 | S.b=buff; |
| 211 | LoadHeader(&S); | 217 | LoadHeader(&S); |
| 212 | return LoadFunction(&S); | 218 | return luai_verifycode(L,buff,LoadFunction(&S)); |
| 213 | } | 219 | } |
| 214 | 220 | ||
| 215 | /* data to catch conversion errors */ | 221 | #define MYINT(s) (s[0]-'0') |
| 216 | #define TAIL "\x19\x93\r\n\x1a\n" | 222 | #define VERSION MYINT(LUA_VERSION_MAJOR)*16+MYINT(LUA_VERSION_MINOR) |
| 223 | #define FORMAT 0 /* this is the official format */ | ||
| 217 | 224 | ||
| 218 | /* | 225 | /* |
| 219 | * make header for precompiled chunks | 226 | * make header for precompiled chunks |
| 220 | * if you make any changes in the code below or in LUA_SIGNATURE in lua.h, | 227 | * if you change the code below be sure to update LoadHeader and FORMAT above |
| 221 | * be sure to update LoadHeader above and LUAC_HEADERSIZE in lundump.h | 228 | * and LUAC_HEADERSIZE in lundump.h |
| 222 | */ | 229 | */ |
| 223 | void luaU_header (char* h) | 230 | void luaU_header (lu_byte* h) |
| 224 | { | 231 | { |
| 225 | int x=1; | 232 | int x=1; |
| 226 | memcpy(h,LUA_SIGNATURE,sizeof(LUA_SIGNATURE)-1); | 233 | memcpy(h,LUA_SIGNATURE,sizeof(LUA_SIGNATURE)-sizeof(char)); |
| 227 | h+=sizeof(LUA_SIGNATURE)-1; | 234 | h+=sizeof(LUA_SIGNATURE)-sizeof(char); |
| 228 | *h++=(char)0x52; /* Lua 5.2 */ | 235 | *h++=cast_byte(VERSION); |
| 229 | *h++=(char)0; /* the official format */ | 236 | *h++=cast_byte(FORMAT); |
| 230 | *h++=(char)*(char*)&x; /* endianness */ | 237 | *h++=cast_byte(*(char*)&x); /* endianness */ |
| 231 | *h++=(char)sizeof(int); | 238 | *h++=cast_byte(sizeof(int)); |
| 232 | *h++=(char)sizeof(size_t); | 239 | *h++=cast_byte(sizeof(size_t)); |
| 233 | *h++=(char)sizeof(Instruction); | 240 | *h++=cast_byte(sizeof(Instruction)); |
| 234 | *h++=(char)sizeof(lua_Number); | 241 | *h++=cast_byte(sizeof(lua_Number)); |
| 235 | *h++=(char)(((lua_Number)0.5)==0); /* is lua_Number integral? */ | 242 | *h++=cast_byte(((lua_Number)0.5)==0); /* is lua_Number integral? */ |
| 236 | memcpy(h,TAIL,sizeof(TAIL)-1); | 243 | memcpy(h,LUAC_TAIL,sizeof(LUAC_TAIL)-sizeof(char)); |
| 237 | } | 244 | } |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lundump.h,v 1.43 2010/10/26 00:23:46 lhf Exp $ | 2 | ** $Id: lundump.h,v 1.44 2011/05/06 13:35:17 lhf 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 | */ |
| @@ -14,12 +14,15 @@ · 8 unmodified lines | |||
| 14 | LUAI_FUNC Proto* luaU_undump (lua_State* L, ZIO* Z, Mbuffer* buff, const char* name); | 14 | LUAI_FUNC Proto* luaU_undump (lua_State* L, ZIO* Z, Mbuffer* buff, const char* name); |
| 15 | 15 | ||
| 16 | /* make header; from lundump.c */ | 16 | /* make header; from lundump.c */ |
| 17 | LUAI_FUNC void luaU_header (char* h); | 17 | LUAI_FUNC void luaU_header (lu_byte* h); |
| 18 | 18 | ||
| 19 | /* dump one chunk; from ldump.c */ | 19 | /* dump one chunk; from ldump.c */ |
| 20 | LUAI_FUNC int luaU_dump (lua_State* L, const Proto* f, lua_Writer w, void* data, int strip); | 20 | LUAI_FUNC int luaU_dump (lua_State* L, const Proto* f, lua_Writer w, void* data, int strip); |
| 21 | 21 | ||
| 22 | /* size of header of binary files */ | 22 | /* data to catch conversion errors */ |
| 23 | #define LUAC_HEADERSIZE 18 | 23 | #define LUAC_TAIL "\x19\x93\r\n\x1a\n" |
| 24 | |||
| 25 | /* size in bytes of header of binary files */ | ||
| 26 | #define LUAC_HEADERSIZE (sizeof(LUA_SIGNATURE)-sizeof(char)+2+6+sizeof(LUAC_TAIL)-sizeof(char)) | ||
| 24 | 27 | ||
| 25 | #endif | 28 | #endif |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lvm.c,v 2.125 2010/10/29 17:52:46 roberto Exp $ | 2 | ** $Id: lvm.c,v 2.141 2011/06/09 18:24:22 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 | */ |
| @@ -35,7 +35,7 @@ · 29 unmodified lines | |||
| 35 | const TValue *luaV_tonumber (const TValue *obj, TValue *n) { | 35 | const TValue *luaV_tonumber (const TValue *obj, TValue *n) { |
| 36 | lua_Number num; | 36 | lua_Number num; |
| 37 | if (ttisnumber(obj)) return obj; | 37 | if (ttisnumber(obj)) return obj; |
| 38 | if (ttisstring(obj) && luaO_str2d(svalue(obj), &num)) { | 38 | if (ttisstring(obj) && luaO_str2d(svalue(obj), tsvalue(obj)->len, &num)) { |
| 39 | setnvalue(n, num); | 39 | setnvalue(n, num); |
| 40 | return n; | 40 | return n; |
| 41 | } | 41 | } |
| @@ -65,7 +65,7 @@ static void traceexec (lua_State *L) { · 23 unmodified lines | |||
| 65 | luaD_hook(L, LUA_HOOKCOUNT, -1); | 65 | luaD_hook(L, LUA_HOOKCOUNT, -1); |
| 66 | } | 66 | } |
| 67 | if (mask & LUA_MASKLINE) { | 67 | if (mask & LUA_MASKLINE) { |
| 68 | Proto *p = ci_func(ci)->l.p; | 68 | Proto *p = ci_func(ci)->p; |
| 69 | int npc = pcRel(ci->u.l.savedpc, p); | 69 | int npc = pcRel(ci->u.l.savedpc, p); |
| 70 | int newline = getfuncline(p, npc); | 70 | int newline = getfuncline(p, npc); |
| 71 | if (npc == 0 || /* call linehook when enter a new function, */ | 71 | if (npc == 0 || /* call linehook when enter a new function, */ |
| @@ -161,7 +161,6 @@ static int call_binTM (lua_State *L, const TValue *p1, const TValue *p2, · 89 unmodified lines | |||
| 161 | if (ttisnil(tm)) | 161 | if (ttisnil(tm)) |
| 162 | tm = luaT_gettmbyobj(L, p2, event); /* try second operand */ | 162 | tm = luaT_gettmbyobj(L, p2, event); /* try second operand */ |
| 163 | if (ttisnil(tm)) return 0; | 163 | if (ttisnil(tm)) return 0; |
| 164 | if (event == TM_UNM) p2 = luaO_nilobject; | ||
| 165 | callTM(L, tm, p1, p2, res, 1); | 164 | callTM(L, tm, p1, p2, res, 1); |
| 166 | return 1; | 165 | return 1; |
| 167 | } | 166 | } |
| @@ -175,7 +174,7 @@ static const TValue *get_equalTM (lua_State *L, Table *mt1, Table *mt2, · 7 unmodified lines | |||
| 175 | if (mt1 == mt2) return tm1; /* same metatables => same metamethods */ | 174 | if (mt1 == mt2) return tm1; /* same metatables => same metamethods */ |
| 176 | tm2 = fasttm(L, mt2, event); | 175 | tm2 = fasttm(L, mt2, event); |
| 177 | if (tm2 == NULL) return NULL; /* no metamethod */ | 176 | if (tm2 == NULL) return NULL; /* no metamethod */ |
| 178 | if (luaO_rawequalObj(tm1, tm2)) /* same metamethods? */ | 177 | if (luaV_rawequalobj(tm1, tm2)) /* same metamethods? */ |
| 179 | return tm1; | 178 | return tm1; |
| 180 | return NULL; | 179 | return NULL; |
| 181 | } | 180 | } |
| @@ -238,9 +237,12 @@ int luaV_lessequal (lua_State *L, const TValue *l, const TValue *r) { · 56 unmodified lines | |||
| 238 | } | 237 | } |
| 239 | 238 | ||
| 240 | 239 | ||
| 241 | int luaV_equalval_ (lua_State *L, const TValue *t1, const TValue *t2) { | 240 | /* |
| 241 | ** equality of Lua values. L == NULL means raw equality (no metamethods) | ||
| 242 | */ | ||
| 243 | int luaV_equalobj_ (lua_State *L, const TValue *t1, const TValue *t2) { | ||
| 242 | const TValue *tm; | 244 | const TValue *tm; |
| 243 | lua_assert(ttype(t1) == ttype(t2)); | 245 | lua_assert(ttisequal(t1, t2)); |
| 244 | switch (ttype(t1)) { | 246 | switch (ttype(t1)) { |
| 245 | case LUA_TNIL: return 1; | 247 | case LUA_TNIL: return 1; |
| 246 | case LUA_TNUMBER: return luai_numeq(nvalue(t1), nvalue(t2)); | 248 | case LUA_TNUMBER: return luai_numeq(nvalue(t1), nvalue(t2)); |
| @@ -250,15 +252,19 @@ int luaV_equalval_ (lua_State *L, const TValue *t1, const TValue *t2) { · 3 unmodified lines | |||
| 250 | case LUA_TSTRING: return eqstr(rawtsvalue(t1), rawtsvalue(t2)); | 252 | case LUA_TSTRING: return eqstr(rawtsvalue(t1), rawtsvalue(t2)); |
| 251 | case LUA_TUSERDATA: { | 253 | case LUA_TUSERDATA: { |
| 252 | if (uvalue(t1) == uvalue(t2)) return 1; | 254 | if (uvalue(t1) == uvalue(t2)) return 1; |
| 255 | else if (L == NULL) return 0; | ||
| 253 | tm = get_equalTM(L, uvalue(t1)->metatable, uvalue(t2)->metatable, TM_EQ); | 256 | tm = get_equalTM(L, uvalue(t1)->metatable, uvalue(t2)->metatable, TM_EQ); |
| 254 | break; /* will try TM */ | 257 | break; /* will try TM */ |
| 255 | } | 258 | } |
| 256 | case LUA_TTABLE: { | 259 | case LUA_TTABLE: { |
| 257 | if (hvalue(t1) == hvalue(t2)) return 1; | 260 | if (hvalue(t1) == hvalue(t2)) return 1; |
| 261 | else if (L == NULL) return 0; | ||
| 258 | tm = get_equalTM(L, hvalue(t1)->metatable, hvalue(t2)->metatable, TM_EQ); | 262 | tm = get_equalTM(L, hvalue(t1)->metatable, hvalue(t2)->metatable, TM_EQ); |
| 259 | break; /* will try TM */ | 263 | break; /* will try TM */ |
| 260 | } | 264 | } |
| 261 | default: return gcvalue(t1) == gcvalue(t2); | 265 | default: |
| 266 | lua_assert(iscollectable(t1)); | ||
| 267 | return gcvalue(t1) == gcvalue(t2); | ||
| 262 | } | 268 | } |
| 263 | if (tm == NULL) return 0; /* no TM? */ | 269 | if (tm == NULL) return 0; /* no TM? */ |
| 264 | callTM(L, tm, t1, t2, L->top, 1); /* call TM */ | 270 | callTM(L, tm, t1, t2, L->top, 1); /* call TM */ |
| @@ -286,18 +292,20 @@ void luaV_concat (lua_State *L, int total) { · 21 unmodified lines | |||
| 286 | char *buffer; | 292 | char *buffer; |
| 287 | int i; | 293 | int i; |
| 288 | /* collect total length */ | 294 | /* collect total length */ |
| 289 | for (n = 1; n < total && tostring(L, top-n-1); n++) { | 295 | for (i = 1; i < total && tostring(L, top-i-1); i++) { |
| 290 | size_t l = tsvalue(top-n-1)->len; | 296 | size_t l = tsvalue(top-i-1)->len; |
| 291 | if (l >= MAX_SIZET - tl) luaG_runerror(L, "string length overflow"); | 297 | if (l >= (MAX_SIZET/sizeof(char)) - tl) |
| 298 | luaG_runerror(L, "string length overflow"); | ||
| 292 | tl += l; | 299 | tl += l; |
| 293 | } | 300 | } |
| 294 | buffer = luaZ_openspace(L, &G(L)->buff, tl); | 301 | buffer = luaZ_openspace(L, &G(L)->buff, tl); |
| 295 | tl = 0; | 302 | tl = 0; |
| 296 | for (i=n; i>0; i--) { /* concat all strings */ | 303 | n = i; |
| 304 | do { /* concat all strings */ | ||
| 297 | size_t l = tsvalue(top-i)->len; | 305 | size_t l = tsvalue(top-i)->len; |
| 298 | memcpy(buffer+tl, svalue(top-i), l); | 306 | memcpy(buffer+tl, svalue(top-i), l * sizeof(char)); |
| 299 | tl += l; | 307 | tl += l; |
| 300 | } | 308 | } while (--i > 0); |
| 301 | setsvalue2s(L, top-n, luaS_newlstr(L, buffer, tl)); | 309 | setsvalue2s(L, top-n, luaS_newlstr(L, buffer, tl)); |
| 302 | } | 310 | } |
| 303 | total -= n-1; /* got 'n' strings to create 1 new */ | 311 | total -= n-1; /* got 'n' strings to create 1 new */ |
| @@ -308,7 +316,7 @@ void luaV_concat (lua_State *L, int total) { · 4 unmodified lines | |||
| 308 | 316 | ||
| 309 | void luaV_objlen (lua_State *L, StkId ra, const TValue *rb) { | 317 | void luaV_objlen (lua_State *L, StkId ra, const TValue *rb) { |
| 310 | const TValue *tm; | 318 | const TValue *tm; |
| 311 | switch (ttype(rb)) { | 319 | switch (ttypenv(rb)) { |
| 312 | case LUA_TTABLE: { | 320 | case LUA_TTABLE: { |
| 313 | Table *h = hvalue(rb); | 321 | Table *h = hvalue(rb); |
| 314 | tm = fasttm(L, h->metatable, TM_LEN); | 322 | tm = fasttm(L, h->metatable, TM_LEN); |
| @@ -327,7 +335,7 @@ void luaV_objlen (lua_State *L, StkId ra, const TValue *rb) { · 12 unmodified lines | |||
| 327 | break; | 335 | break; |
| 328 | } | 336 | } |
| 329 | } | 337 | } |
| 330 | callTM(L, tm, rb, luaO_nilobject, ra, 1); | 338 | callTM(L, tm, rb, rb, ra, 1); |
| 331 | } | 339 | } |
| 332 | 340 | ||
| 333 | 341 | ||
| @@ -378,7 +386,7 @@ static void pushclosure (lua_State *L, Proto *p, UpVal **encup, StkId base, · 44 unmodified lines | |||
| 378 | Upvaldesc *uv = p->upvalues; | 386 | Upvaldesc *uv = p->upvalues; |
| 379 | int i; | 387 | int i; |
| 380 | Closure *ncl = luaF_newLclosure(L, p); | 388 | Closure *ncl = luaF_newLclosure(L, p); |
| 381 | setclvalue(L, ra, ncl); /* anchor new closure in stack */ | 389 | setclLvalue(L, ra, ncl); /* anchor new closure in stack */ |
| 382 | for (i = 0; i < nup; i++) { /* fill in its upvalues */ | 390 | for (i = 0; i < nup; i++) { /* fill in its upvalues */ |
| 383 | if (uv[i].instack) /* upvalue refers to local variable? */ | 391 | if (uv[i].instack) /* upvalue refers to local variable? */ |
| 384 | ncl->l.upvals[i] = luaF_findupval(L, base + uv[i].idx); | 392 | ncl->l.upvals[i] = luaF_findupval(L, base + uv[i].idx); |
| @@ -454,6 +462,11 @@ void luaV_finishOp (lua_State *L) { · 69 unmodified lines | |||
| 454 | ** some macros for common tasks in `luaV_execute' | 462 | ** some macros for common tasks in `luaV_execute' |
| 455 | */ | 463 | */ |
| 456 | 464 | ||
| 465 | #if !defined luai_runtimecheck | ||
| 466 | #define luai_runtimecheck(L, c) /* void */ | ||
| 467 | #endif | ||
| 468 | |||
| 469 | |||
| 457 | #define RA(i) (base+GETARG_A(i)) | 470 | #define RA(i) (base+GETARG_A(i)) |
| 458 | /* to be used after possible stack reallocation */ | 471 | /* to be used after possible stack reallocation */ |
| 459 | #define RB(i) check_exp(getBMode(GET_OPCODE(i)) == OpArgR, base+GETARG_B(i)) | 472 | #define RB(i) check_exp(getBMode(GET_OPCODE(i)) == OpArgR, base+GETARG_B(i)) |
| @@ -466,12 +479,19 @@ void luaV_finishOp (lua_State *L) { · 6 unmodified lines | |||
| 466 | (k + (GETARG_Bx(i) != 0 ? GETARG_Bx(i) - 1 : GETARG_Ax(*ci->u.l.savedpc++))) | 479 | (k + (GETARG_Bx(i) != 0 ? GETARG_Bx(i) - 1 : GETARG_Ax(*ci->u.l.savedpc++))) |
| 467 | 480 | ||
| 468 | 481 | ||
| 469 | #define dojump(i) (ci->u.l.savedpc += (i)) | 482 | /* execute a jump instruction */ |
| 483 | #define dojump(ci,i,e) \ | ||
| 484 | { int a = GETARG_A(i); \ | ||
| 485 | if (a > 0) luaF_close(L, ci->u.l.base + a - 1); \ | ||
| 486 | ci->u.l.savedpc += GETARG_sBx(i) + e; } | ||
| 487 | |||
| 488 | /* for test instructions, execute the jump instruction that follows it */ | ||
| 489 | #define donextjump(ci) { i = *ci->u.l.savedpc; dojump(ci, i, 1); } | ||
| 470 | 490 | ||
| 471 | 491 | ||
| 472 | #define Protect(x) { {x;}; base = ci->u.l.base; } | 492 | #define Protect(x) { {x;}; base = ci->u.l.base; } |
| 473 | 493 | ||
| 474 | #define checkGC(L) Protect(luaC_checkGC(L); luai_threadyield(L);) | 494 | #define checkGC(L,c) Protect(luaC_condGC(L, c); luai_threadyield(L);) |
| 475 | 495 | ||
| 476 | 496 | ||
| 477 | #define arith_op(op,tm) { \ | 497 | #define arith_op(op,tm) { \ |
| @@ -493,9 +513,8 @@ void luaV_execute (lua_State *L) { · 15 unmodified lines | |||
| 493 | TValue *k; | 513 | TValue *k; |
| 494 | StkId base; | 514 | StkId base; |
| 495 | newframe: /* reentry point when frame changes (call/return) */ | 515 | newframe: /* reentry point when frame changes (call/return) */ |
| 496 | lua_assert(isLua(ci)); | ||
| 497 | lua_assert(ci == L->ci); | 516 | lua_assert(ci == L->ci); |
| 498 | cl = &clvalue(ci->func)->l; | 517 | cl = clLvalue(ci->func); |
| 499 | k = cl->p->k; | 518 | k = cl->p->k; |
| 500 | base = ci->u.l.base; | 519 | base = ci->u.l.base; |
| 501 | /* main loop of interpreter */ | 520 | /* main loop of interpreter */ |
| @@ -515,7 +534,13 @@ void luaV_execute (lua_State *L) { · 13 unmodified lines | |||
| 515 | setobjs2s(L, ra, RB(i)); | 534 | setobjs2s(L, ra, RB(i)); |
| 516 | ) | 535 | ) |
| 517 | vmcase(OP_LOADK, | 536 | vmcase(OP_LOADK, |
| 518 | TValue *rb = KBx(i); | 537 | TValue *rb = k + GETARG_Bx(i); |
| 538 | setobj2s(L, ra, rb); | ||
| 539 | ) | ||
| 540 | vmcase(OP_LOADKX, | ||
| 541 | TValue *rb; | ||
| 542 | lua_assert(GET_OPCODE(*ci->u.l.savedpc) == OP_EXTRAARG); | ||
| 543 | rb = k + GETARG_Ax(*ci->u.l.savedpc++); | ||
| 519 | setobj2s(L, ra, rb); | 544 | setobj2s(L, ra, rb); |
| 520 | ) | 545 | ) |
| 521 | vmcase(OP_LOADBOOL, | 546 | vmcase(OP_LOADBOOL, |
| @@ -523,10 +548,10 @@ void luaV_execute (lua_State *L) { · 1 unmodified line | |||
| 523 | if (GETARG_C(i)) ci->u.l.savedpc++; /* skip next instruction (if C) */ | 548 | if (GETARG_C(i)) ci->u.l.savedpc++; /* skip next instruction (if C) */ |
| 524 | ) | 549 | ) |
| 525 | vmcase(OP_LOADNIL, | 550 | vmcase(OP_LOADNIL, |
| 526 | TValue *rb = RB(i); | 551 | int b = GETARG_B(i); |
| 527 | do { | 552 | do { |
| 528 | setnilvalue(rb--); | 553 | setnilvalue(ra++); |
| 529 | } while (rb >= ra); | 554 | } while (b--); |
| 530 | ) | 555 | ) |
| 531 | vmcase(OP_GETUPVAL, | 556 | vmcase(OP_GETUPVAL, |
| 532 | int b = GETARG_B(i); | 557 | int b = GETARG_B(i); |
| @@ -558,7 +583,11 @@ void luaV_execute (lua_State *L) { · 25 unmodified lines | |||
| 558 | sethvalue(L, ra, t); | 583 | sethvalue(L, ra, t); |
| 559 | if (b != 0 || c != 0) | 584 | if (b != 0 || c != 0) |
| 560 | luaH_resize(L, t, luaO_fb2int(b), luaO_fb2int(c)); | 585 | luaH_resize(L, t, luaO_fb2int(b), luaO_fb2int(c)); |
| 561 | checkGC(L); | 586 | checkGC(L, |
| 587 | L->top = ra + 1; /* limit of live values */ | ||
| 588 | luaC_step(L); | ||
| 589 | L->top = ci->top; /* restore top */ | ||
| 590 | ) | ||
| 562 | ) | 591 | ) |
| 563 | vmcase(OP_SELF, | 592 | vmcase(OP_SELF, |
| 564 | StkId rb = RB(i); | 593 | StkId rb = RB(i); |
| @@ -594,7 +623,8 @@ void luaV_execute (lua_State *L) { · 29 unmodified lines | |||
| 594 | } | 623 | } |
| 595 | ) | 624 | ) |
| 596 | vmcase(OP_NOT, | 625 | vmcase(OP_NOT, |
| 597 | int res = l_isfalse(RB(i)); /* next assignment may change this value */ | 626 | TValue *rb = RB(i); |
| 627 | int res = l_isfalse(rb); /* next assignment may change this value */ | ||
| 598 | setbvalue(ra, res); | 628 | setbvalue(ra, res); |
| 599 | ) | 629 | ) |
| 600 | vmcase(OP_LEN, | 630 | vmcase(OP_LEN, |
| @@ -603,49 +633,61 @@ void luaV_execute (lua_State *L) { · 2 unmodified lines | |||
| 603 | vmcase(OP_CONCAT, | 633 | vmcase(OP_CONCAT, |
| 604 | int b = GETARG_B(i); | 634 | int b = GETARG_B(i); |
| 605 | int c = GETARG_C(i); | 635 | int c = GETARG_C(i); |
| 636 | StkId rb; | ||
| 606 | L->top = base + c + 1; /* mark the end of concat operands */ | 637 | L->top = base + c + 1; /* mark the end of concat operands */ |
| 607 | Protect(luaV_concat(L, c-b+1); checkGC(L);) | 638 | Protect(luaV_concat(L, c - b + 1)); |
| 639 | ra = RA(i); /* 'luav_concat' may invoke TMs and move the stack */ | ||
| 640 | rb = b + base; | ||
| 641 | setobjs2s(L, ra, rb); | ||
| 642 | checkGC(L, | ||
| 643 | L->top = (ra >= rb ? ra + 1 : rb); /* limit of live values */ | ||
| 644 | luaC_step(L); | ||
| 645 | ) | ||
| 608 | L->top = ci->top; /* restore top */ | 646 | L->top = ci->top; /* restore top */ |
| 609 | setobjs2s(L, RA(i), base+b); | ||
| 610 | ) | 647 | ) |
| 611 | vmcase(OP_JMP, | 648 | vmcase(OP_JMP, |
| 612 | dojump(GETARG_sBx(i)); | 649 | dojump(ci, i, 0); |
| 613 | ) | 650 | ) |
| 614 | vmcase(OP_EQ, | 651 | vmcase(OP_EQ, |
| 615 | TValue *rb = RKB(i); | 652 | TValue *rb = RKB(i); |
| 616 | TValue *rc = RKC(i); | 653 | TValue *rc = RKC(i); |
| 617 | Protect( | 654 | Protect( |
| 618 | if (equalobj(L, rb, rc) == GETARG_A(i)) | 655 | if (equalobj(L, rb, rc) != GETARG_A(i)) |
| 619 | dojump(GETARG_sBx(*ci->u.l.savedpc)); | 656 | ci->u.l.savedpc++; |
| 657 | else | ||
| 658 | donextjump(ci); | ||
| 620 | ) | 659 | ) |
| 621 | ci->u.l.savedpc++; | ||
| 622 | ) | 660 | ) |
| 623 | vmcase(OP_LT, | 661 | vmcase(OP_LT, |
| 624 | Protect( | 662 | Protect( |
| 625 | if (luaV_lessthan(L, RKB(i), RKC(i)) == GETARG_A(i)) | 663 | if (luaV_lessthan(L, RKB(i), RKC(i)) != GETARG_A(i)) |
| 626 | dojump(GETARG_sBx(*ci->u.l.savedpc)); | 664 | ci->u.l.savedpc++; |
| 665 | else | ||
| 666 | donextjump(ci); | ||
| 627 | ) | 667 | ) |
| 628 | ci->u.l.savedpc++; | ||
| 629 | ) | 668 | ) |
| 630 | vmcase(OP_LE, | 669 | vmcase(OP_LE, |
| 631 | Protect( | 670 | Protect( |
| 632 | if (luaV_lessequal(L, RKB(i), RKC(i)) == GETARG_A(i)) | 671 | if (luaV_lessequal(L, RKB(i), RKC(i)) != GETARG_A(i)) |
| 633 | dojump(GETARG_sBx(*ci->u.l.savedpc)); | 672 | ci->u.l.savedpc++; |
| 673 | else | ||
| 674 | donextjump(ci); | ||
| 634 | ) | 675 | ) |
| 635 | ci->u.l.savedpc++; | ||
| 636 | ) | 676 | ) |
| 637 | vmcase(OP_TEST, | 677 | vmcase(OP_TEST, |
| 638 | if (GETARG_C(i) ? !l_isfalse(ra) : l_isfalse(ra)) | 678 | if (GETARG_C(i) ? l_isfalse(ra) : !l_isfalse(ra)) |
| 639 | dojump(GETARG_sBx(*ci->u.l.savedpc)); | 679 | ci->u.l.savedpc++; |
| 640 | ci->u.l.savedpc++; | 680 | else |
| 681 | donextjump(ci); | ||
| 641 | ) | 682 | ) |
| 642 | vmcase(OP_TESTSET, | 683 | vmcase(OP_TESTSET, |
| 643 | TValue *rb = RB(i); | 684 | TValue *rb = RB(i); |
| 644 | if (GETARG_C(i) ? !l_isfalse(rb) : l_isfalse(rb)) { | 685 | if (GETARG_C(i) ? l_isfalse(rb) : !l_isfalse(rb)) |
| 686 | ci->u.l.savedpc++; | ||
| 687 | else { | ||
| 645 | setobjs2s(L, ra, rb); | 688 | setobjs2s(L, ra, rb); |
| 646 | dojump(GETARG_sBx(*ci->u.l.savedpc)); | 689 | donextjump(ci); |
| 647 | } | 690 | } |
| 648 | ci->u.l.savedpc++; | ||
| 649 | ) | 691 | ) |
| 650 | vmcase(OP_CALL, | 692 | vmcase(OP_CALL, |
| 651 | int b = GETARG_B(i); | 693 | int b = GETARG_B(i); |
| @@ -711,7 +753,7 @@ void luaV_execute (lua_State *L) { · 59 unmodified lines | |||
| 711 | lua_Number limit = nvalue(ra+1); | 753 | lua_Number limit = nvalue(ra+1); |
| 712 | if (luai_numlt(L, 0, step) ? luai_numle(L, idx, limit) | 754 | if (luai_numlt(L, 0, step) ? luai_numle(L, idx, limit) |
| 713 | : luai_numle(L, limit, idx)) { | 755 | : luai_numle(L, limit, idx)) { |
| 714 | dojump(GETARG_sBx(i)); /* jump back */ | 756 | ci->u.l.savedpc += GETARG_sBx(i); /* jump back */ |
| 715 | setnvalue(ra, idx); /* update internal index... */ | 757 | setnvalue(ra, idx); /* update internal index... */ |
| 716 | setnvalue(ra+3, idx); /* ...and external index */ | 758 | setnvalue(ra+3, idx); /* ...and external index */ |
| 717 | } | 759 | } |
| @@ -727,7 +769,7 @@ void luaV_execute (lua_State *L) { · 9 unmodified lines | |||
| 727 | else if (!tonumber(pstep, ra+2)) | 769 | else if (!tonumber(pstep, ra+2)) |
| 728 | luaG_runerror(L, LUA_QL("for") " step must be a number"); | 770 | luaG_runerror(L, LUA_QL("for") " step must be a number"); |
| 729 | setnvalue(ra, luai_numsub(L, nvalue(ra), nvalue(pstep))); | 771 | setnvalue(ra, luai_numsub(L, nvalue(ra), nvalue(pstep))); |
| 730 | dojump(GETARG_sBx(i)); | 772 | ci->u.l.savedpc += GETARG_sBx(i); |
| 731 | ) | 773 | ) |
| 732 | vmcase(OP_TFORCALL, | 774 | vmcase(OP_TFORCALL, |
| 733 | StkId cb = ra + 3; /* call base */ | 775 | StkId cb = ra + 3; /* call base */ |
| @@ -746,7 +788,7 @@ void luaV_execute (lua_State *L) { · 12 unmodified lines | |||
| 746 | l_tforloop: | 788 | l_tforloop: |
| 747 | if (!ttisnil(ra + 1)) { /* continue loop? */ | 789 | if (!ttisnil(ra + 1)) { /* continue loop? */ |
| 748 | setobjs2s(L, ra, ra + 1); /* save control variable */ | 790 | setobjs2s(L, ra, ra + 1); /* save control variable */ |
| 749 | dojump(GETARG_sBx(i)); /* jump back */ | 791 | ci->u.l.savedpc += GETARG_sBx(i); /* jump back */ |
| 750 | } | 792 | } |
| 751 | ) | 793 | ) |
| 752 | vmcase(OP_SETLIST, | 794 | vmcase(OP_SETLIST, |
| @@ -759,6 +801,7 @@ void luaV_execute (lua_State *L) { · 6 unmodified lines | |||
| 759 | lua_assert(GET_OPCODE(*ci->u.l.savedpc) == OP_EXTRAARG); | 801 | lua_assert(GET_OPCODE(*ci->u.l.savedpc) == OP_EXTRAARG); |
| 760 | c = GETARG_Ax(*ci->u.l.savedpc++); | 802 | c = GETARG_Ax(*ci->u.l.savedpc++); |
| 761 | } | 803 | } |
| 804 | luai_runtimecheck(L, ttistable(ra)); | ||
| 762 | h = hvalue(ra); | 805 | h = hvalue(ra); |
| 763 | last = ((c-1)*LFIELDS_PER_FLUSH) + n; | 806 | last = ((c-1)*LFIELDS_PER_FLUSH) + n; |
| 764 | if (last > h->sizearray) /* needs more space? */ | 807 | if (last > h->sizearray) /* needs more space? */ |
| @@ -770,17 +813,18 @@ void luaV_execute (lua_State *L) { · 5 unmodified lines | |||
| 770 | } | 813 | } |
| 771 | L->top = ci->top; /* correct top (in case of previous open call) */ | 814 | L->top = ci->top; /* correct top (in case of previous open call) */ |
| 772 | ) | 815 | ) |
| 773 | vmcase(OP_CLOSE, | ||
| 774 | luaF_close(L, ra); | ||
| 775 | ) | ||
| 776 | vmcase(OP_CLOSURE, | 816 | vmcase(OP_CLOSURE, |
| 777 | Proto *p = cl->p->p[GETARG_Bx(i)]; | 817 | Proto *p = cl->p->p[GETARG_Bx(i)]; |
| 778 | Closure *ncl = getcached(p, cl->upvals, base); /* cached closure */ | 818 | Closure *ncl = getcached(p, cl->upvals, base); /* cached closure */ |
| 779 | if (ncl == NULL) /* no match? */ | 819 | if (ncl == NULL) /* no match? */ |
| 780 | pushclosure(L, p, cl->upvals, base, ra); /* create a new one */ | 820 | pushclosure(L, p, cl->upvals, base, ra); /* create a new one */ |
| 781 | else | 821 | else |
| 782 | setclvalue(L, ra, ncl); /* push cashed closure */ | 822 | setclLvalue(L, ra, ncl); /* push cashed closure */ |
| 783 | checkGC(L); | 823 | checkGC(L, |
| 824 | L->top = ra + 1; /* limit of live values */ | ||
| 825 | luaC_step(L); | ||
| 826 | L->top = ci->top; /* restore top */ | ||
| 827 | ) | ||
| 784 | ) | 828 | ) |
| 785 | vmcase(OP_VARARG, | 829 | vmcase(OP_VARARG, |
| 786 | int b = GETARG_B(i) - 1; | 830 | int b = GETARG_B(i) - 1; |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lvm.h,v 2.14 2009/12/17 16:20:01 roberto Exp $ | 2 | ** $Id: lvm.h,v 2.17 2011/05/31 18:27:56 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 | */ |
| @@ -17,12 +17,15 @@ · 11 unmodified lines | |||
| 17 | 17 | ||
| 18 | #define tonumber(o,n) (ttisnumber(o) || (((o) = luaV_tonumber(o,n)) != NULL)) | 18 | #define tonumber(o,n) (ttisnumber(o) || (((o) = luaV_tonumber(o,n)) != NULL)) |
| 19 | 19 | ||
| 20 | #define equalobj(L,o1,o2) \ | 20 | #define equalobj(L,o1,o2) (ttisequal(o1, o2) && luaV_equalobj_(L, o1, o2)) |
| 21 | (ttype(o1) == ttype(o2) && luaV_equalval_(L, o1, o2)) | 21 | |
| 22 | #define luaV_rawequalobj(t1,t2) \ | ||
| 23 | (ttisequal(t1,t2) && luaV_equalobj_(NULL,t1,t2)) | ||
| 22 | 24 | ||
| 23 | 25 | ||
| 24 | /* not to called directly */ | 26 | /* not to called directly */ |
| 25 | LUAI_FUNC int luaV_equalval_ (lua_State *L, const TValue *t1, const TValue *t2); | 27 | LUAI_FUNC int luaV_equalobj_ (lua_State *L, const TValue *t1, const TValue *t2); |
| 28 | |||
| 26 | 29 | ||
| 27 | LUAI_FUNC int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r); | 30 | LUAI_FUNC int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r); |
| 28 | LUAI_FUNC int luaV_lessequal (lua_State *L, const TValue *l, const TValue *r); | 31 | LUAI_FUNC int luaV_lessequal (lua_State *L, const TValue *l, const TValue *r); |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lzio.c,v 1.31 2005/06/03 20:15:29 roberto Exp $ | 2 | ** $Id: lzio.c,v 1.33 2011/02/23 13:13:10 roberto Exp $ |
| 3 | ** a generic input stream interface | 3 | ** a generic input stream interface |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -25,26 +25,14 @@ int luaZ_fill (ZIO *z) { · 19 unmodified lines | |||
| 25 | lua_unlock(L); | 25 | lua_unlock(L); |
| 26 | buff = z->reader(L, z->data, &size); | 26 | buff = z->reader(L, z->data, &size); |
| 27 | lua_lock(L); | 27 | lua_lock(L); |
| 28 | if (buff == NULL || size == 0) return EOZ; | 28 | if (buff == NULL || size == 0) |
| 29 | z->n = size - 1; | 29 | return EOZ; |
| 30 | z->n = size - 1; /* discount char being returned */ | ||
| 30 | z->p = buff; | 31 | z->p = buff; |
| 31 | return char2int(*(z->p++)); | 32 | return char2int(*(z->p++)); |
| 32 | } | 33 | } |
| 33 | 34 | ||
| 34 | 35 | ||
| 35 | int luaZ_lookahead (ZIO *z) { | ||
| 36 | if (z->n == 0) { | ||
| 37 | if (luaZ_fill(z) == EOZ) | ||
| 38 | return EOZ; | ||
| 39 | else { | ||
| 40 | z->n++; /* luaZ_fill removed first byte; put back it */ | ||
| 41 | z->p--; | ||
| 42 | } | ||
| 43 | } | ||
| 44 | return char2int(*z->p); | ||
| 45 | } | ||
| 46 | |||
| 47 | |||
| 48 | void luaZ_init (lua_State *L, ZIO *z, lua_Reader reader, void *data) { | 36 | void luaZ_init (lua_State *L, ZIO *z, lua_Reader reader, void *data) { |
| 49 | z->L = L; | 37 | z->L = L; |
| 50 | z->reader = reader; | 38 | z->reader = reader; |
| @@ -58,8 +46,14 @@ void luaZ_init (lua_State *L, ZIO *z, lua_Reader reader, void *data) { · 7 unmodified lines | |||
| 58 | size_t luaZ_read (ZIO *z, void *b, size_t n) { | 46 | size_t luaZ_read (ZIO *z, void *b, size_t n) { |
| 59 | while (n) { | 47 | while (n) { |
| 60 | size_t m; | 48 | size_t m; |
| 61 | if (luaZ_lookahead(z) == EOZ) | 49 | if (z->n == 0) { /* no bytes in buffer? */ |
| 62 | return n; /* return number of missing bytes */ | 50 | if (luaZ_fill(z) == EOZ) /* try to read more */ |
| 51 | return n; /* no more input; return number of missing bytes */ | ||
| 52 | else { | ||
| 53 | z->n++; /* luaZ_fill consumed first byte; put it back */ | ||
| 54 | z->p--; | ||
| 55 | } | ||
| 56 | } | ||
| 63 | m = (n <= z->n) ? n : z->n; /* min. between n and z->n */ | 57 | m = (n <= z->n) ? n : z->n; /* min. between n and z->n */ |
| 64 | memcpy(b, z->p, m); | 58 | memcpy(b, z->p, m); |
| 65 | z->n -= m; | 59 | z->n -= m; |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lzio.h,v 1.22 2009/05/18 17:26:25 roberto Exp $ | 2 | ** $Id: lzio.h,v 1.24 2011/02/23 13:13:10 roberto Exp $ |
| 3 | ** Buffered streams | 3 | ** Buffered streams |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -50,7 +50,6 @@ LUAI_FUNC char *luaZ_openspace (lua_State *L, Mbuffer *buff, size_t n); · 44 unmodified lines | |||
| 50 | LUAI_FUNC void luaZ_init (lua_State *L, ZIO *z, lua_Reader reader, | 50 | LUAI_FUNC void luaZ_init (lua_State *L, ZIO *z, lua_Reader reader, |
| 51 | void *data); | 51 | void *data); |
| 52 | LUAI_FUNC size_t luaZ_read (ZIO* z, void* b, size_t n); /* read next n bytes */ | 52 | LUAI_FUNC size_t luaZ_read (ZIO* z, void* b, size_t n); /* read next n bytes */ |
| 53 | LUAI_FUNC int luaZ_lookahead (ZIO *z); | ||
| 54 | 53 | ||
| 55 | 54 | ||
| 56 | 55 | ||
| @@ -59,7 +58,7 @@ LUAI_FUNC int luaZ_lookahead (ZIO *z); · 2 unmodified lines | |||
| 59 | struct Zio { | 58 | struct Zio { |
| 60 | size_t n; /* bytes still unread */ | 59 | size_t n; /* bytes still unread */ |
| 61 | const char *p; /* current position in buffer */ | 60 | const char *p; /* current position in buffer */ |
| 62 | lua_Reader reader; | 61 | lua_Reader reader; /* reader function */ |
| 63 | void* data; /* additional data */ | 62 | void* data; /* additional data */ |
| 64 | lua_State *L; /* Lua state (for reader) */ | 63 | lua_State *L; /* Lua state (for reader) */ |
| 65 | }; | 64 | }; |