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 | 4 | For installation instructions, license details, and |
| 5 | 5 | further information about Lua, see doc/readme.html. |
| @@ -22,7 +22,7 @@ Lua 5.2 Reference Manual · 21 unmodified lines | ||
| 22 | 22 | |
| 23 | 23 | <P> |
| 24 | 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 | 26 | Some details may change in the final version.</EM> |
| 27 | 27 | |
| 28 | 28 | <P> |
| @@ -38,7 +38,7 @@ For a complete introduction to Lua programming, see the book · 9 unmodified lines | ||
| 38 | 38 | <A HREF="#index">index</A> |
| 39 | 39 | <HR> |
| 40 | 40 | <SMALL> |
| 41 | −Copyright © 2010 Lua.org, PUC-Rio. | |
| 41 | +Copyright © 2011 Lua.org, PUC-Rio. | |
| 42 | 42 | Freely available under the terms of the |
| 43 | 43 | <a href="http://www.lua.org/license.html#5">Lua license</a>. |
| 44 | 44 | </SMALL> |
| @@ -120,7 +120,7 @@ Freely available under the terms of the · 75 unmodified lines | ||
| 120 | 120 | </UL> |
| 121 | 121 | <LI><A HREF="manual.html#6.5">6.5 – Table Manipulation</A> |
| 122 | 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 | 124 | <LI><A HREF="manual.html#6.8">6.8 – Input and Output Facilities</A> |
| 125 | 125 | <LI><A HREF="manual.html#6.9">6.9 – Operating System Facilities</A> |
| 126 | 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 | 154 | <A HREF="manual.html#pdf-ipairs">ipairs</A><BR> |
| 155 | 155 | <A HREF="manual.html#pdf-load">load</A><BR> |
| 156 | 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 | 157 | <A HREF="manual.html#pdf-next">next</A><BR> |
| 160 | 158 | <A HREF="manual.html#pdf-pairs">pairs</A><BR> |
| 161 | 159 | <A HREF="manual.html#pdf-pcall">pcall</A><BR> |
| 162 | 160 | <A HREF="manual.html#pdf-print">print</A><BR> |
| 163 | 161 | <A HREF="manual.html#pdf-rawequal">rawequal</A><BR> |
| 164 | 162 | <A HREF="manual.html#pdf-rawget">rawget</A><BR> |
| 163 | +<A HREF="manual.html#pdf-rawlen">rawlen</A><BR> | |
| 165 | 164 | <A HREF="manual.html#pdf-rawset">rawset</A><BR> |
| 166 | 165 | <A HREF="manual.html#pdf-require">require</A><BR> |
| 167 | 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 | 177 | <A HREF="manual.html#pdf-bit32.bor">bit32.bor</A><BR> |
| 179 | 178 | <A HREF="manual.html#pdf-bit32.btest">bit32.btest</A><BR> |
| 180 | 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 | 181 | <A HREF="manual.html#pdf-bit32.lrotate">bit32.lrotate</A><BR> |
| 182 | 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 | 184 | <A HREF="manual.html#pdf-bit32.rrotate">bit32.rrotate</A><BR> |
| 184 | 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 | 476 | <A HREF="manual.html#luaL_dofile">luaL_dofile</A><BR> |
| 476 | 477 | <A HREF="manual.html#luaL_dostring">luaL_dostring</A><BR> |
| 477 | 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 | 481 | <A HREF="manual.html#luaL_getmetafield">luaL_getmetafield</A><BR> |
| 480 | 482 | <A HREF="manual.html#luaL_getmetatable">luaL_getmetatable</A><BR> |
| 483 | +<A HREF="manual.html#luaL_getsubtable">luaL_getsubtable</A><BR> | |
| 481 | 484 | <A HREF="manual.html#luaL_gsub">luaL_gsub</A><BR> |
| 482 | 485 | <A HREF="manual.html#luaL_len">luaL_len</A><BR> |
| 483 | 486 | <A HREF="manual.html#luaL_loadbuffer">luaL_loadbuffer</A><BR> |
| 484 | 487 | <A HREF="manual.html#luaL_loadfile">luaL_loadfile</A><BR> |
| 485 | 488 | <A HREF="manual.html#luaL_loadstring">luaL_loadstring</A><BR> |
| 486 | 489 | <A HREF="manual.html#luaL_newlib">luaL_newlib</A><BR> |
| 490 | +<A HREF="manual.html#luaL_newlibtable">luaL_newlibtable</A><BR> | |
| 487 | 491 | <A HREF="manual.html#luaL_newmetatable">luaL_newmetatable</A><BR> |
| 488 | 492 | <A HREF="manual.html#luaL_newstate">luaL_newstate</A><BR> |
| 489 | 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 | 520 | <HR> |
| 517 | 521 | <SMALL> |
| 518 | 522 | Last update: |
| 519 | −Mon Nov 22 16:38:54 BRST 2010 | |
| 523 | +Mon Jun 13 15:09:33 BRT 2011 | |
| 520 | 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 | 529 | </BODY> |
| @@ -8,6 +8,7 @@ body { · 7 unmodified lines | ||
| 8 | 8 | } |
| 9 | 9 | |
| 10 | 10 | h1, h2, h3, h4 { |
| 11 | + font-family: Verdana, sans-serif ; | |
| 11 | 12 | font-weight: normal ; |
| 12 | 13 | font-style: italic ; |
| 13 | 14 | } |
| @@ -27,7 +28,7 @@ h3 { · 13 unmodified lines | ||
| 27 | 28 | |
| 28 | 29 | table h3 { |
| 29 | 30 | padding-left: 0px ; |
| 30 | − border-left: none ; | |
| 31 | + border-left: none ; | |
| 31 | 32 | } |
| 32 | 33 | |
| 33 | 34 | a:link { |
| @@ -62,3 +63,21 @@ hr { · 28 unmodified lines | ||
| 62 | 63 | padding: 8px ; |
| 63 | 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 | 17 | </h1> |
| 18 | 18 | |
| 19 | 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 | 21 | Some details may change in the final version.</EM> |
| 22 | 22 | <P> |
| 23 | 23 | |
| 24 | 24 | by Roberto Ierusalimschy, Luiz Henrique de Figueiredo, Waldemar Celes |
| 25 | 25 | <p> |
| 26 | 26 | <small> |
| 27 | −Copyright © 2010 Lua.org, PUC-Rio. | |
| 27 | +Copyright © 2011 Lua.org, PUC-Rio. | |
| 28 | 28 | Freely available under the terms of the |
| 29 | 29 | <a href="http://www.lua.org/license.html#5">Lua license</a>. |
| 30 | 30 | </small> |
| @@ -38,7 +38,7 @@ Freely available under the terms of the · 7 unmodified lines | ||
| 38 | 38 | <!-- ====================================================================== --> |
| 39 | 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 | 53 | functional programming, and data-driven programming. |
| 54 | 54 | Lua is intended to be used as a powerful, light-weight |
| 55 | 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 | 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 | 125 | Both <b>nil</b> and <b>false</b> make a condition false; |
| 126 | 126 | any other value makes it true. |
| 127 | 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 | 131 | (It is easy to build Lua interpreters that use other |
| 129 | 132 | internal representations for numbers, |
| 130 | 133 | such as single-precision floats or long integers; |
| 131 | 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 | 137 | Lua is 8-bit clean: |
| 135 | 138 | strings can contain any 8-bit value, |
| @@ -167,11 +170,19 @@ even those that do not support threads. · 31 unmodified lines | ||
| 167 | 170 | <p> |
| 168 | 171 | The type <em>table</em> implements associative arrays, |
| 169 | 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 | 176 | Tables can be <em>heterogeneous</em>; |
| 172 | 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 | 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 | 186 | symbol tables, sets, records, graphs, trees, etc. |
| 176 | 187 | To represent records, Lua uses the field name as an index. |
| 177 | 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 | 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 | 200 | <p> |
| 184 | 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 | 203 | In particular, |
| 187 | 204 | because functions are first-class values, |
| 188 | 205 | table fields can contain functions. |
| 189 | 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 | 217 | <p> |
| 193 | 218 | Tables, functions, threads, and (full) userdata values are <em>objects</em>: |
| 194 | 219 | variables do not actually <em>contain</em> these values, |
| @@ -210,7 +235,7 @@ of a given value. · 15 unmodified lines | ||
| 210 | 235 | |
| 211 | 236 | <p> |
| 212 | 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 | 239 | to <code>_ENV.var</code>. |
| 215 | 240 | Moreover, every chunk is compiled in the scope of an external |
| 216 | 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 | 267 | <p> |
| 243 | 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 | 270 | with the global environment (see <a href="#pdf-load"><code>load</code></a>). |
| 246 | 271 | Therefore, by default, |
| 247 | 272 | global variables in Lua code refer to entries in the global environment. |
| 248 | 273 | Moreover, all standard libraries are loaded in the global environment, |
| 249 | 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 | 276 | (In C, you have to load the chunk and then change the value |
| 252 | 277 | of its first upvalue.) |
| 253 | 278 | |
| @@ -283,7 +308,32 @@ which can take appropriate measures · 29 unmodified lines | ||
| 283 | 308 | Lua code can explicitly generate an error by calling the |
| 284 | 309 | <a href="#pdf-error"><code>error</code></a> function. |
| 285 | 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 | 357 | <p> |
| 308 | 358 | The keys in a metatable are derived from the <em>event</em> names; |
| 309 | 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 | 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 | 674 | <li><b>"index":</b> |
| 625 | 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 | 683 | <pre> |
| @@ -630,6 +685,7 @@ The indexing access <code>table[key]</code>. · 1 unmodified line | ||
| 630 | 685 | local h |
| 631 | 686 | if type(table) == "table" then |
| 632 | 687 | local v = rawget(table, key) |
| 688 | + -- if key is present, return raw value | |
| 633 | 689 | if v ~= nil then return v end |
| 634 | 690 | h = metatable(table).__index |
| 635 | 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 | 706 | <li><b>"newindex":</b> |
| 651 | 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 | 712 | <pre> |
| @@ -656,6 +714,7 @@ The indexing assignment <code>table[key] = value</code>. · 1 unmodified line | ||
| 656 | 714 | local h |
| 657 | 715 | if type(table) == "table" then |
| 658 | 716 | local v = rawget(table, key) |
| 717 | + -- if key is present, do raw assignment | |
| 659 | 718 | if v ~= nil then rawset(table, key, value); return end |
| 660 | 719 | h = metatable(table).__newindex |
| 661 | 720 | if h == nil then rawset(table, key, value); return end |
| @@ -758,7 +817,7 @@ memory usage. · 96 unmodified lines | ||
| 758 | 817 | <p> |
| 759 | 818 | You can change these numbers by calling <a href="#lua_gc"><code>lua_gc</code></a> in C |
| 760 | 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 | 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 | 825 | <h3>2.5.1 – <a name="2.5.1">Garbage-Collection Metamethods</a></h3> |
| 767 | 826 | |
| 768 | 827 | <p> |
| 769 | −Using the C API, | |
| 770 | −you can set garbage-collector metamethods for full userdata (see <a href="#2.4">§2.4</a>). | |
| 828 | +You can set garbage-collector metamethods for tables | |
| 829 | +and, using the C API, | |
| 830 | +for full userdata (see <a href="#2.4">§2.4</a>). | |
| 771 | 831 | These metamethods are also called <em>finalizers</em>. |
| 772 | 832 | Finalizers allow you to coordinate Lua's garbage collection |
| 773 | 833 | with external resource management |
| @@ -776,43 +836,43 @@ or freeing your own memory). · 2 unmodified lines | ||
| 776 | 836 | |
| 777 | 837 | |
| 778 | 838 | <p> |
| 779 | −For a userdata to be finalized when collected, | |
| 839 | +For an object (table or userdata) to be finalized when collected, | |
| 780 | 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 | 843 | and the metatable has a field indexed by the string "<code>__gc</code>". |
| 784 | 844 | Note that if you set a metatable without a <code>__gc</code> field |
| 785 | 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 | 847 | However, after a userdata is marked, |
| 788 | 848 | you can freely change the <code>__gc</code> field of its metatable. |
| 789 | 849 | |
| 790 | 850 | |
| 791 | 851 | <p> |
| 792 | −When a marked userdata becomes garbage, | |
| 852 | +When a marked object becomes garbage, | |
| 793 | 853 | it is not collected immediately by the garbage collector. |
| 794 | 854 | Instead, Lua puts it in a list. |
| 795 | 855 | After the collection, |
| 796 | 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 | 859 | <pre> |
| 800 | − function gc_event (udata) | |
| 801 | − local h = metatable(udata).__gc | |
| 860 | + function gc_event (obj) | |
| 861 | + local h = metatable(obj).__gc | |
| 802 | 862 | if type(h) == "function" then |
| 803 | − h(udata) | |
| 863 | + h(obj) | |
| 804 | 864 | end |
| 805 | 865 | end |
| 806 | 866 | </pre> |
| 807 | 867 | |
| 808 | 868 | <p> |
| 809 | 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 | 871 | the reverse order that they were marked for collection, |
| 812 | 872 | among those collected in that cycle; |
| 813 | 873 | that is, the first finalizer to be called is the one associated |
| 814 | −with the userdata marked last in the program. | |
| 815 | −The userdata memory is freed only in the next garbage-collection cycle. | |
| 874 | +with the object marked last in the program. | |
| 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 | 935 | <p> |
| 876 | −Userdata marked for finalization have a special behavior in weak tables. | |
| 877 | −When a marked userdata is a value in a weak table, | |
| 878 | −it is removed from the table the first time it is collected, | |
| 879 | −before running its finalizer. | |
| 936 | +Objects marked for finalization have a special behavior in weak tables. | |
| 937 | +When a marked object is a value in a weak table, | |
| 938 | +it is removed from the table before running its finalizer. | |
| 880 | 939 | However, when it is a key, |
| 881 | −it is removed from the table only when it is really freed, | |
| 882 | −after running its finalizer. | |
| 883 | −This behavior allows the finalizer to access values | |
| 884 | −associated with the userdata through weak tables. | |
| 940 | +it is removed from the table only after running its finalizer. | |
| 941 | +This behavior allows the finalizer to access properties | |
| 942 | +associated with the object through weak tables. | |
| 885 | 943 | |
| 886 | 944 | |
| 887 | 945 | |
| @@ -980,7 +1038,7 @@ consider the following code: · 92 unmodified lines | ||
| 980 | 1038 | print("co-body", r, s) |
| 981 | 1039 | return b, "end" |
| 982 | 1040 | end) |
| 983 | − | |
| 1041 | + | |
| 984 | 1042 | print("main", coroutine.resume(co, 1, 10)) |
| 985 | 1043 | print("main", coroutine.resume(co, "r")) |
| 986 | 1044 | print("main", coroutine.resume(co, "x", "y")) |
| @@ -1048,8 +1106,7 @@ except as delimiters between names and keywords. · 61 unmodified lines | ||
| 1048 | 1106 | in Lua can be any string of letters, |
| 1049 | 1107 | digits, and underscores, |
| 1050 | 1108 | not beginning with a digit. |
| 1051 | −This coincides with the definition of names in most languages. | |
| 1052 | −Identifiers are used to name variables and table fields. | |
| 1109 | +Identifiers are used to name variables, table fields, and labels. | |
| 1053 | 1110 | |
| 1054 | 1111 | |
| 1055 | 1112 | <p> |
| @@ -1058,10 +1115,10 @@ and cannot be used as names: · 2 unmodified lines | ||
| 1058 | 1115 | |
| 1059 | 1116 | |
| 1060 | 1117 | <pre> |
| 1061 | − and break do else elseif | |
| 1062 | − end false for function if | |
| 1063 | − in local nil not or | |
| 1064 | − repeat return then true until while | |
| 1118 | + and break do else elseif end | |
| 1119 | + false for function goto if in | |
| 1120 | + local nil not or repeat return | |
| 1121 | + then true until while | |
| 1065 | 1122 | </pre> |
| 1066 | 1123 | |
| 1067 | 1124 | <p> |
| @@ -1102,7 +1159,7 @@ results in a newline in the string. · 34 unmodified lines | ||
| 1102 | 1159 | The escape sequence '<code>\*</code>' skips the following span |
| 1103 | 1160 | of white-space characters, |
| 1104 | 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 | 1163 | into multiple lines without adding the newlines and spaces |
| 1107 | 1164 | into the string contents. |
| 1108 | 1165 | |
| @@ -1140,9 +1197,18 @@ Any kind of end-of-line sequence · 31 unmodified lines | ||
| 1140 | 1197 | (carriage return, newline, carriage return followed by newline, |
| 1141 | 1198 | or newline followed by carriage return) |
| 1142 | 1199 | is converted to a simple newline. |
| 1143 | −You should not use long strings for non-text data; | |
| 1144 | −Use instead a regular quoted literal with explicit escape sequences | |
| 1145 | −for control characters. | |
| 1200 | + | |
| 1201 | + | |
| 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 | 1214 | <p> |
| @@ -1166,14 +1232,19 @@ the five literal strings below denote the same string: · 17 unmodified lines | ||
| 1166 | 1232 | </pre> |
| 1167 | 1233 | |
| 1168 | 1234 | <p> |
| 1169 | −A <em>numerical constant</em> can be written with an optional decimal part | |
| 1170 | −and an optional decimal exponent. | |
| 1171 | −Lua also accepts integer hexadecimal constants, | |
| 1172 | −by prefixing them with <code>0x</code>. | |
| 1235 | +A <em>numerical constant</em> can be written with an optional fractional part | |
| 1236 | +and an optional decimal exponent, | |
| 1237 | +marked by a letter '<code>e</code>' or '<code>E</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 | 1243 | Examples of valid numerical constants are |
| 1174 | 1244 | |
| 1175 | 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 | 1248 | </pre> |
| 1178 | 1249 | |
| 1179 | 1250 | <p> |
| @@ -1194,7 +1265,6 @@ Long comments are frequently used to disable code temporarily. · 14 unmodified lines | ||
| 1194 | 1265 | |
| 1195 | 1266 | <p> |
| 1196 | 1267 | Variables are places that store values. |
| 1197 | − | |
| 1198 | 1268 | There are three kinds of variables in Lua: |
| 1199 | 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 | 1363 | Explicit blocks are useful |
| 1294 | 1364 | to control the scope of variable declarations. |
| 1295 | 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 | 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 | 1382 | </pre> |
| 1313 | 1383 | |
| 1314 | 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 | 1386 | with a variable number of arguments |
| 1317 | 1387 | (see <a href="#3.4.10">§3.4.10</a>). |
| 1318 | 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 | 1524 | <p> |
| 1455 | −The <b>return</b> statement is used to return values | |
| 1456 | −from a function or a chunk (which is just a function). | |
| 1525 | +The <b>goto</b> statement transfers the program control to a label. | |
| 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 | 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 | 1535 | </pre> |
| 1464 | 1536 | |
| 1465 | 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 | 1551 | <b>while</b>, <b>repeat</b>, or <b>for</b> loop, |
| 1468 | 1552 | skipping to the next statement after the loop: |
| 1469 | 1553 | |
| 1470 | 1554 | |
| 1471 | 1555 | <pre> |
| 1472 | − stat ::= <b>break</b> [‘<b>;</b>’] | |
| 1556 | + stat ::= <b>break</b> | |
| 1473 | 1557 | </pre><p> |
| 1474 | 1558 | A <b>break</b> ends the innermost enclosing loop. |
| 1475 | 1559 | |
| 1476 | 1560 | |
| 1477 | 1561 | <p> |
| 1478 | −The <b>return</b> and <b>break</b> | |
| 1479 | −statements can only be written as the <em>last</em> statement of a block. | |
| 1480 | −If it is really necessary to <b>return</b> or <b>break</b> in the | |
| 1481 | −middle of a block, | |
| 1562 | +The <b>return</b> statement is used to return values | |
| 1563 | +from a function or a chunk (which is a function in disguise). | |
| 1564 | + | |
| 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 | 1576 | then an explicit inner block can be used, |
| 1483 | −as in the idioms | |
| 1484 | −<code>do return end</code> and <code>do break end</code>, | |
| 1485 | −because now <b>return</b> and <b>break</b> are the last statements in | |
| 1486 | −their (inner) blocks. | |
| 1577 | +as in the idiom <code>do return end</code>, | |
| 1578 | +because now <b>return</b> is the last statement in its (inner) block. | |
| 1487 | 1579 | |
| 1488 | 1580 | |
| 1489 | 1581 | |
| @@ -1582,8 +1674,8 @@ is equivalent to the code: · 92 unmodified lines | ||
| 1582 | 1674 | local <em>f</em>, <em>s</em>, <em>var</em> = <em>explist</em> |
| 1583 | 1675 | while true do |
| 1584 | 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 | 1678 | <em>var</em> = <em>var_1</em> |
| 1586 | − if <em>var</em> == nil then break end | |
| 1587 | 1679 | <em>block</em> |
| 1588 | 1680 | end |
| 1589 | 1681 | end |
| @@ -1649,7 +1741,6 @@ Otherwise, all variables are initialized with <b>nil</b>. · 59 unmodified lines | ||
| 1649 | 1741 | <p> |
| 1650 | 1742 | A chunk is also a block (see <a href="#3.3.2">§3.3.2</a>), |
| 1651 | 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 | 1746 | <p> |
| @@ -1671,7 +1762,7 @@ The basic expressions in Lua are the following: · 15 unmodified lines | ||
| 1671 | 1762 | exp ::= <b>nil</b> | <b>false</b> | <b>true</b> |
| 1672 | 1763 | exp ::= Number |
| 1673 | 1764 | exp ::= String |
| 1674 | − exp ::= function | |
| 1765 | + exp ::= functiondef | |
| 1675 | 1766 | exp ::= tableconstructor |
| 1676 | 1767 | exp ::= ‘<b>...</b>’ |
| 1677 | 1768 | exp ::= exp binop exp |
| @@ -1776,7 +1867,9 @@ the quotient towards minus infinity. · 98 unmodified lines | ||
| 1776 | 1867 | Lua provides automatic conversion between |
| 1777 | 1868 | string and number values at run time. |
| 1778 | 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 | 1873 | Conversely, whenever a number is used where a string is expected, |
| 1781 | 1874 | the number is converted to a string, in a reasonable format. |
| 1782 | 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 | 1895 | Otherwise, the values of the operands are compared. |
| 1803 | 1896 | Numbers and strings are compared in the usual way. |
| 1804 | 1897 | Tables, userdata, and threads |
| 1805 | −are compared by <em>reference</em>: | |
| 1806 | −two objects are considered equal only if they are the <em>same</em> object. | |
| 1898 | +are compared by reference: | |
| 1899 | +two objects are considered equal only if they are the same object. | |
| 1807 | 1900 | Every time you create a new object |
| 1808 | 1901 | (a table, userdata, or thread), |
| 1809 | 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 | 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 | 1910 | by using the "eq" metamethod (see <a href="#2.4">§2.4</a>). |
| 1818 | 1911 | |
| 1819 | 1912 | |
| 1820 | 1913 | <p> |
| 1821 | 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 | 1916 | Thus, <code>"0"==0</code> evaluates to <b>false</b>, |
| 1824 | 1917 | and <code>t[0]</code> and <code>t["0"]</code> denote different |
| 1825 | 1918 | entries in a table. |
| @@ -1902,25 +1995,27 @@ character is one byte). · 76 unmodified lines | ||
| 1902 | 1995 | |
| 1903 | 1996 | |
| 1904 | 1997 | <p> |
| 1905 | −The length of a table <code>t</code> can be any integer index <code>n</code> | |
| 1906 | −such that <code>t[n]</code> is not <b>nil</b> and <code>t[n+1]</code> is <b>nil</b>; | |
| 1907 | −moreover, if <code>t[1]</code> is <b>nil</b>, <code>n</code> can be zero. | |
| 1908 | −(All accesses are assumed to be raw for this description.) | |
| 1909 | −For a regular array, where all non-nil values | |
| 1910 | −have keys from 1 to a given <code>n</code>, | |
| 1911 | −its length is exactly that <code>n</code>, | |
| 1912 | −the index of its last value. | |
| 1913 | −If the array has "holes" | |
| 1914 | −(that is, <b>nil</b> values between other non-nil values), | |
| 1915 | −then <code>#t</code> can be any of the indices that | |
| 1916 | −directly precedes a <b>nil</b> value | |
| 1917 | −(that is, it may consider any such <b>nil</b> value as the end of | |
| 1918 | −the array). | |
| 1998 | +The length of a table <code>t</code> is only defined if the | |
| 1999 | +table is a <em>sequence</em>, | |
| 2000 | +that is, | |
| 2001 | +all its numeric keys comprise the set <em>{1..n}</em> for some integer <em>n</em>. | |
| 2002 | +In that case, <em>n</em> is its length. | |
| 2003 | +Note that a table like | |
| 2004 | + | |
| 2005 | +<pre> | |
| 2006 | + {10, 20, nil, 40} | |
| 2007 | +</pre><p> | |
| 2008 | +is not a sequence, because it has the key <code>4</code> | |
| 2009 | +but does not have the key <code>3</code>. | |
| 2010 | +(So, there is no <em>n</em> such that the set <em>{1..n}</em> is equal | |
| 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 | 2016 | <p> |
| 1922 | 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 | 2094 | and the expression is a function call or a vararg expression, |
| 2000 | 2095 | then all values returned by this expression enter the list consecutively |
| 2001 | 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 | 2099 | <p> |
| @@ -2060,7 +2152,7 @@ that is, the argument list is a single literal string. · 52 unmodified lines | ||
| 2060 | 2152 | |
| 2061 | 2153 | |
| 2062 | 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 | 2156 | a <em>tail call</em>. |
| 2065 | 2157 | Lua implements <em>proper tail calls</em> |
| 2066 | 2158 | (or <em>proper tail recursion</em>): |
| @@ -2093,7 +2185,7 @@ So, none of the following examples are tail calls: · 26 unmodified lines | ||
| 2093 | 2185 | The syntax for function definition is |
| 2094 | 2186 | |
| 2095 | 2187 | <pre> |
| 2096 | − function ::= <b>function</b> funcbody | |
| 2188 | + functiondef ::= <b>function</b> funcbody | |
| 2097 | 2189 | funcbody ::= ‘<b>(</b>’ [parlist] ‘<b>)</b>’ block <b>end</b> |
| 2098 | 2190 | </pre> |
| 2099 | 2191 | |
| @@ -2135,7 +2227,7 @@ translates to · 35 unmodified lines | ||
| 2135 | 2227 | <pre> |
| 2136 | 2228 | local f; f = function () <em>body</em> end |
| 2137 | 2229 | </pre><p> |
| 2138 | −<em>not</em> to | |
| 2230 | +not to | |
| 2139 | 2231 | |
| 2140 | 2232 | <pre> |
| 2141 | 2233 | local f = function () <em>body</em> end |
| @@ -2153,8 +2245,6 @@ Then, whenever Lua executes the function definition, · 11 unmodified lines | ||
| 2153 | 2245 | the function is <em>instantiated</em> (or <em>closed</em>). |
| 2154 | 2246 | This function instance (or <em>closure</em>) |
| 2155 | 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 | 2250 | <p> |
| @@ -2249,9 +2339,9 @@ is syntactic sugar for · 88 unmodified lines | ||
| 2249 | 2339 | <p> |
| 2250 | 2340 | |
| 2251 | 2341 | Lua is a lexically scoped language. |
| 2252 | −The scope of variables begins at the first statement <em>after</em> | |
| 2253 | −their declaration and lasts until the end of the innermost block that | |
| 2254 | −includes the declaration. | |
| 2342 | +The scope of a local variable begins at the first statement after | |
| 2343 | +its declaration and lasts until the last non-void statement | |
| 2344 | +of the innermost block that includes the declaration. | |
| 2255 | 2345 | Consider the following example: |
| 2256 | 2346 | |
| 2257 | 2347 | <pre> |
| @@ -2356,9 +2446,9 @@ For convenience, · 98 unmodified lines | ||
| 2356 | 2446 | most query operations in the API do not follow a strict stack discipline. |
| 2357 | 2447 | Instead, they can refer to any element in the stack |
| 2358 | 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 | 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 | 2452 | More specifically, if the stack has <em>n</em> elements, |
| 2363 | 2453 | then index 1 represents the first element |
| 2364 | 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 | 2684 | Instead, Lua calls a <em>continuation function</em>, |
| 2595 | 2685 | which was given as an argument to the callee function. |
| 2596 | 2686 | As the name implies, |
| 2597 | −the continuation function should continue the task | |
| 2687 | +the continuation function should continue the task | |
| 2598 | 2688 | of the original function. |
| 2599 | 2689 | |
| 2600 | 2690 | |
| @@ -2684,8 +2774,7 @@ is being allocated; · 83 unmodified lines | ||
| 2684 | 2774 | |
| 2685 | 2775 | <p> |
| 2686 | 2776 | When <code>ptr</code> is not <code>NULL</code>, |
| 2687 | −<code>osize</code> is the previous size of the block | |
| 2688 | −pointed by <code>ptr</code>, | |
| 2777 | +<code>osize</code> is the size of the block pointed by <code>ptr</code>, | |
| 2689 | 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 | 2796 | <p> |
| 2708 | −When <code>nsize</code> is zero: | |
| 2709 | −if <code>ptr</code> is not <code>NULL</code>, | |
| 2710 | −the allocator should free the block pointed to by <code>ptr</code>. | |
| 2711 | −Anyway, the allocator must return <code>NULL</code>. | |
| 2797 | +When <code>nsize</code> is zero, | |
| 2798 | +the allocator should behave like <code>free</code> | |
| 2799 | +and return <code>NULL</code>. | |
| 2712 | 2800 | |
| 2713 | 2801 | |
| 2714 | 2802 | <p> |
| 2715 | −When <code>nsize</code> is not zero: | |
| 2716 | −if <code>ptr</code> is <code>NULL</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>. | |
| 2803 | +When <code>nsize</code> is not zero, | |
| 2804 | +the allocator should behave like <code>realloc</code>. | |
| 2720 | 2805 | The allocator returns <code>NULL</code> |
| 2721 | 2806 | if and only if it cannot fill the request. |
| 2722 | 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 | 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 | 2840 | <pre>int lua_arith (lua_State *L, int op);</pre> |
| 2756 | 2841 | |
| 2757 | 2842 | <p> |
| 2758 | −Performs an arithmetic operation over the two values at the top | |
| 2759 | −of the stack (with the value at the top being the second operand), | |
| 2843 | +Performs an arithmetic operation over the two values | |
| 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 | 2847 | pops these values, and pushes the result of the operation. |
| 2761 | 2848 | The function follows the semantics of the corresponding Lua operator |
| 2762 | 2849 | (that is, it may call metamethods). |
| @@ -2824,7 +2911,7 @@ when the function is called. · 61 unmodified lines | ||
| 2824 | 2911 | The function results are pushed onto the stack when the function returns. |
| 2825 | 2912 | The number of results is adjusted to <code>nresults</code>, |
| 2826 | 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 | 2915 | Lua takes care that the returned values fit into the stack space. |
| 2829 | 2916 | The function results are pushed onto the stack in direct order |
| 2830 | 2917 | (the first result is pushed first), |
| @@ -3028,10 +3115,13 @@ without shifting any element · 197 unmodified lines | ||
| 3028 | 3115 | |
| 3029 | 3116 | <p> |
| 3030 | 3117 | Creates a new empty table and pushes it onto the stack. |
| 3031 | −The new table has space pre-allocated | |
| 3032 | −for <code>narr</code> array elements and <code>nrec</code> non-array elements. | |
| 3033 | −This pre-allocation is useful when you know exactly how many elements | |
| 3118 | +Parameter <code>narr</code> is a hint for how many elements the table | |
| 3119 | +will have as a sequence; | |
| 3120 | +parameter <code>nrec</code> is a hint for how many other elements | |
| 3034 | 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 | 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 | 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 | 3750 | While traversing a table, |
| 3656 | 3751 | do not call <a href="#lua_tolstring"><code>lua_tolstring</code></a> directly on a key, |
| 3657 | 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 | 3754 | the value at the given index; |
| 3660 | 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 | 3779 | <hr><h3><a name="lua_pcall"><code>lua_pcall</code></a></h3><p> |
| 3685 | 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 | 3783 | <p> |
| 3689 | 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 | 3801 | <p> |
| 3707 | −If <code>errfunc</code> is 0, | |
| 3802 | +If <code>msgh</code> is 0, | |
| 3708 | 3803 | then the error message returned on the stack |
| 3709 | 3804 | is exactly the original error message. |
| 3710 | −Otherwise, <code>errfunc</code> is the stack index of an | |
| 3711 | −<em>error handler function</em>. | |
| 3805 | +Otherwise, <code>msgh</code> is the stack index of a | |
| 3806 | +<em>message handler</em>. | |
| 3712 | 3807 | (In the current implementation, this index cannot be a pseudo-index.) |
| 3713 | 3808 | In case of runtime errors, |
| 3714 | 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 | 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 | 3816 | information to the error message, such as a stack traceback. |
| 3721 | 3817 | Such information cannot be gathered after the return of <a href="#lua_pcall"><code>lua_pcall</code></a>, |
| 3722 | 3818 | since by then the stack has unwound. |
| @@ -3737,11 +3833,11 @@ a runtime error. · 14 unmodified lines | ||
| 3737 | 3833 | |
| 3738 | 3834 | <li><b><a name="pdf-LUA_ERRMEM"><code>LUA_ERRMEM</code></a>:</b> |
| 3739 | 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 | 3837 | </li> |
| 3742 | 3838 | |
| 3743 | 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 | 3841 | </li> |
| 3746 | 3842 | |
| 3747 | 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 | 4040 | Lua makes (or reuses) an internal copy of the given string, |
| 3945 | 4041 | so the memory at <code>s</code> can be freed or reused immediately after |
| 3946 | 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 | 4047 | <p> |
| @@ -3986,8 +4083,6 @@ onto the stack. · 35 unmodified lines | ||
| 3986 | 4083 | Lua makes (or reuses) an internal copy of the given string, |
| 3987 | 4084 | so the memory at <code>s</code> can be freed or reused immediately after |
| 3988 | 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 | 4088 | <p> |
| @@ -4249,14 +4344,11 @@ with user data <code>ud</code>. · 255 unmodified lines | ||
| 4249 | 4344 | |
| 4250 | 4345 | <hr><h3><a name="lua_setuservalue"><code>lua_setuservalue</code></a></h3><p> |
| 4251 | 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 | 4349 | <p> |
| 4255 | 4350 | Pops a table or <b>nil</b> from the stack and sets it as |
| 4256 | 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 | 4389 | <hr><h3><a name="lua_setmetatable"><code>lua_setmetatable</code></a></h3><p> |
| 4298 | 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 | 4393 | <p> |
| 4302 | 4394 | Pops a table from the stack and |
| @@ -4716,7 +4808,7 @@ calling the writer again. · 413 unmodified lines | ||
| 4716 | 4808 | <pre>void lua_xmove (lua_State *from, lua_State *to, int n);</pre> |
| 4717 | 4809 | |
| 4718 | 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 | 4814 | <p> |
| @@ -5033,17 +5125,14 @@ In the first case, · 310 unmodified lines | ||
| 5033 | 5125 | the parameter <code>ar</code> must be a valid activation record that was |
| 5034 | 5126 | filled by a previous call to <a href="#lua_getstack"><code>lua_getstack</code></a> or |
| 5035 | 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 | |
| 5037 | −(1 is the first parameter or active local variable, and so on, | |
| 5038 | −until the last active local variable). | |
| 5039 | −<a href="#lua_getlocal"><code>lua_getlocal</code></a> pushes the variable's value onto the stack | |
| 5040 | −and returns its name. | |
| 5128 | +The index <code>n</code> selects which local variable to inspect; | |
| 5129 | +see <a href="#pdf-debug.getlocal"><code>debug.getlocal</code></a> for details about variable indices | |
| 5130 | +and names. | |
| 5041 | 5131 | |
| 5042 | 5132 | |
| 5043 | 5133 | <p> |
| 5044 | −Variable names starting with '<code>(</code>' (open parentheses) | |
| 5045 | −represent internal variables | |
| 5046 | −(loop control variables, temporaries, and C function locals). | |
| 5134 | +<a href="#lua_getlocal"><code>lua_getlocal</code></a> pushes the variable's value onto the stack | |
| 5135 | +and returns its name. | |
| 5047 | 5136 | |
| 5048 | 5137 | |
| 5049 | 5138 | <p> |
| @@ -5176,7 +5265,8 @@ before the function gets its arguments. · 126 unmodified lines | ||
| 5176 | 5265 | |
| 5177 | 5266 | <li><b>The return hook:</b> is called when the interpreter returns from a function. |
| 5178 | 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 | 5270 | </li> |
| 5181 | 5271 | |
| 5182 | 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 | 5376 | The <em>auxiliary library</em> provides several convenient functions |
| 5287 | 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 | 5379 | interactions between C and Lua, |
| 5290 | 5380 | the auxiliary library provides higher-level functions for some |
| 5291 | 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> | |
| 5820 | −<span class="apii">[-0, +1, <em>m</em>]</span> | |
| 5821 | −<pre>void luaL_findtable (lua_State *L, int idx, const char *fname);</pre> | |
| 5909 | +<hr><h3><a name="luaL_execresult"><code>luaL_execresult</code></a></h3><p> | |
| 5910 | +<span class="apii">[-0, +(1/3), <em>m</em>]</span> | |
| 5911 | +<pre>int luaL_execresult (lua_State *L, int stat);</pre> | |
| 5822 | 5912 | |
| 5823 | 5913 | <p> |
| 5824 | −Ensures that the value <code>t[fname]</code>, | |
| 5825 | −where <code>t</code> is the value at the valid index <code>idx</code>, | |
| 5826 | −is a table, | |
| 5827 | −and pushes that table onto the stack. | |
| 5914 | +This function produces the return values for | |
| 5915 | +process-related functions in the standard library | |
| 5916 | +(<a href="#pdf-os.execute"><code>os.execute</code></a> and <a href="#pdf-io.close"><code>io.close</code></a>). | |
| 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 | 5979 | <hr><h3><a name="luaL_gsub"><code>luaL_gsub</code></a></h3><p> |
| 5861 | 5980 | <span class="apii">[-0, +1, <em>m</em>]</span> |
| 5862 | 5981 | <pre>const char *luaL_gsub (lua_State *L, |
| @@ -5965,13 +6084,27 @@ it does not run it. · 102 unmodified lines | ||
| 5965 | 6084 | <pre>int luaL_newlib (lua_State *L, const luaL_Reg *l);</pre> |
| 5966 | 6085 | |
| 5967 | 6086 | <p> |
| 5968 | −Equivalent to <a href="#luaL_setfuncs"><code>luaL_setfuncs</code></a> with no upvalues, | |
| 5969 | −but first creates a new table wherein to register the functions | |
| 5970 | −in list <code>l</code>. | |
| 6087 | +Creates a new table and registers there | |
| 6088 | +the functions 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 | 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 | 6110 | <p> |
| @@ -6176,7 +6309,7 @@ Returns an address to a space of size <code>sz</code> · 198 unmodified lines | ||
| 6176 | 6309 | where you can copy a string to be added to buffer <code>B</code> |
| 6177 | 6310 | (see <a href="#luaL_Buffer"><code>luaL_Buffer</code></a>). |
| 6178 | 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 | 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 | 6417 | Registers all functions in the array <code>l</code> |
| 6285 | 6418 | (see <a href="#luaL_Reg"><code>luaL_Reg</code></a>) into the table on the top of the stack |
| 6286 | 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 | 6422 | <p> |
| @@ -6495,7 +6626,7 @@ e.g., by using <a href="#lua_call"><code>lua_call</code></a>. · 203 unmodified lines | ||
| 6495 | 6626 | <p> |
| 6496 | 6627 | The basic library provides some core functions to Lua. |
| 6497 | 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 | 6630 | implementations for some of its facilities. |
| 6500 | 6631 | |
| 6501 | 6632 | |
| @@ -6526,11 +6657,13 @@ This is the default option. · 24 unmodified lines | ||
| 6526 | 6657 | </li> |
| 6527 | 6658 | |
| 6528 | 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 | 6663 | </li> |
| 6531 | 6664 | |
| 6532 | 6665 | <li><b>"restart":</b> |
| 6533 | −restarts the garbage collector. | |
| 6666 | +restarts automatic invocation the garbage collector. | |
| 6534 | 6667 | </li> |
| 6535 | 6668 | |
| 6536 | 6669 | <li><b>"count":</b> |
| @@ -6543,6 +6676,8 @@ so the following equality is always true: · 6 unmodified lines | ||
| 6543 | 6676 | k, b = collectgarbage("count") |
| 6544 | 6677 | assert(k*1024 == math.floor(k)*1024 + b) |
| 6545 | 6678 | </pre><p> |
| 6679 | +(The second result is useful when Lua is compiled | |
| 6680 | +with a non floating-point type for numbers.) | |
| 6546 | 6681 | </li> |
| 6547 | 6682 | |
| 6548 | 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 | 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 | 6799 | <p> |
| @@ -6666,32 +6801,35 @@ Loads a chunk. · 1 unmodified line | ||
| 6666 | 6801 | |
| 6667 | 6802 | |
| 6668 | 6803 | <p> |
| 6804 | +If <code>ld</code> is a string, the chunk is this string. | |
| 6669 | 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 | 6807 | Each call to <code>ld</code> must return a string that concatenates |
| 6672 | 6808 | with previous results. |
| 6673 | 6809 | A return of an empty string, <b>nil</b>, or no value signals the end of the chunk. |
| 6674 | 6810 | |
| 6675 | 6811 | |
| 6676 | 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 | 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 | 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 | 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 | 6827 | <p> |
| 6691 | 6828 | <code>source</code> is used as the source of the chunk for error messages |
| 6692 | 6829 | and debug information (see <a href="#4.9">§4.9</a>). |
| 6693 | 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 | 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 | 6845 | <p> |
| 6723 | 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 | 6858 | <p> |
| 6759 | 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 | 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 | 6888 | during the traversal, |
| 6789 | 6889 | you assign any value to a non-existent field in the table. |
| 6790 | 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 | 6985 | <p> |
| 6876 | 6986 | <hr><h3><a name="pdf-rawset"><code>rawset (table, index, value)</code></a></h3> |
| 6877 | 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 | 7044 | In bases above 10, the letter '<code>A</code>' (in either upper or lower case) |
| 6935 | 7045 | represents 10, '<code>B</code>' represents 11, and so forth, |
| 6936 | 7046 | with '<code>Z</code>' representing 35. |
| 6937 | −In base 10 (the default), the number can have a decimal part, | |
| 6938 | −as well as an optional exponent part (see <a href="#3.1">§3.1</a>). | |
| 6939 | −In other bases, only unsigned integers are accepted. | |
| 7047 | +In base 10 (the default), | |
| 7048 | +the numeral is converted following the coercion rules (see <a href="#3.4.2">§3.4.2</a>). | |
| 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 | 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 | 7100 | <p> |
| 6991 | 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 | 7241 | <p> |
| 7132 | 7242 | To find a loader, |
| 7133 | −<code>require</code> is guided by the <a href="#pdf-package.loaders"><code>package.loaders</code></a> array. | |
| 7134 | −By changing this array, | |
| 7243 | +<code>require</code> is guided by the <a href="#pdf-package.loaders"><code>package.loaders</code></a> sequence. | |
| 7244 | +By changing this sequence, | |
| 7135 | 7245 | we can change how <code>require</code> looks for a module. |
| 7136 | 7246 | The following explanation is based on the default configuration |
| 7137 | 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 | 7262 | <p> |
| 7153 | 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 | 7268 | If the loader returns any non-nil value, |
| 7156 | 7269 | <code>require</code> assigns the returned value to <code>package.loaded[modname]</code>. |
| 7157 | 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 | 7277 | <p> |
| 7165 | 7278 | If there is any error loading or running the module, |
| 7166 | 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 | 7368 | with the module name (the argument given to <a href="#pdf-require"><code>require</code></a>) as its |
| 7256 | 7369 | sole parameter. |
| 7257 | 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 | 7372 | or a string explaining why it did not find that module |
| 7259 | 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 | 7380 | <p> |
| @@ -7313,6 +7430,13 @@ into one single library, · 49 unmodified lines | ||
| 7313 | 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 | 7442 | <p> |
| @@ -7384,10 +7508,16 @@ A table to store loaders for specific modules · 65 unmodified lines | ||
| 7384 | 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 | 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 | 7523 | <p> |
| @@ -7400,8 +7530,15 @@ A path is string containing a sequence of · 6 unmodified lines | ||
| 7400 | 7530 | For each template, |
| 7401 | 7531 | the function changes each interrogation |
| 7402 | 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 | 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 | 7542 | For instance, if the path is the string |
| 7406 | 7543 | |
| 7407 | 7544 | <pre> |
| @@ -7485,9 +7622,8 @@ Note that numerical codes are not necessarily portable across platforms. · 77 unmodified lines | ||
| 7485 | 7622 | |
| 7486 | 7623 | <p> |
| 7487 | 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 | |
| 7489 | −a copy of the function. | |
| 7490 | −<code>function</code> must be a Lua function without upvalues. | |
| 7625 | +so that a later <a href="#pdf-load"><code>load</code></a> on this string returns | |
| 7626 | +a copy of the function (but with new upvalues). | |
| 7491 | 7627 | |
| 7492 | 7628 | |
| 7493 | 7629 | |
| @@ -7552,16 +7688,19 @@ will produce the string: · 58 unmodified lines | ||
| 7552 | 7688 | </pre> |
| 7553 | 7689 | |
| 7554 | 7690 | <p> |
| 7555 | −The options <code>c</code>, <code>d</code>, <code>E</code>, <code>e</code>, <code>f</code>, | |
| 7556 | −<code>g</code>, <code>G</code>, <code>i</code>, <code>o</code>, <code>u</code>, <code>X</code>, and <code>x</code> all | |
| 7557 | −expect a number as argument, | |
| 7558 | −whereas <code>q</code> and <code>s</code> expect a string. | |
| 7559 | − | |
| 7560 | − | |
| 7561 | −<p> | |
| 7562 | −This function does not accept string values | |
| 7563 | −containing embedded zeros, | |
| 7564 | −except as arguments to the <code>q</code> option. | |
| 7691 | +Options | |
| 7692 | +<code>A</code> and <code>a</code> (when available), | |
| 7693 | +<code>E</code>, <code>e</code>, <code>f</code>, | |
| 7694 | +<code>G</code>, and <code>g</code> all expect a number as argument. | |
| 7695 | +Options <code>c</code>, <code>d</code>, | |
| 7696 | +<code>i</code>, <code>o</code>, <code>u</code>, <code>X</code>, and <code>x</code> | |
| 7697 | +expect an integer as argument; | |
| 7698 | +the range of that integer may be limited by | |
| 7699 | +the underlying C implementation. | |
| 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 | 7717 | <p> |
| 7579 | 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 | 7722 | <pre> |
| 7582 | 7723 | s = "hello world from Lua" |
| @@ -7584,8 +7725,6 @@ As an example, the following loop · 1 unmodified line | ||
| 7584 | 7725 | print(w) |
| 7585 | 7726 | end |
| 7586 | 7727 | </pre><p> |
| 7587 | −will iterate over all the words from string <code>s</code>, | |
| 7588 | −printing one per line. | |
| 7589 | 7728 | The next example collects all pairs <code>key=value</code> from the |
| 7590 | 7729 | given string into a table: |
| 7591 | 7730 | |
| @@ -7667,7 +7806,7 @@ Here are some examples: · 75 unmodified lines | ||
| 7667 | 7806 | --> x="home = /home/roberto, user = roberto" |
| 7668 | 7807 | |
| 7669 | 7808 | x = string.gsub("4+5 = $return 4+5$", "%$(.-)%$", function (s) |
| 7670 | − return loadstring(s)() | |
| 7809 | + return load(s)() | |
| 7671 | 7810 | end) |
| 7672 | 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 | 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 | 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 | 8008 | a single character class followed by '<code>-</code>', |
| 7868 | 8009 | which also matches 0 or more repetitions of characters in the class. |
| 7869 | 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 | 8012 | </li> |
| 7872 | 8013 | |
| 7873 | 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 | 8096 | This library provides generic functions for table manipulation. |
| 7954 | 8097 | It provides all its functions inside the table <a name="pdf-table"><code>table</code></a>. |
| 7955 | 8098 | |
| 7956 | 8099 | |
| 7957 | 8100 | <p> |
| 7958 | −Most functions in the table library assume that the table | |
| 7959 | −represents an array or a list. | |
| 7960 | −For these functions, when we talk about the "length" of a table | |
| 7961 | −we mean the result of the length operator. | |
| 8101 | +Currently, all functions in the table library assume that the table | |
| 8102 | +represents a list. | |
| 8103 | +In particular, they all ignore non-numeric keys | |
| 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 | 8121 | <p> |
| 7965 | −<hr><h3><a name="pdf-table.concat"><code>table.concat (table [, sep [, i [, j]]])</code></a></h3> | |
| 7966 | −Given an array where all elements are strings or numbers, | |
| 7967 | −returns <code>table[i]..sep..table[i+1] ··· sep..table[j]</code>. | |
| 8122 | +Given a list where all elements are strings or numbers, | |
| 8123 | +returns <code>list[i]..sep..list[i+1] ··· sep..list[j]</code>. | |
| 7968 | 8124 | The default value for <code>sep</code> is the empty string, |
| 7969 | 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 | 8127 | If <code>i</code> is greater than <code>j</code>, returns the empty string. |
| 7972 | 8128 | |
| 7973 | 8129 | |
| 7974 | 8130 | |
| 7975 | 8131 | |
| 7976 | 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 | 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 | 8138 | shifting up other elements to open space, if necessary. |
| 7983 | −The default value for <code>pos</code> is <code>n+1</code>, | |
| 7984 | −where <code>n</code> is the length of the table (see <a href="#3.4.6">§3.4.6</a>), | |
| 8139 | +The default value for <code>pos</code> is <code>#list+1</code>, | |
| 7985 | 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 | 8150 | <p> |
| 7996 | −Returns a new table with all parameters stored into | |
| 7997 | −keys 1, 2, etc. | |
| 8151 | +Returns a new table with all parameters stored into keys 1, 2, etc. | |
| 7998 | 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 | 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 | 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 | 8165 | shifting down other elements to close the space, if necessary. |
| 8010 | 8166 | Returns the value of the removed element. |
| 8011 | −The default value for <code>pos</code> is <code>n</code>, | |
| 8012 | −where <code>n</code> is the length of the table, | |
| 8167 | +The default value for <code>pos</code> is <code>#list</code>, | |
| 8013 | 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 | 8174 | <p> |
| 8020 | −<hr><h3><a name="pdf-table.sort"><code>table.sort (table [, comp])</code></a></h3> | |
| 8021 | −Sorts table elements in a given order, <em>in-place</em>, | |
| 8022 | −from <code>table[1]</code> to <code>table[n]</code>, | |
| 8023 | −where <code>n</code> is the length of the table. | |
| 8175 | +<hr><h3><a name="pdf-table.sort"><code>table.sort (list [, comp])</code></a></h3> | |
| 8176 | + | |
| 8177 | + | |
| 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 | 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 | 8183 | and returns true when the first element must come |
| 8027 | 8184 | before the second in the final order |
| 8028 | 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 | 8198 | <p> |
| 8042 | 8199 | <hr><h3><a name="pdf-table.unpack"><code>table.unpack (list [, i [, j]])</code></a></h3> |
| 8200 | + | |
| 8201 | + | |
| 8202 | +<p> | |
| 8043 | 8203 | Returns the elements from the given table. |
| 8044 | 8204 | This function is equivalent to |
| 8045 | 8205 | |
| 8046 | 8206 | <pre> |
| 8047 | 8207 | return list[i], list[i+1], ···, list[j] |
| 8048 | 8208 | </pre><p> |
| 8049 | −except that the above code can be written only for a fixed number | |
| 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>). | |
| 8209 | +By default, <code>i</code> is 1 and <code>j</code> is <code>#list</code>. | |
| 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 | 8548 | <p> |
| 8392 | 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 | 8627 | <p> |
| 8471 | −Returns a boolean signaling | |
| 8628 | +Returns a boolean signaling | |
| 8472 | 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 | 8670 | <p> |
| 8488 | 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 | 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 | 8913 | <p> |
| 8726 | 8914 | Starts program <code>prog</code> in a separated process and returns |
| 8727 | 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 | 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 | 8923 | <p> |
| @@ -8794,8 +8977,9 @@ but that takes an unpredictable amount of time to happen. · 53 unmodified lines | ||
| 8794 | 8977 | |
| 8795 | 8978 | |
| 8796 | 8979 | <p> |
| 8797 | −If <code>file</code> was created with <a href="#pdf-io.popen"><code>io.popen</code></a>, | |
| 8798 | −a successful close returns the exit status of the process. | |
| 8980 | +When closing a file handle created with <a href="#pdf-io.popen"><code>io.popen</code></a>, | |
| 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 | 9204 | <code>wday</code> (weekday, Sunday is 1), |
| 9021 | 9205 | <code>yday</code> (day of the year), |
| 9022 | 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 | 9211 | <p> |
| @@ -9056,9 +9242,28 @@ this value is exactly <code>t2</code><em>-</em><code>t1</code>. · 30 unmodified lines | ||
| 9056 | 9242 | <p> |
| 9057 | 9243 | This function is equivalent to the C function <code>system</code>. |
| 9058 | 9244 | It passes <code>command</code> to be executed by an operating system shell. |
| 9059 | −It returns a status code, which is system-dependent. | |
| 9060 | −If <code>command</code> is absent, then it returns nonzero if a shell is available | |
| 9061 | −and zero otherwise. | |
| 9245 | +It returns <b>true</b> | |
| 9246 | +if the command terminated successfully. | |
| 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 | 9277 | If <code>code</code> is <b>true</b>, |
| 9073 | 9278 | the returned status is <code>EXIT_SUCCESS</code>; |
| 9074 | 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 | 9281 | if <code>code</code> is a number, |
| 9077 | 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 | 9286 | <p> |
| @@ -9101,8 +9306,8 @@ or <b>nil</b> if the variable is not defined. · 19 unmodified lines | ||
| 9101 | 9306 | |
| 9102 | 9307 | |
| 9103 | 9308 | <p> |
| 9104 | −Deletes the file or directory with the given name. | |
| 9105 | −Directories must be empty to be removed. | |
| 9309 | +Deletes the file (or empty directory, on POSIX systems) | |
| 9310 | +with the given name. | |
| 9106 | 9311 | If this function fails, it returns <b>nil</b>, |
| 9107 | 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 | 9371 | <p> |
| 9167 | 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 | 9375 | of seconds since some given start time (the "epoch"). |
| 9170 | 9376 | In other systems, the meaning is not specified, |
| 9171 | 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 | 9394 | <p> |
| 9189 | −On some systems (POSIX), | |
| 9395 | +On POSIX systems, | |
| 9190 | 9396 | this function also creates a file with that name, |
| 9191 | 9397 | to avoid security risks. |
| 9192 | 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 | 9533 | <p> |
| 9328 | 9534 | This function returns the name and the value of the local variable |
| 9329 | 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, | |
| 9331 | −until the last active local variable.) | |
| 9332 | −The function returns <b>nil</b> if there is no local | |
| 9333 | −variable with the given index, | |
| 9536 | +This function accesses not only explicit local variables, | |
| 9537 | +but also parameters, temporaries, etc. | |
| 9538 | + | |
| 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 | 9546 | and raises an error when called with a level out of range. |
| 9335 | 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 | 9550 | <p> |
| 9339 | 9551 | Variable names starting with '<code>(</code>' (open parentheses) |
| 9340 | 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 | 9556 | <p> |
| @@ -9454,6 +9666,11 @@ and raises an error when called with a <code>level</code> out of range. · 109 unmodified lines | ||
| 9454 | 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 | 9676 | <p> |
| @@ -9463,6 +9680,7 @@ Otherwise, it returns the name of the local variable. · 3 unmodified lines | ||
| 9463 | 9680 | <p> |
| 9464 | 9681 | Sets the metatable for the given <code>object</code> to the given <code>table</code> |
| 9465 | 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 | 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 | 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 | 9708 | this function returns <code>message</code> without further processing. |
| 9491 | 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 | 9711 | An optional <code>message</code> string is appended |
| 9494 | 9712 | at the beginning of the traceback. |
| 9495 | 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 | 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 | 9864 | <p> |
| 9639 | 9865 | If the global variable <a name="pdf-_PROMPT"><code>_PROMPT</code></a> contains a string, |
| 9640 | 9866 | then its value is used as the prompt. |
| @@ -9671,12 +9897,12 @@ as in · 30 unmodified lines | ||
| 9671 | 9897 | (Of course, |
| 9672 | 9898 | the location of the Lua interpreter can be different in your machine. |
| 9673 | 9899 | If <code>lua</code> is in your <code>PATH</code>, |
| 9674 | −then | |
| 9900 | +then | |
| 9675 | 9901 | |
| 9676 | 9902 | <pre> |
| 9677 | 9903 | #!/usr/bin/env lua |
| 9678 | 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 | 9922 | <ul> |
| 9697 | 9923 | |
| 9698 | 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 | 9944 | </li> |
| 9701 | 9945 | |
| 9702 | 9946 | <li> |
| 9703 | −Doing a step in the garbage collector does not restart the collector | |
| 9704 | −if it has been stopped. | |
| 9947 | +Lua identifiers cannot use locale-dependent letters. | |
| 9705 | 9948 | </li> |
| 9706 | 9949 | |
| 9707 | 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 | 9953 | </li> |
| 9710 | 9954 | |
| 9711 | 9955 | <li> |
| 9712 | −Threads do not have individual environments. | |
| 9713 | −All threads share a single fixed environment. | |
| 9956 | +Weak tables with weak keys now perform like <em>ephemeron tables</em>. | |
| 9714 | 9957 | </li> |
| 9715 | 9958 | |
| 9716 | 9959 | <li> |
| @@ -9720,6 +9963,13 @@ Instead, tail calls generate a special new event, · 3 unmodified lines | ||
| 9720 | 9963 | not be a corresponding return event. |
| 9721 | 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 | 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 | 9985 | </li> |
| 9736 | 9986 | |
| 9737 | 9987 | <li> |
| 9738 | −Functions <code>setfenv</code> and <code>getfenv</code> are deprecated. | |
| 9739 | −To set the environment of a Lua function, | |
| 9740 | −use the variable <code>_ENV</code> or the new function <a href="#pdf-loadin"><code>loadin</code></a>. | |
| 9988 | +Functions <code>setfenv</code> and <code>getfenv</code> are deprecated, | |
| 9989 | +because of the changes in environments. | |
| 9741 | 9990 | </li> |
| 9742 | 9991 | |
| 9743 | 9992 | <li> |
| @@ -9745,11 +9994,23 @@ Function <code>math.log10</code> is deprecated. · 1 unmodified line | ||
| 9745 | 9994 | Use <a href="#pdf-math.log"><code>math.log</code></a> with 10 as its second argument, instead. |
| 9746 | 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 | 10003 | <li> |
| 9749 | 10004 | Function <code>table.maxn</code> is deprecated. |
| 9750 | 10005 | Write it in Lua if you really need it. |
| 9751 | 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 | 10014 | <li> |
| 9754 | 10015 | Function <code>unpack</code> was moved into the table library |
| 9755 | 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 | 10024 | <li> |
| 9764 | 10025 | Lua does not have bytecode verification anymore. |
| 9765 | 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 | 10028 | are potentially insecure when loading untrusted binary data. |
| 9768 | 10029 | (Actually, those functions were already insecure because |
| 9769 | 10030 | of bugs in the verification algorithm.) |
| @@ -9789,19 +10050,8 @@ You must get the global environment from the registry · 19 unmodified lines | ||
| 9789 | 10050 | <li> |
| 9790 | 10051 | Pseudoindex <code>LUA_ENVIRONINDEX</code> |
| 9791 | 10052 | and functions <code>lua_getfenv</code>/<code>lua_setfenv</code> |
| 9792 | −were removed. | |
| 9793 | −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>. | |
| 10053 | +were removed, | |
| 10054 | +as C functions do not have environments any more. | |
| 9805 | 10055 | </li> |
| 9806 | 10056 | |
| 9807 | 10057 | <li> |
| @@ -9812,12 +10062,21 @@ create globals anymore. · 4 unmodified lines | ||
| 9812 | 10062 | </li> |
| 9813 | 10063 | |
| 9814 | 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 | 10075 | reverse order that they were marked, |
| 9817 | 10076 | not that they were created (see <a href="#2.5.1">§2.5.1</a>). |
| 9818 | 10077 | (Most userdata are marked immediately after they are created.) |
| 9819 | 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 | 10080 | the finalizer will not be called, |
| 9822 | 10081 | even if it is set later. |
| 9823 | 10082 | </li> |
| @@ -9860,11 +10119,14 @@ Here is the complete syntax of Lua in extended BNF. · 36 unmodified lines | ||
| 9860 | 10119 | |
| 9861 | 10120 | chunk ::= block |
| 9862 | 10121 | |
| 9863 | − block ::= {stat} [laststat [‘<b>;</b>’]] | |
| 10122 | + block ::= {stat} [retstat] | |
| 9864 | 10123 | |
| 9865 | 10124 | stat ::= ‘<b>;</b>’ | |
| 9866 | 10125 | varlist ‘<b>=</b>’ explist | |
| 9867 | 10126 | functioncall | |
| 10127 | + label | | |
| 10128 | + <b>break</b> | | |
| 10129 | + <b>goto</b> Name | | |
| 9868 | 10130 | <b>do</b> block <b>end</b> | |
| 9869 | 10131 | <b>while</b> exp <b>do</b> block <b>end</b> | |
| 9870 | 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 | 10137 | <b>local</b> <b>function</b> Name funcbody | |
| 9876 | 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 | 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 | 10150 | namelist ::= Name {‘<b>,</b>’ Name} |
| 9887 | 10151 | |
| 9888 | − explist ::= {exp ‘<b>,</b>’} exp | |
| 10152 | + explist ::= exp {‘<b>,</b>’ exp} | |
| 9889 | 10153 | |
| 9890 | 10154 | exp ::= <b>nil</b> | <b>false</b> | <b>true</b> | Number | String | ‘<b>...</b>’ | function | |
| 9891 | 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 | 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 | 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 | 10193 | <HR> |
| 9930 | 10194 | <SMALL> |
| 9931 | 10195 | Last update: |
| 9932 | −Mon Nov 22 16:36:19 BRST 2010 | |
| 10196 | +Mon Jun 13 14:56:14 BRT 2011 | |
| 9933 | 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 | 10202 | </body></html> |
| @@ -27,12 +27,12 @@ tt, kbd, code { · 26 unmodified lines | ||
| 27 | 27 | <HR> |
| 28 | 28 | <H1> |
| 29 | 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 | 31 | </H1> |
| 32 | 32 | |
| 33 | 33 | <P> |
| 34 | 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 | 36 | Some details may change in the final version.</EM> |
| 37 | 37 | |
| 38 | 38 | <P> |
| @@ -278,11 +278,13 @@ lists the · 239 unmodified lines | ||
| 278 | 278 | <H3>Main changes</H3> |
| 279 | 279 | <UL> |
| 280 | 280 | <LI> yieldable pcall and metamethods |
| 281 | −<LI> new <CODE>_ENV</CODE> scheme | |
| 281 | +<LI> new lexical scheme for globals | |
| 282 | 282 | <LI> ephemeron tables |
| 283 | 283 | <LI> new library for bitwise operations |
| 284 | 284 | <LI> light C functions |
| 285 | 285 | <LI> emergency garbage collector |
| 286 | +<LI> <CODE>goto</CODE> statement | |
| 287 | +<LI> finalizers for tables | |
| 286 | 288 | </UL> |
| 287 | 289 | |
| 288 | 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 | 293 | <LI> no more fenv for threads or functions |
| 292 | 294 | <LI> tables honor the <CODE>__len</CODE> metamethod |
| 293 | 295 | <LI> hex and <CODE>\*</CODE> escapes in strings |
| 296 | +<LI> support for hexadecimal floats | |
| 294 | 297 | <LI> order metamethods work for different types |
| 295 | 298 | <LI> no more verification of opcode consistency |
| 296 | 299 | <LI> hook event "tail return" replaced by "tail call" |
| 297 | 300 | <LI> empty statement |
| 301 | +<LI> <CODE>break</CODE> statement may appear in the middle of a block | |
| 298 | 302 | </UL> |
| 299 | 303 | |
| 300 | 304 | <H3>Libraries</H3> |
| 301 | 305 | <UL> |
| 302 | −<LI> new metamethods <CODE>__pairs</CODE> and <CODE>__ipairs</CODE> | |
| 303 | 306 | <LI> arguments for function called through <CODE>xpcall</CODE> |
| 304 | 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 | 309 | <LI> <CODE>loadlib</CODE> may load libraries with global names (RTLD_GLOBAL) |
| 307 | 310 | <LI> new function <CODE>package.searchpath</CODE> |
| 311 | +<LI> modules receive their paths when loaded | |
| 308 | 312 | <LI> optional base in <CODE>math.log</CODE> |
| 313 | +<LI> optional separator in <CODE>string.rep</CODE> | |
| 309 | 314 | <LI> <CODE>file:write</CODE> returns <CODE>file</CODE> |
| 310 | 315 | <LI> closing a pipe returns exit status |
| 311 | 316 | <LI> <CODE>os.exit</CODE> may close state |
| 317 | +<LI> new metamethods <CODE>__pairs</CODE> and <CODE>__ipairs</CODE> | |
| 312 | 318 | <LI> new option 'isrunning' for <CODE>collectgarbage</CODE> and <CODE>lua_gc</CODE> |
| 313 | 319 | <LI> frontier patterns |
| 314 | 320 | <LI> <CODE>\0</CODE> in patterns |
| 315 | 321 | <LI> new option <CODE>*L</CODE> for <CODE>io.read</CODE> |
| 316 | 322 | <LI> options for <CODE>io.lines</CODE> |
| 323 | +<LI> <CODE>debug.getlocal</CODE> can access function varargs | |
| 317 | 324 | </UL> |
| 318 | 325 | |
| 319 | 326 | <H3>C API</H3> |
| @@ -321,7 +328,7 @@ Here are the other changes introduced in Lua 5.2: · 1 unmodified line | ||
| 321 | 328 | <LI> main thread predefined in the registry |
| 322 | 329 | <LI> new constants <CODE>LUA_OK</CODE> and <CODE>LUA_ERRGCMM</CODE> |
| 323 | 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 | 332 | <LI> <CODE>lua_pushstring</CODE> and <CODE>pushlstring</CODE> return string |
| 326 | 333 | <LI> new <CODE>luaL_testudata</CODE> and <CODE>luaL_setmetatable</CODE> |
| 327 | 334 | <LI> new <CODE>luaL_tolstring</CODE> |
| @@ -364,7 +371,7 @@ For details, see · 36 unmodified lines | ||
| 364 | 371 | <A HREF="http://www.lua.org/license.html">this</A>. |
| 365 | 372 | |
| 366 | 373 | <BLOCKQUOTE> |
| 367 | −Copyright © 1994–2010 Lua.org, PUC-Rio. | |
| 374 | +Copyright © 1994–2011 Lua.org, PUC-Rio. | |
| 368 | 375 | |
| 369 | 376 | <P> |
| 370 | 377 | Permission is hereby granted, free of charge, to any person obtaining a copy |
| @@ -391,10 +398,10 @@ THE SOFTWARE. · 20 unmodified lines | ||
| 391 | 398 | <HR> |
| 392 | 399 | <SMALL> |
| 393 | 400 | Last update: |
| 394 | −Sat Nov 20 19:23:14 BRST 2010 | |
| 401 | +Mon Jun 13 15:07:49 BRT 2011 | |
| 395 | 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 | 407 | </BODY> |
| @@ -126,7 +126,7 @@ lbaselib.o: lbaselib.c lua.h luaconf.h lauxlib.h lualib.h · 125 unmodified lines | ||
| 126 | 126 | lbitlib.o: lbitlib.c lua.h luaconf.h lauxlib.h lualib.h |
| 127 | 127 | lcode.o: lcode.c lua.h luaconf.h lcode.h llex.h lobject.h llimits.h \ |
| 128 | 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 | 130 | lcorolib.o: lcorolib.c lua.h luaconf.h lauxlib.h lualib.h |
| 131 | 131 | lctype.o: lctype.c lctype.h lua.h luaconf.h llimits.h |
| 132 | 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 | 164 | ltm.h lzio.h lstring.h lgc.h |
| 165 | 165 | lstrlib.o: lstrlib.c lua.h luaconf.h lauxlib.h lualib.h |
| 166 | 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 | 168 | ltablib.o: ltablib.c lua.h luaconf.h lauxlib.h lualib.h |
| 169 | 169 | ltm.o: ltm.c lua.h luaconf.h lobject.h llimits.h lstate.h ltm.h lzio.h \ |
| 170 | 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 | 3 | ** Lua API |
| 4 | 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 | 59 | if (ttislcf(ci->func)) /* light C function? */ |
| 60 | 60 | return cast(TValue *, luaO_nilobject); /* it has no upvalues */ |
| 61 | 61 | else { |
| 62 | − Closure *func = clvalue(ci->func); | |
| 63 | − return (idx <= func->c.nupvalues) | |
| 64 | − ? &func->c.upvalue[idx-1] | |
| 62 | + CClosure *func = clCvalue(ci->func); | |
| 63 | + return (idx <= func->nupvalues) | |
| 64 | + ? &func->upvalue[idx-1] | |
| 65 | 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 | 195 | TValue *to = index2addr(L, idx); |
| 196 | 196 | api_checkvalidindex(L, to); |
| 197 | 197 | setobj(L, to, fr); |
| 198 | − if (idx < LUA_REGISTRYINDEX) { /* function upvalue? */ | |
| 199 | − lua_assert(ttisclosure(L->ci->func)); | |
| 200 | − luaC_barrier(L, clvalue(L->ci->func), fr); | |
| 201 | − } | |
| 198 | + if (idx < LUA_REGISTRYINDEX) /* function upvalue? */ | |
| 199 | + luaC_barrier(L, clCvalue(L->ci->func), fr); | |
| 202 | 200 | /* LUA_REGISTRYINDEX does not need gc barrier |
| 203 | 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 | 250 | LUA_API int lua_iscfunction (lua_State *L, int idx) { |
| 253 | 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 | 276 | StkId o1 = index2addr(L, index1); |
| 279 | 277 | StkId o2 = index2addr(L, index2); |
| 280 | 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 | 283 | LUA_API void lua_arith (lua_State *L, int op) { |
| 284 | + StkId o1; /* 1st operand */ | |
| 285 | + StkId o2; /* 2nd operand */ | |
| 286 | 286 | lua_lock(L); |
| 287 | − api_checknelems(L, 2); | |
| 288 | − if (ttisnumber(L->top - 2) && ttisnumber(L->top - 1)) { | |
| 289 | − changenvalue(L->top - 2, | |
| 290 | − luaO_arith(op, nvalue(L->top - 2), nvalue(L->top - 1))); | |
| 287 | + if (op != LUA_OPUNM) /* all other operations expect two operands */ | |
| 288 | + api_checknelems(L, 2); | |
| 289 | + else { /* for unary minus, add fake 2nd operand */ | |
| 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 | 299 | else |
| 293 | − luaV_arith(L, L->top - 2, L->top - 2, L->top - 1, | |
| 294 | − cast(TMS, op - LUA_OPADD + TM_ADD)); | |
| 300 | + luaV_arith(L, o1, o1, o2, cast(TMS, op - LUA_OPADD + TM_ADD)); | |
| 295 | 301 | L->top--; |
| 296 | 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 | 397 | LUA_API size_t lua_rawlen (lua_State *L, int idx) { |
| 392 | 398 | StkId o = index2addr(L, idx); |
| 393 | − switch (ttype(o)) { | |
| 399 | + switch (ttypenv(o)) { | |
| 394 | 400 | case LUA_TSTRING: return tsvalue(o)->len; |
| 395 | 401 | case LUA_TUSERDATA: return uvalue(o)->len; |
| 396 | 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 | 408 | LUA_API lua_CFunction lua_tocfunction (lua_State *L, int idx) { |
| 403 | 409 | StkId o = index2addr(L, idx); |
| 404 | 410 | if (ttislcf(o)) return fvalue(o); |
| 405 | − else if (ttisclosure(o) && clvalue(o)->c.isC) | |
| 406 | − return clvalue(o)->c.f; | |
| 411 | + else if (ttisCclosure(o)) | |
| 412 | + return clCvalue(o)->f; | |
| 407 | 413 | else return NULL; /* not a C function */ |
| 408 | 414 | } |
| 409 | 415 | |
| 410 | 416 | |
| 411 | 417 | LUA_API void *lua_touserdata (lua_State *L, int idx) { |
| 412 | 418 | StkId o = index2addr(L, idx); |
| 413 | − switch (ttype(o)) { | |
| 419 | + switch (ttypenv(o)) { | |
| 414 | 420 | case LUA_TUSERDATA: return (rawuvalue(o) + 1); |
| 415 | 421 | case LUA_TLIGHTUSERDATA: return pvalue(o); |
| 416 | 422 | default: return NULL; |
| @@ -428,7 +434,8 @@ LUA_API const void *lua_topointer (lua_State *L, int idx) { · 11 unmodified lines | ||
| 428 | 434 | StkId o = index2addr(L, idx); |
| 429 | 435 | switch (ttype(o)) { |
| 430 | 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 | 439 | case LUA_TLCF: return cast(void *, cast(size_t, fvalue(o))); |
| 433 | 440 | case LUA_TTHREAD: return thvalue(o); |
| 434 | 441 | case LUA_TUSERDATA: |
| @@ -456,6 +463,8 @@ LUA_API void lua_pushnil (lua_State *L) { · 21 unmodified lines | ||
| 456 | 463 | LUA_API void lua_pushnumber (lua_State *L, lua_Number n) { |
| 457 | 464 | lua_lock(L); |
| 458 | 465 | setnvalue(L->top, n); |
| 466 | + luai_checknum(L, L->top, | |
| 467 | + luaG_runerror(L, "C API - attempt to push a signaling NaN")); | |
| 459 | 468 | api_incr_top(L); |
| 460 | 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 | 557 | L->top -= n; |
| 549 | 558 | while (n--) |
| 550 | 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 | 562 | api_incr_top(L); |
| 554 | 563 | lua_unlock(L); |
| @@ -648,7 +657,7 @@ LUA_API int lua_getmetatable (lua_State *L, int objindex) { · 93 unmodified lines | ||
| 648 | 657 | int res; |
| 649 | 658 | lua_lock(L); |
| 650 | 659 | obj = index2addr(L, objindex); |
| 651 | − switch (ttype(obj)) { | |
| 660 | + switch (ttypenv(obj)) { | |
| 652 | 661 | case LUA_TTABLE: |
| 653 | 662 | mt = hvalue(obj)->metatable; |
| 654 | 663 | break; |
| @@ -755,18 +764,19 @@ LUA_API int lua_setmetatable (lua_State *L, int objindex) { · 100 unmodified lines | ||
| 755 | 764 | api_check(L, ttistable(L->top - 1), "table expected"); |
| 756 | 765 | mt = hvalue(L->top - 1); |
| 757 | 766 | } |
| 758 | − switch (ttype(obj)) { | |
| 767 | + switch (ttypenv(obj)) { | |
| 759 | 768 | case LUA_TTABLE: { |
| 760 | 769 | hvalue(obj)->metatable = mt; |
| 761 | 770 | if (mt) |
| 762 | 771 | luaC_objbarrierback(L, gcvalue(obj), mt); |
| 772 | + luaC_checkfinalizer(L, gcvalue(obj), mt); | |
| 763 | 773 | break; |
| 764 | 774 | } |
| 765 | 775 | case LUA_TUSERDATA: { |
| 766 | 776 | uvalue(obj)->metatable = mt; |
| 767 | 777 | if (mt) { |
| 768 | 778 | luaC_objbarrier(L, rawuvalue(obj), mt); |
| 769 | − luaC_checkfinalizer(L, rawuvalue(obj)); | |
| 779 | + luaC_checkfinalizer(L, gcvalue(obj), mt); | |
| 770 | 780 | } |
| 771 | 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 | 922 | luaZ_init(L, &z, reader, data); |
| 913 | 923 | status = luaD_protectedparser(L, &z, chunkname); |
| 914 | 924 | if (status == LUA_OK) { /* no errors? */ |
| 915 | − Closure *f = clvalue(L->top - 1); /* get newly created function */ | |
| 916 | − lua_assert(!f->c.isC); | |
| 917 | − if (f->l.nupvalues == 1) { /* does it have one upvalue? */ | |
| 925 | + LClosure *f = clLvalue(L->top - 1); /* get newly created function */ | |
| 926 | + if (f->nupvalues == 1) { /* does it have one upvalue? */ | |
| 918 | 927 | /* get global table from registry */ |
| 919 | 928 | Table *reg = hvalue(&G(L)->l_registry); |
| 920 | 929 | const TValue *gt = luaH_getint(reg, LUA_RIDX_GLOBALS); |
| 921 | 930 | /* set global table as 1st upvalue of 'f' (may be LUA_ENV) */ |
| 922 | − setobj(L, f->l.upvals[0]->v, gt); | |
| 923 | − luaC_barrier(L, f->l.upvals[0], gt); | |
| 931 | + setobj(L, f->upvals[0]->v, gt); | |
| 932 | + luaC_barrier(L, f->upvals[0], gt); | |
| 924 | 933 | } |
| 925 | 934 | } |
| 926 | 935 | lua_unlock(L); |
| @@ -959,11 +968,12 @@ LUA_API int lua_gc (lua_State *L, int what, int data) { · 32 unmodified lines | ||
| 959 | 968 | g = G(L); |
| 960 | 969 | switch (what) { |
| 961 | 970 | case LUA_GCSTOP: { |
| 962 | − stopgc(g); | |
| 971 | + g->gcrunning = 0; | |
| 963 | 972 | break; |
| 964 | 973 | } |
| 965 | 974 | case LUA_GCRESTART: { |
| 966 | − g->GCdebt = 0; | |
| 975 | + luaE_setdebt(g, 0); | |
| 976 | + g->gcrunning = 1; | |
| 967 | 977 | break; |
| 968 | 978 | } |
| 969 | 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 | 983 | case LUA_GCCOUNT: { |
| 974 | 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 | 986 | break; |
| 977 | 987 | } |
| 978 | 988 | case LUA_GCCOUNTB: { |
| 979 | − res = cast_int(g->totalbytes & 0x3ff); | |
| 989 | + res = cast_int(gettotalbytes(g) & 0x3ff); | |
| 980 | 990 | break; |
| 981 | 991 | } |
| 982 | 992 | case LUA_GCSTEP: { |
| 983 | − int stopped = gcstopped(g); | |
| 984 | 993 | if (g->gckind == KGC_GEN) { /* generational mode? */ |
| 985 | 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 | 997 | else { |
| 989 | 998 | while (data-- >= 0) { |
| 990 | − luaC_step(L); | |
| 999 | + luaC_forcestep(L); | |
| 991 | 1000 | if (g->gcstate == GCSpause) { /* end of cycle? */ |
| 992 | 1001 | res = 1; /* signal it */ |
| 993 | 1002 | break; |
| 994 | 1003 | } |
| 995 | 1004 | } |
| 996 | 1005 | } |
| 997 | − if (stopped) /* collector was stopped? */ | |
| 998 | − stopgc(g); /* keep it that way */ | |
| 999 | 1006 | break; |
| 1000 | 1007 | } |
| 1001 | 1008 | case LUA_GCSETPAUSE: { |
| @@ -1014,7 +1021,7 @@ LUA_API int lua_gc (lua_State *L, int what, int data) { · 12 unmodified lines | ||
| 1014 | 1021 | break; |
| 1015 | 1022 | } |
| 1016 | 1023 | case LUA_GCISRUNNING: { |
| 1017 | − res = !gcstopped(g); | |
| 1024 | + res = g->gcrunning; | |
| 1018 | 1025 | break; |
| 1019 | 1026 | } |
| 1020 | 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 | 1132 | static const char *aux_upvalue (StkId fi, int n, TValue **val, |
| 1126 | 1133 | GCObject **owner) { |
| 1127 | − Closure *f; | |
| 1128 | − if (!ttisclosure(fi)) return NULL; | |
| 1129 | − f = clvalue(fi); | |
| 1130 | − if (f->c.isC) { | |
| 1131 | − if (!(1 <= n && n <= f->c.nupvalues)) return NULL; | |
| 1132 | − *val = &f->c.upvalue[n-1]; | |
| 1133 | − if (owner) *owner = obj2gco(f); | |
| 1134 | − return ""; | |
| 1135 | − } | |
| 1136 | − else { | |
| 1137 | − const char *name; | |
| 1138 | − Proto *p = f->l.p; | |
| 1139 | − if (!(1 <= n && n <= p->sizeupvalues)) return NULL; | |
| 1140 | − *val = f->l.upvals[n-1]->v; | |
| 1141 | − if (owner) *owner = obj2gco(f->l.upvals[n - 1]); | |
| 1142 | − name = getstr(p->upvalues[n-1].name); | |
| 1143 | − if (name == NULL) /* no debug information? */ | |
| 1144 | − name = ""; | |
| 1145 | − return name; | |
| 1134 | + switch (ttype(fi)) { | |
| 1135 | + case LUA_TCCL: { /* C closure */ | |
| 1136 | + CClosure *f = clCvalue(fi); | |
| 1137 | + if (!(1 <= n && n <= f->nupvalues)) return NULL; | |
| 1138 | + *val = &f->upvalue[n-1]; | |
| 1139 | + if (owner) *owner = obj2gco(f); | |
| 1140 | + return ""; | |
| 1141 | + } | |
| 1142 | + case LUA_TLCL: { /* Lua closure */ | |
| 1143 | + LClosure *f = clLvalue(fi); | |
| 1144 | + const char *name; | |
| 1145 | + Proto *p = f->p; | |
| 1146 | + if (!(1 <= n && n <= p->sizeupvalues)) return NULL; | |
| 1147 | + *val = f->upvals[n-1]->v; | |
| 1148 | + if (owner) *owner = obj2gco(f->upvals[n - 1]); | |
| 1149 | + name = getstr(p->upvalues[n-1].name); | |
| 1150 | + if (name == NULL) /* no debug information? */ | |
| 1151 | + 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) { | |
| 1184 | − Closure *f; | |
| 1192 | +static UpVal **getupvalref (lua_State *L, int fidx, int n, LClosure **pf) { | |
| 1193 | + LClosure *f; | |
| 1185 | 1194 | StkId fi = index2addr(L, fidx); |
| 1186 | − api_check(L, ttisclosure(fi), "Lua function expected"); | |
| 1187 | − f = clvalue(fi); | |
| 1188 | − api_check(L, !f->c.isC, "Lua function expected"); | |
| 1189 | − api_check(L, (1 <= n && n <= f->l.p->sizeupvalues), "invalid upvalue index"); | |
| 1195 | + api_check(L, ttisLclosure(fi), "Lua function expected"); | |
| 1196 | + f = clLvalue(fi); | |
| 1197 | + api_check(L, (1 <= n && n <= f->p->sizeupvalues), "invalid upvalue index"); | |
| 1190 | 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 | 1203 | LUA_API void *lua_upvalueid (lua_State *L, int fidx, int n) { |
| 1196 | − Closure *f; | |
| 1197 | 1204 | StkId fi = index2addr(L, fidx); |
| 1198 | − api_check(L, ttisclosure(fi), "function expected"); | |
| 1199 | − f = clvalue(fi); | |
| 1200 | − if (f->c.isC) { | |
| 1201 | − api_check(L, 1 <= n && n <= f->c.nupvalues, "invalid upvalue index"); | |
| 1202 | − return &f->c.upvalue[n - 1]; | |
| 1205 | + switch (ttype(fi)) { | |
| 1206 | + case LUA_TLCL: { /* lua closure */ | |
| 1207 | + return *getupvalref(L, fidx, n, NULL); | |
| 1208 | + } | |
| 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 | 1222 | LUA_API void lua_upvaluejoin (lua_State *L, int fidx1, int n1, |
| 1209 | 1223 | int fidx2, int n2) { |
| 1210 | − Closure *f1; | |
| 1224 | + LClosure *f1; | |
| 1211 | 1225 | UpVal **up1 = getupvalref(L, fidx1, n1, &f1); |
| 1212 | 1226 | UpVal **up2 = getupvalref(L, fidx2, n2, NULL); |
| 1213 | 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 | 3 | ** Auxiliary functions for building Lua libraries |
| 4 | 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 | 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 | 442 | newsize = B->n + sz; |
| 385 | 443 | if (newsize < B->n || newsize - B->n < sz) |
| 386 | 444 | luaL_error(L, "buffer too large"); |
| 387 | − newbuff = (char *)lua_newuserdata(L, newsize); /* create larger buffer */ | |
| 388 | − memcpy(newbuff, B->b, B->n); /* move content to new buffer */ | |
| 445 | + /* create larger 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 | 449 | if (buffonstack(B)) |
| 390 | 450 | lua_remove(L, -2); /* remove old buffer */ |
| 391 | 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 | 458 | LUALIB_API void luaL_addlstring (luaL_Buffer *B, const char *s, size_t l) { |
| 399 | 459 | char *b = luaL_prepbuffsize(B, l); |
| 400 | − memcpy(b, s, l); | |
| 460 | + memcpy(b, s, l * sizeof(char)); | |
| 401 | 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 | 761 | #if defined(LUA_COMPAT_MODULE) |
| 702 | 762 | |
| 703 | −static const char *luaL_findtablex (lua_State *L, int idx, | |
| 704 | − const char *fname, int szhint) { | |
| 763 | +static const char *luaL_findtable (lua_State *L, int idx, | |
| 764 | + const char *fname, int szhint) { | |
| 705 | 765 | const char *e; |
| 706 | 766 | if (idx) lua_pushvalue(L, idx); |
| 707 | 767 | do { |
| @@ -745,13 +805,13 @@ static int libsize (const luaL_Reg *l) { · 37 unmodified lines | ||
| 745 | 805 | */ |
| 746 | 806 | LUALIB_API void luaL_pushmodule (lua_State *L, const char *modname, |
| 747 | 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 | 809 | lua_getfield(L, -1, modname); /* get _LOADED[modname] */ |
| 750 | 810 | if (!lua_istable(L, -1)) { /* not found? */ |
| 751 | 811 | lua_pop(L, 1); /* remove previous result */ |
| 752 | 812 | /* try global variable (and create one if it does not exist) */ |
| 753 | 813 | lua_pushglobaltable(L); |
| 754 | − if (luaL_findtablex(L, 0, modname, sizehint) != NULL) | |
| 814 | + if (luaL_findtable(L, 0, modname, sizehint) != NULL) | |
| 755 | 815 | luaL_error(L, "name conflict for module " LUA_QS, modname); |
| 756 | 816 | lua_pushvalue(L, -1); |
| 757 | 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 | 827 | luaL_pushmodule(L, libname, libsize(l)); /* get/create library table */ |
| 768 | 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 | 836 | #endif |
| @@ -780,7 +843,7 @@ LUALIB_API void luaL_openlib (lua_State *L, const char *libname, · 6 unmodified lines | ||
| 780 | 843 | */ |
| 781 | 844 | LUALIB_API void luaL_setfuncs (lua_State *L, const luaL_Reg *l, int nup) { |
| 782 | 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 | 847 | int i; |
| 785 | 848 | for (i = 0; i < nup; i++) /* copy upvalues to the top */ |
| 786 | 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 | 858 | ** ensure that stack[idx][fname] has a table and push that table |
| 796 | 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 | 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 | 864 | else { |
| 802 | 865 | idx = lua_absindex(L, idx); |
| 803 | 866 | lua_pop(L, 1); /* remove previous result */ |
| 804 | 867 | lua_newtable(L); |
| 805 | 868 | lua_pushvalue(L, -1); /* copy to be left at top */ |
| 806 | 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 | 883 | lua_pushcfunction(L, openf); |
| 820 | 884 | lua_pushstring(L, modname); /* argument to open function */ |
| 821 | 885 | lua_call(L, 1, 1); /* open module */ |
| 822 | − luaL_findtable(L, LUA_REGISTRYINDEX, "_LOADED"); | |
| 886 | + luaL_getsubtable(L, LUA_REGISTRYINDEX, "_LOADED"); | |
| 823 | 887 | lua_pushvalue(L, -2); /* make copy of module (call result) */ |
| 824 | 888 | lua_setfield(L, -2, modname); /* _LOADED[modname] = module */ |
| 825 | 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 | 3 | ** Auxiliary functions for building Lua libraries |
| 4 | 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 | 62 | LUALIB_API int (luaL_checkoption) (lua_State *L, int narg, const char *def, |
| 63 | 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 | 68 | /* pre-defined references */ |
| 66 | 69 | #define LUA_NOREF (-2) |
| 67 | 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 | 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 | 91 | LUALIB_API void (luaL_traceback) (lua_State *L, lua_State *L1, |
| 89 | 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 | 3 | ** Basic library |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| @@ -32,44 +32,54 @@ static int luaB_print (lua_State *L) { · 26 unmodified lines | ||
| 32 | 32 | lua_call(L, 1, 1); |
| 33 | 33 | s = lua_tolstring(L, -1, &l); /* get result */ |
| 34 | 34 | if (s == NULL) |
| 35 | − return luaL_error(L, LUA_QL("tostring") " must return a string to " | |
| 36 | − LUA_QL("print")); | |
| 35 | + return luaL_error(L, | |
| 36 | + LUA_QL("tostring") " must return a string to " LUA_QL("print")); | |
| 37 | 37 | if (i>1) luai_writestring("\t", 1); |
| 38 | 38 | luai_writestring(s, l); |
| 39 | 39 | lua_pop(L, 1); /* pop result */ |
| 40 | 40 | } |
| 41 | − luai_writestring("\n", 1); | |
| 41 | + luai_writeline(); | |
| 42 | 42 | return 0; |
| 43 | 43 | } |
| 44 | 44 | |
| 45 | 45 | |
| 46 | +#define SPACECHARS " \f\n\r\t\v" | |
| 47 | + | |
| 46 | 48 | static int luaB_tonumber (lua_State *L) { |
| 47 | 49 | int base = luaL_optint(L, 2, 10); |
| 50 | + luaL_argcheck(L, 2 <= base && base <= 36, 2, "base out of range"); | |
| 48 | 51 | if (base == 10) { /* standard conversion */ |
| 49 | 52 | luaL_checkany(L, 1); |
| 50 | 53 | if (lua_isnumber(L, 1)) { |
| 51 | 54 | lua_pushnumber(L, lua_tonumber(L, 1)); |
| 52 | 55 | return 1; |
| 53 | − } | |
| 56 | + } /* else not a number */ | |
| 54 | 57 | } |
| 55 | 58 | else { |
| 56 | − const char *s1 = luaL_checkstring(L, 1); | |
| 57 | − char *s2; | |
| 58 | − unsigned long n; | |
| 59 | + size_t l; | |
| 60 | + const char *s = luaL_checklstring(L, 1, &l); | |
| 61 | + const char *e = s + l; /* end point for 's' */ | |
| 59 | 62 | int neg = 0; |
| 60 | − luaL_argcheck(L, 2 <= base && base <= 36, 2, "base out of range"); | |
| 61 | − while (isspace((unsigned char)(*s1))) s1++; /* skip initial spaces */ | |
| 62 | − if (*s1 == '-') { s1++; neg = 1; } | |
| 63 | − n = strtoul(s1, &s2, base); | |
| 64 | − if (s1 != s2) { /* at least one valid digit? */ | |
| 65 | − while (isspace((unsigned char)(*s2))) s2++; /* skip trailing spaces */ | |
| 66 | − if (*s2 == '\0') { /* no invalid trailing characters? */ | |
| 67 | − lua_pushnumber(L, (neg) ? -(lua_Number)n : (lua_Number)n); | |
| 63 | + s += strspn(s, SPACECHARS); /* skip initial spaces */ | |
| 64 | + if (*s == '-') { s++; neg = 1; } /* handle signal */ | |
| 65 | + else if (*s == '+') s++; | |
| 66 | + if (isalnum((unsigned char)*s)) { | |
| 67 | + lua_Number n = 0; | |
| 68 | + do { | |
| 69 | + int digit = (isdigit((unsigned char)*s)) ? *s - '0' | |
| 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 | 78 | return 1; |
| 69 | − } | |
| 70 | − } | |
| 79 | + } /* else not a number */ | |
| 80 | + } /* else not a number */ | |
| 71 | 81 | } |
| 72 | − lua_pushnil(L); /* else not a number */ | |
| 82 | + lua_pushnil(L); /* not a number */ | |
| 73 | 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) { | |
| 114 | − return luaL_error(L, "getfenv/setfenv deprecated"); | |
| 123 | +static int luaB_deprecated (lua_State *L) { | |
| 124 | + return luaL_error(L, "deprecated function"); | |
| 115 | 125 | } |
| 116 | 126 | |
| 117 | −#define luaB_setfenv luaB_getfenv | |
| 118 | − | |
| 119 | 127 | |
| 120 | 128 | static int luaB_rawequal (lua_State *L) { |
| 121 | 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 | 145 | static int luaB_rawget (lua_State *L) { |
| 129 | 146 | luaL_checktype(L, 1, LUA_TTABLE); |
| 130 | 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 | 276 | static const char *checkrights (lua_State *L, const char *mode, const char *s) { |
| 255 | 277 | if (strchr(mode, 'b') == NULL && *s == LUA_SIGNATURE[0]) |
| 256 | 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 | |
| 265 | −** string to avoid it being collected while parsed | |
| 286 | +** reserved slot, above all arguments, to hold a copy of the returned | |
| 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 | 296 | ** stack top. Instead, it keeps its resulting string in a |
| 274 | 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 | 299 | static const char *generic_reader (lua_State *L, void *ud, size_t *size) { |
| 282 | 300 | const char *s; |
| 283 | − Readstat *stat = (Readstat *)ud; | |
| 301 | + const char **mode = (const char **)ud; | |
| 284 | 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 | 304 | lua_call(L, 0, 1); /* call it */ |
| 287 | 305 | if (lua_isnil(L, -1)) { |
| 288 | 306 | *size = 0; |
| 289 | 307 | return NULL; |
| 290 | 308 | } |
| 291 | 309 | else if ((s = lua_tostring(L, -1)) != NULL) { |
| 292 | − if (stat->mode != NULL) { /* first time? */ | |
| 293 | − s = checkrights(L, stat->mode, s); /* check mode */ | |
| 294 | − stat->mode = NULL; /* to avoid further checks */ | |
| 310 | + if (*mode != NULL) { /* first time? */ | |
| 311 | + s = checkrights(L, *mode, s); /* check mode */ | |
| 312 | + *mode = NULL; /* to avoid further checks */ | |
| 295 | 313 | if (s) luaL_error(L, s); |
| 296 | 314 | } |
| 297 | 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 | 326 | int status; |
| 309 | − Readstat stat; | |
| 310 | 327 | size_t l; |
| 311 | − const char *s = lua_tolstring(L, farg, &l); | |
| 312 | − stat.mode = luaL_optstring(L, farg + 2, "bt"); | |
| 328 | + int top = lua_gettop(L); | |
| 329 | + const char *s = lua_tolstring(L, 1, &l); | |
| 330 | + const char *mode = luaL_optstring(L, 3, "bt"); | |
| 313 | 331 | if (s != NULL) { /* loading a string? */ |
| 314 | − const char *chunkname = luaL_optstring(L, farg + 1, s); | |
| 315 | − status = (checkrights(L, stat.mode, s) != NULL) | |
| 332 | + const char *chunkname = luaL_optstring(L, 2, s); | |
| 333 | + status = (checkrights(L, mode, s) != NULL) | |
| 316 | 334 | || luaL_loadbuffer(L, s, l, chunkname); |
| 317 | 335 | } |
| 318 | 336 | else { /* loading from a reader function */ |
| 319 | − const char *chunkname = luaL_optstring(L, farg + 1, "=(load)"); | |
| 320 | − luaL_checktype(L, farg, LUA_TFUNCTION); | |
| 321 | − stat.f = farg; | |
| 337 | + const char *chunkname = luaL_optstring(L, 2, "=(load)"); | |
| 338 | + luaL_checktype(L, 1, LUA_TFUNCTION); | |
| 322 | 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 | 346 | return load_aux(L, status); |
| 326 | 347 | } |
| 327 | 348 | |
| 328 | 349 | |
| 329 | −static int luaB_load (lua_State *L) { | |
| 330 | − return luaB_load_aux(L, 1); | |
| 331 | −} | |
| 332 | − | |
| 333 | − | |
| 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 | −} | |
| 350 | +#if defined(LUA_COMPAT_LOADSTRING) | |
| 351 | +#define luaB_loadstring luaB_load | |
| 352 | +#else | |
| 353 | +#define luaB_loadstring luaB_deprecated | |
| 354 | +#endif | |
| 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 | 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 | 399 | int status = lua_getctx(L, &errfunc); |
| 396 | 400 | lua_assert(status != LUA_OK); |
| 397 | 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 | 443 | static const luaL_Reg base_funcs[] = { |
| 468 | 444 | {"assert", luaB_assert}, |
| 469 | 445 | {"collectgarbage", luaB_collectgarbage}, |
| 470 | 446 | {"dofile", luaB_dofile}, |
| 471 | 447 | {"error", luaB_error}, |
| 472 | − {"getfenv", luaB_getfenv}, | |
| 448 | + {"getfenv", luaB_deprecated}, | |
| 473 | 449 | {"getmetatable", luaB_getmetatable}, |
| 474 | 450 | {"ipairs", luaB_ipairs}, |
| 475 | 451 | {"loadfile", luaB_loadfile}, |
| 476 | 452 | {"load", luaB_load}, |
| 477 | − {"loadin", luaB_loadin}, | |
| 478 | 453 | {"loadstring", luaB_loadstring}, |
| 479 | 454 | {"next", luaB_next}, |
| 480 | 455 | {"pairs", luaB_pairs}, |
| 481 | 456 | {"pcall", luaB_pcall}, |
| 482 | 457 | {"print", luaB_print}, |
| 483 | 458 | {"rawequal", luaB_rawequal}, |
| 459 | + {"rawlen", luaB_rawlen}, | |
| 484 | 460 | {"rawget", luaB_rawget}, |
| 485 | 461 | {"rawset", luaB_rawset}, |
| 486 | 462 | {"select", luaB_select}, |
| 487 | − {"setfenv", luaB_setfenv}, | |
| 463 | + {"setfenv", luaB_deprecated}, | |
| 488 | 464 | {"setmetatable", luaB_setmetatable}, |
| 489 | 465 | {"tonumber", luaB_tonumber}, |
| 490 | 466 | {"tostring", luaB_tostring}, |
| @@ -503,14 +479,6 @@ LUAMOD_API int luaopen_base (lua_State *L) { · 12 unmodified lines | ||
| 503 | 479 | luaL_setfuncs(L, base_funcs, 0); |
| 504 | 480 | lua_pushliteral(L, LUA_VERSION); |
| 505 | 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 | 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 | 3 | ** Standard library for bitwise operations |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| @@ -14,25 +14,30 @@ · 8 unmodified lines | ||
| 14 | 14 | |
| 15 | 15 | |
| 16 | 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 | 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 | 36 | static b_uint andaux (lua_State *L) { |
| 32 | 37 | int i, n = lua_gettop(L); |
| 33 | 38 | b_uint r = ~(b_uint)0; |
| 34 | 39 | for (i = 1; i <= n; i++) |
| 35 | − r &= getuintarg(L, i); | |
| 40 | + r &= luaL_checkunsigned(L, i); | |
| 36 | 41 | return trim(r); |
| 37 | 42 | } |
| 38 | 43 | |
| @@ -55,7 +60,7 @@ static int b_or (lua_State *L) { · 16 unmodified lines | ||
| 55 | 60 | int i, n = lua_gettop(L); |
| 56 | 61 | b_uint r = 0; |
| 57 | 62 | for (i = 1; i <= n; i++) |
| 58 | − r |= getuintarg(L, i); | |
| 63 | + r |= luaL_checkunsigned(L, i); | |
| 59 | 64 | lua_pushunsigned(L, trim(r)); |
| 60 | 65 | return 1; |
| 61 | 66 | } |
| @@ -65,14 +70,14 @@ static int b_xor (lua_State *L) { · 3 unmodified lines | ||
| 65 | 70 | int i, n = lua_gettop(L); |
| 66 | 71 | b_uint r = 0; |
| 67 | 72 | for (i = 1; i <= n; i++) |
| 68 | − r ^= getuintarg(L, i); | |
| 73 | + r ^= luaL_checkunsigned(L, i); | |
| 69 | 74 | lua_pushunsigned(L, trim(r)); |
| 70 | 75 | return 1; |
| 71 | 76 | } |
| 72 | 77 | |
| 73 | 78 | |
| 74 | 79 | static int b_not (lua_State *L) { |
| 75 | − b_uint r = ~getuintarg(L, 1); | |
| 80 | + b_uint r = ~luaL_checkunsigned(L, 1); | |
| 76 | 81 | lua_pushunsigned(L, trim(r)); |
| 77 | 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 | 87 | if (i < 0) { /* shift right? */ |
| 83 | 88 | i = -i; |
| 84 | 89 | r = trim(r); |
| 85 | − if (i >= NBITS) r = 0; | |
| 90 | + if (i >= LUA_NBITS) r = 0; | |
| 86 | 91 | else r >>= i; |
| 87 | 92 | } |
| 88 | 93 | else { /* shift left */ |
| 89 | − if (i >= NBITS) r = 0; | |
| 94 | + if (i >= LUA_NBITS) r = 0; | |
| 90 | 95 | else r <<= i; |
| 91 | 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 | 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 | 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 | 113 | static int b_arshift (lua_State *L) { |
| 109 | − b_uint r = getuintarg(L, 1); | |
| 114 | + b_uint r = luaL_checkunsigned(L, 1); | |
| 110 | 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 | 117 | return b_shift(L, r, -i); |
| 113 | 118 | else { /* arithmetic shift for 'negative' number */ |
| 114 | − if (i >= NBITS) r = ALLONES; | |
| 119 | + if (i >= LUA_NBITS) r = ALLONES; | |
| 115 | 120 | else |
| 116 | 121 | r = trim((r >> i) | ~(~(b_uint)0 >> i)); /* add signal bit */ |
| 117 | 122 | lua_pushunsigned(L, r); |
| @@ -121,10 +126,10 @@ static int b_arshift (lua_State *L) { · 3 unmodified lines | ||
| 121 | 126 | |
| 122 | 127 | |
| 123 | 128 | static int b_rot (lua_State *L, int i) { |
| 124 | − b_uint r = getuintarg(L, 1); | |
| 125 | − i &= (NBITS - 1); /* i = i % NBITS */ | |
| 129 | + b_uint r = luaL_checkunsigned(L, 1); | |
| 130 | + i &= (LUA_NBITS - 1); /* i = i % NBITS */ | |
| 126 | 131 | r = trim(r); |
| 127 | − r = (r << i) | (r >> (NBITS - i)); | |
| 132 | + r = (r << i) | (r >> (LUA_NBITS - i)); | |
| 128 | 133 | lua_pushunsigned(L, trim(r)); |
| 129 | 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 | 187 | static const luaL_Reg bitlib[] = { |
| 144 | 188 | {"arshift", b_arshift}, |
| 145 | 189 | {"band", b_and}, |
| 146 | 190 | {"bnot", b_not}, |
| 147 | 191 | {"bor", b_or}, |
| 148 | 192 | {"bxor", b_xor}, |
| 193 | + {"btest", b_test}, | |
| 194 | + {"extract", b_extract}, | |
| 149 | 195 | {"lrotate", b_lrot}, |
| 150 | 196 | {"lshift", b_lshift}, |
| 197 | + {"replace", b_replace}, | |
| 151 | 198 | {"rrotate", b_rrot}, |
| 152 | 199 | {"rshift", b_rshift}, |
| 153 | − {"btest", b_test}, | |
| 154 | 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 | 3 | ** Code generator for Lua |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| @@ -23,6 +23,7 @@ · 17 unmodified lines | ||
| 23 | 23 | #include "lparser.h" |
| 24 | 24 | #include "lstring.h" |
| 25 | 25 | #include "ltable.h" |
| 26 | +#include "lvm.h" | |
| 26 | 27 | |
| 27 | 28 | |
| 28 | 29 | #define hasjumps(e) ((e)->t != (e)->f) |
| @@ -35,19 +36,23 @@ static int isnumeral(expdesc *e) { · 6 unmodified lines | ||
| 35 | 36 | |
| 36 | 37 | void luaK_nil (FuncState *fs, int from, int n) { |
| 37 | 38 | Instruction *previous; |
| 39 | + int l = from + n - 1; /* last register to set nil */ | |
| 38 | 40 | if (fs->pc > fs->lasttarget) { /* no jumps to current position? */ |
| 39 | 41 | previous = &fs->f->code[fs->pc-1]; |
| 40 | 42 | if (GET_OPCODE(*previous) == OP_LOADNIL) { |
| 41 | 43 | int pfrom = GETARG_A(*previous); |
| 42 | − int pto = GETARG_B(*previous); | |
| 43 | − if (pfrom <= from && from <= pto+1) { /* can connect both? */ | |
| 44 | − if (from+n-1 > pto) | |
| 45 | − SETARG_B(*previous, from+n-1); | |
| 44 | + int pl = pfrom + GETARG_B(*previous); | |
| 45 | + if ((pfrom <= from && from <= pl + 1) || | |
| 46 | + (from <= pfrom && pfrom <= l + 1)) { /* can connect both? */ | |
| 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 | 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 | 192 | void luaK_patchtohere (FuncState *fs, int list) { |
| 175 | 193 | luaK_getlabel(fs); |
| 176 | 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) { | |
| 233 | − if (k < MAXARG_Bx) | |
| 234 | − return luaK_codeABx(fs, o, reg, k + 1); | |
| 250 | +int luaK_codek (FuncState *fs, int reg, int k) { | |
| 251 | + if (k <= MAXARG_Bx) | |
| 252 | + return luaK_codeABx(fs, OP_LOADK, reg, k); | |
| 235 | 253 | else { |
| 236 | − int p = luaK_codeABx(fs, o, reg, 0); | |
| 254 | + int p = luaK_codeABx(fs, OP_LOADKX, reg, 0); | |
| 237 | 255 | codeextraarg(fs, k); |
| 238 | 256 | return p; |
| 239 | 257 | } |
| @@ -278,7 +296,7 @@ static int addk (FuncState *fs, TValue *key, TValue *v) { · 38 unmodified lines | ||
| 278 | 296 | if (ttisnumber(idx)) { |
| 279 | 297 | lua_Number n = nvalue(idx); |
| 280 | 298 | lua_number2int(k, n); |
| 281 | − if (luaO_rawequalObj(&f->k[k], v)) | |
| 299 | + if (luaV_rawequalobj(&f->k[k], v)) | |
| 282 | 300 | return k; |
| 283 | 301 | /* else may be a collision (e.g., between 0.0 and "\0\0\0\0\0\0\0\0"); |
| 284 | 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 | 584 | void luaK_self (FuncState *fs, expdesc *e, expdesc *key) { |
| 567 | − int func; | |
| 585 | + int ereg; | |
| 568 | 586 | luaK_exp2anyreg(fs, e); |
| 587 | + ereg = e->u.info; /* register where 'e' was placed */ | |
| 569 | 588 | freeexp(fs, e); |
| 570 | − func = fs->freereg; | |
| 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; | |
| 589 | + e->u.info = fs->freereg; /* base register for op_self */ | |
| 575 | 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 | 621 | int pc; /* pc of last jump */ |
| 604 | 622 | luaK_dischargevars(fs, e); |
| 605 | 623 | switch (e->k) { |
| 606 | − case VK: case VKNUM: case VTRUE: { | |
| 607 | − pc = NO_JUMP; /* always true; do nothing */ | |
| 608 | − break; | |
| 609 | − } | |
| 610 | 624 | case VJMP: { |
| 611 | 625 | invertjump(fs, e); |
| 612 | 626 | pc = e->u.info; |
| 613 | 627 | break; |
| 614 | 628 | } |
| 615 | − case VFALSE: { | |
| 616 | − if (!hasjumps(e)) { | |
| 617 | − pc = luaK_jump(fs); /* always jump */ | |
| 618 | − break; | |
| 619 | − } | |
| 620 | − /* else go through */ | |
| 629 | + case VK: case VKNUM: case VTRUE: { | |
| 630 | + pc = NO_JUMP; /* always true; do nothing */ | |
| 631 | + break; | |
| 621 | 632 | } |
| 622 | 633 | default: { |
| 623 | 634 | pc = jumponcond(fs, e, 0); |
| @@ -634,20 +645,13 @@ static void luaK_goiffalse (FuncState *fs, expdesc *e) { · 10 unmodified lines | ||
| 634 | 645 | int pc; /* pc of last jump */ |
| 635 | 646 | luaK_dischargevars(fs, e); |
| 636 | 647 | switch (e->k) { |
| 637 | − case VNIL: case VFALSE: { | |
| 638 | − pc = NO_JUMP; /* always false; do nothing */ | |
| 639 | − break; | |
| 640 | − } | |
| 641 | 648 | case VJMP: { |
| 642 | 649 | pc = e->u.info; |
| 643 | 650 | break; |
| 644 | 651 | } |
| 645 | − case VTRUE: { | |
| 646 | − if (!hasjumps(e)) { | |
| 647 | − pc = luaK_jump(fs); /* always jump */ | |
| 648 | − break; | |
| 649 | − } | |
| 650 | − /* else go through */ | |
| 652 | + case VNIL: case VFALSE: { | |
| 653 | + pc = NO_JUMP; /* always false; do nothing */ | |
| 654 | + break; | |
| 651 | 655 | } |
| 652 | 656 | default: { |
| 653 | 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 | 3 | ** Code generator for Lua |
| 4 | 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 | 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 | 47 | LUAI_FUNC int luaK_codeABx (FuncState *fs, OpCode o, int A, unsigned int Bx); |
| 50 | 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 | 50 | LUAI_FUNC void luaK_fixline (FuncState *fs, int line); |
| 53 | 51 | LUAI_FUNC void luaK_nil (FuncState *fs, int from, int n); |
| 54 | 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 | 69 | LUAI_FUNC void luaK_ret (FuncState *fs, int first, int nret); |
| 72 | 70 | LUAI_FUNC void luaK_patchlist (FuncState *fs, int list, int target); |
| 73 | 71 | LUAI_FUNC void luaK_patchtohere (FuncState *fs, int list); |
| 72 | +LUAI_FUNC void luaK_patchclose (FuncState *fs, int list, int level); | |
| 74 | 73 | LUAI_FUNC void luaK_concat (FuncState *fs, int *l1, int l2); |
| 75 | 74 | LUAI_FUNC int luaK_getlabel (FuncState *fs); |
| 76 | 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 | 3 | ** Interface from Lua to its debug API |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| @@ -18,6 +18,9 @@ · 12 unmodified lines | ||
| 18 | 18 | #include "lualib.h" |
| 19 | 19 | |
| 20 | 20 | |
| 21 | +#define HOOKKEY "_HKEY" | |
| 22 | + | |
| 23 | + | |
| 21 | 24 | |
| 22 | 25 | static int db_getregistry (lua_State *L) { |
| 23 | 26 | lua_pushvalue(L, LUA_REGISTRYINDEX); |
| @@ -39,8 +42,8 @@ static int db_setmetatable (lua_State *L) { · 15 unmodified lines | ||
| 39 | 42 | luaL_argcheck(L, t == LUA_TNIL || t == LUA_TTABLE, 2, |
| 40 | 43 | "nil or table expected"); |
| 41 | 44 | lua_settop(L, 2); |
| 42 | − lua_pushboolean(L, lua_setmetatable(L, 1)); | |
| 43 | − return 1; | |
| 45 | + lua_setmetatable(L, 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 | 259 | static void hookf (lua_State *L, lua_Debug *ar) { |
| 257 | 260 | static const char *const hooknames[] = |
| 258 | 261 | {"call", "return", "line", "count", "tail call"}; |
| 259 | − lua_pushlightuserdata(L, (void *)&KEY_HOOK); | |
| 260 | − lua_rawget(L, LUA_REGISTRYINDEX); | |
| 262 | + gethooktable(L); | |
| 261 | 263 | lua_pushlightuserdata(L, L); |
| 262 | 264 | lua_rawget(L, -2); |
| 263 | 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 | 296 | static int db_sethook (lua_State *L) { |
| 308 | 297 | int arg, mask, count; |
| 309 | 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 | 3 | ** Debug Interface |
| 4 | 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 | 36 | static int currentpc (CallInfo *ci) { |
| 37 | 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 | 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 | 108 | static const char *findlocal (lua_State *L, CallInfo *ci, int n, |
| 98 | 109 | StkId *pos) { |
| 99 | 110 | const char *name = NULL; |
| 100 | 111 | StkId base; |
| 101 | 112 | if (isLua(ci)) { |
| 102 | − base = ci->u.l.base; | |
| 103 | − name = luaF_getlocalname(ci_func(ci)->l.p, n, currentpc(ci)); | |
| 113 | + if (n < 0) /* access to vararg values? */ | |
| 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 | 120 | else |
| 106 | 121 | base = ci->func + 1; |
| @@ -108,10 +123,8 @@ static const char *findlocal (lua_State *L, CallInfo *ci, int n, · 1 unmodified line | ||
| 108 | 123 | StkId limit = (ci == L->ci) ? L->top : ci->next->func; |
| 109 | 124 | if (limit - base >= n && n > 0) /* is 'n' inside 'ci' stack? */ |
| 110 | 125 | name = "(*temporary)"; /* generic name for any valid slot */ |
| 111 | − else { | |
| 112 | − *pos = base; /* to avoid warnings */ | |
| 126 | + else | |
| 113 | 127 | return NULL; /* no name */ |
| 114 | − } | |
| 115 | 128 | } |
| 116 | 129 | *pos = base + (n - 1); |
| 117 | 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 | 138 | if (!isLfunction(L->top - 1)) /* not a Lua function? */ |
| 126 | 139 | name = NULL; |
| 127 | 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 | 143 | else { /* active function; get information through 'ar' */ |
| 131 | − StkId pos; | |
| 144 | + StkId pos = 0; /* to avoid warnings */ | |
| 132 | 145 | name = findlocal(L, ar->i_ci, n, &pos); |
| 133 | 146 | if (name) { |
| 134 | 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 | 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 | 158 | const char *name = findlocal(L, ar->i_ci, n, &pos); |
| 146 | 159 | lua_lock(L); |
| 147 | 160 | if (name) |
| 148 | − setobjs2s(L, pos, L->top - 1); | |
| 161 | + setobjs2s(L, pos, L->top - 1); | |
| 149 | 162 | L->top--; /* pop value */ |
| 150 | 163 | lua_unlock(L); |
| 151 | 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 | 256 | if (*what == '>') { |
| 244 | 257 | ci = NULL; |
| 245 | 258 | func = L->top - 1; |
| 246 | − luai_apicheck(L, ttisfunction(func)); | |
| 259 | + api_check(L, ttisfunction(func), "function expected"); | |
| 247 | 260 | what++; /* skip the '>' */ |
| 248 | 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, | |
| 276 | − const char **name) { | |
| 277 | − if (c == reg && what && *what == 'c') | |
| 278 | − return; /* index is a constant; name already correct */ | |
| 279 | − else if (ISK(c) && ttisstring(&p->k[INDEXK(c)])) | |
| 280 | − *name = svalue(&p->k[INDEXK(c)]); | |
| 281 | − else | |
| 282 | − *name = "?"; | |
| 290 | + | |
| 291 | +/* | |
| 292 | +** find a "name" for the RK value 'c' | |
| 293 | +*/ | |
| 294 | +static void kname (lua_State *L, CallInfo *ci, int c, int oreg, | |
| 295 | + const char *what, const char **name) { | |
| 296 | + if (ISK(c)) { /* is 'c' a constant? */ | |
| 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 | 316 | static const char *getobjname (lua_State *L, CallInfo *ci, int reg, |
| 287 | 317 | const char **name) { |
| 288 | − Proto *p = ci_func(ci)->l.p; | |
| 318 | + Proto *p = ci_func(ci)->p; | |
| 289 | 319 | const char *what = NULL; |
| 290 | 320 | int lastpc = currentpc(ci); |
| 291 | 321 | int pc; |
| @@ -312,10 +342,10 @@ static const char *getobjname (lua_State *L, CallInfo *ci, int reg, · 20 unmodified lines | ||
| 312 | 342 | if (reg == a) { |
| 313 | 343 | int k = GETARG_C(i); /* key index */ |
| 314 | 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 | 346 | ? luaF_getlocalname(p, t + 1, pc) |
| 317 | 347 | : getstr(p->upvalues[t].name); |
| 318 | − kname(p, k, a, what, name); | |
| 348 | + kname(L, ci, k, a, what, name); | |
| 319 | 349 | what = (vn && strcmp(vn, LUA_ENV) == 0) ? "global" : "field"; |
| 320 | 350 | } |
| 321 | 351 | break; |
| @@ -329,10 +359,11 @@ static const char *getobjname (lua_State *L, CallInfo *ci, int reg, · 7 unmodified lines | ||
| 329 | 359 | } |
| 330 | 360 | break; |
| 331 | 361 | } |
| 332 | − case OP_LOADK: { | |
| 362 | + case OP_LOADK: | |
| 363 | + case OP_LOADKX: { | |
| 333 | 364 | if (reg == a) { |
| 334 | − int b = GETARG_Bx(i); | |
| 335 | − b = (b > 0) ? b - 1 : GETARG_Ax(p->code[pc + 1]); | |
| 365 | + int b = (op == OP_LOADK) ? GETARG_Bx(i) | |
| 366 | + : GETARG_Ax(p->code[pc + 1]); | |
| 336 | 367 | if (ttisstring(&p->k[b])) { |
| 337 | 368 | what = "constant"; |
| 338 | 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 | 372 | break; |
| 342 | 373 | } |
| 343 | 374 | case OP_LOADNIL: { |
| 344 | − int b = GETARG_B(i); /* move from 'b' to 'a' */ | |
| 345 | − if (a <= reg && reg <= b) /* set registers from 'a' to 'b' */ | |
| 375 | + int b = GETARG_B(i); | |
| 376 | + if (a <= reg && reg <= a + b) /* set registers from 'a' to 'a+b' */ | |
| 346 | 377 | what = NULL; |
| 347 | 378 | break; |
| 348 | 379 | } |
| 349 | 380 | case OP_SELF: { |
| 350 | 381 | if (reg == a) { |
| 351 | 382 | int k = GETARG_C(i); /* key index */ |
| 352 | − kname(p, k, a, what, name); | |
| 383 | + kname(L, ci, k, a, what, name); | |
| 353 | 384 | what = "method"; |
| 354 | 385 | } |
| 355 | 386 | break; |
| @@ -371,6 +402,10 @@ static const char *getobjname (lua_State *L, CallInfo *ci, int reg, · 15 unmodified lines | ||
| 371 | 402 | pc += b; /* do the jump */ |
| 372 | 403 | break; |
| 373 | 404 | } |
| 405 | + case OP_TEST: { | |
| 406 | + if (reg == a) what = NULL; /* jumped code can change 'a' */ | |
| 407 | + break; | |
| 408 | + } | |
| 374 | 409 | default: |
| 375 | 410 | if (testAMode(op) && reg == a) what = NULL; |
| 376 | 411 | break; |
| @@ -386,9 +421,9 @@ static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name) { · 9 unmodified lines | ||
| 386 | 421 | if ((ci->callstatus & CIST_TAIL) || !isLua(ci->previous)) |
| 387 | 422 | return NULL; /* calling function is not Lua (or is unknown) */ |
| 388 | 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 | 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 | 427 | switch (GET_OPCODE(i)) { |
| 393 | 428 | case OP_CALL: |
| 394 | 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 | 467 | static int isinstack (CallInfo *ci, const TValue *o) { |
| 430 | 468 | StkId p; |
| 431 | 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 | 475 | static const char *getupvalname (CallInfo *ci, const TValue *o, |
| 438 | 476 | const char **name) { |
| 439 | − LClosure *c = &ci_func(ci)->l; | |
| 477 | + LClosure *c = ci_func(ci); | |
| 440 | 478 | int i; |
| 441 | 479 | for (i = 0; i < c->nupvalues; i++) { |
| 442 | 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 | 493 | const char *kind = NULL; |
| 456 | 494 | if (isLua(ci)) { |
| 457 | 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 | 497 | kind = getobjname(L, ci, cast_int(o - ci->u.l.base), &name); |
| 460 | 498 | } |
| 461 | 499 | if (kind) |
| @@ -497,7 +535,7 @@ static void addinfo (lua_State *L, const char *msg) { · 35 unmodified lines | ||
| 497 | 535 | if (isLua(ci)) { /* is Lua code? */ |
| 498 | 536 | char buff[LUA_IDSIZE]; /* add file:line information */ |
| 499 | 537 | int line = currentline(ci); |
| 500 | − TString *src = ci_func(ci)->l.p->source; | |
| 538 | + TString *src = ci_func(ci)->p->source; | |
| 501 | 539 | if (src) |
| 502 | 540 | luaO_chunkid(buff, getstr(src), LUA_IDSIZE); |
| 503 | 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 | 3 | ** Auxiliary functions from Debug Interface module |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| @@ -17,6 +17,9 @@ · 11 unmodified lines | ||
| 17 | 17 | |
| 18 | 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 | 24 | LUAI_FUNC void luaG_typeerror (lua_State *L, const TValue *o, |
| 22 | 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 | 3 | ** Stack and Call structure of Lua |
| 4 | 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 | 293 | ** returns true if function has been executed (C function) |
| 294 | 294 | */ |
| 295 | 295 | int luaD_precall (lua_State *L, StkId func, int nresults) { |
| 296 | − Closure *cl; | |
| 297 | 296 | lua_CFunction f; |
| 298 | − ptrdiff_t funcr; | |
| 299 | − if (!ttisfunction(func)) /* `func' is not a function? */ | |
| 300 | − func = tryfuncTM(L, func); /* check the `function' tag method */ | |
| 301 | − funcr = savestack(L, func); | |
| 302 | − if (ttislcf(func)) { /* light C function? */ | |
| 303 | − f = fvalue(func); /* get it */ | |
| 304 | − goto isCfunc; /* go to call it */ | |
| 305 | − } | |
| 306 | − cl = clvalue(func); | |
| 307 | − if (cl->c.isC) { /* C closure? */ | |
| 308 | − CallInfo *ci; | |
| 309 | − int n; | |
| 310 | − f = cl->c.f; | |
| 311 | − isCfunc: /* call C function 'f' */ | |
| 312 | − luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */ | |
| 313 | − ci = next_ci(L); /* now 'enter' new function */ | |
| 314 | − ci->nresults = nresults; | |
| 315 | − ci->func = restorestack(L, funcr); | |
| 316 | − ci->top = L->top + LUA_MINSTACK; | |
| 317 | − lua_assert(ci->top <= L->stack_last); | |
| 318 | − ci->callstatus = 0; | |
| 319 | − if (L->hookmask & LUA_MASKCALL) | |
| 320 | − luaD_hook(L, LUA_HOOKCALL, -1); | |
| 321 | − lua_unlock(L); | |
| 322 | − n = (*f)(L); /* do the actual call */ | |
| 323 | − lua_lock(L); | |
| 324 | − api_checknelems(L, n); | |
| 325 | − luaD_poscall(L, L->top - n); | |
| 326 | − return 1; | |
| 327 | − } | |
| 328 | − else { /* Lua function: prepare its call */ | |
| 329 | − CallInfo *ci; | |
| 330 | − int nparams, nargs; | |
| 331 | − StkId base; | |
| 332 | − Proto *p = cl->l.p; | |
| 333 | − luaD_checkstack(L, p->maxstacksize); | |
| 334 | − func = restorestack(L, funcr); | |
| 335 | − nargs = cast_int(L->top - func) - 1; /* number of real arguments */ | |
| 336 | − nparams = p->numparams; /* number of expected parameters */ | |
| 337 | − for (; nargs < nparams; nargs++) | |
| 338 | − setnilvalue(L->top++); /* complete missing arguments */ | |
| 339 | − if (!p->is_vararg) /* no varargs? */ | |
| 340 | − base = func + 1; | |
| 341 | − else /* vararg function */ | |
| 342 | − base = adjust_varargs(L, p, nargs); | |
| 343 | − ci = next_ci(L); /* now 'enter' new function */ | |
| 344 | − ci->nresults = nresults; | |
| 345 | − ci->func = func; | |
| 346 | − ci->u.l.base = base; | |
| 347 | − ci->top = base + p->maxstacksize; | |
| 348 | − lua_assert(ci->top <= L->stack_last); | |
| 349 | − ci->u.l.savedpc = p->code; /* starting point */ | |
| 350 | − ci->callstatus = CIST_LUA; | |
| 351 | − L->top = ci->top; | |
| 352 | − if (L->hookmask & LUA_MASKCALL) | |
| 353 | − callhook(L, ci); | |
| 354 | − return 0; | |
| 297 | + CallInfo *ci; | |
| 298 | + int n; /* number of arguments (Lua) or returns (C) */ | |
| 299 | + ptrdiff_t funcr = savestack(L, func); | |
| 300 | + switch (ttype(func)) { | |
| 301 | + case LUA_TLCF: /* light C function */ | |
| 302 | + f = fvalue(func); | |
| 303 | + goto Cfunc; | |
| 304 | + case LUA_TCCL: { /* C closure */ | |
| 305 | + f = clCvalue(func)->f; | |
| 306 | + Cfunc: | |
| 307 | + luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */ | |
| 308 | + ci = next_ci(L); /* now 'enter' new function */ | |
| 309 | + ci->nresults = nresults; | |
| 310 | + ci->func = restorestack(L, funcr); | |
| 311 | + ci->top = L->top + LUA_MINSTACK; | |
| 312 | + lua_assert(ci->top <= L->stack_last); | |
| 313 | + ci->callstatus = 0; | |
| 314 | + if (L->hookmask & LUA_MASKCALL) | |
| 315 | + luaD_hook(L, LUA_HOOKCALL, -1); | |
| 316 | + lua_unlock(L); | |
| 317 | + n = (*f)(L); /* do the actual call */ | |
| 318 | + lua_lock(L); | |
| 319 | + api_checknelems(L, n); | |
| 320 | + luaD_poscall(L, L->top - n); | |
| 321 | + return 1; | |
| 322 | + } | |
| 323 | + case LUA_TLCL: { /* Lua function: prepare its call */ | |
| 324 | + StkId base; | |
| 325 | + Proto *p = clLvalue(func)->p; | |
| 326 | + luaD_checkstack(L, p->maxstacksize); | |
| 327 | + func = restorestack(L, funcr); | |
| 328 | + n = cast_int(L->top - func) - 1; /* number of real arguments */ | |
| 329 | + for (; n < p->numparams; n++) | |
| 330 | + setnilvalue(L->top++); /* complete missing arguments */ | |
| 331 | + base = (!p->is_vararg) ? func + 1 : adjust_varargs(L, p, n); | |
| 332 | + ci = next_ci(L); /* now 'enter' new function */ | |
| 333 | + ci->nresults = nresults; | |
| 334 | + ci->func = func; | |
| 335 | + ci->u.l.base = base; | |
| 336 | + ci->top = base + p->maxstacksize; | |
| 337 | + lua_assert(ci->top <= L->stack_last); | |
| 338 | + ci->u.l.savedpc = p->code; /* starting point */ | |
| 339 | + ci->callstatus = CIST_LUA; | |
| 340 | + L->top = ci->top; | |
| 341 | + if (L->hookmask & LUA_MASKCALL) | |
| 342 | + callhook(L, ci); | |
| 343 | + return 0; | |
| 344 | + } | |
| 345 | + default: { /* not a function */ | |
| 346 | + func = tryfuncTM(L, func); /* retry with 'function' tag method */ | |
| 347 | + return luaD_precall(L, func, nresults); | |
| 348 | + } | |
| 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 | 610 | struct SParser { /* data to `f_parser' */ |
| 617 | 611 | ZIO *z; |
| 618 | − Mbuffer buff; /* buffer to be used by the scanner */ | |
| 619 | − Varlist varl; /* list of local variables (to be used by the parser) */ | |
| 612 | + Mbuffer buff; /* dynamic structure used by the scanner */ | |
| 613 | + Dyndata dyd; /* dynamic structures used by the parser */ | |
| 620 | 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 | 619 | Proto *tf; |
| 626 | 620 | Closure *cl; |
| 627 | 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 | 623 | tf = (c == LUA_SIGNATURE[0]) |
| 630 | 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 | 626 | setptvalue2s(L, L->top, tf); |
| 633 | 627 | incr_top(L); |
| 634 | 628 | cl = luaF_newLclosure(L, tf); |
| 635 | − setclvalue(L, L->top - 1, cl); | |
| 629 | + setclLvalue(L, L->top - 1, cl); | |
| 636 | 630 | for (i = 0; i < tf->sizeupvalues; i++) /* initialize upvalues */ |
| 637 | 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 | 637 | int status; |
| 644 | 638 | L->nny++; /* cannot yield during parsing */ |
| 645 | 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 | 643 | luaZ_initbuffer(L, &p.buff); |
| 648 | 644 | status = luaD_pcall(L, f_parser, &p, savestack(L, L->top), L->errfunc); |
| 649 | 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 | 649 | L->nny--; |
| 652 | 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 | 3 | ** save precompiled Lua chunks |
| 4 | 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 | 70 | size_t size=s->tsv.len+1; /* include trailing '\0' */ |
| 71 | 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 | 151 | static void DumpHeader(DumpState* D) |
| 152 | 152 | { |
| 153 | − char h[LUAC_HEADERSIZE]; | |
| 153 | + lu_byte h[LUAC_HEADERSIZE]; | |
| 154 | 154 | luaU_header(h); |
| 155 | 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 | 3 | ** Garbage Collector |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| @@ -51,7 +51,7 @@ · 45 unmodified lines | ||
| 51 | 51 | ** standard negative debt for GC; a reasonable "time" to wait before |
| 52 | 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 | 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 | 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 | 80 | #define markvalue(g,o) { checkconsistency(o); \ |
| 77 | 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 | 119 | static int iscleared (const TValue *o, int iskey) { |
| 116 | 120 | if (!iscollectable(o)) return 0; |
| 117 | − if (ttisstring(o)) { | |
| 121 | + else if (ttisstring(o)) { | |
| 118 | 122 | stringmark(rawtsvalue(o)); /* strings are `values', so are never weak */ |
| 119 | 123 | return 0; |
| 120 | 124 | } |
| 121 | − return iswhite(gcvalue(o)) || | |
| 122 | − (ttisuserdata(o) && (!iskey && isfinalized(uvalue(o)))); | |
| 125 | + else return iswhite(gcvalue(o)) || (!iskey && isfinalized(gcvalue(o))); | |
| 123 | 126 | } |
| 124 | 127 | |
| 125 | 128 | |
| @@ -319,8 +322,7 @@ static void remarkupvals (global_State *g) { · 193 unmodified lines | ||
| 319 | 322 | ** mark root set and reset all gray lists, to start a new |
| 320 | 323 | ** incremental (or full) collection |
| 321 | 324 | */ |
| 322 | −static void markroot (lua_State *L) { | |
| 323 | − global_State *g = G(L); | |
| 325 | +static void markroot (global_State *g) { | |
| 324 | 326 | g->gray = g->grayagain = NULL; |
| 325 | 327 | g->weak = g->allweak = g->ephemeron = NULL; |
| 326 | 328 | markobject(g, g->mainthread); |
| @@ -635,6 +637,7 @@ static GCObject **sweeplist (lua_State *L, GCObject **p, lu_mem count) { · 308 unmodified lines | ||
| 635 | 637 | int ow = otherwhite(g); |
| 636 | 638 | int toclear, toset; /* bits to clear and to set in all live objects */ |
| 637 | 639 | int tostop; /* stop sweep when this is true */ |
| 640 | + l_mem debt = g->GCdebt; /* current debt */ | |
| 638 | 641 | if (isgenerational(g)) { /* generational mode? */ |
| 639 | 642 | toclear = ~0; /* clear nothing */ |
| 640 | 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 | 660 | sweepthread(L, gco2th(curr)); /* sweep thread's upvalues */ |
| 658 | 661 | if (testbits(marked, tostop)) { |
| 659 | 662 | static GCObject *nullp = NULL; |
| 660 | − return &nullp; /* stop sweeping this list */ | |
| 663 | + p = &nullp; /* stop sweeping this list */ | |
| 664 | + break; | |
| 661 | 665 | } |
| 662 | 666 | /* update marks */ |
| 663 | 667 | gch(curr)->marked = cast_byte((marked & toclear) | toset); |
| 664 | 668 | p = &gch(curr)->next; /* go to next element */ |
| 665 | 669 | } |
| 666 | 670 | } |
| 671 | + luaE_setdebt(g, debt); /* sweeping should not change debt */ | |
| 667 | 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 | 696 | GCObject *o = g->tobefnz; /* get first element */ |
| 692 | − Udata *u = rawgco2u(o); | |
| 693 | − lua_assert(isfinalized(&u->uv)); | |
| 694 | − lua_assert(!isold(o)); | |
| 695 | − g->tobefnz = u->uv.next; /* remove it from 'tobefnz' list */ | |
| 696 | − u->uv.next = g->allgc; /* return it to 'allgc' list */ | |
| 697 | + lua_assert(isfinalized(o)); | |
| 698 | + g->tobefnz = gch(o)->next; /* remove it from 'tobefnz' list */ | |
| 699 | + gch(o)->next = g->allgc; /* return it to 'allgc' list */ | |
| 697 | 700 | g->allgc = o; |
| 698 | − resetbit(u->uv.marked, SEPARATED); /* mark that it is not in 'tobefnz' */ | |
| 699 | − resetoldbit(o); /* see MOVE OLD rule */ | |
| 701 | + resetbit(gch(o)->marked, SEPARATED); /* mark that it is not in 'tobefnz' */ | |
| 702 | + lua_assert(!isold(o)); /* see MOVE OLD rule */ | |
| 700 | 703 | if (!keepinvariant(g)) /* not keeping invariant? */ |
| 701 | 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 | 715 | static void GCTM (lua_State *L, int propagateerrors) { |
| 713 | 716 | global_State *g = G(L); |
| 714 | − Udata *udata = udata2finalize(g); | |
| 715 | − const TValue *tm = gfasttm(g, udata->uv.metatable, TM_GC); | |
| 717 | + const TValue *tm; | |
| 718 | + TValue v; | |
| 719 | + setgcovalue(L, &v, udata2finalize(g)); | |
| 720 | + tm = luaT_gettmbyobj(L, &v, TM_GC); | |
| 716 | 721 | if (tm != NULL && ttisfunction(tm)) { /* is there a finalizer? */ |
| 717 | 722 | int status; |
| 718 | 723 | lu_byte oldah = L->allowhook; |
| 719 | − lu_mem oldd = g->GCdebt; | |
| 724 | + int running = g->gcrunning; | |
| 720 | 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 | 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 | 729 | L->top += 2; /* and (next line) call the finalizer */ |
| 725 | 730 | status = luaD_pcall(L, dothecall, NULL, savestack(L, L->top - 2), 0); |
| 726 | 731 | L->allowhook = oldah; /* restore hooks */ |
| 727 | − g->GCdebt = oldd; /* restore threshold */ | |
| 732 | + g->gcrunning = running; /* restore state */ | |
| 728 | 733 | if (status != LUA_OK && propagateerrors) { /* error while running __gc? */ |
| 729 | 734 | if (status == LUA_ERRRUN) { /* is there an error msg.? */ |
| 730 | 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 | |
| 742 | −** list 'tobefnz' | |
| 746 | +** move all unreachable objects that need finalization from list 'finobj' | |
| 747 | +** to list 'tobefnz' | |
| 743 | 748 | */ |
| 744 | 749 | void luaC_separateudata (lua_State *L, int all) { |
| 745 | 750 | global_State *g = G(L); |
| 746 | − GCObject **p = &g->udgc; | |
| 751 | + GCObject **p = &g->finobj; | |
| 747 | 752 | GCObject *curr; |
| 748 | 753 | GCObject **lastnext = &g->tobefnz; |
| 749 | 754 | /* find last 'next' field in 'tobefnz' list (to add elements in its end) */ |
| 750 | 755 | while (*lastnext != NULL) |
| 751 | 756 | lastnext = &gch(*lastnext)->next; |
| 752 | 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 | 759 | lua_assert(testbit(gch(curr)->marked, SEPARATED)); |
| 755 | 760 | if (!(all || iswhite(curr))) /* not being collected? */ |
| 756 | 761 | p = &gch(curr)->next; /* don't bother with it */ |
| 757 | 762 | else { |
| 758 | 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 | 765 | gch(curr)->next = *lastnext; /* link at the end of 'tobefnz' list */ |
| 761 | 766 | *lastnext = curr; |
| 762 | 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 | |
| 770 | −** search the list to find it) and link it in 'udgc' list. | |
| 774 | +** if object 'o' has a finalizer, remove it from 'allgc' list (must | |
| 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 | 778 | global_State *g = G(L); |
| 774 | − if (testbit(u->uv.marked, SEPARATED) || /* udata is already separated... */ | |
| 775 | − isfinalized(&u->uv) || /* ... or is finalized... */ | |
| 776 | − gfasttm(g, u->uv.metatable, TM_GC) == NULL) /* or has no finalizer? */ | |
| 779 | + if (testbit(gch(o)->marked, SEPARATED) || /* obj. is already separated... */ | |
| 780 | + isfinalized(o) || /* ... or is finalized... */ | |
| 781 | + gfasttm(g, mt, TM_GC) == NULL) /* or has no finalizer? */ | |
| 777 | 782 | return; /* nothing to be done */ |
| 778 | − else { /* move 'u' to 'udgc' list */ | |
| 783 | + else { /* move 'o' to 'finobj' list */ | |
| 779 | 784 | GCObject **p; |
| 780 | − for (p = &g->allgc; *p != obj2gco(u); p = &gch(*p)->next) ; | |
| 781 | − *p = u->uv.next; /* remove 'u' from root list */ | |
| 782 | − u->uv.next = g->udgc; /* link it in list 'udgc' */ | |
| 783 | − g->udgc = obj2gco(u); | |
| 784 | − l_setbit(u->uv.marked, SEPARATED); /* mark it as such */ | |
| 785 | − resetoldbit(obj2gco(u)); /* see MOVE OLD rule */ | |
| 785 | + for (p = &g->allgc; *p != o; p = &gch(*p)->next) ; | |
| 786 | + *p = gch(o)->next; /* remove 'o' from root list */ | |
| 787 | + gch(o)->next = g->finobj; /* link it in list 'finobj' */ | |
| 788 | + g->finobj = o; | |
| 789 | + l_setbit(gch(o)->marked, SEPARATED); /* mark it as such */ | |
| 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 | 813 | if (mode == KGC_GEN) { /* change to generational mode */ |
| 809 | 814 | /* make sure gray lists are consistent */ |
| 810 | 815 | luaC_runtilstate(L, bitmask(GCSpropagate)); |
| 811 | − g->lastmajormem = g->totalbytes; | |
| 816 | + g->lastmajormem = gettotalbytes(g); | |
| 812 | 817 | g->gckind = KGC_GEN; |
| 813 | 818 | } |
| 814 | 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 | 833 | static void callallpendingfinalizers (lua_State *L, int propagateerrors) { |
| 828 | 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 | 846 | /* following "white" makes all objects look dead */ |
| 838 | 847 | g->currentwhite = WHITEBITS; |
| 839 | 848 | g->gckind = KGC_NORMAL; |
| 840 | − sweepwholelist(L, &g->udgc); | |
| 841 | − lua_assert(g->udgc == NULL); | |
| 849 | + sweepwholelist(L, &g->finobj); | |
| 850 | + lua_assert(g->finobj == NULL); | |
| 842 | 851 | sweepwholelist(L, &g->allgc); |
| 843 | 852 | lua_assert(g->allgc == NULL); |
| 844 | 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 | 892 | switch (g->gcstate) { |
| 884 | 893 | case GCSpause: { |
| 885 | 894 | if (!isgenerational(g)) |
| 886 | − markroot(L); /* start a new collection */ | |
| 895 | + markroot(g); /* start a new collection */ | |
| 887 | 896 | /* in any case, root must be marked */ |
| 888 | 897 | lua_assert(!iswhite(obj2gco(g->mainthread)) |
| 889 | 898 | && !iswhite(gcvalue(&g->l_registry))); |
| @@ -905,7 +914,7 @@ static l_mem singlestep (lua_State *L) { · 15 unmodified lines | ||
| 905 | 914 | return GCSWEEPCOST; |
| 906 | 915 | } |
| 907 | 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 | 918 | g->gcstate = GCSsweepudata; |
| 910 | 919 | return 0; |
| 911 | 920 | } |
| @@ -955,15 +964,15 @@ static void generationalcollection (lua_State *L) { · 43 unmodified lines | ||
| 955 | 964 | global_State *g = G(L); |
| 956 | 965 | if (g->lastmajormem == 0) { /* signal for another major collection? */ |
| 957 | 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 | 969 | else { |
| 961 | 970 | luaC_runtilstate(L, ~bitmask(GCSpause)); /* run complete cycle */ |
| 962 | 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 | 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 | 983 | lim -= singlestep(L); |
| 975 | 984 | } while (lim > 0 && g->gcstate != GCSpause); |
| 976 | 985 | if (g->gcstate != GCSpause) |
| 977 | − g->GCdebt -= GCSTEPSIZE; | |
| 986 | + luaE_setdebt(g, g->GCdebt - GCSTEPSIZE); | |
| 978 | 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 | 997 | int i; |
| 985 | − if (isgenerational(G(L))) generationalcollection(L); | |
| 998 | + if (isgenerational(g)) generationalcollection(L); | |
| 986 | 999 | else step(L); |
| 987 | − for (i = 0; i < GCFINALIZENUM && G(L)->tobefnz; i++) | |
| 1000 | + for (i = 0; i < GCFINALIZENUM && g->tobefnz; i++) | |
| 988 | 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 | 1014 | ** performs a full GC cycle; if "isemergency", does not call |
| 994 | 1015 | ** finalizers (which could change stack positions) |
| @@ -1016,7 +1037,7 @@ void luaC_fullgc (lua_State *L, int isemergency) { · 21 unmodified lines | ||
| 1016 | 1037 | luaC_runtilstate(L, bitmask(GCSpropagate)); |
| 1017 | 1038 | } |
| 1018 | 1039 | g->gckind = origkind; |
| 1019 | − g->GCdebt = stddebt(g); | |
| 1040 | + luaE_setdebt(g, stddebt(g)); | |
| 1020 | 1041 | if (!isemergency) /* do not run finalizers during emergency GC */ |
| 1021 | 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 | 3 | ** Garbage Collector |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| @@ -52,10 +52,6 @@ · 46 unmodified lines | ||
| 52 | 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 | 56 | ** some useful bit tricks |
| 61 | 57 | */ |
| @@ -76,8 +72,8 @@ · 14 unmodified lines | ||
| 76 | 72 | #define WHITE0BIT 0 /* object is white (type 0) */ |
| 77 | 73 | #define WHITE1BIT 1 /* object is white (type 1) */ |
| 78 | 74 | #define BLACKBIT 2 /* object is black */ |
| 79 | −#define FINALIZEDBIT 3 /* for userdata: has been finalized */ | |
| 80 | −#define SEPARATED 4 /* " ": it's in 'udgc' list or in 'tobefnz' */ | |
| 75 | +#define FINALIZEDBIT 3 /* object has been separated for finalization */ | |
| 76 | +#define SEPARATED 4 /* object is in 'finobj' list or in 'tobefnz' */ | |
| 81 | 77 | #define FIXEDBIT 5 /* object is fixed (should not be collected) */ |
| 82 | 78 | #define OLDBIT 6 /* object is old (only in generational mode) */ |
| 83 | 79 | /* bit 7 is currently used by tests (luaL_checkmemory) */ |
| @@ -108,7 +104,9 @@ · 24 unmodified lines | ||
| 108 | 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 | 112 | #define luaC_barrier(L,p,v) { if (valiswhite(v) && isblack(obj2gco(p))) \ |
| @@ -130,6 +128,7 @@ · 15 unmodified lines | ||
| 130 | 128 | LUAI_FUNC void luaC_separateudata (lua_State *L, int all); |
| 131 | 129 | LUAI_FUNC void luaC_freeallobjects (lua_State *L); |
| 132 | 130 | LUAI_FUNC void luaC_step (lua_State *L); |
| 131 | +LUAI_FUNC void luaC_forcestep (lua_State *L); | |
| 133 | 132 | LUAI_FUNC void luaC_runtilstate (lua_State *L, int statesmask); |
| 134 | 133 | LUAI_FUNC void luaC_fullgc (lua_State *L, int isemergency); |
| 135 | 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 | 136 | LUAI_FUNC void luaC_barrier_ (lua_State *L, GCObject *o, GCObject *v); |
| 138 | 137 | LUAI_FUNC void luaC_barrierback_ (lua_State *L, GCObject *o); |
| 139 | 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 | 140 | LUAI_FUNC void luaC_checkupvalcolor (global_State *g, UpVal *uv); |
| 142 | 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 $ | |
| 3 | −** Initialization of libraries for lua.c and other clients | |
| 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 | |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| 6 | 6 | |
| 7 | 7 | |
| 8 | −/* | |
| 8 | +/* | |
| 9 | 9 | ** If you embed Lua in your program and need to open the standard |
| 10 | 10 | ** libraries, call luaL_openlibs in your program. If you need a |
| 11 | 11 | ** different set of libraries, copy this file to your project and edit |
| 12 | 12 | ** it to suit your needs. |
| 13 | −*/ | |
| 13 | +*/ | |
| 14 | 14 | |
| 15 | 15 | |
| 16 | 16 | #define linit_c |
| @@ -57,7 +57,7 @@ LUALIB_API void luaL_openlibs (lua_State *L) { · 40 unmodified lines | ||
| 57 | 57 | lua_pop(L, 1); /* remove lib */ |
| 58 | 58 | } |
| 59 | 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 | 61 | for (lib = preloadedlibs; lib->func; lib++) { |
| 62 | 62 | lua_pushcfunction(L, lib->func); |
| 63 | 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 | 3 | ** Standard I/O (and system) library |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| @@ -26,28 +26,29 @@ · 20 unmodified lines | ||
| 26 | 26 | ** lua_popen spawns a new process connected to the current one through |
| 27 | 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)) | |
| 34 | −#define lua_pclose(L,file) ((void)L, pclose(file)) | |
| 33 | +#define lua_popen(L,c,m) ((void)L, fflush(NULL), popen(c,m)) | |
| 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)) | |
| 39 | −#define lua_pclose(L,file) ((void)L, _pclose(file)) | |
| 38 | +#define lua_popen(L,c,m) ((void)L, _popen(c,m)) | |
| 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), \ | |
| 44 | − luaL_error(L, LUA_QL("popen") " not supported"), (FILE*)0) | |
| 45 | −#define lua_pclose(L,file) ((void)((void)L, file), -1) | |
| 42 | +#else /* }{ */ | |
| 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 | 54 | #define IO_INPUT 1 |
| @@ -57,24 +58,6 @@ · 3 unmodified lines | ||
| 57 | 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 | 61 | static void fileerror (lua_State *L, int arg, const char *filename) { |
| 79 | 62 | lua_pushfstring(L, "%s: %s", filename, strerror(errno)); |
| 80 | 63 | luaL_argerror(L, arg, lua_tostring(L, -1)); |
| @@ -143,13 +126,8 @@ static int io_noclose (lua_State *L) { · 62 unmodified lines | ||
| 143 | 126 | static int io_pclose (lua_State *L) { |
| 144 | 127 | FILE **p = tofilep(L); |
| 145 | 128 | int stat = lua_pclose(L, *p); |
| 146 | − *p = NULL; | |
| 147 | − if (stat == -1) /* error? */ | |
| 148 | − return pushresult(L, 0, NULL); | |
| 149 | − else { | |
| 150 | − lua_pushinteger(L, stat); | |
| 151 | − return 1; /* return status */ | |
| 152 | − } | |
| 129 | + *p = NULL; /* mark stream as closed (for GC) */ | |
| 130 | + return luaL_execresult(L, stat); | |
| 153 | 131 | } |
| 154 | 132 | |
| 155 | 133 | |
| @@ -159,8 +137,8 @@ static int io_pclose (lua_State *L) { · 3 unmodified lines | ||
| 159 | 137 | static int io_fclose (lua_State *L) { |
| 160 | 138 | FILE **p = tofilep(L); |
| 161 | 139 | int ok = (fclose(*p) == 0); |
| 162 | − *p = NULL; | |
| 163 | − return pushresult(L, ok, NULL); | |
| 140 | + *p = NULL; /* mark stream as closed (for GC) */ | |
| 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 | 160 | static int io_gc (lua_State *L) { |
| 183 | 161 | FILE *f = *tofilep(L); |
| 184 | − /* ignore closed files */ | |
| 185 | − if (f != NULL) | |
| 162 | + if (f != NULL) /* ignore closed files */ | |
| 186 | 163 | aux_close(L); |
| 187 | 164 | return 0; |
| 188 | 165 | } |
| @@ -205,14 +182,14 @@ static int io_open (lua_State *L) { · 16 unmodified lines | ||
| 205 | 182 | int i = 0; |
| 206 | 183 | /* check whether 'mode' matches '[rwa]%+?b?' */ |
| 207 | 184 | if (!(mode[i] != '\0' && strchr("rwa", mode[i++]) != NULL && |
| 208 | − (mode[i] != '+' || ++i) && /* skip if char is '+' */ | |
| 209 | − (mode[i] != 'b' || ++i) && /* skip if char is 'b' */ | |
| 185 | + (mode[i] != '+' || ++i) && /* skip if char is '+' */ | |
| 186 | + (mode[i] != 'b' || ++i) && /* skip if char is 'b' */ | |
| 210 | 187 | (mode[i] == '\0'))) |
| 211 | 188 | luaL_error(L, "invalid mode " LUA_QL("%s") |
| 212 | 189 | " (should match " LUA_QL("[rwa]%%+?b?") ")", mode); |
| 213 | 190 | pf = newfile(L); |
| 214 | 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 | 202 | const char *mode = luaL_optstring(L, 2, "r"); |
| 226 | 203 | FILE **pf = newfile(L); |
| 227 | 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 | 209 | static int io_tmpfile (lua_State *L) { |
| 233 | 210 | FILE **pf = newfile(L); |
| 234 | 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 | 282 | if (lua_isnone(L, 1)) lua_pushnil(L); /* at least one argument */ |
| 306 | 283 | if (lua_isnil(L, 1)) { /* no file name? */ |
| 307 | 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 | 286 | tofile(L); /* check that it's a valid file handle */ |
| 310 | 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 | 292 | *pf = fopen(filename, "r"); |
| 316 | 293 | if (*pf == NULL) |
| 317 | 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 | 296 | toclose = 1; /* close it after iteration */ |
| 320 | 297 | } |
| 321 | 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 | 422 | if (ferror(f)) |
| 446 | − return pushresult(L, 0, NULL); | |
| 423 | + return luaL_fileresult(L, 0, NULL); | |
| 447 | 424 | if (!success) { |
| 448 | 425 | lua_pop(L, 1); /* remove last result */ |
| 449 | 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 | 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 | 496 | static int f_write (lua_State *L) { |
| 520 | − FILE * f = tofile(L); | |
| 497 | + FILE * f = tofile(L); | |
| 521 | 498 | lua_pushvalue(L, 1); /* push file at the stack top (to be returned) */ |
| 522 | 499 | return g_write(L, f, 2); |
| 523 | 500 | } |
| @@ -531,7 +508,7 @@ static int f_seek (lua_State *L) { · 7 unmodified lines | ||
| 531 | 508 | long offset = luaL_optlong(L, 3, 0); |
| 532 | 509 | op = fseek(f, offset, mode[op]); |
| 533 | 510 | if (op) |
| 534 | − return pushresult(L, 0, NULL); /* error */ | |
| 511 | + return luaL_fileresult(L, 0, NULL); /* error */ | |
| 535 | 512 | else { |
| 536 | 513 | lua_pushinteger(L, ftell(f)); |
| 537 | 514 | return 1; |
| @@ -546,18 +523,18 @@ static int f_setvbuf (lua_State *L) { · 8 unmodified lines | ||
| 546 | 523 | int op = luaL_checkoption(L, 2, NULL, modenames); |
| 547 | 524 | lua_Integer sz = luaL_optinteger(L, 3, LUAL_BUFFERSIZE); |
| 548 | 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 | 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 | 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 | 3 | ** Lexical Analyzer |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| @@ -35,7 +35,7 @@ · 29 unmodified lines | ||
| 35 | 35 | /* ORDER RESERVED */ |
| 36 | 36 | static const char *const luaX_tokens [] = { |
| 37 | 37 | "and", "break", "do", "else", "elseif", |
| 38 | − "end", "false", "for", "function", "if", | |
| 38 | + "end", "false", "for", "function", "goto", "if", | |
| 39 | 39 | "in", "local", "nil", "not", "or", "repeat", |
| 40 | 40 | "return", "then", "true", "until", "while", |
| 41 | 41 | "..", "...", "==", ">=", "<=", "~=", "<eof>", |
| @@ -67,7 +67,6 @@ void luaX_init (lua_State *L) { · 25 unmodified lines | ||
| 67 | 67 | for (i=0; i<NUM_RESERVED; i++) { |
| 68 | 68 | TString *ts = luaS_new(L, luaX_tokens[i]); |
| 69 | 69 | luaS_fix(ts); /* reserved words are never collected */ |
| 70 | − lua_assert(strlen(luaX_tokens[i])+1 <= TOKEN_LEN); | |
| 71 | 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 | 126 | TValue *o; /* entry for `str' */ |
| 128 | 127 | TString *ts = luaS_newlstr(L, str, l); /* create new string */ |
| 129 | 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 | 130 | if (ttisnil(o)) { |
| 132 | 131 | setbvalue(o, 1); /* t[string] = true */ |
| 133 | 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 | 156 | ls->decpoint = '.'; |
| 157 | 157 | ls->L = L; |
| 158 | + ls->current = firstchar; | |
| 158 | 159 | ls->lookahead.token = TK_EOS; /* no look-ahead token */ |
| 159 | 160 | ls->z = z; |
| 160 | 161 | ls->fs = NULL; |
| @@ -164,7 +165,6 @@ void luaX_setinput (lua_State *L, LexState *ls, ZIO *z, TString *source) { · 3 unmodified lines | ||
| 164 | 165 | ls->envn = luaS_new(L, LUA_ENV); /* create env name */ |
| 165 | 166 | luaS_fix(ls->envn); /* never collect this name */ |
| 166 | 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 | 189 | ** change all characters 'from' in buffer to 'to' |
| 190 | 190 | */ |
| 191 | 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 | 200 | #define getlocaledecpoint() (localeconv()->decimal_point[0]) |
| 201 | 201 | #endif |
| 202 | 202 | |
| 203 | + | |
| 204 | +#define buff2d(b,e) luaO_str2d(luaZ_buffer(b), luaZ_bufflen(b) - 1, e) | |
| 205 | + | |
| 203 | 206 | /* |
| 204 | 207 | ** in case of format error, try to change decimal point separator to |
| 205 | 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 | 211 | char old = ls->decpoint; |
| 209 | 212 | ls->decpoint = getlocaledecpoint(); |
| 210 | 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 | 215 | /* format error with correct decimal point: no more options */ |
| 213 | 216 | buffreplace(ls, ls->decpoint, '.'); /* undo change (for error message) */ |
| 214 | 217 | lexerror(ls, "malformed number", TK_NUMBER); |
| @@ -226,7 +229,7 @@ static void read_numeral (LexState *ls, SemInfo *seminfo) { · 11 unmodified lines | ||
| 226 | 229 | } while (lislalnum(ls->current) || ls->current == '.'); |
| 227 | 230 | save(ls, '\0'); |
| 228 | 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 | 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 | 289 | static int readhexaesc (LexState *ls) { |
| 294 | 290 | int c1, c2 = EOZ; |
| 295 | 291 | if (!lisxdigit(c1 = next(ls)) || !lisxdigit(c2 = next(ls))) { |
| @@ -299,7 +295,7 @@ static int readhexaesc (LexState *ls) { · 3 unmodified lines | ||
| 299 | 295 | if (c2 != EOZ) save(ls, c2); |
| 300 | 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 | 3 | ** Lexical Analyzer |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| @@ -13,8 +13,6 @@ · 7 unmodified lines | ||
| 13 | 13 | |
| 14 | 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 | 23 | /* terminal symbols denoted by reserved words */ |
| 26 | 24 | TK_AND = FIRST_RESERVED, TK_BREAK, |
| 27 | 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 | 27 | TK_RETURN, TK_THEN, TK_TRUE, TK_UNTIL, TK_WHILE, |
| 30 | 28 | /* other terminal symbols */ |
| 31 | 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 | 46 | } Token; |
| 49 | 47 | |
| 50 | 48 | |
| 49 | +/* state of the lexer plus state of the parser when shared by all | |
| 50 | + functions */ | |
| 51 | 51 | typedef struct LexState { |
| 52 | 52 | int current; /* current character (charint) */ |
| 53 | 53 | int linenumber; /* input line counter */ |
| 54 | 54 | int lastline; /* line of last token `consumed' */ |
| 55 | 55 | Token t; /* current token */ |
| 56 | 56 | Token lookahead; /* look ahead token */ |
| 57 | − struct FuncState *fs; /* `FuncState' is private to the parser */ | |
| 57 | + struct FuncState *fs; /* current function (parser) */ | |
| 58 | 58 | struct lua_State *L; |
| 59 | 59 | ZIO *z; /* input stream */ |
| 60 | 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 | 62 | TString *source; /* current source name */ |
| 63 | 63 | TString *envn; /* environment variable name */ |
| 64 | 64 | char decpoint; /* locale decimal point */ |
| @@ -67,7 +67,7 @@ typedef struct LexState { · 2 unmodified lines | ||
| 67 | 67 | |
| 68 | 68 | LUAI_FUNC void luaX_init (lua_State *L); |
| 69 | 69 | LUAI_FUNC void luaX_setinput (lua_State *L, LexState *ls, ZIO *z, |
| 70 | − TString *source); | |
| 70 | + TString *source, int firstchar); | |
| 71 | 71 | LUAI_FUNC TString *luaX_newstring (LexState *ls, const char *str, size_t l); |
| 72 | 72 | LUAI_FUNC void luaX_next (LexState *ls); |
| 73 | 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 | 3 | ** Limits, basic types, and some other `installation-dependent' definitions |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| @@ -59,9 +59,12 @@ typedef LUAI_UACNUMBER l_uacNumber; · 53 unmodified lines | ||
| 59 | 59 | /* internal assertions for in-house debugging */ |
| 60 | 60 | #if defined(lua_assert) |
| 61 | 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 | 64 | #else |
| 63 | 65 | #define lua_assert(c) /* empty */ |
| 64 | 66 | #define check_exp(c,e) (e) |
| 67 | +#define lua_longassert(c) /* empty */ | |
| 65 | 68 | #endif |
| 66 | 69 | |
| 67 | 70 | /* |
| @@ -87,6 +90,7 @@ typedef LUAI_UACNUMBER l_uacNumber; · 19 unmodified lines | ||
| 87 | 90 | #define cast_byte(i) cast(lu_byte, (i)) |
| 88 | 91 | #define cast_num(i) cast(lua_Number, (i)) |
| 89 | 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 | 177 | ** lua_number2integer is a macro to convert lua_Number to lua_Integer. |
| 174 | 178 | ** lua_number2unsigned is a macro to convert a lua_Number to a lua_Unsigned. |
| 175 | 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 | 185 | #if defined(MS_ASMTRICK) /* { */ |
| @@ -203,6 +210,10 @@ union luai_Cast { double l_d; LUA_INT32 l_p[2]; }; · 24 unmodified lines | ||
| 203 | 210 | volatile union luai_Cast u; u.l_d = (n) + 6755399441055744.0; \ |
| 204 | 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 | 217 | #define lua_number2int(i,n) lua_number2int32(i, n, int) |
| 207 | 218 | #define lua_number2integer(i,n) lua_number2int32(i, n, lua_Integer) |
| 208 | 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 | 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 | 258 | #include <float.h> |
| 254 | 259 | #include <math.h> |
| @@ -257,7 +262,7 @@ union luai_Cast { double l_d; LUA_INT32 l_p[2]; }; · 2 unmodified lines | ||
| 257 | 262 | n = frexp(n, &e) * (lua_Number)(INT_MAX - DBL_MAX_EXP); \ |
| 258 | 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 | 280 | #define condchangemem(L) condmovestack(L) |
| 276 | 281 | #else |
| 277 | 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 | 284 | #endif |
| 280 | 285 | |
| 281 | 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 | 3 | ** Interface to Memory Manager |
| 4 | 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 | 79 | size_t realosize = (block) ? osize : 0; |
| 80 | 80 | lua_assert((realosize == 0) == (block == NULL)); |
| 81 | 81 | #if defined(HARDMEMTESTS) |
| 82 | − if (nsize > realosize && !gcstopped(g)) | |
| 82 | + if (nsize > realosize && g->gcrunning) | |
| 83 | 83 | luaC_fullgc(L, 1); /* force a GC whenever possible */ |
| 84 | 84 | #endif |
| 85 | 85 | newblock = (*g->frealloc)(g->ud, block, osize, nsize); |
| 86 | 86 | if (newblock == NULL && nsize > 0) { |
| 87 | 87 | api_check(L, nsize > realosize, |
| 88 | 88 | "realloc cannot fail when shrinking a block"); |
| 89 | − if (!gcstopped(g)) { | |
| 89 | + if (g->gcrunning) { | |
| 90 | 90 | luaC_fullgc(L, 1); /* try to free some memory... */ |
| 91 | 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 | 94 | luaD_throw(L, LUA_ERRMEM); |
| 95 | 95 | } |
| 96 | 96 | lua_assert((nsize == 0) == (newblock == NULL)); |
| 97 | − g->totalbytes = (g->totalbytes - realosize) + nsize; | |
| 98 | − if (!gcstopped(g)) | |
| 99 | − g->GCdebt += nsize; /* give some credit to garbage collector */ | |
| 97 | + g->GCdebt = (g->GCdebt + nsize) - realosize; | |
| 100 | 98 | #if defined(TRACEMEM) |
| 101 | 99 | { /* auxiliary patch to monitor garbage collection. |
| 102 | 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 | 106 | if ((total % 200) == 0) { |
| 109 | 107 | if (f == NULL) f = fopen(TRACEMEM, "w"); |
| 110 | 108 | fprintf(f, "%lu %u %d %d\n", total, |
| 111 | − g->totalbytes, | |
| 112 | − gcstopped(g) ? 0 : g->GCdebt, | |
| 113 | − g->gcstate * 1000); | |
| 109 | + g->totalbytes, g->GCdebt, g->gcstate * 1000); | |
| 114 | 110 | } |
| 115 | 111 | } |
| 116 | 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 | 3 | ** Dynamic library loader for Lua |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | ** |
| @@ -164,7 +164,7 @@ static void pusherror (lua_State *L) { · 158 unmodified lines | ||
| 164 | 164 | int error = GetLastError(); |
| 165 | 165 | char buffer[128]; |
| 166 | 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 | 168 | lua_pushstring(L, buffer); |
| 169 | 169 | else |
| 170 | 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 | 323 | static const char *searchpath (lua_State *L, const char *name, |
| 324 | − const char *path) { | |
| 325 | − name = luaL_gsub(L, name, ".", LUA_DIRSEP); | |
| 324 | + const char *path, | |
| 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 | 328 | lua_pushliteral(L, ""); /* error accumulator */ |
| 327 | 329 | while ((path = pushnexttemplate(L, path)) != NULL) { |
| 328 | 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 | 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 | 347 | if (f != NULL) return 1; |
| 344 | 348 | else { /* error message is on top of the stack */ |
| 345 | 349 | lua_pushnil(L); |
| @@ -356,13 +360,19 @@ static const char *findfile (lua_State *L, const char *name, · 10 unmodified lines | ||
| 356 | 360 | path = lua_tostring(L, -1); |
| 357 | 361 | if (path == NULL) |
| 358 | 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) { | |
| 364 | − luaL_error(L, "error loading module " LUA_QS " from file " LUA_QS ":\n\t%s", | |
| 365 | − lua_tostring(L, 1), filename, lua_tostring(L, -1)); | |
| 367 | +static int checkload (lua_State *L, int stat, const char *filename) { | |
| 368 | + if (stat) { /* module loaded successfully? */ | |
| 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 | 380 | const char *filename; |
| 371 | 381 | const char *name = luaL_checkstring(L, 1); |
| 372 | 382 | filename = findfile(L, name, "path"); |
| 373 | − if (filename == NULL) return 1; /* library not found in this path */ | |
| 374 | − if (luaL_loadfile(L, filename) != LUA_OK) | |
| 375 | − loaderror(L, filename); | |
| 376 | − return 1; /* library loaded successfully */ | |
| 383 | + if (filename == NULL) return 1; /* module not found in this path */ | |
| 384 | + return checkload(L, (luaL_loadfile(L, filename) == LUA_OK), filename); | |
| 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 | 406 | static int loader_C (lua_State *L) { |
| 399 | 407 | const char *name = luaL_checkstring(L, 1); |
| 400 | 408 | const char *filename = findfile(L, name, "cpath"); |
| 401 | − if (filename == NULL) return 1; /* library not found in this path */ | |
| 402 | − if (loadfunc(L, filename, name) != 0) | |
| 403 | − loaderror(L, filename); | |
| 404 | − return 1; /* library loaded successfully */ | |
| 409 | + if (filename == NULL) return 1; /* module not found in this path */ | |
| 410 | + return checkload(L, (loadfunc(L, filename, name) == 0), filename); | |
| 405 | 411 | } |
| 406 | 412 | |
| 407 | 413 | |
| @@ -415,12 +421,16 @@ static int loader_Croot (lua_State *L) { · 7 unmodified lines | ||
| 415 | 421 | filename = findfile(L, lua_tostring(L, -1), "cpath"); |
| 416 | 422 | if (filename == NULL) return 1; /* root not found */ |
| 417 | 423 | if ((stat = loadfunc(L, filename, name)) != 0) { |
| 418 | − if (stat != ERRFUNC) loaderror(L, filename); /* real error */ | |
| 419 | − lua_pushfstring(L, "\n\tno module " LUA_QS " in file " LUA_QS, | |
| 420 | − name, filename); | |
| 421 | − return 1; /* function not found */ | |
| 424 | + if (stat != ERRFUNC) | |
| 425 | + return checkload(L, 0, filename); /* real error */ | |
| 426 | + else { /* open 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 | 463 | luaL_error(L, "module " LUA_QS " not found:%s", |
| 454 | 464 | name, lua_tostring(L, -2)); |
| 455 | 465 | lua_pushstring(L, name); |
| 456 | − lua_call(L, 1, 1); /* call it */ | |
| 457 | − if (lua_isfunction(L, -1)) /* did it find module? */ | |
| 466 | + lua_call(L, 1, 2); /* call it */ | |
| 467 | + if (lua_isfunction(L, -2)) /* did it find module? */ | |
| 458 | 468 | break; /* module loaded successfully */ |
| 459 | − else if (lua_isstring(L, -1)) /* loader returned error message? */ | |
| 460 | − lua_concat(L, 2); /* accumulate it */ | |
| 469 | + else if (lua_isstring(L, -2)) { /* loader returned error message? */ | |
| 470 | + lua_pop(L, 1); /* remove extra return */ | |
| 471 | + lua_concat(L, 2); /* accumulate error message */ | |
| 472 | + } | |
| 461 | 473 | else |
| 462 | − lua_pop(L, 1); | |
| 474 | + lua_pop(L, 2); /* remove both returns */ | |
| 463 | 475 | } |
| 464 | 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 | 479 | if (!lua_isnil(L, -1)) /* non-nil return? */ |
| 467 | 480 | lua_setfield(L, 2, name); /* _LOADED[name] = returned value */ |
| 468 | 481 | lua_getfield(L, 2, name); |
| @@ -639,10 +652,10 @@ LUAMOD_API int luaopen_package (lua_State *L) { · 170 unmodified lines | ||
| 639 | 652 | LUA_EXEC_DIR "\n" LUA_IGMARK "\n"); |
| 640 | 653 | lua_setfield(L, -2, "config"); |
| 641 | 654 | /* set field `loaded' */ |
| 642 | − luaL_findtable(L, LUA_REGISTRYINDEX, "_LOADED"); | |
| 655 | + luaL_getsubtable(L, LUA_REGISTRYINDEX, "_LOADED"); | |
| 643 | 656 | lua_setfield(L, -2, "loaded"); |
| 644 | 657 | /* set field `preload' */ |
| 645 | − luaL_findtable(L, LUA_REGISTRYINDEX, "_PRELOAD"); | |
| 658 | + luaL_getsubtable(L, LUA_REGISTRYINDEX, "_PRELOAD"); | |
| 646 | 659 | lua_setfield(L, -2, "preload"); |
| 647 | 660 | lua_pushglobaltable(L); |
| 648 | 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 | 3 | ** Some generic functions over Lua objects |
| 4 | 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 | 73 | lua_Number luaO_arith (int op, lua_Number v1, lua_Number v2) { |
| 96 | 74 | switch (op) { |
| 97 | 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) { | |
| 110 | − if (endptr == s) return 0; /* no characters converted */ | |
| 111 | − while (lisspace(cast(unsigned char, *endptr))) endptr++; | |
| 112 | − return (*endptr == '\0'); /* OK if no trailing characters */ | |
| 87 | +int luaO_hexavalue (int c) { | |
| 88 | + if (lisdigit(c)) return c - '0'; | |
| 89 | + else if (lisupper(c)) return c - 'A' + 10; | |
| 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 | 160 | char *endptr; |
| 118 | − *result = lua_str2number(s, &endptr); | |
| 119 | − if (checkend(s, endptr)) return 1; /* conversion OK? */ | |
| 120 | − *result = cast_num(strtoul(s, &endptr, 0)); /* try hexadecimal */ | |
| 121 | − return checkend(s, endptr); | |
| 161 | + if (strpbrk(s, "xX")) /* hexa? */ | |
| 162 | + *result = lua_strx2number(s, &endptr); | |
| 163 | + else | |
| 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 | 248 | #define RETS "..." |
| 202 | 249 | #define PRE "[string \"" |
| 203 | 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 | 254 | void luaO_chunkid (char *out, const char *source, size_t bufflen) { |
| 208 | 255 | size_t l = strlen(source); |
| 209 | 256 | if (*source == '=') { /* 'literal' source */ |
| 210 | 257 | if (l <= bufflen) /* small enough? */ |
| 211 | − memcpy(out, source + 1, l); | |
| 258 | + memcpy(out, source + 1, l * sizeof(char)); | |
| 212 | 259 | else { /* truncate it */ |
| 213 | 260 | addstr(out, source + 1, bufflen - 1); |
| 214 | 261 | *out = '\0'; |
| @@ -216,11 +263,11 @@ void luaO_chunkid (char *out, const char *source, size_t bufflen) { · 1 unmodified line | ||
| 216 | 263 | } |
| 217 | 264 | else if (*source == '@') { /* file name */ |
| 218 | 265 | if (l <= bufflen) /* small enough? */ |
| 219 | − memcpy(out, source + 1, l); | |
| 266 | + memcpy(out, source + 1, l * sizeof(char)); | |
| 220 | 267 | else { /* add '...' before rest of name */ |
| 221 | 268 | addstr(out, RETS, LL(RETS)); |
| 222 | 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 | 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 | 283 | addstr(out, source, l); |
| 237 | 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 | 3 | ** Type definitions for Lua objects |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| @@ -23,12 +23,38 @@ · 17 unmodified lines | ||
| 23 | 23 | #define LUA_TUPVAL (LUA_NUMTAGS+1) |
| 24 | 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 | |
| 29 | −** non collectable by 'iscollectable') | |
| 40 | +** LUA_TFUNCTION variants: | |
| 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 | 60 | ** Union of all collectable objects |
| @@ -55,13 +81,10 @@ typedef struct GCheader { · 20 unmodified lines | ||
| 55 | 81 | /* |
| 56 | 82 | ** Union of all Lua values |
| 57 | 83 | */ |
| 58 | −typedef union { | |
| 59 | − GCObject *gc; /* collectable objects */ | |
| 60 | − void *p; /* light userdata */ | |
| 61 | − lua_Number n; /* numbers */ | |
| 62 | − int b; /* booleans */ | |
| 63 | − lua_CFunction f; /* light C functions */ | |
| 64 | −} Value; | |
| 84 | +typedef union Value Value; | |
| 85 | + | |
| 86 | + | |
| 87 | +#define numfield lua_Number n; /* numbers */ | |
| 65 | 88 | |
| 66 | 89 | |
| 67 | 90 | |
| @@ -72,125 +95,143 @@ typedef union { · 4 unmodified lines | ||
| 72 | 95 | |
| 73 | 96 | #define TValuefields Value value_; int tt_ |
| 74 | 97 | |
| 75 | −typedef struct lua_TValue { | |
| 76 | − TValuefields; | |
| 77 | −} TValue; | |
| 98 | +typedef struct lua_TValue TValue; | |
| 78 | 99 | |
| 79 | 100 | |
| 80 | 101 | /* macro defining a nil value */ |
| 81 | −#define NILCONSTANT {NULL}, LUA_TNIL | |
| 102 | +#define NILCONSTANT {NULL}, LUA_TNIL | |
| 82 | 103 | |
| 83 | 104 | |
| 84 | −/* | |
| 85 | −** type tag of a TValue | |
| 86 | −*/ | |
| 87 | −#define ttype(o) ((o)->tt_) | |
| 105 | +#define val_(o) ((o)->value_) | |
| 106 | +#define num_(o) (val_(o).n) | |
| 88 | 107 | |
| 89 | 108 | |
| 90 | −/* | |
| 91 | −** type tag of a TValue with no variants | |
| 92 | −*/ | |
| 93 | −#define ttypenv(o) (ttype(o) & 0x0F) | |
| 109 | +/* raw type tag of a TValue */ | |
| 110 | +#define rttype(o) ((o)->tt_) | |
| 111 | + | |
| 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 | 120 | /* Macros to test type */ |
| 97 | −#define ttisnil(o) (ttype(o) == LUA_TNIL) | |
| 98 | −#define ttisnumber(o) (ttype(o) == LUA_TNUMBER) | |
| 99 | −#define ttisstring(o) (ttype(o) == LUA_TSTRING) | |
| 100 | −#define ttistable(o) (ttype(o) == LUA_TTABLE) | |
| 101 | −#define ttisfunction(o) (ttypenv(o) == LUA_TFUNCTION) | |
| 102 | −#define ttisclosure(o) (ttype(o) == LUA_TFUNCTION) | |
| 103 | −#define ttislcf(o) (ttype(o) == LUA_TLCF) | |
| 104 | −#define ttisboolean(o) (ttype(o) == LUA_TBOOLEAN) | |
| 105 | −#define ttisuserdata(o) (ttype(o) == LUA_TUSERDATA) | |
| 106 | −#define ttisthread(o) (ttype(o) == LUA_TTHREAD) | |
| 107 | −#define ttislightuserdata(o) (ttype(o) == LUA_TLIGHTUSERDATA) | |
| 108 | −#define ttisdeadkey(o) (ttype(o) == LUA_TDEADKEY) | |
| 121 | +#define checktag(o,t) (rttype(o) == (t)) | |
| 122 | +#define ttisnumber(o) checktag((o), LUA_TNUMBER) | |
| 123 | +#define ttisnil(o) checktag((o), LUA_TNIL) | |
| 124 | +#define ttisboolean(o) checktag((o), LUA_TBOOLEAN) | |
| 125 | +#define ttislightuserdata(o) checktag((o), LUA_TLIGHTUSERDATA) | |
| 126 | +#define ttisstring(o) checktag((o), ctb(LUA_TSTRING)) | |
| 127 | +#define ttistable(o) checktag((o), ctb(LUA_TTABLE)) | |
| 128 | +#define ttisfunction(o) (ttypenv(o) == LUA_TFUNCTION) | |
| 129 | +#define ttisclosure(o) ((rttype(o) & 0x1F) == LUA_TFUNCTION) | |
| 130 | +#define ttisCclosure(o) checktag((o), ctb(LUA_TCCL)) | |
| 131 | +#define ttisLclosure(o) checktag((o), ctb(LUA_TLCL)) | |
| 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 | 139 | /* Macros to access values */ |
| 111 | −#define gcvalue(o) check_exp(iscollectable(o), (o)->value_.gc) | |
| 112 | −#define pvalue(o) check_exp(ttislightuserdata(o), (o)->value_.p) | |
| 113 | −#define nvalue(o) check_exp(ttisnumber(o), (o)->value_.n) | |
| 114 | −#define rawtsvalue(o) check_exp(ttisstring(o), &(o)->value_.gc->ts) | |
| 140 | +#define nvalue(o) check_exp(ttisnumber(o), num_(o)) | |
| 141 | +#define gcvalue(o) check_exp(iscollectable(o), val_(o).gc) | |
| 142 | +#define pvalue(o) check_exp(ttislightuserdata(o), val_(o).p) | |
| 143 | +#define rawtsvalue(o) check_exp(ttisstring(o), &val_(o).gc->ts) | |
| 115 | 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 | 146 | #define uvalue(o) (&rawuvalue(o)->uv) |
| 118 | −#define clvalue(o) check_exp(ttisclosure(o), &(o)->value_.gc->cl) | |
| 119 | −#define fvalue(o) check_exp(ttislcf(o), (o)->value_.f) | |
| 120 | −#define hvalue(o) check_exp(ttistable(o), &(o)->value_.gc->h) | |
| 121 | −#define bvalue(o) check_exp(ttisboolean(o), (o)->value_.b) | |
| 122 | −#define thvalue(o) check_exp(ttisthread(o), &(o)->value_.gc->th) | |
| 147 | +#define clvalue(o) check_exp(ttisclosure(o), &val_(o).gc->cl) | |
| 148 | +#define clLvalue(o) check_exp(ttisLclosure(o), &val_(o).gc->cl.l) | |
| 149 | +#define clCvalue(o) check_exp(ttisCclosure(o), &val_(o).gc->cl.c) | |
| 150 | +#define fvalue(o) check_exp(ttislcf(o), val_(o).f) | |
| 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 | 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 | 161 | /* Macros for internal tests */ |
| 131 | −#define righttt(obj) (ttype(obj) == gcvalue(obj)->gch.tt) | |
| 132 | − | |
| 133 | −#define checkconsistency(obj) lua_assert(!iscollectable(obj) || righttt(obj)) | |
| 162 | +#define righttt(obj) (ttypenv(obj) == gcvalue(obj)->gch.tt) | |
| 134 | 163 | |
| 135 | 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 | 169 | /* Macros to set values */ |
| 140 | −#define setnilvalue(obj) ((obj)->tt_=LUA_TNIL) | |
| 170 | +#define settt_(o,t) ((o)->tt_=(t)) | |
| 141 | 171 | |
| 142 | 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) \ | |
| 146 | − { TValue *i_o=(obj); i_o->value_.f=(x); i_o->tt_=LUA_TLCF; } | |
| 175 | +#define changenvalue(o,x) check_exp(ttisnumber(o), num_(o)=(x)) | |
| 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 | 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 | 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 | 192 | #define setsvalue(L,obj,x) \ |
| 157 | − { TValue *i_o=(obj); \ | |
| 158 | − i_o->value_.gc=cast(GCObject *, (x)); i_o->tt_=LUA_TSTRING; \ | |
| 159 | − checkliveness(G(L),i_o); } | |
| 193 | + { TValue *io=(obj); \ | |
| 194 | + val_(io).gc=cast(GCObject *, (x)); settt_(io, ctb(LUA_TSTRING)); \ | |
| 195 | + checkliveness(G(L),io); } | |
| 160 | 196 | |
| 161 | 197 | #define setuvalue(L,obj,x) \ |
| 162 | − { TValue *i_o=(obj); \ | |
| 163 | − i_o->value_.gc=cast(GCObject *, (x)); i_o->tt_=LUA_TUSERDATA; \ | |
| 164 | − checkliveness(G(L),i_o); } | |
| 198 | + { TValue *io=(obj); \ | |
| 199 | + val_(io).gc=cast(GCObject *, (x)); settt_(io, ctb(LUA_TUSERDATA)); \ | |
| 200 | + checkliveness(G(L),io); } | |
| 165 | 201 | |
| 166 | 202 | #define setthvalue(L,obj,x) \ |
| 167 | − { TValue *i_o=(obj); \ | |
| 168 | − i_o->value_.gc=cast(GCObject *, (x)); i_o->tt_=LUA_TTHREAD; \ | |
| 169 | − checkliveness(G(L),i_o); } | |
| 203 | + { TValue *io=(obj); \ | |
| 204 | + val_(io).gc=cast(GCObject *, (x)); settt_(io, ctb(LUA_TTHREAD)); \ | |
| 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) \ | |
| 172 | − { TValue *i_o=(obj); \ | |
| 173 | − i_o->value_.gc=cast(GCObject *, (x)); i_o->tt_=LUA_TFUNCTION; \ | |
| 174 | − checkliveness(G(L),i_o); } | |
| 212 | +#define setclCvalue(L,obj,x) \ | |
| 213 | + { TValue *io=(obj); \ | |
| 214 | + val_(io).gc=cast(GCObject *, (x)); settt_(io, ctb(LUA_TCCL)); \ | |
| 215 | + checkliveness(G(L),io); } | |
| 175 | 216 | |
| 176 | 217 | #define sethvalue(L,obj,x) \ |
| 177 | − { TValue *i_o=(obj); \ | |
| 178 | − i_o->value_.gc=cast(GCObject *, (x)); i_o->tt_=LUA_TTABLE; \ | |
| 179 | − checkliveness(G(L),i_o); } | |
| 218 | + { TValue *io=(obj); \ | |
| 219 | + val_(io).gc=cast(GCObject *, (x)); settt_(io, ctb(LUA_TTABLE)); \ | |
| 220 | + checkliveness(G(L),io); } | |
| 180 | 221 | |
| 181 | 222 | #define setptvalue(L,obj,x) \ |
| 182 | − { TValue *i_o=(obj); \ | |
| 183 | − i_o->value_.gc=cast(GCObject *, (x)); i_o->tt_=LUA_TPROTO; \ | |
| 184 | − checkliveness(G(L),i_o); } | |
| 223 | + { TValue *io=(obj); \ | |
| 224 | + val_(io).gc=cast(GCObject *, (x)); settt_(io, ctb(LUA_TPROTO)); \ | |
| 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 | 231 | #define setobj(L,obj1,obj2) \ |
| 191 | − { const TValue *o2=(obj2); TValue *o1=(obj1); \ | |
| 192 | − o1->value_ = o2->value_; o1->tt_=o2->tt_; \ | |
| 193 | − checkliveness(G(L),o1); } | |
| 232 | + { const TValue *io2=(obj2); TValue *io1=(obj1); \ | |
| 233 | + io1->value_ = io2->value_; io1->tt_ = io2->tt_; \ | |
| 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 | 368 | typedef TValue *StkId; /* index to stack elements */ |
| 218 | 369 | |
| 219 | 370 | |
| 371 | + | |
| 372 | + | |
| 220 | 373 | /* |
| 221 | 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 | 379 | CommonHeader; |
| 227 | 380 | lu_byte reserved; |
| 228 | 381 | unsigned int hash; |
| 229 | − size_t len; | |
| 382 | + size_t len; /* number of characters in string */ | |
| 230 | 383 | } tsv; |
| 231 | 384 | } TString; |
| 232 | 385 | |
| @@ -247,7 +400,7 @@ typedef union Udata { · 14 unmodified lines | ||
| 247 | 400 | CommonHeader; |
| 248 | 401 | struct Table *metatable; |
| 249 | 402 | struct Table *env; |
| 250 | − size_t len; | |
| 403 | + size_t len; /* number of bytes */ | |
| 251 | 404 | } uv; |
| 252 | 405 | } Udata; |
| 253 | 406 | |
| @@ -346,9 +499,9 @@ typedef union Closure { · 92 unmodified lines | ||
| 346 | 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 | 557 | LUAI_DDEC const TValue luaO_nilobject_; |
| 405 | 558 | |
| 559 | + | |
| 406 | 560 | LUAI_FUNC int luaO_int2fb (unsigned int x); |
| 407 | 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 | 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); | |
| 411 | −LUAI_FUNC int luaO_str2d (const char *s, lua_Number *result); | |
| 564 | +LUAI_FUNC int luaO_str2d (const char *s, size_t len, lua_Number *result); | |
| 565 | +LUAI_FUNC int luaO_hexavalue (int c); | |
| 412 | 566 | LUAI_FUNC const char *luaO_pushvfstring (lua_State *L, const char *fmt, |
| 413 | 567 | va_list argp); |
| 414 | 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 | 3 | ** See Copyright Notice in lua.h |
| 4 | 4 | */ |
| 5 | 5 | |
| @@ -16,6 +16,7 @@ · 10 unmodified lines | ||
| 16 | 16 | LUAI_DDEF const char *const luaP_opnames[NUM_OPCODES+1] = { |
| 17 | 17 | "MOVE", |
| 18 | 18 | "LOADK", |
| 19 | + "LOADKX", | |
| 19 | 20 | "LOADBOOL", |
| 20 | 21 | "LOADNIL", |
| 21 | 22 | "GETUPVAL", |
| @@ -50,7 +51,6 @@ LUAI_DDEF const char *const luaP_opnames[NUM_OPCODES+1] = { · 28 unmodified lines | ||
| 50 | 51 | "TFORCALL", |
| 51 | 52 | "TFORLOOP", |
| 52 | 53 | "SETLIST", |
| 53 | − "CLOSE", | |
| 54 | 54 | "CLOSURE", |
| 55 | 55 | "VARARG", |
| 56 | 56 | "EXTRAARG", |
| @@ -64,8 +64,9 @@ LUAI_DDEF const lu_byte luaP_opmodes[NUM_OPCODES] = { · 7 unmodified lines | ||
| 64 | 64 | /* T A B C mode opcode */ |
| 65 | 65 | opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_MOVE */ |
| 66 | 66 | ,opmode(0, 1, OpArgK, OpArgN, iABx) /* OP_LOADK */ |
| 67 | + ,opmode(0, 1, OpArgN, OpArgN, iABx) /* OP_LOADKX */ | |
| 67 | 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 | 70 | ,opmode(0, 1, OpArgU, OpArgN, iABC) /* OP_GETUPVAL */ |
| 70 | 71 | ,opmode(0, 1, OpArgU, OpArgK, iABC) /* OP_GETTABUP */ |
| 71 | 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 | 89 | ,opmode(1, 0, OpArgK, OpArgK, iABC) /* OP_EQ */ |
| 89 | 90 | ,opmode(1, 0, OpArgK, OpArgK, iABC) /* OP_LT */ |
| 90 | 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 | 93 | ,opmode(1, 1, OpArgR, OpArgU, iABC) /* OP_TESTSET */ |
| 93 | 94 | ,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_CALL */ |
| 94 | 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 | 99 | ,opmode(0, 0, OpArgN, OpArgU, iABC) /* OP_TFORCALL */ |
| 99 | 100 | ,opmode(0, 1, OpArgR, OpArgN, iAsBx) /* OP_TFORLOOP */ |
| 100 | 101 | ,opmode(0, 0, OpArgU, OpArgU, iABC) /* OP_SETLIST */ |
| 101 | − ,opmode(0, 0, OpArgN, OpArgN, iABC) /* OP_CLOSE */ | |
| 102 | 102 | ,opmode(0, 1, OpArgU, OpArgN, iABx) /* OP_CLOSURE */ |
| 103 | 103 | ,opmode(0, 1, OpArgU, OpArgN, iABC) /* OP_VARARG */ |
| 104 | 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 | 3 | ** Opcodes for Lua virtual machine |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| @@ -167,9 +167,10 @@ typedef enum { · 161 unmodified lines | ||
| 167 | 167 | name args description |
| 168 | 168 | ------------------------------------------------------------------------*/ |
| 169 | 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 | 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 | 174 | OP_GETUPVAL,/* A B R(A) := UpValue[B] */ |
| 174 | 175 | |
| 175 | 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 | 197 | OP_CONCAT,/* A B C R(A) := R(B).. ... ..R(C) */ |
| 197 | 198 | |
| 198 | −OP_JMP,/* sBx pc+=sBx */ | |
| 199 | − | |
| 199 | +OP_JMP,/* A sBx pc+=sBx; if (A) close all upvalues >= R(A) + 1 */ | |
| 200 | 200 | OP_EQ,/* A B C if ((RK(B) == RK(C)) ~= A) then pc++ */ |
| 201 | 201 | OP_LT,/* A B C if ((RK(B) < RK(C)) ~= A) then pc++ */ |
| 202 | 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 | 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 | 220 | OP_CLOSURE,/* A Bx R(A) := closure(KPROTO[Bx]) */ |
| 222 | 221 | |
| 223 | 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 | 243 | (*) In OP_SETLIST, if (B == 0) then B = `top'; if (C == 0) then next |
| 245 | 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 | 248 | (*) For comparisons, A specifies what condition the test should accept |
| 250 | 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 | 3 | ** Standard Operating System library |
| 4 | 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) { | |
| 63 | − int en = errno; /* calls to Lua API may change this value */ | |
| 64 | − if (i) { | |
| 65 | − lua_pushboolean(L, 1); | |
| 66 | − return 1; | |
| 67 | − } | |
| 62 | +static int os_execute (lua_State *L) { | |
| 63 | + const char *cmd = luaL_optstring(L, 1, NULL); | |
| 64 | + int stat = system(cmd); | |
| 65 | + if (cmd != NULL) | |
| 66 | + return luaL_execresult(L, stat); | |
| 68 | 67 | else { |
| 69 | − lua_pushnil(L); | |
| 70 | − lua_pushfstring(L, "%s: %s", filename, strerror(en)); | |
| 71 | − lua_pushinteger(L, en); | |
| 72 | − return 3; | |
| 68 | + lua_pushboolean(L, stat); /* true if there is a shell */ | |
| 69 | + return 1; | |
| 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 | 74 | static int os_remove (lua_State *L) { |
| 84 | 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 | 80 | static int os_rename (lua_State *L) { |
| 90 | 81 | const char *fromname = luaL_checkstring(L, 1); |
| 91 | 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 | 173 | return conv; /* to avoid warnings */ |
| 183 | 174 | } |
| 184 | 175 | |
| 185 | − | |
| 176 | + | |
| 186 | 177 | static int os_date (lua_State *L) { |
| 187 | 178 | const char *s = luaL_optstring(L, 1, "%c"); |
| 188 | 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 | 3 | ** Lua Parser |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| @@ -41,10 +41,11 @@ · 35 unmodified lines | ||
| 41 | 41 | */ |
| 42 | 42 | typedef struct BlockCnt { |
| 43 | 43 | struct BlockCnt *previous; /* chain */ |
| 44 | − int breaklist; /* list of jumps out of this loop */ | |
| 45 | − lu_byte nactvar; /* # active locals outside the breakable structure */ | |
| 44 | + int firstlabel; /* index of first label in this block */ | |
| 45 | + int firstgoto; /* index of first pending goto in this block */ | |
| 46 | + lu_byte nactvar; /* # active locals outside the block */ | |
| 46 | 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 | 49 | } BlockCnt; |
| 49 | 50 | |
| 50 | 51 | |
| @@ -52,7 +53,7 @@ typedef struct BlockCnt { · 1 unmodified line | ||
| 52 | 53 | /* |
| 53 | 54 | ** prototypes for recursive non-terminal functions |
| 54 | 55 | */ |
| 55 | −static void chunk (LexState *ls); | |
| 56 | +static void statement (LexState *ls); | |
| 56 | 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 | 77 | static void error_expected (LexState *ls, int token) { |
| 70 | 78 | luaX_syntaxerror(ls, |
| 71 | 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 | 111 | error_expected(ls, c); |
| 104 | 112 | } |
| 105 | 113 | |
| 114 | + | |
| 106 | 115 | static void checknext (LexState *ls, int c) { |
| 107 | 116 | check(ls, c); |
| 108 | 117 | luaX_next(ls); |
| @@ -167,13 +176,13 @@ static int registerlocalvar (LexState *ls, TString *varname) { · 58 unmodified lines | ||
| 167 | 176 | |
| 168 | 177 | static void new_localvar (LexState *ls, TString *name) { |
| 169 | 178 | FuncState *fs = ls->fs; |
| 170 | − Varlist *vl = ls->varl; | |
| 179 | + Dyndata *dyd = ls->dyd; | |
| 171 | 180 | int reg = registerlocalvar(ls, name); |
| 172 | − checklimit(fs, vl->nactvar + 1 - fs->firstlocal, | |
| 181 | + checklimit(fs, dyd->actvar.n + 1 - fs->firstlocal, | |
| 173 | 182 | MAXVARS, "local variables"); |
| 174 | − luaM_growvector(ls->L, vl->actvar, vl->nactvar + 1, | |
| 175 | − vl->actvarsize, vardesc, MAX_INT, "local variables"); | |
| 176 | − vl->actvar[vl->nactvar++].idx = cast(unsigned short, reg); | |
| 183 | + luaM_growvector(ls->L, dyd->actvar.arr, dyd->actvar.n + 1, | |
| 184 | + dyd->actvar.size, Vardesc, MAX_INT, "local variables"); | |
| 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 | 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 | 199 | lua_assert(idx < fs->nlocvars); |
| 191 | 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 | 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 | 215 | while (fs->nactvar > tolevel) |
| 207 | 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 | 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 | 259 | static void markupval (FuncState *fs, int level) { |
| 251 | 260 | BlockCnt *bl = fs->bl; |
| 252 | − while (bl && bl->nactvar > level) bl = bl->previous; | |
| 253 | − if (bl) bl->upval = 1; | |
| 261 | + while (bl->nactvar > level) bl = bl->previous; | |
| 262 | + bl->upval = 1; | |
| 254 | 263 | } |
| 255 | 264 | |
| 256 | 265 | |
| @@ -327,10 +336,107 @@ static void enterlevel (LexState *ls) { · 70 unmodified lines | ||
| 327 | 336 | #define leavelevel(ls) (G((ls)->L)->nCcalls--) |
| 328 | 337 | |
| 329 | 338 | |
| 330 | −static void enterblock (FuncState *fs, BlockCnt *bl, lu_byte isbreakable) { | |
| 331 | − bl->breaklist = NO_JUMP; | |
| 332 | − bl->isbreakable = isbreakable; | |
| 339 | +static void closegoto (LexState *ls, int g, Labeldesc *label) { | |
| 340 | + int i; | |
| 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 | 437 | bl->nactvar = fs->nactvar; |
| 438 | + bl->firstlabel = fs->ls->dyd->label.n; | |
| 439 | + bl->firstgoto = fs->ls->dyd->gt.n; | |
| 334 | 440 | bl->upval = 0; |
| 335 | 441 | bl->previous = fs->bl; |
| 336 | 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 | 469 | static void leaveblock (FuncState *fs) { |
| 342 | 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 | 480 | fs->bl = bl->previous; |
| 344 | 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 | 482 | lua_assert(bl->nactvar == fs->nactvar); |
| 350 | 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 | 505 | f->p[fs->np++] = clp; |
| 369 | 506 | luaC_objbarrier(ls->L, f, clp); |
| 370 | 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 | 513 | lua_State *L = ls->L; |
| 376 | 514 | Proto *f; |
| 377 | 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 | 525 | fs->nups = 0; |
| 388 | 526 | fs->nlocvars = 0; |
| 389 | 527 | fs->nactvar = 0; |
| 390 | − fs->firstlocal = ls->varl->nactvar; | |
| 528 | + fs->firstlocal = ls->dyd->actvar.n; | |
| 391 | 529 | fs->bl = NULL; |
| 392 | 530 | f = luaF_newproto(L); |
| 393 | 531 | fs->f = f; |
| @@ -400,6 +538,7 @@ static void open_func (LexState *ls, FuncState *fs) { · 6 unmodified lines | ||
| 400 | 538 | /* anchor table of constants (to avoid being collected) */ |
| 401 | 539 | sethvalue2s(L, L->top, fs->h); |
| 402 | 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 | 547 | FuncState *fs = ls->fs; |
| 409 | 548 | Proto *f = fs->f; |
| 410 | 549 | luaK_ret(fs, 0, 0); /* final return */ |
| 411 | − removevars(fs, 0); | |
| 550 | + leaveblock(fs); | |
| 412 | 551 | luaM_reallocvector(L, f->code, f->sizecode, fs->pc, Instruction); |
| 413 | 552 | f->sizecode = fs->pc; |
| 414 | 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 | 574 | ** opens the main function, which is a regular vararg function with an |
| 436 | 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 | 578 | expdesc v; |
| 440 | − open_func(ls, fs); | |
| 579 | + open_func(ls, fs, bl); | |
| 441 | 580 | fs->f->is_vararg = 1; /* main function is always vararg */ |
| 442 | 581 | init_exp(&v, VLOCAL, 0); |
| 443 | 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 | 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 | 620 | static void fieldsel (LexState *ls, expdesc *v) { |
| 475 | 621 | /* fieldsel -> ['.' | ':'] NAME */ |
| 476 | 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 | 734 | static void constructor (LexState *ls, expdesc *t) { |
| 589 | − /* constructor -> '{' [ field { sep field } [sep] ] '}' | |
| 735 | + /* constructor -> '{' [ field { sep field } [sep] ] '}' | |
| 590 | 736 | sep -> ',' | ';' */ |
| 591 | 737 | FuncState *fs = ls->fs; |
| 592 | 738 | int line = ls->linenumber; |
| @@ -596,7 +742,7 @@ static void constructor (LexState *ls, expdesc *t) { · 3 unmodified lines | ||
| 596 | 742 | cc.t = t; |
| 597 | 743 | init_exp(t, VRELOCABLE, pc); |
| 598 | 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 | 746 | checknext(ls, '{'); |
| 601 | 747 | do { |
| 602 | 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) { | |
| 647 | − /* body -> `(' parlist `)' chunk END */ | |
| 792 | +static void body (LexState *ls, expdesc *e, int ismethod, int line) { | |
| 793 | + /* body -> `(' parlist `)' block END */ | |
| 648 | 794 | FuncState new_fs; |
| 649 | − open_func(ls, &new_fs); | |
| 795 | + BlockCnt bl; | |
| 796 | + open_func(ls, &new_fs, &bl); | |
| 650 | 797 | new_fs.f->linedefined = line; |
| 651 | 798 | checknext(ls, '('); |
| 652 | − if (needself) { | |
| 653 | − new_localvarliteral(ls, "self"); | |
| 799 | + if (ismethod) { | |
| 800 | + new_localvarliteral(ls, "self"); /* create 'self' parameter */ | |
| 654 | 801 | adjustlocalvars(ls, 1); |
| 655 | 802 | } |
| 656 | 803 | parlist(ls); |
| 657 | 804 | checknext(ls, ')'); |
| 658 | − chunk(ls); | |
| 805 | + statlist(ls); | |
| 659 | 806 | new_fs.f->lastlinedefined = ls->linenumber; |
| 660 | 807 | check_match(ls, TK_END, TK_FUNCTION, line); |
| 661 | 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) { | |
| 667 | − /* explist1 -> expr { `,' expr } */ | |
| 813 | +static int explist (LexState *ls, expdesc *v) { | |
| 814 | + /* explist -> expr { `,' expr } */ | |
| 668 | 815 | int n = 1; /* at least one expression */ |
| 669 | 816 | expr(ls, v); |
| 670 | 817 | while (testnext(ls, ',')) { |
| @@ -681,12 +828,12 @@ static void funcargs (LexState *ls, expdesc *f, int line) { · 10 unmodified lines | ||
| 681 | 828 | expdesc args; |
| 682 | 829 | int base, nparams; |
| 683 | 830 | switch (ls->t.token) { |
| 684 | − case '(': { /* funcargs -> `(' [ explist1 ] `)' */ | |
| 831 | + case '(': { /* funcargs -> `(' [ explist ] `)' */ | |
| 685 | 832 | luaX_next(ls); |
| 686 | 833 | if (ls->t.token == ')') /* arg list is empty? */ |
| 687 | 834 | args.k = VVOID; |
| 688 | 835 | else { |
| 689 | − explist1(ls, &args); | |
| 836 | + explist(ls, &args); | |
| 690 | 837 | luaK_setmultret(fs, &args); |
| 691 | 838 | } |
| 692 | 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 | 1087 | static void block (LexState *ls) { |
| 951 | − /* block -> chunk */ | |
| 1088 | + /* block -> statlist */ | |
| 952 | 1089 | FuncState *fs = ls->fs; |
| 953 | 1090 | BlockCnt bl; |
| 954 | 1091 | enterblock(fs, &bl, 0); |
| 955 | − chunk(ls); | |
| 956 | − lua_assert(bl.breaklist == NO_JUMP); | |
| 1092 | + statlist(ls); | |
| 957 | 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 | 1148 | "variable names"); |
| 1013 | 1149 | assignment(ls, &nv, nvars+1); |
| 1014 | 1150 | } |
| 1015 | − else { /* assignment -> `=' explist1 */ | |
| 1151 | + else { /* assignment -> `=' explist */ | |
| 1016 | 1152 | int nexps; |
| 1017 | 1153 | checknext(ls, '='); |
| 1018 | − nexps = explist1(ls, &e); | |
| 1154 | + nexps = explist(ls, &e); | |
| 1019 | 1155 | if (nexps != nvars) { |
| 1020 | 1156 | adjust_assign(ls, nvars, nexps, &e); |
| 1021 | 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 | 1190 | FuncState *fs = ls->fs; |
| 1047 | − BlockCnt *bl = fs->bl; | |
| 1048 | − int upval = 0; | |
| 1049 | − while (bl && !bl->isbreakable) { | |
| 1050 | − upval |= bl->upval; | |
| 1051 | − bl = bl->previous; | |
| 1191 | + Labellist *ll = &ls->dyd->label; | |
| 1192 | + int l, i; /* index of new label being created */ | |
| 1193 | + /* check for repeated labels on the same block */ | |
| 1194 | + for (i = ls->fs->bl->firstlabel; i < ll->n; i++) { | |
| 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) | |
| 1054 | − luaX_syntaxerror(ls, "no loop to break"); | |
| 1055 | − if (upval) | |
| 1056 | − luaK_codeABC(fs, OP_CLOSE, bl->nactvar, 0, 0); | |
| 1057 | − luaK_concat(fs, &bl->breaklist, luaK_jump(fs)); | |
| 1202 | + checknext(ls, ':'); /* skip colon */ | |
| 1203 | + /* create new entry for this label */ | |
| 1204 | + l = newlabelentry(ls, ll, label, line, fs->pc); | |
| 1205 | + /* skip other no-op statements */ | |
| 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 | 1241 | enterblock(fs, &bl1, 1); /* loop block */ |
| 1087 | 1242 | enterblock(fs, &bl2, 0); /* scope block */ |
| 1088 | 1243 | luaX_next(ls); /* skip REPEAT */ |
| 1089 | − chunk(ls); | |
| 1244 | + statlist(ls); | |
| 1090 | 1245 | check_match(ls, TK_UNTIL, TK_REPEAT, line); |
| 1091 | 1246 | condexit = cond(ls); /* read condition (inside scope block) */ |
| 1092 | − if (!bl2.upval) { /* no upvalues? */ | |
| 1093 | − leaveblock(fs); /* finish scope */ | |
| 1094 | − luaK_patchlist(fs, condexit, repeat_init); /* close the loop */ | |
| 1095 | − } | |
| 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 | − } | |
| 1247 | + if (bl2.upval) /* upvalues? */ | |
| 1248 | + luaK_patchclose(fs, condexit, bl2.nactvar); | |
| 1249 | + leaveblock(fs); /* finish scope */ | |
| 1250 | + luaK_patchlist(fs, condexit, repeat_init); /* close the loop */ | |
| 1102 | 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 | 1314 | static void forlist (LexState *ls, TString *indexname) { |
| 1166 | − /* forlist -> NAME {,NAME} IN explist1 forbody */ | |
| 1315 | + /* forlist -> NAME {,NAME} IN explist forbody */ | |
| 1167 | 1316 | FuncState *fs = ls->fs; |
| 1168 | 1317 | expdesc e; |
| 1169 | 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 | 1331 | checknext(ls, TK_IN); |
| 1183 | 1332 | line = ls->linenumber; |
| 1184 | − adjust_assign(ls, 3, explist1(ls, &e), &e); | |
| 1333 | + adjust_assign(ls, 3, explist(ls, &e), &e); | |
| 1185 | 1334 | luaK_checkstack(fs, 3); /* extra space to call generator */ |
| 1186 | 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 | 1392 | static void localfunc (LexState *ls) { |
| 1244 | − expdesc v, b; | |
| 1393 | + expdesc b; | |
| 1245 | 1394 | FuncState *fs = ls->fs; |
| 1246 | − new_localvar(ls, str_checkname(ls)); | |
| 1247 | − init_exp(&v, VLOCAL, fs->freereg); | |
| 1248 | − luaK_reserveregs(fs, 1); | |
| 1249 | − adjustlocalvars(ls, 1); | |
| 1250 | − body(ls, &b, 0, ls->linenumber); | |
| 1251 | − luaK_storevar(fs, &v, &b); | |
| 1395 | + int varidx = fs->nactvar; /* index of new local variable */ | |
| 1396 | + new_localvar(ls, str_checkname(ls)); /* new local variable */ | |
| 1397 | + adjustlocalvars(ls, 1); /* enter its scope */ | |
| 1398 | + body(ls, &b, 0, ls->linenumber); /* function created in next register */ | |
| 1399 | + lua_assert(b.k == VNONRELOC && b.u.ind.idx == varidx); | |
| 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 | 1405 | static void localstat (LexState *ls) { |
| 1256 | − /* stat -> LOCAL NAME {`,' NAME} [`=' explist1] */ | |
| 1406 | + /* stat -> LOCAL NAME {`,' NAME} [`=' explist] */ | |
| 1257 | 1407 | int nvars = 0; |
| 1258 | 1408 | int nexps; |
| 1259 | 1409 | expdesc e; |
| @@ -1262,7 +1412,7 @@ static void localstat (LexState *ls) { · 2 unmodified lines | ||
| 1262 | 1412 | nvars++; |
| 1263 | 1413 | } while (testnext(ls, ',')); |
| 1264 | 1414 | if (testnext(ls, '=')) |
| 1265 | − nexps = explist1(ls, &e); | |
| 1415 | + nexps = explist(ls, &e); | |
| 1266 | 1416 | else { |
| 1267 | 1417 | e.k = VVOID; |
| 1268 | 1418 | nexps = 0; |
| @@ -1274,25 +1424,25 @@ static void localstat (LexState *ls) { · 5 unmodified lines | ||
| 1274 | 1424 | |
| 1275 | 1425 | static int funcname (LexState *ls, expdesc *v) { |
| 1276 | 1426 | /* funcname -> NAME {fieldsel} [`:' NAME] */ |
| 1277 | − int needself = 0; | |
| 1427 | + int ismethod = 0; | |
| 1278 | 1428 | singlevar(ls, v); |
| 1279 | 1429 | while (ls->t.token == '.') |
| 1280 | 1430 | fieldsel(ls, v); |
| 1281 | 1431 | if (ls->t.token == ':') { |
| 1282 | − needself = 1; | |
| 1432 | + ismethod = 1; | |
| 1283 | 1433 | fieldsel(ls, v); |
| 1284 | 1434 | } |
| 1285 | − return needself; | |
| 1435 | + return ismethod; | |
| 1286 | 1436 | } |
| 1287 | 1437 | |
| 1288 | 1438 | |
| 1289 | 1439 | static void funcstat (LexState *ls, int line) { |
| 1290 | 1440 | /* funcstat -> FUNCTION funcname body */ |
| 1291 | − int needself; | |
| 1441 | + int ismethod; | |
| 1292 | 1442 | expdesc v, b; |
| 1293 | 1443 | luaX_next(ls); /* skip FUNCTION */ |
| 1294 | − needself = funcname(ls, &v); | |
| 1295 | − body(ls, &b, needself, line); | |
| 1444 | + ismethod = funcname(ls, &v); | |
| 1445 | + body(ls, &b, ismethod, line); | |
| 1296 | 1446 | luaK_storevar(ls->fs, &v, &b); |
| 1297 | 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 | 1465 | static void retstat (LexState *ls) { |
| 1316 | − /* stat -> RETURN explist */ | |
| 1466 | + /* stat -> RETURN [explist] [';'] */ | |
| 1317 | 1467 | FuncState *fs = ls->fs; |
| 1318 | 1468 | expdesc e; |
| 1319 | 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 | 1471 | first = nret = 0; /* return no values */ |
| 1322 | 1472 | else { |
| 1323 | − nret = explist1(ls, &e); /* optional return values */ | |
| 1473 | + nret = explist(ls, &e); /* optional return values */ | |
| 1324 | 1474 | if (hasmultret(e.k)) { |
| 1325 | 1475 | luaK_setmultret(fs, &e); |
| 1326 | 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 | 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 | 1499 | int line = ls->linenumber; /* may be needed for error messages */ |
| 1500 | + enterlevel(ls); | |
| 1349 | 1501 | switch (ls->t.token) { |
| 1350 | 1502 | case ';': { /* stat -> ';' (empty statement) */ |
| 1351 | 1503 | luaX_next(ls); /* skip ';' */ |
| 1352 | − return 0; | |
| 1504 | + break; | |
| 1353 | 1505 | } |
| 1354 | 1506 | case TK_IF: { /* stat -> ifstat */ |
| 1355 | 1507 | ifstat(ls, line); |
| 1356 | − return 0; | |
| 1508 | + break; | |
| 1357 | 1509 | } |
| 1358 | 1510 | case TK_WHILE: { /* stat -> whilestat */ |
| 1359 | 1511 | whilestat(ls, line); |
| 1360 | − return 0; | |
| 1512 | + break; | |
| 1361 | 1513 | } |
| 1362 | 1514 | case TK_DO: { /* stat -> DO block END */ |
| 1363 | 1515 | luaX_next(ls); /* skip DO */ |
| 1364 | 1516 | block(ls); |
| 1365 | 1517 | check_match(ls, TK_END, TK_DO, line); |
| 1366 | − return 0; | |
| 1518 | + break; | |
| 1367 | 1519 | } |
| 1368 | 1520 | case TK_FOR: { /* stat -> forstat */ |
| 1369 | 1521 | forstat(ls, line); |
| 1370 | − return 0; | |
| 1522 | + break; | |
| 1371 | 1523 | } |
| 1372 | 1524 | case TK_REPEAT: { /* stat -> repeatstat */ |
| 1373 | 1525 | repeatstat(ls, line); |
| 1374 | − return 0; | |
| 1526 | + break; | |
| 1375 | 1527 | } |
| 1376 | 1528 | case TK_FUNCTION: { /* stat -> funcstat */ |
| 1377 | 1529 | funcstat(ls, line); |
| 1378 | − return 0; | |
| 1530 | + break; | |
| 1379 | 1531 | } |
| 1380 | 1532 | case TK_LOCAL: { /* stat -> localstat */ |
| 1381 | 1533 | luaX_next(ls); /* skip LOCAL */ |
| @@ -1383,39 +1535,62 @@ static int statement (LexState *ls) { · 1 unmodified line | ||
| 1383 | 1535 | localfunc(ls); |
| 1384 | 1536 | else |
| 1385 | 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 | 1545 | case TK_RETURN: { /* stat -> retstat */ |
| 1389 | 1546 | luaX_next(ls); /* skip RETURN */ |
| 1390 | 1547 | retstat(ls); |
| 1391 | − return 1; /* must be last statement */ | |
| 1548 | + break; | |
| 1392 | 1549 | } |
| 1393 | 1550 | case TK_BREAK: { /* stat -> breakstat */ |
| 1394 | 1551 | luaX_next(ls); /* skip BREAK */ |
| 1395 | − breakstat(ls); | |
| 1396 | − return 1; /* must be last statement */ | |
| 1552 | + /* code it as "goto 'break'" */ | |
| 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 | 1561 | default: { /* stat -> func | assignment */ |
| 1399 | 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) { | |
| 1407 | − /* chunk -> { stat [`;'] } */ | |
| 1408 | − int islast = 0; | |
| 1409 | − enterlevel(ls); | |
| 1410 | − while (!islast && !block_follow(ls->t.token)) { | |
| 1411 | − islast = statement(ls); | |
| 1412 | − if (islast) | |
| 1413 | − testnext(ls, ';'); | |
| 1414 | − lua_assert(ls->fs->f->maxstacksize >= ls->fs->freereg && | |
| 1415 | − ls->fs->freereg >= ls->fs->nactvar); | |
| 1416 | − ls->fs->freereg = ls->fs->nactvar; /* free registers */ | |
| 1417 | − } | |
| 1418 | − leavelevel(ls); | |
| 1574 | + | |
| 1575 | +Proto *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff, | |
| 1576 | + Dyndata *dyd, const char *name, int firstchar) { | |
| 1577 | + LexState lexstate; | |
| 1578 | + FuncState funcstate; | |
| 1579 | + BlockCnt bl; | |
| 1580 | + TString *tname = luaS_new(L, name); | |
| 1581 | + setsvalue2s(L, L->top, tname); /* push name to protect it */ | |
| 1582 | + incr_top(L); | |
| 1583 | + lexstate.buff = buff; | |
| 1584 | + lexstate.dyd = dyd; | |
| 1585 | + dyd->actvar.n = dyd->gt.n = dyd->label.n = 0; | |
| 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 | 3 | ** Lua Parser |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| @@ -53,19 +53,42 @@ typedef struct expdesc { · 47 unmodified lines | ||
| 53 | 53 | } expdesc; |
| 54 | 54 | |
| 55 | 55 | |
| 56 | −typedef struct vardesc { | |
| 57 | − unsigned short idx; | |
| 58 | −} vardesc; | |
| 56 | +/* description of active local variable */ | |
| 57 | +typedef struct Vardesc { | |
| 58 | + unsigned short idx; /* variable index in stack */ | |
| 59 | +} Vardesc; | |
| 59 | 60 | |
| 60 | 61 | |
| 61 | −/* list of all active local variables */ | |
| 62 | −typedef struct Varlist { | |
| 63 | − vardesc *actvar; | |
| 64 | − int nactvar; | |
| 65 | − int actvarsize; | |
| 66 | −} Varlist; | |
| 62 | +/* description of pending goto statements and label statements */ | |
| 63 | +typedef struct Labeldesc { | |
| 64 | + TString *name; /* label identifier */ | |
| 65 | + int pc; /* position in code */ | |
| 66 | + int line; /* line where it appeared */ | |
| 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 | 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 | 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 | 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 | 3 | ** Global State |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| @@ -65,11 +65,14 @@ typedef struct LG { · 59 unmodified lines | ||
| 65 | 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 | 78 | CallInfo *luaE_extendCI (lua_State *L) { |
| @@ -154,7 +157,7 @@ static void f_luaopen (lua_State *L, void *ud) { · 78 unmodified lines | ||
| 154 | 157 | /* pre-create memory-error message */ |
| 155 | 158 | g->memerrmsg = luaS_newliteral(L, MEMERRMSG); |
| 156 | 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 | 190 | luaM_freearray(L, G(L)->strt.hash, G(L)->strt.size); |
| 188 | 191 | luaZ_freebuffer(L, &g->buff); |
| 189 | 192 | freestack(L); |
| 190 | − lua_assert(g->totalbytes == sizeof(LG)); | |
| 193 | + lua_assert(gettotalbytes(g) == sizeof(LG)); | |
| 191 | 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 | 244 | g->mainthread = L; |
| 242 | 245 | g->uvhead.u.l.prev = &g->uvhead; |
| 243 | 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 | 248 | g->lastmajormem = 0; |
| 246 | 249 | g->strt.size = 0; |
| 247 | 250 | g->strt.nuse = 0; |
| @@ -252,11 +255,12 @@ LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) { · 4 unmodified lines | ||
| 252 | 255 | g->version = lua_version(NULL); |
| 253 | 256 | g->gcstate = GCSpause; |
| 254 | 257 | g->allgc = NULL; |
| 255 | − g->udgc = NULL; | |
| 258 | + g->finobj = NULL; | |
| 256 | 259 | g->tobefnz = NULL; |
| 257 | 260 | g->gray = g->grayagain = NULL; |
| 258 | 261 | g->weak = g->ephemeron = g->allweak = NULL; |
| 259 | 262 | g->totalbytes = sizeof(LG); |
| 263 | + g->GCdebt = 0; | |
| 260 | 264 | g->gcpause = LUAI_GCPAUSE; |
| 261 | 265 | g->gcmajorinc = LUAI_GCMAJOR; |
| 262 | 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 | 3 | ** Global State |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| @@ -32,9 +32,9 @@ · 26 unmodified lines | ||
| 32 | 32 | ** when traversing the respective threads, but the thread may already be |
| 33 | 33 | ** dead, while the upvalue is still accessible through closures.) |
| 34 | 34 | ** |
| 35 | −** Userdata with finalizers are kept in the list g->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 | 104 | #define CIST_TAIL (1<<6) /* call was tail called */ |
| 105 | 105 | |
| 106 | 106 | |
| 107 | −#define ci_func(ci) (clvalue((ci)->func)) | |
| 108 | 107 | #define isLua(ci) ((ci)->callstatus & CIST_LUA) |
| 109 | 108 | |
| 110 | 109 | |
| @@ -114,8 +113,8 @@ typedef struct CallInfo { · 3 unmodified lines | ||
| 114 | 113 | typedef struct global_State { |
| 115 | 114 | lua_Alloc frealloc; /* function to reallocate memory */ |
| 116 | 115 | void *ud; /* auxiliary data to `frealloc' */ |
| 117 | − lu_mem totalbytes; /* number of bytes currently allocated */ | |
| 118 | − l_mem GCdebt; /* when positive, run a GC step */ | |
| 116 | + lu_mem totalbytes; /* number of bytes currently allocated - GCdebt */ | |
| 117 | + l_mem GCdebt; /* bytes allocated not yet compensated by the collector */ | |
| 119 | 118 | lu_mem lastmajormem; /* memory in use after last major collection */ |
| 120 | 119 | stringtable strt; /* hash table for strings */ |
| 121 | 120 | TValue l_registry; |
| @@ -123,9 +122,10 @@ typedef struct global_State { · 1 unmodified line | ||
| 123 | 122 | lu_byte currentwhite; |
| 124 | 123 | lu_byte gcstate; /* state of garbage collector */ |
| 125 | 124 | lu_byte gckind; /* kind of GC running */ |
| 125 | + lu_byte gcrunning; /* true if GC is running */ | |
| 126 | 126 | int sweepstrgc; /* position of sweep in `strt' */ |
| 127 | 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 | 129 | GCObject **sweepgc; /* current position of sweep */ |
| 130 | 130 | GCObject *gray; /* list of gray objects */ |
| 131 | 131 | GCObject *grayagain; /* list of objects to be traversed atomically */ |
| @@ -209,6 +209,10 @@ union GCObject { · 77 unmodified lines | ||
| 209 | 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 | 216 | LUAI_FUNC void luaE_freethread (lua_State *L, lua_State *L1); |
| 213 | 217 | LUAI_FUNC CallInfo *luaE_extendCI (lua_State *L); |
| 214 | 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 | 3 | ** String table (keeps all strings handled by Lua) |
| 4 | 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 | 84 | o != NULL; |
| 85 | 85 | o = gch(o)->next) { |
| 86 | 86 | TString *ts = rawgco2ts(o); |
| 87 | − if (h == ts->tsv.hash && ts->tsv.len == l && | |
| 88 | − (memcmp(str, getstr(ts), l) == 0)) { | |
| 87 | + if (h == ts->tsv.hash && | |
| 88 | + ts->tsv.len == l && | |
| 89 | + (memcmp(str, getstr(ts), l * sizeof(char)) == 0)) { | |
| 89 | 90 | if (isdead(G(L), o)) /* string is dead (but was not collected yet)? */ |
| 90 | 91 | changewhite(o); /* resurrect it */ |
| 91 | 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 | 3 | ** Standard library for string operations and pattern-matching |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| @@ -45,7 +45,7 @@ static int str_len (lua_State *L) { · 39 unmodified lines | ||
| 45 | 45 | /* translate a relative string position: negative means back from end */ |
| 46 | 46 | static size_t posrelat (ptrdiff_t pos, size_t len) { |
| 47 | 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 | 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 | 101 | return 1; |
| 102 | 102 | } |
| 103 | 103 | |
| 104 | + | |
| 105 | +/* reasonable limit to avoid arithmetic overflow */ | |
| 106 | +#define MAXSIZE ((~(size_t)0) >> 1) | |
| 107 | + | |
| 104 | 108 | static int str_rep (lua_State *L) { |
| 105 | − size_t l; | |
| 106 | − luaL_Buffer b; | |
| 109 | + size_t l, lsep; | |
| 107 | 110 | const char *s = luaL_checklstring(L, 1, &l); |
| 108 | 111 | int n = luaL_checkint(L, 2); |
| 109 | − luaL_buffinit(L, &b); | |
| 110 | − while (n-- > 0) | |
| 111 | − luaL_addlstring(&b, s, l); | |
| 112 | − luaL_pushresult(&b); | |
| 112 | + const char *sep = luaL_optlstring(L, 3, "", &lsep); | |
| 113 | + if (n <= 0) lua_pushliteral(L, ""); | |
| 114 | + else if (l + lsep < l || l + lsep >= MAXSIZE / n) /* may overflow? */ | |
| 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 | 127 | return 1; |
| 114 | 128 | } |
| 115 | 129 | |
| @@ -125,7 +139,7 @@ static int str_byte (lua_State *L) { · 9 unmodified lines | ||
| 125 | 139 | if (posi > pose) return 0; /* empty interval; return no values */ |
| 126 | 140 | n = (int)(pose - posi + 1); |
| 127 | 141 | if (posi + n <= pose) /* overflow? */ |
| 128 | − luaL_error(L, "string slice too long"); | |
| 142 | + return luaL_error(L, "string slice too long"); | |
| 129 | 143 | luaL_checkstack(L, n, "string slice too long"); |
| 130 | 144 | for (i=0; i<n; i++) |
| 131 | 145 | lua_pushinteger(L, uchar(s[posi+i-1])); |
| @@ -161,7 +175,7 @@ static int str_dump (lua_State *L) { · 29 unmodified lines | ||
| 161 | 175 | lua_settop(L, 1); |
| 162 | 176 | luaL_buffinit(L,&b); |
| 163 | 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 | 179 | luaL_pushresult(&b); |
| 166 | 180 | return 1; |
| 167 | 181 | } |
| @@ -510,7 +524,7 @@ static int nospecials (const char *p, size_t l) { · 342 unmodified lines | ||
| 510 | 524 | size_t upto = 0; |
| 511 | 525 | do { |
| 512 | 526 | if (strpbrk(p + upto, SPECIALS)) |
| 513 | − return 0; /* pattern has a special character */ | |
| 527 | + return 0; /* pattern has a special character */ | |
| 514 | 528 | upto += strlen(p + upto) + 1; /* may have more after \0 */ |
| 515 | 529 | } while (upto <= l); |
| 516 | 530 | return 1; /* no special chars found */ |
| @@ -729,7 +743,7 @@ static int str_gsub (lua_State *L) { · 212 unmodified lines | ||
| 729 | 743 | ** the previous length |
| 730 | 744 | */ |
| 731 | 745 | #if !defined(LUA_INTFRMLEN) /* { */ |
| 732 | −#if defined(LUA_USELONGLONG) | |
| 746 | +#if defined(LUA_USE_LONGLONG) | |
| 733 | 747 | |
| 734 | 748 | #define LUA_INTFRMLEN "ll" |
| 735 | 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 | 808 | static const char *scanformat (lua_State *L, const char *strfrmt, char *form) { |
| 795 | 809 | const char *p = strfrmt; |
| 796 | 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 | 812 | luaL_error(L, "invalid format (repeated flags)"); |
| 799 | 813 | if (isdigit(uchar(*p))) p++; /* skip width */ |
| 800 | 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 | 820 | if (isdigit(uchar(*p))) |
| 807 | 821 | luaL_error(L, "invalid format (width or precision too long)"); |
| 808 | 822 | *(form++) = '%'; |
| 809 | − memcpy(form, strfrmt, p - strfrmt + 1); | |
| 823 | + memcpy(form, strfrmt, (p - strfrmt + 1) * sizeof(char)); | |
| 810 | 824 | form += p - strfrmt + 1; |
| 811 | 825 | *form = '\0'; |
| 812 | 826 | return p; |
| @@ -861,6 +875,9 @@ static int str_format (lua_State *L) { · 48 unmodified lines | ||
| 861 | 875 | break; |
| 862 | 876 | } |
| 863 | 877 | case 'e': case 'E': case 'f': |
| 878 | +#if defined(LUA_USE_AFORMAT) | |
| 879 | + case 'a': case 'A': | |
| 880 | +#endif | |
| 864 | 881 | case 'g': case 'G': { |
| 865 | 882 | addlenmod(form, LUA_FLTFRMLEN); |
| 866 | 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 | 890 | case 's': { |
| 874 | 891 | size_t l; |
| 875 | − const char *s = luaL_checklstring(L, arg, &l); | |
| 892 | + const char *s = luaL_tolstring(L, arg, &l); | |
| 876 | 893 | if (!strchr(form, '.') && l >= 100) { |
| 877 | 894 | /* no precision and string is too long to be formatted; |
| 878 | 895 | keep original string */ |
| 879 | − lua_pushvalue(L, arg); | |
| 880 | 896 | luaL_addvalue(&b); |
| 881 | 897 | break; |
| 882 | 898 | } |
| 883 | 899 | else { |
| 884 | 900 | nb = sprintf(buff, form, s); |
| 901 | + lua_pop(L, 1); /* remove result from 'luaL_tolstring' */ | |
| 885 | 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 | 929 | static const luaL_Reg strlib[] = { |
| 904 | 930 | {"byte", str_byte}, |
| 905 | 931 | {"char", str_char}, |
| @@ -915,19 +941,22 @@ static const luaL_Reg strlib[] = { · 9 unmodified lines | ||
| 915 | 941 | {"reverse", str_reverse}, |
| 916 | 942 | {"sub", str_sub}, |
| 917 | 943 | {"upper", str_upper}, |
| 944 | + {"__index", noindex}, | |
| 918 | 945 | {NULL, NULL} |
| 919 | 946 | }; |
| 920 | 947 | |
| 921 | 948 | |
| 922 | 949 | static void createmetatable (lua_State *L) { |
| 923 | − lua_createtable(L, 0, 1); /* create metatable for strings */ | |
| 950 | + /* setmetatable("", {__index = string}) */ | |
| 924 | 951 | lua_pushliteral(L, ""); /* dummy string */ |
| 925 | − lua_pushvalue(L, -2); | |
| 926 | − lua_setmetatable(L, -2); /* set string metatable */ | |
| 952 | + lua_createtable(L, 0, 1); /* create metatable for strings */ | |
| 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 | 956 | lua_pop(L, 1); /* pop dummy string */ |
| 928 | − lua_pushvalue(L, -2); /* string library... */ | |
| 929 | − lua_setfield(L, -2, "__index"); /* ...is the __index metamethod */ | |
| 930 | − lua_pop(L, 1); /* pop metatable */ | |
| 957 | + /* setmetatable(string, string) */ | |
| 958 | + lua_pushvalue(L, -1); /* push string library */ | |
| 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 | 3 | ** Lua tables (hash) |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| @@ -33,6 +33,7 @@ · 27 unmodified lines | ||
| 33 | 33 | #include "lstate.h" |
| 34 | 34 | #include "lstring.h" |
| 35 | 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 | 88 | int i; |
| 88 | 89 | luai_hashnum(i, n); |
| 89 | 90 | if (i < 0) { |
| 90 | − i = -i; /* must be a positive value */ | |
| 91 | − if (i < 0) i = 0; /* handle INT_MIN */ | |
| 91 | + if ((unsigned int)i == -(unsigned int)i) | |
| 92 | + i = 0; /* handle INT_MIN */ | |
| 93 | + i = -i; /* must be a positive value */ | |
| 92 | 94 | } |
| 93 | 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 | 150 | Node *n = mainposition(t, key); |
| 149 | 151 | do { /* check whether `key' is somewhere in the chain */ |
| 150 | 152 | /* key may be dead already, but it is ok to use it in `next' */ |
| 151 | − if (luaO_rawequalObj(gkey(n), key) || | |
| 152 | − (ttype(gkey(n)) == LUA_TDEADKEY && iscollectable(key) && | |
| 153 | + if (luaV_rawequalobj(gkey(n), key) || | |
| 154 | + (ttisdeadkey(gkey(n)) && iscollectable(key) && | |
| 153 | 155 | gcvalue(gkey(n)) == gcvalue(key))) { |
| 154 | 156 | i = cast_int(n - gnode(t, 0)); /* key index in hash table */ |
| 155 | 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 | 339 | static void rehash (lua_State *L, Table *t, const TValue *ek) { |
| 338 | 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 | 342 | int i; |
| 341 | 343 | int totaluse; |
| 342 | 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 | 469 | ** main search function |
| 468 | 470 | */ |
| 469 | 471 | const TValue *luaH_get (Table *t, const TValue *key) { |
| 470 | − switch (ttype(key)) { | |
| 472 | + switch (ttypenv(key)) { | |
| 471 | 473 | case LUA_TNIL: return luaO_nilobject; |
| 472 | 474 | case LUA_TSTRING: return luaH_getstr(t, rawtsvalue(key)); |
| 473 | 475 | case LUA_TNUMBER: { |
| @@ -481,7 +483,7 @@ const TValue *luaH_get (Table *t, const TValue *key) { · 7 unmodified lines | ||
| 481 | 483 | default: { |
| 482 | 484 | Node *n = mainposition(t, key); |
| 483 | 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 | 487 | return gval(n); /* that's it */ |
| 486 | 488 | else n = gnext(n); |
| 487 | 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 | 3 | ** Library for Table Manipulation |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| @@ -17,7 +17,7 @@ · 11 unmodified lines | ||
| 17 | 17 | |
| 18 | 18 | |
| 19 | 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 | 23 | static int deprecatedfunc (lua_State *L) { |
| @@ -104,7 +104,7 @@ static int tconcat (lua_State *L) { · 80 unmodified lines | ||
| 104 | 104 | const char *sep = luaL_optlstring(L, 2, "", &lsep); |
| 105 | 105 | luaL_checktype(L, 1, LUA_TTABLE); |
| 106 | 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 | 108 | luaL_buffinit(L, &b); |
| 109 | 109 | for (; i < last; i++) { |
| 110 | 110 | addfield(L, &b, i); |
| @@ -143,7 +143,7 @@ static int unpack (lua_State *L) { · 32 unmodified lines | ||
| 143 | 143 | int i, e, n; |
| 144 | 144 | luaL_checktype(L, 1, LUA_TTABLE); |
| 145 | 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 | 147 | if (i > e) return 0; /* empty range */ |
| 148 | 148 | n = e - i + 1; /* number of elements */ |
| 149 | 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 | 3 | ** Tag methods |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| @@ -21,11 +21,11 @@ · 15 unmodified lines | ||
| 21 | 21 | |
| 22 | 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 | 25 | "no value", |
| 26 | 26 | "nil", "boolean", udatatypename, "number", |
| 27 | 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 | 63 | const TValue *luaT_gettmbyobj (lua_State *L, const TValue *o, TMS event) { |
| 64 | 64 | Table *mt; |
| 65 | − switch (ttype(o)) { | |
| 65 | + switch (ttypenv(o)) { | |
| 66 | 66 | case LUA_TTABLE: |
| 67 | 67 | mt = hvalue(o)->metatable; |
| 68 | 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 | 3 | ** Tag methods |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| @@ -46,7 +46,7 @@ typedef enum { · 40 unmodified lines | ||
| 46 | 46 | #define ttypename(x) luaT_typenames_[(x) + 1] |
| 47 | 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 | 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 | 3 | ** Lua stand-alone interpreter |
| 4 | 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 | 108 | static void print_usage (const char *badoption) { |
| 109 | − if (badoption[1] == 'e' || badoption[1] == 'l') { | |
| 110 | − luai_writestringerror("%s: ", progname); | |
| 109 | + luai_writestringerror("%s: ", progname); | |
| 110 | + if (badoption[1] == 'e' || badoption[1] == 'l') | |
| 111 | 111 | luai_writestringerror("'%s' needs argument\n", badoption); |
| 112 | − } else { | |
| 113 | − luai_writestringerror("%s: ", progname); | |
| 112 | + else | |
| 114 | 113 | luai_writestringerror("unrecognized option '%s'\n", badoption); |
| 115 | − } | |
| 116 | 114 | luai_writestringerror( |
| 117 | 115 | "usage: %s [options] [script [args]]\n" |
| 118 | 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 | 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 | 248 | /* mark in error messages for incomplete statements */ |
| 250 | −#define mark "<eof>" | |
| 251 | −#define marklen (sizeof(mark) - 1) | |
| 249 | +#define EOFMARK "<eof>" | |
| 250 | +#define marklen (sizeof(EOFMARK)/sizeof(char) - 1) | |
| 252 | 251 | |
| 253 | 252 | static int incomplete (lua_State *L, int status) { |
| 254 | 253 | if (status == LUA_ERRSYNTAX) { |
| 255 | 254 | size_t lmsg; |
| 256 | 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 | 257 | lua_pop(L, 1); |
| 259 | 258 | return 1; |
| 260 | 259 | } |
| @@ -322,7 +321,7 @@ static void dotty (lua_State *L) { · 61 unmodified lines | ||
| 322 | 321 | } |
| 323 | 322 | } |
| 324 | 323 | lua_settop(L, 0); /* clear stack */ |
| 325 | − luai_writestring("\n", 1); | |
| 324 | + luai_writeline(); | |
| 326 | 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 | 3 | ** Lua - A Scripting Language |
| 4 | 4 | ** Lua.org, PUC-Rio, Brazil (http://www.lua.org) |
| 5 | 5 | ** See Copyright Notice at the end of this file |
| @@ -18,12 +18,12 @@ · 12 unmodified lines | ||
| 18 | 18 | |
| 19 | 19 | #define LUA_VERSION_MAJOR "5" |
| 20 | 20 | #define LUA_VERSION_MINOR "2" |
| 21 | −#define LUA_VERSION_RELEASE "0" " (alpha)" | |
| 21 | +#define LUA_VERSION_RELEASE "0" " (beta)" | |
| 22 | 22 | |
| 23 | 23 | #define LUA_VERSION "Lua " LUA_VERSION_MAJOR "." LUA_VERSION_MINOR |
| 24 | 24 | #define LUA_RELEASE LUA_VERSION "." LUA_VERSION_RELEASE |
| 25 | 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 | 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 | 420 | * Permission is hereby granted, free of charge, to any person obtaining |
| 421 | 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 | 3 | ** Lua compiler (saves bytecodes to files; also list bytecodes) |
| 4 | 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 | 143 | int i=n; |
| 144 | 144 | if (lua_load(L,reader,&i,"=(" PROGNAME ")")!=LUA_OK) fatal(lua_tostring(L,-1)); |
| 145 | 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 | 151 | f->sizelineinfo=0; |
| 148 | − f->sizeupvalues=0; | |
| 149 | 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 | 207 | ** print bytecodes |
| 205 | 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 | 275 | #define UPVALNAME(x) ((f->upvalues[x].name) ? getstr(f->upvalues[x].name) : "-") |
| 276 | +#define MYK(x) (-1-(x)) | |
| 273 | 277 | |
| 274 | 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 | 298 | case iABC: |
| 295 | 299 | printf("%d",a); |
| 296 | − if (getBMode(o)!=OpArgN) printf(" %d",ISK(b) ? (-1-INDEXK(b)) : b); | |
| 297 | − if (getCMode(o)!=OpArgN) printf(" %d",ISK(c) ? (-1-INDEXK(c)) : c); | |
| 300 | + if (getBMode(o)!=OpArgN) printf(" %d",ISK(b) ? (MYK(INDEXK(b))) : b); | |
| 301 | + if (getCMode(o)!=OpArgN) printf(" %d",ISK(c) ? (MYK(INDEXK(c))) : c); | |
| 298 | 302 | break; |
| 299 | 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 | 307 | break; |
| 302 | 308 | case iAsBx: |
| 303 | − if (o==OP_JMP) printf("%d",sbx); else printf("%d %d",a,sbx); | |
| 309 | + printf("%d %d",a,sbx); | |
| 304 | 310 | break; |
| 305 | 311 | case iAx: |
| 306 | − printf("%d",-1-ax); | |
| 312 | + printf("%d",MYK(ax)); | |
| 307 | 313 | break; |
| 308 | 314 | } |
| 309 | 315 | switch (o) |
| 310 | 316 | { |
| 311 | 317 | case OP_LOADK: |
| 312 | − if (bx>0) { printf("\t; "); PrintConstant(f,bx-1); } | |
| 318 | + printf("\t; "); PrintConstant(f,bx); | |
| 313 | 319 | break; |
| 314 | 320 | case OP_GETUPVAL: |
| 315 | 321 | case OP_SETUPVAL: |
| @@ -355,8 +361,7 @@ static void PrintCode(const Proto* f) · 39 unmodified lines | ||
| 355 | 361 | printf("\t; %p",VOID(f->p[bx])); |
| 356 | 362 | break; |
| 357 | 363 | case OP_SETLIST: |
| 358 | − if (c==0) printf("\t; %d",(int)code[++pc]); | |
| 359 | − else printf("\t; %d",c); | |
| 364 | + if (c==0) printf("\t; %d",(int)code[++pc]); else printf("\t; %d",c); | |
| 360 | 365 | break; |
| 361 | 366 | case OP_EXTRAARG: |
| 362 | 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 | 3 | ** Configuration file for Lua |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| @@ -35,6 +35,7 @@ · 29 unmodified lines | ||
| 35 | 35 | |
| 36 | 36 | #if defined(LUA_WIN) |
| 37 | 37 | #define LUA_DL_DLL |
| 38 | +#define LUA_USE_AFORMAT /* assume 'printf' handles 'aA' specifiers */ | |
| 38 | 39 | #endif |
| 39 | 40 | |
| 40 | 41 | |
| @@ -43,12 +44,18 @@ · 2 unmodified lines | ||
| 43 | 44 | #define LUA_USE_POSIX |
| 44 | 45 | #define LUA_USE_DLOPEN /* needs an extra library: -ldl */ |
| 45 | 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 | 50 | #endif |
| 47 | 51 | |
| 48 | 52 | #if defined(LUA_USE_MACOSX) |
| 49 | 53 | #define LUA_USE_POSIX |
| 50 | 54 | #define LUA_USE_DLOPEN /* does not need -ldl */ |
| 51 | 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 | 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 | 214 | #include <stdio.h> |
| 208 | 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 | 219 | @@ luai_writestringerror defines how to print error messages. |
| @@ -253,6 +261,12 @@ · 41 unmodified lines | ||
| 253 | 261 | */ |
| 254 | 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 | 271 | @@ LUA_COMPAT_MAXN defines the function 'maxn' in the table library. |
| 258 | 272 | */ |
| @@ -371,14 +385,27 @@ · 112 unmodified lines | ||
| 371 | 385 | @@ LUA_NUMBER_FMT is the format for writing numbers. |
| 372 | 386 | @@ lua_number2str converts a number to a string. |
| 373 | 387 | @@ LUAI_MAXNUMBER2STR is maximum size of previous conversion. |
| 374 | −@@ lua_str2number converts a string to a number. | |
| 375 | 388 | */ |
| 376 | 389 | #define LUA_NUMBER_SCAN "%lf" |
| 377 | 390 | #define LUA_NUMBER_FMT "%.14g" |
| 378 | 391 | #define lua_number2str(s,n) sprintf((s), LUA_NUMBER_FMT, (n)) |
| 379 | 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 | 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 | 411 | @@ The luai_num* macros define the primitive operations over numbers. |
| @@ -438,11 +465,11 @@ · 53 unmodified lines | ||
| 438 | 465 | |
| 439 | 466 | /* |
| 440 | 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 | |
| 442 | −@@ check it dynamically. | |
| 468 | +** (0 for little endian, 1 for big endian); if not defined, Lua will | |
| 469 | +** check it dynamically. | |
| 443 | 470 | */ |
| 444 | 471 | /* check for known architectures */ |
| 445 | −#if defined(__i386__) || defined(__i386) || defined(i386) || \ | |
| 472 | +#if defined(__i386__) || defined(__i386) || defined(__X86__) || \ | |
| 446 | 473 | defined (__x86_64) |
| 447 | 474 | #define LUA_IEEEENDIAN 0 |
| 448 | 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 | 3 | ** Lua standard libraries |
| 4 | 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 | 54 | #define lua_assert(x) ((void)0) |
| 55 | 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 | 3 | ** load precompiled Lua chunks |
| 4 | 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 | 38 | #define LoadVar(S,x) LoadMem(S,&x,1,sizeof(x)) |
| 39 | 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 | 45 | static void LoadBlock(LoadState* S, void* b, size_t size) |
| 42 | 46 | { |
| 43 | 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 | 59 | int x; |
| 56 | 60 | LoadVar(S,x); |
| 61 | + if (x<0) error(S,"corrupted"); | |
| 57 | 62 | return x; |
| 58 | 63 | } |
| 59 | 64 | |
| @@ -73,7 +78,7 @@ static TString* LoadString(LoadState* S) · 13 unmodified lines | ||
| 73 | 78 | else |
| 74 | 79 | { |
| 75 | 80 | char* s=luaZ_openspace(S->L,S->b,size); |
| 76 | − LoadBlock(S,s,size); | |
| 81 | + LoadBlock(S,s,size*sizeof(char)); | |
| 77 | 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 | 183 | /* the code below must be consistent with the code in luaU_header */ |
| 179 | 184 | #define N0 LUAC_HEADERSIZE |
| 180 | −#define N1 (sizeof(LUA_SIGNATURE)-1) | |
| 185 | +#define N1 (sizeof(LUA_SIGNATURE)-sizeof(char)) | |
| 181 | 186 | #define N2 N1+2 |
| 182 | 187 | #define N3 N2+6 |
| 183 | 188 | |
| 184 | 189 | static void LoadHeader(LoadState* S) |
| 185 | 190 | { |
| 186 | − char h[LUAC_HEADERSIZE]; | |
| 187 | − char s[LUAC_HEADERSIZE]; | |
| 191 | + lu_byte h[LUAC_HEADERSIZE]; | |
| 192 | + lu_byte s[LUAC_HEADERSIZE]; | |
| 188 | 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 | 196 | if (memcmp(h,s,N0)==0) return; |
| 191 | 197 | if (memcmp(h,s,N1)!=0) error(S,"not a"); |
| 192 | 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 | 215 | S.Z=Z; |
| 210 | 216 | S.b=buff; |
| 211 | 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 */ | |
| 216 | −#define TAIL "\x19\x93\r\n\x1a\n" | |
| 221 | +#define MYINT(s) (s[0]-'0') | |
| 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 | 226 | * make header for precompiled chunks |
| 220 | −* if you make any changes in the code below or in LUA_SIGNATURE in lua.h, | |
| 221 | −* be sure to update LoadHeader above and LUAC_HEADERSIZE in lundump.h | |
| 227 | +* if you change the code below be sure to update LoadHeader and FORMAT above | |
| 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 | 232 | int x=1; |
| 226 | − memcpy(h,LUA_SIGNATURE,sizeof(LUA_SIGNATURE)-1); | |
| 227 | − h+=sizeof(LUA_SIGNATURE)-1; | |
| 228 | − *h++=(char)0x52; /* Lua 5.2 */ | |
| 229 | − *h++=(char)0; /* the official format */ | |
| 230 | − *h++=(char)*(char*)&x; /* endianness */ | |
| 231 | − *h++=(char)sizeof(int); | |
| 232 | − *h++=(char)sizeof(size_t); | |
| 233 | − *h++=(char)sizeof(Instruction); | |
| 234 | − *h++=(char)sizeof(lua_Number); | |
| 235 | − *h++=(char)(((lua_Number)0.5)==0); /* is lua_Number integral? */ | |
| 236 | − memcpy(h,TAIL,sizeof(TAIL)-1); | |
| 233 | + memcpy(h,LUA_SIGNATURE,sizeof(LUA_SIGNATURE)-sizeof(char)); | |
| 234 | + h+=sizeof(LUA_SIGNATURE)-sizeof(char); | |
| 235 | + *h++=cast_byte(VERSION); | |
| 236 | + *h++=cast_byte(FORMAT); | |
| 237 | + *h++=cast_byte(*(char*)&x); /* endianness */ | |
| 238 | + *h++=cast_byte(sizeof(int)); | |
| 239 | + *h++=cast_byte(sizeof(size_t)); | |
| 240 | + *h++=cast_byte(sizeof(Instruction)); | |
| 241 | + *h++=cast_byte(sizeof(lua_Number)); | |
| 242 | + *h++=cast_byte(((lua_Number)0.5)==0); /* is lua_Number integral? */ | |
| 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 | 3 | ** load precompiled Lua chunks |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| @@ -14,12 +14,15 @@ · 8 unmodified lines | ||
| 14 | 14 | LUAI_FUNC Proto* luaU_undump (lua_State* L, ZIO* Z, Mbuffer* buff, const char* name); |
| 15 | 15 | |
| 16 | 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 | 19 | /* dump one chunk; from ldump.c */ |
| 20 | 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 */ | |
| 23 | −#define LUAC_HEADERSIZE 18 | |
| 22 | +/* data to catch conversion errors */ | |
| 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 | 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 | 3 | ** Lua virtual machine |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| @@ -35,7 +35,7 @@ · 29 unmodified lines | ||
| 35 | 35 | const TValue *luaV_tonumber (const TValue *obj, TValue *n) { |
| 36 | 36 | lua_Number num; |
| 37 | 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 | 39 | setnvalue(n, num); |
| 40 | 40 | return n; |
| 41 | 41 | } |
| @@ -65,7 +65,7 @@ static void traceexec (lua_State *L) { · 23 unmodified lines | ||
| 65 | 65 | luaD_hook(L, LUA_HOOKCOUNT, -1); |
| 66 | 66 | } |
| 67 | 67 | if (mask & LUA_MASKLINE) { |
| 68 | − Proto *p = ci_func(ci)->l.p; | |
| 68 | + Proto *p = ci_func(ci)->p; | |
| 69 | 69 | int npc = pcRel(ci->u.l.savedpc, p); |
| 70 | 70 | int newline = getfuncline(p, npc); |
| 71 | 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 | 161 | if (ttisnil(tm)) |
| 162 | 162 | tm = luaT_gettmbyobj(L, p2, event); /* try second operand */ |
| 163 | 163 | if (ttisnil(tm)) return 0; |
| 164 | − if (event == TM_UNM) p2 = luaO_nilobject; | |
| 165 | 164 | callTM(L, tm, p1, p2, res, 1); |
| 166 | 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 | 174 | if (mt1 == mt2) return tm1; /* same metatables => same metamethods */ |
| 176 | 175 | tm2 = fasttm(L, mt2, event); |
| 177 | 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 | 178 | return tm1; |
| 180 | 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 | 244 | const TValue *tm; |
| 243 | − lua_assert(ttype(t1) == ttype(t2)); | |
| 245 | + lua_assert(ttisequal(t1, t2)); | |
| 244 | 246 | switch (ttype(t1)) { |
| 245 | 247 | case LUA_TNIL: return 1; |
| 246 | 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 | 252 | case LUA_TSTRING: return eqstr(rawtsvalue(t1), rawtsvalue(t2)); |
| 251 | 253 | case LUA_TUSERDATA: { |
| 252 | 254 | if (uvalue(t1) == uvalue(t2)) return 1; |
| 255 | + else if (L == NULL) return 0; | |
| 253 | 256 | tm = get_equalTM(L, uvalue(t1)->metatable, uvalue(t2)->metatable, TM_EQ); |
| 254 | 257 | break; /* will try TM */ |
| 255 | 258 | } |
| 256 | 259 | case LUA_TTABLE: { |
| 257 | 260 | if (hvalue(t1) == hvalue(t2)) return 1; |
| 261 | + else if (L == NULL) return 0; | |
| 258 | 262 | tm = get_equalTM(L, hvalue(t1)->metatable, hvalue(t2)->metatable, TM_EQ); |
| 259 | 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 | 269 | if (tm == NULL) return 0; /* no TM? */ |
| 264 | 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 | 292 | char *buffer; |
| 287 | 293 | int i; |
| 288 | 294 | /* collect total length */ |
| 289 | − for (n = 1; n < total && tostring(L, top-n-1); n++) { | |
| 290 | − size_t l = tsvalue(top-n-1)->len; | |
| 291 | − if (l >= MAX_SIZET - tl) luaG_runerror(L, "string length overflow"); | |
| 295 | + for (i = 1; i < total && tostring(L, top-i-1); i++) { | |
| 296 | + size_t l = tsvalue(top-i-1)->len; | |
| 297 | + if (l >= (MAX_SIZET/sizeof(char)) - tl) | |
| 298 | + luaG_runerror(L, "string length overflow"); | |
| 292 | 299 | tl += l; |
| 293 | 300 | } |
| 294 | 301 | buffer = luaZ_openspace(L, &G(L)->buff, tl); |
| 295 | 302 | tl = 0; |
| 296 | − for (i=n; i>0; i--) { /* concat all strings */ | |
| 303 | + n = i; | |
| 304 | + do { /* concat all strings */ | |
| 297 | 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 | 307 | tl += l; |
| 300 | − } | |
| 308 | + } while (--i > 0); | |
| 301 | 309 | setsvalue2s(L, top-n, luaS_newlstr(L, buffer, tl)); |
| 302 | 310 | } |
| 303 | 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 | 317 | void luaV_objlen (lua_State *L, StkId ra, const TValue *rb) { |
| 310 | 318 | const TValue *tm; |
| 311 | − switch (ttype(rb)) { | |
| 319 | + switch (ttypenv(rb)) { | |
| 312 | 320 | case LUA_TTABLE: { |
| 313 | 321 | Table *h = hvalue(rb); |
| 314 | 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 | 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 | 386 | Upvaldesc *uv = p->upvalues; |
| 379 | 387 | int i; |
| 380 | 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 | 390 | for (i = 0; i < nup; i++) { /* fill in its upvalues */ |
| 383 | 391 | if (uv[i].instack) /* upvalue refers to local variable? */ |
| 384 | 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 | 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 | 470 | #define RA(i) (base+GETARG_A(i)) |
| 458 | 471 | /* to be used after possible stack reallocation */ |
| 459 | 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 | 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 | 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 | 497 | #define arith_op(op,tm) { \ |
| @@ -493,9 +513,8 @@ void luaV_execute (lua_State *L) { · 15 unmodified lines | ||
| 493 | 513 | TValue *k; |
| 494 | 514 | StkId base; |
| 495 | 515 | newframe: /* reentry point when frame changes (call/return) */ |
| 496 | − lua_assert(isLua(ci)); | |
| 497 | 516 | lua_assert(ci == L->ci); |
| 498 | − cl = &clvalue(ci->func)->l; | |
| 517 | + cl = clLvalue(ci->func); | |
| 499 | 518 | k = cl->p->k; |
| 500 | 519 | base = ci->u.l.base; |
| 501 | 520 | /* main loop of interpreter */ |
| @@ -515,7 +534,13 @@ void luaV_execute (lua_State *L) { · 13 unmodified lines | ||
| 515 | 534 | setobjs2s(L, ra, RB(i)); |
| 516 | 535 | ) |
| 517 | 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 | 544 | setobj2s(L, ra, rb); |
| 520 | 545 | ) |
| 521 | 546 | vmcase(OP_LOADBOOL, |
| @@ -523,10 +548,10 @@ void luaV_execute (lua_State *L) { · 1 unmodified line | ||
| 523 | 548 | if (GETARG_C(i)) ci->u.l.savedpc++; /* skip next instruction (if C) */ |
| 524 | 549 | ) |
| 525 | 550 | vmcase(OP_LOADNIL, |
| 526 | − TValue *rb = RB(i); | |
| 551 | + int b = GETARG_B(i); | |
| 527 | 552 | do { |
| 528 | − setnilvalue(rb--); | |
| 529 | − } while (rb >= ra); | |
| 553 | + setnilvalue(ra++); | |
| 554 | + } while (b--); | |
| 530 | 555 | ) |
| 531 | 556 | vmcase(OP_GETUPVAL, |
| 532 | 557 | int b = GETARG_B(i); |
| @@ -558,7 +583,11 @@ void luaV_execute (lua_State *L) { · 25 unmodified lines | ||
| 558 | 583 | sethvalue(L, ra, t); |
| 559 | 584 | if (b != 0 || c != 0) |
| 560 | 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 | 592 | vmcase(OP_SELF, |
| 564 | 593 | StkId rb = RB(i); |
| @@ -594,7 +623,8 @@ void luaV_execute (lua_State *L) { · 29 unmodified lines | ||
| 594 | 623 | } |
| 595 | 624 | ) |
| 596 | 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 | 628 | setbvalue(ra, res); |
| 599 | 629 | ) |
| 600 | 630 | vmcase(OP_LEN, |
| @@ -603,49 +633,61 @@ void luaV_execute (lua_State *L) { · 2 unmodified lines | ||
| 603 | 633 | vmcase(OP_CONCAT, |
| 604 | 634 | int b = GETARG_B(i); |
| 605 | 635 | int c = GETARG_C(i); |
| 636 | + StkId rb; | |
| 606 | 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 | 646 | L->top = ci->top; /* restore top */ |
| 609 | − setobjs2s(L, RA(i), base+b); | |
| 610 | 647 | ) |
| 611 | 648 | vmcase(OP_JMP, |
| 612 | − dojump(GETARG_sBx(i)); | |
| 649 | + dojump(ci, i, 0); | |
| 613 | 650 | ) |
| 614 | 651 | vmcase(OP_EQ, |
| 615 | 652 | TValue *rb = RKB(i); |
| 616 | 653 | TValue *rc = RKC(i); |
| 617 | 654 | Protect( |
| 618 | − if (equalobj(L, rb, rc) == GETARG_A(i)) | |
| 619 | − dojump(GETARG_sBx(*ci->u.l.savedpc)); | |
| 655 | + if (equalobj(L, rb, rc) != GETARG_A(i)) | |
| 656 | + ci->u.l.savedpc++; | |
| 657 | + else | |
| 658 | + donextjump(ci); | |
| 620 | 659 | ) |
| 621 | − ci->u.l.savedpc++; | |
| 622 | 660 | ) |
| 623 | 661 | vmcase(OP_LT, |
| 624 | 662 | Protect( |
| 625 | − if (luaV_lessthan(L, RKB(i), RKC(i)) == GETARG_A(i)) | |
| 626 | − dojump(GETARG_sBx(*ci->u.l.savedpc)); | |
| 663 | + if (luaV_lessthan(L, RKB(i), RKC(i)) != GETARG_A(i)) | |
| 664 | + ci->u.l.savedpc++; | |
| 665 | + else | |
| 666 | + donextjump(ci); | |
| 627 | 667 | ) |
| 628 | − ci->u.l.savedpc++; | |
| 629 | 668 | ) |
| 630 | 669 | vmcase(OP_LE, |
| 631 | 670 | Protect( |
| 632 | − if (luaV_lessequal(L, RKB(i), RKC(i)) == GETARG_A(i)) | |
| 633 | − dojump(GETARG_sBx(*ci->u.l.savedpc)); | |
| 671 | + if (luaV_lessequal(L, RKB(i), RKC(i)) != GETARG_A(i)) | |
| 672 | + ci->u.l.savedpc++; | |
| 673 | + else | |
| 674 | + donextjump(ci); | |
| 634 | 675 | ) |
| 635 | − ci->u.l.savedpc++; | |
| 636 | 676 | ) |
| 637 | 677 | vmcase(OP_TEST, |
| 638 | − if (GETARG_C(i) ? !l_isfalse(ra) : l_isfalse(ra)) | |
| 639 | − dojump(GETARG_sBx(*ci->u.l.savedpc)); | |
| 640 | − ci->u.l.savedpc++; | |
| 678 | + if (GETARG_C(i) ? l_isfalse(ra) : !l_isfalse(ra)) | |
| 679 | + ci->u.l.savedpc++; | |
| 680 | + else | |
| 681 | + donextjump(ci); | |
| 641 | 682 | ) |
| 642 | 683 | vmcase(OP_TESTSET, |
| 643 | 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 | 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 | 692 | vmcase(OP_CALL, |
| 651 | 693 | int b = GETARG_B(i); |
| @@ -711,7 +753,7 @@ void luaV_execute (lua_State *L) { · 59 unmodified lines | ||
| 711 | 753 | lua_Number limit = nvalue(ra+1); |
| 712 | 754 | if (luai_numlt(L, 0, step) ? luai_numle(L, idx, limit) |
| 713 | 755 | : luai_numle(L, limit, idx)) { |
| 714 | − dojump(GETARG_sBx(i)); /* jump back */ | |
| 756 | + ci->u.l.savedpc += GETARG_sBx(i); /* jump back */ | |
| 715 | 757 | setnvalue(ra, idx); /* update internal index... */ |
| 716 | 758 | setnvalue(ra+3, idx); /* ...and external index */ |
| 717 | 759 | } |
| @@ -727,7 +769,7 @@ void luaV_execute (lua_State *L) { · 9 unmodified lines | ||
| 727 | 769 | else if (!tonumber(pstep, ra+2)) |
| 728 | 770 | luaG_runerror(L, LUA_QL("for") " step must be a number"); |
| 729 | 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 | 774 | vmcase(OP_TFORCALL, |
| 733 | 775 | StkId cb = ra + 3; /* call base */ |
| @@ -746,7 +788,7 @@ void luaV_execute (lua_State *L) { · 12 unmodified lines | ||
| 746 | 788 | l_tforloop: |
| 747 | 789 | if (!ttisnil(ra + 1)) { /* continue loop? */ |
| 748 | 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 | 794 | vmcase(OP_SETLIST, |
| @@ -759,6 +801,7 @@ void luaV_execute (lua_State *L) { · 6 unmodified lines | ||
| 759 | 801 | lua_assert(GET_OPCODE(*ci->u.l.savedpc) == OP_EXTRAARG); |
| 760 | 802 | c = GETARG_Ax(*ci->u.l.savedpc++); |
| 761 | 803 | } |
| 804 | + luai_runtimecheck(L, ttistable(ra)); | |
| 762 | 805 | h = hvalue(ra); |
| 763 | 806 | last = ((c-1)*LFIELDS_PER_FLUSH) + n; |
| 764 | 807 | if (last > h->sizearray) /* needs more space? */ |
| @@ -770,17 +813,18 @@ void luaV_execute (lua_State *L) { · 5 unmodified lines | ||
| 770 | 813 | } |
| 771 | 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 | 816 | vmcase(OP_CLOSURE, |
| 777 | 817 | Proto *p = cl->p->p[GETARG_Bx(i)]; |
| 778 | 818 | Closure *ncl = getcached(p, cl->upvals, base); /* cached closure */ |
| 779 | 819 | if (ncl == NULL) /* no match? */ |
| 780 | 820 | pushclosure(L, p, cl->upvals, base, ra); /* create a new one */ |
| 781 | 821 | else |
| 782 | − setclvalue(L, ra, ncl); /* push cashed closure */ | |
| 783 | − checkGC(L); | |
| 822 | + setclLvalue(L, ra, ncl); /* push cashed closure */ | |
| 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 | 829 | vmcase(OP_VARARG, |
| 786 | 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 | 3 | ** Lua virtual machine |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| @@ -17,12 +17,15 @@ · 11 unmodified lines | ||
| 17 | 17 | |
| 18 | 18 | #define tonumber(o,n) (ttisnumber(o) || (((o) = luaV_tonumber(o,n)) != NULL)) |
| 19 | 19 | |
| 20 | −#define equalobj(L,o1,o2) \ | |
| 21 | − (ttype(o1) == ttype(o2) && luaV_equalval_(L, o1, o2)) | |
| 20 | +#define equalobj(L,o1,o2) (ttisequal(o1, o2) && luaV_equalobj_(L, o1, o2)) | |
| 21 | + | |
| 22 | +#define luaV_rawequalobj(t1,t2) \ | |
| 23 | + (ttisequal(t1,t2) && luaV_equalobj_(NULL,t1,t2)) | |
| 22 | 24 | |
| 23 | 25 | |
| 24 | 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 | 30 | LUAI_FUNC int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r); |
| 28 | 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 | 3 | ** a generic input stream interface |
| 4 | 4 | ** See Copyright Notice in lua.h |
| 5 | 5 | */ |
| @@ -25,26 +25,14 @@ int luaZ_fill (ZIO *z) { · 19 unmodified lines | ||
| 25 | 25 | lua_unlock(L); |
| 26 | 26 | buff = z->reader(L, z->data, &size); |
| 27 | 27 | lua_lock(L); |
| 28 | − if (buff == NULL || size == 0) return EOZ; | |
| 29 | − z->n = size - 1; | |
| 28 | + if (buff == NULL || size == 0) | |
| 29 | + return EOZ; | |
| 30 | + z->n = size - 1; /* discount char being returned */ | |
| 30 | 31 | z->p = buff; |
| 31 | 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 | 36 | void luaZ_init (lua_State *L, ZIO *z, lua_Reader reader, void *data) { |
| 49 | 37 | z->L = L; |
| 50 | 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 | 46 | size_t luaZ_read (ZIO *z, void *b, size_t n) { |
| 59 | 47 | while (n) { |
| 60 | 48 | size_t m; |
| 61 | − if (luaZ_lookahead(z) == EOZ) | |
| 62 | − return n; /* return number of missing bytes */ | |
| 49 | + if (z->n == 0) { /* no bytes in buffer? */ | |
| 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 | 57 | m = (n <= z->n) ? n : z->n; /* min. between n and z->n */ |
| 64 | 58 | memcpy(b, z->p, m); |
| 65 | 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 | 3 | ** Buffered streams |
| 4 | 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 | 50 | LUAI_FUNC void luaZ_init (lua_State *L, ZIO *z, lua_Reader reader, |
| 51 | 51 | void *data); |
| 52 | 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 | 58 | struct Zio { |
| 60 | 59 | size_t n; /* bytes still unread */ |
| 61 | 60 | const char *p; /* current position in buffer */ |
| 62 | − lua_Reader reader; | |
| 61 | + lua_Reader reader; /* reader function */ | |
| 63 | 62 | void* data; /* additional data */ |
| 64 | 63 | lua_State *L; /* Lua state (for reader) */ |
| 65 | 64 | }; |