Unified · Split
| @@ -1,5 +1,5 @@ | |||
| 1 | 1 | ||
| 2 | This is Lua 5.3.0 (work1), released on 5 Jul 2013. | 2 | This is Lua 5.3.0 (work2), released on 21 Mar 2014. |
| 3 | 3 | ||
| 4 | For installation instructions, license details, and | 4 | For installation instructions, license details, and |
| 5 | further information about Lua, see doc/readme.html. | 5 | further information about Lua, see doc/readme.html. |
Binary file not shown.
| @@ -20,6 +20,10 @@ ul { · 19 unmodified lines | |||
| 20 | Lua 5.3 Reference Manual | 20 | Lua 5.3 Reference Manual |
| 21 | </H1> | 21 | </H1> |
| 22 | 22 | ||
| 23 | <P> | ||
| 24 | <IMG SRC="alert.png" ALIGN="absbottom"> | ||
| 25 | <EM>All details may change in the final version.</EM> | ||
| 26 | |||
| 23 | <P> | 27 | <P> |
| 24 | The reference manual is the official definition of the Lua language. | 28 | The reference manual is the official definition of the Lua language. |
| 25 | For a complete introduction to Lua programming, see the book | 29 | For a complete introduction to Lua programming, see the book |
| @@ -33,7 +37,7 @@ For a complete introduction to Lua programming, see the book · 7 unmodified lines | |||
| 33 | <A HREF="#index">index</A> | 37 | <A HREF="#index">index</A> |
| 34 | <HR> | 38 | <HR> |
| 35 | <SMALL> | 39 | <SMALL> |
| 36 | Copyright © 2011–2013 Lua.org, PUC-Rio. | 40 | Copyright © 2011–2014 Lua.org, PUC-Rio. |
| 37 | Freely available under the terms of the | 41 | Freely available under the terms of the |
| 38 | <A HREF="http://www.lua.org/license.html">Lua license</A>. | 42 | <A HREF="http://www.lua.org/license.html">Lua license</A>. |
| 39 | </SMALL> | 43 | </SMALL> |
| @@ -73,15 +77,16 @@ Freely available under the terms of the · 33 unmodified lines | |||
| 73 | <LI><A HREF="manual.html#3.4">3.4 – Expressions</A> | 77 | <LI><A HREF="manual.html#3.4">3.4 – Expressions</A> |
| 74 | <UL> | 78 | <UL> |
| 75 | <LI><A HREF="manual.html#3.4.1">3.4.1 – Arithmetic Operators</A> | 79 | <LI><A HREF="manual.html#3.4.1">3.4.1 – Arithmetic Operators</A> |
| 76 | <LI><A HREF="manual.html#3.4.2">3.4.2 – Coercions and Conversions</A> | 80 | <LI><A HREF="manual.html#3.4.2">3.4.2 – Bitwise Operators</A> |
| 77 | <LI><A HREF="manual.html#3.4.3">3.4.3 – Relational Operators</A> | 81 | <LI><A HREF="manual.html#3.4.3">3.4.3 – Coercions and Conversions</A> |
| 78 | <LI><A HREF="manual.html#3.4.4">3.4.4 – Logical Operators</A> | 82 | <LI><A HREF="manual.html#3.4.4">3.4.4 – Relational Operators</A> |
| 79 | <LI><A HREF="manual.html#3.4.5">3.4.5 – Concatenation</A> | 83 | <LI><A HREF="manual.html#3.4.5">3.4.5 – Logical Operators</A> |
| 80 | <LI><A HREF="manual.html#3.4.6">3.4.6 – The Length Operator</A> | 84 | <LI><A HREF="manual.html#3.4.6">3.4.6 – Concatenation</A> |
| 81 | <LI><A HREF="manual.html#3.4.7">3.4.7 – Precedence</A> | 85 | <LI><A HREF="manual.html#3.4.7">3.4.7 – The Length Operator</A> |
| 82 | <LI><A HREF="manual.html#3.4.8">3.4.8 – Table Constructors</A> | 86 | <LI><A HREF="manual.html#3.4.8">3.4.8 – Precedence</A> |
| 83 | <LI><A HREF="manual.html#3.4.9">3.4.9 – Function Calls</A> | 87 | <LI><A HREF="manual.html#3.4.9">3.4.9 – Table Constructors</A> |
| 84 | <LI><A HREF="manual.html#3.4.10">3.4.10 – Function Definitions</A> | 88 | <LI><A HREF="manual.html#3.4.10">3.4.10 – Function Calls</A> |
| 89 | <LI><A HREF="manual.html#3.4.11">3.4.11 – Function Definitions</A> | ||
| 85 | </UL> | 90 | </UL> |
| 86 | <LI><A HREF="manual.html#3.5">3.5 – Visibility Rules</A> | 91 | <LI><A HREF="manual.html#3.5">3.5 – Visibility Rules</A> |
| 87 | </UL> | 92 | </UL> |
| @@ -113,9 +118,9 @@ Freely available under the terms of the · 25 unmodified lines | |||
| 113 | <UL> | 118 | <UL> |
| 114 | <LI><A HREF="manual.html#6.4.1">6.4.1 – Patterns</A> | 119 | <LI><A HREF="manual.html#6.4.1">6.4.1 – Patterns</A> |
| 115 | </UL> | 120 | </UL> |
| 116 | <LI><A HREF="manual.html#6.5">6.5 – Table Manipulation</A> | 121 | <LI><A HREF="manual.html#6.5">6.5 – UTF-8 Support</A> |
| 117 | <LI><A HREF="manual.html#6.6">6.6 – Mathematical Functions</A> | 122 | <LI><A HREF="manual.html#6.6">6.6 – Table Manipulation</A> |
| 118 | <LI><A HREF="manual.html#6.7">6.7 – Bitwise Operations</A> | 123 | <LI><A HREF="manual.html#6.7">6.7 – Mathematical Functions</A> |
| 119 | <LI><A HREF="manual.html#6.8">6.8 – Input and Output Facilities</A> | 124 | <LI><A HREF="manual.html#6.8">6.8 – Input and Output Facilities</A> |
| 120 | <LI><A HREF="manual.html#6.9">6.9 – Operating System Facilities</A> | 125 | <LI><A HREF="manual.html#6.9">6.9 – Operating System Facilities</A> |
| 121 | <LI><A HREF="manual.html#6.10">6.10 – The Debug Library</A> | 126 | <LI><A HREF="manual.html#6.10">6.10 – The Debug Library</A> |
| @@ -167,20 +172,6 @@ Freely available under the terms of the · 45 unmodified lines | |||
| 167 | <A HREF="manual.html#pdf-type">type</A><BR> | 172 | <A HREF="manual.html#pdf-type">type</A><BR> |
| 168 | <A HREF="manual.html#pdf-xpcall">xpcall</A><BR> | 173 | <A HREF="manual.html#pdf-xpcall">xpcall</A><BR> |
| 169 | 174 | ||
| 170 | <P> | ||
| 171 | <A HREF="manual.html#pdf-bit32.arshift">bit32.arshift</A><BR> | ||
| 172 | <A HREF="manual.html#pdf-bit32.band">bit32.band</A><BR> | ||
| 173 | <A HREF="manual.html#pdf-bit32.bnot">bit32.bnot</A><BR> | ||
| 174 | <A HREF="manual.html#pdf-bit32.bor">bit32.bor</A><BR> | ||
| 175 | <A HREF="manual.html#pdf-bit32.btest">bit32.btest</A><BR> | ||
| 176 | <A HREF="manual.html#pdf-bit32.bxor">bit32.bxor</A><BR> | ||
| 177 | <A HREF="manual.html#pdf-bit32.extract">bit32.extract</A><BR> | ||
| 178 | <A HREF="manual.html#pdf-bit32.lrotate">bit32.lrotate</A><BR> | ||
| 179 | <A HREF="manual.html#pdf-bit32.lshift">bit32.lshift</A><BR> | ||
| 180 | <A HREF="manual.html#pdf-bit32.replace">bit32.replace</A><BR> | ||
| 181 | <A HREF="manual.html#pdf-bit32.rrotate">bit32.rrotate</A><BR> | ||
| 182 | <A HREF="manual.html#pdf-bit32.rshift">bit32.rshift</A><BR> | ||
| 183 | |||
| 184 | <P> | 175 | <P> |
| 185 | <A HREF="manual.html#pdf-coroutine.create">coroutine.create</A><BR> | 176 | <A HREF="manual.html#pdf-coroutine.create">coroutine.create</A><BR> |
| 186 | <A HREF="manual.html#pdf-coroutine.resume">coroutine.resume</A><BR> | 177 | <A HREF="manual.html#pdf-coroutine.resume">coroutine.resume</A><BR> |
| @@ -191,18 +182,19 @@ Freely available under the terms of the · 4 unmodified lines | |||
| 191 | 182 | ||
| 192 | <P> | 183 | <P> |
| 193 | <A HREF="manual.html#pdf-debug.debug">debug.debug</A><BR> | 184 | <A HREF="manual.html#pdf-debug.debug">debug.debug</A><BR> |
| 194 | <A HREF="manual.html#pdf-debug.getuservalue">debug.getuservalue</A><BR> | ||
| 195 | <A HREF="manual.html#pdf-debug.gethook">debug.gethook</A><BR> | 185 | <A HREF="manual.html#pdf-debug.gethook">debug.gethook</A><BR> |
| 196 | <A HREF="manual.html#pdf-debug.getinfo">debug.getinfo</A><BR> | 186 | <A HREF="manual.html#pdf-debug.getinfo">debug.getinfo</A><BR> |
| 197 | <A HREF="manual.html#pdf-debug.getlocal">debug.getlocal</A><BR> | 187 | <A HREF="manual.html#pdf-debug.getlocal">debug.getlocal</A><BR> |
| 198 | <A HREF="manual.html#pdf-debug.getmetatable">debug.getmetatable</A><BR> | 188 | <A HREF="manual.html#pdf-debug.getmetatable">debug.getmetatable</A><BR> |
| 199 | <A HREF="manual.html#pdf-debug.getregistry">debug.getregistry</A><BR> | 189 | <A HREF="manual.html#pdf-debug.getregistry">debug.getregistry</A><BR> |
| 200 | <A HREF="manual.html#pdf-debug.getupvalue">debug.getupvalue</A><BR> | 190 | <A HREF="manual.html#pdf-debug.getupvalue">debug.getupvalue</A><BR> |
| 201 | <A HREF="manual.html#pdf-debug.setuservalue">debug.setuservalue</A><BR> | 191 | <A HREF="manual.html#pdf-debug.getuservalue">debug.getuservalue</A><BR> |
| 192 | <A HREF="manual.html#pdf-debug.numbits">debug.numbits</A><BR> | ||
| 202 | <A HREF="manual.html#pdf-debug.sethook">debug.sethook</A><BR> | 193 | <A HREF="manual.html#pdf-debug.sethook">debug.sethook</A><BR> |
| 203 | <A HREF="manual.html#pdf-debug.setlocal">debug.setlocal</A><BR> | 194 | <A HREF="manual.html#pdf-debug.setlocal">debug.setlocal</A><BR> |
| 204 | <A HREF="manual.html#pdf-debug.setmetatable">debug.setmetatable</A><BR> | 195 | <A HREF="manual.html#pdf-debug.setmetatable">debug.setmetatable</A><BR> |
| 205 | <A HREF="manual.html#pdf-debug.setupvalue">debug.setupvalue</A><BR> | 196 | <A HREF="manual.html#pdf-debug.setupvalue">debug.setupvalue</A><BR> |
| 197 | <A HREF="manual.html#pdf-debug.setuservalue">debug.setuservalue</A><BR> | ||
| 206 | <A HREF="manual.html#pdf-debug.traceback">debug.traceback</A><BR> | 198 | <A HREF="manual.html#pdf-debug.traceback">debug.traceback</A><BR> |
| 207 | <A HREF="manual.html#pdf-debug.upvalueid">debug.upvalueid</A><BR> | 199 | <A HREF="manual.html#pdf-debug.upvalueid">debug.upvalueid</A><BR> |
| 208 | <A HREF="manual.html#pdf-debug.upvaluejoin">debug.upvaluejoin</A><BR> | 200 | <A HREF="manual.html#pdf-debug.upvaluejoin">debug.upvaluejoin</A><BR> |
| @@ -267,6 +259,8 @@ Freely available under the terms of the · 58 unmodified lines | |||
| 267 | <A HREF="manual.html#pdf-math.sqrt">math.sqrt</A><BR> | 259 | <A HREF="manual.html#pdf-math.sqrt">math.sqrt</A><BR> |
| 268 | <A HREF="manual.html#pdf-math.tan">math.tan</A><BR> | 260 | <A HREF="manual.html#pdf-math.tan">math.tan</A><BR> |
| 269 | <A HREF="manual.html#pdf-math.tanh">math.tanh</A><BR> | 261 | <A HREF="manual.html#pdf-math.tanh">math.tanh</A><BR> |
| 262 | <A HREF="manual.html#pdf-math.type">math.type</A><BR> | ||
| 263 | |||
| 270 | 264 | ||
| 271 | <P> | 265 | <P> |
| 272 | <A HREF="manual.html#pdf-os.clock">os.clock</A><BR> | 266 | <A HREF="manual.html#pdf-os.clock">os.clock</A><BR> |
| @@ -302,9 +296,13 @@ Freely available under the terms of the · 29 unmodified lines | |||
| 302 | <A HREF="manual.html#pdf-string.len">string.len</A><BR> | 296 | <A HREF="manual.html#pdf-string.len">string.len</A><BR> |
| 303 | <A HREF="manual.html#pdf-string.lower">string.lower</A><BR> | 297 | <A HREF="manual.html#pdf-string.lower">string.lower</A><BR> |
| 304 | <A HREF="manual.html#pdf-string.match">string.match</A><BR> | 298 | <A HREF="manual.html#pdf-string.match">string.match</A><BR> |
| 299 | <A HREF="manual.html#pdf-string.packfloat">string.packfloat</A><BR> | ||
| 300 | <A HREF="manual.html#pdf-string.packint">string.packint</A><BR> | ||
| 305 | <A HREF="manual.html#pdf-string.rep">string.rep</A><BR> | 301 | <A HREF="manual.html#pdf-string.rep">string.rep</A><BR> |
| 306 | <A HREF="manual.html#pdf-string.reverse">string.reverse</A><BR> | 302 | <A HREF="manual.html#pdf-string.reverse">string.reverse</A><BR> |
| 307 | <A HREF="manual.html#pdf-string.sub">string.sub</A><BR> | 303 | <A HREF="manual.html#pdf-string.sub">string.sub</A><BR> |
| 304 | <A HREF="manual.html#pdf-string.unpackfloat">string.unpackfloat</A><BR> | ||
| 305 | <A HREF="manual.html#pdf-string.unpackint">string.unpackint</A><BR> | ||
| 308 | <A HREF="manual.html#pdf-string.upper">string.upper</A><BR> | 306 | <A HREF="manual.html#pdf-string.upper">string.upper</A><BR> |
| 309 | 307 | ||
| 310 | <P> | 308 | <P> |
| @@ -315,6 +313,14 @@ Freely available under the terms of the · 4 unmodified lines | |||
| 315 | <A HREF="manual.html#pdf-table.sort">table.sort</A><BR> | 313 | <A HREF="manual.html#pdf-table.sort">table.sort</A><BR> |
| 316 | <A HREF="manual.html#pdf-table.unpack">table.unpack</A><BR> | 314 | <A HREF="manual.html#pdf-table.unpack">table.unpack</A><BR> |
| 317 | 315 | ||
| 316 | <P> | ||
| 317 | <A HREF="manual.html#pdf-utf8.char">utf8.char</A><BR> | ||
| 318 | <A HREF="manual.html#pdf-utf8.charpatt">utf8.charpatt</A><BR> | ||
| 319 | <A HREF="manual.html#pdf-utf8.codepoint">utf8.codepoint</A><BR> | ||
| 320 | <A HREF="manual.html#pdf-utf8.codes">utf8.codes</A><BR> | ||
| 321 | <A HREF="manual.html#pdf-utf8.len">utf8.len</A><BR> | ||
| 322 | <A HREF="manual.html#pdf-utf8.offset">utf8.offset</A><BR> | ||
| 323 | |||
| 318 | </TD> | 324 | </TD> |
| 319 | <TD> | 325 | <TD> |
| 320 | <H3>C API</H3> | 326 | <H3>C API</H3> |
| @@ -364,6 +370,7 @@ Freely available under the terms of the · 43 unmodified lines | |||
| 364 | <A HREF="manual.html#lua_isboolean">lua_isboolean</A><BR> | 370 | <A HREF="manual.html#lua_isboolean">lua_isboolean</A><BR> |
| 365 | <A HREF="manual.html#lua_iscfunction">lua_iscfunction</A><BR> | 371 | <A HREF="manual.html#lua_iscfunction">lua_iscfunction</A><BR> |
| 366 | <A HREF="manual.html#lua_isfunction">lua_isfunction</A><BR> | 372 | <A HREF="manual.html#lua_isfunction">lua_isfunction</A><BR> |
| 373 | <A HREF="manual.html#lua_isinteger">lua_isinteger</A><BR> | ||
| 367 | <A HREF="manual.html#lua_islightuserdata">lua_islightuserdata</A><BR> | 374 | <A HREF="manual.html#lua_islightuserdata">lua_islightuserdata</A><BR> |
| 368 | <A HREF="manual.html#lua_isnil">lua_isnil</A><BR> | 375 | <A HREF="manual.html#lua_isnil">lua_isnil</A><BR> |
| 369 | <A HREF="manual.html#lua_isnone">lua_isnone</A><BR> | 376 | <A HREF="manual.html#lua_isnone">lua_isnone</A><BR> |
| @@ -422,6 +429,7 @@ Freely available under the terms of the · 52 unmodified lines | |||
| 422 | <A HREF="manual.html#lua_setupvalue">lua_setupvalue</A><BR> | 429 | <A HREF="manual.html#lua_setupvalue">lua_setupvalue</A><BR> |
| 423 | <A HREF="manual.html#lua_setuservalue">lua_setuservalue</A><BR> | 430 | <A HREF="manual.html#lua_setuservalue">lua_setuservalue</A><BR> |
| 424 | <A HREF="manual.html#lua_status">lua_status</A><BR> | 431 | <A HREF="manual.html#lua_status">lua_status</A><BR> |
| 432 | <A HREF="manual.html#lua_strtonum">lua_strtonum</A><BR> | ||
| 425 | <A HREF="manual.html#lua_toboolean">lua_toboolean</A><BR> | 433 | <A HREF="manual.html#lua_toboolean">lua_toboolean</A><BR> |
| 426 | <A HREF="manual.html#lua_tocfunction">lua_tocfunction</A><BR> | 434 | <A HREF="manual.html#lua_tocfunction">lua_tocfunction</A><BR> |
| 427 | <A HREF="manual.html#lua_tointeger">lua_tointeger</A><BR> | 435 | <A HREF="manual.html#lua_tointeger">lua_tointeger</A><BR> |
| @@ -451,6 +459,7 @@ Freely available under the terms of the · 23 unmodified lines | |||
| 451 | <P> | 459 | <P> |
| 452 | <A HREF="manual.html#luaL_Buffer">luaL_Buffer</A><BR> | 460 | <A HREF="manual.html#luaL_Buffer">luaL_Buffer</A><BR> |
| 453 | <A HREF="manual.html#luaL_Reg">luaL_Reg</A><BR> | 461 | <A HREF="manual.html#luaL_Reg">luaL_Reg</A><BR> |
| 462 | <A HREF="manual.html#luaL_Stream">luaL_Stream</A><BR> | ||
| 454 | 463 | ||
| 455 | <P> | 464 | <P> |
| 456 | <A HREF="manual.html#luaL_addchar">luaL_addchar</A><BR> | 465 | <A HREF="manual.html#luaL_addchar">luaL_addchar</A><BR> |
| @@ -525,10 +534,10 @@ Freely available under the terms of the · 68 unmodified lines | |||
| 525 | <HR> | 534 | <HR> |
| 526 | <SMALL CLASS="footer"> | 535 | <SMALL CLASS="footer"> |
| 527 | Last update: | 536 | Last update: |
| 528 | Fri Jul 5 23:06:54 BRT 2013 | 537 | Fri Mar 21 17:34:12 BRT 2014 |
| 529 | </SMALL> | 538 | </SMALL> |
| 530 | <!-- | 539 | <!-- |
| 531 | Last change: updated for Lua 5.3.0 (work1) | 540 | Last change: updated for Lua 5.3.0 (work2) |
| 532 | --> | 541 | --> |
| 533 | 542 | ||
| 534 | </BODY> | 543 | </BODY> |
| @@ -1,30 +1,37 @@ | |||
| 1 | html { | ||
| 2 | background-color: #F8F8F8 ; | ||
| 3 | } | ||
| 4 | |||
| 1 | body { | 5 | body { |
| 6 | border: solid #a0a0a0 1px ; | ||
| 7 | border-radius: 20px ; | ||
| 8 | padding: 26px ; | ||
| 9 | margin: 16px ; | ||
| 2 | color: #000000 ; | 10 | color: #000000 ; |
| 3 | background-color: #FFFFFF ; | 11 | background-color: #FFFFFF ; |
| 4 | font-family: Helvetica, Arial, sans-serif ; | 12 | font-family: Helvetica, Arial, sans-serif ; |
| 5 | text-align: justify ; | 13 | text-align: justify ; |
| 6 | margin-right: 30px ; | ||
| 7 | margin-left: 30px ; | ||
| 8 | } | 14 | } |
| 9 | 15 | ||
| 10 | h1, h2, h3, h4 { | 16 | h1, h2, h3, h4 { |
| 11 | font-family: Verdana, Geneva, sans-serif ; | 17 | font-family: Verdana, Geneva, sans-serif ; |
| 12 | font-weight: normal ; | 18 | font-weight: normal ; |
| 13 | font-style: italic ; | 19 | font-style: normal ; |
| 14 | } | 20 | } |
| 15 | 21 | ||
| 16 | h2 { | 22 | h2 { |
| 17 | padding-top: 0.4em ; | 23 | padding-top: 0.4em ; |
| 18 | padding-bottom: 0.4em ; | 24 | padding-bottom: 0.4em ; |
| 19 | padding-left: 1em ; | 25 | padding-left: 0.8em ; |
| 20 | padding-right: 1em ; | 26 | padding-right: 0.8em ; |
| 21 | background-color: #E0E0FF ; | 27 | background-color: #D0D0FF ; |
| 22 | border-radius: 8px ; | 28 | border-radius: 8px ; |
| 29 | border: solid #a0a0a0 1px ; | ||
| 23 | } | 30 | } |
| 24 | 31 | ||
| 25 | h3 { | 32 | h3 { |
| 26 | padding-left: 0.5em ; | 33 | padding-left: 0.5em ; |
| 27 | border-left: solid #E0E0FF 1em ; | 34 | border-left: solid #D0D0FF 1em ; |
| 28 | } | 35 | } |
| 29 | 36 | ||
| 30 | table h3 { | 37 | table h3 { |
| @@ -45,7 +52,7 @@ a:visited { · 14 unmodified lines | |||
| 45 | 52 | ||
| 46 | a:link:hover, a:visited:hover { | 53 | a:link:hover, a:visited:hover { |
| 47 | color: #000080 ; | 54 | color: #000080 ; |
| 48 | background-color: #E0E0FF ; | 55 | background-color: #D0D0FF ; |
| 49 | } | 56 | } |
| 50 | 57 | ||
| 51 | a:link:active, a:visited:active { | 58 | a:link:active, a:visited:active { |
| @@ -57,17 +64,23 @@ hr { · 5 unmodified lines | |||
| 57 | height: 1px ; | 64 | height: 1px ; |
| 58 | color: #a0a0a0 ; | 65 | color: #a0a0a0 ; |
| 59 | background-color: #a0a0a0 ; | 66 | background-color: #a0a0a0 ; |
| 67 | display: none ; | ||
| 68 | } | ||
| 69 | |||
| 70 | table hr { | ||
| 71 | display: block ; | ||
| 60 | } | 72 | } |
| 61 | 73 | ||
| 62 | :target { | 74 | :target { |
| 63 | background-color: #F8F8F8 ; | 75 | background-color: #F8F8F8 ; |
| 64 | padding: 8px ; | 76 | padding: 8px ; |
| 65 | border: solid #a0a0a0 2px ; | 77 | border: solid #a0a0a0 2px ; |
| 78 | border-radius: 8px ; | ||
| 66 | } | 79 | } |
| 67 | 80 | ||
| 68 | .footer { | 81 | .footer { |
| 69 | color: gray ; | 82 | color: gray ; |
| 70 | font-size: small ; | 83 | font-size: x-small ; |
| 71 | } | 84 | } |
| 72 | 85 | ||
| 73 | input[type=text] { | 86 | input[type=text] { |
| @@ -16,11 +16,12 @@ span.apii { · 15 unmodified lines | |||
| 16 | } | 16 | } |
| 17 | 17 | ||
| 18 | p+h1, ul+h1 { | 18 | p+h1, ul+h1 { |
| 19 | font-style: normal ; | ||
| 19 | padding-top: 0.4em ; | 20 | padding-top: 0.4em ; |
| 20 | padding-bottom: 0.4em ; | 21 | padding-bottom: 0.4em ; |
| 21 | padding-left: 24px ; | 22 | padding-left: 16px ; |
| 22 | margin-left: -24px ; | 23 | margin-left: -16px ; |
| 23 | background-color: #E0E0FF ; | 24 | background-color: #D0D0FF ; |
| 24 | border-radius: 8px ; | 25 | border-radius: 8px ; |
| 26 | border: solid #000080 1px ; | ||
| 25 | } | 27 | } |
| 26 | |||
| @@ -16,10 +16,15 @@ · 15 unmodified lines | |||
| 16 | Lua 5.3 Reference Manual | 16 | Lua 5.3 Reference Manual |
| 17 | </h1> | 17 | </h1> |
| 18 | 18 | ||
| 19 | <P> | ||
| 20 | <IMG SRC="alert.png" ALIGN="absbottom"> | ||
| 21 | <EM>All details may change in the final version.</EM> | ||
| 22 | <P> | ||
| 23 | |||
| 19 | by Roberto Ierusalimschy, Luiz Henrique de Figueiredo, Waldemar Celes | 24 | by Roberto Ierusalimschy, Luiz Henrique de Figueiredo, Waldemar Celes |
| 20 | <p> | 25 | <p> |
| 21 | <small> | 26 | <small> |
| 22 | Copyright © 2011–2013 Lua.org, PUC-Rio. | 27 | Copyright © 2011–2014 Lua.org, PUC-Rio. |
| 23 | Freely available under the terms of the | 28 | Freely available under the terms of the |
| 24 | <a href="http://www.lua.org/license.html">Lua license</a>. | 29 | <a href="http://www.lua.org/license.html">Lua license</a>. |
| 25 | </small> | 30 | </small> |
| @@ -33,7 +38,7 @@ Freely available under the terms of the · 7 unmodified lines | |||
| 33 | <!-- ====================================================================== --> | 38 | <!-- ====================================================================== --> |
| 34 | <p> | 39 | <p> |
| 35 | 40 | ||
| 36 | <!-- $Id: manual.of,v 1.105 2013/07/05 18:48:52 roberto Exp $ --> | 41 | <!-- $Id: manual.of,v 1.114 2014/03/21 18:32:52 roberto Exp $ --> |
| 37 | 42 | ||
| 38 | 43 | ||
| 39 | 44 | ||
| @@ -119,11 +124,8 @@ it usually represents the absence of a useful value. · 79 unmodified lines | |||
| 119 | <em>Boolean</em> is the type of the values <b>false</b> and <b>true</b>. | 124 | <em>Boolean</em> is the type of the values <b>false</b> and <b>true</b>. |
| 120 | Both <b>nil</b> and <b>false</b> make a condition false; | 125 | Both <b>nil</b> and <b>false</b> make a condition false; |
| 121 | any other value makes it true. | 126 | any other value makes it true. |
| 122 | <em>Number</em> represents both integer numbers and | 127 | <em>Number</em> represents both |
| 123 | real (floating-point) numbers. | 128 | integral numbers and real (floating-point) numbers. |
| 124 | Standard Lua uses 64-bit integers and double-precision floats, | ||
| 125 | but it is easy to compile Lua so that it | ||
| 126 | uses 32-bit integers and single-precision floats. | ||
| 127 | <em>String</em> represents immutable sequences of bytes. | 129 | <em>String</em> represents immutable sequences of bytes. |
| 128 | 130 | ||
| 129 | Lua is 8-bit clean: | 131 | Lua is 8-bit clean: |
| @@ -131,10 +133,27 @@ strings can contain any 8-bit value, · 1 unmodified line | |||
| 131 | including embedded zeros ('<code>\0</code>'). | 133 | including embedded zeros ('<code>\0</code>'). |
| 132 | 134 | ||
| 133 | 135 | ||
| 136 | <p> | ||
| 137 | The type <em>number</em> uses two internal representations, | ||
| 138 | one called <em>integer</em> and the other called <em>float</em>. | ||
| 139 | Lua has explicit rules about when each representation is used, | ||
| 140 | but it also converts between them automatically as needed (see <a href="#3.4.3">§3.4.3</a>). | ||
| 141 | Therefore, | ||
| 142 | the programmer has the option of mostly ignore the difference | ||
| 143 | between integers and floats | ||
| 144 | or assume complete control about the representation of each value. | ||
| 145 | Standard Lua uses 64-bit integers and double-precision (64-bit) floats, | ||
| 146 | but you can also compile Lua so that it | ||
| 147 | uses 32-bit integers and/or single-precision (32-bit) floats. | ||
| 148 | The option with 32 bits both for integers and floats | ||
| 149 | (what is called <em>Small Lua</em>) is particularly attractive | ||
| 150 | for small machines. | ||
| 151 | |||
| 152 | |||
| 134 | <p> | 153 | <p> |
| 135 | Lua can call (and manipulate) functions written in Lua and | 154 | Lua can call (and manipulate) functions written in Lua and |
| 136 | functions written in C | 155 | functions written in C |
| 137 | (see <a href="#3.4.9">§3.4.9</a>). | 156 | (see <a href="#3.4.10">§3.4.10</a>). |
| 138 | 157 | ||
| 139 | 158 | ||
| 140 | <p> | 159 | <p> |
| @@ -183,14 +202,14 @@ To represent records, Lua uses the field name as an index. · 42 unmodified lines | |||
| 183 | The language supports this representation by | 202 | The language supports this representation by |
| 184 | providing <code>a.name</code> as syntactic sugar for <code>a["name"]</code>. | 203 | providing <code>a.name</code> as syntactic sugar for <code>a["name"]</code>. |
| 185 | There are several convenient ways to create tables in Lua | 204 | There are several convenient ways to create tables in Lua |
| 186 | (see <a href="#3.4.8">§3.4.8</a>). | 205 | (see <a href="#3.4.9">§3.4.9</a>). |
| 187 | 206 | ||
| 188 | 207 | ||
| 189 | <p> | 208 | <p> |
| 190 | We use the term <em>sequence</em> to denote a table where | 209 | We use the term <em>sequence</em> to denote a table where |
| 191 | the set of all positive numeric keys is equal to <em>{1..n}</em> | 210 | the set of all positive numeric keys is equal to <em>{1..n}</em> |
| 192 | for some integer <em>n</em>, | 211 | for some integer <em>n</em>, |
| 193 | which is called the length of the sequence (see <a href="#3.4.6">§3.4.6</a>). | 212 | which is called the length of the sequence (see <a href="#3.4.7">§3.4.7</a>). |
| 194 | 213 | ||
| 195 | 214 | ||
| 196 | <p> | 215 | <p> |
| @@ -199,7 +218,7 @@ the values of table fields can be of any type. · 2 unmodified lines | |||
| 199 | In particular, | 218 | In particular, |
| 200 | because functions are first-class values, | 219 | because functions are first-class values, |
| 201 | table fields can contain functions. | 220 | table fields can contain functions. |
| 202 | Thus tables can also carry <em>methods</em> (see <a href="#3.4.10">§3.4.10</a>). | 221 | Thus tables can also carry <em>methods</em> (see <a href="#3.4.11">§3.4.11</a>). |
| 203 | 222 | ||
| 204 | 223 | ||
| 205 | <p> | 224 | <p> |
| @@ -211,6 +230,18 @@ if and only if <code>i</code> and <code>j</code> are raw equal · 5 unmodified lines | |||
| 211 | (that is, equal without metamethods). | 230 | (that is, equal without metamethods). |
| 212 | 231 | ||
| 213 | 232 | ||
| 233 | <p> | ||
| 234 | In particular, floats with integral values | ||
| 235 | are equal to their respective integers | ||
| 236 | (e.g., <code>1.0 == 1</code>). | ||
| 237 | To avoid ambiguities, | ||
| 238 | any float with integral value used as a key | ||
| 239 | is converted to its respective integer. | ||
| 240 | For instance, if you write <code>a[2.0] = true</code>, | ||
| 241 | the actual key inserted into the table will be the | ||
| 242 | integer <code>2</code>. | ||
| 243 | |||
| 244 | |||
| 214 | <p> | 245 | <p> |
| 215 | Tables, functions, threads, and (full) userdata values are <em>objects</em>: | 246 | Tables, functions, threads, and (full) userdata values are <em>objects</em>: |
| 216 | variables do not actually <em>contain</em> these values, | 247 | variables do not actually <em>contain</em> these values, |
| @@ -382,57 +413,37 @@ but the string library sets a metatable for the string type (see <a href="#6.4"> · 165 unmodified lines | |||
| 382 | 413 | ||
| 383 | 414 | ||
| 384 | <p> | 415 | <p> |
| 385 | A metatable controls how an object behaves in arithmetic operations, | 416 | A metatable controls how an object behaves in |
| 386 | order comparisons, concatenation, length operation, and indexing. | 417 | arithmetic and bitwise operations, |
| 418 | order comparisons, concatenation, length operation, calls, and indexing. | ||
| 387 | A metatable also can define a function to be called | 419 | A metatable also can define a function to be called |
| 388 | when a userdata or a table is garbage collected. | 420 | when a userdata or a table is garbage collected. |
| 389 | When Lua performs one of these operations over a value, | ||
| 390 | it checks whether this value has a metatable with the corresponding event. | ||
| 391 | If so, the value associated with that key (the metamethod) | ||
| 392 | controls how Lua will perform the operation. | ||
| 393 | 421 | ||
| 394 | 422 | ||
| 395 | <p> | 423 | <p> |
| 396 | Metatables control the operations listed next. | 424 | A detailed list of events controlled by metatables is given next. |
| 397 | Each operation is identified by its corresponding name. | 425 | Each operation is identified by its corresponding event name. |
| 398 | The key for each operation is a string with its name prefixed by | 426 | The key for each event is a string with its name prefixed by |
| 399 | two underscores, '<code>__</code>'; | 427 | two underscores, '<code>__</code>'; |
| 400 | for instance, the key for operation "add" is the | 428 | for instance, the key for operation "add" is the |
| 401 | string "<code>__add</code>". | 429 | string "<code>__add</code>". |
| 402 | 430 | Note that queries for metamethods are always raw; | |
| 403 | 431 | the access to a metamethod does not invoke other metamethods. | |
| 404 | <p> | 432 | You can emulate how Lua queries a metamethod for an object <code>obj</code> |
| 405 | The semantics of these operations is better explained by a Lua function | 433 | with the following code: |
| 406 | describing how the interpreter executes the operation. | ||
| 407 | The code shown here in Lua is only illustrative; | ||
| 408 | the real behavior is hard coded in the interpreter | ||
| 409 | and it is much more efficient than this simulation. | ||
| 410 | All functions used in these descriptions | ||
| 411 | (<a href="#pdf-rawget"><code>rawget</code></a>, <a href="#pdf-tonumber"><code>tonumber</code></a>, etc.) | ||
| 412 | are described in <a href="#6.1">§6.1</a>. | ||
| 413 | In particular, to retrieve the metamethod of a given object, | ||
| 414 | we use the expression | ||
| 415 | |||
| 416 | <pre> | ||
| 417 | metatable(obj)[event] | ||
| 418 | </pre><p> | ||
| 419 | This should be read as | ||
| 420 | 434 | ||
| 421 | <pre> | 435 | <pre> |
| 422 | rawget(getmetatable(obj) or {}, event) | 436 | rawget(getmetatable(obj) or {}, event_name) |
| 423 | </pre><p> | 437 | </pre> |
| 424 | This means that the access to a metamethod does not invoke other metamethods, | ||
| 425 | and access to objects with no metatables does not fail | ||
| 426 | (it simply results in <b>nil</b>). | ||
| 427 | |||
| 428 | 438 | ||
| 429 | <p> | 439 | <p> |
| 430 | For the unary <code>-</code> and <code>#</code> operators, | 440 | For the unary minus and the bitwise not operators, |
| 431 | the metamethod is called with a dummy second argument. | 441 | the metamethod is computed and called with a dummy second operand, |
| 432 | This extra argument is only to simplify Lua's internals; | 442 | equal to the first one. |
| 433 | it may be removed in future versions and therefore it is not present | 443 | This extra operand is only to simplify Lua's internals |
| 434 | in the following code. | 444 | (by making these operators behave like a binary operation) |
| 435 | (For most uses this extra argument is irrelevant.) | 445 | and may be removed in future versions. |
| 446 | (For most uses this extra operand is irrelevant.) | ||
| 436 | 447 | ||
| 437 | 448 | ||
| 438 | 449 | ||
| @@ -441,39 +452,19 @@ in the following code. · 2 unmodified lines | |||
| 441 | <li><b>"add": </b> | 452 | <li><b>"add": </b> |
| 442 | the <code>+</code> operation. | 453 | the <code>+</code> operation. |
| 443 | 454 | ||
| 444 | 455 | If any operand for an addition is not a number | |
| 445 | 456 | (nor a string coercible to a number), | |
| 446 | <p> | 457 | Lua will try to call a metamethod. |
| 447 | The function <code>getbinhandler</code> below defines how Lua chooses a handler | 458 | First, Lua will check the first operand (even if it is valid). |
| 448 | for a binary operation. | 459 | If that operand does not define a metamethod for the "<code>__add</code>" event, |
| 449 | First, Lua tries the first operand. | 460 | then Lua will check the second operand. |
| 450 | If its type does not define a handler for the operation, | 461 | If Lua cannot find a metamethod, |
| 451 | then Lua tries the second operand. | 462 | it raises an error. |
| 452 | 463 | Otherwise, | |
| 453 | <pre> | 464 | it calls the metamethod with the two operands as arguments, |
| 454 | function getbinhandler (op1, op2, event) | 465 | and the result of the call |
| 455 | return metatable(op1)[event] or metatable(op2)[event] | 466 | (adjusted to one value) |
| 456 | end | 467 | is the result of the operation. |
| 457 | </pre><p> | ||
| 458 | By using this function, | ||
| 459 | the behavior of the <code>op1 + op2</code> is | ||
| 460 | |||
| 461 | <pre> | ||
| 462 | function add_event (op1, op2) | ||
| 463 | local o1, o2 = tonumber(op1), tonumber(op2) | ||
| 464 | if o1 and o2 then -- both operands are numeric? | ||
| 465 | return o1 + o2 -- '+' here is the primitive 'add' | ||
| 466 | else -- at least one of the operands is not numeric | ||
| 467 | local h = getbinhandler(op1, op2, "__add") | ||
| 468 | if h then | ||
| 469 | -- call the handler with both operands | ||
| 470 | return (h(op1, op2)) | ||
| 471 | else -- no handler available: default behavior | ||
| 472 | error(···) | ||
| 473 | end | ||
| 474 | end | ||
| 475 | end | ||
| 476 | </pre><p> | ||
| 477 | </li> | 468 | </li> |
| 478 | 469 | ||
| 479 | <li><b>"sub": </b> | 470 | <li><b>"sub": </b> |
| @@ -497,263 +488,177 @@ Behavior similar to the "add" operation. · 17 unmodified lines | |||
| 497 | <li><b>"mod": </b> | 488 | <li><b>"mod": </b> |
| 498 | the <code>%</code> operation. | 489 | the <code>%</code> operation. |
| 499 | 490 | ||
| 500 | Behavior similar to the "add" operation, | 491 | Behavior similar to the "add" operation. |
| 501 | with the operation | ||
| 502 | <code>o1 - floor(o1/o2)*o2</code> as the primitive operation. | ||
| 503 | </li> | 492 | </li> |
| 504 | 493 | ||
| 505 | <li><b>"pow": </b> | 494 | <li><b>"pow": </b> |
| 506 | the <code>^</code> (exponentiation) operation. | 495 | the <code>^</code> (exponentiation) operation. |
| 507 | 496 | ||
| 508 | Behavior similar to the "add" operation, | 497 | Behavior similar to the "add" operation. |
| 509 | with the function <code>pow</code> (from the C math library) | ||
| 510 | as the primitive operation. | ||
| 511 | </li> | 498 | </li> |
| 512 | 499 | ||
| 513 | <li><b>"unm": </b> | 500 | <li><b>"unm": </b> |
| 514 | the unary <code>-</code> operation. | 501 | the <code>-</code> (unary minus) operation. |
| 515 | 502 | ||
| 503 | Behavior similar to the "add" operation. | ||
| 504 | </li> | ||
| 516 | 505 | ||
| 517 | <pre> | 506 | <li><b>"idiv": </b> |
| 518 | function unm_event (op) | 507 | the <code>//</code> (integer division) operation. |
| 519 | local o = tonumber(op) | 508 | |
| 520 | if o then -- operand is numeric? | 509 | Behavior similar to the "add" operation, |
| 521 | return -o -- '-' here is the primitive 'unm' | 510 | except that Lua will try a metamethod |
| 522 | else -- the operand is not numeric. | 511 | if any operator is neither an integer |
| 523 | -- Try to get a handler from the operand | 512 | nor a value coercible to an integer (see <a href="#3.4.3">§3.4.3</a>). |
| 524 | local h = metatable(op).__unm | ||
| 525 | if h then | ||
| 526 | -- call the handler with the operand | ||
| 527 | return (h(op)) | ||
| 528 | else -- no handler available: default behavior | ||
| 529 | error(···) | ||
| 530 | end | ||
| 531 | end | ||
| 532 | end | ||
| 533 | </pre><p> | ||
| 534 | </li> | 513 | </li> |
| 535 | 514 | ||
| 536 | <li><b>"concat": </b> | 515 | <li><b>"band": </b> |
| 537 | the <code>..</code> (concatenation) operation. | 516 | the <code>&</code> (bitwise and) operation. |
| 538 | 517 | ||
| 518 | Behavior similar to the "idiv" operation. | ||
| 519 | </li> | ||
| 539 | 520 | ||
| 540 | <pre> | 521 | <li><b>"bor": </b> |
| 541 | function concat_event (op1, op2) | 522 | the <code>|</code> (bitwise or) operation. |
| 542 | if (type(op1) == "string" or type(op1) == "number") and | 523 | |
| 543 | (type(op2) == "string" or type(op2) == "number") then | 524 | Behavior similar to the "band" operation. |
| 544 | return op1 .. op2 -- primitive string concatenation | ||
| 545 | else | ||
| 546 | local h = getbinhandler(op1, op2, "__concat") | ||
| 547 | if h then | ||
| 548 | return (h(op1, op2)) | ||
| 549 | else | ||
| 550 | error(···) | ||
| 551 | end | ||
| 552 | end | ||
| 553 | end | ||
| 554 | </pre><p> | ||
| 555 | </li> | 525 | </li> |
| 556 | 526 | ||
| 557 | <li><b>"len": </b> | 527 | <li><b>"bxor": </b> |
| 558 | the <code>#</code> operation. | 528 | the <code>~</code> (bitwise exclusive or) operation. |
| 559 | 529 | ||
| 530 | Behavior similar to the "band" operation. | ||
| 531 | </li> | ||
| 560 | 532 | ||
| 561 | <pre> | 533 | <li><b>"bnot": </b> |
| 562 | function len_event (op) | 534 | the <code>~</code> (bitwise unary not) operation. |
| 563 | if type(op) == "string" then | 535 | |
| 564 | return strlen(op) -- primitive string length | 536 | Behavior similar to the "band" operation. |
| 565 | else | ||
| 566 | local h = metatable(op).__len | ||
| 567 | if h then | ||
| 568 | return (h(op)) -- call handler with the operand | ||
| 569 | elseif type(op) == "table" then | ||
| 570 | return #op -- primitive table length | ||
| 571 | else -- no handler available: error | ||
| 572 | error(···) | ||
| 573 | end | ||
| 574 | end | ||
| 575 | end | ||
| 576 | </pre><p> | ||
| 577 | See <a href="#3.4.6">§3.4.6</a> for a description of the length of a table. | ||
| 578 | </li> | 537 | </li> |
| 579 | 538 | ||
| 580 | <li><b>"eq": </b> | 539 | <li><b>"shl": </b> |
| 581 | the <code>==</code> operation. | 540 | the <code><<</code> (bitwise left shift) operation. |
| 582 | 541 | ||
| 583 | The function <code>getequalhandler</code> defines how Lua chooses a metamethod | 542 | Behavior similar to the "band" operation. |
| 584 | for equality. | 543 | </li> |
| 585 | A metamethod is selected only when both values | ||
| 586 | being compared have the same type | ||
| 587 | and the same metamethod for the selected operation, | ||
| 588 | and the values are either tables or full userdata. | ||
| 589 | 544 | ||
| 590 | <pre> | 545 | <li><b>"shr": </b> |
| 591 | function getequalhandler (op1, op2) | 546 | the <code>>></code> (bitwise right shift) operation. |
| 592 | if type(op1) ~= type(op2) or | ||
| 593 | (type(op1) ~= "table" and type(op1) ~= "userdata") then | ||
| 594 | return nil -- different values | ||
| 595 | end | ||
| 596 | local mm1 = metatable(op1).__eq | ||
| 597 | local mm2 = metatable(op2).__eq | ||
| 598 | if mm1 == mm2 then return mm1 else return nil end | ||
| 599 | end | ||
| 600 | </pre><p> | ||
| 601 | The "eq" event is defined as follows: | ||
| 602 | 547 | ||
| 603 | <pre> | 548 | Behavior similar to the "band" operation. |
| 604 | function eq_event (op1, op2) | ||
| 605 | if op1 == op2 then -- primitive equal? | ||
| 606 | return true -- values are equal | ||
| 607 | end | ||
| 608 | -- try metamethod | ||
| 609 | local h = getequalhandler(op1, op2) | ||
| 610 | if h then | ||
| 611 | return not not h(op1, op2) | ||
| 612 | else | ||
| 613 | return false | ||
| 614 | end | ||
| 615 | end | ||
| 616 | </pre><p> | ||
| 617 | Note that the result is always a boolean. | ||
| 618 | </li> | 549 | </li> |
| 619 | 550 | ||
| 620 | <li><b>"lt": </b> | 551 | <li><b>"concat": </b> |
| 621 | the <code><</code> operation. | 552 | the <code>..</code> (concatenation) operation. |
| 622 | 553 | ||
| 554 | Behavior similar to the "add" operation, | ||
| 555 | except that Lua will try a metamethod | ||
| 556 | if any operator is neither a string nor a number | ||
| 557 | (which is always coercible to a string). | ||
| 558 | </li> | ||
| 623 | 559 | ||
| 624 | <pre> | 560 | <li><b>"len": </b> |
| 625 | function lt_event (op1, op2) | 561 | the <code>#</code> (length) operation. |
| 626 | if type(op1) == "number" and type(op2) == "number" then | 562 | |
| 627 | return op1 < op2 -- numeric comparison | 563 | If the object is not a string, |
| 628 | elseif type(op1) == "string" and type(op2) == "string" then | 564 | Lua will try its metamethod. |
| 629 | return op1 < op2 -- lexicographic comparison | 565 | If there is a metamethod, |
| 630 | else | 566 | Lua calls it with the object as argument, |
| 631 | local h = getbinhandler(op1, op2, "__lt") | 567 | and the result of the call |
| 632 | if h then | 568 | (always adjusted to one value) |
| 633 | return not not h(op1, op2) | 569 | is the result of the operation. |
| 634 | else | 570 | If there is no metamethod but the object is a table, |
| 635 | error(···) | 571 | then Lua uses the table length operation (see <a href="#3.4.7">§3.4.7</a>). |
| 636 | end | 572 | Otherwise, Lua raises an error. |
| 637 | end | ||
| 638 | end | ||
| 639 | </pre><p> | ||
| 640 | Note that the result is always a boolean. | ||
| 641 | </li> | 573 | </li> |
| 642 | 574 | ||
| 643 | <li><b>"le": </b> | 575 | <li><b>"eq": </b> |
| 644 | the <code><=</code> operation. | 576 | the <code>==</code> (equal) operation. |
| 645 | 577 | ||
| 578 | Lua will try a metamethod only when the values | ||
| 579 | being compared are both either tables or full userdata, | ||
| 580 | both have the same metamethod, | ||
| 581 | and they are not primitively equal. | ||
| 582 | The result of the call is always converted to a boolean. | ||
| 583 | </li> | ||
| 646 | 584 | ||
| 647 | <pre> | 585 | <li><b>"lt": </b> |
| 648 | function le_event (op1, op2) | 586 | the <code><</code> (less than) operation. |
| 649 | if type(op1) == "number" and type(op2) == "number" then | ||
| 650 | return op1 <= op2 -- numeric comparison | ||
| 651 | elseif type(op1) == "string" and type(op2) == "string" then | ||
| 652 | return op1 <= op2 -- lexicographic comparison | ||
| 653 | else | ||
| 654 | local h = getbinhandler(op1, op2, "__le") | ||
| 655 | if h then | ||
| 656 | return not not h(op1, op2) | ||
| 657 | else | ||
| 658 | h = getbinhandler(op1, op2, "__lt") | ||
| 659 | if h then | ||
| 660 | return not h(op2, op1) | ||
| 661 | else | ||
| 662 | error(···) | ||
| 663 | end | ||
| 664 | end | ||
| 665 | end | ||
| 666 | end | ||
| 667 | </pre><p> | ||
| 668 | Note that, in the absence of a "le" metamethod, | ||
| 669 | Lua tries the "lt", assuming that <code>a <= b</code> is | ||
| 670 | equivalent to <code>not (b < a)</code>. | ||
| 671 | 587 | ||
| 588 | Behavior similar to the "add" operation, | ||
| 589 | except that the result of the call is always converted to a boolean. | ||
| 590 | </li> | ||
| 672 | 591 | ||
| 673 | <p> | 592 | <li><b>"le": </b> |
| 593 | the <code><=</code> (less equal) operation. | ||
| 594 | |||
| 595 | Unlike other operations, | ||
| 596 | The less-equal operation can use two different events. | ||
| 597 | First, Lua looks for the "<code>__le</code>" metamethod in both operands, | ||
| 598 | like in the "add" operation. | ||
| 599 | If it cannot find such a metamethod, | ||
| 600 | then it will try the "<code>__lt</code>" event, | ||
| 601 | assuming that <code>a <= b</code> is equivalent to <code>not (b < a)</code>. | ||
| 674 | As with the other comparison operators, | 602 | As with the other comparison operators, |
| 675 | the result is always a boolean. | 603 | the result is always a boolean. |
| 676 | </li> | 604 | </li> |
| 677 | 605 | ||
| 678 | <li><b>"index": </b> | 606 | <li><b>"index": </b> |
| 679 | The indexing access <code>table[key]</code>. | 607 | The indexing access <code>table[key]</code>. |
| 680 | Note that the metamethod is tried only | 608 | |
| 609 | This event happens when <code>table</code> is not a table or | ||
| 681 | when <code>key</code> is not present in <code>table</code>. | 610 | when <code>key</code> is not present in <code>table</code>. |
| 682 | (When <code>table</code> is not a table, | 611 | The metamethod is looked up in <code>table</code>. |
| 683 | no key is ever present, | ||
| 684 | so the metamethod is always tried.) | ||
| 685 | 612 | ||
| 686 | 613 | ||
| 687 | <pre> | 614 | <p> |
| 688 | function gettable_event (table, key) | 615 | Despite the name, |
| 689 | local h | 616 | the metamethod for this event can be either a function or a table. |
| 690 | if type(table) == "table" then | 617 | If it is a function, |
| 691 | local v = rawget(table, key) | 618 | it is called with <code>table</code> and <code>key</code> as arguments. |
| 692 | -- if key is present, return raw value | 619 | If it is a table, |
| 693 | if v ~= nil then return v end | 620 | the final result is the result of indexing this table with <code>key</code>. |
| 694 | h = metatable(table).__index | 621 | (This indexing is regular, not raw, |
| 695 | if h == nil then return nil end | 622 | and therefore can trigger another metamethod.) |
| 696 | else | ||
| 697 | h = metatable(table).__index | ||
| 698 | if h == nil then | ||
| 699 | error(···) | ||
| 700 | end | ||
| 701 | end | ||
| 702 | if type(h) == "function" then | ||
| 703 | return (h(table, key)) -- call the handler | ||
| 704 | else return h[key] -- or repeat operation on it | ||
| 705 | end | ||
| 706 | end | ||
| 707 | </pre><p> | ||
| 708 | </li> | 623 | </li> |
| 709 | 624 | ||
| 710 | <li><b>"newindex": </b> | 625 | <li><b>"newindex": </b> |
| 711 | The indexing assignment <code>table[key] = value</code>. | 626 | The indexing assignment <code>table[key] = value</code>. |
| 712 | Note that the metamethod is tried only | 627 | |
| 628 | Like the index event, | ||
| 629 | this event happens when <code>table</code> is not a table or | ||
| 713 | when <code>key</code> is not present in <code>table</code>. | 630 | when <code>key</code> is not present in <code>table</code>. |
| 631 | The metamethod is looked up in <code>table</code>. | ||
| 714 | 632 | ||
| 715 | 633 | ||
| 716 | <pre> | 634 | <p> |
| 717 | function settable_event (table, key, value) | 635 | Again like with indexing, |
| 718 | local h | 636 | the metamethod for this event can be either a function or a table. |
| 719 | if type(table) == "table" then | 637 | If it is a function, |
| 720 | local v = rawget(table, key) | 638 | it is called with <code>table</code>, <code>key</code>, and <code>value</code> as arguments. |
| 721 | -- if key is present, do raw assignment | 639 | If it is a table, |
| 722 | if v ~= nil then rawset(table, key, value); return end | 640 | Lua does an indexing assignment to this table with the same key and value. |
| 723 | h = metatable(table).__newindex | 641 | (This assignment is regular, not raw, |
| 724 | if h == nil then rawset(table, key, value); return end | 642 | and therefore can trigger another metamethod.) |
| 725 | else | 643 | |
| 726 | h = metatable(table).__newindex | 644 | |
| 727 | if h == nil then | 645 | <p> |
| 728 | error(···) | 646 | Whenever there is a metamethod, |
| 729 | end | 647 | Lua does not perform the primitive assignment. |
| 730 | end | 648 | (If necessary, |
| 731 | if type(h) == "function" then | 649 | the metamethod itself can call <a href="#pdf-rawset"><code>rawset</code></a> |
| 732 | h(table, key,value) -- call the handler | 650 | to do the assignment.) |
| 733 | else h[key] = value -- or repeat operation on it | ||
| 734 | end | ||
| 735 | end | ||
| 736 | </pre><p> | ||
| 737 | </li> | 651 | </li> |
| 738 | 652 | ||
| 739 | <li><b>"call": </b> | 653 | <li><b>"call": </b> |
| 740 | called when Lua calls a value. | 654 | The call operation <code>func(args)</code>. |
| 741 | |||
| 742 | 655 | ||
| 743 | <pre> | 656 | This event happens when Lua tries to call a non-function value |
| 744 | function function_event (func, ...) | 657 | (that is, <code>func</code> is not a function). |
| 745 | if type(func) == "function" then | 658 | The metamethod is looked up in <code>func</code>. |
| 746 | return func(...) -- primitive call | 659 | If present, |
| 747 | else | 660 | the metamethod is called with <code>func</code> as its first argument, |
| 748 | local h = metatable(func).__call | 661 | followed by the arguments of the original call (<code>args</code>). |
| 749 | if h then | ||
| 750 | return h(func, ...) | ||
| 751 | else | ||
| 752 | error(···) | ||
| 753 | end | ||
| 754 | end | ||
| 755 | end | ||
| 756 | </pre><p> | ||
| 757 | </li> | 662 | </li> |
| 758 | 663 | ||
| 759 | </ul> | 664 | </ul> |
| @@ -800,7 +705,8 @@ controls the relative speed of the collector relative to · 40 unmodified lines | |||
| 800 | memory allocation. | 705 | memory allocation. |
| 801 | Larger values make the collector more aggressive but also increase | 706 | Larger values make the collector more aggressive but also increase |
| 802 | the size of each incremental step. | 707 | the size of each incremental step. |
| 803 | Values smaller than 100 make the collector too slow and | 708 | You should not use values smaller than 100, |
| 709 | as they make the collector too slow and | ||
| 804 | can result in the collector never finishing a cycle. | 710 | can result in the collector never finishing a cycle. |
| 805 | The default is 200, | 711 | The default is 200, |
| 806 | which means that the collector runs at "twice" | 712 | which means that the collector runs at "twice" |
| @@ -825,21 +731,6 @@ You can also use these functions to control · 18 unmodified lines | |||
| 825 | the collector directly (e.g., stop and restart it). | 731 | the collector directly (e.g., stop and restart it). |
| 826 | 732 | ||
| 827 | 733 | ||
| 828 | <p> | ||
| 829 | As an experimental feature in Lua 5.3, | ||
| 830 | you can change the collector's operation mode | ||
| 831 | from incremental to <em>generational</em>. | ||
| 832 | A <em>generational collector</em> assumes that most objects die young, | ||
| 833 | and therefore it traverses only young (recently created) objects. | ||
| 834 | This behavior can reduce the time used by the collector, | ||
| 835 | but also increases memory usage (as old dead objects may accumulate). | ||
| 836 | To mitigate this second problem, | ||
| 837 | from time to time the generational collector performs a full collection. | ||
| 838 | Remember that this is an experimental feature; | ||
| 839 | you are welcome to try it, | ||
| 840 | but check your gains. | ||
| 841 | |||
| 842 | |||
| 843 | 734 | ||
| 844 | <h3>2.5.1 – <a name="2.5.1">Garbage-Collection Metamethods</a></h3> | 735 | <h3>2.5.1 – <a name="2.5.1">Garbage-Collection Metamethods</a></h3> |
| 845 | 736 | ||
| @@ -872,17 +763,14 @@ When a marked object becomes garbage, · 26 unmodified lines | |||
| 872 | it is not collected immediately by the garbage collector. | 763 | it is not collected immediately by the garbage collector. |
| 873 | Instead, Lua puts it in a list. | 764 | Instead, Lua puts it in a list. |
| 874 | After the collection, | 765 | After the collection, |
| 875 | Lua does the equivalent of the following function | 766 | Lua goes through that list: |
| 876 | for each object in that list: | 767 | For each object, |
| 768 | it checks the object's <code>__gc</code> metamethod; | ||
| 769 | if it is a function, | ||
| 770 | Lua calls it with the object as its single argument. | ||
| 771 | (If the metamethod is not a function, | ||
| 772 | Lua simply ignores it.) | ||
| 877 | 773 | ||
| 878 | <pre> | ||
| 879 | function gc_event (obj) | ||
| 880 | local h = metatable(obj).__gc | ||
| 881 | if type(h) == "function" then | ||
| 882 | h(obj) | ||
| 883 | end | ||
| 884 | end | ||
| 885 | </pre> | ||
| 886 | 774 | ||
| 887 | <p> | 775 | <p> |
| 888 | At the end of each garbage-collection cycle, | 776 | At the end of each garbage-collection cycle, |
| @@ -1227,6 +1115,15 @@ Strings in Lua can contain any 8-bit value, including embedded zeros, · 338 unmodified lines | |||
| 1227 | which can be specified as '<code>\0</code>'. | 1115 | which can be specified as '<code>\0</code>'. |
| 1228 | 1116 | ||
| 1229 | 1117 | ||
| 1118 | <p> | ||
| 1119 | The UTF-8 encoding of a Unicode character | ||
| 1120 | can be inserted in a literal string with | ||
| 1121 | the escape sequence <code>\u{<em>XXX</em>}</code> | ||
| 1122 | (note the mandatory enclosing brackets), | ||
| 1123 | where <em>XXX</em> is a sequence of one or more hexadecimal digits | ||
| 1124 | representing the character code point. | ||
| 1125 | |||
| 1126 | |||
| 1230 | <p> | 1127 | <p> |
| 1231 | Literal strings can also be defined using a long format | 1128 | Literal strings can also be defined using a long format |
| 1232 | enclosed by <em>long brackets</em>. | 1129 | enclosed by <em>long brackets</em>. |
| @@ -1290,15 +1187,15 @@ which start with <code>0x</code> or <code>0X</code>. · 57 unmodified lines | |||
| 1290 | Hexadecimal constants also accept an optional fractional part | 1187 | Hexadecimal constants also accept an optional fractional part |
| 1291 | plus an optional binary exponent, | 1188 | plus an optional binary exponent, |
| 1292 | marked by a letter '<code>p</code>' or '<code>P</code>'. | 1189 | marked by a letter '<code>p</code>' or '<code>P</code>'. |
| 1293 | A numeric constant with an fractional dot or an exponent | 1190 | A numeric constant with a fractional dot or an exponent |
| 1294 | denotes a floating-point number; | 1191 | denotes a float; |
| 1295 | otherwise it denotes an integer number. | 1192 | otherwise it denotes an integer. |
| 1296 | Examples of valid integer constants are | 1193 | Examples of valid integer constants are |
| 1297 | 1194 | ||
| 1298 | <pre> | 1195 | <pre> |
| 1299 | 3 345 0xff 0xBEBADA | 1196 | 3 345 0xff 0xBEBADA |
| 1300 | </pre><p> | 1197 | </pre><p> |
| 1301 | Examples of valid floating-point constants are | 1198 | Examples of valid float constants are |
| 1302 | 1199 | ||
| 1303 | <pre> | 1200 | <pre> |
| 1304 | 3.0 3.1416 314.16e-2 0.31416E1 34e1 | 1201 | 3.0 3.1416 314.16e-2 0.31416E1 34e1 |
| @@ -1471,7 +1368,7 @@ a chunk is simply a block: · 166 unmodified lines | |||
| 1471 | <p> | 1368 | <p> |
| 1472 | Lua handles a chunk as the body of an anonymous function | 1369 | Lua handles a chunk as the body of an anonymous function |
| 1473 | with a variable number of arguments | 1370 | with a variable number of arguments |
| 1474 | (see <a href="#3.4.10">§3.4.10</a>). | 1371 | (see <a href="#3.4.11">§3.4.11</a>). |
| 1475 | As such, chunks can define local variables, | 1372 | As such, chunks can define local variables, |
| 1476 | receive arguments, and return values. | 1373 | receive arguments, and return values. |
| 1477 | Moreover, such anonymous function is compiled as in the | 1374 | Moreover, such anonymous function is compiled as in the |
| @@ -1490,10 +1387,9 @@ with an interpreter for the virtual machine. · 12 unmodified lines | |||
| 1490 | 1387 | ||
| 1491 | <p> | 1388 | <p> |
| 1492 | Chunks can also be precompiled into binary form; | 1389 | Chunks can also be precompiled into binary form; |
| 1493 | see program <code>luac</code> for details. | 1390 | see program <code>luac</code> and function <a href="#pdf-string.dump"><code>string.dump</code></a> for details. |
| 1494 | Programs in source and compiled forms are interchangeable; | 1391 | Programs in source and compiled forms are interchangeable; |
| 1495 | Lua automatically detects the file type and acts accordingly. | 1392 | Lua automatically detects the file type and acts accordingly (see <a href="#pdf-load"><code>load</code></a>). |
| 1496 | |||
| 1497 | 1393 | ||
| 1498 | 1394 | ||
| 1499 | 1395 | ||
| @@ -1698,7 +1594,7 @@ is equivalent to the code: · 198 unmodified lines | |||
| 1698 | 1594 | ||
| 1699 | <pre> | 1595 | <pre> |
| 1700 | do | 1596 | do |
| 1701 | local <em>var</em>, <em>limit</em>, <em>step</em> = tonumber(<em>e1</em>), tonumber(<em>e2</em>), tonumber(<em>e3</em>) | 1597 | local <em>var</em>, <em>limit</em>, <em>step</em> = convert(<em>e1</em>, <em>e2</em>, <em>e3</em>) |
| 1702 | if not (<em>var</em> and <em>limit</em> and <em>step</em>) then error() end | 1598 | if not (<em>var</em> and <em>limit</em> and <em>step</em>) then error() end |
| 1703 | while (<em>step</em> > 0 and <em>var</em> <= <em>limit</em>) or (<em>step</em> <= 0 and <em>var</em> >= <em>limit</em>) do | 1599 | while (<em>step</em> > 0 and <em>var</em> <= <em>limit</em>) or (<em>step</em> <= 0 and <em>var</em> >= <em>limit</em>) do |
| 1704 | local v = <em>var</em> | 1600 | local v = <em>var</em> |
| @@ -1707,6 +1603,13 @@ is equivalent to the code: · 2 unmodified lines | |||
| 1707 | end | 1603 | end |
| 1708 | end | 1604 | end |
| 1709 | </pre><p> | 1605 | </pre><p> |
| 1606 | where <code>convert</code> returns | ||
| 1607 | its three arguments unaltered | ||
| 1608 | if they are all integers, | ||
| 1609 | otherwise it converts them to floats. | ||
| 1610 | |||
| 1611 | |||
| 1612 | <p> | ||
| 1710 | Note the following: | 1613 | Note the following: |
| 1711 | 1614 | ||
| 1712 | <ul> | 1615 | <ul> |
| @@ -1717,6 +1620,12 @@ before the loop starts. · 4 unmodified lines | |||
| 1717 | They must all result in numbers. | 1620 | They must all result in numbers. |
| 1718 | </li> | 1621 | </li> |
| 1719 | 1622 | ||
| 1623 | <li> | ||
| 1624 | If any of the three control values is not an integer, | ||
| 1625 | all three values are converted to floats, | ||
| 1626 | so that the loop is done with floats. | ||
| 1627 | </li> | ||
| 1628 | |||
| 1720 | <li> | 1629 | <li> |
| 1721 | <code><em>var</em></code>, <code><em>limit</em></code>, and <code><em>step</em></code> are invisible variables. | 1630 | <code><em>var</em></code>, <code><em>limit</em></code>, and <code><em>step</em></code> are invisible variables. |
| 1722 | The names shown here are for explanatory purposes only. | 1631 | The names shown here are for explanatory purposes only. |
| @@ -1728,14 +1637,14 @@ then a step of 1 is used. · 5 unmodified lines | |||
| 1728 | </li> | 1637 | </li> |
| 1729 | 1638 | ||
| 1730 | <li> | 1639 | <li> |
| 1731 | You can use <b>break</b> to exit a <b>for</b> loop. | 1640 | You can use <b>break</b> and <b>goto</b> to exit a <b>for</b> loop. |
| 1732 | </li> | 1641 | </li> |
| 1733 | 1642 | ||
| 1734 | <li> | 1643 | <li> |
| 1735 | The loop variable <code>v</code> is local to the loop; | 1644 | The loop variable <code>v</code> is local to the loop; |
| 1736 | you cannot use its value after the <b>for</b> ends or is broken. | 1645 | you cannot use its value after the <b>for</b> ends or is broken. |
| 1737 | If you need this value, | 1646 | If you need its value, |
| 1738 | assign it to another variable before breaking or exiting the loop. | 1647 | assign it to another variable before exiting the loop. |
| 1739 | </li> | 1648 | </li> |
| 1740 | 1649 | ||
| 1741 | </ul> | 1650 | </ul> |
| @@ -1809,7 +1718,7 @@ function calls can be executed as statements: · 67 unmodified lines | |||
| 1809 | stat ::= functioncall | 1718 | stat ::= functioncall |
| 1810 | </pre><p> | 1719 | </pre><p> |
| 1811 | In this case, all returned values are thrown away. | 1720 | In this case, all returned values are thrown away. |
| 1812 | Function calls are explained in <a href="#3.4.9">§3.4.9</a>. | 1721 | Function calls are explained in <a href="#3.4.10">§3.4.10</a>. |
| 1813 | 1722 | ||
| 1814 | 1723 | ||
| 1815 | 1724 | ||
| @@ -1862,22 +1771,24 @@ The basic expressions in Lua are the following: · 46 unmodified lines | |||
| 1862 | <p> | 1771 | <p> |
| 1863 | Numbers and literal strings are explained in <a href="#3.1">§3.1</a>; | 1772 | Numbers and literal strings are explained in <a href="#3.1">§3.1</a>; |
| 1864 | variables are explained in <a href="#3.2">§3.2</a>; | 1773 | variables are explained in <a href="#3.2">§3.2</a>; |
| 1865 | function definitions are explained in <a href="#3.4.10">§3.4.10</a>; | 1774 | function definitions are explained in <a href="#3.4.11">§3.4.11</a>; |
| 1866 | function calls are explained in <a href="#3.4.9">§3.4.9</a>; | 1775 | function calls are explained in <a href="#3.4.10">§3.4.10</a>; |
| 1867 | table constructors are explained in <a href="#3.4.8">§3.4.8</a>. | 1776 | table constructors are explained in <a href="#3.4.9">§3.4.9</a>. |
| 1868 | Vararg expressions, | 1777 | Vararg expressions, |
| 1869 | denoted by three dots ('<code>...</code>'), can only be used when | 1778 | denoted by three dots ('<code>...</code>'), can only be used when |
| 1870 | directly inside a vararg function; | 1779 | directly inside a vararg function; |
| 1871 | they are explained in <a href="#3.4.10">§3.4.10</a>. | 1780 | they are explained in <a href="#3.4.11">§3.4.11</a>. |
| 1872 | 1781 | ||
| 1873 | 1782 | ||
| 1874 | <p> | 1783 | <p> |
| 1875 | Binary operators comprise arithmetic operators (see <a href="#3.4.1">§3.4.1</a>), | 1784 | Binary operators comprise arithmetic operators (see <a href="#3.4.1">§3.4.1</a>), |
| 1876 | relational operators (see <a href="#3.4.3">§3.4.3</a>), logical operators (see <a href="#3.4.4">§3.4.4</a>), | 1785 | bitwise operators (see <a href="#3.4.2">§3.4.2</a>), |
| 1877 | and the concatenation operator (see <a href="#3.4.5">§3.4.5</a>). | 1786 | relational operators (see <a href="#3.4.4">§3.4.4</a>), logical operators (see <a href="#3.4.5">§3.4.5</a>), |
| 1787 | and the concatenation operator (see <a href="#3.4.6">§3.4.6</a>). | ||
| 1878 | Unary operators comprise the unary minus (see <a href="#3.4.1">§3.4.1</a>), | 1788 | Unary operators comprise the unary minus (see <a href="#3.4.1">§3.4.1</a>), |
| 1879 | the unary <b>not</b> (see <a href="#3.4.4">§3.4.4</a>), | 1789 | the unary bitwise not (see <a href="#3.4.2">§3.4.2</a>), |
| 1880 | and the unary <em>length operator</em> (see <a href="#3.4.6">§3.4.6</a>). | 1790 | the unary logic <b>not</b> (see <a href="#3.4.5">§3.4.5</a>), |
| 1791 | and the unary <em>length operator</em> (see <a href="#3.4.7">§3.4.7</a>). | ||
| 1881 | 1792 | ||
| 1882 | 1793 | ||
| 1883 | <p> | 1794 | <p> |
| @@ -1939,40 +1850,32 @@ that rounds the quotient towards minus infinite (floor). · 55 unmodified lines | |||
| 1939 | 1850 | ||
| 1940 | 1851 | ||
| 1941 | <p> | 1852 | <p> |
| 1942 | With the exception of division, integer division, and exponentiation, | 1853 | With the exception of division and integer division, |
| 1943 | the arithmetic operators work as follows: | 1854 | the arithmetic operators work as follows: |
| 1944 | If both operands are integers, | 1855 | If both operands are integers, |
| 1945 | the operation is performed over integers and the result is an integer. | 1856 | the operation is performed over integers and the result is an integer. |
| 1946 | Otherwise, if both operands are numbers | 1857 | Otherwise, if both operands are numbers |
| 1947 | or strings that can be converted to | 1858 | or strings that can be converted to |
| 1948 | numbers (see <a href="#3.4.2">§3.4.2</a>), | 1859 | numbers (see <a href="#3.4.3">§3.4.3</a>), |
| 1949 | then they are converted to floating-point numbers, | 1860 | then they are converted to floats, |
| 1950 | the operation is performed following the usual rules | 1861 | the operation is performed following the usual rules |
| 1951 | for floating-point arithmetic | 1862 | for floating-point arithmetic |
| 1952 | (usually following the IEEE 754 standard), | 1863 | (usually the IEEE 754 standard), |
| 1953 | and the result is a floating-point number. | 1864 | and the result is a float. |
| 1954 | 1865 | ||
| 1955 | 1866 | ||
| 1956 | <p> | 1867 | <p> |
| 1957 | Division (<code>/</code>) always converts its operands to floating-point numbers | 1868 | Division (<code>/</code>) always converts its operands to floats |
| 1958 | and its result is always a floating-point number. | 1869 | and its result is always a float. |
| 1959 | 1870 | ||
| 1960 | 1871 | ||
| 1961 | <p> | 1872 | <p> |
| 1962 | Integer division (<code>//</code>) converts its operands to integer numbers | 1873 | Integer division (<code>//</code>) converts its operands to integers |
| 1963 | (see <a href="#3.4.2">§3.4.2</a>) | 1874 | (see <a href="#3.4.3">§3.4.3</a>) |
| 1964 | and its result is always an integer number. | 1875 | and its result is always an integer. |
| 1965 | The result is always rounded towards minus infinite (floor). | 1876 | The result is always rounded towards minus infinite (floor). |
| 1966 | 1877 | ||
| 1967 | 1878 | ||
| 1968 | <p> | ||
| 1969 | Exponentiation (<code>^</code>) checks whether both operands are integers and | ||
| 1970 | the exponent is non-negative. | ||
| 1971 | In that case, the exponentiation is performed as an integer operation | ||
| 1972 | and the result is an integer number. | ||
| 1973 | Otherwise, it is performed as a floatint-point operation (<code>pow</code>). | ||
| 1974 | |||
| 1975 | |||
| 1976 | <p> | 1879 | <p> |
| 1977 | In case of overflows in integer arithmetic, | 1880 | In case of overflows in integer arithmetic, |
| 1978 | all operations <em>wrap around</em>, | 1881 | all operations <em>wrap around</em>, |
| @@ -1982,15 +1885,41 @@ according to the usual rules of two-complement arithmetic. · 3 unmodified lines | |||
| 1982 | 1885 | ||
| 1983 | 1886 | ||
| 1984 | 1887 | ||
| 1985 | <h3>3.4.2 – <a name="3.4.2">Coercions and Conversions</a></h3> | 1888 | <h3>3.4.2 – <a name="3.4.2">Bitwise Operators</a></h3><p> |
| 1889 | Lua supports the following bitwise operators: | ||
| 1890 | the binary <code>&</code> (bitwise and), | ||
| 1891 | <code>|</code> (bitwise or), <code>~</code> (bitwise exclusive or), | ||
| 1892 | <code>>></code> (right shift), <code><<</code> (left shift), | ||
| 1893 | and unary <code>~</code> (bitwise not). | ||
| 1894 | |||
| 1895 | |||
| 1896 | <p> | ||
| 1897 | All bitwise operations convert its operands to integers | ||
| 1898 | (see <a href="#3.4.3">§3.4.3</a>), | ||
| 1899 | operate on all bits of those integers, | ||
| 1900 | and result in an integer. | ||
| 1901 | |||
| 1986 | 1902 | ||
| 1987 | <p> | 1903 | <p> |
| 1988 | Lua provides some automatic conversions between types at run time. | 1904 | Both right and left shifts fill with zeros the vacant bits. |
| 1989 | Most binary operations applied to mixed numbers | 1905 | Negative displacements shift to the other direction; |
| 1906 | displacements with absolute values equal to or higher than | ||
| 1907 | the number of bits in an integer | ||
| 1908 | result in zero (all bits are shifted out). | ||
| 1909 | |||
| 1910 | |||
| 1911 | |||
| 1912 | |||
| 1913 | |||
| 1914 | <h3>3.4.3 – <a name="3.4.3">Coercions and Conversions</a></h3><p> | ||
| 1915 | Lua provides some automatic conversions between some | ||
| 1916 | types and representations at run time. | ||
| 1917 | Most arithmetic operations applied to mixed numbers | ||
| 1990 | (integers and floats) convert the integer operand to a float; | 1918 | (integers and floats) convert the integer operand to a float; |
| 1991 | this is called the <em>usual rule</em>. | 1919 | this is called the <em>usual rule</em>. |
| 1992 | Division always convert integer operands to floats, | 1920 | Division always convert integer operands to floats; |
| 1993 | and integer division always convert floating operands to integers. | 1921 | integer division and bitwise operators |
| 1922 | always convert float operands to integers. | ||
| 1994 | The C API also converts both integers to floats and | 1923 | The C API also converts both integers to floats and |
| 1995 | floats to integers, as needed. | 1924 | floats to integers, as needed. |
| 1996 | Moreover, string concatenation accepts numbers as arguments, | 1925 | Moreover, string concatenation accepts numbers as arguments, |
| @@ -2015,8 +1944,8 @@ This kind of conversion never fails. · 18 unmodified lines | |||
| 2015 | <p> | 1944 | <p> |
| 2016 | The conversion from float to integer | 1945 | The conversion from float to integer |
| 2017 | first takes the floor of the float number. | 1946 | first takes the floor of the float number. |
| 2018 | If that value can be represented as an integer number | 1947 | If that value can be represented as an integer |
| 2019 | (that is, it is in the range of integer numbers), | 1948 | (that is, it is in the range of integer representation), |
| 2020 | that is the result. | 1949 | that is the result. |
| 2021 | Otherwise, the conversion fails. | 1950 | Otherwise, the conversion fails. |
| 2022 | 1951 | ||
| @@ -2027,14 +1956,12 @@ follows the rules of the Lua lexer. · 4 unmodified lines | |||
| 2027 | (The string may have leading and trailing spaces and a sign.) | 1956 | (The string may have leading and trailing spaces and a sign.) |
| 2028 | There is no direct conversion from strings to integers: | 1957 | There is no direct conversion from strings to integers: |
| 2029 | If a string is provided where an integer is needed, | 1958 | If a string is provided where an integer is needed, |
| 2030 | Lua converts the string to a float an then the float to an integer. | 1959 | Lua converts the string to a float and then the float to an integer. |
| 2031 | 1960 | ||
| 2032 | 1961 | ||
| 2033 | <p> | 1962 | <p> |
| 2034 | The conversion from numbers to strings use a reasonable, | 1963 | The conversion from numbers to strings use a human-readable, |
| 2035 | non-specified format. | 1964 | non-specified format. |
| 2036 | Floating-point numbers always produce strings with some | ||
| 2037 | floating-point indication (either a decimal dot or an exponent). | ||
| 2038 | For complete control over how numbers are converted to strings, | 1965 | For complete control over how numbers are converted to strings, |
| 2039 | use the <code>format</code> function from the string library | 1966 | use the <code>format</code> function from the string library |
| 2040 | (see <a href="#pdf-string.format"><code>string.format</code></a>). | 1967 | (see <a href="#pdf-string.format"><code>string.format</code></a>). |
| @@ -2043,7 +1970,7 @@ use the <code>format</code> function from the string library · 2 unmodified lines | |||
| 2043 | 1970 | ||
| 2044 | 1971 | ||
| 2045 | 1972 | ||
| 2046 | <h3>3.4.3 – <a name="3.4.3">Relational Operators</a></h3><p> | 1973 | <h3>3.4.4 – <a name="3.4.4">Relational Operators</a></h3><p> |
| 2047 | The relational operators in Lua are | 1974 | The relational operators in Lua are |
| 2048 | 1975 | ||
| 2049 | <pre> | 1976 | <pre> |
| @@ -2060,7 +1987,7 @@ Strings are compared in the obvious way. · 10 unmodified lines | |||
| 2060 | Numbers follow the usual rule for binary operations: | 1987 | Numbers follow the usual rule for binary operations: |
| 2061 | if both operands are integers, | 1988 | if both operands are integers, |
| 2062 | the are compared as integers. | 1989 | the are compared as integers. |
| 2063 | Otherwise, they are converted to floating-point numbers | 1990 | Otherwise, they are converted to floats |
| 2064 | and compared as such. | 1991 | and compared as such. |
| 2065 | 1992 | ||
| 2066 | 1993 | ||
| @@ -2109,7 +2036,7 @@ and <code>a >= b</code> is translated to <code>b <= a</code>. · 42 unmodified lines | |||
| 2109 | 2036 | ||
| 2110 | 2037 | ||
| 2111 | 2038 | ||
| 2112 | <h3>3.4.4 – <a name="3.4.4">Logical Operators</a></h3><p> | 2039 | <h3>3.4.5 – <a name="3.4.5">Logical Operators</a></h3><p> |
| 2113 | The logical operators in Lua are | 2040 | The logical operators in Lua are |
| 2114 | <b>and</b>, <b>or</b>, and <b>not</b>. | 2041 | <b>and</b>, <b>or</b>, and <b>not</b>. |
| 2115 | Like the control structures (see <a href="#3.3.4">§3.3.4</a>), | 2042 | Like the control structures (see <a href="#3.3.4">§3.3.4</a>), |
| @@ -2125,7 +2052,7 @@ otherwise, <b>and</b> returns its second argument. · 9 unmodified lines | |||
| 2125 | The disjunction operator <b>or</b> returns its first argument | 2052 | The disjunction operator <b>or</b> returns its first argument |
| 2126 | if this value is different from <b>nil</b> and <b>false</b>; | 2053 | if this value is different from <b>nil</b> and <b>false</b>; |
| 2127 | otherwise, <b>or</b> returns its second argument. | 2054 | otherwise, <b>or</b> returns its second argument. |
| 2128 | Both <b>and</b> and <b>or</b> use short-cut evaluation; | 2055 | Both <b>and</b> and <b>or</b> use short-circuit evaluation; |
| 2129 | that is, | 2056 | that is, |
| 2130 | the second operand is evaluated only if necessary. | 2057 | the second operand is evaluated only if necessary. |
| 2131 | Here are some examples: | 2058 | Here are some examples: |
| @@ -2147,18 +2074,18 @@ Here are some examples: · 15 unmodified lines | |||
| 2147 | 2074 | ||
| 2148 | 2075 | ||
| 2149 | 2076 | ||
| 2150 | <h3>3.4.5 – <a name="3.4.5">Concatenation</a></h3><p> | 2077 | <h3>3.4.6 – <a name="3.4.6">Concatenation</a></h3><p> |
| 2151 | The string concatenation operator in Lua is | 2078 | The string concatenation operator in Lua is |
| 2152 | denoted by two dots ('<code>..</code>'). | 2079 | denoted by two dots ('<code>..</code>'). |
| 2153 | If both operands are strings or numbers, then they are converted to | 2080 | If both operands are strings or numbers, then they are converted to |
| 2154 | strings according to the rules mentioned in <a href="#3.4.2">§3.4.2</a>. | 2081 | strings according to the rules described in <a href="#3.4.3">§3.4.3</a>. |
| 2155 | Otherwise, the <code>__concat</code> metamethod is called (see <a href="#2.4">§2.4</a>). | 2082 | Otherwise, the <code>__concat</code> metamethod is called (see <a href="#2.4">§2.4</a>). |
| 2156 | 2083 | ||
| 2157 | 2084 | ||
| 2158 | 2085 | ||
| 2159 | 2086 | ||
| 2160 | 2087 | ||
| 2161 | <h3>3.4.6 – <a name="3.4.6">The Length Operator</a></h3> | 2088 | <h3>3.4.7 – <a name="3.4.7">The Length Operator</a></h3> |
| 2162 | 2089 | ||
| 2163 | <p> | 2090 | <p> |
| 2164 | The length operator is denoted by the unary prefix operator <code>#</code>. | 2091 | The length operator is denoted by the unary prefix operator <code>#</code>. |
| @@ -2196,7 +2123,7 @@ with whether a table is a sequence. · 31 unmodified lines | |||
| 2196 | 2123 | ||
| 2197 | 2124 | ||
| 2198 | 2125 | ||
| 2199 | <h3>3.4.7 – <a name="3.4.7">Precedence</a></h3><p> | 2126 | <h3>3.4.8 – <a name="3.4.8">Precedence</a></h3><p> |
| 2200 | Operator precedence in Lua follows the table below, | 2127 | Operator precedence in Lua follows the table below, |
| 2201 | from lower to higher priority: | 2128 | from lower to higher priority: |
| 2202 | 2129 | ||
| @@ -2220,7 +2147,7 @@ All other binary operators are left associative. · 17 unmodified lines | |||
| 2220 | 2147 | ||
| 2221 | 2148 | ||
| 2222 | 2149 | ||
| 2223 | <h3>3.4.8 – <a name="3.4.8">Table Constructors</a></h3><p> | 2150 | <h3>3.4.9 – <a name="3.4.9">Table Constructors</a></h3><p> |
| 2224 | Table constructors are expressions that create tables. | 2151 | Table constructors are expressions that create tables. |
| 2225 | Every time a constructor is evaluated, a new table is created. | 2152 | Every time a constructor is evaluated, a new table is created. |
| 2226 | A constructor can be used to create an empty table | 2153 | A constructor can be used to create an empty table |
| @@ -2268,7 +2195,7 @@ is equivalent to · 41 unmodified lines | |||
| 2268 | If the last field in the list has the form <code>exp</code> | 2195 | If the last field in the list has the form <code>exp</code> |
| 2269 | and the expression is a function call or a vararg expression, | 2196 | and the expression is a function call or a vararg expression, |
| 2270 | then all values returned by this expression enter the list consecutively | 2197 | then all values returned by this expression enter the list consecutively |
| 2271 | (see <a href="#3.4.9">§3.4.9</a>). | 2198 | (see <a href="#3.4.10">§3.4.10</a>). |
| 2272 | 2199 | ||
| 2273 | 2200 | ||
| 2274 | <p> | 2201 | <p> |
| @@ -2279,7 +2206,7 @@ as a convenience for machine-generated code. · 4 unmodified lines | |||
| 2279 | 2206 | ||
| 2280 | 2207 | ||
| 2281 | 2208 | ||
| 2282 | <h3>3.4.9 – <a name="3.4.9">Function Calls</a></h3><p> | 2209 | <h3>3.4.10 – <a name="3.4.10">Function Calls</a></h3><p> |
| 2283 | A function call in Lua has the following syntax: | 2210 | A function call in Lua has the following syntax: |
| 2284 | 2211 | ||
| 2285 | <pre> | 2212 | <pre> |
| @@ -2354,7 +2281,7 @@ So, none of the following examples are tail calls: · 68 unmodified lines | |||
| 2354 | 2281 | ||
| 2355 | 2282 | ||
| 2356 | 2283 | ||
| 2357 | <h3>3.4.10 – <a name="3.4.10">Function Definitions</a></h3> | 2284 | <h3>3.4.11 – <a name="3.4.11">Function Definitions</a></h3> |
| 2358 | 2285 | ||
| 2359 | <p> | 2286 | <p> |
| 2360 | The syntax for function definition is | 2287 | The syntax for function definition is |
| @@ -3046,8 +2973,8 @@ it seems to be a safe assumption.) · 685 unmodified lines | |||
| 3046 | <pre>void lua_arith (lua_State *L, int op);</pre> | 2973 | <pre>void lua_arith (lua_State *L, int op);</pre> |
| 3047 | 2974 | ||
| 3048 | <p> | 2975 | <p> |
| 3049 | Performs an arithmetic operation over the two values | 2976 | Performs an arithmetic or bitwise operation over the two values |
| 3050 | (or one, in the case of negation) | 2977 | (or one, in the case of negations) |
| 3051 | at the top of the stack, | 2978 | at the top of the stack, |
| 3052 | with the value at the top being the second operand, | 2979 | with the value at the top being the second operand, |
| 3053 | pops these values, and pushes the result of the operation. | 2980 | pops these values, and pushes the result of the operation. |
| @@ -3064,9 +2991,16 @@ The value of <code>op</code> must be one of the following constants: · 10 unmodified lines | |||
| 3064 | <li><b><a name="pdf-LUA_OPSUB"><code>LUA_OPSUB</code></a>: </b> performs subtraction (<code>-</code>)</li> | 2991 | <li><b><a name="pdf-LUA_OPSUB"><code>LUA_OPSUB</code></a>: </b> performs subtraction (<code>-</code>)</li> |
| 3065 | <li><b><a name="pdf-LUA_OPMUL"><code>LUA_OPMUL</code></a>: </b> performs multiplication (<code>*</code>)</li> | 2992 | <li><b><a name="pdf-LUA_OPMUL"><code>LUA_OPMUL</code></a>: </b> performs multiplication (<code>*</code>)</li> |
| 3066 | <li><b><a name="pdf-LUA_OPDIV"><code>LUA_OPDIV</code></a>: </b> performs division (<code>/</code>)</li> | 2993 | <li><b><a name="pdf-LUA_OPDIV"><code>LUA_OPDIV</code></a>: </b> performs division (<code>/</code>)</li> |
| 2994 | <li><b><a name="pdf-LUA_OPIDIV"><code>LUA_OPIDIV</code></a>: </b> performs integer division (<code>//</code>)</li> | ||
| 3067 | <li><b><a name="pdf-LUA_OPMOD"><code>LUA_OPMOD</code></a>: </b> performs modulo (<code>%</code>)</li> | 2995 | <li><b><a name="pdf-LUA_OPMOD"><code>LUA_OPMOD</code></a>: </b> performs modulo (<code>%</code>)</li> |
| 3068 | <li><b><a name="pdf-LUA_OPPOW"><code>LUA_OPPOW</code></a>: </b> performs exponentiation (<code>^</code>)</li> | 2996 | <li><b><a name="pdf-LUA_OPPOW"><code>LUA_OPPOW</code></a>: </b> performs exponentiation (<code>^</code>)</li> |
| 3069 | <li><b><a name="pdf-LUA_OPUNM"><code>LUA_OPUNM</code></a>: </b> performs mathematical negation (unary <code>-</code>)</li> | 2997 | <li><b><a name="pdf-LUA_OPUNM"><code>LUA_OPUNM</code></a>: </b> performs mathematical negation (unary <code>-</code>)</li> |
| 2998 | <li><b><a name="pdf-LUA_OPBNOT"><code>LUA_OPBNOT</code></a>: </b> performs bitwise negation (<code>~</code>)</li> | ||
| 2999 | <li><b><a name="pdf-LUA_OPBAND"><code>LUA_OPBAND</code></a>: </b> performs bitwise and (<code>&</code>)</li> | ||
| 3000 | <li><b><a name="pdf-LUA_OPBOR"><code>LUA_OPBOR</code></a>: </b> performs bitwise or (<code>|</code>)</li> | ||
| 3001 | <li><b><a name="pdf-LUA_OPBXOR"><code>LUA_OPBXOR</code></a>: </b> performs bitwise exclusive or (<code>~</code>)</li> | ||
| 3002 | <li><b><a name="pdf-LUA_OPSHL"><code>LUA_OPSHL</code></a>: </b> performs left shift (<code><<</code>)</li> | ||
| 3003 | <li><b><a name="pdf-LUA_OPSHR"><code>LUA_OPSHR</code></a>: </b> performs right shift (<code>>></code>)</li> | ||
| 3070 | 3004 | ||
| 3071 | </ul> | 3005 | </ul> |
| 3072 | 3006 | ||
| @@ -3283,7 +3217,7 @@ If <code>n</code> is 1, the result is the single value on the stack · 210 unmodified lines | |||
| 3283 | (that is, the function does nothing); | 3217 | (that is, the function does nothing); |
| 3284 | if <code>n</code> is 0, the result is the empty string. | 3218 | if <code>n</code> is 0, the result is the empty string. |
| 3285 | Concatenation is performed following the usual semantics of Lua | 3219 | Concatenation is performed following the usual semantics of Lua |
| 3286 | (see <a href="#3.4.5">§3.4.5</a>). | 3220 | (see <a href="#3.4.6">§3.4.6</a>). |
| 3287 | 3221 | ||
| 3288 | 3222 | ||
| 3289 | 3223 | ||
| @@ -3404,24 +3338,18 @@ memory in use by Lua by 1024. · 114 unmodified lines | |||
| 3404 | 3338 | ||
| 3405 | <li><b><code>LUA_GCSTEP</code>: </b> | 3339 | <li><b><code>LUA_GCSTEP</code>: </b> |
| 3406 | performs an incremental step of garbage collection. | 3340 | performs an incremental step of garbage collection. |
| 3407 | The step "size" is controlled by <code>data</code> | ||
| 3408 | (larger values mean more steps) in a non-specified way. | ||
| 3409 | If you want to control the step size | ||
| 3410 | you must experimentally tune the value of <code>data</code>. | ||
| 3411 | The function returns 1 if the step finished a | ||
| 3412 | garbage-collection cycle. | ||
| 3413 | </li> | 3341 | </li> |
| 3414 | 3342 | ||
| 3415 | <li><b><code>LUA_GCSETPAUSE</code>: </b> | 3343 | <li><b><code>LUA_GCSETPAUSE</code>: </b> |
| 3416 | sets <code>data</code> as the new value | 3344 | sets <code>data</code> as the new value |
| 3417 | for the <em>pause</em> of the collector (see <a href="#2.5">§2.5</a>). | 3345 | for the <em>pause</em> of the collector (see <a href="#2.5">§2.5</a>) |
| 3418 | The function returns the previous value of the pause. | 3346 | and returns the previous value of the pause. |
| 3419 | </li> | 3347 | </li> |
| 3420 | 3348 | ||
| 3421 | <li><b><code>LUA_GCSETSTEPMUL</code>: </b> | 3349 | <li><b><code>LUA_GCSETSTEPMUL</code>: </b> |
| 3422 | sets <code>data</code> as the new value for the <em>step multiplier</em> of | 3350 | sets <code>data</code> as the new value for the <em>step multiplier</em> of |
| 3423 | the collector (see <a href="#2.5">§2.5</a>). | 3351 | the collector (see <a href="#2.5">§2.5</a>) |
| 3424 | The function returns the previous value of the step multiplier. | 3352 | and returns the previous value of the step multiplier. |
| 3425 | </li> | 3353 | </li> |
| 3426 | 3354 | ||
| 3427 | <li><b><code>LUA_GCISRUNNING</code>: </b> | 3355 | <li><b><code>LUA_GCISRUNNING</code>: </b> |
| @@ -3429,16 +3357,6 @@ returns a boolean that tells whether the collector is running · 1 unmodified line | |||
| 3429 | (i.e., not stopped). | 3357 | (i.e., not stopped). |
| 3430 | </li> | 3358 | </li> |
| 3431 | 3359 | ||
| 3432 | <li><b><code>LUA_GCGEN</code>: </b> | ||
| 3433 | changes the collector to generational mode | ||
| 3434 | (see <a href="#2.5">§2.5</a>). | ||
| 3435 | </li> | ||
| 3436 | |||
| 3437 | <li><b><code>LUA_GCINC</code>: </b> | ||
| 3438 | changes the collector to incremental mode. | ||
| 3439 | This is the default mode. | ||
| 3440 | </li> | ||
| 3441 | |||
| 3442 | </ul> | 3360 | </ul> |
| 3443 | 3361 | ||
| 3444 | <p> | 3362 | <p> |
| @@ -3514,10 +3432,11 @@ for the "index" event (see <a href="#2.4">§2.4</a>). · 69 unmodified lines | |||
| 3514 | 3432 | ||
| 3515 | <hr><h3><a name="lua_getglobal"><code>lua_getglobal</code></a></h3><p> | 3433 | <hr><h3><a name="lua_getglobal"><code>lua_getglobal</code></a></h3><p> |
| 3516 | <span class="apii">[-0, +1, <em>e</em>]</span> | 3434 | <span class="apii">[-0, +1, <em>e</em>]</span> |
| 3517 | <pre>void lua_getglobal (lua_State *L, const char *name);</pre> | 3435 | <pre>int lua_getglobal (lua_State *L, const char *name);</pre> |
| 3518 | 3436 | ||
| 3519 | <p> | 3437 | <p> |
| 3520 | Pushes onto the stack the value of the global <code>name</code>. | 3438 | Pushes onto the stack the value of the global <code>name</code>. |
| 3439 | Returns the type of that value. | ||
| 3521 | 3440 | ||
| 3522 | 3441 | ||
| 3523 | 3442 | ||
| @@ -3538,7 +3457,7 @@ the function returns 0 and pushes nothing on the stack. · 14 unmodified lines | |||
| 3538 | 3457 | ||
| 3539 | <hr><h3><a name="lua_gettable"><code>lua_gettable</code></a></h3><p> | 3458 | <hr><h3><a name="lua_gettable"><code>lua_gettable</code></a></h3><p> |
| 3540 | <span class="apii">[-1, +1, <em>e</em>]</span> | 3459 | <span class="apii">[-1, +1, <em>e</em>]</span> |
| 3541 | <pre>void lua_gettable (lua_State *L, int index);</pre> | 3460 | <pre>int lua_gettable (lua_State *L, int index);</pre> |
| 3542 | 3461 | ||
| 3543 | <p> | 3462 | <p> |
| 3544 | Pushes onto the stack the value <code>t[k]</code>, | 3463 | Pushes onto the stack the value <code>t[k]</code>, |
| @@ -3553,6 +3472,10 @@ As in Lua, this function may trigger a metamethod · 8 unmodified lines | |||
| 3553 | for the "index" event (see <a href="#2.4">§2.4</a>). | 3472 | for the "index" event (see <a href="#2.4">§2.4</a>). |
| 3554 | 3473 | ||
| 3555 | 3474 | ||
| 3475 | <p> | ||
| 3476 | Returns the type of the pushed value. | ||
| 3477 | |||
| 3478 | |||
| 3556 | 3479 | ||
| 3557 | 3480 | ||
| 3558 | 3481 | ||
| @@ -3577,7 +3500,6 @@ this result is equal to the number of elements in the stack · 18 unmodified lines | |||
| 3577 | <p> | 3500 | <p> |
| 3578 | Pushes onto the stack the Lua value associated with the userdata | 3501 | Pushes onto the stack the Lua value associated with the userdata |
| 3579 | at the given index. | 3502 | at the given index. |
| 3580 | This Lua value must be a table or <b>nil</b>. | ||
| 3581 | 3503 | ||
| 3582 | 3504 | ||
| 3583 | 3505 | ||
| @@ -3598,17 +3520,18 @@ because a pseudo-index is not an actual stack position. · 14 unmodified lines | |||
| 3598 | 3520 | ||
| 3599 | 3521 | ||
| 3600 | <hr><h3><a name="lua_Integer"><code>lua_Integer</code></a></h3> | 3522 | <hr><h3><a name="lua_Integer"><code>lua_Integer</code></a></h3> |
| 3601 | <pre>typedef ptrdiff_t lua_Integer;</pre> | 3523 | <pre>typedef long long int lua_Integer;</pre> |
| 3602 | 3524 | ||
| 3603 | <p> | 3525 | <p> |
| 3604 | The type of integer numbers in Lua. | 3526 | The type of integers in Lua. |
| 3605 | 3527 | ||
| 3606 | 3528 | ||
| 3607 | <p> | 3529 | <p> |
| 3608 | By default it is defined as <code>long long</code>, | 3530 | By default this type is <code>long long</code> |
| 3609 | usually a 64-bit two-complement integer, | 3531 | (usually a 64-bit two-complement integer), |
| 3610 | but it can also be <code>long</code> or <code>int</code>, | 3532 | but that can be changed in <code>luaconf.h</code> |
| 3611 | usually a 32-bit two-complement integer. | 3533 | to <code>long</code> or <code>int</code> |
| 3534 | (usually a 32-bit two-complement integer). | ||
| 3612 | 3535 | ||
| 3613 | 3536 | ||
| 3614 | 3537 | ||
| @@ -3780,7 +3703,7 @@ Returns 1 if the value at the given index is a userdata · 165 unmodified lines | |||
| 3780 | 3703 | ||
| 3781 | <p> | 3704 | <p> |
| 3782 | Returns the "length" of the value at the given index; | 3705 | Returns the "length" of the value at the given index; |
| 3783 | it is equivalent to the '<code>#</code>' operator in Lua (see <a href="#3.4.6">§3.4.6</a>). | 3706 | it is equivalent to the '<code>#</code>' operator in Lua (see <a href="#3.4.7">§3.4.7</a>). |
| 3784 | The result is pushed on the stack. | 3707 | The result is pushed on the stack. |
| 3785 | 3708 | ||
| 3786 | 3709 | ||
| @@ -3973,8 +3896,11 @@ the table during its traversal. · 186 unmodified lines | |||
| 3973 | <pre>typedef double lua_Number;</pre> | 3896 | <pre>typedef double lua_Number;</pre> |
| 3974 | 3897 | ||
| 3975 | <p> | 3898 | <p> |
| 3976 | The type of floating-point numbers in Lua. | 3899 | The type of floats in Lua. |
| 3977 | By default, it is double, | 3900 | |
| 3901 | |||
| 3902 | <p> | ||
| 3903 | By default this type is double, | ||
| 3978 | but that can be changed in <code>luaconf.h</code> to a single float. | 3904 | but that can be changed in <code>luaconf.h</code> to a single float. |
| 3979 | 3905 | ||
| 3980 | 3906 | ||
| @@ -4183,12 +4109,14 @@ the result is a Lua string and Lua takes care of memory allocation · 202 unmodified lines | |||
| 4183 | The conversion specifiers are quite restricted. | 4109 | The conversion specifiers are quite restricted. |
| 4184 | There are no flags, widths, or precisions. | 4110 | There are no flags, widths, or precisions. |
| 4185 | The conversion specifiers can only be | 4111 | The conversion specifiers can only be |
| 4186 | '<code>%%</code>' (inserts a '<code>%</code>' in the string), | 4112 | '<code>%%</code>' (inserts the character '<code>%</code>'), |
| 4187 | '<code>%s</code>' (inserts a zero-terminated string, with no size restrictions), | 4113 | '<code>%s</code>' (inserts a zero-terminated string, with no size restrictions), |
| 4188 | '<code>%f</code>' (inserts a <a href="#lua_Number"><code>lua_Number</code></a>), | 4114 | '<code>%f</code>' (inserts a <a href="#lua_Number"><code>lua_Number</code></a>), |
| 4115 | '<code>%L</code>' (inserts a <a href="#lua_Integer"><code>lua_Integer</code></a>), | ||
| 4189 | '<code>%p</code>' (inserts a pointer as a hexadecimal numeral), | 4116 | '<code>%p</code>' (inserts a pointer as a hexadecimal numeral), |
| 4190 | '<code>%d</code>' (inserts an <code>int</code>), and | 4117 | '<code>%d</code>' (inserts an <code>int</code>), |
| 4191 | '<code>%c</code>' (inserts an <code>int</code> as a byte). | 4118 | '<code>%c</code>' (inserts an <code>int</code> as a one-byte character), and |
| 4119 | '<code>%U</code>' (inserts an <code>int</code> as a UTF-8 byte sequence). | ||
| 4192 | </li> | 4120 | </li> |
| 4193 | 4121 | ||
| 4194 | </ul> | 4122 | </ul> |
| @@ -4289,7 +4217,7 @@ Pushes a nil value onto the stack. · 94 unmodified lines | |||
| 4289 | <pre>void lua_pushnumber (lua_State *L, lua_Number n);</pre> | 4217 | <pre>void lua_pushnumber (lua_State *L, lua_Number n);</pre> |
| 4290 | 4218 | ||
| 4291 | <p> | 4219 | <p> |
| 4292 | Pushes a number with value <code>n</code> onto the stack. | 4220 | Pushes a float with value <code>n</code> onto the stack. |
| 4293 | 4221 | ||
| 4294 | 4222 | ||
| 4295 | 4223 | ||
| @@ -4335,7 +4263,7 @@ Returns 1 if this thread is the main thread of its state. · 39 unmodified lines | |||
| 4335 | <pre>void lua_pushunsigned (lua_State *L, lua_Unsigned n);</pre> | 4263 | <pre>void lua_pushunsigned (lua_State *L, lua_Unsigned n);</pre> |
| 4336 | 4264 | ||
| 4337 | <p> | 4265 | <p> |
| 4338 | Pushes a number with value <code>n</code> onto the stack. | 4266 | Pushes an integer with value <code>n</code> onto the stack. |
| 4339 | 4267 | ||
| 4340 | 4268 | ||
| 4341 | 4269 | ||
| @@ -4384,7 +4312,7 @@ Also returns 0 if any of the indices are non valid. · 42 unmodified lines | |||
| 4384 | 4312 | ||
| 4385 | <hr><h3><a name="lua_rawget"><code>lua_rawget</code></a></h3><p> | 4313 | <hr><h3><a name="lua_rawget"><code>lua_rawget</code></a></h3><p> |
| 4386 | <span class="apii">[-1, +1, –]</span> | 4314 | <span class="apii">[-1, +1, –]</span> |
| 4387 | <pre>void lua_rawget (lua_State *L, int index);</pre> | 4315 | <pre>int lua_rawget (lua_State *L, int index);</pre> |
| 4388 | 4316 | ||
| 4389 | <p> | 4317 | <p> |
| 4390 | Similar to <a href="#lua_gettable"><code>lua_gettable</code></a>, but does a raw access | 4318 | Similar to <a href="#lua_gettable"><code>lua_gettable</code></a>, but does a raw access |
| @@ -4396,7 +4324,7 @@ Similar to <a href="#lua_gettable"><code>lua_gettable</code></a>, but does a raw · 5 unmodified lines | |||
| 4396 | 4324 | ||
| 4397 | <hr><h3><a name="lua_rawgeti"><code>lua_rawgeti</code></a></h3><p> | 4325 | <hr><h3><a name="lua_rawgeti"><code>lua_rawgeti</code></a></h3><p> |
| 4398 | <span class="apii">[-0, +1, –]</span> | 4326 | <span class="apii">[-0, +1, –]</span> |
| 4399 | <pre>void lua_rawgeti (lua_State *L, int index, lua_Integer n);</pre> | 4327 | <pre>int lua_rawgeti (lua_State *L, int index, lua_Integer n);</pre> |
| 4400 | 4328 | ||
| 4401 | <p> | 4329 | <p> |
| 4402 | Pushes onto the stack the value <code>t[n]</code>, | 4330 | Pushes onto the stack the value <code>t[n]</code>, |
| @@ -4405,12 +4333,16 @@ The access is raw; · 2 unmodified lines | |||
| 4405 | that is, it does not invoke metamethods. | 4333 | that is, it does not invoke metamethods. |
| 4406 | 4334 | ||
| 4407 | 4335 | ||
| 4336 | <p> | ||
| 4337 | Returns the type of the pushed value. | ||
| 4338 | |||
| 4339 | |||
| 4408 | 4340 | ||
| 4409 | 4341 | ||
| 4410 | 4342 | ||
| 4411 | <hr><h3><a name="lua_rawgetp"><code>lua_rawgetp</code></a></h3><p> | 4343 | <hr><h3><a name="lua_rawgetp"><code>lua_rawgetp</code></a></h3><p> |
| 4412 | <span class="apii">[-0, +1, –]</span> | 4344 | <span class="apii">[-0, +1, –]</span> |
| 4413 | <pre>void lua_rawgetp (lua_State *L, int index, const void *p);</pre> | 4345 | <pre>int lua_rawgetp (lua_State *L, int index, const void *p);</pre> |
| 4414 | 4346 | ||
| 4415 | <p> | 4347 | <p> |
| 4416 | Pushes onto the stack the value <code>t[k]</code>, | 4348 | Pushes onto the stack the value <code>t[k]</code>, |
| @@ -4420,6 +4352,10 @@ The access is raw; · 3 unmodified lines | |||
| 4420 | that is, it does not invoke metamethods. | 4352 | that is, it does not invoke metamethods. |
| 4421 | 4353 | ||
| 4422 | 4354 | ||
| 4355 | <p> | ||
| 4356 | Returns the type of the pushed value. | ||
| 4357 | |||
| 4358 | |||
| 4423 | 4359 | ||
| 4424 | 4360 | ||
| 4425 | 4361 | ||
| @@ -4699,7 +4635,7 @@ If <code>index</code> is 0, then all stack elements are removed. · 273 unmodified lines | |||
| 4699 | <pre>void lua_setuservalue (lua_State *L, int index);</pre> | 4635 | <pre>void lua_setuservalue (lua_State *L, int index);</pre> |
| 4700 | 4636 | ||
| 4701 | <p> | 4637 | <p> |
| 4702 | Pops a table or <b>nil</b> from the stack and sets it as | 4638 | Pops a value from the stack and sets it as |
| 4703 | the new value associated to the userdata at the given index. | 4639 | the new value associated to the userdata at the given index. |
| 4704 | 4640 | ||
| 4705 | 4641 | ||
| @@ -4818,7 +4754,7 @@ Equivalent to <a href="#lua_tointegerx"><code>lua_tointegerx</code></a> with <co · 112 unmodified lines | |||
| 4818 | Converts the Lua value at the given index | 4754 | Converts the Lua value at the given index |
| 4819 | to the signed integral type <a href="#lua_Integer"><code>lua_Integer</code></a>. | 4755 | to the signed integral type <a href="#lua_Integer"><code>lua_Integer</code></a>. |
| 4820 | The Lua value must be an integer, | 4756 | The Lua value must be an integer, |
| 4821 | or a number or string convertible to an integer (see <a href="#3.4.2">§3.4.2</a>); | 4757 | or a number or string convertible to an integer (see <a href="#3.4.3">§3.4.3</a>); |
| 4822 | otherwise, <code>lua_tointegerx</code> returns 0. | 4758 | otherwise, <code>lua_tointegerx</code> returns 0. |
| 4823 | 4759 | ||
| 4824 | 4760 | ||
| @@ -4881,7 +4817,7 @@ Equivalent to <a href="#lua_tonumberx"><code>lua_tonumberx</code></a> with <code · 56 unmodified lines | |||
| 4881 | Converts the Lua value at the given index | 4817 | Converts the Lua value at the given index |
| 4882 | to the C type <a href="#lua_Number"><code>lua_Number</code></a> (see <a href="#lua_Number"><code>lua_Number</code></a>). | 4818 | to the C type <a href="#lua_Number"><code>lua_Number</code></a> (see <a href="#lua_Number"><code>lua_Number</code></a>). |
| 4883 | The Lua value must be a number or a string convertible to a number | 4819 | The Lua value must be a number or a string convertible to a number |
| 4884 | (see <a href="#3.4.2">§3.4.2</a>); | 4820 | (see <a href="#3.4.3">§3.4.3</a>); |
| 4885 | otherwise, <a href="#lua_tonumberx"><code>lua_tonumberx</code></a> returns 0. | 4821 | otherwise, <a href="#lua_tonumberx"><code>lua_tonumberx</code></a> returns 0. |
| 4886 | 4822 | ||
| 4887 | 4823 | ||
| @@ -4960,7 +4896,7 @@ to the unsigned integral type <a href="#lua_Unsigned"><code>lua_Unsigned</code>< · 72 unmodified lines | |||
| 4960 | The Lua value must be an integer, | 4896 | The Lua value must be an integer, |
| 4961 | or a float, | 4897 | or a float, |
| 4962 | or a string convertible to a number | 4898 | or a string convertible to a number |
| 4963 | (see <a href="#3.4.2">§3.4.2</a>); | 4899 | (see <a href="#3.4.3">§3.4.3</a>); |
| 4964 | otherwise, <code>lua_tounsignedx</code> returns 0. | 4900 | otherwise, <code>lua_tounsignedx</code> returns 0. |
| 4965 | 4901 | ||
| 4966 | 4902 | ||
| @@ -5544,7 +5480,7 @@ calling <a href="#lua_yield"><code>lua_yield</code></a> with <code>nresults</cod · 577 unmodified lines | |||
| 5544 | 5480 | ||
| 5545 | <hr><h3><a name="lua_sethook"><code>lua_sethook</code></a></h3><p> | 5481 | <hr><h3><a name="lua_sethook"><code>lua_sethook</code></a></h3><p> |
| 5546 | <span class="apii">[-0, +0, –]</span> | 5482 | <span class="apii">[-0, +0, –]</span> |
| 5547 | <pre>int lua_sethook (lua_State *L, lua_Hook f, int mask, int count);</pre> | 5483 | <pre>void lua_sethook (lua_State *L, lua_Hook f, int mask, int count);</pre> |
| 5548 | 5484 | ||
| 5549 | <p> | 5485 | <p> |
| 5550 | Sets the debugging hook function. | 5486 | Sets the debugging hook function. |
| @@ -5779,7 +5715,6 @@ buffer area (see <a href="#luaL_prepbuffer"><code>luaL_prepbuffer</code></a>). · 228 unmodified lines | |||
| 5779 | Adds the zero-terminated string pointed to by <code>s</code> | 5715 | Adds the zero-terminated string pointed to by <code>s</code> |
| 5780 | to the buffer <code>B</code> | 5716 | to the buffer <code>B</code> |
| 5781 | (see <a href="#luaL_Buffer"><code>luaL_Buffer</code></a>). | 5717 | (see <a href="#luaL_Buffer"><code>luaL_Buffer</code></a>). |
| 5782 | The string cannot contain embedded zeros. | ||
| 5783 | 5718 | ||
| 5784 | 5719 | ||
| 5785 | 5720 | ||
| @@ -5814,7 +5749,7 @@ which is the value to be added to the buffer. · 28 unmodified lines | |||
| 5814 | 5749 | ||
| 5815 | <p> | 5750 | <p> |
| 5816 | Checks whether <code>cond</code> is true. | 5751 | Checks whether <code>cond</code> is true. |
| 5817 | If not, raises an error with a standard message. | 5752 | If it is not, raises an error with a standard message (see <a href="#luaL_argerror"><code>luaL_argerror</code></a>). |
| 5818 | 5753 | ||
| 5819 | 5754 | ||
| 5820 | 5755 | ||
| @@ -5825,14 +5760,15 @@ If not, raises an error with a standard message. · 4 unmodified lines | |||
| 5825 | <pre>int luaL_argerror (lua_State *L, int arg, const char *extramsg);</pre> | 5760 | <pre>int luaL_argerror (lua_State *L, int arg, const char *extramsg);</pre> |
| 5826 | 5761 | ||
| 5827 | <p> | 5762 | <p> |
| 5828 | Raises an error with a standard message | 5763 | Raises an error reporting a problem with argument <code>arg</code> |
| 5829 | that includes <code>extramsg</code> as a comment. | 5764 | of the C function that called it, |
| 5830 | 5765 | using a standard message | |
| 5766 | that includes <code>extramsg</code> as a comment: | ||
| 5831 | 5767 | ||
| 5832 | <p> | 5768 | <pre> |
| 5833 | This function never returns, | 5769 | bad argument #<em>arg</em> to '<em>funcname</em>' (<em>extramsg</em>) |
| 5834 | but it is an idiom to use it in C functions | 5770 | </pre><p> |
| 5835 | as <code>return luaL_argerror(<em>args</em>)</code>. | 5771 | This function never returns. |
| 5836 | 5772 | ||
| 5837 | 5773 | ||
| 5838 | 5774 | ||
| @@ -6304,7 +6240,7 @@ Pushes the resulting string on the stack and returns it. · 465 unmodified lines | |||
| 6304 | <p> | 6240 | <p> |
| 6305 | Returns the "length" of the value at the given index | 6241 | Returns the "length" of the value at the given index |
| 6306 | as a number; | 6242 | as a number; |
| 6307 | it is equivalent to the '<code>#</code>' operator in Lua (see <a href="#3.4.6">§3.4.6</a>). | 6243 | it is equivalent to the '<code>#</code>' operator in Lua (see <a href="#3.4.7">§3.4.7</a>). |
| 6308 | Raises an error if the result of the operation is not an integer. | 6244 | Raises an error if the result of the operation is not an integer. |
| 6309 | (This case only can happen through metamethods.) | 6245 | (This case only can happen through metamethods.) |
| 6310 | 6246 | ||
| @@ -6461,7 +6397,8 @@ If the registry already has the key <code>tname</code>, · 150 unmodified lines | |||
| 6461 | returns 0. | 6397 | returns 0. |
| 6462 | Otherwise, | 6398 | Otherwise, |
| 6463 | creates a new table to be used as a metatable for userdata, | 6399 | creates a new table to be used as a metatable for userdata, |
| 6464 | adds it to the registry with key <code>tname</code>, | 6400 | adds to this new table the pair <code>__name = tname</code>, |
| 6401 | adds to the registry the pair <code></code>[tname] = new table, | ||
| 6465 | and returns 1. | 6402 | and returns 1. |
| 6466 | 6403 | ||
| 6467 | 6404 | ||
| @@ -6781,6 +6718,43 @@ in the registry (see <a href="#luaL_newmetatable"><code>luaL_newmetatable</code> · 313 unmodified lines | |||
| 6781 | 6718 | ||
| 6782 | 6719 | ||
| 6783 | 6720 | ||
| 6721 | <hr><h3><a name="luaL_Stream"><code>luaL_Stream</code></a></h3> | ||
| 6722 | <pre>typedef struct luaL_Stream { | ||
| 6723 | FILE *f; | ||
| 6724 | lua_CFunction closef; | ||
| 6725 | } luaL_Stream;</pre> | ||
| 6726 | |||
| 6727 | <p> | ||
| 6728 | The standard representation for file handles, | ||
| 6729 | which is used by the standard I/O library. | ||
| 6730 | |||
| 6731 | |||
| 6732 | <p> | ||
| 6733 | A file handle is implemented as a full userdata, | ||
| 6734 | with a metatable called <code>LUA_FILEHANDLE</code>. | ||
| 6735 | <code>LUA_FILEHANDLE</code> is a macro with the actual metatable's name. | ||
| 6736 | The metatable is created by the I/O library | ||
| 6737 | (see <a href="#luaL_newmetatable"><code>luaL_newmetatable</code></a>). | ||
| 6738 | |||
| 6739 | |||
| 6740 | <p> | ||
| 6741 | This userdata must start with the structure <code>luaL_Stream</code>; | ||
| 6742 | it can contain other data after this initial structure. | ||
| 6743 | Field <code>f</code> points to the corresponding C stream | ||
| 6744 | (or it can be <code>NULL</code> to indicate an incompletely created handle). | ||
| 6745 | Field <code>closef</code> points to a Lua function | ||
| 6746 | that will be called to close the stream | ||
| 6747 | when the handle is closed or collected; | ||
| 6748 | this function receives the file handle as its sole argument and | ||
| 6749 | must return either <b>true</b> (in case of success) | ||
| 6750 | or <b>nil</b> plus an error message (in case of error). | ||
| 6751 | Once Lua calls this field, | ||
| 6752 | the field value is changed to <b>nil</b> to signal that the handle is closed. | ||
| 6753 | |||
| 6754 | |||
| 6755 | |||
| 6756 | |||
| 6757 | |||
| 6784 | <hr><h3><a name="luaL_testudata"><code>luaL_testudata</code></a></h3><p> | 6758 | <hr><h3><a name="luaL_testudata"><code>luaL_testudata</code></a></h3><p> |
| 6785 | <span class="apii">[-0, +0, <em>e</em>]</span> | 6759 | <span class="apii">[-0, +0, <em>e</em>]</span> |
| 6786 | <pre>void *luaL_testudata (lua_State *L, int arg, const char *tname);</pre> | 6760 | <pre>void *luaL_testudata (lua_State *L, int arg, const char *tname);</pre> |
| @@ -6888,8 +6862,6 @@ This function is used to build a prefix for error messages. · 101 unmodified lines | |||
| 6888 | 6862 | ||
| 6889 | 6863 | ||
| 6890 | 6864 | ||
| 6891 | |||
| 6892 | |||
| 6893 | <h1>6 – <a name="6">Standard Libraries</a></h1> | 6865 | <h1>6 – <a name="6">Standard Libraries</a></h1> |
| 6894 | 6866 | ||
| 6895 | <p> | 6867 | <p> |
| @@ -6918,11 +6890,11 @@ Currently, Lua has the following standard libraries: · 22 unmodified lines | |||
| 6918 | 6890 | ||
| 6919 | <li>string manipulation (<a href="#6.4">§6.4</a>);</li> | 6891 | <li>string manipulation (<a href="#6.4">§6.4</a>);</li> |
| 6920 | 6892 | ||
| 6921 | <li>table manipulation (<a href="#6.5">§6.5</a>);</li> | 6893 | <li>basic UTF-8 support (<a href="#6.5">§6.5</a>);</li> |
| 6922 | 6894 | ||
| 6923 | <li>mathematical functions (<a href="#6.6">§6.6</a>) (sin, log, etc.);</li> | 6895 | <li>table manipulation (<a href="#6.6">§6.6</a>);</li> |
| 6924 | 6896 | ||
| 6925 | <li>bitwise operations (<a href="#6.7">§6.7</a>);</li> | 6897 | <li>mathematical functions (<a href="#6.7">§6.7</a>) (sin, log, etc.);</li> |
| 6926 | 6898 | ||
| 6927 | <li>input and output (<a href="#6.8">§6.8</a>);</li> | 6899 | <li>input and output (<a href="#6.8">§6.8</a>);</li> |
| 6928 | 6900 | ||
| @@ -6949,7 +6921,6 @@ the host program can open them individually by using · 20 unmodified lines | |||
| 6949 | <a name="pdf-luaopen_string"><code>luaopen_string</code></a> (for the string library), | 6921 | <a name="pdf-luaopen_string"><code>luaopen_string</code></a> (for the string library), |
| 6950 | <a name="pdf-luaopen_table"><code>luaopen_table</code></a> (for the table library), | 6922 | <a name="pdf-luaopen_table"><code>luaopen_table</code></a> (for the table library), |
| 6951 | <a name="pdf-luaopen_math"><code>luaopen_math</code></a> (for the mathematical library), | 6923 | <a name="pdf-luaopen_math"><code>luaopen_math</code></a> (for the mathematical library), |
| 6952 | <a name="pdf-luaopen_bit32"><code>luaopen_bit32</code></a> (for the bit library), | ||
| 6953 | <a name="pdf-luaopen_io"><code>luaopen_io</code></a> (for the I/O library), | 6924 | <a name="pdf-luaopen_io"><code>luaopen_io</code></a> (for the I/O library), |
| 6954 | <a name="pdf-luaopen_os"><code>luaopen_os</code></a> (for the Operating System library), | 6925 | <a name="pdf-luaopen_os"><code>luaopen_os</code></a> (for the Operating System library), |
| 6955 | and <a name="pdf-luaopen_debug"><code>luaopen_debug</code></a> (for the debug library). | 6926 | and <a name="pdf-luaopen_debug"><code>luaopen_debug</code></a> (for the debug library). |
| @@ -7003,25 +6974,21 @@ restarts automatic execution of the garbage collector. · 47 unmodified lines | |||
| 7003 | </li> | 6974 | </li> |
| 7004 | 6975 | ||
| 7005 | <li><b>"<code>count</code>": </b> | 6976 | <li><b>"<code>count</code>": </b> |
| 7006 | returns the total memory in use by Lua (in Kbytes) and | 6977 | returns the total memory in use by Lua in Kbytes. |
| 7007 | a second value with the total memory in bytes modulo 1024. | 6978 | The value has a fractional part, |
| 7008 | The first value has a fractional part, | 6979 | so that it multiplied by 1024 |
| 7009 | so the following equality is always true: | 6980 | gives the exact number of bytes in use by Lua |
| 7010 | 6981 | (except for overflows). | |
| 7011 | <pre> | ||
| 7012 | k, b = collectgarbage("count") | ||
| 7013 | assert(k*1024 == math.floor(k)*1024 + b) | ||
| 7014 | </pre><p> | ||
| 7015 | (The second result is useful when Lua is compiled | ||
| 7016 | with a non floating-point type for numbers.) | ||
| 7017 | </li> | 6982 | </li> |
| 7018 | 6983 | ||
| 7019 | <li><b>"<code>step</code>": </b> | 6984 | <li><b>"<code>step</code>": </b> |
| 7020 | performs a garbage-collection step. | 6985 | performs a garbage-collection step. |
| 7021 | The step "size" is controlled by <code>arg</code> | 6986 | The step "size" is controlled by <code>arg</code>. |
| 7022 | (larger values mean more steps) in a non-specified way. | 6987 | With a zero value, |
| 7023 | If you want to control the step size | 6988 | the collector will perform one basic (indivisible) step. |
| 7024 | you must experimentally tune the value of <code>arg</code>. | 6989 | For non-zero values, |
| 6990 | the collector will perform as if that amount of memory | ||
| 6991 | (in KBytes) had been allocated by Lua. | ||
| 7025 | Returns <b>true</b> if the step finished a collection cycle. | 6992 | Returns <b>true</b> if the step finished a collection cycle. |
| 7026 | </li> | 6993 | </li> |
| 7027 | 6994 | ||
| @@ -7095,7 +7062,7 @@ A global variable (not a function) that · 67 unmodified lines | |||
| 7095 | holds the global environment (see <a href="#2.2">§2.2</a>). | 7062 | holds the global environment (see <a href="#2.2">§2.2</a>). |
| 7096 | Lua itself does not use this variable; | 7063 | Lua itself does not use this variable; |
| 7097 | changing its value does not affect any environment, | 7064 | changing its value does not affect any environment, |
| 7098 | nor vice-versa. | 7065 | nor vice versa. |
| 7099 | 7066 | ||
| 7100 | 7067 | ||
| 7101 | 7068 | ||
| @@ -7190,6 +7157,12 @@ or "<code>bt</code>" (both binary and text). · 88 unmodified lines | |||
| 7190 | The default is "<code>bt</code>". | 7157 | The default is "<code>bt</code>". |
| 7191 | 7158 | ||
| 7192 | 7159 | ||
| 7160 | <p> | ||
| 7161 | Lua does not check the consistency of binary chunks. | ||
| 7162 | Maliciously crafted binary chunks can crash | ||
| 7163 | the interpreter. | ||
| 7164 | |||
| 7165 | |||
| 7193 | 7166 | ||
| 7194 | 7167 | ||
| 7195 | <p> | 7168 | <p> |
| @@ -7328,7 +7301,7 @@ without invoking any metamethod. · 132 unmodified lines | |||
| 7328 | Returns the length of the object <code>v</code>, | 7301 | Returns the length of the object <code>v</code>, |
| 7329 | which must be a table or a string, | 7302 | which must be a table or a string, |
| 7330 | without invoking any metamethod. | 7303 | without invoking any metamethod. |
| 7331 | Returns an integer number. | 7304 | Returns an integer. |
| 7332 | 7305 | ||
| 7333 | 7306 | ||
| 7334 | 7307 | ||
| @@ -7417,7 +7390,9 @@ the function returns <b>nil</b>. · 82 unmodified lines | |||
| 7417 | <p> | 7390 | <p> |
| 7418 | <hr><h3><a name="pdf-tostring"><code>tostring (v)</code></a></h3> | 7391 | <hr><h3><a name="pdf-tostring"><code>tostring (v)</code></a></h3> |
| 7419 | Receives a value of any type and | 7392 | Receives a value of any type and |
| 7420 | converts it to a string in a reasonable format. | 7393 | converts it to a string in a human-readable format. |
| 7394 | Floats always produce strings with some | ||
| 7395 | floating-point indication (either a decimal dot or an exponent). | ||
| 7421 | (For complete control of how numbers are converted, | 7396 | (For complete control of how numbers are converted, |
| 7422 | use <a href="#pdf-string.format"><code>string.format</code></a>.) | 7397 | use <a href="#pdf-string.format"><code>string.format</code></a>.) |
| 7423 | 7398 | ||
| @@ -7451,7 +7426,7 @@ and "<code>userdata</code>". · 27 unmodified lines | |||
| 7451 | <hr><h3><a name="pdf-_VERSION"><code>_VERSION</code></a></h3> | 7426 | <hr><h3><a name="pdf-_VERSION"><code>_VERSION</code></a></h3> |
| 7452 | A global variable (not a function) that | 7427 | A global variable (not a function) that |
| 7453 | holds a string containing the current interpreter version. | 7428 | holds a string containing the current interpreter version. |
| 7454 | The current contents of this variable is "<code>Lua 5.3</code>". | 7429 | The current value of this variable is "<code>Lua 5.3</code>". |
| 7455 | 7430 | ||
| 7456 | 7431 | ||
| 7457 | 7432 | ||
| @@ -7981,13 +7956,19 @@ Numerical codes are not necessarily portable across platforms. · 523 unmodified lines | |||
| 7981 | 7956 | ||
| 7982 | 7957 | ||
| 7983 | <p> | 7958 | <p> |
| 7984 | <hr><h3><a name="pdf-string.dump"><code>string.dump (function)</code></a></h3> | 7959 | <hr><h3><a name="pdf-string.dump"><code>string.dump (function [, strip])</code></a></h3> |
| 7985 | 7960 | ||
| 7986 | 7961 | ||
| 7987 | <p> | 7962 | <p> |
| 7988 | Returns a string containing a binary representation of the given function, | 7963 | Returns a string containing a binary representation |
| 7964 | (a <em>binary chunk</em>) | ||
| 7965 | of the given function, | ||
| 7989 | so that a later <a href="#pdf-load"><code>load</code></a> on this string returns | 7966 | so that a later <a href="#pdf-load"><code>load</code></a> on this string returns |
| 7990 | a copy of the function (but with new upvalues). | 7967 | a copy of the function (but with new upvalues). |
| 7968 | If <code>strip</code> is a true value, | ||
| 7969 | the binary representation is created without debug information | ||
| 7970 | about the function | ||
| 7971 | (local variable names, lines, etc.). | ||
| 7991 | 7972 | ||
| 7992 | 7973 | ||
| 7993 | 7974 | ||
| @@ -8055,11 +8036,7 @@ Options · 61 unmodified lines | |||
| 8055 | <code>G</code>, and <code>g</code> all expect a number as argument. | 8036 | <code>G</code>, and <code>g</code> all expect a number as argument. |
| 8056 | Options <code>c</code>, <code>d</code>, | 8037 | Options <code>c</code>, <code>d</code>, |
| 8057 | <code>i</code>, <code>o</code>, <code>u</code>, <code>X</code>, and <code>x</code> | 8038 | <code>i</code>, <code>o</code>, <code>u</code>, <code>X</code>, and <code>x</code> |
| 8058 | also expect a number, | 8039 | expect an integer. |
| 8059 | but the range of that number may be limited by | ||
| 8060 | the underlying C implementation. | ||
| 8061 | For options <code>o</code>, <code>u</code>, <code>X</code>, and <code>x</code>, | ||
| 8062 | the number cannot be negative. | ||
| 8063 | Option <code>q</code> expects a string; | 8040 | Option <code>q</code> expects a string; |
| 8064 | option <code>s</code> expects a string without embedded zeros. | 8041 | option <code>s</code> expects a string without embedded zeros. |
| 8065 | If the argument to option <code>s</code> is not a string, | 8042 | If the argument to option <code>s</code> is not a string, |
| @@ -8175,9 +8152,9 @@ Here are some examples: · 109 unmodified lines | |||
| 8175 | end) | 8152 | end) |
| 8176 | --> x="4+5 = 9" | 8153 | --> x="4+5 = 9" |
| 8177 | 8154 | ||
| 8178 | local t = {name="lua", version="5.2"} | 8155 | local t = {name="lua", version="5.3"} |
| 8179 | x = string.gsub("$name-$version.tar.gz", "%$(%w+)", t) | 8156 | x = string.gsub("$name-$version.tar.gz", "%$(%w+)", t) |
| 8180 | --> x="lua-5.2.tar.gz" | 8157 | --> x="lua-5.3.tar.gz" |
| 8181 | </pre> | 8158 | </pre> |
| 8182 | 8159 | ||
| 8183 | 8160 | ||
| @@ -8218,6 +8195,45 @@ its default value is 1 and can be negative. · 34 unmodified lines | |||
| 8218 | 8195 | ||
| 8219 | 8196 | ||
| 8220 | 8197 | ||
| 8198 | <p> | ||
| 8199 | <hr><h3><a name="pdf-string.packfloat"><code>string.packfloat (n [, size [, endianess]])</code></a></h3> | ||
| 8200 | Returns a string with the machine representation of float <code>n</code>, | ||
| 8201 | with given size and endianess. | ||
| 8202 | The <code>size</code> is the string "<code>f</code>" (single precision), | ||
| 8203 | "<code>d</code>" (double precision), or "<code>n</code>", | ||
| 8204 | which means the size of a <a href="#lua_Number"><code>lua_Number</code></a>; | ||
| 8205 | its default is St{n}. | ||
| 8206 | The endianess is the string "<code>l</code>" (little endian), "<code>b</code>" (big endian), | ||
| 8207 | or "<code>n</code>" (native); | ||
| 8208 | the default is the native endianess. | ||
| 8209 | |||
| 8210 | |||
| 8211 | <p> | ||
| 8212 | (This function may not work correctly for non-native endianess | ||
| 8213 | in mixed-endian architectures.) | ||
| 8214 | |||
| 8215 | |||
| 8216 | |||
| 8217 | |||
| 8218 | <p> | ||
| 8219 | <hr><h3><a name="pdf-string.packint"><code>string.packint (n [, size [, endianess]])</code></a></h3> | ||
| 8220 | Returns a string with the machine representation of integer <code>n</code>, | ||
| 8221 | with <code>size</code> bytes and given endianess. | ||
| 8222 | The <code>size</code> can be any value from 1 to 8 or 0, | ||
| 8223 | which means the size of a <a href="#lua_Integer"><code>lua_Integer</code></a>; | ||
| 8224 | its default is zero. | ||
| 8225 | The endianess is the string "<code>l</code>" (little endian), "<code>b</code>" (big endian), | ||
| 8226 | or "<code>n</code>" (native); | ||
| 8227 | the default is the native endianess. | ||
| 8228 | |||
| 8229 | |||
| 8230 | <p> | ||
| 8231 | (This function may not work correctly for native endianess | ||
| 8232 | in mixed-endian architectures.) | ||
| 8233 | |||
| 8234 | |||
| 8235 | |||
| 8236 | |||
| 8221 | <p> | 8237 | <p> |
| 8222 | <hr><h3><a name="pdf-string.rep"><code>string.rep (s, n [, sep])</code></a></h3> | 8238 | <hr><h3><a name="pdf-string.rep"><code>string.rep (s, n [, sep])</code></a></h3> |
| 8223 | Returns a string that is the concatenation of <code>n</code> copies of | 8239 | Returns a string that is the concatenation of <code>n</code> copies of |
| @@ -8262,6 +8278,28 @@ the function returns the empty string. · 38 unmodified lines | |||
| 8262 | 8278 | ||
| 8263 | 8279 | ||
| 8264 | 8280 | ||
| 8281 | <p> | ||
| 8282 | <hr><h3><a name="pdf-string.unpackfloat"><code>string.unpackfloat (s [, pos [, size [, endianess]]])</code></a></h3> | ||
| 8283 | Reads the machine representation of a float starting at position | ||
| 8284 | <code>pos</code> in string <code>s</code> and returns that number. | ||
| 8285 | See <a href="#pdf-string.packfloat"><code>string.packfloat</code></a> for details about <code>size</code> and <code>endianess</code>. | ||
| 8286 | |||
| 8287 | |||
| 8288 | |||
| 8289 | |||
| 8290 | <p> | ||
| 8291 | <hr><h3><a name="pdf-string.unpackint"><code>string.unpackint (s [, pos [, size [, endianess]]])</code></a></h3> | ||
| 8292 | Reads the machine representation of an integer starting at position | ||
| 8293 | <code>pos</code> in string <code>s</code> and returns that integer. | ||
| 8294 | See <a href="#pdf-string.packint"><code>string.packint</code></a> for details about <code>size</code> and <code>endianess</code>. | ||
| 8295 | |||
| 8296 | |||
| 8297 | <p> | ||
| 8298 | Integers are always read as signed. | ||
| 8299 | |||
| 8300 | |||
| 8301 | |||
| 8302 | |||
| 8265 | <p> | 8303 | <p> |
| 8266 | <hr><h3><a name="pdf-string.upper"><code>string.upper (s)</code></a></h3> | 8304 | <hr><h3><a name="pdf-string.upper"><code>string.upper (s)</code></a></h3> |
| 8267 | Receives a string and returns a copy of this string with all | 8305 | Receives a string and returns a copy of this string with all |
| @@ -8321,7 +8359,7 @@ represents the class which is the union of all · 53 unmodified lines | |||
| 8321 | characters in <em>set</em>. | 8359 | characters in <em>set</em>. |
| 8322 | A range of characters can be specified by | 8360 | A range of characters can be specified by |
| 8323 | separating the end characters of the range, | 8361 | separating the end characters of the range, |
| 8324 | in ascending order, with a '<code>-</code>', | 8362 | in ascending order, with a '<code>-</code>'. |
| 8325 | All classes <code>%</code><em>x</em> described above can also be used as | 8363 | All classes <code>%</code><em>x</em> described above can also be used as |
| 8326 | components in <em>set</em>. | 8364 | components in <em>set</em>. |
| 8327 | All other characters in <em>set</em> represent themselves. | 8365 | All other characters in <em>set</em> represent themselves. |
| @@ -8466,48 +8504,151 @@ string <code>"flaaap"</code>, there will be two captures: 3 and 5. · 138 unmodified lines | |||
| 8466 | 8504 | ||
| 8467 | 8505 | ||
| 8468 | 8506 | ||
| 8469 | <h2>6.5 – <a name="6.5">Table Manipulation</a></h2> | 8507 | <h2>6.5 – <a name="6.5">UTF-8 Support</a></h2> |
| 8470 | 8508 | ||
| 8471 | <p> | 8509 | <p> |
| 8472 | This library provides generic functions for table manipulation. | 8510 | This library provides basic support for UTF-8 encoding. |
| 8473 | It provides all its functions inside the table <a name="pdf-table"><code>table</code></a>. | 8511 | It provides all its functions inside the table <a name="pdf-utf8"><code>utf8</code></a>. |
| 8512 | This library does not provide any support for Unicode other | ||
| 8513 | than the handling of the encoding. | ||
| 8514 | Any operation that needs the meaning of a character, | ||
| 8515 | such as character classification, is outside its scope. | ||
| 8474 | 8516 | ||
| 8475 | 8517 | ||
| 8476 | <p> | 8518 | <p> |
| 8477 | Remember that, whenever an operation needs the length of a table, | 8519 | Unless stated otherwise, |
| 8478 | the table should be a proper sequence | 8520 | all functions that expect a byte index as a parameter |
| 8479 | or have a <code>__len</code> metamethod (see <a href="#3.4.6">§3.4.6</a>). | 8521 | assume that the given position is either the start of a byte sequence |
| 8480 | All functions ignore non-numeric keys | 8522 | or one plus the length of the subject string. |
| 8481 | in tables given as arguments. | 8523 | As in the string library, |
| 8524 | negative indices count from the end of the string. | ||
| 8482 | 8525 | ||
| 8483 | 8526 | ||
| 8484 | <p> | 8527 | <p> |
| 8485 | For performance reasons, | 8528 | <hr><h3><a name="pdf-utf8.char"><code>utf8.char (···)</code></a></h3> |
| 8486 | all table accesses (get/set) performed by these functions are raw. | 8529 | Receives zero or more integers, |
| 8530 | converts each one to its corresponding UTF-8 byte sequence | ||
| 8531 | and returns a string with the concatenation of all these sequences. | ||
| 8487 | 8532 | ||
| 8488 | 8533 | ||
| 8489 | <p> | ||
| 8490 | <hr><h3><a name="pdf-table.concat"><code>table.concat (list [, sep [, i [, j]]])</code></a></h3> | ||
| 8491 | 8534 | ||
| 8492 | 8535 | ||
| 8493 | <p> | 8536 | <p> |
| 8494 | Given a list where all elements are strings or numbers, | 8537 | <hr><h3><a name="pdf-utf8.charpatt"><code>utf8.charpatt</code></a></h3> |
| 8495 | returns the string <code>list[i]..sep..list[i+1] ··· sep..list[j]</code>. | 8538 | The pattern (a string, not a function) "<code>[\0-\x7F\xC2-\xF4][\x80-\xBF]*</code>" |
| 8496 | The default value for <code>sep</code> is the empty string, | 8539 | (see <a href="#6.4.1">§6.4.1</a>), |
| 8497 | the default for <code>i</code> is 1, | 8540 | which matches exactly one UTF-8 byte sequence, |
| 8498 | and the default for <code>j</code> is <code>#list</code>. | 8541 | assuming that the subject is a valid UTF-8 string. |
| 8499 | If <code>i</code> is greater than <code>j</code>, returns the empty string. | ||
| 8500 | 8542 | ||
| 8501 | 8543 | ||
| 8502 | 8544 | ||
| 8503 | 8545 | ||
| 8504 | <p> | 8546 | <p> |
| 8505 | <hr><h3><a name="pdf-table.insert"><code>table.insert (list, [pos,] value)</code></a></h3> | 8547 | <hr><h3><a name="pdf-utf8.codes"><code>utf8.codes (s)</code></a></h3> |
| 8506 | 8548 | ||
| 8507 | 8549 | ||
| 8508 | <p> | 8550 | <p> |
| 8509 | Inserts element <code>value</code> at position <code>pos</code> in <code>list</code>, | 8551 | Returns values so that the construction |
| 8510 | shifting up the elements | 8552 | |
| 8553 | <pre> | ||
| 8554 | for p, c in utf8.codes(s) do <em>body</em> end | ||
| 8555 | </pre><p> | ||
| 8556 | will iterate over all characters in string <code>s</code>, | ||
| 8557 | with <code>p</code> being the position (in bytes) and <code>c</code> the code point | ||
| 8558 | of each character. | ||
| 8559 | It raises an error if it meets any invalid byte sequence. | ||
| 8560 | |||
| 8561 | |||
| 8562 | |||
| 8563 | |||
| 8564 | <p> | ||
| 8565 | <hr><h3><a name="pdf-utf8.codepoint"><code>utf8.codepoint (s [, i [, j]])</code></a></h3> | ||
| 8566 | Returns the codepoints (as integers) from all characters in <code>s</code> | ||
| 8567 | that start between byte position <code>i</code> and <code>j</code> (both included). | ||
| 8568 | The default for <code>i</code> is 1 and for <code>j</code> is <code>i</code>. | ||
| 8569 | It raises an error if it meets any invalid byte sequence. | ||
| 8570 | |||
| 8571 | |||
| 8572 | |||
| 8573 | |||
| 8574 | <p> | ||
| 8575 | <hr><h3><a name="pdf-utf8.len"><code>utf8.len (s [, i])</code></a></h3> | ||
| 8576 | Returns the number of UTF-8 characters in string <code>s</code>, | ||
| 8577 | starting from position <code>i</code>. | ||
| 8578 | The default for <code>i</code> is 1. | ||
| 8579 | Returns <b>nil</b> if the sufix of <code>s</code> starting at <code>i</code> | ||
| 8580 | contains any invalid byte sequence. | ||
| 8581 | |||
| 8582 | |||
| 8583 | |||
| 8584 | |||
| 8585 | <p> | ||
| 8586 | <hr><h3><a name="pdf-utf8.offset"><code>utf8.offset (s, n [, i])</code></a></h3> | ||
| 8587 | Returns the byte index where the encoding of the | ||
| 8588 | <code>n</code>-th character of <code>s</code> starts, | ||
| 8589 | counting from position <code>i</code>. | ||
| 8590 | A negative <code>n</code> gets characters before position <code>i</code>. | ||
| 8591 | The default for <code>i</code> is 1. | ||
| 8592 | Returns <b>nil</b> if the subject does not have such character. | ||
| 8593 | |||
| 8594 | |||
| 8595 | <p> | ||
| 8596 | As a special case, | ||
| 8597 | when <code>n</code> is 0 the function returns the start of the encoding | ||
| 8598 | of the character that contains the <code>i</code>-th byte of <code>s</code>. | ||
| 8599 | |||
| 8600 | |||
| 8601 | <p> | ||
| 8602 | This function assumes that <code>s</code> is a valid UTF-8 string. | ||
| 8603 | |||
| 8604 | |||
| 8605 | |||
| 8606 | |||
| 8607 | |||
| 8608 | |||
| 8609 | |||
| 8610 | <h2>6.6 – <a name="6.6">Table Manipulation</a></h2> | ||
| 8611 | |||
| 8612 | <p> | ||
| 8613 | This library provides generic functions for table manipulation. | ||
| 8614 | It provides all its functions inside the table <a name="pdf-table"><code>table</code></a>. | ||
| 8615 | |||
| 8616 | |||
| 8617 | <p> | ||
| 8618 | Remember that, whenever an operation needs the length of a table, | ||
| 8619 | the table should be a proper sequence | ||
| 8620 | or have a <code>__len</code> metamethod (see <a href="#3.4.7">§3.4.7</a>). | ||
| 8621 | All functions ignore non-numeric keys | ||
| 8622 | in tables given as arguments. | ||
| 8623 | |||
| 8624 | |||
| 8625 | <p> | ||
| 8626 | For performance reasons, | ||
| 8627 | all table accesses (get/set) performed by these functions are raw. | ||
| 8628 | |||
| 8629 | |||
| 8630 | <p> | ||
| 8631 | <hr><h3><a name="pdf-table.concat"><code>table.concat (list [, sep [, i [, j]]])</code></a></h3> | ||
| 8632 | |||
| 8633 | |||
| 8634 | <p> | ||
| 8635 | Given a list where all elements are strings or numbers, | ||
| 8636 | returns the string <code>list[i]..sep..list[i+1] ··· sep..list[j]</code>. | ||
| 8637 | The default value for <code>sep</code> is the empty string, | ||
| 8638 | the default for <code>i</code> is 1, | ||
| 8639 | and the default for <code>j</code> is <code>#list</code>. | ||
| 8640 | If <code>i</code> is greater than <code>j</code>, returns the empty string. | ||
| 8641 | |||
| 8642 | |||
| 8643 | |||
| 8644 | |||
| 8645 | <p> | ||
| 8646 | <hr><h3><a name="pdf-table.insert"><code>table.insert (list, [pos,] value)</code></a></h3> | ||
| 8647 | |||
| 8648 | |||
| 8649 | <p> | ||
| 8650 | Inserts element <code>value</code> at position <code>pos</code> in <code>list</code>, | ||
| 8651 | shifting up the elements | ||
| 8511 | <code>list[pos], list[pos+1], ···, list[#list]</code>. | 8652 | <code>list[pos], list[pos+1], ···, list[#list]</code>. |
| 8512 | The default value for <code>pos</code> is <code>#list+1</code>, | 8653 | The default value for <code>pos</code> is <code>#list+1</code>, |
| 8513 | so that a call <code>table.insert(t,x)</code> inserts <code>x</code> at the end | 8654 | so that a call <code>table.insert(t,x)</code> inserts <code>x</code> at the end |
| @@ -8546,8 +8687,8 @@ in those cases, the function erases the element <code>list[pos]</code>. · 32 unmodified lines | |||
| 8546 | 8687 | ||
| 8547 | <p> | 8688 | <p> |
| 8548 | The default value for <code>pos</code> is <code>#list</code>, | 8689 | The default value for <code>pos</code> is <code>#list</code>, |
| 8549 | so that a call <code>table.remove(t)</code> removes the last element | 8690 | so that a call <code>table.remove(l)</code> removes the last element |
| 8550 | of list <code>t</code>. | 8691 | of list <code>l</code>. |
| 8551 | 8692 | ||
| 8552 | 8693 | ||
| 8553 | 8694 | ||
| @@ -8581,7 +8722,7 @@ may have their relative positions changed by the sort. · 27 unmodified lines | |||
| 8581 | 8722 | ||
| 8582 | 8723 | ||
| 8583 | <p> | 8724 | <p> |
| 8584 | Returns the elements from the given table. | 8725 | Returns the elements from the given list. |
| 8585 | This function is equivalent to | 8726 | This function is equivalent to |
| 8586 | 8727 | ||
| 8587 | <pre> | 8728 | <pre> |
| @@ -8595,14 +8736,13 @@ By default, <code>i</code> is 1 and <code>j</code> is <code>#list</code>. · 7 unmodified lines | |||
| 8595 | 8736 | ||
| 8596 | 8737 | ||
| 8597 | 8738 | ||
| 8598 | <h2>6.6 – <a name="6.6">Mathematical Functions</a></h2> | 8739 | <h2>6.7 – <a name="6.7">Mathematical Functions</a></h2> |
| 8599 | 8740 | ||
| 8600 | <p> | 8741 | <p> |
| 8601 | This library is an interface to the standard C math library. | 8742 | This library is an interface to the standard C math library. |
| 8602 | It provides all its functions inside the table <a name="pdf-math"><code>math</code></a>. | 8743 | It provides all its functions inside the table <a name="pdf-math"><code>math</code></a>. |
| 8603 | Unless stated otherwise, | 8744 | Unless stated otherwise, |
| 8604 | all functions in this library operate with and return | 8745 | all functions in this library operate with and return floats. |
| 8605 | floating-point numbers. | ||
| 8606 | 8746 | ||
| 8607 | 8747 | ||
| 8608 | <p> | 8748 | <p> |
| @@ -8713,7 +8853,8 @@ Returns the value <em>e<sup>x</sup></em>. · 104 unmodified lines | |||
| 8713 | 8853 | ||
| 8714 | 8854 | ||
| 8715 | <p> | 8855 | <p> |
| 8716 | Returns the largest integer smaller than or equal to <code>x</code>. | 8856 | Returns a float with the largest |
| 8857 | integral value smaller than or equal to <code>x</code>. | ||
| 8717 | 8858 | ||
| 8718 | 8859 | ||
| 8719 | 8860 | ||
| @@ -8758,24 +8899,13 @@ a value larger than or equal to any other numerical value. · 38 unmodified lines | |||
| 8758 | 8899 | ||
| 8759 | 8900 | ||
| 8760 | <p> | 8901 | <p> |
| 8761 | Returns the largest integer smaller than or equal to <code>x</code> | 8902 | Returns the largest integer smaller than or equal to <code>x</code>. |
| 8762 | as an integer number. | ||
| 8763 | If the value does not fit in an integer, | 8903 | If the value does not fit in an integer, |
| 8764 | returns <b>nil</b>. | 8904 | returns <b>nil</b>. |
| 8765 | 8905 | ||
| 8766 | 8906 | ||
| 8767 | 8907 | ||
| 8768 | 8908 | ||
| 8769 | <p> | ||
| 8770 | <hr><h3><a name="pdf-math.isfloat"><code>math.isfloat (x)</code></a></h3> | ||
| 8771 | |||
| 8772 | |||
| 8773 | <p> | ||
| 8774 | Returns whether <code>x</code> is a floating-point number. | ||
| 8775 | |||
| 8776 | |||
| 8777 | |||
| 8778 | |||
| 8779 | <p> | 8909 | <p> |
| 8780 | <hr><h3><a name="pdf-math.ldexp"><code>math.ldexp (m, e)</code></a></h3> | 8910 | <hr><h3><a name="pdf-math.ldexp"><code>math.ldexp (m, e)</code></a></h3> |
| 8781 | 8911 | ||
| @@ -8872,11 +9002,11 @@ pseudo-random generator function <code>rand</code> provided by Standard C. · 90 unmodified lines | |||
| 8872 | 9002 | ||
| 8873 | <p> | 9003 | <p> |
| 8874 | When called without arguments, | 9004 | When called without arguments, |
| 8875 | returns a uniform pseudo-random float number | 9005 | returns a uniform pseudo-random float |
| 8876 | in the range <em>[0,1)</em>. | 9006 | in the range <em>[0,1)</em>. |
| 8877 | When called with two integer values <code>m</code> and <code>n</code>, | 9007 | When called with two integers <code>m</code> and <code>n</code>, |
| 8878 | <code>math.random</code> returns a uniform pseudo-random | 9008 | <code>math.random</code> returns a uniform pseudo-random |
| 8879 | integer number in the range <em>[m, n]</em>. | 9009 | integer in the range <em>[m, n]</em>. |
| 8880 | The call <code>math.random(n)</code> is equivalent to <code>math.random(1,n)</code>. | 9010 | The call <code>math.random(n)</code> is equivalent to <code>math.random(1,n)</code>. |
| 8881 | 9011 | ||
| 8882 | 9012 | ||
| @@ -8945,229 +9075,14 @@ Returns the hyperbolic tangent of <code>x</code>. · 62 unmodified lines | |||
| 8945 | 9075 | ||
| 8946 | 9076 | ||
| 8947 | 9077 | ||
| 8948 | |||
| 8949 | |||
| 8950 | |||
| 8951 | <h2>6.7 – <a name="6.7">Bitwise Operations</a></h2> | ||
| 8952 | |||
| 8953 | <p> | ||
| 8954 | This library provides bitwise operations. | ||
| 8955 | It provides all its functions inside the table <a name="pdf-bit32"><code>bit32</code></a>. | ||
| 8956 | |||
| 8957 | |||
| 8958 | <p> | ||
| 8959 | Unless otherwise stated, | ||
| 8960 | all functions accept numeric arguments in the range | ||
| 8961 | <em>(-2<sup>51</sup>,+2<sup>51</sup>)</em>; | ||
| 8962 | each argument is normalized to | ||
| 8963 | the remainder of its division by <em>2<sup>32</sup></em> | ||
| 8964 | and truncated to an integer (in some unspecified way), | ||
| 8965 | so that its final value falls in the range <em>[0,2<sup>32</sup> - 1]</em>. | ||
| 8966 | Similarly, all results are in the range <em>[0,2<sup>32</sup> - 1]</em>. | ||
| 8967 | Note that <code>bit32.bnot(0)</code> is <code>0xFFFFFFFF</code>, | ||
| 8968 | which is different from <code>-1</code>. | ||
| 8969 | |||
| 8970 | |||
| 8971 | <p> | ||
| 8972 | <hr><h3><a name="pdf-bit32.arshift"><code>bit32.arshift (x, disp)</code></a></h3> | ||
| 8973 | |||
| 8974 | |||
| 8975 | <p> | ||
| 8976 | Returns the number <code>x</code> shifted <code>disp</code> bits to the right. | ||
| 8977 | The number <code>disp</code> may be any representable integer. | ||
| 8978 | Negative displacements shift to the left. | ||
| 8979 | |||
| 8980 | |||
| 8981 | <p> | ||
| 8982 | This shift operation is what is called arithmetic shift. | ||
| 8983 | Vacant bits on the left are filled | ||
| 8984 | with copies of the higher bit of <code>x</code>; | ||
| 8985 | vacant bits on the right are filled with zeros. | ||
| 8986 | In particular, | ||
| 8987 | displacements with absolute values higher than 31 | ||
| 8988 | result in zero or <code>0xFFFFFFFF</code> (all original bits are shifted out). | ||
| 8989 | |||
| 8990 | |||
| 8991 | |||
| 8992 | |||
| 8993 | <p> | ||
| 8994 | <hr><h3><a name="pdf-bit32.band"><code>bit32.band (···)</code></a></h3> | ||
| 8995 | |||
| 8996 | |||
| 8997 | <p> | ||
| 8998 | Returns the bitwise <em>and</em> of its operands. | ||
| 8999 | |||
| 9000 | |||
| 9001 | |||
| 9002 | |||
| 9003 | <p> | ||
| 9004 | <hr><h3><a name="pdf-bit32.bnot"><code>bit32.bnot (x)</code></a></h3> | ||
| 9005 | |||
| 9006 | |||
| 9007 | <p> | ||
| 9008 | Returns the bitwise negation of <code>x</code>. | ||
| 9009 | For any integer <code>x</code>, | ||
| 9010 | the following identity holds: | ||
| 9011 | |||
| 9012 | <pre> | ||
| 9013 | assert(bit32.bnot(x) == (-1 - x) % 2^32) | ||
| 9014 | </pre> | ||
| 9015 | |||
| 9016 | |||
| 9017 | |||
| 9018 | <p> | ||
| 9019 | <hr><h3><a name="pdf-bit32.bor"><code>bit32.bor (···)</code></a></h3> | ||
| 9020 | |||
| 9021 | |||
| 9022 | <p> | ||
| 9023 | Returns the bitwise <em>or</em> of its operands. | ||
| 9024 | |||
| 9025 | |||
| 9026 | |||
| 9027 | |||
| 9028 | <p> | 9078 | <p> |
| 9029 | <hr><h3><a name="pdf-bit32.btest"><code>bit32.btest (···)</code></a></h3> | 9079 | <hr><h3><a name="pdf-math.type"><code>math.type (x)</code></a></h3> |
| 9030 | 9080 | ||
| 9031 | 9081 | ||
| 9032 | <p> | 9082 | <p> |
| 9033 | Returns a boolean signaling | 9083 | Returns "<code>integer</code>" if <code>x</code> is an integer, |
| 9034 | whether the bitwise <em>and</em> of its operands is different from zero. | 9084 | "<code>float</code>" if it is a float, |
| 9035 | 9085 | or <b>nil</b> if <code>x</code> is not a number. | |
| 9036 | |||
| 9037 | |||
| 9038 | |||
| 9039 | <p> | ||
| 9040 | <hr><h3><a name="pdf-bit32.bxor"><code>bit32.bxor (···)</code></a></h3> | ||
| 9041 | |||
| 9042 | |||
| 9043 | <p> | ||
| 9044 | Returns the bitwise <em>exclusive or</em> of its operands. | ||
| 9045 | |||
| 9046 | |||
| 9047 | |||
| 9048 | |||
| 9049 | <p> | ||
| 9050 | <hr><h3><a name="pdf-bit32.extract"><code>bit32.extract (n, field [, width])</code></a></h3> | ||
| 9051 | |||
| 9052 | |||
| 9053 | <p> | ||
| 9054 | Returns the unsigned number formed by the bits | ||
| 9055 | <code>field</code> to <code>field + width - 1</code> from <code>n</code>. | ||
| 9056 | Bits are numbered from 0 (least significant) to 31 (most significant). | ||
| 9057 | All accessed bits must be in the range <em>[0, 31]</em>. | ||
| 9058 | |||
| 9059 | |||
| 9060 | <p> | ||
| 9061 | The default for <code>width</code> is 1. | ||
| 9062 | |||
| 9063 | |||
| 9064 | |||
| 9065 | |||
| 9066 | <p> | ||
| 9067 | <hr><h3><a name="pdf-bit32.replace"><code>bit32.replace (n, v, field [, width])</code></a></h3> | ||
| 9068 | |||
| 9069 | |||
| 9070 | <p> | ||
| 9071 | Returns a copy of <code>n</code> with | ||
| 9072 | the bits <code>field</code> to <code>field + width - 1</code> | ||
| 9073 | replaced by the value <code>v</code>. | ||
| 9074 | See <a href="#pdf-bit32.extract"><code>bit32.extract</code></a> for details about <code>field</code> and <code>width</code>. | ||
| 9075 | |||
| 9076 | |||
| 9077 | |||
| 9078 | |||
| 9079 | <p> | ||
| 9080 | <hr><h3><a name="pdf-bit32.lrotate"><code>bit32.lrotate (x, disp)</code></a></h3> | ||
| 9081 | |||
| 9082 | |||
| 9083 | <p> | ||
| 9084 | Returns the number <code>x</code> rotated <code>disp</code> bits to the left. | ||
| 9085 | The number <code>disp</code> may be any representable integer. | ||
| 9086 | |||
| 9087 | |||
| 9088 | <p> | ||
| 9089 | For any valid displacement, | ||
| 9090 | the following identity holds: | ||
| 9091 | |||
| 9092 | <pre> | ||
| 9093 | assert(bit32.lrotate(x, disp) == bit32.lrotate(x, disp % 32)) | ||
| 9094 | </pre><p> | ||
| 9095 | In particular, | ||
| 9096 | negative displacements rotate to the right. | ||
| 9097 | |||
| 9098 | |||
| 9099 | |||
| 9100 | |||
| 9101 | <p> | ||
| 9102 | <hr><h3><a name="pdf-bit32.lshift"><code>bit32.lshift (x, disp)</code></a></h3> | ||
| 9103 | |||
| 9104 | |||
| 9105 | <p> | ||
| 9106 | Returns the number <code>x</code> shifted <code>disp</code> bits to the left. | ||
| 9107 | The number <code>disp</code> may be any representable integer. | ||
| 9108 | Negative displacements shift to the right. | ||
| 9109 | In any direction, vacant bits are filled with zeros. | ||
| 9110 | In particular, | ||
| 9111 | displacements with absolute values higher than 31 | ||
| 9112 | result in zero (all bits are shifted out). | ||
| 9113 | |||
| 9114 | |||
| 9115 | <p> | ||
| 9116 | For positive displacements, | ||
| 9117 | the following equality holds: | ||
| 9118 | |||
| 9119 | <pre> | ||
| 9120 | assert(bit32.lshift(b, disp) == (b * 2^disp) % 2^32) | ||
| 9121 | </pre> | ||
| 9122 | |||
| 9123 | |||
| 9124 | |||
| 9125 | <p> | ||
| 9126 | <hr><h3><a name="pdf-bit32.rrotate"><code>bit32.rrotate (x, disp)</code></a></h3> | ||
| 9127 | |||
| 9128 | |||
| 9129 | <p> | ||
| 9130 | Returns the number <code>x</code> rotated <code>disp</code> bits to the right. | ||
| 9131 | The number <code>disp</code> may be any representable integer. | ||
| 9132 | |||
| 9133 | |||
| 9134 | <p> | ||
| 9135 | For any valid displacement, | ||
| 9136 | the following identity holds: | ||
| 9137 | |||
| 9138 | <pre> | ||
| 9139 | assert(bit32.rrotate(x, disp) == bit32.rrotate(x, disp % 32)) | ||
| 9140 | </pre><p> | ||
| 9141 | In particular, | ||
| 9142 | negative displacements rotate to the left. | ||
| 9143 | |||
| 9144 | |||
| 9145 | |||
| 9146 | |||
| 9147 | <p> | ||
| 9148 | <hr><h3><a name="pdf-bit32.rshift"><code>bit32.rshift (x, disp)</code></a></h3> | ||
| 9149 | |||
| 9150 | |||
| 9151 | <p> | ||
| 9152 | Returns the number <code>x</code> shifted <code>disp</code> bits to the right. | ||
| 9153 | The number <code>disp</code> may be any representable integer. | ||
| 9154 | Negative displacements shift to the left. | ||
| 9155 | In any direction, vacant bits are filled with zeros. | ||
| 9156 | In particular, | ||
| 9157 | displacements with absolute values higher than 31 | ||
| 9158 | result in zero (all bits are shifted out). | ||
| 9159 | |||
| 9160 | |||
| 9161 | <p> | ||
| 9162 | For positive displacements, | ||
| 9163 | the following equality holds: | ||
| 9164 | |||
| 9165 | <pre> | ||
| 9166 | assert(bit32.rshift(b, disp) == math.floor(b % 2^32 / 2^disp)) | ||
| 9167 | </pre> | ||
| 9168 | |||
| 9169 | <p> | ||
| 9170 | This shift operation is what is called logical shift. | ||
| 9171 | 9086 | ||
| 9172 | 9087 | ||
| 9173 | 9088 | ||
| @@ -9179,24 +9094,24 @@ This shift operation is what is called logical shift. · 5 unmodified lines | |||
| 9179 | 9094 | ||
| 9180 | <p> | 9095 | <p> |
| 9181 | The I/O library provides two different styles for file manipulation. | 9096 | The I/O library provides two different styles for file manipulation. |
| 9182 | The first one uses implicit file descriptors; | 9097 | The first one uses implicit file handles; |
| 9183 | that is, there are operations to set a default input file and a | 9098 | that is, there are operations to set a default input file and a |
| 9184 | default output file, | 9099 | default output file, |
| 9185 | and all input/output operations are over these default files. | 9100 | and all input/output operations are over these default files. |
| 9186 | The second style uses explicit file descriptors. | 9101 | The second style uses explicit file handles. |
| 9187 | 9102 | ||
| 9188 | 9103 | ||
| 9189 | <p> | 9104 | <p> |
| 9190 | When using implicit file descriptors, | 9105 | When using implicit file handles, |
| 9191 | all operations are supplied by table <a name="pdf-io"><code>io</code></a>. | 9106 | all operations are supplied by table <a name="pdf-io"><code>io</code></a>. |
| 9192 | When using explicit file descriptors, | 9107 | When using explicit file handles, |
| 9193 | the operation <a href="#pdf-io.open"><code>io.open</code></a> returns a file descriptor | 9108 | the operation <a href="#pdf-io.open"><code>io.open</code></a> returns a file handle |
| 9194 | and then all operations are supplied as methods of the file descriptor. | 9109 | and then all operations are supplied as methods of the file handle. |
| 9195 | 9110 | ||
| 9196 | 9111 | ||
| 9197 | <p> | 9112 | <p> |
| 9198 | The table <code>io</code> also provides | 9113 | The table <code>io</code> also provides |
| 9199 | three predefined file descriptors with their usual meanings from C: | 9114 | three predefined file handles with their usual meanings from C: |
| 9200 | <a name="pdf-io.stdin"><code>io.stdin</code></a>, <a name="pdf-io.stdout"><code>io.stdout</code></a>, and <a name="pdf-io.stderr"><code>io.stderr</code></a>. | 9115 | <a name="pdf-io.stdin"><code>io.stdin</code></a>, <a name="pdf-io.stdout"><code>io.stdout</code></a>, and <a name="pdf-io.stderr"><code>io.stderr</code></a>. |
| 9201 | The I/O library never closes these files. | 9116 | The I/O library never closes these files. |
| 9202 | 9117 | ||
| @@ -9207,7 +9122,7 @@ all I/O functions return <b>nil</b> on failure · 4 unmodified lines | |||
| 9207 | (plus an error message as a second result and | 9122 | (plus an error message as a second result and |
| 9208 | a system-dependent error code as a third result) | 9123 | a system-dependent error code as a third result) |
| 9209 | and some value different from <b>nil</b> on success. | 9124 | and some value different from <b>nil</b> on success. |
| 9210 | On non-Posix systems, | 9125 | On non-POSIX systems, |
| 9211 | the computation of the error message and error code | 9126 | the computation of the error message and error code |
| 9212 | in case of errors | 9127 | in case of errors |
| 9213 | may be not thread safe, | 9128 | may be not thread safe, |
| @@ -9264,12 +9179,12 @@ Opens the given file name in read mode · 50 unmodified lines | |||
| 9264 | and returns an iterator function that | 9179 | and returns an iterator function that |
| 9265 | works like <code>file:lines(···)</code> over the opened file. | 9180 | works like <code>file:lines(···)</code> over the opened file. |
| 9266 | When the iterator function detects the end of file, | 9181 | When the iterator function detects the end of file, |
| 9267 | it returns <b>nil</b> (to finish the loop) and automatically closes the file. | 9182 | it returns no values (to finish the loop) and automatically closes the file. |
| 9268 | 9183 | ||
| 9269 | 9184 | ||
| 9270 | <p> | 9185 | <p> |
| 9271 | The call <code>io.lines()</code> (with no file name) is equivalent | 9186 | The call <code>io.lines()</code> (with no file name) is equivalent |
| 9272 | to <code>io.input():lines()</code>; | 9187 | to <code>io.input():lines("*l")</code>; |
| 9273 | that is, it iterates over the lines of the default input file. | 9188 | that is, it iterates over the lines of the default input file. |
| 9274 | In this case it does not close the file when the loop ends. | 9189 | In this case it does not close the file when the loop ends. |
| 9275 | 9190 | ||
| @@ -9449,7 +9364,7 @@ instead of returning an error code. · 173 unmodified lines | |||
| 9449 | Reads the file <code>file</code>, | 9364 | Reads the file <code>file</code>, |
| 9450 | according to the given formats, which specify what to read. | 9365 | according to the given formats, which specify what to read. |
| 9451 | For each format, | 9366 | For each format, |
| 9452 | the function returns a string (or a number) with the characters read, | 9367 | the function returns a string or a number with the characters read, |
| 9453 | or <b>nil</b> if it cannot read data with the specified format. | 9368 | or <b>nil</b> if it cannot read data with the specified format. |
| 9454 | When called without formats, | 9369 | When called without formats, |
| 9455 | it uses a default format that reads the next line | 9370 | it uses a default format that reads the next line |
| @@ -9462,8 +9377,15 @@ The available formats are · 6 unmodified lines | |||
| 9462 | <ul> | 9377 | <ul> |
| 9463 | 9378 | ||
| 9464 | <li><b>"<code>*n</code>": </b> | 9379 | <li><b>"<code>*n</code>": </b> |
| 9465 | reads a number; | 9380 | reads a number and returns it as a float. |
| 9466 | this is the only format that returns a number instead of a string. | 9381 | If the input has only a prefix of a valid number |
| 9382 | (e.g., "<code>0x</code>" or "<code>3.4e-</code>"), | ||
| 9383 | this format can read the entire prefix | ||
| 9384 | even when returning <b>nil</b>. | ||
| 9385 | </li> | ||
| 9386 | |||
| 9387 | <li><b>"<code>*i</code>": </b> | ||
| 9388 | reads an integral number and returns it as an integer. | ||
| 9467 | </li> | 9389 | </li> |
| 9468 | 9390 | ||
| 9469 | <li><b>"<code>*a</code>": </b> | 9391 | <li><b>"<code>*a</code>": </b> |
| @@ -9478,19 +9400,21 @@ This is the default format. · 8 unmodified lines | |||
| 9478 | </li> | 9400 | </li> |
| 9479 | 9401 | ||
| 9480 | <li><b>"<code>*L</code>": </b> | 9402 | <li><b>"<code>*L</code>": </b> |
| 9481 | reads the next line keeping the end of line (if present), | 9403 | reads the next line keeping the end-of-line character (if present), |
| 9482 | returning <b>nil</b> on end of file. | 9404 | returning <b>nil</b> on end of file. |
| 9483 | </li> | 9405 | </li> |
| 9484 | 9406 | ||
| 9485 | <li><b><em>number</em>: </b> | 9407 | <li><b><em>number</em>: </b> |
| 9486 | reads a string with up to this number of bytes, | 9408 | reads a string with up to this number of bytes, |
| 9487 | returning <b>nil</b> on end of file. | 9409 | returning <b>nil</b> on end of file. |
| 9488 | If number is zero, | 9410 | If <code>number</code> is zero, |
| 9489 | it reads nothing and returns an empty string, | 9411 | it reads nothing and returns an empty string, |
| 9490 | or <b>nil</b> on end of file. | 9412 | or <b>nil</b> on end of file. |
| 9491 | </li> | 9413 | </li> |
| 9492 | 9414 | ||
| 9493 | </ul> | 9415 | </ul><p> |
| 9416 | The formats "<code>*l</code>" and "<code>*L</code>" should be used only for text files. | ||
| 9417 | |||
| 9494 | 9418 | ||
| 9495 | 9419 | ||
| 9496 | 9420 | ||
| @@ -9643,7 +9567,7 @@ the host system and on the current locale · 146 unmodified lines | |||
| 9643 | 9567 | ||
| 9644 | 9568 | ||
| 9645 | <p> | 9569 | <p> |
| 9646 | On non-Posix systems, | 9570 | On non-POSIX systems, |
| 9647 | this function may be not thread safe | 9571 | this function may be not thread safe |
| 9648 | because of its reliance on C function <code>gmtime</code> and C function <code>localtime</code>. | 9572 | because of its reliance on C function <code>gmtime</code> and C function <code>localtime</code>. |
| 9649 | 9573 | ||
| @@ -9673,7 +9597,7 @@ Its first result is <b>true</b> · 23 unmodified lines | |||
| 9673 | if the command terminated successfully, | 9597 | if the command terminated successfully, |
| 9674 | or <b>nil</b> otherwise. | 9598 | or <b>nil</b> otherwise. |
| 9675 | After this first result | 9599 | After this first result |
| 9676 | the function returns a string and a number, | 9600 | the function returns a string plus a number, |
| 9677 | as follows: | 9601 | as follows: |
| 9678 | 9602 | ||
| 9679 | <ul> | 9603 | <ul> |
| @@ -9975,8 +9899,9 @@ and raises an error when called with a level out of range. · 295 unmodified lines | |||
| 9975 | 9899 | ||
| 9976 | <p> | 9900 | <p> |
| 9977 | Variable names starting with '<code>(</code>' (open parenthesis) | 9901 | Variable names starting with '<code>(</code>' (open parenthesis) |
| 9978 | represent internal variables | 9902 | represent variables with no known names |
| 9979 | (loop control variables, temporaries, varargs, and C function locals). | 9903 | (internal variables like loop control variables, |
| 9904 | and variables from chunks saved without debug information). | ||
| 9980 | 9905 | ||
| 9981 | 9906 | ||
| 9982 | <p> | 9907 | <p> |
| @@ -10017,6 +9942,12 @@ with index <code>up</code> of the function <code>f</code>. · 34 unmodified lines | |||
| 10017 | The function returns <b>nil</b> if there is no upvalue with the given index. | 9942 | The function returns <b>nil</b> if there is no upvalue with the given index. |
| 10018 | 9943 | ||
| 10019 | 9944 | ||
| 9945 | <p> | ||
| 9946 | Variable names starting with '<code>(</code>' (open parenthesis) | ||
| 9947 | represent variables with no known names | ||
| 9948 | (variables from chunks saved without debug information). | ||
| 9949 | |||
| 9950 | |||
| 10020 | 9951 | ||
| 10021 | 9952 | ||
| 10022 | <p> | 9953 | <p> |
| @@ -10037,8 +9968,8 @@ returns <b>nil</b>. · 14 unmodified lines | |||
| 10037 | 9968 | ||
| 10038 | <p> | 9969 | <p> |
| 10039 | Returns the number of bits in the underlying representation | 9970 | Returns the number of bits in the underlying representation |
| 10040 | of integer (if <code>t</code> is "<code>i</code>") | 9971 | of an integer (if <code>t</code> is "<code>i</code>") |
| 10041 | or float numbers (if <code>t</code> is "<code>f</code>"). | 9972 | or a float (if <code>t</code> is "<code>f</code>"). |
| 10042 | 9973 | ||
| 10043 | 9974 | ||
| 10044 | 9975 | ||
| @@ -10140,7 +10071,6 @@ Otherwise, it returns the name of the upvalue. · 95 unmodified lines | |||
| 10140 | <p> | 10071 | <p> |
| 10141 | Sets the given <code>value</code> as | 10072 | Sets the given <code>value</code> as |
| 10142 | the Lua value associated to the given <code>udata</code>. | 10073 | the Lua value associated to the given <code>udata</code>. |
| 10143 | <code>value</code> must be a table or <b>nil</b>; | ||
| 10144 | <code>udata</code> must be a full userdata. | 10074 | <code>udata</code> must be a full userdata. |
| 10145 | 10075 | ||
| 10146 | 10076 | ||
| @@ -10352,139 +10282,65 @@ is a more portable solution.) · 205 unmodified lines | |||
| 10352 | 10282 | ||
| 10353 | <p> | 10283 | <p> |
| 10354 | Here we list the incompatibilities that you may find when moving a program | 10284 | Here we list the incompatibilities that you may find when moving a program |
| 10355 | from Lua 5.1 to Lua 5.2. | 10285 | from Lua 5.2 to Lua 5.3. |
| 10356 | You can avoid some incompatibilities by compiling Lua with | 10286 | You can avoid some incompatibilities by compiling Lua with |
| 10357 | appropriate options (see file <code>luaconf.h</code>). | 10287 | appropriate options (see file <code>luaconf.h</code>). |
| 10358 | However, | 10288 | However, |
| 10359 | all these compatibility options will be removed in the next version of Lua. | 10289 | all these compatibility options will be removed in the future. |
| 10360 | Similarly, | ||
| 10361 | all features marked as deprecated in Lua 5.1 | ||
| 10362 | have been removed in Lua 5.2. | ||
| 10363 | |||
| 10364 | |||
| 10365 | |||
| 10366 | <h2>8.1 – <a name="8.1">Changes in the Language</a></h2> | ||
| 10367 | <ul> | ||
| 10368 | |||
| 10369 | <li> | ||
| 10370 | The concept of <em>environment</em> changed. | ||
| 10371 | Only Lua functions have environments. | ||
| 10372 | To set the environment of a Lua function, | ||
| 10373 | use the variable <code>_ENV</code> or the function <a href="#pdf-load"><code>load</code></a>. | ||
| 10374 | 10290 | ||
| 10375 | 10291 | ||
| 10376 | <p> | 10292 | <p> |
| 10377 | C functions no longer have environments. | 10293 | Lua versions can always change the C API in ways that |
| 10378 | Use an upvalue with a shared table if you need to keep | 10294 | do not imply source-code changes in a program, |
| 10379 | shared state among several C functions. | 10295 | such as the numeric values for constants |
| 10380 | (You may use <a href="#luaL_setfuncs"><code>luaL_setfuncs</code></a> to open a C library | 10296 | or the implementation of functions as macros. |
| 10381 | with all functions sharing a common upvalue.) | 10297 | Therefore, |
| 10298 | you should never assume that binaries are compatible between | ||
| 10299 | different Lua versions. | ||
| 10300 | Always recompile clients of the Lua API when | ||
| 10301 | using a new version. | ||
| 10382 | 10302 | ||
| 10383 | 10303 | ||
| 10384 | <p> | 10304 | <p> |
| 10385 | To manipulate the "environment" of a userdata | 10305 | The standard paths in the official distribution may |
| 10386 | (which is now called user value), | 10306 | change between versions. |
| 10387 | use the new functions | ||
| 10388 | <a href="#lua_getuservalue"><code>lua_getuservalue</code></a> and <a href="#lua_setuservalue"><code>lua_setuservalue</code></a>. | ||
| 10389 | </li> | ||
| 10390 | |||
| 10391 | <li> | ||
| 10392 | Lua identifiers cannot use locale-dependent letters. | ||
| 10393 | </li> | ||
| 10394 | |||
| 10395 | <li> | ||
| 10396 | Doing a step or a full collection in the garbage collector | ||
| 10397 | does not restart the collector if it has been stopped. | ||
| 10398 | </li> | ||
| 10399 | |||
| 10400 | <li> | ||
| 10401 | Weak tables with weak keys now perform like <em>ephemeron tables</em>. | ||
| 10402 | </li> | ||
| 10403 | |||
| 10404 | <li> | ||
| 10405 | The event <em>tail return</em> in debug hooks was removed. | ||
| 10406 | Instead, tail calls generate a special new event, | ||
| 10407 | <em>tail call</em>, so that the debugger can know that | ||
| 10408 | there will not be a corresponding return event. | ||
| 10409 | </li> | ||
| 10410 | |||
| 10411 | <li> | ||
| 10412 | Equality between function values has changed. | ||
| 10413 | Now, a function definition may not create a new value; | ||
| 10414 | it may reuse some previous value if there is no | ||
| 10415 | observable difference to the new function. | ||
| 10416 | </li> | ||
| 10417 | |||
| 10418 | </ul> | ||
| 10419 | |||
| 10420 | 10307 | ||
| 10421 | 10308 | ||
| 10422 | 10309 | ||
| 10423 | <h2>8.2 – <a name="8.2">Changes in the Libraries</a></h2> | 10310 | <h2>8.1 – <a name="8.1">Changes in the Language</a></h2> |
| 10424 | <ul> | 10311 | <ul> |
| 10425 | 10312 | ||
| 10426 | <li> | 10313 | <li> |
| 10427 | Function <code>module</code> is deprecated. | 10314 | The main difference between Lua 5.2 and Lua 5.3 is the |
| 10428 | It is easy to set up a module with regular Lua code. | 10315 | introduction of an integer subtype for numbers. |
| 10429 | Modules are not expected to set global variables. | 10316 | Although this change should not affect "normal" computations, |
| 10430 | </li> | 10317 | some computations |
| 10318 | (mainly those that involve some kind of overflow) | ||
| 10319 | can give different results. | ||
| 10431 | 10320 | ||
| 10432 | <li> | ||
| 10433 | Functions <code>setfenv</code> and <code>getfenv</code> were removed, | ||
| 10434 | because of the changes in environments. | ||
| 10435 | </li> | ||
| 10436 | 10321 | ||
| 10437 | <li> | 10322 | <p> |
| 10438 | Function <code>math.log10</code> is deprecated. | 10323 | You can fix these differences by forcing a number to be a float |
| 10439 | Use <a href="#pdf-math.log"><code>math.log</code></a> with 10 as its second argument, instead. | 10324 | (in Lua 5.2 all numbers were float), |
| 10440 | </li> | 10325 | in particular writing constants with an ending <code>.0</code> |
| 10441 | 10326 | or using <code>x = x + 0.0</code> to convert a variable. | |
| 10442 | <li> | 10327 | (This recommendation is only for a quick fix |
| 10443 | Function <code>loadstring</code> is deprecated. | 10328 | for an occasional incompatibility, |
| 10444 | Use <code>load</code> instead; it now accepts string arguments | 10329 | not as a general guideline for good programming. |
| 10445 | and are exactly equivalent to <code>loadstring</code>. | 10330 | For good programming, |
| 10446 | </li> | 10331 | use floats where you need floats |
| 10447 | 10332 | and integers where you need integers.) | |
| 10448 | <li> | ||
| 10449 | Function <code>table.maxn</code> is deprecated. | ||
| 10450 | Write it in Lua if you really need it. | ||
| 10451 | </li> | ||
| 10452 | |||
| 10453 | <li> | ||
| 10454 | Function <code>os.execute</code> now returns <b>true</b> when command | ||
| 10455 | terminates successfully and <b>nil</b> plus error information | ||
| 10456 | otherwise. | ||
| 10457 | </li> | ||
| 10458 | |||
| 10459 | <li> | ||
| 10460 | Function <code>unpack</code> was moved into the table library | ||
| 10461 | and therefore must be called as <a href="#pdf-table.unpack"><code>table.unpack</code></a>. | ||
| 10462 | </li> | ||
| 10463 | |||
| 10464 | <li> | ||
| 10465 | Character class <code>%z</code> in patterns is deprecated, | ||
| 10466 | as now patterns may contain '<code>\0</code>' as a regular character. | ||
| 10467 | </li> | ||
| 10468 | 10333 | ||
| 10469 | <li> | ||
| 10470 | The table <code>package.loaders</code> was renamed <code>package.searchers</code>. | ||
| 10471 | </li> | ||
| 10472 | 10334 | ||
| 10473 | <li> | 10335 | <p> |
| 10474 | Lua does not have bytecode verification anymore. | 10336 | Although not formally an incompatibility, |
| 10475 | So, all functions that load code | 10337 | the proper differentiation between floats and integers |
| 10476 | (<a href="#pdf-load"><code>load</code></a> and <a href="#pdf-loadfile"><code>loadfile</code></a>) | 10338 | can sometimes have a big impact on performance. |
| 10477 | are potentially insecure when loading untrusted binary data. | ||
| 10478 | (Actually, those functions were already insecure because | ||
| 10479 | of flaws in the verification algorithm.) | ||
| 10480 | When in doubt, | ||
| 10481 | use the <code>mode</code> argument of those functions | ||
| 10482 | to restrict them to loading textual chunks. | ||
| 10483 | </li> | 10339 | </li> |
| 10484 | 10340 | ||
| 10485 | <li> | 10341 | <li> |
| 10486 | The standard paths in the official distribution may | 10342 | The generational mode for the garbage collector was removed. |
| 10487 | change between versions. | 10343 | (It was an experimental feature in Lua 5.2.) |
| 10488 | </li> | 10344 | </li> |
| 10489 | 10345 | ||
| 10490 | </ul> | 10346 | </ul> |
| @@ -10492,76 +10348,39 @@ change between versions. · 1 unmodified line | |||
| 10492 | 10348 | ||
| 10493 | 10349 | ||
| 10494 | 10350 | ||
| 10495 | <h2>8.3 – <a name="8.3">Changes in the API</a></h2> | 10351 | <h2>8.2 – <a name="8.2">Changes in the Libraries</a></h2> |
| 10496 | <ul> | 10352 | <ul> |
| 10497 | 10353 | ||
| 10498 | <li> | 10354 | <li> |
| 10499 | Pseudoindex <code>LUA_GLOBALSINDEX</code> was removed. | 10355 | The conversion of a float to a string through <a href="#pdf-tostring"><code>tostring</code></a> |
| 10500 | You must get the global environment from the registry | 10356 | (which is used by <a href="#pdf-print"><code>print</code></a>) now adds a <code>.0</code> suffix if the |
| 10501 | (see <a href="#4.5">§4.5</a>). | 10357 | number has an integral value. |
| 10502 | </li> | 10358 | (For instance, the float 2.0 will be printed as <code>2.0</code>, |
| 10503 | 10359 | not as <code>2</code>.) | |
| 10504 | <li> | 10360 | You should always use an explicit format |
| 10505 | Pseudoindex <code>LUA_ENVIRONINDEX</code> | 10361 | when you need a specific format for numbers. |
| 10506 | and functions <code>lua_getfenv</code>/<code>lua_setfenv</code> | ||
| 10507 | were removed, | ||
| 10508 | as C functions no longer have environments. | ||
| 10509 | </li> | 10362 | </li> |
| 10510 | 10363 | ||
| 10511 | <li> | 10364 | <li> |
| 10512 | Function <code>luaL_register</code> is deprecated. | 10365 | The <code>bit32</code> library has been deprecated. |
| 10513 | Use <a href="#luaL_setfuncs"><code>luaL_setfuncs</code></a> so that your module does not create globals. | 10366 | It is easy to require a compatible external library or, |
| 10514 | (Modules are not expected to set global variables anymore.) | 10367 | better yet, to replace its functions with appropriate bitwise operations. |
| 10368 | (Just keep in mind that <code>bit32</code> operates on 32-bit integers, | ||
| 10369 | while the bitwise operators in Standard Lua operate on 64-bit integers.) | ||
| 10515 | </li> | 10370 | </li> |
| 10516 | 10371 | ||
| 10517 | <li> | 10372 | </ul> |
| 10518 | The <code>osize</code> argument to the allocation function | ||
| 10519 | may not be zero when creating a new block, | ||
| 10520 | that is, when <code>ptr</code> is <code>NULL</code> | ||
| 10521 | (see <a href="#lua_Alloc"><code>lua_Alloc</code></a>). | ||
| 10522 | Use only the test <code>ptr == NULL</code> to check whether | ||
| 10523 | the block is new. | ||
| 10524 | </li> | ||
| 10525 | 10373 | ||
| 10526 | <li> | ||
| 10527 | Finalizers (<code>__gc</code> metamethods) for userdata are called in the | ||
| 10528 | reverse order that they were marked for finalization, | ||
| 10529 | not that they were created (see <a href="#2.5.1">§2.5.1</a>). | ||
| 10530 | (Most userdata are marked immediately after they are created.) | ||
| 10531 | Moreover, | ||
| 10532 | if the metatable does not have a <code>__gc</code> field when set, | ||
| 10533 | the finalizer will not be called, | ||
| 10534 | even if it is set later. | ||
| 10535 | </li> | ||
| 10536 | 10374 | ||
| 10537 | <li> | ||
| 10538 | <code>luaL_typerror</code> was removed. | ||
| 10539 | Write your own version if you need it. | ||
| 10540 | </li> | ||
| 10541 | 10375 | ||
| 10542 | <li> | ||
| 10543 | Function <code>lua_cpcall</code> is deprecated. | ||
| 10544 | You can simply push the function with <a href="#lua_pushcfunction"><code>lua_pushcfunction</code></a> | ||
| 10545 | and call it with <a href="#lua_pcall"><code>lua_pcall</code></a>. | ||
| 10546 | </li> | ||
| 10547 | 10376 | ||
| 10548 | <li> | 10377 | <h2>8.3 – <a name="8.3">Changes in the API</a></h2> |
| 10549 | Functions <code>lua_equal</code> and <code>lua_lessthan</code> are deprecated. | ||
| 10550 | Use the new <a href="#lua_compare"><code>lua_compare</code></a> with appropriate options instead. | ||
| 10551 | </li> | ||
| 10552 | 10378 | ||
| 10553 | <li> | ||
| 10554 | Function <code>lua_objlen</code> was renamed <a href="#lua_rawlen"><code>lua_rawlen</code></a>. | ||
| 10555 | </li> | ||
| 10556 | 10379 | ||
| 10557 | <li> | 10380 | <ul> |
| 10558 | Function <a href="#lua_load"><code>lua_load</code></a> has an extra parameter, <code>mode</code>. | ||
| 10559 | Pass <code>NULL</code> to simulate the old behavior. | ||
| 10560 | </li> | ||
| 10561 | 10381 | ||
| 10562 | <li> | 10382 | <li> |
| 10563 | Function <a href="#lua_resume"><code>lua_resume</code></a> has an extra parameter, <code>from</code>. | 10383 | No changes (yet). |
| 10564 | Pass <code>NULL</code> or the thread doing the call. | ||
| 10565 | </li> | 10384 | </li> |
| 10566 | 10385 | ||
| 10567 | </ul> | 10386 | </ul> |
| @@ -10649,17 +10468,17 @@ Here is the complete syntax of Lua in extended BNF. · 81 unmodified lines | |||
| 10649 | 10468 | ||
| 10650 | 10469 | ||
| 10651 | 10470 | ||
| 10652 | 10471 | } | |
| 10653 | 10472 | ||
| 10654 | 10473 | ||
| 10655 | 10474 | ||
| 10656 | <HR> | 10475 | <HR> |
| 10657 | <SMALL CLASS="footer"> | 10476 | <SMALL CLASS="footer"> |
| 10658 | Last update: | 10477 | Last update: |
| 10659 | Fri Jul 5 23:09:01 BRT 2013 | 10478 | Fri Mar 21 17:33:56 BRT 2014 |
| 10660 | </SMALL> | 10479 | </SMALL> |
| 10661 | <!-- | 10480 | <!-- |
| 10662 | Last change: updated for Lua 5.3.0 (work1) | 10481 | Last change: updated for Lua 5.3.0 (work2) |
| 10663 | --> | 10482 | --> |
| 10664 | 10483 | ||
| 10665 | </body></html> | 10484 | </body></html> |
| @@ -9,6 +9,7 @@ blockquote, .display { · 8 unmodified lines | |||
| 9 | border: solid #a0a0a0 2px ; | 9 | border: solid #a0a0a0 2px ; |
| 10 | padding: 1em ; | 10 | padding: 1em ; |
| 11 | margin: 0px ; | 11 | margin: 0px ; |
| 12 | border-radius: 8px ; | ||
| 12 | } | 13 | } |
| 13 | 14 | ||
| 14 | .display { | 15 | .display { |
| @@ -30,9 +31,13 @@ tt, kbd, code { · 15 unmodified lines | |||
| 30 | <HR> | 31 | <HR> |
| 31 | <H1> | 32 | <H1> |
| 32 | <A HREF="http://www.lua.org/"><IMG SRC="logo.gif" ALT="Lua" BORDER=0></A> | 33 | <A HREF="http://www.lua.org/"><IMG SRC="logo.gif" ALT="Lua" BORDER=0></A> |
| 33 | Welcome to Lua 5.3 (work1) | 34 | Welcome to Lua 5.3 (work2) |
| 34 | </H1> | 35 | </H1> |
| 35 | 36 | ||
| 37 | <P> | ||
| 38 | <IMG SRC="alert.png" ALIGN="absbottom"> | ||
| 39 | <EM>All details may change in the final version.</EM> | ||
| 40 | |||
| 36 | <P> | 41 | <P> |
| 37 | <A HREF="#about">about</A> | 42 | <A HREF="#about">about</A> |
| 38 | · | 43 | · |
| @@ -232,7 +237,7 @@ lapi.c lcode.c lctype.c ldebug.c ldo.c ldump.c lfunc.c lgc.c llex.c · 193 unmodified lines | |||
| 232 | lmem.c lobject.c lopcodes.c lparser.c lstate.c lstring.c ltable.c | 237 | lmem.c lobject.c lopcodes.c lparser.c lstate.c lstring.c ltable.c |
| 233 | ltm.c lundump.c lvm.c lzio.c | 238 | ltm.c lundump.c lvm.c lzio.c |
| 234 | lauxlib.c lbaselib.c lbitlib.c lcorolib.c ldblib.c liolib.c | 239 | lauxlib.c lbaselib.c lbitlib.c lcorolib.c ldblib.c liolib.c |
| 235 | lmathlib.c loslib.c lstrlib.c ltablib.c loadlib.c linit.c | 240 | lmathlib.c loslib.c lstrlib.c ltablib.c lutf8lib.c loadlib.c linit.c |
| 236 | <DT> | 241 | <DT> |
| 237 | interpreter: | 242 | interpreter: |
| 238 | <DD> | 243 | <DD> |
| @@ -258,7 +263,7 @@ compiler: · 19 unmodified lines | |||
| 258 | As mentioned above, you may edit <TT>src/luaconf.h</TT> to customize | 263 | As mentioned above, you may edit <TT>src/luaconf.h</TT> to customize |
| 259 | some features before building Lua. | 264 | some features before building Lua. |
| 260 | 265 | ||
| 261 | <H2><A NAME="changes">Changes since Lua 5.1</A></H2> | 266 | <H2><A NAME="changes">Changes since Lua 5.2</A></H2> |
| 262 | 267 | ||
| 263 | <P> | 268 | <P> |
| 264 | Here are the main changes introduced in Lua 5.3. | 269 | Here are the main changes introduced in Lua 5.3. |
| @@ -269,90 +274,40 @@ lists the · 4 unmodified lines | |||
| 269 | 274 | ||
| 270 | <H3>Main changes</H3> | 275 | <H3>Main changes</H3> |
| 271 | <UL> | 276 | <UL> |
| 272 | <LI> yieldable pcall and metamethods | 277 | <LI> support for integers (64-bit by default) |
| 273 | <LI> new lexical scheme for globals | 278 | <LI> better support for small architectures ("Small Lua" with 32-bit numbers) |
| 274 | <LI> ephemeron tables | 279 | <LI> bitwise operators |
| 275 | <LI> new library for bitwise operations | 280 | <LI> basic utf-8 library |
| 276 | <LI> light C functions | 281 | <LI> utf-8 escapes in literal strings |
| 277 | <LI> emergency garbage collector | 282 | <LI> functions for packing/unpacking numbers |
| 278 | <LI> <CODE>goto</CODE> statement | 283 | <LI> userdata can have any Lua value as uservalue |
| 279 | <LI> finalizers for tables | 284 | <LI> strip option in <CODE>lua_dump</CODE>/<CODE>string.dump</CODE> |
| 280 | </UL> | 285 | </UL> |
| 281 | 286 | ||
| 282 | Here are the other changes introduced in Lua 5.3: | 287 | Here are the other changes introduced in Lua 5.3: |
| 283 | <H3>Language</H3> | 288 | <H3>Language</H3> |
| 284 | <UL> | 289 | <UL> |
| 285 | <LI> no more fenv for threads or functions | 290 | <LI> |
| 286 | <LI> tables honor the <CODE>__len</CODE> metamethod | ||
| 287 | <LI> hex and <CODE>\z</CODE> escapes in strings | ||
| 288 | <LI> support for hexadecimal floats | ||
| 289 | <LI> order metamethods work for different types | ||
| 290 | <LI> no more verification of opcode consistency | ||
| 291 | <LI> hook event "tail return" replaced by "tail call" | ||
| 292 | <LI> empty statement | ||
| 293 | <LI> <CODE>break</CODE> statement may appear in the middle of a block | ||
| 294 | </UL> | 291 | </UL> |
| 295 | 292 | ||
| 296 | <H3>Libraries</H3> | 293 | <H3>Libraries</H3> |
| 297 | <UL> | 294 | <UL> |
| 298 | <LI> arguments for function called through <CODE>xpcall</CODE> | 295 | <LI> |
| 299 | <LI> optional 'mode' argument to load and loadfile (to control binary x text) | ||
| 300 | <LI> optional 'env' argument to load and loadfile (environment for loaded chunk) | ||
| 301 | <LI> <CODE>loadlib</CODE> may load libraries with global names (RTLD_GLOBAL) | ||
| 302 | <LI> new function <CODE>package.searchpath</CODE> | ||
| 303 | <LI> modules receive their paths when loaded | ||
| 304 | <LI> optional base in <CODE>math.log</CODE> | ||
| 305 | <LI> optional separator in <CODE>string.rep</CODE> | ||
| 306 | <LI> <CODE>file:write</CODE> returns <CODE>file</CODE> | ||
| 307 | <LI> closing a pipe returns exit status | ||
| 308 | <LI> <CODE>os.exit</CODE> may close state | ||
| 309 | <LI> new metamethods <CODE>__pairs</CODE> and <CODE>__ipairs</CODE> | ||
| 310 | <LI> new option 'isrunning' for <CODE>collectgarbage</CODE> and <CODE>lua_gc</CODE> | ||
| 311 | <LI> frontier patterns | ||
| 312 | <LI> <CODE>\0</CODE> in patterns | ||
| 313 | <LI> new option <CODE>*L</CODE> for <CODE>io.read</CODE> | ||
| 314 | <LI> options for <CODE>io.lines</CODE> | ||
| 315 | <LI> <CODE>debug.getlocal</CODE> can access function varargs | ||
| 316 | </UL> | 296 | </UL> |
| 317 | 297 | ||
| 318 | <H3>C API</H3> | 298 | <H3>C API</H3> |
| 319 | <UL> | 299 | <UL> |
| 320 | <LI> main thread predefined in the registry | 300 | <LI> |
| 321 | <LI> new functions | ||
| 322 | <CODE>lua_absindex</CODE>, | ||
| 323 | <CODE>lua_arith</CODE>, | ||
| 324 | <CODE>lua_compare</CODE>, | ||
| 325 | <CODE>lua_copy</CODE>, | ||
| 326 | <CODE>lua_len</CODE>, | ||
| 327 | <CODE>lua_rawgetp</CODE>, | ||
| 328 | <CODE>lua_rawsetp</CODE>, | ||
| 329 | <CODE>lua_upvalueid</CODE>, | ||
| 330 | <CODE>lua_upvaluejoin</CODE>, | ||
| 331 | <CODE>lua_version</CODE>. | ||
| 332 | <LI> new functions | ||
| 333 | <CODE>luaL_checkversion</CODE>, | ||
| 334 | <CODE>luaL_setmetatable</CODE>, | ||
| 335 | <CODE>luaL_testudata</CODE>, | ||
| 336 | <CODE>luaL_tolstring</CODE>. | ||
| 337 | <LI> <CODE>lua_pushstring</CODE> and <CODE>pushlstring</CODE> return string | ||
| 338 | <LI> <CODE>nparams</CODE> and <CODE>isvararg</CODE> available in debug API | ||
| 339 | <LI> new <CODE>lua_Unsigned</CODE> | ||
| 340 | </UL> | 301 | </UL> |
| 341 | 302 | ||
| 342 | <H3>Implementation</H3> | 303 | <H3>Implementation</H3> |
| 343 | <UL> | 304 | <UL> |
| 344 | <LI> max constants per function raised to 2<SUP>26</SUP> | 305 | <LI> |
| 345 | <LI> generational mode for garbage collection (experimental) | ||
| 346 | <LI> NaN trick (experimental) | ||
| 347 | <LI> internal (immutable) version of ctypes | ||
| 348 | <LI> simpler implementation for string buffers | ||
| 349 | <LI> parser uses much less C-stack space (no more auto arrays) | ||
| 350 | </UL> | 306 | </UL> |
| 351 | 307 | ||
| 352 | <H3>Lua standalone interpreter</H3> | 308 | <H3>Lua standalone interpreter</H3> |
| 353 | <UL> | 309 | <UL> |
| 354 | <LI> new <CODE>-E</CODE> option to avoid environment variables | 310 | <LI> Can be used as calculator; no need to prefix with '=' |
| 355 | <LI> handling of non-string error messages | ||
| 356 | </UL> | 311 | </UL> |
| 357 | 312 | ||
| 358 | <H2><A NAME="license">License</A></H2> | 313 | <H2><A NAME="license">License</A></H2> |
| @@ -374,7 +329,7 @@ For details, see · 15 unmodified lines | |||
| 374 | <A HREF="http://www.lua.org/license.html">this</A>. | 329 | <A HREF="http://www.lua.org/license.html">this</A>. |
| 375 | 330 | ||
| 376 | <BLOCKQUOTE STYLE="padding-bottom: 0em"> | 331 | <BLOCKQUOTE STYLE="padding-bottom: 0em"> |
| 377 | Copyright © 1994–2013 Lua.org, PUC-Rio. | 332 | Copyright © 1994–2014 Lua.org, PUC-Rio. |
| 378 | 333 | ||
| 379 | <P> | 334 | <P> |
| 380 | Permission is hereby granted, free of charge, to any person obtaining a copy | 335 | Permission is hereby granted, free of charge, to any person obtaining a copy |
| @@ -402,10 +357,10 @@ THE SOFTWARE. · 21 unmodified lines | |||
| 402 | <HR> | 357 | <HR> |
| 403 | <SMALL CLASS="footer"> | 358 | <SMALL CLASS="footer"> |
| 404 | Last update: | 359 | Last update: |
| 405 | Mon Jun 3 23:13:40 BRT 2013 | 360 | Fri Mar 21 17:33:08 BRT 2014 |
| 406 | </SMALL> | 361 | </SMALL> |
| 407 | <!-- | 362 | <!-- |
| 408 | Last change: revised for Lua 5.3.0 | 363 | Last change: updated for Lua 5.3.0 (work2) |
| 409 | --> | 364 | --> |
| 410 | 365 | ||
| 411 | </BODY> | 366 | </BODY> |
| @@ -1,2 +1,2 @@ | |||
| 1 | #define nvalue(x) 0 | 1 | #define nvalue(x) ((lua_Number)0) |
| 2 | #define ttypenv(x) ttnov(x) | 2 | #define ttypenv(x) ttnov(x) |
| @@ -33,7 +33,7 @@ CORE_O= lapi.o lcode.o lctype.o ldebug.o ldo.o ldump.o lfunc.o lgc.o llex.o \ · 32 unmodified lines | |||
| 33 | lmem.o lobject.o lopcodes.o lparser.o lstate.o lstring.o ltable.o \ | 33 | lmem.o lobject.o lopcodes.o lparser.o lstate.o lstring.o ltable.o \ |
| 34 | ltm.o lundump.o lvm.o lzio.o | 34 | ltm.o lundump.o lvm.o lzio.o |
| 35 | LIB_O= lauxlib.o lbaselib.o lbitlib.o lcorolib.o ldblib.o liolib.o \ | 35 | LIB_O= lauxlib.o lbaselib.o lbitlib.o lcorolib.o ldblib.o liolib.o \ |
| 36 | lmathlib.o loslib.o lstrlib.o ltablib.o loadlib.o linit.o | 36 | lmathlib.o loslib.o lstrlib.o ltablib.o lutf8lib.o loadlib.o linit.o |
| 37 | BASE_O= $(CORE_O) $(LIB_O) $(MYOBJS) | 37 | BASE_O= $(CORE_O) $(LIB_O) $(MYOBJS) |
| 38 | 38 | ||
| 39 | LUA_T= lua | 39 | LUA_T= lua |
| @@ -152,7 +152,7 @@ lgc.o: lgc.c lua.h luaconf.h ldebug.h lstate.h lobject.h llimits.h ltm.h \ · 112 unmodified lines | |||
| 152 | linit.o: linit.c lua.h luaconf.h lualib.h lauxlib.h | 152 | linit.o: linit.c lua.h luaconf.h lualib.h lauxlib.h |
| 153 | liolib.o: liolib.c lua.h luaconf.h lauxlib.h lualib.h | 153 | liolib.o: liolib.c lua.h luaconf.h lauxlib.h lualib.h |
| 154 | llex.o: llex.c lua.h luaconf.h lctype.h llimits.h ldo.h lobject.h \ | 154 | llex.o: llex.c lua.h luaconf.h lctype.h llimits.h ldo.h lobject.h \ |
| 155 | lstate.h ltm.h lzio.h lmem.h llex.h lparser.h lstring.h lgc.h ltable.h | 155 | lstate.h ltm.h lzio.h lmem.h lgc.h llex.h lparser.h lstring.h ltable.h |
| 156 | lmathlib.o: lmathlib.c lua.h luaconf.h lauxlib.h lualib.h | 156 | lmathlib.o: lmathlib.c lua.h luaconf.h lauxlib.h lualib.h |
| 157 | lmem.o: lmem.c lua.h luaconf.h ldebug.h lstate.h lobject.h llimits.h \ | 157 | lmem.o: lmem.c lua.h luaconf.h ldebug.h lstate.h lobject.h llimits.h \ |
| 158 | ltm.h lzio.h lmem.h ldo.h lgc.h | 158 | ltm.h lzio.h lmem.h ldo.h lgc.h |
| @@ -167,8 +167,8 @@ lparser.o: lparser.c lua.h luaconf.h lcode.h llex.h lobject.h llimits.h \ · 8 unmodified lines | |||
| 167 | lstate.o: lstate.c lua.h luaconf.h lapi.h llimits.h lstate.h lobject.h \ | 167 | lstate.o: lstate.c lua.h luaconf.h lapi.h llimits.h lstate.h lobject.h \ |
| 168 | ltm.h lzio.h lmem.h ldebug.h ldo.h lfunc.h lgc.h llex.h lstring.h \ | 168 | ltm.h lzio.h lmem.h ldebug.h ldo.h lfunc.h lgc.h llex.h lstring.h \ |
| 169 | ltable.h | 169 | ltable.h |
| 170 | lstring.o: lstring.c lua.h luaconf.h lmem.h llimits.h lobject.h lstate.h \ | 170 | lstring.o: lstring.c lua.h luaconf.h ldebug.h lstate.h lobject.h \ |
| 171 | ltm.h lzio.h lstring.h lgc.h | 171 | llimits.h ltm.h lzio.h lmem.h ldo.h lstring.h lgc.h |
| 172 | lstrlib.o: lstrlib.c lua.h luaconf.h lauxlib.h lualib.h | 172 | lstrlib.o: lstrlib.c lua.h luaconf.h lauxlib.h lualib.h |
| 173 | ltable.o: ltable.c lua.h luaconf.h ldebug.h lstate.h lobject.h llimits.h \ | 173 | ltable.o: ltable.c lua.h luaconf.h ldebug.h lstate.h lobject.h llimits.h \ |
| 174 | ltm.h lzio.h lmem.h ldo.h lgc.h lstring.h ltable.h lvm.h | 174 | ltm.h lzio.h lmem.h ldo.h lgc.h lstring.h ltable.h lvm.h |
| @@ -180,6 +180,7 @@ luac.o: luac.c lua.h luaconf.h lauxlib.h lobject.h llimits.h lstate.h \ · 5 unmodified lines | |||
| 180 | ltm.h lzio.h lmem.h lundump.h ldebug.h lopcodes.h | 180 | ltm.h lzio.h lmem.h lundump.h ldebug.h lopcodes.h |
| 181 | lundump.o: lundump.c lua.h luaconf.h ldebug.h lstate.h lobject.h \ | 181 | lundump.o: lundump.c lua.h luaconf.h ldebug.h lstate.h lobject.h \ |
| 182 | llimits.h ltm.h lzio.h lmem.h ldo.h lfunc.h lstring.h lgc.h lundump.h | 182 | llimits.h ltm.h lzio.h lmem.h ldo.h lfunc.h lstring.h lgc.h lundump.h |
| 183 | lutf8lib.o: lutf8lib.c lua.h luaconf.h lauxlib.h lualib.h | ||
| 183 | lvm.o: lvm.c lua.h luaconf.h ldebug.h lstate.h lobject.h llimits.h ltm.h \ | 184 | lvm.o: lvm.c lua.h luaconf.h ldebug.h lstate.h lobject.h llimits.h ltm.h \ |
| 184 | lzio.h lmem.h ldo.h lfunc.h lgc.h lopcodes.h lstring.h ltable.h lvm.h | 185 | lzio.h lmem.h ldo.h lfunc.h lgc.h lopcodes.h lstring.h ltable.h lvm.h |
| 185 | lzio.o: lzio.c lua.h luaconf.h llimits.h lmem.h lstate.h lobject.h ltm.h \ | 186 | lzio.o: lzio.c lua.h luaconf.h llimits.h lmem.h lstate.h lobject.h ltm.h \ |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lapi.c,v 2.185 2013/07/05 14:29:51 roberto Exp $ | 2 | ** $Id: lapi.c,v 2.201 2014/03/12 20:57:40 roberto Exp $ |
| 3 | ** Lua API | 3 | ** Lua API |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -286,7 +286,7 @@ LUA_API int lua_isstring (lua_State *L, int idx) { · 280 unmodified lines | |||
| 286 | 286 | ||
| 287 | LUA_API int lua_isuserdata (lua_State *L, int idx) { | 287 | LUA_API int lua_isuserdata (lua_State *L, int idx) { |
| 288 | const TValue *o = index2addr(L, idx); | 288 | const TValue *o = index2addr(L, idx); |
| 289 | return (ttisuserdata(o) || ttislightuserdata(o)); | 289 | return (ttisfulluserdata(o) || ttislightuserdata(o)); |
| 290 | } | 290 | } |
| 291 | 291 | ||
| 292 | 292 | ||
| @@ -299,9 +299,9 @@ LUA_API int lua_rawequal (lua_State *L, int index1, int index2) { · 6 unmodified lines | |||
| 299 | 299 | ||
| 300 | LUA_API void lua_arith (lua_State *L, int op) { | 300 | LUA_API void lua_arith (lua_State *L, int op) { |
| 301 | lua_lock(L); | 301 | lua_lock(L); |
| 302 | if (op != LUA_OPUNM) /* all other operations expect two operands */ | 302 | if (op != LUA_OPUNM && op != LUA_OPBNOT) |
| 303 | api_checknelems(L, 2); | 303 | api_checknelems(L, 2); /* all other operations expect two operands */ |
| 304 | else { /* for unary minus, add fake 2nd operand */ | 304 | else { /* for unary operations, add fake 2nd operand */ |
| 305 | api_checknelems(L, 1); | 305 | api_checknelems(L, 1); |
| 306 | setobjs2s(L, L->top, L->top - 1); | 306 | setobjs2s(L, L->top, L->top - 1); |
| 307 | L->top++; | 307 | L->top++; |
| @@ -379,20 +379,20 @@ LUA_API lua_Unsigned lua_tounsignedx (lua_State *L, int idx, int *pisnum) { · 71 unmodified lines | |||
| 379 | isnum = 1; | 379 | isnum = 1; |
| 380 | break; | 380 | break; |
| 381 | } | 381 | } |
| 382 | case LUA_TNUMFLT: { | 382 | case LUA_TNUMFLT: { /* compute floor(n) % 2^(numbits in an integer) */ |
| 383 | const lua_Number twop = (~(lua_Unsigned)0) + cast_num(1); | 383 | const lua_Number twop = cast_num(MAX_UINTEGER) + cast_num(1); /* 2^n */ |
| 384 | lua_Number n = fltvalue(o); | 384 | lua_Number n = fltvalue(o); /* get value */ |
| 385 | int neg = 0; | 385 | int neg = 0; |
| 386 | n = l_floor(n); | 386 | n = l_floor(n); /* get its floor */ |
| 387 | if (n < 0) { | 387 | if (n < 0) { |
| 388 | neg = 1; | 388 | neg = 1; |
| 389 | n = -n; | 389 | n = -n; /* make 'n' positive, so that 'fmod' is the same as '%' */ |
| 390 | } | 390 | } |
| 391 | n = l_mathop(fmod)(n, twop); | 391 | n = l_mathop(fmod)(n, twop); /* n = n % 2^(numbits in an integer) */ |
| 392 | if (luai_numisnan(L,n)) /* not a number? */ | 392 | if (luai_numisnan(n)) /* not a number? */ |
| 393 | break; /* not an integer, too */ | 393 | break; /* not an integer, too */ |
| 394 | res = cast_unsigned(n); | 394 | res = cast_unsigned(n); /* 'n' now must fit in an unsigned */ |
| 395 | if (neg) res = 0u - res; | 395 | if (neg) res = 0u - res; /* back to negative, if needed */ |
| 396 | isnum = 1; | 396 | isnum = 1; |
| 397 | break; | 397 | break; |
| 398 | } | 398 | } |
| @@ -586,8 +586,10 @@ LUA_API void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n) { · 187 unmodified lines | |||
| 586 | cl = luaF_newCclosure(L, n); | 586 | cl = luaF_newCclosure(L, n); |
| 587 | cl->c.f = fn; | 587 | cl->c.f = fn; |
| 588 | L->top -= n; | 588 | L->top -= n; |
| 589 | while (n--) | 589 | while (n--) { |
| 590 | setobj2n(L, &cl->c.upvalue[n], L->top + n); | 590 | setobj2n(L, &cl->c.upvalue[n], L->top + n); |
| 591 | /* does not need barrier because closure is white */ | ||
| 592 | } | ||
| 591 | setclCvalue(L, L->top, cl); | 593 | setclCvalue(L, L->top, cl); |
| 592 | } | 594 | } |
| 593 | api_incr_top(L); | 595 | api_incr_top(L); |
| @@ -626,7 +628,7 @@ LUA_API int lua_pushthread (lua_State *L) { · 32 unmodified lines | |||
| 626 | */ | 628 | */ |
| 627 | 629 | ||
| 628 | 630 | ||
| 629 | LUA_API void lua_getglobal (lua_State *L, const char *var) { | 631 | LUA_API int lua_getglobal (lua_State *L, const char *var) { |
| 630 | Table *reg = hvalue(&G(L)->l_registry); | 632 | Table *reg = hvalue(&G(L)->l_registry); |
| 631 | const TValue *gt; /* global table */ | 633 | const TValue *gt; /* global table */ |
| 632 | lua_lock(L); | 634 | lua_lock(L); |
| @@ -634,19 +636,21 @@ LUA_API void lua_getglobal (lua_State *L, const char *var) { · 1 unmodified line | |||
| 634 | setsvalue2s(L, L->top++, luaS_new(L, var)); | 636 | setsvalue2s(L, L->top++, luaS_new(L, var)); |
| 635 | luaV_gettable(L, gt, L->top - 1, L->top - 1); | 637 | luaV_gettable(L, gt, L->top - 1, L->top - 1); |
| 636 | lua_unlock(L); | 638 | lua_unlock(L); |
| 639 | return ttnov(L->top - 1); | ||
| 637 | } | 640 | } |
| 638 | 641 | ||
| 639 | 642 | ||
| 640 | LUA_API void lua_gettable (lua_State *L, int idx) { | 643 | LUA_API int lua_gettable (lua_State *L, int idx) { |
| 641 | StkId t; | 644 | StkId t; |
| 642 | lua_lock(L); | 645 | lua_lock(L); |
| 643 | t = index2addr(L, idx); | 646 | t = index2addr(L, idx); |
| 644 | luaV_gettable(L, t, L->top - 1, L->top - 1); | 647 | luaV_gettable(L, t, L->top - 1, L->top - 1); |
| 645 | lua_unlock(L); | 648 | lua_unlock(L); |
| 649 | return ttnov(L->top - 1); | ||
| 646 | } | 650 | } |
| 647 | 651 | ||
| 648 | 652 | ||
| 649 | LUA_API void lua_getfield (lua_State *L, int idx, const char *k) { | 653 | LUA_API int lua_getfield (lua_State *L, int idx, const char *k) { |
| 650 | StkId t; | 654 | StkId t; |
| 651 | lua_lock(L); | 655 | lua_lock(L); |
| 652 | t = index2addr(L, idx); | 656 | t = index2addr(L, idx); |
| @@ -654,20 +658,22 @@ LUA_API void lua_getfield (lua_State *L, int idx, const char *k) { · 1 unmodified line | |||
| 654 | api_incr_top(L); | 658 | api_incr_top(L); |
| 655 | luaV_gettable(L, t, L->top - 1, L->top - 1); | 659 | luaV_gettable(L, t, L->top - 1, L->top - 1); |
| 656 | lua_unlock(L); | 660 | lua_unlock(L); |
| 661 | return ttnov(L->top - 1); | ||
| 657 | } | 662 | } |
| 658 | 663 | ||
| 659 | 664 | ||
| 660 | LUA_API void lua_rawget (lua_State *L, int idx) { | 665 | LUA_API int lua_rawget (lua_State *L, int idx) { |
| 661 | StkId t; | 666 | StkId t; |
| 662 | lua_lock(L); | 667 | lua_lock(L); |
| 663 | t = index2addr(L, idx); | 668 | t = index2addr(L, idx); |
| 664 | api_check(L, ttistable(t), "table expected"); | 669 | api_check(L, ttistable(t), "table expected"); |
| 665 | setobj2s(L, L->top - 1, luaH_get(hvalue(t), L->top - 1)); | 670 | setobj2s(L, L->top - 1, luaH_get(hvalue(t), L->top - 1)); |
| 666 | lua_unlock(L); | 671 | lua_unlock(L); |
| 672 | return ttnov(L->top - 1); | ||
| 667 | } | 673 | } |
| 668 | 674 | ||
| 669 | 675 | ||
| 670 | LUA_API void lua_rawgeti (lua_State *L, int idx, lua_Integer n) { | 676 | LUA_API int lua_rawgeti (lua_State *L, int idx, lua_Integer n) { |
| 671 | StkId t; | 677 | StkId t; |
| 672 | lua_lock(L); | 678 | lua_lock(L); |
| 673 | t = index2addr(L, idx); | 679 | t = index2addr(L, idx); |
| @@ -675,10 +681,11 @@ LUA_API void lua_rawgeti (lua_State *L, int idx, lua_Integer n) { · 1 unmodified line | |||
| 675 | setobj2s(L, L->top, luaH_getint(hvalue(t), n)); | 681 | setobj2s(L, L->top, luaH_getint(hvalue(t), n)); |
| 676 | api_incr_top(L); | 682 | api_incr_top(L); |
| 677 | lua_unlock(L); | 683 | lua_unlock(L); |
| 684 | return ttnov(L->top - 1); | ||
| 678 | } | 685 | } |
| 679 | 686 | ||
| 680 | 687 | ||
| 681 | LUA_API void lua_rawgetp (lua_State *L, int idx, const void *p) { | 688 | LUA_API int lua_rawgetp (lua_State *L, int idx, const void *p) { |
| 682 | StkId t; | 689 | StkId t; |
| 683 | TValue k; | 690 | TValue k; |
| 684 | lua_lock(L); | 691 | lua_lock(L); |
| @@ -688,6 +695,7 @@ LUA_API void lua_rawgetp (lua_State *L, int idx, const void *p) { · 3 unmodified lines | |||
| 688 | setobj2s(L, L->top, luaH_get(hvalue(t), &k)); | 695 | setobj2s(L, L->top, luaH_get(hvalue(t), &k)); |
| 689 | api_incr_top(L); | 696 | api_incr_top(L); |
| 690 | lua_unlock(L); | 697 | lua_unlock(L); |
| 698 | return ttnov(L->top - 1); | ||
| 691 | } | 699 | } |
| 692 | 700 | ||
| 693 | 701 | ||
| @@ -737,11 +745,8 @@ LUA_API void lua_getuservalue (lua_State *L, int idx) { · 43 unmodified lines | |||
| 737 | StkId o; | 745 | StkId o; |
| 738 | lua_lock(L); | 746 | lua_lock(L); |
| 739 | o = index2addr(L, idx); | 747 | o = index2addr(L, idx); |
| 740 | api_check(L, ttisuserdata(o), "userdata expected"); | 748 | api_check(L, ttisfulluserdata(o), "full userdata expected"); |
| 741 | if (uvalue(o)->env) { | 749 | getuservalue(L, rawuvalue(o), L->top); |
| 742 | sethvalue(L, L->top, uvalue(o)->env); | ||
| 743 | } else | ||
| 744 | setnilvalue(L->top); | ||
| 745 | api_incr_top(L); | 750 | api_incr_top(L); |
| 746 | lua_unlock(L); | 751 | lua_unlock(L); |
| 747 | } | 752 | } |
| @@ -846,7 +851,7 @@ LUA_API int lua_setmetatable (lua_State *L, int objindex) { · 98 unmodified lines | |||
| 846 | case LUA_TTABLE: { | 851 | case LUA_TTABLE: { |
| 847 | hvalue(obj)->metatable = mt; | 852 | hvalue(obj)->metatable = mt; |
| 848 | if (mt) { | 853 | if (mt) { |
| 849 | luaC_objbarrierback(L, gcvalue(obj), mt); | 854 | luaC_objbarrier(L, gcvalue(obj), mt); |
| 850 | luaC_checkfinalizer(L, gcvalue(obj), mt); | 855 | luaC_checkfinalizer(L, gcvalue(obj), mt); |
| 851 | } | 856 | } |
| 852 | break; | 857 | break; |
| @@ -875,14 +880,9 @@ LUA_API void lua_setuservalue (lua_State *L, int idx) { · 22 unmodified lines | |||
| 875 | lua_lock(L); | 880 | lua_lock(L); |
| 876 | api_checknelems(L, 1); | 881 | api_checknelems(L, 1); |
| 877 | o = index2addr(L, idx); | 882 | o = index2addr(L, idx); |
| 878 | api_check(L, ttisuserdata(o), "userdata expected"); | 883 | api_check(L, ttisfulluserdata(o), "full userdata expected"); |
| 879 | if (ttisnil(L->top - 1)) | 884 | setuservalue(L, rawuvalue(o), L->top - 1); |
| 880 | uvalue(o)->env = NULL; | 885 | luaC_barrier(L, gcvalue(o), L->top - 1); |
| 881 | else { | ||
| 882 | api_check(L, ttistable(L->top - 1), "table expected"); | ||
| 883 | uvalue(o)->env = hvalue(L->top - 1); | ||
| 884 | luaC_objbarrier(L, gcvalue(o), hvalue(L->top - 1)); | ||
| 885 | } | ||
| 886 | L->top--; | 886 | L->top--; |
| 887 | lua_unlock(L); | 887 | lua_unlock(L); |
| 888 | } | 888 | } |
| @@ -1015,14 +1015,14 @@ LUA_API int lua_load (lua_State *L, lua_Reader reader, void *data, · 126 unmodified lines | |||
| 1015 | } | 1015 | } |
| 1016 | 1016 | ||
| 1017 | 1017 | ||
| 1018 | LUA_API int lua_dump (lua_State *L, lua_Writer writer, void *data) { | 1018 | LUA_API int lua_dump (lua_State *L, lua_Writer writer, void *data, int strip) { |
| 1019 | int status; | 1019 | int status; |
| 1020 | TValue *o; | 1020 | TValue *o; |
| 1021 | lua_lock(L); | 1021 | lua_lock(L); |
| 1022 | api_checknelems(L, 1); | 1022 | api_checknelems(L, 1); |
| 1023 | o = L->top - 1; | 1023 | o = L->top - 1; |
| 1024 | if (isLfunction(o)) | 1024 | if (isLfunction(o)) |
| 1025 | status = luaU_dump(L, getproto(o), writer, data, 0); | 1025 | status = luaU_dump(L, getproto(o), writer, data, strip); |
| 1026 | else | 1026 | else |
| 1027 | status = 1; | 1027 | status = 1; |
| 1028 | lua_unlock(L); | 1028 | lua_unlock(L); |
| @@ -1068,19 +1068,21 @@ LUA_API int lua_gc (lua_State *L, int what, int data) { · 39 unmodified lines | |||
| 1068 | break; | 1068 | break; |
| 1069 | } | 1069 | } |
| 1070 | case LUA_GCSTEP: { | 1070 | case LUA_GCSTEP: { |
| 1071 | if (g->gckind == KGC_GEN) { /* generational mode? */ | 1071 | l_mem debt = 1; /* =1 to signal that it did an actual step */ |
| 1072 | res = (g->GCestimate == 0); /* true if it will do major collection */ | 1072 | int oldrunning = g->gcrunning; |
| 1073 | luaC_forcestep(L); /* do a single step */ | 1073 | g->gcrunning = 1; /* force GC to run */ |
| 1074 | if (data == 0) { | ||
| 1075 | luaE_setdebt(g, -GCSTEPSIZE); /* to do a "small" step */ | ||
| 1076 | luaC_step(L); | ||
| 1074 | } | 1077 | } |
| 1075 | else { | 1078 | else { /* add 'data' to total debt */ |
| 1076 | lu_mem debt = cast(lu_mem, data) * 1024 - GCSTEPSIZE; | 1079 | debt = cast(l_mem, data) * 1024 + g->GCdebt; |
| 1077 | if (g->gcrunning) | 1080 | luaE_setdebt(g, debt); |
| 1078 | debt += g->GCdebt; /* include current debt */ | 1081 | luaC_checkGC(L); |
| 1079 | luaE_setdebt(g, debt); | ||
| 1080 | luaC_forcestep(L); | ||
| 1081 | if (g->gcstate == GCSpause) /* end of cycle? */ | ||
| 1082 | res = 1; /* signal it */ | ||
| 1083 | } | 1082 | } |
| 1083 | g->gcrunning = oldrunning; /* restore previous state */ | ||
| 1084 | if (debt > 0 && g->gcstate == GCSpause) /* end of cycle? */ | ||
| 1085 | res = 1; /* signal it */ | ||
| 1084 | break; | 1086 | break; |
| 1085 | } | 1087 | } |
| 1086 | case LUA_GCSETPAUSE: { | 1088 | case LUA_GCSETPAUSE: { |
| @@ -1088,13 +1090,9 @@ LUA_API int lua_gc (lua_State *L, int what, int data) { · 1 unmodified line | |||
| 1088 | g->gcpause = data; | 1090 | g->gcpause = data; |
| 1089 | break; | 1091 | break; |
| 1090 | } | 1092 | } |
| 1091 | case LUA_GCSETMAJORINC: { | ||
| 1092 | res = g->gcmajorinc; | ||
| 1093 | g->gcmajorinc = data; | ||
| 1094 | break; | ||
| 1095 | } | ||
| 1096 | case LUA_GCSETSTEPMUL: { | 1093 | case LUA_GCSETSTEPMUL: { |
| 1097 | res = g->gcstepmul; | 1094 | res = g->gcstepmul; |
| 1095 | if (data < 40) data = 40; /* avoid ridiculous low values (and 0) */ | ||
| 1098 | g->gcstepmul = data; | 1096 | g->gcstepmul = data; |
| 1099 | break; | 1097 | break; |
| 1100 | } | 1098 | } |
| @@ -1102,14 +1100,6 @@ LUA_API int lua_gc (lua_State *L, int what, int data) { · 1 unmodified line | |||
| 1102 | res = g->gcrunning; | 1100 | res = g->gcrunning; |
| 1103 | break; | 1101 | break; |
| 1104 | } | 1102 | } |
| 1105 | case LUA_GCGEN: { /* change collector to generational mode */ | ||
| 1106 | luaC_changemode(L, KGC_GEN); | ||
| 1107 | break; | ||
| 1108 | } | ||
| 1109 | case LUA_GCINC: { /* change collector to incremental mode */ | ||
| 1110 | luaC_changemode(L, KGC_NORMAL); | ||
| 1111 | break; | ||
| 1112 | } | ||
| 1113 | default: res = -1; /* invalid option */ | 1103 | default: res = -1; /* invalid option */ |
| 1114 | } | 1104 | } |
| 1115 | lua_unlock(L); | 1105 | lua_unlock(L); |
| @@ -1197,7 +1187,7 @@ LUA_API void *lua_newuserdata (lua_State *L, size_t size) { · 81 unmodified lines | |||
| 1197 | Udata *u; | 1187 | Udata *u; |
| 1198 | lua_lock(L); | 1188 | lua_lock(L); |
| 1199 | luaC_checkGC(L); | 1189 | luaC_checkGC(L); |
| 1200 | u = luaS_newudata(L, size, NULL); | 1190 | u = luaS_newudata(L, size); |
| 1201 | setuvalue(L, L->top, u); | 1191 | setuvalue(L, L->top, u); |
| 1202 | api_incr_top(L); | 1192 | api_incr_top(L); |
| 1203 | lua_unlock(L); | 1193 | lua_unlock(L); |
| @@ -1207,7 +1197,7 @@ LUA_API void *lua_newuserdata (lua_State *L, size_t size) { · 3 unmodified lines | |||
| 1207 | 1197 | ||
| 1208 | 1198 | ||
| 1209 | static const char *aux_upvalue (StkId fi, int n, TValue **val, | 1199 | static const char *aux_upvalue (StkId fi, int n, TValue **val, |
| 1210 | GCObject **owner) { | 1200 | GCObject **owner, UpVal **uv) { |
| 1211 | switch (ttype(fi)) { | 1201 | switch (ttype(fi)) { |
| 1212 | case LUA_TCCL: { /* C closure */ | 1202 | case LUA_TCCL: { /* C closure */ |
| 1213 | CClosure *f = clCvalue(fi); | 1203 | CClosure *f = clCvalue(fi); |
| @@ -1222,9 +1212,9 @@ static const char *aux_upvalue (StkId fi, int n, TValue **val, · 8 unmodified lines | |||
| 1222 | Proto *p = f->p; | 1212 | Proto *p = f->p; |
| 1223 | if (!(1 <= n && n <= p->sizeupvalues)) return NULL; | 1213 | if (!(1 <= n && n <= p->sizeupvalues)) return NULL; |
| 1224 | *val = f->upvals[n-1]->v; | 1214 | *val = f->upvals[n-1]->v; |
| 1225 | if (owner) *owner = obj2gco(f->upvals[n - 1]); | 1215 | if (uv) *uv = f->upvals[n - 1]; |
| 1226 | name = p->upvalues[n-1].name; | 1216 | name = p->upvalues[n-1].name; |
| 1227 | return (name == NULL) ? "" : getstr(name); | 1217 | return (name == NULL) ? "(*no name)" : getstr(name); |
| 1228 | } | 1218 | } |
| 1229 | default: return NULL; /* not a closure */ | 1219 | default: return NULL; /* not a closure */ |
| 1230 | } | 1220 | } |
| @@ -1235,7 +1225,7 @@ LUA_API const char *lua_getupvalue (lua_State *L, int funcindex, int n) { · 4 unmodified lines | |||
| 1235 | const char *name; | 1225 | const char *name; |
| 1236 | TValue *val = NULL; /* to avoid warnings */ | 1226 | TValue *val = NULL; /* to avoid warnings */ |
| 1237 | lua_lock(L); | 1227 | lua_lock(L); |
| 1238 | name = aux_upvalue(index2addr(L, funcindex), n, &val, NULL); | 1228 | name = aux_upvalue(index2addr(L, funcindex), n, &val, NULL, NULL); |
| 1239 | if (name) { | 1229 | if (name) { |
| 1240 | setobj2s(L, L->top, val); | 1230 | setobj2s(L, L->top, val); |
| 1241 | api_incr_top(L); | 1231 | api_incr_top(L); |
| @@ -1248,16 +1238,18 @@ LUA_API const char *lua_getupvalue (lua_State *L, int funcindex, int n) { · 6 unmodified lines | |||
| 1248 | LUA_API const char *lua_setupvalue (lua_State *L, int funcindex, int n) { | 1238 | LUA_API const char *lua_setupvalue (lua_State *L, int funcindex, int n) { |
| 1249 | const char *name; | 1239 | const char *name; |
| 1250 | TValue *val = NULL; /* to avoid warnings */ | 1240 | TValue *val = NULL; /* to avoid warnings */ |
| 1251 | GCObject *owner = NULL; /* to avoid warnings */ | 1241 | GCObject *owner = NULL; |
| 1242 | UpVal *uv = NULL; | ||
| 1252 | StkId fi; | 1243 | StkId fi; |
| 1253 | lua_lock(L); | 1244 | lua_lock(L); |
| 1254 | fi = index2addr(L, funcindex); | 1245 | fi = index2addr(L, funcindex); |
| 1255 | api_checknelems(L, 1); | 1246 | api_checknelems(L, 1); |
| 1256 | name = aux_upvalue(fi, n, &val, &owner); | 1247 | name = aux_upvalue(fi, n, &val, &owner, &uv); |
| 1257 | if (name) { | 1248 | if (name) { |
| 1258 | L->top--; | 1249 | L->top--; |
| 1259 | setobj(L, val, L->top); | 1250 | setobj(L, val, L->top); |
| 1260 | luaC_barrier(L, owner, L->top); | 1251 | if (owner) { luaC_barrier(L, owner, L->top); } |
| 1252 | else if (uv) { luaC_upvalbarrier(L, uv); } | ||
| 1261 | } | 1253 | } |
| 1262 | lua_unlock(L); | 1254 | lua_unlock(L); |
| 1263 | return name; | 1255 | return name; |
| @@ -1299,7 +1291,11 @@ LUA_API void lua_upvaluejoin (lua_State *L, int fidx1, int n1, · 35 unmodified lines | |||
| 1299 | LClosure *f1; | 1291 | LClosure *f1; |
| 1300 | UpVal **up1 = getupvalref(L, fidx1, n1, &f1); | 1292 | UpVal **up1 = getupvalref(L, fidx1, n1, &f1); |
| 1301 | UpVal **up2 = getupvalref(L, fidx2, n2, NULL); | 1293 | UpVal **up2 = getupvalref(L, fidx2, n2, NULL); |
| 1294 | luaC_upvdeccount(L, *up1); | ||
| 1302 | *up1 = *up2; | 1295 | *up1 = *up2; |
| 1303 | luaC_objbarrier(L, f1, *up2); | 1296 | (*up1)->refcount++; |
| 1297 | if (upisopen(*up1)) (*up1)->u.open.touched = 1; | ||
| 1298 | luaC_upvalbarrier(L, *up1); | ||
| 1304 | } | 1299 | } |
| 1305 | 1300 | ||
| 1301 | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lauxlib.c,v 1.255 2013/06/27 18:32:33 roberto Exp $ | 2 | ** $Id: lauxlib.c,v 1.260 2014/03/12 20:57:40 roberto Exp $ |
| 3 | ** Auxiliary functions for building Lua libraries | 3 | ** Auxiliary functions for building Lua libraries |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -150,33 +150,40 @@ LUALIB_API void luaL_traceback (lua_State *L, lua_State *L1, · 144 unmodified lines | |||
| 150 | ** ======================================================= | 150 | ** ======================================================= |
| 151 | */ | 151 | */ |
| 152 | 152 | ||
| 153 | LUALIB_API int luaL_argerror (lua_State *L, int narg, const char *extramsg) { | 153 | LUALIB_API int luaL_argerror (lua_State *L, int arg, const char *extramsg) { |
| 154 | lua_Debug ar; | 154 | lua_Debug ar; |
| 155 | if (!lua_getstack(L, 0, &ar)) /* no stack frame? */ | 155 | if (!lua_getstack(L, 0, &ar)) /* no stack frame? */ |
| 156 | return luaL_error(L, "bad argument #%d (%s)", narg, extramsg); | 156 | return luaL_error(L, "bad argument #%d (%s)", arg, extramsg); |
| 157 | lua_getinfo(L, "n", &ar); | 157 | lua_getinfo(L, "n", &ar); |
| 158 | if (strcmp(ar.namewhat, "method") == 0) { | 158 | if (strcmp(ar.namewhat, "method") == 0) { |
| 159 | narg--; /* do not count `self' */ | 159 | arg--; /* do not count `self' */ |
| 160 | if (narg == 0) /* error is in the self argument itself? */ | 160 | if (arg == 0) /* error is in the self argument itself? */ |
| 161 | return luaL_error(L, "calling " LUA_QS " on bad self (%s)", | 161 | return luaL_error(L, "calling " LUA_QS " on bad self (%s)", |
| 162 | ar.name, extramsg); | 162 | ar.name, extramsg); |
| 163 | } | 163 | } |
| 164 | if (ar.name == NULL) | 164 | if (ar.name == NULL) |
| 165 | ar.name = (pushglobalfuncname(L, &ar)) ? lua_tostring(L, -1) : "?"; | 165 | ar.name = (pushglobalfuncname(L, &ar)) ? lua_tostring(L, -1) : "?"; |
| 166 | return luaL_error(L, "bad argument #%d to " LUA_QS " (%s)", | 166 | return luaL_error(L, "bad argument #%d to " LUA_QS " (%s)", |
| 167 | narg, ar.name, extramsg); | 167 | arg, ar.name, extramsg); |
| 168 | } | 168 | } |
| 169 | 169 | ||
| 170 | 170 | ||
| 171 | static int typeerror (lua_State *L, int narg, const char *tname) { | 171 | static int typeerror (lua_State *L, int arg, const char *tname) { |
| 172 | const char *msg = lua_pushfstring(L, "%s expected, got %s", | 172 | const char *msg; |
| 173 | tname, luaL_typename(L, narg)); | 173 | const char *typearg = luaL_typename(L, arg); |
| 174 | return luaL_argerror(L, narg, msg); | 174 | if (lua_getmetatable(L, arg)) { |
| 175 | if (lua_getfield(L, -1, "__name") == LUA_TSTRING) | ||
| 176 | typearg = lua_tostring(L, -1); | ||
| 177 | } | ||
| 178 | else if (lua_type(L, arg) == LUA_TLIGHTUSERDATA) | ||
| 179 | typearg = "light userdata"; | ||
| 180 | msg = lua_pushfstring(L, "%s expected, got %s", tname, typearg); | ||
| 181 | return luaL_argerror(L, arg, msg); | ||
| 175 | } | 182 | } |
| 176 | 183 | ||
| 177 | 184 | ||
| 178 | static void tag_error (lua_State *L, int narg, int tag) { | 185 | static void tag_error (lua_State *L, int arg, int tag) { |
| 179 | typeerror(L, narg, lua_typename(L, tag)); | 186 | typeerror(L, arg, lua_typename(L, tag)); |
| 180 | } | 187 | } |
| 181 | 188 | ||
| 182 | 189 | ||
| @@ -275,6 +282,8 @@ LUALIB_API int luaL_newmetatable (lua_State *L, const char *tname) { · 92 unmodified lines | |||
| 275 | return 0; /* leave previous value on top, but return 0 */ | 282 | return 0; /* leave previous value on top, but return 0 */ |
| 276 | lua_pop(L, 1); | 283 | lua_pop(L, 1); |
| 277 | lua_newtable(L); /* create metatable */ | 284 | lua_newtable(L); /* create metatable */ |
| 285 | lua_pushstring(L, tname); | ||
| 286 | lua_setfield(L, -2, "__name"); /* metatable.__name = tname */ | ||
| 278 | lua_pushvalue(L, -1); | 287 | lua_pushvalue(L, -1); |
| 279 | lua_setfield(L, LUA_REGISTRYINDEX, tname); /* registry.name = metatable */ | 288 | lua_setfield(L, LUA_REGISTRYINDEX, tname); /* registry.name = metatable */ |
| 280 | return 1; | 289 | return 1; |
| @@ -317,15 +326,15 @@ LUALIB_API void *luaL_checkudata (lua_State *L, int ud, const char *tname) { · 36 unmodified lines | |||
| 317 | ** ======================================================= | 326 | ** ======================================================= |
| 318 | */ | 327 | */ |
| 319 | 328 | ||
| 320 | LUALIB_API int luaL_checkoption (lua_State *L, int narg, const char *def, | 329 | LUALIB_API int luaL_checkoption (lua_State *L, int arg, const char *def, |
| 321 | const char *const lst[]) { | 330 | const char *const lst[]) { |
| 322 | const char *name = (def) ? luaL_optstring(L, narg, def) : | 331 | const char *name = (def) ? luaL_optstring(L, arg, def) : |
| 323 | luaL_checkstring(L, narg); | 332 | luaL_checkstring(L, arg); |
| 324 | int i; | 333 | int i; |
| 325 | for (i=0; lst[i]; i++) | 334 | for (i=0; lst[i]; i++) |
| 326 | if (strcmp(lst[i], name) == 0) | 335 | if (strcmp(lst[i], name) == 0) |
| 327 | return i; | 336 | return i; |
| 328 | return luaL_argerror(L, narg, | 337 | return luaL_argerror(L, arg, |
| 329 | lua_pushfstring(L, "invalid option " LUA_QS, name)); | 338 | lua_pushfstring(L, "invalid option " LUA_QS, name)); |
| 330 | } | 339 | } |
| 331 | 340 | ||
| @@ -342,86 +351,86 @@ LUALIB_API void luaL_checkstack (lua_State *L, int space, const char *msg) { · 10 unmodified lines | |||
| 342 | } | 351 | } |
| 343 | 352 | ||
| 344 | 353 | ||
| 345 | LUALIB_API void luaL_checktype (lua_State *L, int narg, int t) { | 354 | LUALIB_API void luaL_checktype (lua_State *L, int arg, int t) { |
| 346 | if (lua_type(L, narg) != t) | 355 | if (lua_type(L, arg) != t) |
| 347 | tag_error(L, narg, t); | 356 | tag_error(L, arg, t); |
| 348 | } | 357 | } |
| 349 | 358 | ||
| 350 | 359 | ||
| 351 | LUALIB_API void luaL_checkany (lua_State *L, int narg) { | 360 | LUALIB_API void luaL_checkany (lua_State *L, int arg) { |
| 352 | if (lua_type(L, narg) == LUA_TNONE) | 361 | if (lua_type(L, arg) == LUA_TNONE) |
| 353 | luaL_argerror(L, narg, "value expected"); | 362 | luaL_argerror(L, arg, "value expected"); |
| 354 | } | 363 | } |
| 355 | 364 | ||
| 356 | 365 | ||
| 357 | LUALIB_API const char *luaL_checklstring (lua_State *L, int narg, size_t *len) { | 366 | LUALIB_API const char *luaL_checklstring (lua_State *L, int arg, size_t *len) { |
| 358 | const char *s = lua_tolstring(L, narg, len); | 367 | const char *s = lua_tolstring(L, arg, len); |
| 359 | if (!s) tag_error(L, narg, LUA_TSTRING); | 368 | if (!s) tag_error(L, arg, LUA_TSTRING); |
| 360 | return s; | 369 | return s; |
| 361 | } | 370 | } |
| 362 | 371 | ||
| 363 | 372 | ||
| 364 | LUALIB_API const char *luaL_optlstring (lua_State *L, int narg, | 373 | LUALIB_API const char *luaL_optlstring (lua_State *L, int arg, |
| 365 | const char *def, size_t *len) { | 374 | const char *def, size_t *len) { |
| 366 | if (lua_isnoneornil(L, narg)) { | 375 | if (lua_isnoneornil(L, arg)) { |
| 367 | if (len) | 376 | if (len) |
| 368 | *len = (def ? strlen(def) : 0); | 377 | *len = (def ? strlen(def) : 0); |
| 369 | return def; | 378 | return def; |
| 370 | } | 379 | } |
| 371 | else return luaL_checklstring(L, narg, len); | 380 | else return luaL_checklstring(L, arg, len); |
| 372 | } | 381 | } |
| 373 | 382 | ||
| 374 | 383 | ||
| 375 | LUALIB_API lua_Number luaL_checknumber (lua_State *L, int narg) { | 384 | LUALIB_API lua_Number luaL_checknumber (lua_State *L, int arg) { |
| 376 | int isnum; | 385 | int isnum; |
| 377 | lua_Number d = lua_tonumberx(L, narg, &isnum); | 386 | lua_Number d = lua_tonumberx(L, arg, &isnum); |
| 378 | if (!isnum) | 387 | if (!isnum) |
| 379 | tag_error(L, narg, LUA_TNUMBER); | 388 | tag_error(L, arg, LUA_TNUMBER); |
| 380 | return d; | 389 | return d; |
| 381 | } | 390 | } |
| 382 | 391 | ||
| 383 | 392 | ||
| 384 | LUALIB_API lua_Number luaL_optnumber (lua_State *L, int narg, lua_Number def) { | 393 | LUALIB_API lua_Number luaL_optnumber (lua_State *L, int arg, lua_Number def) { |
| 385 | return luaL_opt(L, luaL_checknumber, narg, def); | 394 | return luaL_opt(L, luaL_checknumber, arg, def); |
| 386 | } | 395 | } |
| 387 | 396 | ||
| 388 | 397 | ||
| 389 | static void interror (lua_State *L, int narg) { | 398 | static void interror (lua_State *L, int arg) { |
| 390 | if (lua_type(L, narg) == LUA_TNUMBER) | 399 | if (lua_type(L, arg) == LUA_TNUMBER) |
| 391 | luaL_argerror(L, narg, "float value out of range"); | 400 | luaL_argerror(L, arg, "float value out of range"); |
| 392 | else | 401 | else |
| 393 | tag_error(L, narg, LUA_TNUMBER); | 402 | tag_error(L, arg, LUA_TNUMBER); |
| 394 | } | 403 | } |
| 395 | 404 | ||
| 396 | 405 | ||
| 397 | LUALIB_API lua_Integer luaL_checkinteger (lua_State *L, int narg) { | 406 | LUALIB_API lua_Integer luaL_checkinteger (lua_State *L, int arg) { |
| 398 | int isnum; | 407 | int isnum; |
| 399 | lua_Integer d = lua_tointegerx(L, narg, &isnum); | 408 | lua_Integer d = lua_tointegerx(L, arg, &isnum); |
| 400 | if (!isnum) { | 409 | if (!isnum) { |
| 401 | interror(L, narg); | 410 | interror(L, arg); |
| 402 | } | 411 | } |
| 403 | return d; | 412 | return d; |
| 404 | } | 413 | } |
| 405 | 414 | ||
| 406 | 415 | ||
| 407 | LUALIB_API lua_Unsigned luaL_checkunsigned (lua_State *L, int narg) { | 416 | LUALIB_API lua_Unsigned luaL_checkunsigned (lua_State *L, int arg) { |
| 408 | int isnum; | 417 | int isnum; |
| 409 | lua_Unsigned d = lua_tounsignedx(L, narg, &isnum); | 418 | lua_Unsigned d = lua_tounsignedx(L, arg, &isnum); |
| 410 | if (!isnum) | 419 | if (!isnum) |
| 411 | interror(L, narg); | 420 | interror(L, arg); |
| 412 | return d; | 421 | return d; |
| 413 | } | 422 | } |
| 414 | 423 | ||
| 415 | 424 | ||
| 416 | LUALIB_API lua_Integer luaL_optinteger (lua_State *L, int narg, | 425 | LUALIB_API lua_Integer luaL_optinteger (lua_State *L, int arg, |
| 417 | lua_Integer def) { | 426 | lua_Integer def) { |
| 418 | return luaL_opt(L, luaL_checkinteger, narg, def); | 427 | return luaL_opt(L, luaL_checkinteger, arg, def); |
| 419 | } | 428 | } |
| 420 | 429 | ||
| 421 | 430 | ||
| 422 | LUALIB_API lua_Unsigned luaL_optunsigned (lua_State *L, int narg, | 431 | LUALIB_API lua_Unsigned luaL_optunsigned (lua_State *L, int arg, |
| 423 | lua_Unsigned def) { | 432 | lua_Unsigned def) { |
| 424 | return luaL_opt(L, luaL_checkunsigned, narg, def); | 433 | return luaL_opt(L, luaL_checkunsigned, arg, def); |
| 425 | } | 434 | } |
| 426 | 435 | ||
| 427 | /* }====================================================== */ | 436 | /* }====================================================== */ |
| @@ -709,8 +718,7 @@ LUALIB_API int luaL_getmetafield (lua_State *L, int obj, const char *event) { · 281 unmodified lines | |||
| 709 | if (!lua_getmetatable(L, obj)) /* no metatable? */ | 718 | if (!lua_getmetatable(L, obj)) /* no metatable? */ |
| 710 | return 0; | 719 | return 0; |
| 711 | lua_pushstring(L, event); | 720 | lua_pushstring(L, event); |
| 712 | lua_rawget(L, -2); | 721 | if (lua_rawget(L, -2) == LUA_TNIL) { /* is metafield nil? */ |
| 713 | if (lua_isnil(L, -1)) { | ||
| 714 | lua_pop(L, 2); /* remove metatable and metafield */ | 722 | lua_pop(L, 2); /* remove metatable and metafield */ |
| 715 | return 0; | 723 | return 0; |
| 716 | } | 724 | } |
| @@ -746,10 +754,16 @@ LUALIB_API lua_Integer luaL_len (lua_State *L, int idx) { · 29 unmodified lines | |||
| 746 | LUALIB_API const char *luaL_tolstring (lua_State *L, int idx, size_t *len) { | 754 | LUALIB_API const char *luaL_tolstring (lua_State *L, int idx, size_t *len) { |
| 747 | if (!luaL_callmeta(L, idx, "__tostring")) { /* no metafield? */ | 755 | if (!luaL_callmeta(L, idx, "__tostring")) { /* no metafield? */ |
| 748 | switch (lua_type(L, idx)) { | 756 | switch (lua_type(L, idx)) { |
| 749 | case LUA_TNUMBER: { /* concatenate with empty string to convert */ | 757 | case LUA_TNUMBER: { |
| 750 | lua_pushvalue(L, idx); | 758 | if (lua_isinteger(L, idx)) |
| 751 | lua_pushliteral(L, ""); | 759 | lua_pushfstring(L, "%I", lua_tointeger(L, idx)); |
| 752 | lua_concat(L, 2); | 760 | else { |
| 761 | const char *s = lua_pushfstring(L, "%f", lua_tonumber(L, idx)); | ||
| 762 | if (s[strspn(s, "-0123456789")] == '\0') { /* looks like an int? */ | ||
| 763 | lua_pushliteral(L, ".0"); /* add a '.0' to result */ | ||
| 764 | lua_concat(L, 2); | ||
| 765 | } | ||
| 766 | } | ||
| 753 | break; | 767 | break; |
| 754 | } | 768 | } |
| 755 | case LUA_TSTRING: | 769 | case LUA_TSTRING: |
| @@ -786,8 +800,7 @@ static const char *luaL_findtable (lua_State *L, int idx, · 30 unmodified lines | |||
| 786 | e = strchr(fname, '.'); | 800 | e = strchr(fname, '.'); |
| 787 | if (e == NULL) e = fname + strlen(fname); | 801 | if (e == NULL) e = fname + strlen(fname); |
| 788 | lua_pushlstring(L, fname, e - fname); | 802 | lua_pushlstring(L, fname, e - fname); |
| 789 | lua_rawget(L, -2); | 803 | if (lua_rawget(L, -2) == LUA_TNIL) { /* no such field? */ |
| 790 | if (lua_isnil(L, -1)) { /* no such field? */ | ||
| 791 | lua_pop(L, 1); /* remove this nil */ | 804 | lua_pop(L, 1); /* remove this nil */ |
| 792 | lua_createtable(L, 0, (*e == '.' ? 1 : szhint)); /* new table for field */ | 805 | lua_createtable(L, 0, (*e == '.' ? 1 : szhint)); /* new table for field */ |
| 793 | lua_pushlstring(L, fname, e - fname); | 806 | lua_pushlstring(L, fname, e - fname); |
| @@ -824,8 +837,7 @@ static int libsize (const luaL_Reg *l) { · 30 unmodified lines | |||
| 824 | LUALIB_API void luaL_pushmodule (lua_State *L, const char *modname, | 837 | LUALIB_API void luaL_pushmodule (lua_State *L, const char *modname, |
| 825 | int sizehint) { | 838 | int sizehint) { |
| 826 | luaL_findtable(L, LUA_REGISTRYINDEX, "_LOADED", 1); /* get _LOADED table */ | 839 | luaL_findtable(L, LUA_REGISTRYINDEX, "_LOADED", 1); /* get _LOADED table */ |
| 827 | lua_getfield(L, -1, modname); /* get _LOADED[modname] */ | 840 | if (lua_getfield(L, -1, modname) != LUA_TTABLE) { /* no _LOADED[modname]? */ |
| 828 | if (!lua_istable(L, -1)) { /* not found? */ | ||
| 829 | lua_pop(L, 1); /* remove previous result */ | 841 | lua_pop(L, 1); /* remove previous result */ |
| 830 | /* try global variable (and create one if it does not exist) */ | 842 | /* try global variable (and create one if it does not exist) */ |
| 831 | lua_pushglobaltable(L); | 843 | lua_pushglobaltable(L); |
| @@ -877,8 +889,8 @@ LUALIB_API void luaL_setfuncs (lua_State *L, const luaL_Reg *l, int nup) { · 45 unmodified lines | |||
| 877 | ** into the stack | 889 | ** into the stack |
| 878 | */ | 890 | */ |
| 879 | LUALIB_API int luaL_getsubtable (lua_State *L, int idx, const char *fname) { | 891 | LUALIB_API int luaL_getsubtable (lua_State *L, int idx, const char *fname) { |
| 880 | lua_getfield(L, idx, fname); | 892 | if (lua_getfield(L, idx, fname) == LUA_TTABLE) |
| 881 | if (lua_istable(L, -1)) return 1; /* table already there */ | 893 | return 1; /* table already there */ |
| 882 | else { | 894 | else { |
| 883 | lua_pop(L, 1); /* remove previous result */ | 895 | lua_pop(L, 1); /* remove previous result */ |
| 884 | idx = lua_absindex(L, idx); | 896 | idx = lua_absindex(L, idx); |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lauxlib.h,v 1.122 2013/06/27 18:32:33 roberto Exp $ | 2 | ** $Id: lauxlib.h,v 1.123 2014/01/05 14:04:46 roberto Exp $ |
| 3 | ** Auxiliary functions for building Lua libraries | 3 | ** Auxiliary functions for building Lua libraries |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -35,24 +35,24 @@ LUALIB_API void (luaL_checkversion_) (lua_State *L, int ver, size_t sz); · 29 unmodified lines | |||
| 35 | LUALIB_API int (luaL_getmetafield) (lua_State *L, int obj, const char *e); | 35 | LUALIB_API int (luaL_getmetafield) (lua_State *L, int obj, const char *e); |
| 36 | LUALIB_API int (luaL_callmeta) (lua_State *L, int obj, const char *e); | 36 | LUALIB_API int (luaL_callmeta) (lua_State *L, int obj, const char *e); |
| 37 | LUALIB_API const char *(luaL_tolstring) (lua_State *L, int idx, size_t *len); | 37 | LUALIB_API const char *(luaL_tolstring) (lua_State *L, int idx, size_t *len); |
| 38 | LUALIB_API int (luaL_argerror) (lua_State *L, int numarg, const char *extramsg); | 38 | LUALIB_API int (luaL_argerror) (lua_State *L, int arg, const char *extramsg); |
| 39 | LUALIB_API const char *(luaL_checklstring) (lua_State *L, int numArg, | 39 | LUALIB_API const char *(luaL_checklstring) (lua_State *L, int arg, |
| 40 | size_t *l); | 40 | size_t *l); |
| 41 | LUALIB_API const char *(luaL_optlstring) (lua_State *L, int numArg, | 41 | LUALIB_API const char *(luaL_optlstring) (lua_State *L, int arg, |
| 42 | const char *def, size_t *l); | 42 | const char *def, size_t *l); |
| 43 | LUALIB_API lua_Number (luaL_checknumber) (lua_State *L, int numArg); | 43 | LUALIB_API lua_Number (luaL_checknumber) (lua_State *L, int arg); |
| 44 | LUALIB_API lua_Number (luaL_optnumber) (lua_State *L, int nArg, lua_Number def); | 44 | LUALIB_API lua_Number (luaL_optnumber) (lua_State *L, int arg, lua_Number def); |
| 45 | 45 | ||
| 46 | LUALIB_API lua_Integer (luaL_checkinteger) (lua_State *L, int numArg); | 46 | LUALIB_API lua_Integer (luaL_checkinteger) (lua_State *L, int arg); |
| 47 | LUALIB_API lua_Integer (luaL_optinteger) (lua_State *L, int nArg, | 47 | LUALIB_API lua_Integer (luaL_optinteger) (lua_State *L, int arg, |
| 48 | lua_Integer def); | 48 | lua_Integer def); |
| 49 | LUALIB_API lua_Unsigned (luaL_checkunsigned) (lua_State *L, int numArg); | 49 | LUALIB_API lua_Unsigned (luaL_checkunsigned) (lua_State *L, int arg); |
| 50 | LUALIB_API lua_Unsigned (luaL_optunsigned) (lua_State *L, int numArg, | 50 | LUALIB_API lua_Unsigned (luaL_optunsigned) (lua_State *L, int arg, |
| 51 | lua_Unsigned def); | 51 | lua_Unsigned def); |
| 52 | 52 | ||
| 53 | LUALIB_API void (luaL_checkstack) (lua_State *L, int sz, const char *msg); | 53 | LUALIB_API void (luaL_checkstack) (lua_State *L, int sz, const char *msg); |
| 54 | LUALIB_API void (luaL_checktype) (lua_State *L, int narg, int t); | 54 | LUALIB_API void (luaL_checktype) (lua_State *L, int arg, int t); |
| 55 | LUALIB_API void (luaL_checkany) (lua_State *L, int narg); | 55 | LUALIB_API void (luaL_checkany) (lua_State *L, int arg); |
| 56 | 56 | ||
| 57 | LUALIB_API int (luaL_newmetatable) (lua_State *L, const char *tname); | 57 | LUALIB_API int (luaL_newmetatable) (lua_State *L, const char *tname); |
| 58 | LUALIB_API void (luaL_setmetatable) (lua_State *L, const char *tname); | 58 | LUALIB_API void (luaL_setmetatable) (lua_State *L, const char *tname); |
| @@ -62,7 +62,7 @@ LUALIB_API void *(luaL_checkudata) (lua_State *L, int ud, const char *tname); · 3 unmodified lines | |||
| 62 | LUALIB_API void (luaL_where) (lua_State *L, int lvl); | 62 | LUALIB_API void (luaL_where) (lua_State *L, int lvl); |
| 63 | LUALIB_API int (luaL_error) (lua_State *L, const char *fmt, ...); | 63 | LUALIB_API int (luaL_error) (lua_State *L, const char *fmt, ...); |
| 64 | 64 | ||
| 65 | LUALIB_API int (luaL_checkoption) (lua_State *L, int narg, const char *def, | 65 | LUALIB_API int (luaL_checkoption) (lua_State *L, int arg, const char *def, |
| 66 | const char *const lst[]); | 66 | const char *const lst[]); |
| 67 | 67 | ||
| 68 | LUALIB_API int (luaL_fileresult) (lua_State *L, int stat, const char *fname); | 68 | LUALIB_API int (luaL_fileresult) (lua_State *L, int stat, const char *fname); |
| @@ -114,8 +114,8 @@ LUALIB_API void (luaL_requiref) (lua_State *L, const char *modname, · 45 unmodified lines | |||
| 114 | #define luaL_newlib(L,l) \ | 114 | #define luaL_newlib(L,l) \ |
| 115 | (luaL_checkversion(L), luaL_newlibtable(L,l), luaL_setfuncs(L,l,0)) | 115 | (luaL_checkversion(L), luaL_newlibtable(L,l), luaL_setfuncs(L,l,0)) |
| 116 | 116 | ||
| 117 | #define luaL_argcheck(L, cond,numarg,extramsg) \ | 117 | #define luaL_argcheck(L, cond,arg,extramsg) \ |
| 118 | ((void)((cond) || luaL_argerror(L, (numarg), (extramsg)))) | 118 | ((void)((cond) || luaL_argerror(L, (arg), (extramsg)))) |
| 119 | #define luaL_checkstring(L,n) (luaL_checklstring(L, (n), NULL)) | 119 | #define luaL_checkstring(L,n) (luaL_checklstring(L, (n), NULL)) |
| 120 | #define luaL_optstring(L,n,d) (luaL_optlstring(L, (n), (d), NULL)) | 120 | #define luaL_optstring(L,n,d) (luaL_optlstring(L, (n), (d), NULL)) |
| 121 | #define luaL_checkint(L,n) ((int)luaL_checkinteger(L, (n))) | 121 | #define luaL_checkint(L,n) ((int)luaL_checkinteger(L, (n))) |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lbaselib.c,v 1.279 2013/07/05 14:39:15 roberto Exp $ | 2 | ** $Id: lbaselib.c,v 1.285 2014/03/12 20:57:40 roberto Exp $ |
| 3 | ** Basic library | 3 | ** Basic library |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -63,7 +63,7 @@ static int b_str2int (const char *s, const char *e, int base, lua_Integer *pn) { · 57 unmodified lines | |||
| 63 | s += strspn(s, SPACECHARS); /* skip trailing spaces */ | 63 | s += strspn(s, SPACECHARS); /* skip trailing spaces */ |
| 64 | if (s != e) /* invalid trailing characters? */ | 64 | if (s != e) /* invalid trailing characters? */ |
| 65 | return 0; | 65 | return 0; |
| 66 | *pn = (neg) ? -(lua_Integer)n : (lua_Integer)n; | 66 | *pn = (lua_Integer)((neg) ? (0u - n) : n); |
| 67 | return 1; | 67 | return 1; |
| 68 | } | 68 | } |
| 69 | 69 | ||
| @@ -175,19 +175,18 @@ static int luaB_rawset (lua_State *L) { · 105 unmodified lines | |||
| 175 | static int luaB_collectgarbage (lua_State *L) { | 175 | static int luaB_collectgarbage (lua_State *L) { |
| 176 | static const char *const opts[] = {"stop", "restart", "collect", | 176 | static const char *const opts[] = {"stop", "restart", "collect", |
| 177 | "count", "step", "setpause", "setstepmul", | 177 | "count", "step", "setpause", "setstepmul", |
| 178 | "setmajorinc", "isrunning", "generational", "incremental", NULL}; | 178 | "isrunning", NULL}; |
| 179 | static const int optsnum[] = {LUA_GCSTOP, LUA_GCRESTART, LUA_GCCOLLECT, | 179 | static const int optsnum[] = {LUA_GCSTOP, LUA_GCRESTART, LUA_GCCOLLECT, |
| 180 | LUA_GCCOUNT, LUA_GCSTEP, LUA_GCSETPAUSE, LUA_GCSETSTEPMUL, | 180 | LUA_GCCOUNT, LUA_GCSTEP, LUA_GCSETPAUSE, LUA_GCSETSTEPMUL, |
| 181 | LUA_GCSETMAJORINC, LUA_GCISRUNNING, LUA_GCGEN, LUA_GCINC}; | 181 | LUA_GCISRUNNING}; |
| 182 | int o = optsnum[luaL_checkoption(L, 1, "collect", opts)]; | 182 | int o = optsnum[luaL_checkoption(L, 1, "collect", opts)]; |
| 183 | int ex = luaL_optint(L, 2, 0); | 183 | int ex = luaL_optint(L, 2, 0); |
| 184 | int res = lua_gc(L, o, ex); | 184 | int res = lua_gc(L, o, ex); |
| 185 | switch (o) { | 185 | switch (o) { |
| 186 | case LUA_GCCOUNT: { | 186 | case LUA_GCCOUNT: { |
| 187 | int b = lua_gc(L, LUA_GCCOUNTB, 0); | 187 | int b = lua_gc(L, LUA_GCCOUNTB, 0); |
| 188 | lua_pushnumber(L, res + ((lua_Number)b/1024)); | 188 | lua_pushnumber(L, (lua_Number)res + ((lua_Number)b/1024)); |
| 189 | lua_pushinteger(L, b); | 189 | return 1; |
| 190 | return 2; | ||
| 191 | } | 190 | } |
| 192 | case LUA_GCSTEP: case LUA_GCISRUNNING: { | 191 | case LUA_GCSTEP: case LUA_GCISRUNNING: { |
| 193 | lua_pushboolean(L, res); | 192 | lua_pushboolean(L, res); |
| @@ -247,8 +246,7 @@ static int ipairsaux (lua_State *L) { · 53 unmodified lines | |||
| 247 | luaL_checktype(L, 1, LUA_TTABLE); | 246 | luaL_checktype(L, 1, LUA_TTABLE); |
| 248 | i++; /* next value */ | 247 | i++; /* next value */ |
| 249 | lua_pushinteger(L, i); | 248 | lua_pushinteger(L, i); |
| 250 | lua_rawgeti(L, 1, i); | 249 | return (lua_rawgeti(L, 1, i) == LUA_TNIL) ? 1 : 2; |
| 251 | return (lua_isnil(L, -1)) ? 1 : 2; | ||
| 252 | } | 250 | } |
| 253 | 251 | ||
| 254 | 252 | ||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lbitlib.c,v 1.20 2013/06/21 17:27:24 roberto Exp $ | 2 | ** $Id: lbitlib.c,v 1.25 2014/03/20 19:22:16 roberto Exp $ |
| 3 | ** Standard library for bitwise operations | 3 | ** Standard library for bitwise operations |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -13,17 +13,21 @@ · 7 unmodified lines | |||
| 13 | #include "lualib.h" | 13 | #include "lualib.h" |
| 14 | 14 | ||
| 15 | 15 | ||
| 16 | #if defined(LUA_COMPAT_BITLIB) /* { */ | ||
| 17 | |||
| 18 | |||
| 16 | /* number of bits to consider in a number */ | 19 | /* number of bits to consider in a number */ |
| 17 | #if !defined(LUA_NBITS) | 20 | #if !defined(LUA_NBITS) |
| 18 | #define LUA_NBITS 32 | 21 | #define LUA_NBITS 32 |
| 19 | #endif | 22 | #endif |
| 20 | 23 | ||
| 21 | 24 | ||
| 22 | /* type with (at least) LUA_NBITS bits */ | 25 | /* |
| 23 | typedef unsigned long b_uint; | 26 | ** a lua_Unsigned with its first LUA_NBITS bits equal to 1. (Shift must |
| 24 | 27 | ** be made in two parts to avoid problems when LUA_NBITS is equal to the | |
| 25 | 28 | ** number of bits in a lua_Unsigned.) | |
| 26 | #define ALLONES (~(((~(b_uint)0) << (LUA_NBITS - 1)) << 1)) | 29 | */ |
| 30 | #define ALLONES (~(((~(lua_Unsigned)0) << (LUA_NBITS - 1)) << 1)) | ||
| 27 | 31 | ||
| 28 | 32 | ||
| 29 | /* macro to trim extra bits */ | 33 | /* macro to trim extra bits */ |
| @@ -35,9 +39,9 @@ typedef unsigned long b_uint; · 5 unmodified lines | |||
| 35 | 39 | ||
| 36 | 40 | ||
| 37 | 41 | ||
| 38 | static b_uint andaux (lua_State *L) { | 42 | static lua_Unsigned andaux (lua_State *L) { |
| 39 | int i, n = lua_gettop(L); | 43 | int i, n = lua_gettop(L); |
| 40 | b_uint r = ~(b_uint)0; | 44 | lua_Unsigned r = ~(lua_Unsigned)0; |
| 41 | for (i = 1; i <= n; i++) | 45 | for (i = 1; i <= n; i++) |
| 42 | r &= luaL_checkunsigned(L, i); | 46 | r &= luaL_checkunsigned(L, i); |
| 43 | return trim(r); | 47 | return trim(r); |
| @@ -45,14 +49,14 @@ static b_uint andaux (lua_State *L) { · 1 unmodified line | |||
| 45 | 49 | ||
| 46 | 50 | ||
| 47 | static int b_and (lua_State *L) { | 51 | static int b_and (lua_State *L) { |
| 48 | b_uint r = andaux(L); | 52 | lua_Unsigned r = andaux(L); |
| 49 | lua_pushunsigned(L, r); | 53 | lua_pushunsigned(L, r); |
| 50 | return 1; | 54 | return 1; |
| 51 | } | 55 | } |
| 52 | 56 | ||
| 53 | 57 | ||
| 54 | static int b_test (lua_State *L) { | 58 | static int b_test (lua_State *L) { |
| 55 | b_uint r = andaux(L); | 59 | lua_Unsigned r = andaux(L); |
| 56 | lua_pushboolean(L, r != 0); | 60 | lua_pushboolean(L, r != 0); |
| 57 | return 1; | 61 | return 1; |
| 58 | } | 62 | } |
| @@ -60,7 +64,7 @@ static int b_test (lua_State *L) { · 1 unmodified line | |||
| 60 | 64 | ||
| 61 | static int b_or (lua_State *L) { | 65 | static int b_or (lua_State *L) { |
| 62 | int i, n = lua_gettop(L); | 66 | int i, n = lua_gettop(L); |
| 63 | b_uint r = 0; | 67 | lua_Unsigned r = 0; |
| 64 | for (i = 1; i <= n; i++) | 68 | for (i = 1; i <= n; i++) |
| 65 | r |= luaL_checkunsigned(L, i); | 69 | r |= luaL_checkunsigned(L, i); |
| 66 | lua_pushunsigned(L, trim(r)); | 70 | lua_pushunsigned(L, trim(r)); |
| @@ -70,7 +74,7 @@ static int b_or (lua_State *L) { · 3 unmodified lines | |||
| 70 | 74 | ||
| 71 | static int b_xor (lua_State *L) { | 75 | static int b_xor (lua_State *L) { |
| 72 | int i, n = lua_gettop(L); | 76 | int i, n = lua_gettop(L); |
| 73 | b_uint r = 0; | 77 | lua_Unsigned r = 0; |
| 74 | for (i = 1; i <= n; i++) | 78 | for (i = 1; i <= n; i++) |
| 75 | r ^= luaL_checkunsigned(L, i); | 79 | r ^= luaL_checkunsigned(L, i); |
| 76 | lua_pushunsigned(L, trim(r)); | 80 | lua_pushunsigned(L, trim(r)); |
| @@ -79,13 +83,13 @@ static int b_xor (lua_State *L) { · 2 unmodified lines | |||
| 79 | 83 | ||
| 80 | 84 | ||
| 81 | static int b_not (lua_State *L) { | 85 | static int b_not (lua_State *L) { |
| 82 | b_uint r = ~luaL_checkunsigned(L, 1); | 86 | lua_Unsigned r = ~luaL_checkunsigned(L, 1); |
| 83 | lua_pushunsigned(L, trim(r)); | 87 | lua_pushunsigned(L, trim(r)); |
| 84 | return 1; | 88 | return 1; |
| 85 | } | 89 | } |
| 86 | 90 | ||
| 87 | 91 | ||
| 88 | static int b_shift (lua_State *L, b_uint r, int i) { | 92 | static int b_shift (lua_State *L, lua_Unsigned r, int i) { |
| 89 | if (i < 0) { /* shift right? */ | 93 | if (i < 0) { /* shift right? */ |
| 90 | i = -i; | 94 | i = -i; |
| 91 | r = trim(r); | 95 | r = trim(r); |
| @@ -113,14 +117,14 @@ static int b_rshift (lua_State *L) { · 21 unmodified lines | |||
| 113 | 117 | ||
| 114 | 118 | ||
| 115 | static int b_arshift (lua_State *L) { | 119 | static int b_arshift (lua_State *L) { |
| 116 | b_uint r = luaL_checkunsigned(L, 1); | 120 | lua_Unsigned r = luaL_checkunsigned(L, 1); |
| 117 | int i = luaL_checkint(L, 2); | 121 | int i = luaL_checkint(L, 2); |
| 118 | if (i < 0 || !(r & ((b_uint)1 << (LUA_NBITS - 1)))) | 122 | if (i < 0 || !(r & ((lua_Unsigned)1 << (LUA_NBITS - 1)))) |
| 119 | return b_shift(L, r, -i); | 123 | return b_shift(L, r, -i); |
| 120 | else { /* arithmetic shift for 'negative' number */ | 124 | else { /* arithmetic shift for 'negative' number */ |
| 121 | if (i >= LUA_NBITS) r = ALLONES; | 125 | if (i >= LUA_NBITS) r = ALLONES; |
| 122 | else | 126 | else |
| 123 | r = trim((r >> i) | ~(trim(~(b_uint)0) >> i)); /* add signal bit */ | 127 | r = trim((r >> i) | ~(trim(~(lua_Unsigned)0) >> i)); /* add signal bit */ |
| 124 | lua_pushunsigned(L, r); | 128 | lua_pushunsigned(L, r); |
| 125 | return 1; | 129 | return 1; |
| 126 | } | 130 | } |
| @@ -128,10 +132,11 @@ static int b_arshift (lua_State *L) { · 1 unmodified line | |||
| 128 | 132 | ||
| 129 | 133 | ||
| 130 | static int b_rot (lua_State *L, int i) { | 134 | static int b_rot (lua_State *L, int i) { |
| 131 | b_uint r = luaL_checkunsigned(L, 1); | 135 | lua_Unsigned r = luaL_checkunsigned(L, 1); |
| 132 | i &= (LUA_NBITS - 1); /* i = i % NBITS */ | 136 | i &= (LUA_NBITS - 1); /* i = i % NBITS */ |
| 133 | r = trim(r); | 137 | r = trim(r); |
| 134 | r = (r << i) | (r >> (LUA_NBITS - i)); | 138 | if (i != 0) /* avoid undefined shift of LUA_NBITS when i == 0 */ |
| 139 | r = (r << i) | (r >> (LUA_NBITS - i)); | ||
| 135 | lua_pushunsigned(L, trim(r)); | 140 | lua_pushunsigned(L, trim(r)); |
| 136 | return 1; | 141 | return 1; |
| 137 | } | 142 | } |
| @@ -167,7 +172,7 @@ static int fieldargs (lua_State *L, int farg, int *width) { · 29 unmodified lines | |||
| 167 | 172 | ||
| 168 | static int b_extract (lua_State *L) { | 173 | static int b_extract (lua_State *L) { |
| 169 | int w; | 174 | int w; |
| 170 | b_uint r = trim(luaL_checkunsigned(L, 1)); | 175 | lua_Unsigned r = trim(luaL_checkunsigned(L, 1)); |
| 171 | int f = fieldargs(L, 2, &w); | 176 | int f = fieldargs(L, 2, &w); |
| 172 | r = (r >> f) & mask(w); | 177 | r = (r >> f) & mask(w); |
| 173 | lua_pushunsigned(L, r); | 178 | lua_pushunsigned(L, r); |
| @@ -177,8 +182,8 @@ static int b_extract (lua_State *L) { · 3 unmodified lines | |||
| 177 | 182 | ||
| 178 | static int b_replace (lua_State *L) { | 183 | static int b_replace (lua_State *L) { |
| 179 | int w; | 184 | int w; |
| 180 | b_uint r = trim(luaL_checkunsigned(L, 1)); | 185 | lua_Unsigned r = trim(luaL_checkunsigned(L, 1)); |
| 181 | b_uint v = luaL_checkunsigned(L, 2); | 186 | lua_Unsigned v = luaL_checkunsigned(L, 2); |
| 182 | int f = fieldargs(L, 3, &w); | 187 | int f = fieldargs(L, 3, &w); |
| 183 | int m = mask(w); | 188 | int m = mask(w); |
| 184 | v &= m; /* erase bits outside given width */ | 189 | v &= m; /* erase bits outside given width */ |
| @@ -211,3 +216,13 @@ LUAMOD_API int luaopen_bit32 (lua_State *L) { · 26 unmodified lines | |||
| 211 | return 1; | 216 | return 1; |
| 212 | } | 217 | } |
| 213 | 218 | ||
| 219 | |||
| 220 | #else /* }{ */ | ||
| 221 | |||
| 222 | |||
| 223 | LUAMOD_API int luaopen_bit32 (lua_State *L) { | ||
| 224 | lua_pushnil(L); | ||
| 225 | return 1; | ||
| 226 | } | ||
| 227 | |||
| 228 | #endif /* } */ | ||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lcode.c,v 2.71 2013/06/25 18:57:18 roberto Exp $ | 2 | ** $Id: lcode.c,v 2.85 2014/03/21 13:52:33 roberto Exp $ |
| 3 | ** Code generator for Lua | 3 | ** Code generator for Lua |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -307,17 +307,21 @@ static void freeexp (FuncState *fs, expdesc *e) { · 301 unmodified lines | |||
| 307 | } | 307 | } |
| 308 | 308 | ||
| 309 | 309 | ||
| 310 | /* | ||
| 311 | ** Use scanner's table to cache position of constants in constant list | ||
| 312 | ** and try to reuse constants | ||
| 313 | */ | ||
| 310 | static int addk (FuncState *fs, TValue *key, TValue *v) { | 314 | static int addk (FuncState *fs, TValue *key, TValue *v) { |
| 311 | lua_State *L = fs->ls->L; | 315 | lua_State *L = fs->ls->L; |
| 312 | TValue *idx = luaH_set(L, fs->h, key); | ||
| 313 | Proto *f = fs->f; | 316 | Proto *f = fs->f; |
| 317 | TValue *idx = luaH_set(L, fs->ls->h, key); /* index scanner table */ | ||
| 314 | int k, oldsize; | 318 | int k, oldsize; |
| 315 | if (ttisinteger(idx)) { | 319 | if (ttisinteger(idx)) { /* is there an index there? */ |
| 316 | k = ivalue(idx); | 320 | k = ivalue(idx); |
| 317 | if (luaV_rawequalobj(&f->k[k], v)) | 321 | /* correct value? (warning: must distinguish floats from integers!) */ |
| 318 | return k; | 322 | if (k < fs->nk && ttype(&f->k[k]) == ttype(v) && |
| 319 | /* else may be a collision (e.g., between 0.0 and "\0\0\0\0\0\0\0\0"); | 323 | luaV_rawequalobj(&f->k[k], v)) |
| 320 | go through and create a new entry for this value */ | 324 | return k; /* reuse index */ |
| 321 | } | 325 | } |
| 322 | /* constant not found; create a new entry */ | 326 | /* constant not found; create a new entry */ |
| 323 | oldsize = f->sizek; | 327 | oldsize = f->sizek; |
| @@ -360,7 +364,7 @@ int luaK_intK (FuncState *fs, lua_Integer n) { · 36 unmodified lines | |||
| 360 | */ | 364 | */ |
| 361 | static int luaK_numberK (FuncState *fs, lua_Number r) { | 365 | static int luaK_numberK (FuncState *fs, lua_Number r) { |
| 362 | TValue o; | 366 | TValue o; |
| 363 | lua_assert(!luai_numisnan(NULL, r) && !isminuszero(r)); | 367 | lua_assert(!luai_numisnan(r) && !isminuszero(r)); |
| 364 | setnvalue(&o, r); | 368 | setnvalue(&o, r); |
| 365 | return addk(fs, &o, &o); | 369 | return addk(fs, &o, &o); |
| 366 | } | 370 | } |
| @@ -377,7 +381,7 @@ static int nilK (FuncState *fs) { · 10 unmodified lines | |||
| 377 | TValue k, v; | 381 | TValue k, v; |
| 378 | setnilvalue(&v); | 382 | setnilvalue(&v); |
| 379 | /* cannot use nil as key; instead use table itself to represent nil */ | 383 | /* cannot use nil as key; instead use table itself to represent nil */ |
| 380 | sethvalue(fs->ls->L, &k, fs->h); | 384 | sethvalue(fs->ls->L, &k, fs->ls->h); |
| 381 | return addk(fs, &k, &v); | 385 | return addk(fs, &k, &v); |
| 382 | } | 386 | } |
| 383 | 387 | ||
| @@ -746,24 +750,46 @@ void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k) { · 362 unmodified lines | |||
| 746 | } | 750 | } |
| 747 | 751 | ||
| 748 | 752 | ||
| 749 | static int constfolding (OpCode op, expdesc *e1, expdesc *e2) { | 753 | /* |
| 750 | TValue v1, v2, res; | 754 | ** return false if folding can raise an error |
| 755 | */ | ||
| 756 | static int validop (int op, TValue *v1, TValue *v2) { | ||
| 757 | lua_Number a, b; | ||
| 751 | lua_Integer i; | 758 | lua_Integer i; |
| 752 | if (!tonumeral(e1, &v1) || !tonumeral(e2, &v2)) | 759 | cast_void(a); cast_void(b); /* macro may not use its arguments */ |
| 760 | if (luai_numinvalidop(op, (cast_void(tonumber(v1, &a)), a), | ||
| 761 | (cast_void(tonumber(v2, &b)), b))) | ||
| 753 | return 0; | 762 | return 0; |
| 754 | if (op == OP_IDIV && | 763 | switch (op) { |
| 755 | (!tointeger(&v1, &i) || !tointeger(&v2, &i) || i == 0)) | 764 | case LUA_OPIDIV: /* division by 0 and conversion errors */ |
| 756 | return 0; /* avoid division by 0 and conversion errors */ | 765 | return (tointeger(v1, &i) && tointeger(v2, &i) && i != 0); |
| 757 | if (op == OP_MOD && ttisinteger(&v1) && ttisinteger(&v2) && ivalue(&v2) == 0) | 766 | case LUA_OPBAND: case LUA_OPBOR: case LUA_OPBXOR: |
| 758 | return 0; /* avoid module by 0 at compile time */ | 767 | case LUA_OPSHL: case LUA_OPSHR: case LUA_OPBNOT: /* conversion errors */ |
| 759 | luaO_arith(NULL, op - OP_ADD + LUA_OPADD, &v1, &v2, &res); | 768 | return (tointeger(v1, &i) && tointeger(v2, &i)); |
| 769 | case LUA_OPMOD: /* integer module by 0 */ | ||
| 770 | return !(ttisinteger(v1) && ttisinteger(v2) && ivalue(v2) == 0); | ||
| 771 | case LUA_OPPOW: /* negative integer exponentiation */ | ||
| 772 | return !(ttisinteger(v1) && ttisinteger(v2) && ivalue(v2) < 0); | ||
| 773 | default: return 1; /* everything else is valid */ | ||
| 774 | } | ||
| 775 | } | ||
| 776 | |||
| 777 | |||
| 778 | /* | ||
| 779 | ** Try to "constant-fold" an operation; return 1 iff successful | ||
| 780 | */ | ||
| 781 | static int constfolding (FuncState *fs, int op, expdesc *e1, expdesc *e2) { | ||
| 782 | TValue v1, v2, res; | ||
| 783 | if (!tonumeral(e1, &v1) || !tonumeral(e2, &v2) || !validop(op, &v1, &v2)) | ||
| 784 | return 0; /* non-numeric operands or not safe to fold */ | ||
| 785 | luaO_arith(fs->ls->L, op, &v1, &v2, &res); | ||
| 760 | if (ttisinteger(&res)) { | 786 | if (ttisinteger(&res)) { |
| 761 | e1->k = VKINT; | 787 | e1->k = VKINT; |
| 762 | e1->u.ival = ivalue(&res); | 788 | e1->u.ival = ivalue(&res); |
| 763 | } | 789 | } |
| 764 | else { | 790 | else { |
| 765 | lua_Number n = fltvalue(&res); | 791 | lua_Number n = fltvalue(&res); |
| 766 | if (luai_numisnan(NULL, n) || isminuszero(n)) | 792 | if (luai_numisnan(n) || isminuszero(n)) |
| 767 | return 0; /* folds neither NaN nor -0 */ | 793 | return 0; /* folds neither NaN nor -0 */ |
| 768 | e1->k = VKFLT; | 794 | e1->k = VKFLT; |
| 769 | e1->u.nval = n; | 795 | e1->u.nval = n; |
| @@ -774,9 +800,16 @@ static int constfolding (OpCode op, expdesc *e1, expdesc *e2) { · 4 unmodified lines | |||
| 774 | 800 | ||
| 775 | static void codearith (FuncState *fs, OpCode op, | 801 | static void codearith (FuncState *fs, OpCode op, |
| 776 | expdesc *e1, expdesc *e2, int line) { | 802 | expdesc *e1, expdesc *e2, int line) { |
| 777 | if (!constfolding(op, e1, e2)) { /* could not fold operation? */ | 803 | if (!constfolding(fs, op - OP_ADD + LUA_OPADD, e1, e2)) { |
| 778 | int o2 = (op != OP_UNM && op != OP_LEN) ? luaK_exp2RK(fs, e2) : 0; | 804 | int o1, o2; |
| 779 | int o1 = luaK_exp2RK(fs, e1); | 805 | if (op == OP_UNM || op == OP_BNOT || op == OP_LEN) { |
| 806 | o2 = 0; | ||
| 807 | o1 = luaK_exp2anyreg(fs, e1); /* cannot operate on constants */ | ||
| 808 | } | ||
| 809 | else { /* regular case (binary operators) */ | ||
| 810 | o2 = luaK_exp2RK(fs, e2); | ||
| 811 | o1 = luaK_exp2RK(fs, e1); | ||
| 812 | } | ||
| 780 | if (o1 > o2) { | 813 | if (o1 > o2) { |
| 781 | freeexp(fs, e1); | 814 | freeexp(fs, e1); |
| 782 | freeexp(fs, e2); | 815 | freeexp(fs, e2); |
| @@ -810,21 +843,13 @@ static void codecomp (FuncState *fs, OpCode op, int cond, expdesc *e1, · 27 unmodified lines | |||
| 810 | 843 | ||
| 811 | void luaK_prefix (FuncState *fs, UnOpr op, expdesc *e, int line) { | 844 | void luaK_prefix (FuncState *fs, UnOpr op, expdesc *e, int line) { |
| 812 | expdesc e2; | 845 | expdesc e2; |
| 813 | e2.t = e2.f = NO_JUMP; e2.k = VKFLT; e2.u.nval = 0; | 846 | e2.t = e2.f = NO_JUMP; e2.k = VKINT; e2.u.ival = 0; |
| 814 | switch (op) { | 847 | switch (op) { |
| 815 | case OPR_MINUS: { | 848 | case OPR_MINUS: case OPR_BNOT: case OPR_LEN: { |
| 816 | if (!constfolding(OP_UNM, e, e)) { /* cannot fold it? */ | 849 | codearith(fs, cast(OpCode, (op - OPR_MINUS) + OP_UNM), e, &e2, line); |
| 817 | luaK_exp2anyreg(fs, e); | ||
| 818 | codearith(fs, OP_UNM, e, &e2, line); | ||
| 819 | } | ||
| 820 | break; | 850 | break; |
| 821 | } | 851 | } |
| 822 | case OPR_NOT: codenot(fs, e); break; | 852 | case OPR_NOT: codenot(fs, e); break; |
| 823 | case OPR_LEN: { | ||
| 824 | luaK_exp2anyreg(fs, e); /* cannot operate on constants */ | ||
| 825 | codearith(fs, OP_LEN, e, &e2, line); | ||
| 826 | break; | ||
| 827 | } | ||
| 828 | default: lua_assert(0); | 853 | default: lua_assert(0); |
| 829 | } | 854 | } |
| 830 | } | 855 | } |
| @@ -846,7 +871,9 @@ void luaK_infix (FuncState *fs, BinOpr op, expdesc *v) { · 15 unmodified lines | |||
| 846 | } | 871 | } |
| 847 | case OPR_ADD: case OPR_SUB: | 872 | case OPR_ADD: case OPR_SUB: |
| 848 | case OPR_MUL: case OPR_DIV: case OPR_IDIV: | 873 | case OPR_MUL: case OPR_DIV: case OPR_IDIV: |
| 849 | case OPR_MOD: case OPR_POW: { | 874 | case OPR_MOD: case OPR_POW: |
| 875 | case OPR_BAND: case OPR_BOR: case OPR_BXOR: | ||
| 876 | case OPR_SHL: case OPR_SHR: { | ||
| 850 | if (!tonumeral(v, NULL)) luaK_exp2RK(fs, v); | 877 | if (!tonumeral(v, NULL)) luaK_exp2RK(fs, v); |
| 851 | break; | 878 | break; |
| 852 | } | 879 | } |
| @@ -890,8 +917,10 @@ void luaK_posfix (FuncState *fs, BinOpr op, · 37 unmodified lines | |||
| 890 | break; | 917 | break; |
| 891 | } | 918 | } |
| 892 | case OPR_ADD: case OPR_SUB: case OPR_MUL: case OPR_DIV: | 919 | case OPR_ADD: case OPR_SUB: case OPR_MUL: case OPR_DIV: |
| 893 | case OPR_IDIV: case OPR_MOD: case OPR_POW: { | 920 | case OPR_IDIV: case OPR_MOD: case OPR_POW: |
| 894 | codearith(fs, cast(OpCode, op - OPR_ADD + OP_ADD), e1, e2, line); | 921 | case OPR_BAND: case OPR_BOR: case OPR_BXOR: |
| 922 | case OPR_SHL: case OPR_SHR: { | ||
| 923 | codearith(fs, cast(OpCode, (op - OPR_ADD) + OP_ADD), e1, e2, line); | ||
| 895 | break; | 924 | break; |
| 896 | } | 925 | } |
| 897 | case OPR_EQ: case OPR_LT: case OPR_LE: { | 926 | case OPR_EQ: case OPR_LT: case OPR_LE: { |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lcode.h,v 1.60 2013/04/26 13:07:53 roberto Exp $ | 2 | ** $Id: lcode.h,v 1.63 2013/12/30 20:47:58 roberto Exp $ |
| 3 | ** Code generator for Lua | 3 | ** Code generator for Lua |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -24,7 +24,11 @@ · 18 unmodified lines | |||
| 24 | ** grep "ORDER OPR" if you change these enums (ORDER OP) | 24 | ** grep "ORDER OPR" if you change these enums (ORDER OP) |
| 25 | */ | 25 | */ |
| 26 | typedef enum BinOpr { | 26 | typedef enum BinOpr { |
| 27 | OPR_ADD, OPR_SUB, OPR_MUL, OPR_DIV, OPR_IDIV, OPR_MOD, OPR_POW, | 27 | OPR_ADD, OPR_SUB, OPR_MUL, OPR_MOD, OPR_POW, |
| 28 | OPR_DIV, | ||
| 29 | OPR_IDIV, | ||
| 30 | OPR_BAND, OPR_BOR, OPR_BXOR, | ||
| 31 | OPR_SHL, OPR_SHR, | ||
| 28 | OPR_CONCAT, | 32 | OPR_CONCAT, |
| 29 | OPR_EQ, OPR_LT, OPR_LE, | 33 | OPR_EQ, OPR_LT, OPR_LE, |
| 30 | OPR_NE, OPR_GT, OPR_GE, | 34 | OPR_NE, OPR_GT, OPR_GE, |
| @@ -33,7 +37,7 @@ typedef enum BinOpr { · 2 unmodified lines | |||
| 33 | } BinOpr; | 37 | } BinOpr; |
| 34 | 38 | ||
| 35 | 39 | ||
| 36 | typedef enum UnOpr { OPR_MINUS, OPR_NOT, OPR_LEN, OPR_NOUNOPR } UnOpr; | 40 | typedef enum UnOpr { OPR_MINUS, OPR_BNOT, OPR_NOT, OPR_LEN, OPR_NOUNOPR } UnOpr; |
| 37 | 41 | ||
| 38 | 42 | ||
| 39 | #define getcode(fs,e) ((fs)->f->code[(e)->u.info]) | 43 | #define getcode(fs,e) ((fs)->f->code[(e)->u.info]) |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: ldblib.c,v 1.133 2013/06/25 19:37:00 roberto Exp $ | 2 | ** $Id: ldblib.c,v 1.137 2014/03/12 20:57:40 roberto Exp $ |
| 3 | ** Interface from Lua to its debug API | 3 | ** Interface from Lua to its debug API |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -69,11 +69,8 @@ static int db_getuservalue (lua_State *L) { · 63 unmodified lines | |||
| 69 | 69 | ||
| 70 | 70 | ||
| 71 | static int db_setuservalue (lua_State *L) { | 71 | static int db_setuservalue (lua_State *L) { |
| 72 | if (lua_type(L, 1) == LUA_TLIGHTUSERDATA) | ||
| 73 | luaL_argerror(L, 1, "full userdata expected, got light userdata"); | ||
| 74 | luaL_checktype(L, 1, LUA_TUSERDATA); | 72 | luaL_checktype(L, 1, LUA_TUSERDATA); |
| 75 | if (!lua_isnoneornil(L, 2)) | 73 | luaL_checkany(L, 2); |
| 76 | luaL_checktype(L, 2, LUA_TTABLE); | ||
| 77 | lua_settop(L, 2); | 74 | lua_settop(L, 2); |
| 78 | lua_setuservalue(L, 1); | 75 | lua_setuservalue(L, 1); |
| 79 | return 1; | 76 | return 1; |
| @@ -273,8 +270,7 @@ static void hookf (lua_State *L, lua_Debug *ar) { · 193 unmodified lines | |||
| 273 | {"call", "return", "line", "count", "tail call"}; | 270 | {"call", "return", "line", "count", "tail call"}; |
| 274 | gethooktable(L); | 271 | gethooktable(L); |
| 275 | lua_pushthread(L); | 272 | lua_pushthread(L); |
| 276 | lua_rawget(L, -2); | 273 | if (lua_rawget(L, -2) == LUA_TFUNCTION) { |
| 277 | if (lua_isfunction(L, -1)) { | ||
| 278 | lua_pushstring(L, hooknames[(int)ar->event]); | 274 | lua_pushstring(L, hooknames[(int)ar->event]); |
| 279 | if (ar->currentline >= 0) | 275 | if (ar->currentline >= 0) |
| 280 | lua_pushinteger(L, ar->currentline); | 276 | lua_pushinteger(L, ar->currentline); |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: ldebug.c,v 2.95 2013/05/06 17:21:59 roberto Exp $ | 2 | ** $Id: ldebug.c,v 2.97 2013/12/09 14:21:10 roberto Exp $ |
| 3 | ** Debug Interface | 3 | ** Debug Interface |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -50,7 +50,7 @@ static int currentline (CallInfo *ci) { · 44 unmodified lines | |||
| 50 | /* | 50 | /* |
| 51 | ** this function can be called asynchronous (e.g. during a signal) | 51 | ** this function can be called asynchronous (e.g. during a signal) |
| 52 | */ | 52 | */ |
| 53 | LUA_API int lua_sethook (lua_State *L, lua_Hook func, int mask, int count) { | 53 | LUA_API void lua_sethook (lua_State *L, lua_Hook func, int mask, int count) { |
| 54 | if (func == NULL || mask == 0) { /* turn off hooks? */ | 54 | if (func == NULL || mask == 0) { /* turn off hooks? */ |
| 55 | mask = 0; | 55 | mask = 0; |
| 56 | func = NULL; | 56 | func = NULL; |
| @@ -61,7 +61,6 @@ LUA_API int lua_sethook (lua_State *L, lua_Hook func, int mask, int count) { · 4 unmodified lines | |||
| 61 | L->basehookcount = count; | 61 | L->basehookcount = count; |
| 62 | resethookcount(L); | 62 | resethookcount(L); |
| 63 | L->hookmask = cast_byte(mask); | 63 | L->hookmask = cast_byte(mask); |
| 64 | return 1; | ||
| 65 | } | 64 | } |
| 66 | 65 | ||
| 67 | 66 | ||
| @@ -327,12 +326,20 @@ static void kname (Proto *p, int pc, int c, const char **name) { · 259 unmodified lines | |||
| 327 | } | 326 | } |
| 328 | 327 | ||
| 329 | 328 | ||
| 329 | static int filterpc (int pc, int jmptarget) { | ||
| 330 | if (pc < jmptarget) /* is code conditional (inside a jump)? */ | ||
| 331 | return -1; /* cannot know who sets that register */ | ||
| 332 | else return pc; /* current position sets that register */ | ||
| 333 | } | ||
| 334 | |||
| 335 | |||
| 330 | /* | 336 | /* |
| 331 | ** try to find last instruction before 'lastpc' that modified register 'reg' | 337 | ** try to find last instruction before 'lastpc' that modified register 'reg' |
| 332 | */ | 338 | */ |
| 333 | static int findsetreg (Proto *p, int lastpc, int reg) { | 339 | static int findsetreg (Proto *p, int lastpc, int reg) { |
| 334 | int pc; | 340 | int pc; |
| 335 | int setreg = -1; /* keep last instruction that changed 'reg' */ | 341 | int setreg = -1; /* keep last instruction that changed 'reg' */ |
| 342 | int jmptarget = 0; /* any code before this address is conditional */ | ||
| 336 | for (pc = 0; pc < lastpc; pc++) { | 343 | for (pc = 0; pc < lastpc; pc++) { |
| 337 | Instruction i = p->code[pc]; | 344 | Instruction i = p->code[pc]; |
| 338 | OpCode op = GET_OPCODE(i); | 345 | OpCode op = GET_OPCODE(i); |
| @@ -341,33 +348,33 @@ static int findsetreg (Proto *p, int lastpc, int reg) { · 2 unmodified lines | |||
| 341 | case OP_LOADNIL: { | 348 | case OP_LOADNIL: { |
| 342 | int b = GETARG_B(i); | 349 | int b = GETARG_B(i); |
| 343 | if (a <= reg && reg <= a + b) /* set registers from 'a' to 'a+b' */ | 350 | if (a <= reg && reg <= a + b) /* set registers from 'a' to 'a+b' */ |
| 344 | setreg = pc; | 351 | setreg = filterpc(pc, jmptarget); |
| 345 | break; | 352 | break; |
| 346 | } | 353 | } |
| 347 | case OP_TFORCALL: { | 354 | case OP_TFORCALL: { |
| 348 | if (reg >= a + 2) setreg = pc; /* affect all regs above its base */ | 355 | if (reg >= a + 2) /* affect all regs above its base */ |
| 356 | setreg = filterpc(pc, jmptarget); | ||
| 349 | break; | 357 | break; |
| 350 | } | 358 | } |
| 351 | case OP_CALL: | 359 | case OP_CALL: |
| 352 | case OP_TAILCALL: { | 360 | case OP_TAILCALL: { |
| 353 | if (reg >= a) setreg = pc; /* affect all registers above base */ | 361 | if (reg >= a) /* affect all registers above base */ |
| 362 | setreg = filterpc(pc, jmptarget); | ||
| 354 | break; | 363 | break; |
| 355 | } | 364 | } |
| 356 | case OP_JMP: { | 365 | case OP_JMP: { |
| 357 | int b = GETARG_sBx(i); | 366 | int b = GETARG_sBx(i); |
| 358 | int dest = pc + 1 + b; | 367 | int dest = pc + 1 + b; |
| 359 | /* jump is forward and do not skip `lastpc'? */ | 368 | /* jump is forward and do not skip `lastpc'? */ |
| 360 | if (pc < dest && dest <= lastpc) | 369 | if (pc < dest && dest <= lastpc) { |
| 361 | pc += b; /* do the jump */ | 370 | if (dest > jmptarget) |
| 362 | break; | 371 | jmptarget = dest; /* update 'jmptarget' */ |
| 363 | } | 372 | } |
| 364 | case OP_TEST: { | ||
| 365 | if (reg == a) setreg = pc; /* jumped code can change 'a' */ | ||
| 366 | break; | 373 | break; |
| 367 | } | 374 | } |
| 368 | default: | 375 | default: |
| 369 | if (testAMode(op) && reg == a) /* any instruction that set A */ | 376 | if (testAMode(op) && reg == a) /* any instruction that set A */ |
| 370 | setreg = pc; | 377 | setreg = filterpc(pc, jmptarget); |
| 371 | break; | 378 | break; |
| 372 | } | 379 | } |
| 373 | } | 380 | } |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: ldebug.h,v 2.10 2013/05/06 17:19:11 roberto Exp $ | 2 | ** $Id: ldebug.h,v 2.11 2014/02/25 14:31:16 roberto Exp $ |
| 3 | ** Auxiliary functions from Debug Interface module | 3 | ** Auxiliary functions from Debug Interface module |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -13,7 +13,7 @@ · 7 unmodified lines | |||
| 13 | 13 | ||
| 14 | #define pcRel(pc, p) (cast(int, (pc) - (p)->code) - 1) | 14 | #define pcRel(pc, p) (cast(int, (pc) - (p)->code) - 1) |
| 15 | 15 | ||
| 16 | #define getfuncline(f,pc) (((f)->lineinfo) ? (f)->lineinfo[pc] : 0) | 16 | #define getfuncline(f,pc) (((f)->lineinfo) ? (f)->lineinfo[pc] : -1) |
| 17 | 17 | ||
| 18 | #define resethookcount(L) (L->hookcount = L->basehookcount) | 18 | #define resethookcount(L) (L->hookcount = L->basehookcount) |
| 19 | 19 | ||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: ldo.c,v 2.109 2013/04/19 21:05:04 roberto Exp $ | 2 | ** $Id: ldo.c,v 2.115 2014/03/21 13:52:33 roberto Exp $ |
| 3 | ** Stack and Call structure of Lua | 3 | ** Stack and Call structure of Lua |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -46,30 +46,33 @@ · 40 unmodified lines | |||
| 46 | ** C++ code, with _longjmp/_setjmp when asked to use them, and with | 46 | ** C++ code, with _longjmp/_setjmp when asked to use them, and with |
| 47 | ** longjmp/setjmp otherwise. | 47 | ** longjmp/setjmp otherwise. |
| 48 | */ | 48 | */ |
| 49 | #if !defined(LUAI_THROW) | 49 | #if !defined(LUAI_THROW) /* { */ |
| 50 | |||
| 51 | #if defined(__cplusplus) && !defined(LUA_USE_LONGJMP) /* { */ | ||
| 50 | 52 | ||
| 51 | #if defined(__cplusplus) && !defined(LUA_USE_LONGJMP) | ||
| 52 | /* C++ exceptions */ | 53 | /* C++ exceptions */ |
| 53 | #define LUAI_THROW(L,c) throw(c) | 54 | #define LUAI_THROW(L,c) throw(c) |
| 54 | #define LUAI_TRY(L,c,a) \ | 55 | #define LUAI_TRY(L,c,a) \ |
| 55 | try { a } catch(...) { if ((c)->status == 0) (c)->status = -1; } | 56 | try { a } catch(...) { if ((c)->status == 0) (c)->status = -1; } |
| 56 | #define luai_jmpbuf int /* dummy variable */ | 57 | #define luai_jmpbuf int /* dummy variable */ |
| 57 | 58 | ||
| 58 | #elif defined(LUA_USE_ULONGJMP) | 59 | #elif defined(LUA_USE_POSIX) /* }{ */ |
| 59 | /* in Unix, try _longjmp/_setjmp (more efficient) */ | 60 | |
| 61 | /* in POSIX, try _longjmp/_setjmp (more efficient) */ | ||
| 60 | #define LUAI_THROW(L,c) _longjmp((c)->b, 1) | 62 | #define LUAI_THROW(L,c) _longjmp((c)->b, 1) |
| 61 | #define LUAI_TRY(L,c,a) if (_setjmp((c)->b) == 0) { a } | 63 | #define LUAI_TRY(L,c,a) if (_setjmp((c)->b) == 0) { a } |
| 62 | #define luai_jmpbuf jmp_buf | 64 | #define luai_jmpbuf jmp_buf |
| 63 | 65 | ||
| 64 | #else | 66 | #else /* }{ */ |
| 65 | /* default handling with long jumps */ | 67 | |
| 68 | /* ANSI handling with long jumps */ | ||
| 66 | #define LUAI_THROW(L,c) longjmp((c)->b, 1) | 69 | #define LUAI_THROW(L,c) longjmp((c)->b, 1) |
| 67 | #define LUAI_TRY(L,c,a) if (setjmp((c)->b) == 0) { a } | 70 | #define LUAI_TRY(L,c,a) if (setjmp((c)->b) == 0) { a } |
| 68 | #define luai_jmpbuf jmp_buf | 71 | #define luai_jmpbuf jmp_buf |
| 69 | 72 | ||
| 70 | #endif | 73 | #endif /* } */ |
| 71 | 74 | ||
| 72 | #endif | 75 | #endif /* } */ |
| 73 | 76 | ||
| 74 | 77 | ||
| 75 | 78 | ||
| @@ -141,10 +144,10 @@ int luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud) { · 65 unmodified lines | |||
| 141 | 144 | ||
| 142 | static void correctstack (lua_State *L, TValue *oldstack) { | 145 | static void correctstack (lua_State *L, TValue *oldstack) { |
| 143 | CallInfo *ci; | 146 | CallInfo *ci; |
| 144 | GCObject *up; | 147 | UpVal *up; |
| 145 | L->top = (L->top - oldstack) + L->stack; | 148 | L->top = (L->top - oldstack) + L->stack; |
| 146 | for (up = L->openupval; up != NULL; up = up->gch.next) | 149 | for (up = L->openupval; up != NULL; up = up->u.open.next) |
| 147 | gco2uv(up)->v = (gco2uv(up)->v - oldstack) + L->stack; | 150 | up->v = (up->v - oldstack) + L->stack; |
| 148 | for (ci = L->ci; ci != NULL; ci = ci->previous) { | 151 | for (ci = L->ci; ci != NULL; ci = ci->previous) { |
| 149 | ci->top = (ci->top - oldstack) + L->stack; | 152 | ci->top = (ci->top - oldstack) + L->stack; |
| 150 | ci->func = (ci->func - oldstack) + L->stack; | 153 | ci->func = (ci->func - oldstack) + L->stack; |
| @@ -206,7 +209,11 @@ void luaD_shrinkstack (lua_State *L) { · 55 unmodified lines | |||
| 206 | int inuse = stackinuse(L); | 209 | int inuse = stackinuse(L); |
| 207 | int goodsize = inuse + (inuse / 8) + 2*EXTRA_STACK; | 210 | int goodsize = inuse + (inuse / 8) + 2*EXTRA_STACK; |
| 208 | if (goodsize > LUAI_MAXSTACK) goodsize = LUAI_MAXSTACK; | 211 | if (goodsize > LUAI_MAXSTACK) goodsize = LUAI_MAXSTACK; |
| 209 | if (inuse > LUAI_MAXSTACK || /* handling stack overflow? */ | 212 | if (L->stacksize > LUAI_MAXSTACK) /* was handling stack overflow? */ |
| 213 | luaE_freeCI(L); /* free all CIs (list grew because of an error) */ | ||
| 214 | else | ||
| 215 | luaE_shrinkCI(L); /* shrink list */ | ||
| 216 | if (inuse > LUAI_MAXSTACK || /* still handling stack overflow? */ | ||
| 210 | goodsize >= L->stacksize) /* would grow instead of shrink? */ | 217 | goodsize >= L->stacksize) /* would grow instead of shrink? */ |
| 211 | condmovestack(L); /* don't change stack (change only for debugging) */ | 218 | condmovestack(L); /* don't change stack (change only for debugging) */ |
| 212 | else | 219 | else |
| @@ -534,6 +541,7 @@ static void resume (lua_State *L, void *ud) { · 321 unmodified lines | |||
| 534 | 541 | ||
| 535 | LUA_API int lua_resume (lua_State *L, lua_State *from, int nargs) { | 542 | LUA_API int lua_resume (lua_State *L, lua_State *from, int nargs) { |
| 536 | int status; | 543 | int status; |
| 544 | int oldnny = L->nny; /* save 'nny' */ | ||
| 537 | lua_lock(L); | 545 | lua_lock(L); |
| 538 | luai_userstateresume(L, nargs); | 546 | luai_userstateresume(L, nargs); |
| 539 | L->nCcalls = (from) ? from->nCcalls + 1 : 1; | 547 | L->nCcalls = (from) ? from->nCcalls + 1 : 1; |
| @@ -555,7 +563,7 @@ LUA_API int lua_resume (lua_State *L, lua_State *from, int nargs) { · 15 unmodified lines | |||
| 555 | } | 563 | } |
| 556 | lua_assert(status == L->status); | 564 | lua_assert(status == L->status); |
| 557 | } | 565 | } |
| 558 | L->nny = 1; /* do not allow yields */ | 566 | L->nny = oldnny; /* restore 'nny' */ |
| 559 | L->nCcalls--; | 567 | L->nCcalls--; |
| 560 | lua_assert(L->nCcalls == ((from) ? from->nCcalls : 0)); | 568 | lua_assert(L->nCcalls == ((from) ? from->nCcalls : 0)); |
| 561 | lua_unlock(L); | 569 | lua_unlock(L); |
| @@ -637,7 +645,6 @@ static void checkmode (lua_State *L, const char *mode, const char *x) { · 75 unmodified lines | |||
| 637 | 645 | ||
| 638 | 646 | ||
| 639 | static void f_parser (lua_State *L, void *ud) { | 647 | static void f_parser (lua_State *L, void *ud) { |
| 640 | int i; | ||
| 641 | Closure *cl; | 648 | Closure *cl; |
| 642 | struct SParser *p = cast(struct SParser *, ud); | 649 | struct SParser *p = cast(struct SParser *, ud); |
| 643 | int c = zgetc(p->z); /* read first character */ | 650 | int c = zgetc(p->z); /* read first character */ |
| @@ -650,11 +657,7 @@ static void f_parser (lua_State *L, void *ud) { · 6 unmodified lines | |||
| 650 | cl = luaY_parser(L, p->z, &p->buff, &p->dyd, p->name, c); | 657 | cl = luaY_parser(L, p->z, &p->buff, &p->dyd, p->name, c); |
| 651 | } | 658 | } |
| 652 | lua_assert(cl->l.nupvalues == cl->l.p->sizeupvalues); | 659 | lua_assert(cl->l.nupvalues == cl->l.p->sizeupvalues); |
| 653 | for (i = 0; i < cl->l.nupvalues; i++) { /* initialize upvalues */ | 660 | luaF_initupvals(L, &cl->l); |
| 654 | UpVal *up = luaF_newupval(L); | ||
| 655 | cl->l.upvals[i] = up; | ||
| 656 | luaC_objbarrier(L, cl, up); | ||
| 657 | } | ||
| 658 | } | 661 | } |
| 659 | 662 | ||
| 660 | 663 | ||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: ldump.c,v 2.19 2013/04/26 18:48:35 roberto Exp $ | 2 | ** $Id: ldump.c,v 2.27 2014/03/11 18:56:27 roberto Exp $ |
| 3 | ** save precompiled Lua chunks | 3 | ** save precompiled Lua chunks |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -15,167 +15,188 @@ · 9 unmodified lines | |||
| 15 | #include "lstate.h" | 15 | #include "lstate.h" |
| 16 | #include "lundump.h" | 16 | #include "lundump.h" |
| 17 | 17 | ||
| 18 | |||
| 18 | typedef struct { | 19 | typedef struct { |
| 19 | lua_State* L; | 20 | lua_State *L; |
| 20 | lua_Writer writer; | 21 | lua_Writer writer; |
| 21 | void* data; | 22 | void *data; |
| 22 | int strip; | 23 | int strip; |
| 23 | int status; | 24 | int status; |
| 24 | } DumpState; | 25 | } DumpState; |
| 25 | 26 | ||
| 26 | #define DumpMem(b,n,size,D) DumpBlock(b,(n)*(size),D) | 27 | |
| 27 | #define DumpVar(x,D) DumpMem(&x,1,sizeof(x),D) | 28 | /* |
| 28 | 29 | ** All high-level dumps go through DumpVector; you can change it to | |
| 29 | static void DumpBlock(const void* b, size_t size, DumpState* D) | 30 | ** change the endianess of the result |
| 30 | { | 31 | */ |
| 31 | if (D->status==0) | 32 | #define DumpVector(v,n,D) DumpBlock(v,(n)*sizeof((v)[0]),D) |
| 32 | { | 33 | |
| 33 | lua_unlock(D->L); | 34 | #define DumpLiteral(s,D) DumpBlock(s, sizeof(s) - sizeof(char), D) |
| 34 | D->status=(*D->writer)(D->L,b,size,D->data); | 35 | |
| 35 | lua_lock(D->L); | 36 | |
| 36 | } | 37 | static void DumpBlock (const void *b, size_t size, DumpState *D) { |
| 38 | if (D->status == 0) { | ||
| 39 | lua_unlock(D->L); | ||
| 40 | D->status = (*D->writer)(D->L, b, size, D->data); | ||
| 41 | lua_lock(D->L); | ||
| 42 | } | ||
| 37 | } | 43 | } |
| 38 | 44 | ||
| 39 | static void DumpChar(int y, DumpState* D) | 45 | |
| 40 | { | 46 | #define DumpVar(x,D) DumpVector(&x,1,D) |
| 41 | char x=(char)y; | 47 | |
| 42 | DumpVar(x,D); | 48 | |
| 49 | static void DumpByte (int y, DumpState *D) { | ||
| 50 | lu_byte x = (lu_byte)y; | ||
| 51 | DumpVar(x, D); | ||
| 43 | } | 52 | } |
| 44 | 53 | ||
| 45 | static void DumpInt(int x, DumpState* D) | 54 | |
| 46 | { | 55 | static void DumpInt (int x, DumpState *D) { |
| 47 | DumpVar(x,D); | 56 | DumpVar(x, D); |
| 48 | } | 57 | } |
| 49 | 58 | ||
| 50 | static void DumpNumber(lua_Number x, DumpState* D) | 59 | |
| 51 | { | 60 | static void DumpNumber (lua_Number x, DumpState *D) { |
| 52 | DumpVar(x,D); | 61 | DumpVar(x, D); |
| 53 | } | 62 | } |
| 54 | 63 | ||
| 55 | static void DumpInteger(lua_Integer x, DumpState* D) | 64 | |
| 56 | { | 65 | static void DumpInteger (lua_Integer x, DumpState *D) { |
| 57 | DumpVar(x,D); | 66 | DumpVar(x, D); |
| 58 | } | 67 | } |
| 59 | 68 | ||
| 60 | static void DumpVector(const void* b, int n, size_t size, DumpState* D) | 69 | |
| 61 | { | 70 | static void DumpString (const TString *s, DumpState *D) { |
| 62 | DumpInt(n,D); | 71 | if (s == NULL) |
| 63 | DumpMem(b,n,size,D); | 72 | DumpByte(0, D); |
| 73 | else { | ||
| 74 | size_t size = s->tsv.len + 1; /* include trailing '\0' */ | ||
| 75 | if (size < 0xFF) | ||
| 76 | DumpByte(size, D); | ||
| 77 | else { | ||
| 78 | DumpByte(0xFF, D); | ||
| 79 | DumpVar(size, D); | ||
| 80 | } | ||
| 81 | DumpVector(getstr(s), size - 1, D); /* no need to save '\0' */ | ||
| 82 | } | ||
| 64 | } | 83 | } |
| 65 | 84 | ||
| 66 | static void DumpString(const TString* s, DumpState* D) | 85 | |
| 67 | { | 86 | static void DumpCode (const Proto *f, DumpState *D) { |
| 68 | if (s==NULL) | 87 | DumpInt(f->sizecode, D); |
| 69 | { | 88 | DumpVector(f->code, f->sizecode, D); |
| 70 | size_t size=0; | ||
| 71 | DumpVar(size,D); | ||
| 72 | } | ||
| 73 | else | ||
| 74 | { | ||
| 75 | size_t size=s->tsv.len+1; /* include trailing '\0' */ | ||
| 76 | DumpVar(size,D); | ||
| 77 | DumpBlock(getstr(s),size*sizeof(char),D); | ||
| 78 | } | ||
| 79 | } | 89 | } |
| 80 | 90 | ||
| 81 | #define DumpCode(f,D) DumpVector(f->code,f->sizecode,sizeof(Instruction),D) | 91 | |
| 82 | 92 | static void DumpFunction(const Proto *f, DumpState *D); | |
| 83 | static void DumpFunction(const Proto* f, DumpState* D); | 93 | |
| 84 | 94 | static void DumpConstants (const Proto *f, DumpState *D) { | |
| 85 | static void DumpConstants(const Proto* f, DumpState* D) | 95 | int i; |
| 86 | { | 96 | int n = f->sizek; |
| 87 | int i,n=f->sizek; | 97 | DumpInt(n, D); |
| 88 | DumpInt(n,D); | 98 | for (i = 0; i < n; i++) { |
| 89 | for (i=0; i<n; i++) | 99 | const TValue *o = &f->k[i]; |
| 90 | { | 100 | DumpByte(ttype(o), D); |
| 91 | const TValue* o=&f->k[i]; | 101 | switch (ttype(o)) { |
| 92 | DumpChar(ttype(o),D); | 102 | case LUA_TNIL: |
| 93 | switch (ttype(o)) | 103 | break; |
| 94 | { | 104 | case LUA_TBOOLEAN: |
| 95 | case LUA_TNIL: | 105 | DumpByte(bvalue(o), D); |
| 96 | break; | 106 | break; |
| 97 | case LUA_TBOOLEAN: | 107 | case LUA_TNUMFLT: |
| 98 | DumpChar(bvalue(o),D); | 108 | DumpNumber(fltvalue(o), D); |
| 99 | break; | 109 | break; |
| 100 | case LUA_TNUMFLT: | 110 | case LUA_TNUMINT: |
| 101 | DumpNumber(fltvalue(o),D); | 111 | DumpInteger(ivalue(o), D); |
| 102 | break; | 112 | break; |
| 103 | case LUA_TNUMINT: | 113 | case LUA_TSHRSTR: |
| 104 | DumpInteger(ivalue(o),D); | 114 | case LUA_TLNGSTR: |
| 105 | break; | 115 | DumpString(rawtsvalue(o), D); |
| 106 | case LUA_TSHRSTR: case LUA_TLNGSTR: | 116 | break; |
| 107 | DumpString(rawtsvalue(o),D); | 117 | default: |
| 108 | break; | 118 | lua_assert(0); |
| 109 | default: lua_assert(0); | 119 | } |
| 110 | } | 120 | } |
| 111 | } | 121 | n = f->sizep; |
| 112 | n=f->sizep; | 122 | DumpInt(n, D); |
| 113 | DumpInt(n,D); | 123 | for (i = 0; i < n; i++) |
| 114 | for (i=0; i<n; i++) DumpFunction(f->p[i],D); | 124 | DumpFunction(f->p[i], D); |
| 115 | } | 125 | } |
| 116 | 126 | ||
| 117 | static void DumpUpvalues(const Proto* f, DumpState* D) | 127 | |
| 118 | { | 128 | static void DumpUpvalues (const Proto *f, DumpState *D) { |
| 119 | int i,n=f->sizeupvalues; | 129 | int i, n = f->sizeupvalues; |
| 120 | DumpInt(n,D); | 130 | DumpInt(n, D); |
| 121 | for (i=0; i<n; i++) | 131 | for (i = 0; i < n; i++) { |
| 122 | { | 132 | DumpByte(f->upvalues[i].instack, D); |
| 123 | DumpChar(f->upvalues[i].instack,D); | 133 | DumpByte(f->upvalues[i].idx, D); |
| 124 | DumpChar(f->upvalues[i].idx,D); | 134 | } |
| 125 | } | ||
| 126 | } | 135 | } |
| 127 | 136 | ||
| 128 | static void DumpDebug(const Proto* f, DumpState* D) | 137 | |
| 129 | { | 138 | static void DumpDebug (const Proto *f, DumpState *D) { |
| 130 | int i,n; | 139 | int i, n; |
| 131 | DumpString((D->strip) ? NULL : f->source,D); | 140 | DumpString((D->strip) ? NULL : f->source, D); |
| 132 | n= (D->strip) ? 0 : f->sizelineinfo; | 141 | n = (D->strip) ? 0 : f->sizelineinfo; |
| 133 | DumpVector(f->lineinfo,n,sizeof(int),D); | 142 | DumpInt(n, D); |
| 134 | n= (D->strip) ? 0 : f->sizelocvars; | 143 | DumpVector(f->lineinfo, n, D); |
| 135 | DumpInt(n,D); | 144 | n = (D->strip) ? 0 : f->sizelocvars; |
| 136 | for (i=0; i<n; i++) | 145 | DumpInt(n, D); |
| 137 | { | 146 | for (i = 0; i < n; i++) { |
| 138 | DumpString(f->locvars[i].varname,D); | 147 | DumpString(f->locvars[i].varname, D); |
| 139 | DumpInt(f->locvars[i].startpc,D); | 148 | DumpInt(f->locvars[i].startpc, D); |
| 140 | DumpInt(f->locvars[i].endpc,D); | 149 | DumpInt(f->locvars[i].endpc, D); |
| 141 | } | 150 | } |
| 142 | n= (D->strip) ? 0 : f->sizeupvalues; | 151 | n = (D->strip) ? 0 : f->sizeupvalues; |
| 143 | DumpInt(n,D); | 152 | DumpInt(n, D); |
| 144 | for (i=0; i<n; i++) DumpString(f->upvalues[i].name,D); | 153 | for (i = 0; i < n; i++) |
| 154 | DumpString(f->upvalues[i].name, D); | ||
| 145 | } | 155 | } |
| 146 | 156 | ||
| 147 | static void DumpFunction(const Proto* f, DumpState* D) | 157 | |
| 148 | { | 158 | static void DumpFunction (const Proto *f, DumpState *D) { |
| 149 | DumpInt(f->linedefined,D); | 159 | DumpInt(f->linedefined, D); |
| 150 | DumpInt(f->lastlinedefined,D); | 160 | DumpInt(f->lastlinedefined, D); |
| 151 | DumpChar(f->numparams,D); | 161 | DumpByte(f->numparams, D); |
| 152 | DumpChar(f->is_vararg,D); | 162 | DumpByte(f->is_vararg, D); |
| 153 | DumpChar(f->maxstacksize,D); | 163 | DumpByte(f->maxstacksize, D); |
| 154 | DumpCode(f,D); | 164 | DumpCode(f, D); |
| 155 | DumpConstants(f,D); | 165 | DumpConstants(f, D); |
| 156 | DumpUpvalues(f,D); | 166 | DumpUpvalues(f, D); |
| 157 | DumpDebug(f,D); | 167 | DumpDebug(f, D); |
| 158 | } | 168 | } |
| 159 | 169 | ||
| 160 | static void DumpHeader(DumpState* D) | 170 | |
| 161 | { | 171 | static void DumpHeader (DumpState *D) { |
| 162 | lu_byte h[LUAC_HEADERSIZE]; | 172 | DumpLiteral(LUA_SIGNATURE, D); |
| 163 | luaU_header(h); | 173 | DumpByte(LUAC_VERSION, D); |
| 164 | DumpBlock(h,LUAC_HEADERSIZE,D); | 174 | DumpByte(LUAC_FORMAT, D); |
| 175 | DumpLiteral(LUAC_DATA, D); | ||
| 176 | DumpByte(sizeof(int), D); | ||
| 177 | DumpByte(sizeof(size_t), D); | ||
| 178 | DumpByte(sizeof(Instruction), D); | ||
| 179 | DumpByte(sizeof(lua_Integer), D); | ||
| 180 | DumpByte(sizeof(lua_Number), D); | ||
| 181 | DumpInteger(LUAC_INT, D); | ||
| 182 | DumpNumber(LUAC_NUM, D); | ||
| 165 | } | 183 | } |
| 166 | 184 | ||
| 185 | |||
| 167 | /* | 186 | /* |
| 168 | ** dump Lua function as precompiled chunk | 187 | ** dump Lua function as precompiled chunk |
| 169 | */ | 188 | */ |
| 170 | int luaU_dump (lua_State* L, const Proto* f, lua_Writer w, void* data, int strip) | 189 | int luaU_dump(lua_State *L, const Proto *f, lua_Writer w, void *data, |
| 171 | { | 190 | int strip) { |
| 172 | DumpState D; | 191 | DumpState D; |
| 173 | D.L=L; | 192 | D.L = L; |
| 174 | D.writer=w; | 193 | D.writer = w; |
| 175 | D.data=data; | 194 | D.data = data; |
| 176 | D.strip=strip; | 195 | D.strip = strip; |
| 177 | D.status=0; | 196 | D.status = 0; |
| 178 | DumpHeader(&D); | 197 | DumpHeader(&D); |
| 179 | DumpFunction(f,&D); | 198 | DumpByte(f->sizeupvalues, &D); |
| 180 | return D.status; | 199 | DumpFunction(f, &D); |
| 200 | return D.status; | ||
| 181 | } | 201 | } |
| 202 | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lfunc.c,v 2.30 2012/10/03 12:36:46 roberto Exp $ | 2 | ** $Id: lfunc.c,v 2.41 2014/02/18 13:39:37 roberto Exp $ |
| 3 | ** Auxiliary functions to manipulate prototypes and closures | 3 | ** Auxiliary functions to manipulate prototypes and closures |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -21,94 +21,79 @@ · 15 unmodified lines | |||
| 21 | 21 | ||
| 22 | 22 | ||
| 23 | Closure *luaF_newCclosure (lua_State *L, int n) { | 23 | Closure *luaF_newCclosure (lua_State *L, int n) { |
| 24 | Closure *c = &luaC_newobj(L, LUA_TCCL, sizeCclosure(n), NULL, 0)->cl; | 24 | Closure *c = &luaC_newobj(L, LUA_TCCL, sizeCclosure(n))->cl; |
| 25 | c->c.nupvalues = cast_byte(n); | 25 | c->c.nupvalues = cast_byte(n); |
| 26 | return c; | 26 | return c; |
| 27 | } | 27 | } |
| 28 | 28 | ||
| 29 | 29 | ||
| 30 | Closure *luaF_newLclosure (lua_State *L, int n) { | 30 | Closure *luaF_newLclosure (lua_State *L, int n) { |
| 31 | Closure *c = &luaC_newobj(L, LUA_TLCL, sizeLclosure(n), NULL, 0)->cl; | 31 | Closure *c = &luaC_newobj(L, LUA_TLCL, sizeLclosure(n))->cl; |
| 32 | c->l.p = NULL; | 32 | c->l.p = NULL; |
| 33 | c->l.nupvalues = cast_byte(n); | 33 | c->l.nupvalues = cast_byte(n); |
| 34 | while (n--) c->l.upvals[n] = NULL; | 34 | while (n--) c->l.upvals[n] = NULL; |
| 35 | return c; | 35 | return c; |
| 36 | } | 36 | } |
| 37 | 37 | ||
| 38 | 38 | /* | |
| 39 | UpVal *luaF_newupval (lua_State *L) { | 39 | ** fill a closure with new closed upvalues |
| 40 | UpVal *uv = &luaC_newobj(L, LUA_TUPVAL, sizeof(UpVal), NULL, 0)->uv; | 40 | */ |
| 41 | uv->v = &uv->u.value; | 41 | void luaF_initupvals (lua_State *L, LClosure *cl) { |
| 42 | setnilvalue(uv->v); | 42 | int i; |
| 43 | return uv; | 43 | for (i = 0; i < cl->nupvalues; i++) { |
| 44 | UpVal *uv = luaM_new(L, UpVal); | ||
| 45 | uv->refcount = 1; | ||
| 46 | uv->v = &uv->u.value; /* make it closed */ | ||
| 47 | setnilvalue(uv->v); | ||
| 48 | cl->upvals[i] = uv; | ||
| 49 | } | ||
| 44 | } | 50 | } |
| 45 | 51 | ||
| 46 | 52 | ||
| 47 | UpVal *luaF_findupval (lua_State *L, StkId level) { | 53 | UpVal *luaF_findupval (lua_State *L, StkId level) { |
| 48 | global_State *g = G(L); | 54 | UpVal **pp = &L->openupval; |
| 49 | GCObject **pp = &L->openupval; | ||
| 50 | UpVal *p; | 55 | UpVal *p; |
| 51 | UpVal *uv; | 56 | UpVal *uv; |
| 52 | while (*pp != NULL && (p = gco2uv(*pp))->v >= level) { | 57 | lua_assert(isintwups(L) || L->openupval == NULL); |
| 53 | GCObject *o = obj2gco(p); | 58 | while (*pp != NULL && (p = *pp)->v >= level) { |
| 54 | lua_assert(p->v != &p->u.value); | 59 | lua_assert(upisopen(p)); |
| 55 | lua_assert(!isold(o) || isold(obj2gco(L))); | 60 | if (p->v == level) /* found a corresponding upvalue? */ |
| 56 | if (p->v == level) { /* found a corresponding upvalue? */ | 61 | return p; /* return it */ |
| 57 | if (isdead(g, o)) /* is it dead? */ | 62 | pp = &p->u.open.next; |
| 58 | changewhite(o); /* resurrect it */ | ||
| 59 | return p; | ||
| 60 | } | ||
| 61 | pp = &p->next; | ||
| 62 | } | 63 | } |
| 63 | /* not found: create a new one */ | 64 | /* not found: create a new upvalue */ |
| 64 | uv = &luaC_newobj(L, LUA_TUPVAL, sizeof(UpVal), pp, 0)->uv; | 65 | uv = luaM_new(L, UpVal); |
| 66 | uv->refcount = 0; | ||
| 67 | uv->u.open.next = *pp; /* link it to list of open upvalues */ | ||
| 68 | uv->u.open.touched = 1; | ||
| 69 | *pp = uv; | ||
| 65 | uv->v = level; /* current value lives in the stack */ | 70 | uv->v = level; /* current value lives in the stack */ |
| 66 | uv->u.l.prev = &g->uvhead; /* double link it in `uvhead' list */ | 71 | if (!isintwups(L)) { /* thread not in list of threads with upvalues? */ |
| 67 | uv->u.l.next = g->uvhead.u.l.next; | 72 | L->twups = G(L)->twups; /* link it to the list */ |
| 68 | uv->u.l.next->u.l.prev = uv; | 73 | G(L)->twups = L; |
| 69 | g->uvhead.u.l.next = uv; | 74 | } |
| 70 | lua_assert(uv->u.l.next->u.l.prev == uv && uv->u.l.prev->u.l.next == uv); | ||
| 71 | return uv; | 75 | return uv; |
| 72 | } | 76 | } |
| 73 | 77 | ||
| 74 | 78 | ||
| 75 | static void unlinkupval (UpVal *uv) { | ||
| 76 | lua_assert(uv->u.l.next->u.l.prev == uv && uv->u.l.prev->u.l.next == uv); | ||
| 77 | uv->u.l.next->u.l.prev = uv->u.l.prev; /* remove from `uvhead' list */ | ||
| 78 | uv->u.l.prev->u.l.next = uv->u.l.next; | ||
| 79 | } | ||
| 80 | |||
| 81 | |||
| 82 | void luaF_freeupval (lua_State *L, UpVal *uv) { | ||
| 83 | if (uv->v != &uv->u.value) /* is it open? */ | ||
| 84 | unlinkupval(uv); /* remove from open list */ | ||
| 85 | luaM_free(L, uv); /* free upvalue */ | ||
| 86 | } | ||
| 87 | |||
| 88 | |||
| 89 | void luaF_close (lua_State *L, StkId level) { | 79 | void luaF_close (lua_State *L, StkId level) { |
| 90 | UpVal *uv; | 80 | UpVal *uv; |
| 91 | global_State *g = G(L); | 81 | while (L->openupval != NULL && (uv = L->openupval)->v >= level) { |
| 92 | while (L->openupval != NULL && (uv = gco2uv(L->openupval))->v >= level) { | 82 | lua_assert(upisopen(uv)); |
| 93 | GCObject *o = obj2gco(uv); | 83 | L->openupval = uv->u.open.next; /* remove from `open' list */ |
| 94 | lua_assert(!isblack(o) && uv->v != &uv->u.value); | 84 | if (uv->refcount == 0) /* no references? */ |
| 95 | L->openupval = uv->next; /* remove from `open' list */ | 85 | luaM_free(L, uv); /* free upvalue */ |
| 96 | if (isdead(g, o)) | ||
| 97 | luaF_freeupval(L, uv); /* free upvalue */ | ||
| 98 | else { | 86 | else { |
| 99 | unlinkupval(uv); /* remove upvalue from 'uvhead' list */ | ||
| 100 | setobj(L, &uv->u.value, uv->v); /* move value to upvalue slot */ | 87 | setobj(L, &uv->u.value, uv->v); /* move value to upvalue slot */ |
| 101 | uv->v = &uv->u.value; /* now current value lives here */ | 88 | uv->v = &uv->u.value; /* now current value lives here */ |
| 102 | gch(o)->next = g->allgc; /* link upvalue into 'allgc' list */ | 89 | luaC_upvalbarrier(L, uv); |
| 103 | g->allgc = o; | ||
| 104 | luaC_checkupvalcolor(g, uv); | ||
| 105 | } | 90 | } |
| 106 | } | 91 | } |
| 107 | } | 92 | } |
| 108 | 93 | ||
| 109 | 94 | ||
| 110 | Proto *luaF_newproto (lua_State *L) { | 95 | Proto *luaF_newproto (lua_State *L) { |
| 111 | Proto *f = &luaC_newobj(L, LUA_TPROTO, sizeof(Proto), NULL, 0)->p; | 96 | Proto *f = &luaC_newobj(L, LUA_TPROTO, sizeof(Proto))->p; |
| 112 | f->k = NULL; | 97 | f->k = NULL; |
| 113 | f->sizek = 0; | 98 | f->sizek = 0; |
| 114 | f->p = NULL; | 99 | f->p = NULL; |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lfunc.h,v 2.8 2012/05/08 13:53:33 roberto Exp $ | 2 | ** $Id: lfunc.h,v 2.13 2014/02/18 13:39:37 roberto Exp $ |
| 3 | ** Auxiliary functions to manipulate prototypes and closures | 3 | ** Auxiliary functions to manipulate prototypes and closures |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -18,14 +18,35 @@ · 12 unmodified lines | |||
| 18 | cast(int, sizeof(TValue *)*((n)-1))) | 18 | cast(int, sizeof(TValue *)*((n)-1))) |
| 19 | 19 | ||
| 20 | 20 | ||
| 21 | /* test whether thread is in 'twups' list */ | ||
| 22 | #define isintwups(L) (L->twups != L) | ||
| 23 | |||
| 24 | |||
| 25 | /* | ||
| 26 | ** Upvalues for Lua closures | ||
| 27 | */ | ||
| 28 | struct UpVal { | ||
| 29 | TValue *v; /* points to stack or to its own value */ | ||
| 30 | lu_mem refcount; /* reference counter */ | ||
| 31 | union { | ||
| 32 | struct { /* (when open) */ | ||
| 33 | UpVal *next; /* linked list */ | ||
| 34 | int touched; /* mark to avoid cycles with dead threads */ | ||
| 35 | } open; | ||
| 36 | TValue value; /* the value (when closed) */ | ||
| 37 | } u; | ||
| 38 | }; | ||
| 39 | |||
| 40 | #define upisopen(up) ((up)->v != &(up)->u.value) | ||
| 41 | |||
| 42 | |||
| 21 | LUAI_FUNC Proto *luaF_newproto (lua_State *L); | 43 | LUAI_FUNC Proto *luaF_newproto (lua_State *L); |
| 22 | LUAI_FUNC Closure *luaF_newCclosure (lua_State *L, int nelems); | 44 | LUAI_FUNC Closure *luaF_newCclosure (lua_State *L, int nelems); |
| 23 | LUAI_FUNC Closure *luaF_newLclosure (lua_State *L, int nelems); | 45 | LUAI_FUNC Closure *luaF_newLclosure (lua_State *L, int nelems); |
| 24 | LUAI_FUNC UpVal *luaF_newupval (lua_State *L); | 46 | LUAI_FUNC void luaF_initupvals (lua_State *L, LClosure *cl); |
| 25 | LUAI_FUNC UpVal *luaF_findupval (lua_State *L, StkId level); | 47 | LUAI_FUNC UpVal *luaF_findupval (lua_State *L, StkId level); |
| 26 | LUAI_FUNC void luaF_close (lua_State *L, StkId level); | 48 | LUAI_FUNC void luaF_close (lua_State *L, StkId level); |
| 27 | LUAI_FUNC void luaF_freeproto (lua_State *L, Proto *f); | 49 | LUAI_FUNC void luaF_freeproto (lua_State *L, Proto *f); |
| 28 | LUAI_FUNC void luaF_freeupval (lua_State *L, UpVal *uv); | ||
| 29 | LUAI_FUNC const char *luaF_getlocalname (const Proto *func, int local_number, | 50 | LUAI_FUNC const char *luaF_getlocalname (const Proto *func, int local_number, |
| 30 | int pc); | 51 | int pc); |
| 31 | 52 | ||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lgc.c,v 2.141 2013/04/26 18:26:49 roberto Exp $ | 2 | ** $Id: lgc.c,v 2.179 2014/03/21 13:52:33 roberto Exp $ |
| 3 | ** Garbage Collector | 3 | ** Garbage Collector |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -23,6 +23,11 @@ · 17 unmodified lines | |||
| 23 | #include "ltm.h" | 23 | #include "ltm.h" |
| 24 | 24 | ||
| 25 | 25 | ||
| 26 | /* | ||
| 27 | ** internal state for collector while inside the atomic phase. The | ||
| 28 | ** collector should never be in this state while running regular code. | ||
| 29 | */ | ||
| 30 | #define GCSinsideatomic (GCSpause + 1) | ||
| 26 | 31 | ||
| 27 | /* | 32 | /* |
| 28 | ** cost of sweeping one element (the size of a small object divided | 33 | ** cost of sweeping one element (the size of a small object divided |
| @@ -33,8 +38,8 @@ · 4 unmodified lines | |||
| 33 | /* maximum number of elements to sweep in each single step */ | 38 | /* maximum number of elements to sweep in each single step */ |
| 34 | #define GCSWEEPMAX (cast_int((GCSTEPSIZE / GCSWEEPCOST) / 4)) | 39 | #define GCSWEEPMAX (cast_int((GCSTEPSIZE / GCSWEEPCOST) / 4)) |
| 35 | 40 | ||
| 36 | /* maximum number of finalizers to call in each GC step */ | 41 | /* cost of calling one finalizer */ |
| 37 | #define GCFINALIZENUM 4 | 42 | #define GCFINALIZECOST GCSWEEPCOST |
| 38 | 43 | ||
| 39 | 44 | ||
| 40 | /* | 45 | /* |
| @@ -52,10 +57,10 @@ · 11 unmodified lines | |||
| 52 | 57 | ||
| 53 | 58 | ||
| 54 | /* | 59 | /* |
| 55 | ** 'makewhite' erases all color bits plus the old bit and then | 60 | ** 'makewhite' erases all color bits then sets only the current white |
| 56 | ** sets only the current white bit | 61 | ** bit |
| 57 | */ | 62 | */ |
| 58 | #define maskcolors (~(bit2mask(BLACKBIT, OLDBIT) | WHITEBITS)) | 63 | #define maskcolors (~(bitmask(BLACKBIT) | WHITEBITS)) |
| 59 | #define makewhite(g,x) \ | 64 | #define makewhite(g,x) \ |
| 60 | (gch(x)->marked = cast_byte((gch(x)->marked & maskcolors) | luaC_white(g))) | 65 | (gch(x)->marked = cast_byte((gch(x)->marked & maskcolors) | luaC_white(g))) |
| 61 | 66 | ||
| @@ -63,7 +68,7 @@ · 1 unmodified line | |||
| 63 | #define black2gray(x) resetbit(gch(x)->marked, BLACKBIT) | 68 | #define black2gray(x) resetbit(gch(x)->marked, BLACKBIT) |
| 64 | 69 | ||
| 65 | 70 | ||
| 66 | #define isfinalized(x) testbit(gch(x)->marked, FINALIZEDBIT) | 71 | #define valiswhite(x) (iscollectable(x) && iswhite(gcvalue(x))) |
| 67 | 72 | ||
| 68 | #define checkdeadkey(n) lua_assert(!ttisdeadkey(gkey(n)) || ttisnil(gval(n))) | 73 | #define checkdeadkey(n) lua_assert(!ttisdeadkey(gkey(n)) || ttisnil(gval(n))) |
| 69 | 74 | ||
| @@ -75,8 +80,8 @@ · 5 unmodified lines | |||
| 75 | #define markvalue(g,o) { checkconsistency(o); \ | 80 | #define markvalue(g,o) { checkconsistency(o); \ |
| 76 | if (valiswhite(o)) reallymarkobject(g,gcvalue(o)); } | 81 | if (valiswhite(o)) reallymarkobject(g,gcvalue(o)); } |
| 77 | 82 | ||
| 78 | #define markobject(g,t) { if ((t) && iswhite(obj2gco(t))) \ | 83 | #define markobject(g,t) \ |
| 79 | reallymarkobject(g, obj2gco(t)); } | 84 | { if ((t) && iswhite(obj2gco(t))) reallymarkobject(g, obj2gco(t)); } |
| 80 | 85 | ||
| 81 | static void reallymarkobject (global_State *g, GCObject *o); | 86 | static void reallymarkobject (global_State *g, GCObject *o); |
| 82 | 87 | ||
| @@ -136,8 +141,8 @@ void luaC_barrier_ (lua_State *L, GCObject *o, GCObject *v) { · 53 unmodified lines | |||
| 136 | global_State *g = G(L); | 141 | global_State *g = G(L); |
| 137 | lua_assert(isblack(o) && iswhite(v) && !isdead(g, v) && !isdead(g, o)); | 142 | lua_assert(isblack(o) && iswhite(v) && !isdead(g, v) && !isdead(g, o)); |
| 138 | lua_assert(g->gcstate != GCSpause); | 143 | lua_assert(g->gcstate != GCSpause); |
| 139 | lua_assert(gch(o)->tt != LUA_TTABLE); | 144 | lua_assert(gch(o)->tt != LUA_TTABLE); /* tables use a back barrier */ |
| 140 | if (keepinvariantout(g)) /* must keep invariant? */ | 145 | if (keepinvariant(g)) /* must keep invariant? */ |
| 141 | reallymarkobject(g, v); /* restore invariant */ | 146 | reallymarkobject(g, v); /* restore invariant */ |
| 142 | else { /* sweep phase */ | 147 | else { /* sweep phase */ |
| 143 | lua_assert(issweepphase(g)); | 148 | lua_assert(issweepphase(g)); |
| @@ -162,64 +167,41 @@ void luaC_barrierback_ (lua_State *L, GCObject *o) { · 18 unmodified lines | |||
| 162 | 167 | ||
| 163 | 168 | ||
| 164 | /* | 169 | /* |
| 165 | ** barrier for prototypes. When creating first closure (cache is | 170 | ** barrier for assignments to closed upvalues. Because upvalues are |
| 166 | ** NULL), use a forward barrier; this may be the only closure of the | 171 | ** shared among closures, it is impossible to know the color of all |
| 167 | ** prototype (if it is a "regular" function, with a single instance) | 172 | ** closures pointing to it. So, we assume that the object being assigned |
| 168 | ** and the prototype may be big, so it is better to avoid traversing | 173 | ** must be marked. |
| 169 | ** it again. Otherwise, use a backward barrier, to avoid marking all | ||
| 170 | ** possible instances. | ||
| 171 | */ | 174 | */ |
| 172 | LUAI_FUNC void luaC_barrierproto_ (lua_State *L, Proto *p, Closure *c) { | 175 | LUAI_FUNC void luaC_upvalbarrier_ (lua_State *L, UpVal *uv) { |
| 173 | global_State *g = G(L); | 176 | global_State *g = G(L); |
| 174 | lua_assert(isblack(obj2gco(p))); | 177 | GCObject *o = gcvalue(uv->v); |
| 175 | if (p->cache == NULL) { /* first time? */ | 178 | lua_assert(!upisopen(uv)); /* ensured by macro luaC_upvalbarrier */ |
| 176 | luaC_objbarrier(L, p, c); | 179 | if (keepinvariant(g)) |
| 177 | } | 180 | markobject(g, o); |
| 178 | else { /* use a backward barrier */ | ||
| 179 | black2gray(obj2gco(p)); /* make prototype gray (again) */ | ||
| 180 | p->gclist = g->grayagain; | ||
| 181 | g->grayagain = obj2gco(p); | ||
| 182 | } | ||
| 183 | } | 181 | } |
| 184 | 182 | ||
| 185 | 183 | ||
| 186 | /* | 184 | void luaC_fix (lua_State *L, GCObject *o) { |
| 187 | ** check color (and invariants) for an upvalue that was closed, | 185 | global_State *g = G(L); |
| 188 | ** i.e., moved into the 'allgc' list | 186 | lua_assert(g->allgc == o); /* object must be 1st in 'allgc' list! */ |
| 189 | */ | 187 | white2gray(o); /* they will be gray forever */ |
| 190 | void luaC_checkupvalcolor (global_State *g, UpVal *uv) { | 188 | g->allgc = o->gch.next; /* remove object from 'allgc' list */ |
| 191 | GCObject *o = obj2gco(uv); | 189 | o->gch.next = g->fixedgc; /* link it to 'fixedgc' list */ |
| 192 | lua_assert(!isblack(o)); /* open upvalues are never black */ | 190 | g->fixedgc = o; |
| 193 | if (isgray(o)) { | ||
| 194 | if (keepinvariant(g)) { | ||
| 195 | resetoldbit(o); /* see MOVE OLD rule */ | ||
| 196 | gray2black(o); /* it is being visited now */ | ||
| 197 | markvalue(g, uv->v); | ||
| 198 | } | ||
| 199 | else { | ||
| 200 | lua_assert(issweepphase(g)); | ||
| 201 | makewhite(g, o); | ||
| 202 | } | ||
| 203 | } | ||
| 204 | } | 191 | } |
| 205 | 192 | ||
| 206 | 193 | ||
| 207 | /* | 194 | /* |
| 208 | ** create a new collectable object (with given type and size) and link | 195 | ** create a new collectable object (with given type and size) and link |
| 209 | ** it to '*list'. 'offset' tells how many bytes to allocate before the | 196 | ** it to 'allgc' list. |
| 210 | ** object itself (used only by states). | ||
| 211 | */ | 197 | */ |
| 212 | GCObject *luaC_newobj (lua_State *L, int tt, size_t sz, GCObject **list, | 198 | GCObject *luaC_newobj (lua_State *L, int tt, size_t sz) { |
| 213 | int offset) { | ||
| 214 | global_State *g = G(L); | 199 | global_State *g = G(L); |
| 215 | char *raw = cast(char *, luaM_newobject(L, novariant(tt), sz)); | 200 | GCObject *o = cast(GCObject *, luaM_newobject(L, novariant(tt), sz)); |
| 216 | GCObject *o = obj2gco(raw + offset); | ||
| 217 | if (list == NULL) | ||
| 218 | list = &g->allgc; /* standard list for collectable objects */ | ||
| 219 | gch(o)->marked = luaC_white(g); | 201 | gch(o)->marked = luaC_white(g); |
| 220 | gch(o)->tt = tt; | 202 | gch(o)->tt = tt; |
| 221 | gch(o)->next = *list; | 203 | gch(o)->next = g->allgc; |
| 222 | *list = o; | 204 | g->allgc = o; |
| 223 | return o; | 205 | return o; |
| 224 | } | 206 | } |
| 225 | 207 | ||
| @@ -241,57 +223,53 @@ GCObject *luaC_newobj (lua_State *L, int tt, size_t sz, GCObject **list, · 15 unmodified lines | |||
| 241 | ** upvalues are already linked in 'headuv' list.) | 223 | ** upvalues are already linked in 'headuv' list.) |
| 242 | */ | 224 | */ |
| 243 | static void reallymarkobject (global_State *g, GCObject *o) { | 225 | static void reallymarkobject (global_State *g, GCObject *o) { |
| 244 | lu_mem size; | 226 | reentry: |
| 245 | white2gray(o); | 227 | white2gray(o); |
| 246 | switch (gch(o)->tt) { | 228 | switch (gch(o)->tt) { |
| 247 | case LUA_TSHRSTR: | 229 | case LUA_TSHRSTR: |
| 248 | case LUA_TLNGSTR: { | 230 | case LUA_TLNGSTR: { |
| 249 | size = sizestring(gco2ts(o)); | 231 | gray2black(o); |
| 250 | break; /* nothing else to mark; make it black */ | 232 | g->GCmemtrav += sizestring(gco2ts(o)); |
| 251 | } | ||
| 252 | case LUA_TUSERDATA: { | ||
| 253 | Table *mt = gco2u(o)->metatable; | ||
| 254 | markobject(g, mt); | ||
| 255 | markobject(g, gco2u(o)->env); | ||
| 256 | size = sizeudata(gco2u(o)); | ||
| 257 | break; | 233 | break; |
| 258 | } | 234 | } |
| 259 | case LUA_TUPVAL: { | 235 | case LUA_TUSERDATA: { |
| 260 | UpVal *uv = gco2uv(o); | 236 | TValue uvalue; |
| 261 | markvalue(g, uv->v); | 237 | markobject(g, gco2u(o)->metatable); /* mark its metatable */ |
| 262 | if (uv->v != &uv->u.value) /* open? */ | 238 | gray2black(o); |
| 263 | return; /* open upvalues remain gray */ | 239 | g->GCmemtrav += sizeudata(gco2u(o)); |
| 264 | size = sizeof(UpVal); | 240 | getuservalue(g->mainthread, rawgco2u(o), &uvalue); |
| 241 | if (valiswhite(&uvalue)) { /* markvalue(g, &uvalue); */ | ||
| 242 | o = gcvalue(&uvalue); | ||
| 243 | goto reentry; | ||
| 244 | } | ||
| 265 | break; | 245 | break; |
| 266 | } | 246 | } |
| 267 | case LUA_TLCL: { | 247 | case LUA_TLCL: { |
| 268 | gco2lcl(o)->gclist = g->gray; | 248 | gco2lcl(o)->gclist = g->gray; |
| 269 | g->gray = o; | 249 | g->gray = o; |
| 270 | return; | 250 | break; |
| 271 | } | 251 | } |
| 272 | case LUA_TCCL: { | 252 | case LUA_TCCL: { |
| 273 | gco2ccl(o)->gclist = g->gray; | 253 | gco2ccl(o)->gclist = g->gray; |
| 274 | g->gray = o; | 254 | g->gray = o; |
| 275 | return; | 255 | break; |
| 276 | } | 256 | } |
| 277 | case LUA_TTABLE: { | 257 | case LUA_TTABLE: { |
| 278 | linktable(gco2t(o), &g->gray); | 258 | linktable(gco2t(o), &g->gray); |
| 279 | return; | 259 | break; |
| 280 | } | 260 | } |
| 281 | case LUA_TTHREAD: { | 261 | case LUA_TTHREAD: { |
| 282 | gco2th(o)->gclist = g->gray; | 262 | gco2th(o)->gclist = g->gray; |
| 283 | g->gray = o; | 263 | g->gray = o; |
| 284 | return; | 264 | break; |
| 285 | } | 265 | } |
| 286 | case LUA_TPROTO: { | 266 | case LUA_TPROTO: { |
| 287 | gco2p(o)->gclist = g->gray; | 267 | gco2p(o)->gclist = g->gray; |
| 288 | g->gray = o; | 268 | g->gray = o; |
| 289 | return; | 269 | break; |
| 290 | } | 270 | } |
| 291 | default: lua_assert(0); return; | 271 | default: lua_assert(0); break; |
| 292 | } | 272 | } |
| 293 | gray2black(o); | ||
| 294 | g->GCmemtrav += size; | ||
| 295 | } | 273 | } |
| 296 | 274 | ||
| 297 | 275 | ||
| @@ -310,29 +288,41 @@ static void markmt (global_State *g) { · 12 unmodified lines | |||
| 310 | */ | 288 | */ |
| 311 | static void markbeingfnz (global_State *g) { | 289 | static void markbeingfnz (global_State *g) { |
| 312 | GCObject *o; | 290 | GCObject *o; |
| 313 | for (o = g->tobefnz; o != NULL; o = gch(o)->next) { | 291 | for (o = g->tobefnz; o != NULL; o = gch(o)->next) |
| 314 | makewhite(g, o); | 292 | markobject(g, o); |
| 315 | reallymarkobject(g, o); | ||
| 316 | } | ||
| 317 | } | 293 | } |
| 318 | 294 | ||
| 319 | 295 | ||
| 320 | /* | 296 | /* |
| 321 | ** mark all values stored in marked open upvalues. (See comment in | 297 | ** Mark all values stored in marked open upvalues from non-marked threads. |
| 322 | ** 'lstate.h'.) | 298 | ** (Values from marked threads were already marked when traversing the |
| 299 | ** thread.) Remove from the list threads that no longer have upvalues and | ||
| 300 | ** not-marked threads. | ||
| 323 | */ | 301 | */ |
| 324 | static void remarkupvals (global_State *g) { | 302 | static void remarkupvals (global_State *g) { |
| 325 | UpVal *uv; | 303 | lua_State *thread; |
| 326 | for (uv = g->uvhead.u.l.next; uv != &g->uvhead; uv = uv->u.l.next) { | 304 | lua_State **p = &g->twups; |
| 327 | if (isgray(obj2gco(uv))) | 305 | while ((thread = *p) != NULL) { |
| 328 | markvalue(g, uv->v); | 306 | lua_assert(!isblack(obj2gco(thread))); /* threads are never black */ |
| 307 | if (isgray(obj2gco(thread)) && thread->openupval != NULL) | ||
| 308 | p = &thread->twups; /* keep marked thread with upvalues in the list */ | ||
| 309 | else { /* thread is not marked or without upvalues */ | ||
| 310 | UpVal *uv; | ||
| 311 | *p = thread->twups; /* remove thread from the list */ | ||
| 312 | thread->twups = thread; /* mark that it is out of list */ | ||
| 313 | for (uv = thread->openupval; uv != NULL; uv = uv->u.open.next) { | ||
| 314 | if (uv->u.open.touched) { | ||
| 315 | markvalue(g, uv->v); /* remark upvalue's value */ | ||
| 316 | uv->u.open.touched = 0; | ||
| 317 | } | ||
| 318 | } | ||
| 319 | } | ||
| 329 | } | 320 | } |
| 330 | } | 321 | } |
| 331 | 322 | ||
| 332 | 323 | ||
| 333 | /* | 324 | /* |
| 334 | ** mark root set and reset all gray lists, to start a new | 325 | ** mark root set and reset all gray lists, to start a new collection |
| 335 | ** incremental (or full) collection | ||
| 336 | */ | 326 | */ |
| 337 | static void restartcollection (global_State *g) { | 327 | static void restartcollection (global_State *g) { |
| 338 | g->gray = g->grayagain = NULL; | 328 | g->gray = g->grayagain = NULL; |
| @@ -483,11 +473,24 @@ static lu_mem traverseCclosure (global_State *g, CClosure *cl) { · 144 unmodified lines | |||
| 483 | return sizeCclosure(cl->nupvalues); | 473 | return sizeCclosure(cl->nupvalues); |
| 484 | } | 474 | } |
| 485 | 475 | ||
| 476 | /* | ||
| 477 | ** open upvalues point to values in a thread, so those values should | ||
| 478 | ** be marked when the thread is traversed except in the atomic phase | ||
| 479 | ** (because then the value cannot be changed by the thread and the | ||
| 480 | ** thread may not be traversed again) | ||
| 481 | */ | ||
| 486 | static lu_mem traverseLclosure (global_State *g, LClosure *cl) { | 482 | static lu_mem traverseLclosure (global_State *g, LClosure *cl) { |
| 487 | int i; | 483 | int i; |
| 488 | markobject(g, cl->p); /* mark its prototype */ | 484 | markobject(g, cl->p); /* mark its prototype */ |
| 489 | for (i = 0; i < cl->nupvalues; i++) /* mark its upvalues */ | 485 | for (i = 0; i < cl->nupvalues; i++) { /* mark its upvalues */ |
| 490 | markobject(g, cl->upvals[i]); | 486 | UpVal *uv = cl->upvals[i]; |
| 487 | if (uv != NULL) { | ||
| 488 | if (upisopen(uv) && g->gcstate != GCSinsideatomic) | ||
| 489 | uv->u.open.touched = 1; /* can be marked in 'remarkupvals' */ | ||
| 490 | else | ||
| 491 | markvalue(g, uv->v); | ||
| 492 | } | ||
| 493 | } | ||
| 491 | return sizeLclosure(cl->nupvalues); | 494 | return sizeLclosure(cl->nupvalues); |
| 492 | } | 495 | } |
| 493 | 496 | ||
| @@ -497,17 +500,27 @@ static lu_mem traversestack (global_State *g, lua_State *th) { · 3 unmodified lines | |||
| 497 | StkId o = th->stack; | 500 | StkId o = th->stack; |
| 498 | if (o == NULL) | 501 | if (o == NULL) |
| 499 | return 1; /* stack not completely built yet */ | 502 | return 1; /* stack not completely built yet */ |
| 503 | lua_assert(g->gcstate == GCSinsideatomic || | ||
| 504 | th->openupval == NULL || isintwups(th)); | ||
| 500 | for (; o < th->top; o++) /* mark live elements in the stack */ | 505 | for (; o < th->top; o++) /* mark live elements in the stack */ |
| 501 | markvalue(g, o); | 506 | markvalue(g, o); |
| 502 | if (g->gcstate == GCSatomic) { /* final traversal? */ | 507 | if (g->gcstate == GCSinsideatomic) { /* final traversal? */ |
| 503 | StkId lim = th->stack + th->stacksize; /* real end of stack */ | 508 | StkId lim = th->stack + th->stacksize; /* real end of stack */ |
| 504 | for (; o < lim; o++) /* clear not-marked stack slice */ | 509 | for (; o < lim; o++) /* clear not-marked stack slice */ |
| 505 | setnilvalue(o); | 510 | setnilvalue(o); |
| 511 | /* 'remarkupvals' may have removed thread from 'twups' list */ | ||
| 512 | if (!isintwups(th) && th->openupval != NULL) { | ||
| 513 | th->twups = g->twups; /* link it back to the list */ | ||
| 514 | g->twups = th; | ||
| 515 | } | ||
| 506 | } | 516 | } |
| 507 | else { /* count call infos to compute size */ | 517 | else { |
| 508 | CallInfo *ci; | 518 | CallInfo *ci; |
| 509 | for (ci = &th->base_ci; ci != th->ci; ci = ci->next) | 519 | for (ci = &th->base_ci; ci != th->ci; ci = ci->next) |
| 510 | n++; | 520 | n++; /* count call infos to compute size */ |
| 521 | /* should not change the stack during an emergency gc cycle */ | ||
| 522 | if (g->gckind != KGC_EMERGENCY) | ||
| 523 | luaD_shrinkstack(th); | ||
| 511 | } | 524 | } |
| 512 | return sizeof(lua_State) + sizeof(TValue) * th->stacksize + | 525 | return sizeof(lua_State) + sizeof(TValue) * th->stacksize + |
| 513 | sizeof(CallInfo) * n; | 526 | sizeof(CallInfo) * n; |
| @@ -660,23 +673,41 @@ static void clearvalues (global_State *g, GCObject *l, GCObject *f) { · 146 unmodified lines | |||
| 660 | } | 673 | } |
| 661 | 674 | ||
| 662 | 675 | ||
| 676 | void luaC_upvdeccount (lua_State *L, UpVal *uv) { | ||
| 677 | lua_assert(uv->refcount > 0); | ||
| 678 | uv->refcount--; | ||
| 679 | if (uv->refcount == 0 && !upisopen(uv)) | ||
| 680 | luaM_free(L, uv); | ||
| 681 | } | ||
| 682 | |||
| 683 | |||
| 684 | static void freeLclosure (lua_State *L, LClosure *cl) { | ||
| 685 | int i; | ||
| 686 | for (i = 0; i < cl->nupvalues; i++) { | ||
| 687 | UpVal *uv = cl->upvals[i]; | ||
| 688 | if (uv) | ||
| 689 | luaC_upvdeccount(L, uv); | ||
| 690 | } | ||
| 691 | luaM_freemem(L, cl, sizeLclosure(cl->nupvalues)); | ||
| 692 | } | ||
| 693 | |||
| 694 | |||
| 663 | static void freeobj (lua_State *L, GCObject *o) { | 695 | static void freeobj (lua_State *L, GCObject *o) { |
| 664 | switch (gch(o)->tt) { | 696 | switch (gch(o)->tt) { |
| 665 | case LUA_TPROTO: luaF_freeproto(L, gco2p(o)); break; | 697 | case LUA_TPROTO: luaF_freeproto(L, gco2p(o)); break; |
| 666 | case LUA_TLCL: { | 698 | case LUA_TLCL: { |
| 667 | luaM_freemem(L, o, sizeLclosure(gco2lcl(o)->nupvalues)); | 699 | freeLclosure(L, gco2lcl(o)); |
| 668 | break; | 700 | break; |
| 669 | } | 701 | } |
| 670 | case LUA_TCCL: { | 702 | case LUA_TCCL: { |
| 671 | luaM_freemem(L, o, sizeCclosure(gco2ccl(o)->nupvalues)); | 703 | luaM_freemem(L, o, sizeCclosure(gco2ccl(o)->nupvalues)); |
| 672 | break; | 704 | break; |
| 673 | } | 705 | } |
| 674 | case LUA_TUPVAL: luaF_freeupval(L, gco2uv(o)); break; | ||
| 675 | case LUA_TTABLE: luaH_free(L, gco2t(o)); break; | 706 | case LUA_TTABLE: luaH_free(L, gco2t(o)); break; |
| 676 | case LUA_TTHREAD: luaE_freethread(L, gco2th(o)); break; | 707 | case LUA_TTHREAD: luaE_freethread(L, gco2th(o)); break; |
| 677 | case LUA_TUSERDATA: luaM_freemem(L, o, sizeudata(gco2u(o))); break; | 708 | case LUA_TUSERDATA: luaM_freemem(L, o, sizeudata(gco2u(o))); break; |
| 678 | case LUA_TSHRSTR: | 709 | case LUA_TSHRSTR: |
| 679 | G(L)->strt.nuse--; | 710 | luaS_remove(L, rawgco2ts(o)); /* remove it from hash table */ |
| 680 | /* go through */ | 711 | /* go through */ |
| 681 | case LUA_TLNGSTR: { | 712 | case LUA_TLNGSTR: { |
| 682 | luaM_freemem(L, o, sizestring(gco2ts(o))); | 713 | luaM_freemem(L, o, sizestring(gco2ts(o))); |
| @@ -691,46 +722,17 @@ static void freeobj (lua_State *L, GCObject *o) { · 8 unmodified lines | |||
| 691 | static GCObject **sweeplist (lua_State *L, GCObject **p, lu_mem count); | 722 | static GCObject **sweeplist (lua_State *L, GCObject **p, lu_mem count); |
| 692 | 723 | ||
| 693 | 724 | ||
| 694 | /* | ||
| 695 | ** sweep the (open) upvalues of a thread and resize its stack and | ||
| 696 | ** list of call-info structures. | ||
| 697 | */ | ||
| 698 | static void sweepthread (lua_State *L, lua_State *L1) { | ||
| 699 | if (L1->stack == NULL) return; /* stack not completely built yet */ | ||
| 700 | sweepwholelist(L, &L1->openupval); /* sweep open upvalues */ | ||
| 701 | luaE_freeCI(L1); /* free extra CallInfo slots */ | ||
| 702 | /* should not change the stack during an emergency gc cycle */ | ||
| 703 | if (G(L)->gckind != KGC_EMERGENCY) | ||
| 704 | luaD_shrinkstack(L1); | ||
| 705 | } | ||
| 706 | |||
| 707 | |||
| 708 | /* | 725 | /* |
| 709 | ** sweep at most 'count' elements from a list of GCObjects erasing dead | 726 | ** sweep at most 'count' elements from a list of GCObjects erasing dead |
| 710 | ** objects, where a dead (not alive) object is one marked with the "old" | 727 | ** objects, where a dead (not alive) object is one marked with the "old" |
| 711 | ** (non current) white and not fixed. | 728 | ** (non current) white and not fixed; change all non-dead objects back |
| 712 | ** In non-generational mode, change all non-dead objects back to white, | 729 | ** to white, preparing for next collection cycle. |
| 713 | ** preparing for next collection cycle. | ||
| 714 | ** In generational mode, keep black objects black, and also mark them as | ||
| 715 | ** old; stop when hitting an old object, as all objects after that | ||
| 716 | ** one will be old too. | ||
| 717 | ** When object is a thread, sweep its list of open upvalues too. | 730 | ** When object is a thread, sweep its list of open upvalues too. |
| 718 | */ | 731 | */ |
| 719 | static GCObject **sweeplist (lua_State *L, GCObject **p, lu_mem count) { | 732 | static GCObject **sweeplist (lua_State *L, GCObject **p, lu_mem count) { |
| 720 | global_State *g = G(L); | 733 | global_State *g = G(L); |
| 721 | int ow = otherwhite(g); | 734 | int ow = otherwhite(g); |
| 722 | int toclear, toset; /* bits to clear and to set in all live objects */ | 735 | int white = luaC_white(g); /* current white */ |
| 723 | int tostop; /* stop sweep when this is true */ | ||
| 724 | if (isgenerational(g)) { /* generational mode? */ | ||
| 725 | toclear = ~0; /* clear nothing */ | ||
| 726 | toset = bitmask(OLDBIT); /* set the old bit of all surviving objects */ | ||
| 727 | tostop = bitmask(OLDBIT); /* do not sweep old generation */ | ||
| 728 | } | ||
| 729 | else { /* normal mode */ | ||
| 730 | toclear = maskcolors; /* clear all color bits + old bit */ | ||
| 731 | toset = luaC_white(g); /* make object white */ | ||
| 732 | tostop = 0; /* do not stop */ | ||
| 733 | } | ||
| 734 | while (*p != NULL && count-- > 0) { | 736 | while (*p != NULL && count-- > 0) { |
| 735 | GCObject *curr = *p; | 737 | GCObject *curr = *p; |
| 736 | int marked = gch(curr)->marked; | 738 | int marked = gch(curr)->marked; |
| @@ -738,13 +740,8 @@ static GCObject **sweeplist (lua_State *L, GCObject **p, lu_mem count) { · 1 unmodified line | |||
| 738 | *p = gch(curr)->next; /* remove 'curr' from list */ | 740 | *p = gch(curr)->next; /* remove 'curr' from list */ |
| 739 | freeobj(L, curr); /* erase 'curr' */ | 741 | freeobj(L, curr); /* erase 'curr' */ |
| 740 | } | 742 | } |
| 741 | else { | 743 | else { /* update marks */ |
| 742 | if (testbits(marked, tostop)) | 744 | gch(curr)->marked = cast_byte((marked & maskcolors) | white); |
| 743 | return NULL; /* stop sweeping this list */ | ||
| 744 | if (gch(curr)->tt == LUA_TTHREAD) | ||
| 745 | sweepthread(L, gco2th(curr)); /* sweep thread's upvalues */ | ||
| 746 | /* update marks */ | ||
| 747 | gch(curr)->marked = cast_byte((marked & toclear) | toset); | ||
| 748 | p = &gch(curr)->next; /* go to next element */ | 745 | p = &gch(curr)->next; /* go to next element */ |
| 749 | } | 746 | } |
| 750 | } | 747 | } |
| @@ -756,7 +753,7 @@ static GCObject **sweeplist (lua_State *L, GCObject **p, lu_mem count) { · 5 unmodified lines | |||
| 756 | ** sweep a list until a live object (or end of list) | 753 | ** sweep a list until a live object (or end of list) |
| 757 | */ | 754 | */ |
| 758 | static GCObject **sweeptolive (lua_State *L, GCObject **p, int *n) { | 755 | static GCObject **sweeptolive (lua_State *L, GCObject **p, int *n) { |
| 759 | GCObject ** old = p; | 756 | GCObject **old = p; |
| 760 | int i = 0; | 757 | int i = 0; |
| 761 | do { | 758 | do { |
| 762 | i++; | 759 | i++; |
| @@ -775,26 +772,26 @@ static GCObject **sweeptolive (lua_State *L, GCObject **p, int *n) { · 12 unmodified lines | |||
| 775 | ** ======================================================= | 772 | ** ======================================================= |
| 776 | */ | 773 | */ |
| 777 | 774 | ||
| 778 | static void checkSizes (lua_State *L) { | 775 | /* |
| 779 | global_State *g = G(L); | 776 | ** If possible, free concatenation buffer and shrink string table |
| 780 | if (g->gckind != KGC_EMERGENCY) { /* do not change sizes in emergency */ | 777 | */ |
| 781 | int hs = g->strt.size / 2; /* half the size of the string table */ | 778 | static void checkSizes (lua_State *L, global_State *g) { |
| 782 | if (g->strt.nuse < cast(lu_int32, hs)) /* using less than that half? */ | 779 | if (g->gckind != KGC_EMERGENCY) { |
| 783 | luaS_resize(L, hs); /* halve its size */ | ||
| 784 | luaZ_freebuffer(L, &g->buff); /* free concatenation buffer */ | 780 | luaZ_freebuffer(L, &g->buff); /* free concatenation buffer */ |
| 781 | if (g->strt.nuse < g->strt.size / 4) /* string table too big? */ | ||
| 782 | luaS_resize(L, g->strt.size / 2); /* shrink it a little */ | ||
| 785 | } | 783 | } |
| 786 | } | 784 | } |
| 787 | 785 | ||
| 788 | 786 | ||
| 789 | static GCObject *udata2finalize (global_State *g) { | 787 | static GCObject *udata2finalize (global_State *g) { |
| 790 | GCObject *o = g->tobefnz; /* get first element */ | 788 | GCObject *o = g->tobefnz; /* get first element */ |
| 791 | lua_assert(isfinalized(o)); | 789 | lua_assert(tofinalize(o)); |
| 792 | g->tobefnz = gch(o)->next; /* remove it from 'tobefnz' list */ | 790 | g->tobefnz = gch(o)->next; /* remove it from 'tobefnz' list */ |
| 793 | gch(o)->next = g->allgc; /* return it to 'allgc' list */ | 791 | gch(o)->next = g->allgc; /* return it to 'allgc' list */ |
| 794 | g->allgc = o; | 792 | g->allgc = o; |
| 795 | resetbit(gch(o)->marked, SEPARATED); /* mark that it is not in 'tobefnz' */ | 793 | resetbit(gch(o)->marked, FINALIZEDBIT); /* object is "normal" again */ |
| 796 | lua_assert(!isold(o)); /* see MOVE OLD rule */ | 794 | if (issweepphase(g)) |
| 797 | if (!keepinvariantout(g)) /* not keeping invariant? */ | ||
| 798 | makewhite(g, o); /* "sweep" object */ | 795 | makewhite(g, o); /* "sweep" object */ |
| 799 | return o; | 796 | return o; |
| 800 | } | 797 | } |
| @@ -839,25 +836,39 @@ static void GCTM (lua_State *L, int propagateerrors) { · 38 unmodified lines | |||
| 839 | 836 | ||
| 840 | 837 | ||
| 841 | /* | 838 | /* |
| 842 | ** move all unreachable objects (or 'all' objects) that need | 839 | ** call all pending finalizers |
| 843 | ** finalization from list 'finobj' to list 'tobefnz' (to be finalized) | ||
| 844 | */ | 840 | */ |
| 845 | static void separatetobefnz (lua_State *L, int all) { | 841 | static void callallpendingfinalizers (lua_State *L, int propagateerrors) { |
| 846 | global_State *g = G(L); | 842 | global_State *g = G(L); |
| 847 | GCObject **p = &g->finobj; | 843 | while (g->tobefnz) |
| 844 | GCTM(L, propagateerrors); | ||
| 845 | } | ||
| 846 | |||
| 847 | |||
| 848 | /* | ||
| 849 | ** find last 'next' field in list 'p' list (to add elements in its end) | ||
| 850 | */ | ||
| 851 | static GCObject **findlast (GCObject **p) { | ||
| 852 | while (*p != NULL) | ||
| 853 | p = &gch(*p)->next; | ||
| 854 | return p; | ||
| 855 | } | ||
| 856 | |||
| 857 | |||
| 858 | /* | ||
| 859 | ** move all unreachable objects (or 'all' objects) that need | ||
| 860 | ** finalization from list 'p' to list 'tobefnz' (to be finalized) | ||
| 861 | */ | ||
| 862 | static void separatetobefnz (global_State *g, int all) { | ||
| 848 | GCObject *curr; | 863 | GCObject *curr; |
| 849 | GCObject **lastnext = &g->tobefnz; | 864 | GCObject **p = &g->finobj; |
| 850 | /* find last 'next' field in 'tobefnz' list (to add elements in its end) */ | 865 | GCObject **lastnext = findlast(&g->tobefnz); |
| 851 | while (*lastnext != NULL) | ||
| 852 | lastnext = &gch(*lastnext)->next; | ||
| 853 | while ((curr = *p) != NULL) { /* traverse all finalizable objects */ | 866 | while ((curr = *p) != NULL) { /* traverse all finalizable objects */ |
| 854 | lua_assert(!isfinalized(curr)); | 867 | lua_assert(tofinalize(curr)); |
| 855 | lua_assert(testbit(gch(curr)->marked, SEPARATED)); | ||
| 856 | if (!(iswhite(curr) || all)) /* not being collected? */ | 868 | if (!(iswhite(curr) || all)) /* not being collected? */ |
| 857 | p = &gch(curr)->next; /* don't bother with it */ | 869 | p = &gch(curr)->next; /* don't bother with it */ |
| 858 | else { | 870 | else { |
| 859 | l_setbit(gch(curr)->marked, FINALIZEDBIT); /* won't be finalized again */ | 871 | *p = gch(curr)->next; /* remove 'curr' from "fin" list */ |
| 860 | *p = gch(curr)->next; /* remove 'curr' from 'finobj' list */ | ||
| 861 | gch(curr)->next = *lastnext; /* link at the end of 'tobefnz' list */ | 872 | gch(curr)->next = *lastnext; /* link at the end of 'tobefnz' list */ |
| 862 | *lastnext = curr; | 873 | *lastnext = curr; |
| 863 | lastnext = &gch(curr)->next; | 874 | lastnext = &gch(curr)->next; |
| @@ -872,33 +883,30 @@ static void separatetobefnz (lua_State *L, int all) { · 8 unmodified lines | |||
| 872 | */ | 883 | */ |
| 873 | void luaC_checkfinalizer (lua_State *L, GCObject *o, Table *mt) { | 884 | void luaC_checkfinalizer (lua_State *L, GCObject *o, Table *mt) { |
| 874 | global_State *g = G(L); | 885 | global_State *g = G(L); |
| 875 | if (testbit(gch(o)->marked, SEPARATED) || /* obj. is already separated... */ | 886 | if (tofinalize(o) || /* obj. is already marked... */ |
| 876 | isfinalized(o) || /* ... or is finalized... */ | 887 | gfasttm(g, mt, TM_GC) == NULL) /* or has no finalizer? */ |
| 877 | gfasttm(g, mt, TM_GC) == NULL) /* or has no finalizer? */ | ||
| 878 | return; /* nothing to be done */ | 888 | return; /* nothing to be done */ |
| 879 | else { /* move 'o' to 'finobj' list */ | 889 | else { /* move 'o' to 'finobj' list */ |
| 880 | GCObject **p; | 890 | GCObject **p; |
| 881 | GCheader *ho = gch(o); | 891 | if (g->sweepgc == &o->gch.next) { /* avoid removing current sweep object */ |
| 882 | if (g->sweepgc == &ho->next) { /* avoid removing current sweep object */ | ||
| 883 | lua_assert(issweepphase(g)); | 892 | lua_assert(issweepphase(g)); |
| 884 | g->sweepgc = sweeptolive(L, g->sweepgc, NULL); | 893 | g->sweepgc = sweeptolive(L, g->sweepgc, NULL); |
| 885 | } | 894 | } |
| 886 | /* search for pointer pointing to 'o' */ | 895 | /* search for pointer pointing to 'o' */ |
| 887 | for (p = &g->allgc; *p != o; p = &gch(*p)->next) { /* empty */ } | 896 | for (p = &g->allgc; *p != o; p = &gch(*p)->next) { /* empty */ } |
| 888 | *p = ho->next; /* remove 'o' from root list */ | 897 | *p = o->gch.next; /* remove 'o' from its list */ |
| 889 | ho->next = g->finobj; /* link it in list 'finobj' */ | 898 | o->gch.next = g->finobj; /* link it in "fin" list */ |
| 890 | g->finobj = o; | 899 | g->finobj = o; |
| 891 | l_setbit(ho->marked, SEPARATED); /* mark it as such */ | 900 | l_setbit(o->gch.marked, FINALIZEDBIT); /* mark it as such */ |
| 892 | if (!keepinvariantout(g)) /* not keeping invariant? */ | 901 | if (issweepphase(g)) |
| 893 | makewhite(g, o); /* "sweep" object */ | 902 | makewhite(g, o); /* "sweep" object */ |
| 894 | else | ||
| 895 | resetoldbit(o); /* see MOVE OLD rule */ | ||
| 896 | } | 903 | } |
| 897 | } | 904 | } |
| 898 | 905 | ||
| 899 | /* }====================================================== */ | 906 | /* }====================================================== */ |
| 900 | 907 | ||
| 901 | 908 | ||
| 909 | |||
| 902 | /* | 910 | /* |
| 903 | ** {====================================================== | 911 | ** {====================================================== |
| 904 | ** GC control | 912 | ** GC control |
| @@ -911,87 +919,45 @@ void luaC_checkfinalizer (lua_State *L, GCObject *o, Table *mt) { · 6 unmodified lines | |||
| 911 | ** cycle will start when memory use hits threshold | 919 | ** cycle will start when memory use hits threshold |
| 912 | */ | 920 | */ |
| 913 | static void setpause (global_State *g, l_mem estimate) { | 921 | static void setpause (global_State *g, l_mem estimate) { |
| 914 | l_mem debt, threshold; | 922 | l_mem threshold, debt; |
| 915 | estimate = estimate / PAUSEADJ; /* adjust 'estimate' */ | 923 | estimate = estimate / PAUSEADJ; /* adjust 'estimate' */ |
| 916 | threshold = (g->gcpause < MAX_LMEM / estimate) /* overflow? */ | 924 | threshold = (g->gcpause < MAX_LMEM / estimate) /* overflow? */ |
| 917 | ? estimate * g->gcpause /* no overflow */ | 925 | ? estimate * g->gcpause /* no overflow */ |
| 918 | : MAX_LMEM; /* overflow; truncate to maximum */ | 926 | : MAX_LMEM; /* overflow; truncate to maximum */ |
| 919 | debt = -cast(l_mem, threshold - gettotalbytes(g)); | 927 | debt = gettotalbytes(g) - threshold; |
| 920 | luaE_setdebt(g, debt); | 928 | luaE_setdebt(g, debt); |
| 921 | } | 929 | } |
| 922 | 930 | ||
| 923 | 931 | ||
| 924 | #define sweepphases \ | ||
| 925 | (bitmask(GCSsweepstring) | bitmask(GCSsweepudata) | bitmask(GCSsweep)) | ||
| 926 | |||
| 927 | |||
| 928 | /* | 932 | /* |
| 929 | ** enter first sweep phase (strings) and prepare pointers for other | 933 | ** Enter first sweep phase. |
| 930 | ** sweep phases. The calls to 'sweeptolive' make pointers point to an | 934 | ** The call to 'sweeptolive' makes pointer point to an object inside |
| 931 | ** object inside the list (instead of to the header), so that the real | 935 | ** the list (instead of to the header), so that the real sweep do not |
| 932 | ** sweep do not need to skip objects created between "now" and the start | 936 | ** need to skip objects created between "now" and the start of the real |
| 933 | ** of the real sweep. | 937 | ** sweep. |
| 934 | ** Returns how many objects it swept. | 938 | ** Returns how many objects it swept. |
| 935 | */ | 939 | */ |
| 936 | static int entersweep (lua_State *L) { | 940 | static int entersweep (lua_State *L) { |
| 937 | global_State *g = G(L); | 941 | global_State *g = G(L); |
| 938 | int n = 0; | 942 | int n = 0; |
| 939 | g->gcstate = GCSsweepstring; | 943 | g->gcstate = GCSswpallgc; |
| 940 | lua_assert(g->sweepgc == NULL && g->sweepfin == NULL); | 944 | lua_assert(g->sweepgc == NULL); |
| 941 | /* prepare to sweep strings, finalizable objects, and regular objects */ | ||
| 942 | g->sweepstrgc = 0; | ||
| 943 | g->sweepfin = sweeptolive(L, &g->finobj, &n); | ||
| 944 | g->sweepgc = sweeptolive(L, &g->allgc, &n); | 945 | g->sweepgc = sweeptolive(L, &g->allgc, &n); |
| 945 | return n; | 946 | return n; |
| 946 | } | 947 | } |
| 947 | 948 | ||
| 948 | 949 | ||
| 949 | /* | ||
| 950 | ** change GC mode | ||
| 951 | */ | ||
| 952 | void luaC_changemode (lua_State *L, int mode) { | ||
| 953 | global_State *g = G(L); | ||
| 954 | if (mode == g->gckind) return; /* nothing to change */ | ||
| 955 | if (mode == KGC_GEN) { /* change to generational mode */ | ||
| 956 | /* make sure gray lists are consistent */ | ||
| 957 | luaC_runtilstate(L, bitmask(GCSpropagate)); | ||
| 958 | g->GCestimate = gettotalbytes(g); | ||
| 959 | g->gckind = KGC_GEN; | ||
| 960 | } | ||
| 961 | else { /* change to incremental mode */ | ||
| 962 | /* sweep all objects to turn them back to white | ||
| 963 | (as white has not changed, nothing extra will be collected) */ | ||
| 964 | g->gckind = KGC_NORMAL; | ||
| 965 | entersweep(L); | ||
| 966 | luaC_runtilstate(L, ~sweepphases); | ||
| 967 | } | ||
| 968 | } | ||
| 969 | |||
| 970 | |||
| 971 | /* | ||
| 972 | ** call all pending finalizers | ||
| 973 | */ | ||
| 974 | static void callallpendingfinalizers (lua_State *L, int propagateerrors) { | ||
| 975 | global_State *g = G(L); | ||
| 976 | while (g->tobefnz) { | ||
| 977 | resetoldbit(g->tobefnz); | ||
| 978 | GCTM(L, propagateerrors); | ||
| 979 | } | ||
| 980 | } | ||
| 981 | |||
| 982 | |||
| 983 | void luaC_freeallobjects (lua_State *L) { | 950 | void luaC_freeallobjects (lua_State *L) { |
| 984 | global_State *g = G(L); | 951 | global_State *g = G(L); |
| 985 | int i; | 952 | separatetobefnz(g, 1); /* separate all objects with finalizers */ |
| 986 | separatetobefnz(L, 1); /* separate all objects with finalizers */ | ||
| 987 | lua_assert(g->finobj == NULL); | 953 | lua_assert(g->finobj == NULL); |
| 988 | callallpendingfinalizers(L, 0); | 954 | callallpendingfinalizers(L, 0); |
| 955 | lua_assert(g->tobefnz == NULL); | ||
| 989 | g->currentwhite = WHITEBITS; /* this "white" makes all objects look dead */ | 956 | g->currentwhite = WHITEBITS; /* this "white" makes all objects look dead */ |
| 990 | g->gckind = KGC_NORMAL; | 957 | g->gckind = KGC_NORMAL; |
| 991 | sweepwholelist(L, &g->finobj); /* finalizers can create objs. in 'finobj' */ | 958 | sweepwholelist(L, &g->finobj); |
| 992 | sweepwholelist(L, &g->allgc); | 959 | sweepwholelist(L, &g->allgc); |
| 993 | for (i = 0; i < g->strt.size; i++) /* free all string lists */ | 960 | sweepwholelist(L, &g->fixedgc); /* collect fixed objects */ |
| 994 | sweepwholelist(L, &g->strt.hash[i]); | ||
| 995 | lua_assert(g->strt.nuse == 0); | 961 | lua_assert(g->strt.nuse == 0); |
| 996 | } | 962 | } |
| 997 | 963 | ||
| @@ -1001,6 +967,7 @@ static l_mem atomic (lua_State *L) { · 3 unmodified lines | |||
| 1001 | l_mem work = -cast(l_mem, g->GCmemtrav); /* start counting work */ | 967 | l_mem work = -cast(l_mem, g->GCmemtrav); /* start counting work */ |
| 1002 | GCObject *origweak, *origall; | 968 | GCObject *origweak, *origall; |
| 1003 | lua_assert(!iswhite(obj2gco(g->mainthread))); | 969 | lua_assert(!iswhite(obj2gco(g->mainthread))); |
| 970 | g->gcstate = GCSinsideatomic; | ||
| 1004 | markobject(g, L); /* mark running thread */ | 971 | markobject(g, L); /* mark running thread */ |
| 1005 | /* registry and global metatables may be changed by API */ | 972 | /* registry and global metatables may be changed by API */ |
| 1006 | markvalue(g, &g->l_registry); | 973 | markvalue(g, &g->l_registry); |
| @@ -1014,14 +981,15 @@ static l_mem atomic (lua_State *L) { · 7 unmodified lines | |||
| 1014 | work -= g->GCmemtrav; /* restart counting */ | 981 | work -= g->GCmemtrav; /* restart counting */ |
| 1015 | convergeephemerons(g); | 982 | convergeephemerons(g); |
| 1016 | /* at this point, all strongly accessible objects are marked. */ | 983 | /* at this point, all strongly accessible objects are marked. */ |
| 1017 | /* clear values from weak tables, before checking finalizers */ | 984 | /* Clear values from weak tables, before checking finalizers */ |
| 1018 | clearvalues(g, g->weak, NULL); | 985 | clearvalues(g, g->weak, NULL); |
| 1019 | clearvalues(g, g->allweak, NULL); | 986 | clearvalues(g, g->allweak, NULL); |
| 1020 | origweak = g->weak; origall = g->allweak; | 987 | origweak = g->weak; origall = g->allweak; |
| 1021 | work += g->GCmemtrav; /* stop counting (objects being finalized) */ | 988 | work += g->GCmemtrav; /* stop counting (objects being finalized) */ |
| 1022 | separatetobefnz(L, 0); /* separate objects to be finalized */ | 989 | separatetobefnz(g, 0); /* separate objects to be finalized */ |
| 990 | g->gcfinnum = 1; /* there may be objects to be finalized */ | ||
| 1023 | markbeingfnz(g); /* mark objects that will be finalized */ | 991 | markbeingfnz(g); /* mark objects that will be finalized */ |
| 1024 | propagateall(g); /* remark, to propagate `preserveness' */ | 992 | propagateall(g); /* remark, to propagate 'resurrection' */ |
| 1025 | work -= g->GCmemtrav; /* restart counting */ | 993 | work -= g->GCmemtrav; /* restart counting */ |
| 1026 | convergeephemerons(g); | 994 | convergeephemerons(g); |
| 1027 | /* at this point, all resurrected objects are marked. */ | 995 | /* at this point, all resurrected objects are marked. */ |
| @@ -1037,66 +1005,67 @@ static l_mem atomic (lua_State *L) { · 9 unmodified lines | |||
| 1037 | } | 1005 | } |
| 1038 | 1006 | ||
| 1039 | 1007 | ||
| 1008 | static lu_mem sweepstep (lua_State *L, global_State *g, | ||
| 1009 | int nextstate, GCObject **nextlist) { | ||
| 1010 | if (g->sweepgc) { | ||
| 1011 | g->sweepgc = sweeplist(L, g->sweepgc, GCSWEEPMAX); | ||
| 1012 | if (g->sweepgc) /* is there still something to sweep? */ | ||
| 1013 | return (GCSWEEPMAX * GCSWEEPCOST); | ||
| 1014 | } | ||
| 1015 | /* else enter next state */ | ||
| 1016 | g->gcstate = nextstate; | ||
| 1017 | g->sweepgc = nextlist; | ||
| 1018 | return 0; | ||
| 1019 | } | ||
| 1020 | |||
| 1021 | |||
| 1040 | static lu_mem singlestep (lua_State *L) { | 1022 | static lu_mem singlestep (lua_State *L) { |
| 1041 | global_State *g = G(L); | 1023 | global_State *g = G(L); |
| 1042 | switch (g->gcstate) { | 1024 | switch (g->gcstate) { |
| 1043 | case GCSpause: { | 1025 | case GCSpause: { |
| 1044 | /* start to count memory traversed */ | 1026 | /* start to count memory traversed */ |
| 1045 | g->GCmemtrav = g->strt.size * sizeof(GCObject*); | 1027 | g->GCmemtrav = g->strt.size * sizeof(GCObject*); |
| 1046 | lua_assert(!isgenerational(g)); | ||
| 1047 | restartcollection(g); | 1028 | restartcollection(g); |
| 1048 | g->gcstate = GCSpropagate; | 1029 | g->gcstate = GCSpropagate; |
| 1049 | return g->GCmemtrav; | 1030 | return g->GCmemtrav; |
| 1050 | } | 1031 | } |
| 1051 | case GCSpropagate: { | 1032 | case GCSpropagate: { |
| 1052 | if (g->gray) { | 1033 | lu_mem oldtrav = g->GCmemtrav; |
| 1053 | lu_mem oldtrav = g->GCmemtrav; | 1034 | lua_assert(g->gray); |
| 1054 | propagatemark(g); | 1035 | propagatemark(g); |
| 1055 | return g->GCmemtrav - oldtrav; /* memory traversed in this step */ | 1036 | if (g->gray == NULL) /* no more `gray' objects? */ |
| 1056 | } | 1037 | g->gcstate = GCSatomic; /* finish propagate phase */ |
| 1057 | else { /* no more `gray' objects */ | 1038 | return g->GCmemtrav - oldtrav; /* memory traversed in this step */ |
| 1058 | lu_mem work; | ||
| 1059 | int sw; | ||
| 1060 | g->gcstate = GCSatomic; /* finish mark phase */ | ||
| 1061 | g->GCestimate = g->GCmemtrav; /* save what was counted */; | ||
| 1062 | work = atomic(L); /* add what was traversed by 'atomic' */ | ||
| 1063 | g->GCestimate += work; /* estimate of total memory traversed */ | ||
| 1064 | sw = entersweep(L); | ||
| 1065 | return work + sw * GCSWEEPCOST; | ||
| 1066 | } | ||
| 1067 | } | 1039 | } |
| 1068 | case GCSsweepstring: { | 1040 | case GCSatomic: { |
| 1069 | int i; | 1041 | lu_mem work; |
| 1070 | for (i = 0; i < GCSWEEPMAX && g->sweepstrgc + i < g->strt.size; i++) | 1042 | int sw; |
| 1071 | sweepwholelist(L, &g->strt.hash[g->sweepstrgc + i]); | 1043 | propagateall(g); /* make sure gray list is empty */ |
| 1072 | g->sweepstrgc += i; | 1044 | g->GCestimate = g->GCmemtrav; /* save what was counted */; |
| 1073 | if (g->sweepstrgc >= g->strt.size) /* no more strings to sweep? */ | 1045 | work = atomic(L); /* work is what was traversed by 'atomic' */ |
| 1074 | g->gcstate = GCSsweepudata; | 1046 | g->GCestimate += work; /* estimate of total memory traversed */ |
| 1075 | return i * GCSWEEPCOST; | 1047 | sw = entersweep(L); |
| 1048 | return work + sw * GCSWEEPCOST; | ||
| 1076 | } | 1049 | } |
| 1077 | case GCSsweepudata: { | 1050 | case GCSswpallgc: { /* sweep "regular" objects */ |
| 1078 | if (g->sweepfin) { | 1051 | return sweepstep(L, g, GCSswpfinobj, &g->finobj); |
| 1079 | g->sweepfin = sweeplist(L, g->sweepfin, GCSWEEPMAX); | ||
| 1080 | return GCSWEEPMAX*GCSWEEPCOST; | ||
| 1081 | } | ||
| 1082 | else { | ||
| 1083 | g->gcstate = GCSsweep; | ||
| 1084 | return 0; | ||
| 1085 | } | ||
| 1086 | } | 1052 | } |
| 1087 | case GCSsweep: { | 1053 | case GCSswpfinobj: { /* sweep objects with finalizers */ |
| 1088 | if (g->sweepgc) { | 1054 | return sweepstep(L, g, GCSswptobefnz, &g->tobefnz); |
| 1089 | g->sweepgc = sweeplist(L, g->sweepgc, GCSWEEPMAX); | 1055 | } |
| 1090 | return GCSWEEPMAX*GCSWEEPCOST; | 1056 | case GCSswptobefnz: { /* sweep objects to be finalized */ |
| 1091 | } | 1057 | return sweepstep(L, g, GCSswpend, NULL); |
| 1092 | else { | 1058 | } |
| 1093 | /* sweep main thread */ | 1059 | case GCSswpend: { /* finish sweeps */ |
| 1094 | GCObject *mt = obj2gco(g->mainthread); | 1060 | makewhite(g, obj2gco(g->mainthread)); /* sweep main thread */ |
| 1095 | sweeplist(L, &mt, 1); | 1061 | checkSizes(L, g); |
| 1096 | checkSizes(L); | 1062 | g->gcstate = GCScallfin; |
| 1097 | g->gcstate = GCSpause; /* finish collection */ | 1063 | return 0; |
| 1098 | return GCSWEEPCOST; | 1064 | } |
| 1099 | } | 1065 | case GCScallfin: { /* state to finish calling finalizers */ |
| 1066 | /* do nothing here; should be handled by 'luaC_forcestep' */ | ||
| 1067 | g->gcstate = GCSpause; /* finish collection */ | ||
| 1068 | return 0; | ||
| 1100 | } | 1069 | } |
| 1101 | default: lua_assert(0); return 0; | 1070 | default: lua_assert(0); return 0; |
| 1102 | } | 1071 | } |
| @@ -1114,88 +1083,74 @@ void luaC_runtilstate (lua_State *L, int statesmask) { · 11 unmodified lines | |||
| 1114 | } | 1083 | } |
| 1115 | 1084 | ||
| 1116 | 1085 | ||
| 1117 | static void generationalcollection (lua_State *L) { | 1086 | /* |
| 1087 | ** run a few (up to 'g->gcfinnum') finalizers | ||
| 1088 | */ | ||
| 1089 | static int runafewfinalizers (lua_State *L) { | ||
| 1118 | global_State *g = G(L); | 1090 | global_State *g = G(L); |
| 1119 | lua_assert(g->gcstate == GCSpropagate); | 1091 | unsigned int i; |
| 1120 | if (g->GCestimate == 0) { /* signal for another major collection? */ | 1092 | lua_assert(!g->tobefnz || g->gcfinnum > 0); |
| 1121 | luaC_fullgc(L, 0); /* perform a full regular collection */ | 1093 | for (i = 0; g->tobefnz && i < g->gcfinnum; i++) |
| 1122 | g->GCestimate = gettotalbytes(g); /* update control */ | 1094 | GCTM(L, 1); /* call one finalizer */ |
| 1123 | } | 1095 | g->gcfinnum = (!g->tobefnz) ? 0 /* nothing more to finalize? */ |
| 1124 | else { | 1096 | : g->gcfinnum * 2; /* else call a few more next time */ |
| 1125 | lu_mem estimate = g->GCestimate; | 1097 | return i; |
| 1126 | luaC_runtilstate(L, bitmask(GCSpause)); /* run complete (minor) cycle */ | ||
| 1127 | g->gcstate = GCSpropagate; /* skip restart */ | ||
| 1128 | if (gettotalbytes(g) > (estimate / 100) * g->gcmajorinc) | ||
| 1129 | g->GCestimate = 0; /* signal for a major collection */ | ||
| 1130 | else | ||
| 1131 | g->GCestimate = estimate; /* keep estimate from last major coll. */ | ||
| 1132 | |||
| 1133 | } | ||
| 1134 | setpause(g, gettotalbytes(g)); | ||
| 1135 | lua_assert(g->gcstate == GCSpropagate); | ||
| 1136 | } | 1098 | } |
| 1137 | 1099 | ||
| 1138 | 1100 | ||
| 1139 | static void incstep (lua_State *L) { | 1101 | /* |
| 1140 | global_State *g = G(L); | 1102 | ** get GC debt and convert it from Kb to 'work units' (avoid zero debt |
| 1103 | ** and overflows) | ||
| 1104 | */ | ||
| 1105 | static l_mem getdebt (global_State *g) { | ||
| 1141 | l_mem debt = g->GCdebt; | 1106 | l_mem debt = g->GCdebt; |
| 1142 | int stepmul = g->gcstepmul; | 1107 | int stepmul = g->gcstepmul; |
| 1143 | if (stepmul < 40) stepmul = 40; /* avoid ridiculous low values (and 0) */ | ||
| 1144 | /* convert debt from Kb to 'work units' (avoid zero debt and overflows) */ | ||
| 1145 | debt = (debt / STEPMULADJ) + 1; | 1108 | debt = (debt / STEPMULADJ) + 1; |
| 1146 | debt = (debt < MAX_LMEM / stepmul) ? debt * stepmul : MAX_LMEM; | 1109 | debt = (debt < MAX_LMEM / stepmul) ? debt * stepmul : MAX_LMEM; |
| 1147 | do { /* always perform at least one single step */ | 1110 | return debt; |
| 1148 | lu_mem work = singlestep(L); /* do some work */ | ||
| 1149 | debt -= work; | ||
| 1150 | } while (debt > -GCSTEPSIZE && g->gcstate != GCSpause); | ||
| 1151 | if (g->gcstate == GCSpause) | ||
| 1152 | setpause(g, g->GCestimate); /* pause until next cycle */ | ||
| 1153 | else { | ||
| 1154 | debt = (debt / stepmul) * STEPMULADJ; /* convert 'work units' to Kb */ | ||
| 1155 | luaE_setdebt(g, debt); | ||
| 1156 | } | ||
| 1157 | } | 1111 | } |
| 1158 | 1112 | ||
| 1159 | |||
| 1160 | /* | 1113 | /* |
| 1161 | ** performs a basic GC step | 1114 | ** performs a basic GC step when collector is running |
| 1162 | */ | ||
| 1163 | void luaC_forcestep (lua_State *L) { | ||
| 1164 | global_State *g = G(L); | ||
| 1165 | int i; | ||
| 1166 | if (isgenerational(g)) generationalcollection(L); | ||
| 1167 | else incstep(L); | ||
| 1168 | /* run a few finalizers (or all of them at the end of a collect cycle) */ | ||
| 1169 | for (i = 0; g->tobefnz && (i < GCFINALIZENUM || g->gcstate == GCSpause); i++) | ||
| 1170 | GCTM(L, 1); /* call one finalizer */ | ||
| 1171 | } | ||
| 1172 | |||
| 1173 | |||
| 1174 | /* | ||
| 1175 | ** performs a basic GC step only if collector is running | ||
| 1176 | */ | 1115 | */ |
| 1177 | void luaC_step (lua_State *L) { | 1116 | void luaC_step (lua_State *L) { |
| 1178 | global_State *g = G(L); | 1117 | global_State *g = G(L); |
| 1179 | if (g->gcrunning) luaC_forcestep(L); | 1118 | l_mem debt = getdebt(g); |
| 1180 | else luaE_setdebt(g, -GCSTEPSIZE); /* avoid being called too often */ | 1119 | if (!g->gcrunning) { /* not running? */ |
| 1120 | luaE_setdebt(g, -GCSTEPSIZE * 10); /* avoid being called too often */ | ||
| 1121 | return; | ||
| 1122 | } | ||
| 1123 | do { | ||
| 1124 | if (g->gcstate == GCScallfin && g->tobefnz) { | ||
| 1125 | unsigned int n = runafewfinalizers(L); | ||
| 1126 | debt -= (n * GCFINALIZECOST); | ||
| 1127 | } | ||
| 1128 | else { /* perform one single step */ | ||
| 1129 | lu_mem work = singlestep(L); | ||
| 1130 | debt -= work; | ||
| 1131 | } | ||
| 1132 | } while (debt > -GCSTEPSIZE && g->gcstate != GCSpause); | ||
| 1133 | if (g->gcstate == GCSpause) | ||
| 1134 | setpause(g, g->GCestimate); /* pause until next cycle */ | ||
| 1135 | else { | ||
| 1136 | debt = (debt / g->gcstepmul) * STEPMULADJ; /* convert 'work units' to Kb */ | ||
| 1137 | luaE_setdebt(g, debt); | ||
| 1138 | runafewfinalizers(L); | ||
| 1139 | } | ||
| 1181 | } | 1140 | } |
| 1182 | 1141 | ||
| 1183 | 1142 | ||
| 1184 | |||
| 1185 | /* | 1143 | /* |
| 1186 | ** performs a full GC cycle; if "isemergency", does not call | 1144 | ** performs a full GC cycle; if "isemergency", does not call |
| 1187 | ** finalizers (which could change stack positions) | 1145 | ** finalizers (which could change stack positions) |
| 1188 | */ | 1146 | */ |
| 1189 | void luaC_fullgc (lua_State *L, int isemergency) { | 1147 | void luaC_fullgc (lua_State *L, int isemergency) { |
| 1190 | global_State *g = G(L); | 1148 | global_State *g = G(L); |
| 1191 | int origkind = g->gckind; | 1149 | lua_assert(g->gckind == KGC_NORMAL); |
| 1192 | lua_assert(origkind != KGC_EMERGENCY); | ||
| 1193 | if (isemergency) /* do not run finalizers during emergency GC */ | 1150 | if (isemergency) /* do not run finalizers during emergency GC */ |
| 1194 | g->gckind = KGC_EMERGENCY; | 1151 | g->gckind = KGC_EMERGENCY; |
| 1195 | else { | 1152 | else |
| 1196 | g->gckind = KGC_NORMAL; | ||
| 1197 | callallpendingfinalizers(L, 1); | 1153 | callallpendingfinalizers(L, 1); |
| 1198 | } | ||
| 1199 | if (keepinvariant(g)) { /* may there be some black objects? */ | 1154 | if (keepinvariant(g)) { /* may there be some black objects? */ |
| 1200 | /* must sweep all objects to turn them back to white | 1155 | /* must sweep all objects to turn them back to white |
| 1201 | (as white has not changed, nothing will be collected) */ | 1156 | (as white has not changed, nothing will be collected) */ |
| @@ -1205,11 +1160,7 @@ void luaC_fullgc (lua_State *L, int isemergency) { · 3 unmodified lines | |||
| 1205 | luaC_runtilstate(L, bitmask(GCSpause)); | 1160 | luaC_runtilstate(L, bitmask(GCSpause)); |
| 1206 | luaC_runtilstate(L, ~bitmask(GCSpause)); /* start new collection */ | 1161 | luaC_runtilstate(L, ~bitmask(GCSpause)); /* start new collection */ |
| 1207 | luaC_runtilstate(L, bitmask(GCSpause)); /* run entire collection */ | 1162 | luaC_runtilstate(L, bitmask(GCSpause)); /* run entire collection */ |
| 1208 | if (origkind == KGC_GEN) { /* generational mode? */ | 1163 | g->gckind = KGC_NORMAL; |
| 1209 | /* generational mode must be kept in propagate phase */ | ||
| 1210 | luaC_runtilstate(L, bitmask(GCSpropagate)); | ||
| 1211 | } | ||
| 1212 | g->gckind = origkind; | ||
| 1213 | setpause(g, gettotalbytes(g)); | 1164 | setpause(g, gettotalbytes(g)); |
| 1214 | if (!isemergency) /* do not run finalizers during emergency GC */ | 1165 | if (!isemergency) /* do not run finalizers during emergency GC */ |
| 1215 | callallpendingfinalizers(L, 1); | 1166 | callallpendingfinalizers(L, 1); |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lgc.h,v 2.58 2012/09/11 12:53:08 roberto Exp $ | 2 | ** $Id: lgc.h,v 2.82 2014/03/19 18:51:16 roberto Exp $ |
| 3 | ** Garbage Collector | 3 | ** Garbage Collector |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -38,36 +38,27 @@ · 32 unmodified lines | |||
| 38 | */ | 38 | */ |
| 39 | #define GCSpropagate 0 | 39 | #define GCSpropagate 0 |
| 40 | #define GCSatomic 1 | 40 | #define GCSatomic 1 |
| 41 | #define GCSsweepstring 2 | 41 | #define GCSswpallgc 2 |
| 42 | #define GCSsweepudata 3 | 42 | #define GCSswpfinobj 3 |
| 43 | #define GCSsweep 4 | 43 | #define GCSswptobefnz 4 |
| 44 | #define GCSpause 5 | 44 | #define GCSswpend 5 |
| 45 | #define GCScallfin 6 | ||
| 46 | #define GCSpause 7 | ||
| 45 | 47 | ||
| 46 | 48 | ||
| 47 | #define issweepphase(g) \ | 49 | #define issweepphase(g) \ |
| 48 | (GCSsweepstring <= (g)->gcstate && (g)->gcstate <= GCSsweep) | 50 | (GCSswpallgc <= (g)->gcstate && (g)->gcstate <= GCSswpend) |
| 49 | 51 | ||
| 50 | #define isgenerational(g) ((g)->gckind == KGC_GEN) | ||
| 51 | 52 | ||
| 52 | /* | 53 | /* |
| 53 | ** macros to tell when main invariant (white objects cannot point to black | 54 | ** macro to tell when main invariant (white objects cannot point to black |
| 54 | ** ones) must be kept. During a non-generational collection, the sweep | 55 | ** ones) must be kept. During a collection, the sweep |
| 55 | ** phase may break the invariant, as objects turned white may point to | 56 | ** phase may break the invariant, as objects turned white may point to |
| 56 | ** still-black objects. The invariant is restored when sweep ends and | 57 | ** still-black objects. The invariant is restored when sweep ends and |
| 57 | ** all objects are white again. During a generational collection, the | 58 | ** all objects are white again. |
| 58 | ** invariant must be kept all times. | ||
| 59 | */ | 59 | */ |
| 60 | 60 | ||
| 61 | #define keepinvariant(g) (isgenerational(g) || g->gcstate <= GCSatomic) | 61 | #define keepinvariant(g) ((g)->gcstate <= GCSatomic) |
| 62 | |||
| 63 | |||
| 64 | /* | ||
| 65 | ** Outside the collector, the state in generational mode is kept in | ||
| 66 | ** 'propagate', so 'keepinvariant' is always true. | ||
| 67 | */ | ||
| 68 | #define keepinvariantout(g) \ | ||
| 69 | check_exp(g->gcstate == GCSpropagate || !isgenerational(g), \ | ||
| 70 | g->gcstate <= GCSatomic) | ||
| 71 | 62 | ||
| 72 | 63 | ||
| 73 | /* | 64 | /* |
| @@ -87,10 +78,7 @@ · 13 unmodified lines | |||
| 87 | #define WHITE0BIT 0 /* object is white (type 0) */ | 78 | #define WHITE0BIT 0 /* object is white (type 0) */ |
| 88 | #define WHITE1BIT 1 /* object is white (type 1) */ | 79 | #define WHITE1BIT 1 /* object is white (type 1) */ |
| 89 | #define BLACKBIT 2 /* object is black */ | 80 | #define BLACKBIT 2 /* object is black */ |
| 90 | #define FINALIZEDBIT 3 /* object has been separated for finalization */ | 81 | #define FINALIZEDBIT 3 /* object has been marked for finalization */ |
| 91 | #define SEPARATED 4 /* object is in 'finobj' list or in 'tobefnz' */ | ||
| 92 | #define FIXEDBIT 5 /* object is fixed (should not be collected) */ | ||
| 93 | #define OLDBIT 6 /* object is old (only in generational mode) */ | ||
| 94 | /* bit 7 is currently used by tests (luaL_checkmemory) */ | 82 | /* bit 7 is currently used by tests (luaL_checkmemory) */ |
| 95 | 83 | ||
| 96 | #define WHITEBITS bit2mask(WHITE0BIT, WHITE1BIT) | 84 | #define WHITEBITS bit2mask(WHITE0BIT, WHITE1BIT) |
| @@ -101,21 +89,15 @@ · 4 unmodified lines | |||
| 101 | #define isgray(x) /* neither white nor black */ \ | 89 | #define isgray(x) /* neither white nor black */ \ |
| 102 | (!testbits((x)->gch.marked, WHITEBITS | bitmask(BLACKBIT))) | 90 | (!testbits((x)->gch.marked, WHITEBITS | bitmask(BLACKBIT))) |
| 103 | 91 | ||
| 104 | #define isold(x) testbit((x)->gch.marked, OLDBIT) | 92 | #define tofinalize(x) testbit((x)->gch.marked, FINALIZEDBIT) |
| 105 | 93 | ||
| 106 | /* MOVE OLD rule: whenever an object is moved to the beginning of | 94 | #define otherwhite(g) ((g)->currentwhite ^ WHITEBITS) |
| 107 | a GC list, its old bit must be cleared */ | ||
| 108 | #define resetoldbit(o) resetbit((o)->gch.marked, OLDBIT) | ||
| 109 | |||
| 110 | #define otherwhite(g) (g->currentwhite ^ WHITEBITS) | ||
| 111 | #define isdeadm(ow,m) (!(((m) ^ WHITEBITS) & (ow))) | 95 | #define isdeadm(ow,m) (!(((m) ^ WHITEBITS) & (ow))) |
| 112 | #define isdead(g,v) isdeadm(otherwhite(g), (v)->gch.marked) | 96 | #define isdead(g,v) isdeadm(otherwhite(g), (v)->gch.marked) |
| 113 | 97 | ||
| 114 | #define changewhite(x) ((x)->gch.marked ^= WHITEBITS) | 98 | #define changewhite(x) ((x)->gch.marked ^= WHITEBITS) |
| 115 | #define gray2black(x) l_setbit((x)->gch.marked, BLACKBIT) | 99 | #define gray2black(x) l_setbit((x)->gch.marked, BLACKBIT) |
| 116 | 100 | ||
| 117 | #define valiswhite(x) (iscollectable(x) && iswhite(gcvalue(x))) | ||
| 118 | |||
| 119 | #define luaC_white(g) cast(lu_byte, (g)->currentwhite & WHITEBITS) | 101 | #define luaC_white(g) cast(lu_byte, (g)->currentwhite & WHITEBITS) |
| 120 | 102 | ||
| 121 | 103 | ||
| @@ -124,34 +106,33 @@ · 2 unmodified lines | |||
| 124 | #define luaC_checkGC(L) luaC_condGC(L, luaC_step(L);) | 106 | #define luaC_checkGC(L) luaC_condGC(L, luaC_step(L);) |
| 125 | 107 | ||
| 126 | 108 | ||
| 127 | #define luaC_barrier(L,p,v) { if (valiswhite(v) && isblack(obj2gco(p))) \ | 109 | #define luaC_barrier(L,p,v) { \ |
| 110 | if (iscollectable(v) && isblack(obj2gco(p)) && iswhite(gcvalue(v))) \ | ||
| 128 | luaC_barrier_(L,obj2gco(p),gcvalue(v)); } | 111 | luaC_barrier_(L,obj2gco(p),gcvalue(v)); } |
| 129 | 112 | ||
| 130 | #define luaC_barrierback(L,p,v) { if (valiswhite(v) && isblack(obj2gco(p))) \ | 113 | #define luaC_barrierback(L,p,v) { \ |
| 131 | luaC_barrierback_(L,p); } | 114 | if (iscollectable(v) && isblack(obj2gco(p)) && iswhite(gcvalue(v))) \ |
| 115 | luaC_barrierback_(L,obj2gco(p)); } | ||
| 132 | 116 | ||
| 133 | #define luaC_objbarrier(L,p,o) \ | 117 | #define luaC_objbarrier(L,p,o) { \ |
| 134 | { if (iswhite(obj2gco(o)) && isblack(obj2gco(p))) \ | 118 | if (isblack(obj2gco(p)) && iswhite(obj2gco(o))) \ |
| 135 | luaC_barrier_(L,obj2gco(p),obj2gco(o)); } | 119 | luaC_barrier_(L,obj2gco(p),obj2gco(o)); } |
| 136 | 120 | ||
| 137 | #define luaC_objbarrierback(L,p,o) \ | 121 | #define luaC_upvalbarrier(L,uv) \ |
| 138 | { if (iswhite(obj2gco(o)) && isblack(obj2gco(p))) luaC_barrierback_(L,p); } | 122 | { if (iscollectable((uv)->v) && !upisopen(uv)) \ |
| 139 | 123 | luaC_upvalbarrier_(L,uv); } | |
| 140 | #define luaC_barrierproto(L,p,c) \ | ||
| 141 | { if (isblack(obj2gco(p))) luaC_barrierproto_(L,p,c); } | ||
| 142 | 124 | ||
| 125 | LUAI_FUNC void luaC_fix (lua_State *L, GCObject *o); | ||
| 143 | LUAI_FUNC void luaC_freeallobjects (lua_State *L); | 126 | LUAI_FUNC void luaC_freeallobjects (lua_State *L); |
| 144 | LUAI_FUNC void luaC_step (lua_State *L); | 127 | LUAI_FUNC void luaC_step (lua_State *L); |
| 145 | LUAI_FUNC void luaC_forcestep (lua_State *L); | ||
| 146 | LUAI_FUNC void luaC_runtilstate (lua_State *L, int statesmask); | 128 | LUAI_FUNC void luaC_runtilstate (lua_State *L, int statesmask); |
| 147 | LUAI_FUNC void luaC_fullgc (lua_State *L, int isemergency); | 129 | LUAI_FUNC void luaC_fullgc (lua_State *L, int isemergency); |
| 148 | LUAI_FUNC GCObject *luaC_newobj (lua_State *L, int tt, size_t sz, | 130 | LUAI_FUNC GCObject *luaC_newobj (lua_State *L, int tt, size_t sz); |
| 149 | GCObject **list, int offset); | ||
| 150 | LUAI_FUNC void luaC_barrier_ (lua_State *L, GCObject *o, GCObject *v); | 131 | LUAI_FUNC void luaC_barrier_ (lua_State *L, GCObject *o, GCObject *v); |
| 151 | LUAI_FUNC void luaC_barrierback_ (lua_State *L, GCObject *o); | 132 | LUAI_FUNC void luaC_barrierback_ (lua_State *L, GCObject *o); |
| 152 | LUAI_FUNC void luaC_barrierproto_ (lua_State *L, Proto *p, Closure *c); | 133 | LUAI_FUNC void luaC_upvalbarrier_ (lua_State *L, UpVal *uv); |
| 153 | LUAI_FUNC void luaC_checkfinalizer (lua_State *L, GCObject *o, Table *mt); | 134 | LUAI_FUNC void luaC_checkfinalizer (lua_State *L, GCObject *o, Table *mt); |
| 154 | LUAI_FUNC void luaC_checkupvalcolor (global_State *g, UpVal *uv); | 135 | LUAI_FUNC void luaC_upvdeccount (lua_State *L, UpVal *uv); |
| 155 | LUAI_FUNC void luaC_changemode (lua_State *L, int mode); | 136 | |
| 156 | 137 | ||
| 157 | #endif | 138 | #endif |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: linit.c,v 1.32 2011/04/08 19:17:36 roberto Exp $ | 2 | ** $Id: linit.c,v 1.33 2014/02/06 17:32:33 roberto Exp $ |
| 3 | ** Initialization of libraries for lua.c and other clients | 3 | ** Initialization of libraries for lua.c and other clients |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -34,6 +34,7 @@ static const luaL_Reg loadedlibs[] = { · 28 unmodified lines | |||
| 34 | {LUA_IOLIBNAME, luaopen_io}, | 34 | {LUA_IOLIBNAME, luaopen_io}, |
| 35 | {LUA_OSLIBNAME, luaopen_os}, | 35 | {LUA_OSLIBNAME, luaopen_os}, |
| 36 | {LUA_STRLIBNAME, luaopen_string}, | 36 | {LUA_STRLIBNAME, luaopen_string}, |
| 37 | {LUA_UTF8LIBNAME, luaopen_utf8}, | ||
| 37 | {LUA_BITLIBNAME, luaopen_bit32}, | 38 | {LUA_BITLIBNAME, luaopen_bit32}, |
| 38 | {LUA_MATHLIBNAME, luaopen_math}, | 39 | {LUA_MATHLIBNAME, luaopen_math}, |
| 39 | {LUA_DBLIBNAME, luaopen_debug}, | 40 | {LUA_DBLIBNAME, luaopen_debug}, |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: liolib.c,v 2.114 2013/06/07 19:01:35 roberto Exp $ | 2 | ** $Id: liolib.c,v 2.120 2014/03/19 18:57:42 roberto Exp $ |
| 3 | ** Standard I/O (and system) library | 3 | ** Standard I/O (and system) library |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -29,14 +29,14 @@ · 23 unmodified lines | |||
| 29 | #include "lualib.h" | 29 | #include "lualib.h" |
| 30 | 30 | ||
| 31 | 31 | ||
| 32 | #if !defined(lua_checkmode) | 32 | #if !defined(l_checkmode) |
| 33 | 33 | ||
| 34 | /* | 34 | /* |
| 35 | ** Check whether 'mode' matches '[rwa]%+?b?'. | 35 | ** Check whether 'mode' matches '[rwa]%+?b?'. |
| 36 | ** Change this macro to accept other modes for 'fopen' besides | 36 | ** Change this macro to accept other modes for 'fopen' besides |
| 37 | ** the standard ones. | 37 | ** the standard ones. |
| 38 | */ | 38 | */ |
| 39 | #define lua_checkmode(mode) \ | 39 | #define l_checkmode(mode) \ |
| 40 | (*mode != '\0' && strchr("rwa", *(mode++)) != NULL && \ | 40 | (*mode != '\0' && strchr("rwa", *(mode++)) != NULL && \ |
| 41 | (*mode != '+' || ++mode) && /* skip if char is '+' */ \ | 41 | (*mode != '+' || ++mode) && /* skip if char is '+' */ \ |
| 42 | (*mode != 'b' || ++mode) && /* skip if char is 'b' */ \ | 42 | (*mode != 'b' || ++mode) && /* skip if char is 'b' */ \ |
| @@ -46,45 +46,61 @@ · 3 unmodified lines | |||
| 46 | 46 | ||
| 47 | /* | 47 | /* |
| 48 | ** {====================================================== | 48 | ** {====================================================== |
| 49 | ** lua_popen spawns a new process connected to the current | 49 | ** l_popen spawns a new process connected to the current |
| 50 | ** one through the file streams. | 50 | ** one through the file streams. |
| 51 | ** ======================================================= | 51 | ** ======================================================= |
| 52 | */ | 52 | */ |
| 53 | 53 | ||
| 54 | #if !defined(lua_popen) /* { */ | 54 | #if !defined(l_popen) /* { */ |
| 55 | 55 | ||
| 56 | #if defined(LUA_USE_POPEN) /* { */ | 56 | #if defined(LUA_USE_POSIX) /* { */ |
| 57 | 57 | ||
| 58 | #define lua_popen(L,c,m) ((void)L, fflush(NULL), popen(c,m)) | 58 | #define l_popen(L,c,m) (fflush(NULL), popen(c,m)) |
| 59 | #define lua_pclose(L,file) ((void)L, pclose(file)) | 59 | #define l_pclose(L,file) (pclose(file)) |
| 60 | 60 | ||
| 61 | #elif defined(LUA_WIN) /* }{ */ | 61 | #elif defined(LUA_WIN) /* }{ */ |
| 62 | 62 | ||
| 63 | #define lua_popen(L,c,m) ((void)L, _popen(c,m)) | 63 | #define l_popen(L,c,m) (_popen(c,m)) |
| 64 | #define lua_pclose(L,file) ((void)L, _pclose(file)) | 64 | #define l_pclose(L,file) (_pclose(file)) |
| 65 | |||
| 66 | 65 | ||
| 67 | #else /* }{ */ | 66 | #else /* }{ */ |
| 68 | 67 | ||
| 69 | #define lua_popen(L,c,m) ((void)((void)c, m), \ | 68 | /* ANSI definitions */ |
| 70 | luaL_error(L, LUA_QL("popen") " not supported"), (FILE*)0) | 69 | #define l_popen(L,c,m) \ |
| 71 | #define lua_pclose(L,file) ((void)((void)L, file), -1) | 70 | ((void)((void)c, m), \ |
| 72 | 71 | luaL_error(L, LUA_QL("popen") " not supported"), \ | |
| 72 | (FILE*)0) | ||
| 73 | #define l_pclose(L,file) ((void)L, (void)file, -1) | ||
| 73 | 74 | ||
| 74 | #endif /* } */ | 75 | #endif /* } */ |
| 75 | 76 | ||
| 76 | #endif /* } */ | 77 | #endif /* } */ |
| 77 | 78 | ||
| 78 | /* }====================================================== */ | 79 | /* }====================================================== */ |
| 79 | 80 | ||
| 80 | 81 | ||
| 82 | #if !defined(l_getc) /* { */ | ||
| 83 | |||
| 84 | #if defined(LUA_USE_POSIX) | ||
| 85 | #define l_getc(f) getc_unlocked(f) | ||
| 86 | #define l_lockfile(f) flockfile(f) | ||
| 87 | #define l_unlockfile(f) funlockfile(f) | ||
| 88 | #else | ||
| 89 | #define l_getc(f) getc(f) | ||
| 90 | #define l_lockfile(f) ((void)0) | ||
| 91 | #define l_unlockfile(f) ((void)0) | ||
| 92 | #endif | ||
| 93 | |||
| 94 | #endif /* } */ | ||
| 95 | |||
| 96 | |||
| 81 | /* | 97 | /* |
| 82 | ** {====================================================== | 98 | ** {====================================================== |
| 83 | ** lua_fseek: configuration for longer offsets | 99 | ** l_fseek: configuration for longer offsets |
| 84 | ** ======================================================= | 100 | ** ======================================================= |
| 85 | */ | 101 | */ |
| 86 | 102 | ||
| 87 | #if !defined(lua_fseek) && !defined(LUA_ANSI) /* { */ | 103 | #if !defined(l_fseek) /* { */ |
| 88 | 104 | ||
| 89 | #if defined(LUA_USE_POSIX) /* { */ | 105 | #if defined(LUA_USE_POSIX) /* { */ |
| 90 | 106 | ||
| @@ -94,22 +110,22 @@ · 3 unmodified lines | |||
| 94 | 110 | ||
| 95 | #elif defined(LUA_WIN) && !defined(_CRTIMP_TYPEINFO) \ | 111 | #elif defined(LUA_WIN) && !defined(_CRTIMP_TYPEINFO) \ |
| 96 | && defined(_MSC_VER) && (_MSC_VER >= 1400) /* }{ */ | 112 | && defined(_MSC_VER) && (_MSC_VER >= 1400) /* }{ */ |
| 97 | /* Windows (but not DDK) and Visual C++ 2005 or higher */ | ||
| 98 | 113 | ||
| 114 | /* Windows (but not DDK) and Visual C++ 2005 or higher */ | ||
| 99 | #define l_fseek(f,o,w) _fseeki64(f,o,w) | 115 | #define l_fseek(f,o,w) _fseeki64(f,o,w) |
| 100 | #define l_ftell(f) _ftelli64(f) | 116 | #define l_ftell(f) _ftelli64(f) |
| 101 | #define l_seeknum __int64 | 117 | #define l_seeknum __int64 |
| 102 | 118 | ||
| 103 | #endif /* } */ | 119 | #else /* }{ */ |
| 104 | |||
| 105 | #endif /* } */ | ||
| 106 | |||
| 107 | 120 | ||
| 108 | #if !defined(l_fseek) /* default definitions */ | 121 | /* ANSI definitions */ |
| 109 | #define l_fseek(f,o,w) fseek(f,o,w) | 122 | #define l_fseek(f,o,w) fseek(f,o,w) |
| 110 | #define l_ftell(f) ftell(f) | 123 | #define l_ftell(f) ftell(f) |
| 111 | #define l_seeknum long | 124 | #define l_seeknum long |
| 112 | #endif | 125 | |
| 126 | #endif /* } */ | ||
| 127 | |||
| 128 | #endif /* } */ | ||
| 113 | 129 | ||
| 114 | /* }====================================================== */ | 130 | /* }====================================================== */ |
| 115 | 131 | ||
| @@ -228,7 +244,7 @@ static int io_open (lua_State *L) { · 112 unmodified lines | |||
| 228 | const char *mode = luaL_optstring(L, 2, "r"); | 244 | const char *mode = luaL_optstring(L, 2, "r"); |
| 229 | LStream *p = newfile(L); | 245 | LStream *p = newfile(L); |
| 230 | const char *md = mode; /* to traverse/check mode */ | 246 | const char *md = mode; /* to traverse/check mode */ |
| 231 | luaL_argcheck(L, lua_checkmode(md), 2, "invalid mode"); | 247 | luaL_argcheck(L, l_checkmode(md), 2, "invalid mode"); |
| 232 | p->f = fopen(filename, mode); | 248 | p->f = fopen(filename, mode); |
| 233 | return (p->f == NULL) ? luaL_fileresult(L, 0, filename) : 1; | 249 | return (p->f == NULL) ? luaL_fileresult(L, 0, filename) : 1; |
| 234 | } | 250 | } |
| @@ -239,7 +255,7 @@ static int io_open (lua_State *L) { · 4 unmodified lines | |||
| 239 | */ | 255 | */ |
| 240 | static int io_pclose (lua_State *L) { | 256 | static int io_pclose (lua_State *L) { |
| 241 | LStream *p = tolstream(L); | 257 | LStream *p = tolstream(L); |
| 242 | return luaL_execresult(L, lua_pclose(L, p->f)); | 258 | return luaL_execresult(L, l_pclose(L, p->f)); |
| 243 | } | 259 | } |
| 244 | 260 | ||
| 245 | 261 | ||
| @@ -247,7 +263,7 @@ static int io_popen (lua_State *L) { · 1 unmodified line | |||
| 247 | const char *filename = luaL_checkstring(L, 1); | 263 | const char *filename = luaL_checkstring(L, 1); |
| 248 | const char *mode = luaL_optstring(L, 2, "r"); | 264 | const char *mode = luaL_optstring(L, 2, "r"); |
| 249 | LStream *p = newprefile(L); | 265 | LStream *p = newprefile(L); |
| 250 | p->f = lua_popen(L, filename, mode); | 266 | p->f = l_popen(L, filename, mode); |
| 251 | p->closef = &io_pclose; | 267 | p->closef = &io_pclose; |
| 252 | return (p->f == NULL) ? luaL_fileresult(L, 0, filename) : 1; | 268 | return (p->f == NULL) ? luaL_fileresult(L, 0, filename) : 1; |
| 253 | } | 269 | } |
| @@ -375,7 +391,7 @@ static int read_number (lua_State *L, FILE *f) { · 121 unmodified lines | |||
| 375 | 391 | ||
| 376 | static int test_eof (lua_State *L, FILE *f) { | 392 | static int test_eof (lua_State *L, FILE *f) { |
| 377 | int c = getc(f); | 393 | int c = getc(f); |
| 378 | ungetc(c, f); | 394 | ungetc(c, f); /* no-op when c == EOF */ |
| 379 | lua_pushlstring(L, NULL, 0); | 395 | lua_pushlstring(L, NULL, 0); |
| 380 | return (c != EOF); | 396 | return (c != EOF); |
| 381 | } | 397 | } |
| @@ -383,40 +399,27 @@ static int test_eof (lua_State *L, FILE *f) { · 1 unmodified line | |||
| 383 | 399 | ||
| 384 | static int read_line (lua_State *L, FILE *f, int chop) { | 400 | static int read_line (lua_State *L, FILE *f, int chop) { |
| 385 | luaL_Buffer b; | 401 | luaL_Buffer b; |
| 402 | int c; | ||
| 386 | luaL_buffinit(L, &b); | 403 | luaL_buffinit(L, &b); |
| 387 | for (;;) { | 404 | l_lockfile(f); |
| 388 | size_t l; | 405 | while ((c = l_getc(f)) != EOF && c != '\n') |
| 389 | char *p = luaL_prepbuffer(&b); | 406 | luaL_addchar(&b, c); |
| 390 | if (fgets(p, LUAL_BUFFERSIZE, f) == NULL) { /* eof? */ | 407 | l_unlockfile(f); |
| 391 | luaL_pushresult(&b); /* close buffer */ | 408 | if (!chop && c == '\n') luaL_addchar(&b, c); |
| 392 | return (lua_rawlen(L, -1) > 0); /* check whether read something */ | 409 | luaL_pushresult(&b); /* close buffer */ |
| 393 | } | 410 | return (c == '\n' || lua_rawlen(L, -1) > 0); |
| 394 | l = strlen(p); | ||
| 395 | if (l == 0 || p[l-1] != '\n') | ||
| 396 | luaL_addsize(&b, l); | ||
| 397 | else { | ||
| 398 | luaL_addsize(&b, l - chop); /* chop 'eol' if needed */ | ||
| 399 | luaL_pushresult(&b); /* close buffer */ | ||
| 400 | return 1; /* read at least an `eol' */ | ||
| 401 | } | ||
| 402 | } | ||
| 403 | } | 411 | } |
| 404 | 412 | ||
| 405 | 413 | ||
| 406 | #define MAX_SIZE_T (~(size_t)0) | ||
| 407 | |||
| 408 | static void read_all (lua_State *L, FILE *f) { | 414 | static void read_all (lua_State *L, FILE *f) { |
| 409 | size_t rlen = LUAL_BUFFERSIZE; /* how much to read in each cycle */ | 415 | size_t nr; |
| 410 | luaL_Buffer b; | 416 | luaL_Buffer b; |
| 411 | luaL_buffinit(L, &b); | 417 | luaL_buffinit(L, &b); |
| 412 | for (;;) { | 418 | do { /* read file in chunks of LUAL_BUFFERSIZE bytes */ |
| 413 | char *p = luaL_prepbuffsize(&b, rlen); | 419 | char *p = luaL_prepbuffsize(&b, LUAL_BUFFERSIZE); |
| 414 | size_t nr = fread(p, sizeof(char), rlen, f); | 420 | nr = fread(p, sizeof(char), LUAL_BUFFERSIZE, f); |
| 415 | luaL_addsize(&b, nr); | 421 | luaL_addsize(&b, nr); |
| 416 | if (nr < rlen) break; /* eof? */ | 422 | } while (nr == LUAL_BUFFERSIZE); |
| 417 | else if (rlen <= (MAX_SIZE_T / 4)) /* avoid buffers too large */ | ||
| 418 | rlen *= 2; /* double buffer size at each iteration */ | ||
| 419 | } | ||
| 420 | luaL_pushresult(&b); /* close buffer */ | 423 | luaL_pushresult(&b); /* close buffer */ |
| 421 | } | 424 | } |
| 422 | 425 | ||
| @@ -566,15 +569,15 @@ static int f_seek (lua_State *L) { · 143 unmodified lines | |||
| 566 | static const char *const modenames[] = {"set", "cur", "end", NULL}; | 569 | static const char *const modenames[] = {"set", "cur", "end", NULL}; |
| 567 | FILE *f = tofile(L); | 570 | FILE *f = tofile(L); |
| 568 | int op = luaL_checkoption(L, 2, "cur", modenames); | 571 | int op = luaL_checkoption(L, 2, "cur", modenames); |
| 569 | lua_Number p3 = luaL_optnumber(L, 3, 0); | 572 | lua_Integer p3 = luaL_optinteger(L, 3, 0); |
| 570 | l_seeknum offset = (l_seeknum)p3; | 573 | l_seeknum offset = (l_seeknum)p3; |
| 571 | luaL_argcheck(L, (lua_Number)offset == p3, 3, | 574 | luaL_argcheck(L, (lua_Integer)offset == p3, 3, |
| 572 | "not an integer in proper range"); | 575 | "not an integer in proper range"); |
| 573 | op = l_fseek(f, offset, mode[op]); | 576 | op = l_fseek(f, offset, mode[op]); |
| 574 | if (op) | 577 | if (op) |
| 575 | return luaL_fileresult(L, 0, NULL); /* error */ | 578 | return luaL_fileresult(L, 0, NULL); /* error */ |
| 576 | else { | 579 | else { |
| 577 | lua_pushnumber(L, (lua_Number)l_ftell(f)); | 580 | lua_pushinteger(L, (lua_Integer)l_ftell(f)); |
| 578 | return 1; | 581 | return 1; |
| 579 | } | 582 | } |
| 580 | } | 583 | } |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: llex.c,v 2.67 2013/06/19 14:27:00 roberto Exp $ | 2 | ** $Id: llex.c,v 2.74 2014/02/14 15:23:51 roberto Exp $ |
| 3 | ** Lexical Analyzer | 3 | ** Lexical Analyzer |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -15,6 +15,7 @@ · 9 unmodified lines | |||
| 15 | 15 | ||
| 16 | #include "lctype.h" | 16 | #include "lctype.h" |
| 17 | #include "ldo.h" | 17 | #include "ldo.h" |
| 18 | #include "lgc.h" | ||
| 18 | #include "llex.h" | 19 | #include "llex.h" |
| 19 | #include "lobject.h" | 20 | #include "lobject.h" |
| 20 | #include "lparser.h" | 21 | #include "lparser.h" |
| @@ -38,7 +39,8 @@ static const char *const luaX_tokens [] = { · 17 unmodified lines | |||
| 38 | "end", "false", "for", "function", "goto", "if", | 39 | "end", "false", "for", "function", "goto", "if", |
| 39 | "in", "local", "nil", "not", "or", "repeat", | 40 | "in", "local", "nil", "not", "or", "repeat", |
| 40 | "return", "then", "true", "until", "while", | 41 | "return", "then", "true", "until", "while", |
| 41 | "//", "..", "...", "==", ">=", "<=", "~=", "::", "<eof>", | 42 | "//", "..", "...", "==", ">=", "<=", "~=", |
| 43 | "<<", ">>", "::", "<eof>", | ||
| 42 | "<number>", "<number>", "<name>", "<string>" | 44 | "<number>", "<number>", "<name>", "<string>" |
| 43 | }; | 45 | }; |
| 44 | 46 | ||
| @@ -64,9 +66,11 @@ static void save (LexState *ls, int c) { · 19 unmodified lines | |||
| 64 | 66 | ||
| 65 | void luaX_init (lua_State *L) { | 67 | void luaX_init (lua_State *L) { |
| 66 | int i; | 68 | int i; |
| 69 | TString *e = luaS_new(L, LUA_ENV); /* create env name */ | ||
| 70 | luaC_fix(L, obj2gco(e)); /* never collect this name */ | ||
| 67 | for (i=0; i<NUM_RESERVED; i++) { | 71 | for (i=0; i<NUM_RESERVED; i++) { |
| 68 | TString *ts = luaS_new(L, luaX_tokens[i]); | 72 | TString *ts = luaS_new(L, luaX_tokens[i]); |
| 69 | luaS_fix(ts); /* reserved words are never collected */ | 73 | luaC_fix(L, obj2gco(ts)); /* reserved words are never collected */ |
| 70 | ts->tsv.extra = cast_byte(i+1); /* reserved word */ | 74 | ts->tsv.extra = cast_byte(i+1); /* reserved word */ |
| 71 | } | 75 | } |
| 72 | } | 76 | } |
| @@ -116,22 +120,25 @@ l_noret luaX_syntaxerror (LexState *ls, const char *msg) { · 43 unmodified lines | |||
| 116 | 120 | ||
| 117 | 121 | ||
| 118 | /* | 122 | /* |
| 119 | ** creates a new string and anchors it in function's table so that | 123 | ** creates a new string and anchors it in scanner's table so that |
| 120 | ** it will not be collected until the end of the function's compilation | 124 | ** it will not be collected until the end of the compilation |
| 121 | ** (by that time it should be anchored in function's prototype) | 125 | ** (by that time it should be anchored somewhere) |
| 122 | */ | 126 | */ |
| 123 | TString *luaX_newstring (LexState *ls, const char *str, size_t l) { | 127 | TString *luaX_newstring (LexState *ls, const char *str, size_t l) { |
| 124 | lua_State *L = ls->L; | 128 | lua_State *L = ls->L; |
| 125 | TValue *o; /* entry for `str' */ | 129 | TValue *o; /* entry for `str' */ |
| 126 | TString *ts = luaS_newlstr(L, str, l); /* create new string */ | 130 | TString *ts = luaS_newlstr(L, str, l); /* create new string */ |
| 127 | setsvalue2s(L, L->top++, ts); /* temporarily anchor it in stack */ | 131 | setsvalue2s(L, L->top++, ts); /* temporarily anchor it in stack */ |
| 128 | o = luaH_set(L, ls->fs->h, L->top - 1); | 132 | o = luaH_set(L, ls->h, L->top - 1); |
| 129 | if (ttisnil(o)) { /* not in use yet? (see 'addK') */ | 133 | if (ttisnil(o)) { /* not in use yet? */ |
| 130 | /* boolean value does not need GC barrier; | 134 | /* boolean value does not need GC barrier; |
| 131 | table has no metatable, so it does not need to invalidate cache */ | 135 | table has no metatable, so it does not need to invalidate cache */ |
| 132 | setbvalue(o, 1); /* t[string] = true */ | 136 | setbvalue(o, 1); /* t[string] = true */ |
| 133 | luaC_checkGC(L); | 137 | luaC_checkGC(L); |
| 134 | } | 138 | } |
| 139 | else { /* string already present */ | ||
| 140 | ts = rawtsvalue(keyfromval(o)); /* re-use value previously stored */ | ||
| 141 | } | ||
| 135 | L->top--; /* remove string from stack */ | 142 | L->top--; /* remove string from stack */ |
| 136 | return ts; | 143 | return ts; |
| 137 | } | 144 | } |
| @@ -163,8 +170,7 @@ void luaX_setinput (lua_State *L, LexState *ls, ZIO *z, TString *source, · 25 unmodified lines | |||
| 163 | ls->linenumber = 1; | 170 | ls->linenumber = 1; |
| 164 | ls->lastline = 1; | 171 | ls->lastline = 1; |
| 165 | ls->source = source; | 172 | ls->source = source; |
| 166 | ls->envn = luaS_new(L, LUA_ENV); /* create env name */ | 173 | ls->envn = luaS_new(L, LUA_ENV); /* get env name */ |
| 167 | luaS_fix(ls->envn); /* never collect this name */ | ||
| 168 | luaZ_resizebuffer(ls->L, ls->buff, LUA_MINBUFFER); /* initialize buffer */ | 174 | luaZ_resizebuffer(ls->L, ls->buff, LUA_MINBUFFER); /* initialize buffer */ |
| 169 | } | 175 | } |
| 170 | 176 | ||
| @@ -314,40 +320,65 @@ static void read_long_string (LexState *ls, SemInfo *seminfo, int sep) { · 143 unmodified lines | |||
| 314 | } | 320 | } |
| 315 | 321 | ||
| 316 | 322 | ||
| 317 | static void escerror (LexState *ls, int *c, int n, const char *msg) { | 323 | static void esccheck (LexState *ls, int c, const char *msg) { |
| 318 | int i; | 324 | if (!c) { |
| 319 | luaZ_resetbuffer(ls->buff); /* prepare error message */ | 325 | if (ls->current != EOZ) |
| 320 | save(ls, '\\'); | 326 | save_and_next(ls); /* add current to buffer for error message */ |
| 321 | for (i = 0; i < n && c[i] != EOZ; i++) | 327 | lexerror(ls, msg, TK_STRING); |
| 322 | save(ls, c[i]); | 328 | } |
| 323 | lexerror(ls, msg, TK_STRING); | 329 | } |
| 330 | |||
| 331 | |||
| 332 | static int gethexa (LexState *ls) { | ||
| 333 | save_and_next(ls); | ||
| 334 | esccheck (ls, lisxdigit(ls->current), "hexadecimal digit expected"); | ||
| 335 | return luaO_hexavalue(ls->current); | ||
| 324 | } | 336 | } |
| 325 | 337 | ||
| 326 | 338 | ||
| 327 | static int readhexaesc (LexState *ls) { | 339 | static int readhexaesc (LexState *ls) { |
| 328 | int c[3], i; /* keep input for error message */ | 340 | int r = gethexa(ls); |
| 329 | int r = 0; /* result accumulator */ | 341 | r = (r << 4) + gethexa(ls); |
| 330 | c[0] = 'x'; /* for error message */ | 342 | luaZ_buffremove(ls->buff, 2); /* remove saved chars from buffer */ |
| 331 | for (i = 1; i < 3; i++) { /* read two hexadecimal digits */ | 343 | return r; |
| 332 | c[i] = next(ls); | 344 | } |
| 333 | if (!lisxdigit(c[i])) | 345 | |
| 334 | escerror(ls, c, i + 1, "hexadecimal digit expected"); | 346 | |
| 335 | r = (r << 4) + luaO_hexavalue(c[i]); | 347 | static unsigned int readutf8esc (LexState *ls) { |
| 348 | unsigned int r; | ||
| 349 | int i = 4; /* chars to be removed: '\', 'u', '{', and first digit */ | ||
| 350 | save_and_next(ls); /* skip 'u' */ | ||
| 351 | esccheck(ls, ls->current == '{', "missing '{'"); | ||
| 352 | r = gethexa(ls); /* must have at least one digit */ | ||
| 353 | while ((save_and_next(ls), lisxdigit(ls->current))) { | ||
| 354 | i++; | ||
| 355 | r = (r << 4) + luaO_hexavalue(ls->current); | ||
| 356 | esccheck(ls, r <= 0x10FFFF, "UTF-8 value too large"); | ||
| 336 | } | 357 | } |
| 358 | esccheck(ls, ls->current == '}', "missing '}'"); | ||
| 359 | next(ls); /* skip '}' */ | ||
| 360 | luaZ_buffremove(ls->buff, i); /* remove saved chars from buffer */ | ||
| 337 | return r; | 361 | return r; |
| 338 | } | 362 | } |
| 339 | 363 | ||
| 340 | 364 | ||
| 365 | static void utf8esc (LexState *ls) { | ||
| 366 | char buff[UTF8BUFFSZ]; | ||
| 367 | int n = luaO_utf8esc(buff, readutf8esc(ls)); | ||
| 368 | for (; n > 0; n--) /* add 'buff' to string */ | ||
| 369 | save(ls, buff[UTF8BUFFSZ - n]); | ||
| 370 | } | ||
| 371 | |||
| 372 | |||
| 341 | static int readdecesc (LexState *ls) { | 373 | static int readdecesc (LexState *ls) { |
| 342 | int c[3], i; | 374 | int i; |
| 343 | int r = 0; /* result accumulator */ | 375 | int r = 0; /* result accumulator */ |
| 344 | for (i = 0; i < 3 && lisdigit(ls->current); i++) { /* read up to 3 digits */ | 376 | for (i = 0; i < 3 && lisdigit(ls->current); i++) { /* read up to 3 digits */ |
| 345 | c[i] = ls->current; | 377 | r = 10*r + ls->current - '0'; |
| 346 | r = 10*r + c[i] - '0'; | 378 | save_and_next(ls); |
| 347 | next(ls); | ||
| 348 | } | 379 | } |
| 349 | if (r > UCHAR_MAX) | 380 | esccheck(ls, r <= UCHAR_MAX, "decimal escape too large"); |
| 350 | escerror(ls, c, i, "decimal escape too large"); | 381 | luaZ_buffremove(ls->buff, i); /* remove read digits from buffer */ |
| 351 | return r; | 382 | return r; |
| 352 | } | 383 | } |
| 353 | 384 | ||
| @@ -365,7 +396,7 @@ static void read_string (LexState *ls, int del, SemInfo *seminfo) { · 11 unmodified lines | |||
| 365 | break; /* to avoid warnings */ | 396 | break; /* to avoid warnings */ |
| 366 | case '\\': { /* escape sequences */ | 397 | case '\\': { /* escape sequences */ |
| 367 | int c; /* final character to be saved */ | 398 | int c; /* final character to be saved */ |
| 368 | next(ls); /* do not save the `\' */ | 399 | save_and_next(ls); /* keep '\\' for error messages */ |
| 369 | switch (ls->current) { | 400 | switch (ls->current) { |
| 370 | case 'a': c = '\a'; goto read_save; | 401 | case 'a': c = '\a'; goto read_save; |
| 371 | case 'b': c = '\b'; goto read_save; | 402 | case 'b': c = '\b'; goto read_save; |
| @@ -375,12 +406,14 @@ static void read_string (LexState *ls, int del, SemInfo *seminfo) { · 3 unmodified lines | |||
| 375 | case 't': c = '\t'; goto read_save; | 406 | case 't': c = '\t'; goto read_save; |
| 376 | case 'v': c = '\v'; goto read_save; | 407 | case 'v': c = '\v'; goto read_save; |
| 377 | case 'x': c = readhexaesc(ls); goto read_save; | 408 | case 'x': c = readhexaesc(ls); goto read_save; |
| 409 | case 'u': utf8esc(ls); goto no_save; | ||
| 378 | case '\n': case '\r': | 410 | case '\n': case '\r': |
| 379 | inclinenumber(ls); c = '\n'; goto only_save; | 411 | inclinenumber(ls); c = '\n'; goto only_save; |
| 380 | case '\\': case '\"': case '\'': | 412 | case '\\': case '\"': case '\'': |
| 381 | c = ls->current; goto read_save; | 413 | c = ls->current; goto read_save; |
| 382 | case EOZ: goto no_save; /* will raise an error next loop */ | 414 | case EOZ: goto no_save; /* will raise an error next loop */ |
| 383 | case 'z': { /* zap following span of spaces */ | 415 | case 'z': { /* zap following span of spaces */ |
| 416 | luaZ_buffremove(ls->buff, 1); /* remove '\\' */ | ||
| 384 | next(ls); /* skip the 'z' */ | 417 | next(ls); /* skip the 'z' */ |
| 385 | while (lisspace(ls->current)) { | 418 | while (lisspace(ls->current)) { |
| 386 | if (currIsNewline(ls)) inclinenumber(ls); | 419 | if (currIsNewline(ls)) inclinenumber(ls); |
| @@ -389,15 +422,18 @@ static void read_string (LexState *ls, int del, SemInfo *seminfo) { · 2 unmodified lines | |||
| 389 | goto no_save; | 422 | goto no_save; |
| 390 | } | 423 | } |
| 391 | default: { | 424 | default: { |
| 392 | if (!lisdigit(ls->current)) | 425 | esccheck(ls, lisdigit(ls->current), "invalid escape sequence"); |
| 393 | escerror(ls, &ls->current, 1, "invalid escape sequence"); | 426 | c = readdecesc(ls); /* digital escape \ddd */ |
| 394 | /* digital escape \ddd */ | ||
| 395 | c = readdecesc(ls); | ||
| 396 | goto only_save; | 427 | goto only_save; |
| 397 | } | 428 | } |
| 398 | } | 429 | } |
| 399 | read_save: next(ls); /* read next character */ | 430 | read_save: |
| 400 | only_save: save(ls, c); /* save 'c' */ | 431 | next(ls); |
| 432 | /* go through */ | ||
| 433 | only_save: | ||
| 434 | luaZ_buffremove(ls->buff, 1); /* remove '\\' */ | ||
| 435 | save(ls, c); | ||
| 436 | /* go through */ | ||
| 401 | no_save: break; | 437 | no_save: break; |
| 402 | } | 438 | } |
| 403 | default: | 439 | default: |
| @@ -457,13 +493,15 @@ static int llex (LexState *ls, SemInfo *seminfo) { · 53 unmodified lines | |||
| 457 | } | 493 | } |
| 458 | case '<': { | 494 | case '<': { |
| 459 | next(ls); | 495 | next(ls); |
| 460 | if (ls->current != '=') return '<'; | 496 | if (ls->current == '=') { next(ls); return TK_LE; } |
| 461 | else { next(ls); return TK_LE; } | 497 | if (ls->current == '<') { next(ls); return TK_SHL; } |
| 498 | return '<'; | ||
| 462 | } | 499 | } |
| 463 | case '>': { | 500 | case '>': { |
| 464 | next(ls); | 501 | next(ls); |
| 465 | if (ls->current != '=') return '>'; | 502 | if (ls->current == '=') { next(ls); return TK_GE; } |
| 466 | else { next(ls); return TK_GE; } | 503 | if (ls->current == '>') { next(ls); return TK_SHR; } |
| 504 | return '>'; | ||
| 467 | } | 505 | } |
| 468 | case '/': { | 506 | case '/': { |
| 469 | next(ls); | 507 | next(ls); |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: llex.h,v 1.74 2013/04/26 13:07:53 roberto Exp $ | 2 | ** $Id: llex.h,v 1.76 2013/12/30 20:47:58 roberto Exp $ |
| 3 | ** Lexical Analyzer | 3 | ** Lexical Analyzer |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -27,6 +27,7 @@ enum RESERVED { · 21 unmodified lines | |||
| 27 | TK_RETURN, TK_THEN, TK_TRUE, TK_UNTIL, TK_WHILE, | 27 | TK_RETURN, TK_THEN, TK_TRUE, TK_UNTIL, TK_WHILE, |
| 28 | /* other terminal symbols */ | 28 | /* other terminal symbols */ |
| 29 | TK_IDIV, TK_CONCAT, TK_DOTS, TK_EQ, TK_GE, TK_LE, TK_NE, | 29 | TK_IDIV, TK_CONCAT, TK_DOTS, TK_EQ, TK_GE, TK_LE, TK_NE, |
| 30 | TK_SHL, TK_SHR, | ||
| 30 | TK_DBCOLON, TK_EOS, | 31 | TK_DBCOLON, TK_EOS, |
| 31 | TK_FLT, TK_INT, TK_NAME, TK_STRING | 32 | TK_FLT, TK_INT, TK_NAME, TK_STRING |
| 32 | }; | 33 | }; |
| @@ -60,6 +61,7 @@ typedef struct LexState { · 27 unmodified lines | |||
| 60 | struct lua_State *L; | 61 | struct lua_State *L; |
| 61 | ZIO *z; /* input stream */ | 62 | ZIO *z; /* input stream */ |
| 62 | Mbuffer *buff; /* buffer for tokens */ | 63 | Mbuffer *buff; /* buffer for tokens */ |
| 64 | Table *h; /* to avoid collection/reuse strings */ | ||
| 63 | struct Dyndata *dyd; /* dynamic structures used by the parser */ | 65 | struct Dyndata *dyd; /* dynamic structures used by the parser */ |
| 64 | TString *source; /* current source name */ | 66 | TString *source; /* current source name */ |
| 65 | TString *envn; /* environment variable name */ | 67 | TString *envn; /* environment variable name */ |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: llimits.h,v 1.108 2013/06/19 14:27:00 roberto Exp $ | 2 | ** $Id: llimits.h,v 1.111 2014/03/07 16:19:00 roberto Exp $ |
| 3 | ** Limits, basic types, and some other `installation-dependent' definitions | 3 | ** Limits, basic types, and some other `installation-dependent' definitions |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -43,11 +43,13 @@ typedef unsigned char lu_byte; · 37 unmodified lines | |||
| 43 | #define MAX_INT (INT_MAX-2) /* maximum value of an int (-2 for safety) */ | 43 | #define MAX_INT (INT_MAX-2) /* maximum value of an int (-2 for safety) */ |
| 44 | 44 | ||
| 45 | 45 | ||
| 46 | /* maximum value for a lua_Unsigned */ | ||
| 47 | #define MAX_UINTEGER (~(lua_Unsigned)0) | ||
| 48 | |||
| 46 | /* minimum and maximum values for lua_Integer */ | 49 | /* minimum and maximum values for lua_Integer */ |
| 47 | #define MAX_INTEGER ((lua_Integer)(~(lua_Unsigned)0 >> 1)) | 50 | #define MAX_INTEGER ((lua_Integer)(MAX_UINTEGER >> 1)) |
| 48 | #define MIN_INTEGER (~MAX_INTEGER) | 51 | #define MIN_INTEGER (~MAX_INTEGER) |
| 49 | 52 | ||
| 50 | |||
| 51 | /* | 53 | /* |
| 52 | ** conversion of pointer to integer | 54 | ** conversion of pointer to integer |
| 53 | ** this is for hashing only; there is no problem if the integer | 55 | ** this is for hashing only; there is no problem if the integer |
| @@ -104,6 +106,7 @@ typedef LUAI_UACNUMBER l_uacNumber; · 50 unmodified lines | |||
| 104 | 106 | ||
| 105 | #define cast(t, exp) ((t)(exp)) | 107 | #define cast(t, exp) ((t)(exp)) |
| 106 | 108 | ||
| 109 | #define cast_void(i) cast(void, (i)) | ||
| 107 | #define cast_byte(i) cast(lu_byte, (i)) | 110 | #define cast_byte(i) cast(lu_byte, (i)) |
| 108 | #define cast_num(i) cast(lua_Number, (i)) | 111 | #define cast_num(i) cast(lua_Number, (i)) |
| 109 | #define cast_int(i) cast(int, (i)) | 112 | #define cast_int(i) cast(int, (i)) |
| @@ -155,7 +158,7 @@ typedef lu_int32 Instruction; · 45 unmodified lines | |||
| 155 | 158 | ||
| 156 | /* minimum size for the string table (must be power of 2) */ | 159 | /* minimum size for the string table (must be power of 2) */ |
| 157 | #if !defined(MINSTRTABSIZE) | 160 | #if !defined(MINSTRTABSIZE) |
| 158 | #define MINSTRTABSIZE 32 | 161 | #define MINSTRTABSIZE 64 /* minimum size for "predefined" strings */ |
| 159 | #endif | 162 | #endif |
| 160 | 163 | ||
| 161 | 164 | ||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lmathlib.c,v 1.90 2013/07/03 17:23:19 roberto Exp $ | 2 | ** $Id: lmathlib.c,v 1.92 2013/07/22 16:05:53 roberto Exp $ |
| 3 | ** Standard mathematical library | 3 | ** Standard mathematical library |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -251,9 +251,16 @@ static int math_randomseed (lua_State *L) { · 245 unmodified lines | |||
| 251 | } | 251 | } |
| 252 | 252 | ||
| 253 | 253 | ||
| 254 | static int math_isfloat (lua_State *L) { | 254 | static int math_type (lua_State *L) { |
| 255 | luaL_checkany(L, 1); | 255 | luaL_checkany(L, 1); |
| 256 | lua_pushboolean(L, (lua_type(L, 1) == LUA_TNUMBER && !lua_isinteger(L, 1))); | 256 | if (lua_type(L, 1) == LUA_TNUMBER) { |
| 257 | if (lua_isinteger(L, 1)) | ||
| 258 | lua_pushliteral(L, "integer"); | ||
| 259 | else | ||
| 260 | lua_pushliteral(L, "float"); | ||
| 261 | } | ||
| 262 | else | ||
| 263 | lua_pushnil(L); | ||
| 257 | return 1; | 264 | return 1; |
| 258 | } | 265 | } |
| 259 | 266 | ||
| @@ -273,7 +280,6 @@ static const luaL_Reg mathlib[] = { · 13 unmodified lines | |||
| 273 | {"ifloor", math_ifloor}, | 280 | {"ifloor", math_ifloor}, |
| 274 | {"fmod", math_fmod}, | 281 | {"fmod", math_fmod}, |
| 275 | {"frexp", math_frexp}, | 282 | {"frexp", math_frexp}, |
| 276 | {"isfloat", math_isfloat}, | ||
| 277 | {"ldexp", math_ldexp}, | 283 | {"ldexp", math_ldexp}, |
| 278 | #if defined(LUA_COMPAT_LOG10) | 284 | #if defined(LUA_COMPAT_LOG10) |
| 279 | {"log10", math_log10}, | 285 | {"log10", math_log10}, |
| @@ -291,6 +297,7 @@ static const luaL_Reg mathlib[] = { · 11 unmodified lines | |||
| 291 | {"sqrt", math_sqrt}, | 297 | {"sqrt", math_sqrt}, |
| 292 | {"tanh", math_tanh}, | 298 | {"tanh", math_tanh}, |
| 293 | {"tan", math_tan}, | 299 | {"tan", math_tan}, |
| 300 | {"type", math_type}, | ||
| 294 | {NULL, NULL} | 301 | {NULL, NULL} |
| 295 | }; | 302 | }; |
| 296 | 303 | ||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: loadlib.c,v 1.111 2012/05/30 12:33:44 roberto Exp $ | 2 | ** $Id: loadlib.c,v 1.113 2014/03/12 20:57:40 roberto Exp $ |
| 3 | ** Dynamic library loader for Lua | 3 | ** Dynamic library loader for Lua |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | ** | 5 | ** |
| @@ -31,21 +31,21 @@ · 25 unmodified lines | |||
| 31 | 31 | ||
| 32 | 32 | ||
| 33 | /* | 33 | /* |
| 34 | ** LUA_PATH and LUA_CPATH are the names of the environment | 34 | ** LUA_PATH_VAR and LUA_CPATH_VAR are the names of the environment |
| 35 | ** variables that Lua check to set its paths. | 35 | ** variables that Lua check to set its paths. |
| 36 | */ | 36 | */ |
| 37 | #if !defined(LUA_PATH) | 37 | #if !defined(LUA_PATH_VAR) |
| 38 | #define LUA_PATH "LUA_PATH" | 38 | #define LUA_PATH_VAR "LUA_PATH" |
| 39 | #endif | 39 | #endif |
| 40 | 40 | ||
| 41 | #if !defined(LUA_CPATH) | 41 | #if !defined(LUA_CPATH_VAR) |
| 42 | #define LUA_CPATH "LUA_CPATH" | 42 | #define LUA_CPATH_VAR "LUA_CPATH" |
| 43 | #endif | 43 | #endif |
| 44 | 44 | ||
| 45 | #define LUA_PATHSUFFIX "_" LUA_VERSION_MAJOR "_" LUA_VERSION_MINOR | 45 | #define LUA_PATHSUFFIX "_" LUA_VERSION_MAJOR "_" LUA_VERSION_MINOR |
| 46 | 46 | ||
| 47 | #define LUA_PATHVERSION LUA_PATH LUA_PATHSUFFIX | 47 | #define LUA_PATHVARVERSION LUA_PATH_VAR LUA_PATHSUFFIX |
| 48 | #define LUA_CPATHVERSION LUA_CPATH LUA_PATHSUFFIX | 48 | #define LUA_CPATHVARVERSION LUA_CPATH_VAR LUA_PATHSUFFIX |
| 49 | 49 | ||
| 50 | /* | 50 | /* |
| 51 | ** LUA_PATH_SEP is the character that separates templates in a path. | 51 | ** LUA_PATH_SEP is the character that separates templates in a path. |
| @@ -468,8 +468,7 @@ static int searcher_Croot (lua_State *L) { · 416 unmodified lines | |||
| 468 | static int searcher_preload (lua_State *L) { | 468 | static int searcher_preload (lua_State *L) { |
| 469 | const char *name = luaL_checkstring(L, 1); | 469 | const char *name = luaL_checkstring(L, 1); |
| 470 | lua_getfield(L, LUA_REGISTRYINDEX, "_PRELOAD"); | 470 | lua_getfield(L, LUA_REGISTRYINDEX, "_PRELOAD"); |
| 471 | lua_getfield(L, -1, name); | 471 | if (lua_getfield(L, -1, name) == LUA_TNIL) /* not found? */ |
| 472 | if (lua_isnil(L, -1)) /* not found? */ | ||
| 473 | lua_pushfstring(L, "\n\tno field package.preload['%s']", name); | 472 | lua_pushfstring(L, "\n\tno field package.preload['%s']", name); |
| 474 | return 1; | 473 | return 1; |
| 475 | } | 474 | } |
| @@ -484,8 +483,7 @@ static void findloader (lua_State *L, const char *name) { · 8 unmodified lines | |||
| 484 | luaL_error(L, LUA_QL("package.searchers") " must be a table"); | 483 | luaL_error(L, LUA_QL("package.searchers") " must be a table"); |
| 485 | /* iterate over available searchers to find a loader */ | 484 | /* iterate over available searchers to find a loader */ |
| 486 | for (i = 1; ; i++) { | 485 | for (i = 1; ; i++) { |
| 487 | lua_rawgeti(L, 3, i); /* get a searcher */ | 486 | if (lua_rawgeti(L, 3, i) == LUA_TNIL) { /* no more searchers? */ |
| 488 | if (lua_isnil(L, -1)) { /* no more searchers? */ | ||
| 489 | lua_pop(L, 1); /* remove nil */ | 487 | lua_pop(L, 1); /* remove nil */ |
| 490 | luaL_pushresult(&msg); /* create error message */ | 488 | luaL_pushresult(&msg); /* create error message */ |
| 491 | luaL_error(L, "module " LUA_QS " not found:%s", | 489 | luaL_error(L, "module " LUA_QS " not found:%s", |
| @@ -520,8 +518,7 @@ static int ll_require (lua_State *L) { · 28 unmodified lines | |||
| 520 | lua_call(L, 2, 1); /* run loader to load module */ | 518 | lua_call(L, 2, 1); /* run loader to load module */ |
| 521 | if (!lua_isnil(L, -1)) /* non-nil return? */ | 519 | if (!lua_isnil(L, -1)) /* non-nil return? */ |
| 522 | lua_setfield(L, 2, name); /* _LOADED[name] = returned value */ | 520 | lua_setfield(L, 2, name); /* _LOADED[name] = returned value */ |
| 523 | lua_getfield(L, 2, name); | 521 | if (lua_getfield(L, 2, name) == LUA_TNIL) { /* module set no value? */ |
| 524 | if (lua_isnil(L, -1)) { /* module did not set a value? */ | ||
| 525 | lua_pushboolean(L, 1); /* use true as result */ | 522 | lua_pushboolean(L, 1); /* use true as result */ |
| 526 | lua_pushvalue(L, -1); /* extra copy to be returned */ | 523 | lua_pushvalue(L, -1); /* extra copy to be returned */ |
| 527 | lua_setfield(L, 2, name); /* _LOADED[name] = true */ | 524 | lua_setfield(L, 2, name); /* _LOADED[name] = true */ |
| @@ -587,9 +584,8 @@ static int ll_module (lua_State *L) { · 59 unmodified lines | |||
| 587 | int lastarg = lua_gettop(L); /* last parameter */ | 584 | int lastarg = lua_gettop(L); /* last parameter */ |
| 588 | luaL_pushmodule(L, modname, 1); /* get/create module table */ | 585 | luaL_pushmodule(L, modname, 1); /* get/create module table */ |
| 589 | /* check whether table already has a _NAME field */ | 586 | /* check whether table already has a _NAME field */ |
| 590 | lua_getfield(L, -1, "_NAME"); | 587 | if (lua_getfield(L, -1, "_NAME") != LUA_TNIL) |
| 591 | if (!lua_isnil(L, -1)) /* is table an initialized module? */ | 588 | lua_pop(L, 1); /* table is an initialized module */ |
| 592 | lua_pop(L, 1); | ||
| 593 | else { /* no; initialize it */ | 589 | else { /* no; initialize it */ |
| 594 | lua_pop(L, 1); | 590 | lua_pop(L, 1); |
| 595 | modinit(L, modname); | 591 | modinit(L, modname); |
| @@ -703,9 +699,9 @@ LUAMOD_API int luaopen_package (lua_State *L) { · 107 unmodified lines | |||
| 703 | #endif | 699 | #endif |
| 704 | lua_setfield(L, -2, "searchers"); /* put it in field 'searchers' */ | 700 | lua_setfield(L, -2, "searchers"); /* put it in field 'searchers' */ |
| 705 | /* set field 'path' */ | 701 | /* set field 'path' */ |
| 706 | setpath(L, "path", LUA_PATHVERSION, LUA_PATH, LUA_PATH_DEFAULT); | 702 | setpath(L, "path", LUA_PATHVARVERSION, LUA_PATH_VAR, LUA_PATH_DEFAULT); |
| 707 | /* set field 'cpath' */ | 703 | /* set field 'cpath' */ |
| 708 | setpath(L, "cpath", LUA_CPATHVERSION, LUA_CPATH, LUA_CPATH_DEFAULT); | 704 | setpath(L, "cpath", LUA_CPATHVARVERSION, LUA_CPATH_VAR, LUA_CPATH_DEFAULT); |
| 709 | /* store config information */ | 705 | /* store config information */ |
| 710 | lua_pushliteral(L, LUA_DIRSEP "\n" LUA_PATH_SEP "\n" LUA_PATH_MARK "\n" | 706 | lua_pushliteral(L, LUA_DIRSEP "\n" LUA_PATH_SEP "\n" LUA_PATH_MARK "\n" |
| 711 | LUA_EXEC_DIR "\n" LUA_IGMARK "\n"); | 707 | LUA_EXEC_DIR "\n" LUA_IGMARK "\n"); |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lobject.c,v 2.67 2013/06/25 18:58:32 roberto Exp $ | 2 | ** $Id: lobject.c,v 2.76 2014/03/21 13:52:33 roberto Exp $ |
| 3 | ** Some generic functions over Lua objects | 3 | ** Some generic functions over Lua objects |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -77,22 +77,30 @@ static lua_Integer intarith (lua_State *L, int op, lua_Integer v1, · 71 unmodified lines | |||
| 77 | case LUA_OPSUB:return intop(-, v1, v2); | 77 | case LUA_OPSUB:return intop(-, v1, v2); |
| 78 | case LUA_OPMUL:return intop(*, v1, v2); | 78 | case LUA_OPMUL:return intop(*, v1, v2); |
| 79 | case LUA_OPMOD: return luaV_mod(L, v1, v2); | 79 | case LUA_OPMOD: return luaV_mod(L, v1, v2); |
| 80 | case LUA_OPPOW: return luaV_pow(v1, v2); | 80 | case LUA_OPPOW: return luaV_pow(L, v1, v2); |
| 81 | case LUA_OPUNM: return -v1; | 81 | case LUA_OPIDIV: return luaV_div(L, v1, v2); |
| 82 | case LUA_OPBAND: return intop(&, v1, v2); | ||
| 83 | case LUA_OPBOR: return intop(|, v1, v2); | ||
| 84 | case LUA_OPBXOR: return intop(^, v1, v2); | ||
| 85 | case LUA_OPSHL: return luaV_shiftl(v1, v2); | ||
| 86 | case LUA_OPSHR: return luaV_shiftl(v1, -v2); | ||
| 87 | case LUA_OPUNM: return intop(-, 0, v1); | ||
| 88 | case LUA_OPBNOT: return intop(^, cast_integer(-1), v1); | ||
| 82 | default: lua_assert(0); return 0; | 89 | default: lua_assert(0); return 0; |
| 83 | } | 90 | } |
| 84 | } | 91 | } |
| 85 | 92 | ||
| 86 | 93 | ||
| 87 | static lua_Number numarith (int op, lua_Number v1, lua_Number v2) { | 94 | static lua_Number numarith (lua_State *L, int op, lua_Number v1, |
| 95 | lua_Number v2) { | ||
| 88 | switch (op) { | 96 | switch (op) { |
| 89 | case LUA_OPADD: return luai_numadd(NULL, v1, v2); | 97 | case LUA_OPADD: return luai_numadd(L, v1, v2); |
| 90 | case LUA_OPSUB: return luai_numsub(NULL, v1, v2); | 98 | case LUA_OPSUB: return luai_numsub(L, v1, v2); |
| 91 | case LUA_OPMUL: return luai_nummul(NULL, v1, v2); | 99 | case LUA_OPMUL: return luai_nummul(L, v1, v2); |
| 92 | case LUA_OPDIV: return luai_numdiv(NULL, v1, v2); | 100 | case LUA_OPDIV: return luai_numdiv(L, v1, v2); |
| 93 | case LUA_OPMOD: return luai_nummod(NULL, v1, v2); | 101 | case LUA_OPMOD: return luai_nummod(L, v1, v2); |
| 94 | case LUA_OPPOW: return luai_numpow(NULL, v1, v2); | 102 | case LUA_OPPOW: return luai_numpow(L, v1, v2); |
| 95 | case LUA_OPUNM: return luai_numunm(NULL, v1); | 103 | case LUA_OPUNM: return luai_numunm(L, v1); |
| 96 | default: lua_assert(0); return 0; | 104 | default: lua_assert(0); return 0; |
| 97 | } | 105 | } |
| 98 | } | 106 | } |
| @@ -100,29 +108,40 @@ static lua_Number numarith (int op, lua_Number v1, lua_Number v2) { · 1 unmodified line | |||
| 100 | 108 | ||
| 101 | void luaO_arith (lua_State *L, int op, const TValue *p1, const TValue *p2, | 109 | void luaO_arith (lua_State *L, int op, const TValue *p1, const TValue *p2, |
| 102 | TValue *res) { | 110 | TValue *res) { |
| 103 | if (op == LUA_OPIDIV) { /* operates only on integers */ | 111 | switch (op) { |
| 104 | lua_Integer i1; lua_Integer i2; | 112 | case LUA_OPIDIV: case LUA_OPBAND: case LUA_OPBOR: |
| 105 | if (tointeger(p1, &i1) && tointeger(p2, &i2)) { | 113 | case LUA_OPBXOR: case LUA_OPSHL: case LUA_OPSHR: |
| 106 | setivalue(res, luaV_div(L, i1, i2)); | 114 | case LUA_OPBNOT: { /* operates only on integers */ |
| 107 | return; | 115 | lua_Integer i1; lua_Integer i2; |
| 116 | if (tointeger(p1, &i1) && tointeger(p2, &i2)) { | ||
| 117 | setivalue(res, intarith(L, op, i1, i2)); | ||
| 118 | return; | ||
| 119 | } | ||
| 120 | else break; /* go to the end */ | ||
| 108 | } | 121 | } |
| 109 | /* else go to the end */ | 122 | case LUA_OPDIV: { /* operates only on floats */ |
| 110 | } | 123 | lua_Number n1; lua_Number n2; |
| 111 | else { /* other operations */ | 124 | if (tonumber(p1, &n1) && tonumber(p2, &n2)) { |
| 112 | lua_Number n1; lua_Number n2; | 125 | setnvalue(res, numarith(L, op, n1, n2)); |
| 113 | if (ttisinteger(p1) && ttisinteger(p2) && op != LUA_OPDIV && | 126 | return; |
| 114 | (op != LUA_OPPOW || ivalue(p2) >= 0)) { | 127 | } |
| 115 | setivalue(res, intarith(L, op, ivalue(p1), ivalue(p2))); | 128 | else break; /* go to the end */ |
| 116 | return; | ||
| 117 | } | 129 | } |
| 118 | else if (tonumber(p1, &n1) && tonumber(p2, &n2)) { | 130 | default: { /* other operations */ |
| 119 | setnvalue(res, numarith(op, n1, n2)); | 131 | lua_Number n1; lua_Number n2; |
| 120 | return; | 132 | if (ttisinteger(p1) && ttisinteger(p2)) { |
| 133 | setivalue(res, intarith(L, op, ivalue(p1), ivalue(p2))); | ||
| 134 | return; | ||
| 135 | } | ||
| 136 | else if (tonumber(p1, &n1) && tonumber(p2, &n2)) { | ||
| 137 | setnvalue(res, numarith(L, op, n1, n2)); | ||
| 138 | return; | ||
| 139 | } | ||
| 140 | else break; /* go to the end */ | ||
| 121 | } | 141 | } |
| 122 | /* else go to the end */ | ||
| 123 | } | 142 | } |
| 124 | /* could not perform raw operation; try metmethod */ | 143 | /* could not perform raw operation; try metamethod */ |
| 125 | lua_assert(L != NULL); /* cannot fail when folding (compile time) */ | 144 | lua_assert(L != NULL); /* should not fail when folding (compile time) */ |
| 126 | luaT_trybinTM(L, p1, p2, res, cast(TMS, op - LUA_OPADD + TM_ADD)); | 145 | luaT_trybinTM(L, p1, p2, res, cast(TMS, op - LUA_OPADD + TM_ADD)); |
| 127 | } | 146 | } |
| 128 | 147 | ||
| @@ -141,22 +160,26 @@ static int isneg (const char **s) { · 12 unmodified lines | |||
| 141 | 160 | ||
| 142 | 161 | ||
| 143 | /* | 162 | /* |
| 163 | ** {====================================================== | ||
| 144 | ** lua_strx2number converts an hexadecimal numeric string to a number. | 164 | ** lua_strx2number converts an hexadecimal numeric string to a number. |
| 145 | ** In C99, 'strtod' does both conversions. C89, however, has no function | 165 | ** In C99, 'strtod' does both conversions. C89, however, has no function |
| 146 | ** to convert floating hexadecimal strings to numbers. For these | 166 | ** to convert floating hexadecimal strings to numbers. For these |
| 147 | ** systems, you can leave 'lua_strx2number' undefined and Lua will | 167 | ** systems, you can leave 'lua_strx2number' undefined and Lua will |
| 148 | ** provide its own implementation. | 168 | ** provide its own implementation. |
| 169 | ** ======================================================= | ||
| 149 | */ | 170 | */ |
| 150 | #if defined(LUA_USE_STRTODHEX) | 171 | #if !defined(lua_strx2number) /* { */ |
| 172 | |||
| 173 | #if defined(LUA_USE_C99) /* { */ | ||
| 174 | |||
| 151 | #define lua_strx2number(s,p) lua_str2number(s,p) | 175 | #define lua_strx2number(s,p) lua_str2number(s,p) |
| 152 | #endif | ||
| 153 | 176 | ||
| 177 | #else /* }{ */ | ||
| 154 | 178 | ||
| 155 | #if !defined(lua_strx2number) | 179 | /* Lua's implementation for 'lua_strx2number' */ |
| 156 | 180 | ||
| 157 | #include <math.h> | 181 | #include <math.h> |
| 158 | 182 | ||
| 159 | |||
| 160 | /* maximum number of significant digits to read (to avoid overflows | 183 | /* maximum number of significant digits to read (to avoid overflows |
| 161 | even with single floats) */ | 184 | even with single floats) */ |
| 162 | #define MAXSIGDIG 30 | 185 | #define MAXSIGDIG 30 |
| @@ -219,7 +242,11 @@ static lua_Number lua_strx2number (const char *s, char **endptr) { · 56 unmodified lines | |||
| 219 | return l_mathop(ldexp)(r, e); | 242 | return l_mathop(ldexp)(r, e); |
| 220 | } | 243 | } |
| 221 | 244 | ||
| 222 | #endif | 245 | #endif /* } */ |
| 246 | |||
| 247 | #endif /* } */ | ||
| 248 | |||
| 249 | /* }====================================================== */ | ||
| 223 | 250 | ||
| 224 | 251 | ||
| 225 | int luaO_str2d (const char *s, size_t len, lua_Number *result) { | 252 | int luaO_str2d (const char *s, size_t len, lua_Number *result) { |
| @@ -260,19 +287,36 @@ int luaO_str2int (const char *s, size_t len, lua_Integer *result) { · 34 unmodified lines | |||
| 260 | while (lisspace(cast_uchar(*s))) s++; /* skip trailing spaces */ | 287 | while (lisspace(cast_uchar(*s))) s++; /* skip trailing spaces */ |
| 261 | if (empty || s != ends) return 0; /* something wrong in the numeral */ | 288 | if (empty || s != ends) return 0; /* something wrong in the numeral */ |
| 262 | else { | 289 | else { |
| 263 | if (neg) *result = -cast(lua_Integer, a); | 290 | *result = cast_integer((neg) ? 0u - a : a); |
| 264 | else *result = cast(lua_Integer, a); | ||
| 265 | return 1; | 291 | return 1; |
| 266 | } | 292 | } |
| 267 | } | 293 | } |
| 268 | 294 | ||
| 269 | 295 | ||
| 296 | int luaO_utf8esc (char *buff, unsigned int x) { | ||
| 297 | int n = 1; /* number of bytes put in buffer (backwards) */ | ||
| 298 | if (x < 0x80) /* ascii? */ | ||
| 299 | buff[UTF8BUFFSZ - 1] = x; | ||
| 300 | else { /* need continuation bytes */ | ||
| 301 | unsigned int mfb = 0x3f; /* maximum that fits in first byte */ | ||
| 302 | do { | ||
| 303 | buff[UTF8BUFFSZ - (n++)] = 0x80 | (x & 0x3f); /* add continuation byte */ | ||
| 304 | x >>= 6; /* remove added bits */ | ||
| 305 | mfb >>= 1; /* now there is one less bit available in first byte */ | ||
| 306 | } while (x > mfb); /* still needs continuation byte? */ | ||
| 307 | buff[UTF8BUFFSZ - n] = (~mfb << 1) | x; /* add first byte */ | ||
| 308 | } | ||
| 309 | return n; | ||
| 310 | } | ||
| 311 | |||
| 312 | |||
| 270 | static void pushstr (lua_State *L, const char *str, size_t l) { | 313 | static void pushstr (lua_State *L, const char *str, size_t l) { |
| 271 | setsvalue2s(L, L->top++, luaS_newlstr(L, str, l)); | 314 | setsvalue2s(L, L->top++, luaS_newlstr(L, str, l)); |
| 272 | } | 315 | } |
| 273 | 316 | ||
| 274 | 317 | ||
| 275 | /* this function handles only `%d', `%c', %f, %p, and `%s' formats */ | 318 | /* this function handles only '%d', '%c', '%f', '%p', and '%s' |
| 319 | conventional formats, plus Lua-specific '%L' and '%U' */ | ||
| 276 | const char *luaO_pushvfstring (lua_State *L, const char *fmt, va_list argp) { | 320 | const char *luaO_pushvfstring (lua_State *L, const char *fmt, va_list argp) { |
| 277 | int n = 0; | 321 | int n = 0; |
| 278 | for (;;) { | 322 | for (;;) { |
| @@ -311,6 +355,12 @@ const char *luaO_pushvfstring (lua_State *L, const char *fmt, va_list argp) { · 32 unmodified lines | |||
| 311 | pushstr(L, buff, l); | 355 | pushstr(L, buff, l); |
| 312 | break; | 356 | break; |
| 313 | } | 357 | } |
| 358 | case 'U': { | ||
| 359 | char buff[UTF8BUFFSZ]; | ||
| 360 | int l = luaO_utf8esc(buff, va_arg(argp, int)); | ||
| 361 | pushstr(L, buff + UTF8BUFFSZ - l, l); | ||
| 362 | break; | ||
| 363 | } | ||
| 314 | case '%': { | 364 | case '%': { |
| 315 | pushstr(L, "%", 1); | 365 | pushstr(L, "%", 1); |
| 316 | break; | 366 | break; |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lobject.h,v 2.78 2013/05/14 15:59:04 roberto Exp $ | 2 | ** $Id: lobject.h,v 2.86 2014/02/19 13:52:42 roberto Exp $ |
| 3 | ** Type definitions for Lua objects | 3 | ** Type definitions for Lua objects |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -20,13 +20,12 @@ · 14 unmodified lines | |||
| 20 | ** Extra tags for non-values | 20 | ** Extra tags for non-values |
| 21 | */ | 21 | */ |
| 22 | #define LUA_TPROTO LUA_NUMTAGS | 22 | #define LUA_TPROTO LUA_NUMTAGS |
| 23 | #define LUA_TUPVAL (LUA_NUMTAGS+1) | 23 | #define LUA_TDEADKEY (LUA_NUMTAGS+1) |
| 24 | #define LUA_TDEADKEY (LUA_NUMTAGS+2) | ||
| 25 | 24 | ||
| 26 | /* | 25 | /* |
| 27 | ** number of all possible tags (including LUA_TNONE but excluding DEADKEY) | 26 | ** number of all possible tags (including LUA_TNONE but excluding DEADKEY) |
| 28 | */ | 27 | */ |
| 29 | #define LUA_TOTALTAGS (LUA_TUPVAL+2) | 28 | #define LUA_TOTALTAGS (LUA_TPROTO + 2) |
| 30 | 29 | ||
| 31 | 30 | ||
| 32 | /* | 31 | /* |
| @@ -147,7 +146,7 @@ typedef struct lua_TValue TValue; · 114 unmodified lines | |||
| 147 | #define ttisCclosure(o) checktag((o), ctb(LUA_TCCL)) | 146 | #define ttisCclosure(o) checktag((o), ctb(LUA_TCCL)) |
| 148 | #define ttisLclosure(o) checktag((o), ctb(LUA_TLCL)) | 147 | #define ttisLclosure(o) checktag((o), ctb(LUA_TLCL)) |
| 149 | #define ttislcf(o) checktag((o), LUA_TLCF) | 148 | #define ttislcf(o) checktag((o), LUA_TLCF) |
| 150 | #define ttisuserdata(o) checktag((o), ctb(LUA_TUSERDATA)) | 149 | #define ttisfulluserdata(o) checktag((o), ctb(LUA_TUSERDATA)) |
| 151 | #define ttisthread(o) checktag((o), ctb(LUA_TTHREAD)) | 150 | #define ttisthread(o) checktag((o), ctb(LUA_TTHREAD)) |
| 152 | #define ttisdeadkey(o) checktag((o), LUA_TDEADKEY) | 151 | #define ttisdeadkey(o) checktag((o), LUA_TDEADKEY) |
| 153 | 152 | ||
| @@ -159,7 +158,7 @@ typedef struct lua_TValue TValue; · 5 unmodified lines | |||
| 159 | #define pvalue(o) check_exp(ttislightuserdata(o), val_(o).p) | 158 | #define pvalue(o) check_exp(ttislightuserdata(o), val_(o).p) |
| 160 | #define rawtsvalue(o) check_exp(ttisstring(o), &val_(o).gc->ts) | 159 | #define rawtsvalue(o) check_exp(ttisstring(o), &val_(o).gc->ts) |
| 161 | #define tsvalue(o) (&rawtsvalue(o)->tsv) | 160 | #define tsvalue(o) (&rawtsvalue(o)->tsv) |
| 162 | #define rawuvalue(o) check_exp(ttisuserdata(o), &val_(o).gc->u) | 161 | #define rawuvalue(o) check_exp(ttisfulluserdata(o), &val_(o).gc->u) |
| 163 | #define uvalue(o) (&rawuvalue(o)->uv) | 162 | #define uvalue(o) (&rawuvalue(o)->uv) |
| 164 | #define clvalue(o) check_exp(ttisclosure(o), &val_(o).gc->cl) | 163 | #define clvalue(o) check_exp(ttisclosure(o), &val_(o).gc->cl) |
| 165 | #define clLvalue(o) check_exp(ttisLclosure(o), &val_(o).gc->cl.l) | 164 | #define clLvalue(o) check_exp(ttisLclosure(o), &val_(o).gc->cl.l) |
| @@ -311,8 +310,9 @@ typedef union TString { · 145 unmodified lines | |||
| 311 | struct { | 310 | struct { |
| 312 | CommonHeader; | 311 | CommonHeader; |
| 313 | lu_byte extra; /* reserved words for short strings; "has hash" for longs */ | 312 | lu_byte extra; /* reserved words for short strings; "has hash" for longs */ |
| 314 | unsigned int hash; | ||
| 315 | size_t len; /* number of characters in string */ | 313 | size_t len; /* number of characters in string */ |
| 314 | union TString *hnext; /* linked list for hash table */ | ||
| 315 | unsigned int hash; | ||
| 316 | } tsv; | 316 | } tsv; |
| 317 | } TString; | 317 | } TString; |
| 318 | 318 | ||
| @@ -331,13 +331,25 @@ typedef union Udata { · 12 unmodified lines | |||
| 331 | L_Umaxalign dummy; /* ensures maximum alignment for `local' udata */ | 331 | L_Umaxalign dummy; /* ensures maximum alignment for `local' udata */ |
| 332 | struct { | 332 | struct { |
| 333 | CommonHeader; | 333 | CommonHeader; |
| 334 | lu_byte ttuv_; /* user value's tag */ | ||
| 334 | struct Table *metatable; | 335 | struct Table *metatable; |
| 335 | struct Table *env; | ||
| 336 | size_t len; /* number of bytes */ | 336 | size_t len; /* number of bytes */ |
| 337 | union Value user_; /* user value */ | ||
| 337 | } uv; | 338 | } uv; |
| 338 | } Udata; | 339 | } Udata; |
| 339 | 340 | ||
| 340 | 341 | ||
| 342 | #define setuservalue(L,u,o) \ | ||
| 343 | { const TValue *io=(o); Udata *iu = (u); \ | ||
| 344 | iu->uv.user_ = io->value_; iu->uv.ttuv_ = io->tt_; \ | ||
| 345 | checkliveness(G(L),io); } | ||
| 346 | |||
| 347 | |||
| 348 | #define getuservalue(L,u,o) \ | ||
| 349 | { TValue *io=(o); const Udata *iu = (u); \ | ||
| 350 | io->value_ = iu->uv.user_; io->tt_ = iu->uv.ttuv_; \ | ||
| 351 | checkliveness(G(L),io); } | ||
| 352 | |||
| 341 | 353 | ||
| 342 | /* | 354 | /* |
| 343 | ** Description of an upvalue for function prototypes | 355 | ** Description of an upvalue for function prototypes |
| @@ -392,17 +404,7 @@ typedef struct Proto { · 48 unmodified lines | |||
| 392 | /* | 404 | /* |
| 393 | ** Lua Upvalues | 405 | ** Lua Upvalues |
| 394 | */ | 406 | */ |
| 395 | typedef struct UpVal { | 407 | typedef struct UpVal UpVal; |
| 396 | CommonHeader; | ||
| 397 | TValue *v; /* points to stack or to its own value */ | ||
| 398 | union { | ||
| 399 | TValue value; /* the value (when closed) */ | ||
| 400 | struct { /* double linked list (when open) */ | ||
| 401 | struct UpVal *prev; | ||
| 402 | struct UpVal *next; | ||
| 403 | } l; | ||
| 404 | } u; | ||
| 405 | } UpVal; | ||
| 406 | 408 | ||
| 407 | 409 | ||
| 408 | /* | 410 | /* |
| @@ -444,7 +446,7 @@ typedef union Closure { · 35 unmodified lines | |||
| 444 | typedef union TKey { | 446 | typedef union TKey { |
| 445 | struct { | 447 | struct { |
| 446 | TValuefields; | 448 | TValuefields; |
| 447 | struct Node *next; /* for chaining */ | 449 | int next; /* for chaining (offset for next node) */ |
| 448 | } nk; | 450 | } nk; |
| 449 | TValue tvk; | 451 | TValue tvk; |
| 450 | } TKey; | 452 | } TKey; |
| @@ -489,9 +491,12 @@ typedef struct Table { · 38 unmodified lines | |||
| 489 | 491 | ||
| 490 | LUAI_DDEC const TValue luaO_nilobject_; | 492 | LUAI_DDEC const TValue luaO_nilobject_; |
| 491 | 493 | ||
| 494 | /* size of buffer for 'luaO_utf8esc' function */ | ||
| 495 | #define UTF8BUFFSZ 8 | ||
| 492 | 496 | ||
| 493 | LUAI_FUNC int luaO_int2fb (unsigned int x); | 497 | LUAI_FUNC int luaO_int2fb (unsigned int x); |
| 494 | LUAI_FUNC int luaO_fb2int (int x); | 498 | LUAI_FUNC int luaO_fb2int (int x); |
| 499 | LUAI_FUNC int luaO_utf8esc (char *buff, unsigned int x); | ||
| 495 | LUAI_FUNC int luaO_ceillog2 (unsigned int x); | 500 | LUAI_FUNC int luaO_ceillog2 (unsigned int x); |
| 496 | LUAI_FUNC void luaO_arith (lua_State *L, int op, const TValue *p1, | 501 | LUAI_FUNC void luaO_arith (lua_State *L, int op, const TValue *p1, |
| 497 | const TValue *p2, TValue *res); | 502 | const TValue *p2, TValue *res); |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lopcodes.c,v 1.50 2013/04/26 13:07:53 roberto Exp $ | 2 | ** $Id: lopcodes.c,v 1.53 2013/12/30 20:47:58 roberto Exp $ |
| 3 | ** Opcodes for Lua virtual machine | 3 | ** Opcodes for Lua virtual machine |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -31,11 +31,17 @@ LUAI_DDEF const char *const luaP_opnames[NUM_OPCODES+1] = { · 25 unmodified lines | |||
| 31 | "ADD", | 31 | "ADD", |
| 32 | "SUB", | 32 | "SUB", |
| 33 | "MUL", | 33 | "MUL", |
| 34 | "DIV", | ||
| 35 | "IDIV", | ||
| 36 | "MOD", | 34 | "MOD", |
| 37 | "POW", | 35 | "POW", |
| 36 | "DIV", | ||
| 37 | "IDIV", | ||
| 38 | "BAND", | ||
| 39 | "BOR", | ||
| 40 | "BXOR", | ||
| 41 | "SHL", | ||
| 42 | "SHR", | ||
| 38 | "UNM", | 43 | "UNM", |
| 44 | "BNOT", | ||
| 39 | "NOT", | 45 | "NOT", |
| 40 | "LEN", | 46 | "LEN", |
| 41 | "CONCAT", | 47 | "CONCAT", |
| @@ -80,11 +86,17 @@ LUAI_DDEF const lu_byte luaP_opmodes[NUM_OPCODES] = { · 38 unmodified lines | |||
| 80 | ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_ADD */ | 86 | ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_ADD */ |
| 81 | ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_SUB */ | 87 | ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_SUB */ |
| 82 | ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_MUL */ | 88 | ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_MUL */ |
| 83 | ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_DIV */ | ||
| 84 | ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_IDIV */ | ||
| 85 | ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_MOD */ | 89 | ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_MOD */ |
| 86 | ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_POW */ | 90 | ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_POW */ |
| 91 | ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_DIV */ | ||
| 92 | ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_IDIV */ | ||
| 93 | ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_BAND */ | ||
| 94 | ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_BOR */ | ||
| 95 | ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_BXOR */ | ||
| 96 | ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_SHL */ | ||
| 97 | ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_SHR */ | ||
| 87 | ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_UNM */ | 98 | ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_UNM */ |
| 99 | ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_BNOT */ | ||
| 88 | ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_NOT */ | 100 | ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_NOT */ |
| 89 | ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_LEN */ | 101 | ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_LEN */ |
| 90 | ,opmode(0, 1, OpArgR, OpArgR, iABC) /* OP_CONCAT */ | 102 | ,opmode(0, 1, OpArgR, OpArgR, iABC) /* OP_CONCAT */ |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lopcodes.h,v 1.143 2013/04/26 13:07:53 roberto Exp $ | 2 | ** $Id: lopcodes.h,v 1.146 2013/12/30 20:47:58 roberto Exp $ |
| 3 | ** Opcodes for Lua virtual machine | 3 | ** Opcodes for Lua virtual machine |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -187,11 +187,17 @@ OP_SELF,/* A B C R(A+1) := R(B); R(A) := R(B)[RK(C)] */ · 181 unmodified lines | |||
| 187 | OP_ADD,/* A B C R(A) := RK(B) + RK(C) */ | 187 | OP_ADD,/* A B C R(A) := RK(B) + RK(C) */ |
| 188 | OP_SUB,/* A B C R(A) := RK(B) - RK(C) */ | 188 | OP_SUB,/* A B C R(A) := RK(B) - RK(C) */ |
| 189 | OP_MUL,/* A B C R(A) := RK(B) * RK(C) */ | 189 | OP_MUL,/* A B C R(A) := RK(B) * RK(C) */ |
| 190 | OP_DIV,/* A B C R(A) := RK(B) / RK(C) */ | ||
| 191 | OP_IDIV,/* A B C R(A) := RK(B) // RK(C) */ | ||
| 192 | OP_MOD,/* A B C R(A) := RK(B) % RK(C) */ | 190 | OP_MOD,/* A B C R(A) := RK(B) % RK(C) */ |
| 193 | OP_POW,/* A B C R(A) := RK(B) ^ RK(C) */ | 191 | OP_POW,/* A B C R(A) := RK(B) ^ RK(C) */ |
| 192 | OP_DIV,/* A B C R(A) := RK(B) / RK(C) */ | ||
| 193 | OP_IDIV,/* A B C R(A) := RK(B) // RK(C) */ | ||
| 194 | OP_BAND,/* A B C R(A) := RK(B) & RK(C) */ | ||
| 195 | OP_BOR,/* A B C R(A) := RK(B) | RK(C) */ | ||
| 196 | OP_BXOR,/* A B C R(A) := RK(B) ~ RK(C) */ | ||
| 197 | OP_SHL,/* A B C R(A) := RK(B) << RK(C) */ | ||
| 198 | OP_SHR,/* A B C R(A) := RK(B) >> RK(C) */ | ||
| 194 | OP_UNM,/* A B R(A) := -R(B) */ | 199 | OP_UNM,/* A B R(A) := -R(B) */ |
| 200 | OP_BNOT,/* A B R(A) := ~R(B) */ | ||
| 195 | OP_NOT,/* A B R(A) := not R(B) */ | 201 | OP_NOT,/* A B R(A) := not R(B) */ |
| 196 | OP_LEN,/* A B R(A) := length of R(B) */ | 202 | OP_LEN,/* A B R(A) := length of R(B) */ |
| 197 | 203 | ||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: loslib.c,v 1.41 2013/05/14 15:57:11 roberto Exp $ | 2 | ** $Id: loslib.c,v 1.45 2014/03/20 19:18:54 roberto Exp $ |
| 3 | ** Standard Operating System library | 3 | ** Standard Operating System library |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -20,29 +20,44 @@ · 14 unmodified lines | |||
| 20 | #include "lualib.h" | 20 | #include "lualib.h" |
| 21 | 21 | ||
| 22 | 22 | ||
| 23 | #if !defined(LUA_STRFTIMEOPTIONS) /* { */ | ||
| 23 | /* | 24 | /* |
| 24 | ** list of valid conversion specifiers for the 'strftime' function | 25 | ** list of valid conversion specifiers for the 'strftime' function |
| 25 | */ | 26 | */ |
| 26 | #if !defined(LUA_STRFTIMEOPTIONS) | ||
| 27 | 27 | ||
| 28 | #if !defined(LUA_USE_POSIX) | 28 | #if !defined(LUA_USE_POSIX) |
| 29 | #define LUA_STRFTIMEOPTIONS { "aAbBcdHIjmMpSUwWxXyYz%", "" } | 29 | #define LUA_STRFTIMEOPTIONS { "aAbBcdHIjmMpSUwWxXyYz%", "" } |
| 30 | #else | 30 | #else |
| 31 | #define LUA_STRFTIMEOPTIONS \ | 31 | #define LUA_STRFTIMEOPTIONS \ |
| 32 | { "aAbBcCdDeFgGhHIjmMnprRStTuUVwWxXyYzZ%", "" \ | 32 | { "aAbBcCdDeFgGhHIjmMnprRStTuUVwWxXyYzZ%", "", \ |
| 33 | "", "E", "cCxXyY", \ | 33 | "E", "cCxXyY", \ |
| 34 | "O", "deHImMSuUVwWy" } | 34 | "O", "deHImMSuUVwWy" } |
| 35 | #endif | 35 | #endif |
| 36 | 36 | ||
| 37 | #endif | 37 | #endif /* } */ |
| 38 | |||
| 39 | |||
| 40 | |||
| 41 | #if !defined(l_time_t) /* { */ | ||
| 42 | /* | ||
| 43 | ** type to represent time_t in Lua | ||
| 44 | */ | ||
| 45 | #define l_timet lua_Integer | ||
| 46 | #define l_pushtime(L,t) lua_pushinteger(L,(lua_Integer)(t)) | ||
| 47 | #define l_checktime(L,a) ((time_t)luaL_checkinteger(L,a)) | ||
| 38 | 48 | ||
| 49 | #endif /* } */ | ||
| 39 | 50 | ||
| 40 | 51 | ||
| 52 | |||
| 53 | #if !defined(lua_tmpnam) /* { */ | ||
| 41 | /* | 54 | /* |
| 42 | ** By default, Lua uses tmpnam except when POSIX is available, where it | 55 | ** By default, Lua uses tmpnam except when POSIX is available, where it |
| 43 | ** uses mkstemp. | 56 | ** uses mkstemp. |
| 44 | */ | 57 | */ |
| 45 | #if defined(LUA_USE_MKSTEMP) | 58 | |
| 59 | #if defined(LUA_USE_POSIX) /* { */ | ||
| 60 | |||
| 46 | #include <unistd.h> | 61 | #include <unistd.h> |
| 47 | #define LUA_TMPNAMBUFSIZE 32 | 62 | #define LUA_TMPNAMBUFSIZE 32 |
| 48 | #define lua_tmpnam(b,e) { \ | 63 | #define lua_tmpnam(b,e) { \ |
| @@ -51,29 +66,38 @@ · 2 unmodified lines | |||
| 51 | if (e != -1) close(e); \ | 66 | if (e != -1) close(e); \ |
| 52 | e = (e == -1); } | 67 | e = (e == -1); } |
| 53 | 68 | ||
| 54 | #elif !defined(lua_tmpnam) | 69 | #else /* }{ */ |
| 55 | 70 | ||
| 71 | /* ANSI definitions */ | ||
| 56 | #define LUA_TMPNAMBUFSIZE L_tmpnam | 72 | #define LUA_TMPNAMBUFSIZE L_tmpnam |
| 57 | #define lua_tmpnam(b,e) { e = (tmpnam(b) == NULL); } | 73 | #define lua_tmpnam(b,e) { e = (tmpnam(b) == NULL); } |
| 58 | 74 | ||
| 59 | #endif | 75 | #endif /* } */ |
| 76 | |||
| 77 | #endif /* } */ | ||
| 78 | |||
| 60 | 79 | ||
| 61 | 80 | ||
| 81 | #if !defined(l_gmtime) /* { */ | ||
| 62 | /* | 82 | /* |
| 63 | ** By default, Lua uses gmtime/localtime, except when POSIX is available, | 83 | ** By default, Lua uses gmtime/localtime, except when POSIX is available, |
| 64 | ** where it uses gmtime_r/localtime_r | 84 | ** where it uses gmtime_r/localtime_r |
| 65 | */ | 85 | */ |
| 66 | #if defined(LUA_USE_GMTIME_R) | 86 | |
| 87 | #if defined(LUA_USE_POSIX) /* { */ | ||
| 67 | 88 | ||
| 68 | #define l_gmtime(t,r) gmtime_r(t,r) | 89 | #define l_gmtime(t,r) gmtime_r(t,r) |
| 69 | #define l_localtime(t,r) localtime_r(t,r) | 90 | #define l_localtime(t,r) localtime_r(t,r) |
| 70 | 91 | ||
| 71 | #elif !defined(l_gmtime) | 92 | #else /* }{ */ |
| 72 | 93 | ||
| 94 | /* ANSI definitions */ | ||
| 73 | #define l_gmtime(t,r) ((void)r, gmtime(t)) | 95 | #define l_gmtime(t,r) ((void)r, gmtime(t)) |
| 74 | #define l_localtime(t,r) ((void)r, localtime(t)) | 96 | #define l_localtime(t,r) ((void)r, localtime(t)) |
| 75 | 97 | ||
| 76 | #endif | 98 | #endif /* } */ |
| 99 | |||
| 100 | #endif /* } */ | ||
| 77 | 101 | ||
| 78 | 102 | ||
| 79 | 103 | ||
| @@ -147,8 +171,7 @@ static void setboolfield (lua_State *L, const char *key, int value) { · 67 unmodified lines | |||
| 147 | 171 | ||
| 148 | static int getboolfield (lua_State *L, const char *key) { | 172 | static int getboolfield (lua_State *L, const char *key) { |
| 149 | int res; | 173 | int res; |
| 150 | lua_getfield(L, -1, key); | 174 | res = (lua_getfield(L, -1, key) == LUA_TNIL) ? -1 : lua_toboolean(L, -1); |
| 151 | res = lua_isnil(L, -1) ? -1 : lua_toboolean(L, -1); | ||
| 152 | lua_pop(L, 1); | 175 | lua_pop(L, 1); |
| 153 | return res; | 176 | return res; |
| 154 | } | 177 | } |
| @@ -194,7 +217,7 @@ static const char *checkoption (lua_State *L, const char *conv, char *buff) { · 39 unmodified lines | |||
| 194 | 217 | ||
| 195 | static int os_date (lua_State *L) { | 218 | static int os_date (lua_State *L) { |
| 196 | const char *s = luaL_optstring(L, 1, "%c"); | 219 | const char *s = luaL_optstring(L, 1, "%c"); |
| 197 | time_t t = luaL_opt(L, (time_t)luaL_checkinteger, 2, time(NULL)); | 220 | time_t t = luaL_opt(L, l_checktime, 2, time(NULL)); |
| 198 | struct tm tmr, *stm; | 221 | struct tm tmr, *stm; |
| 199 | if (*s == '!') { /* UTC? */ | 222 | if (*s == '!') { /* UTC? */ |
| 200 | stm = l_gmtime(&t, &tmr); | 223 | stm = l_gmtime(&t, &tmr); |
| @@ -255,17 +278,18 @@ static int os_time (lua_State *L) { · 54 unmodified lines | |||
| 255 | ts.tm_isdst = getboolfield(L, "isdst"); | 278 | ts.tm_isdst = getboolfield(L, "isdst"); |
| 256 | t = mktime(&ts); | 279 | t = mktime(&ts); |
| 257 | } | 280 | } |
| 258 | if (t == (time_t)(-1)) | 281 | if (t != (time_t)(l_timet)t) |
| 282 | luaL_error(L, "time result cannot be represented in this Lua instalation"); | ||
| 283 | else if (t == (time_t)(-1)) | ||
| 259 | lua_pushnil(L); | 284 | lua_pushnil(L); |
| 260 | else | 285 | else |
| 261 | lua_pushinteger(L, t); | 286 | l_pushtime(L, t); |
| 262 | return 1; | 287 | return 1; |
| 263 | } | 288 | } |
| 264 | 289 | ||
| 265 | 290 | ||
| 266 | static int os_difftime (lua_State *L) { | 291 | static int os_difftime (lua_State *L) { |
| 267 | lua_pushnumber(L, difftime((time_t)(luaL_checkinteger(L, 1)), | 292 | lua_pushnumber(L, difftime((l_checktime(L, 1)), (l_checktime(L, 2)))); |
| 268 | (time_t)(luaL_optinteger(L, 2, 0)))); | ||
| 269 | return 1; | 293 | return 1; |
| 270 | } | 294 | } |
| 271 | 295 | ||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lparser.c,v 2.133 2013/04/26 13:07:53 roberto Exp $ | 2 | ** $Id: lparser.c,v 2.138 2013/12/30 20:47:58 roberto Exp $ |
| 3 | ** Lua Parser | 3 | ** Lua Parser |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -35,6 +35,10 @@ · 29 unmodified lines | |||
| 35 | #define hasmultret(k) ((k) == VCALL || (k) == VVARARG) | 35 | #define hasmultret(k) ((k) == VCALL || (k) == VVARARG) |
| 36 | 36 | ||
| 37 | 37 | ||
| 38 | /* because all strings are unified by the scanner, the parser | ||
| 39 | can use pointer equality for string equality */ | ||
| 40 | #define eqstr(a,b) ((a) == (b)) | ||
| 41 | |||
| 38 | 42 | ||
| 39 | /* | 43 | /* |
| 40 | ** nodes for block list (list of active blocks) | 44 | ** nodes for block list (list of active blocks) |
| @@ -57,16 +61,6 @@ static void statement (LexState *ls); · 16 unmodified lines | |||
| 57 | static void expr (LexState *ls, expdesc *v); | 61 | static void expr (LexState *ls, expdesc *v); |
| 58 | 62 | ||
| 59 | 63 | ||
| 60 | static void anchor_token (LexState *ls) { | ||
| 61 | /* last token from outer function must be EOS */ | ||
| 62 | lua_assert(ls->fs != NULL || ls->t.token == TK_EOS); | ||
| 63 | if (ls->t.token == TK_NAME || ls->t.token == TK_STRING) { | ||
| 64 | TString *ts = ls->t.seminfo.ts; | ||
| 65 | luaX_newstring(ls, getstr(ts), ts->tsv.len); | ||
| 66 | } | ||
| 67 | } | ||
| 68 | |||
| 69 | |||
| 70 | /* semantic error */ | 64 | /* semantic error */ |
| 71 | static l_noret semerror (LexState *ls, const char *msg) { | 65 | static l_noret semerror (LexState *ls, const char *msg) { |
| 72 | ls->t.token = 0; /* remove 'near to' from final message */ | 66 | ls->t.token = 0; /* remove 'near to' from final message */ |
| @@ -222,7 +216,7 @@ static int searchupvalue (FuncState *fs, TString *name) { · 149 unmodified lines | |||
| 222 | int i; | 216 | int i; |
| 223 | Upvaldesc *up = fs->f->upvalues; | 217 | Upvaldesc *up = fs->f->upvalues; |
| 224 | for (i = 0; i < fs->nups; i++) { | 218 | for (i = 0; i < fs->nups; i++) { |
| 225 | if (luaS_eqstr(up[i].name, name)) return i; | 219 | if (eqstr(up[i].name, name)) return i; |
| 226 | } | 220 | } |
| 227 | return -1; /* not found */ | 221 | return -1; /* not found */ |
| 228 | } | 222 | } |
| @@ -246,7 +240,7 @@ static int newupvalue (FuncState *fs, TString *name, expdesc *v) { · 17 unmodified lines | |||
| 246 | static int searchvar (FuncState *fs, TString *n) { | 240 | static int searchvar (FuncState *fs, TString *n) { |
| 247 | int i; | 241 | int i; |
| 248 | for (i = cast_int(fs->nactvar) - 1; i >= 0; i--) { | 242 | for (i = cast_int(fs->nactvar) - 1; i >= 0; i--) { |
| 249 | if (luaS_eqstr(n, getlocvar(fs, i)->varname)) | 243 | if (eqstr(n, getlocvar(fs, i)->varname)) |
| 250 | return i; | 244 | return i; |
| 251 | } | 245 | } |
| 252 | return -1; /* not found */ | 246 | return -1; /* not found */ |
| @@ -342,7 +336,7 @@ static void closegoto (LexState *ls, int g, Labeldesc *label) { · 89 unmodified lines | |||
| 342 | FuncState *fs = ls->fs; | 336 | FuncState *fs = ls->fs; |
| 343 | Labellist *gl = &ls->dyd->gt; | 337 | Labellist *gl = &ls->dyd->gt; |
| 344 | Labeldesc *gt = &gl->arr[g]; | 338 | Labeldesc *gt = &gl->arr[g]; |
| 345 | lua_assert(luaS_eqstr(gt->name, label->name)); | 339 | lua_assert(eqstr(gt->name, label->name)); |
| 346 | if (gt->nactvar < label->nactvar) { | 340 | if (gt->nactvar < label->nactvar) { |
| 347 | TString *vname = getlocvar(fs, gt->nactvar)->varname; | 341 | TString *vname = getlocvar(fs, gt->nactvar)->varname; |
| 348 | const char *msg = luaO_pushfstring(ls->L, | 342 | const char *msg = luaO_pushfstring(ls->L, |
| @@ -369,7 +363,7 @@ static int findlabel (LexState *ls, int g) { · 20 unmodified lines | |||
| 369 | /* check labels in current block for a match */ | 363 | /* check labels in current block for a match */ |
| 370 | for (i = bl->firstlabel; i < dyd->label.n; i++) { | 364 | for (i = bl->firstlabel; i < dyd->label.n; i++) { |
| 371 | Labeldesc *lb = &dyd->label.arr[i]; | 365 | Labeldesc *lb = &dyd->label.arr[i]; |
| 372 | if (luaS_eqstr(lb->name, gt->name)) { /* correct label? */ | 366 | if (eqstr(lb->name, gt->name)) { /* correct label? */ |
| 373 | if (gt->nactvar > lb->nactvar && | 367 | if (gt->nactvar > lb->nactvar && |
| 374 | (bl->upval || dyd->label.n > bl->firstlabel)) | 368 | (bl->upval || dyd->label.n > bl->firstlabel)) |
| 375 | luaK_patchclose(ls->fs, gt->pc, lb->nactvar); | 369 | luaK_patchclose(ls->fs, gt->pc, lb->nactvar); |
| @@ -403,7 +397,7 @@ static void findgotos (LexState *ls, Labeldesc *lb) { · 27 unmodified lines | |||
| 403 | Labellist *gl = &ls->dyd->gt; | 397 | Labellist *gl = &ls->dyd->gt; |
| 404 | int i = ls->fs->bl->firstgoto; | 398 | int i = ls->fs->bl->firstgoto; |
| 405 | while (i < gl->n) { | 399 | while (i < gl->n) { |
| 406 | if (luaS_eqstr(gl->arr[i].name, lb->name)) | 400 | if (eqstr(gl->arr[i].name, lb->name)) |
| 407 | closegoto(ls, i, lb); | 401 | closegoto(ls, i, lb); |
| 408 | else | 402 | else |
| 409 | i++; | 403 | i++; |
| @@ -525,7 +519,6 @@ static void codeclosure (LexState *ls, expdesc *v) { · 115 unmodified lines | |||
| 525 | 519 | ||
| 526 | 520 | ||
| 527 | static void open_func (LexState *ls, FuncState *fs, BlockCnt *bl) { | 521 | static void open_func (LexState *ls, FuncState *fs, BlockCnt *bl) { |
| 528 | lua_State *L = ls->L; | ||
| 529 | Proto *f; | 522 | Proto *f; |
| 530 | fs->prev = ls->fs; /* linked list of funcstates */ | 523 | fs->prev = ls->fs; /* linked list of funcstates */ |
| 531 | fs->ls = ls; | 524 | fs->ls = ls; |
| @@ -544,10 +537,6 @@ static void open_func (LexState *ls, FuncState *fs, BlockCnt *bl) { · 12 unmodified lines | |||
| 544 | f = fs->f; | 537 | f = fs->f; |
| 545 | f->source = ls->source; | 538 | f->source = ls->source; |
| 546 | f->maxstacksize = 2; /* registers 0/1 are always valid */ | 539 | f->maxstacksize = 2; /* registers 0/1 are always valid */ |
| 547 | fs->h = luaH_new(L); | ||
| 548 | /* anchor table of constants (to avoid being collected) */ | ||
| 549 | sethvalue2s(L, L->top, fs->h); | ||
| 550 | incr_top(L); | ||
| 551 | enterblock(fs, bl, 0); | 540 | enterblock(fs, bl, 0); |
| 552 | } | 541 | } |
| 553 | 542 | ||
| @@ -572,9 +561,6 @@ static void close_func (LexState *ls) { · 18 unmodified lines | |||
| 572 | f->sizeupvalues = fs->nups; | 561 | f->sizeupvalues = fs->nups; |
| 573 | lua_assert(fs->bl == NULL); | 562 | lua_assert(fs->bl == NULL); |
| 574 | ls->fs = fs->prev; | 563 | ls->fs = fs->prev; |
| 575 | /* last token read was anchored in defunct function; must re-anchor it */ | ||
| 576 | anchor_token(ls); | ||
| 577 | L->top--; /* pop table of constants */ | ||
| 578 | luaC_checkGC(L); | 564 | luaC_checkGC(L); |
| 579 | } | 565 | } |
| 580 | 566 | ||
| @@ -993,6 +979,7 @@ static UnOpr getunopr (int op) { · 412 unmodified lines | |||
| 993 | switch (op) { | 979 | switch (op) { |
| 994 | case TK_NOT: return OPR_NOT; | 980 | case TK_NOT: return OPR_NOT; |
| 995 | case '-': return OPR_MINUS; | 981 | case '-': return OPR_MINUS; |
| 982 | case '~': return OPR_BNOT; | ||
| 996 | case '#': return OPR_LEN; | 983 | case '#': return OPR_LEN; |
| 997 | default: return OPR_NOUNOPR; | 984 | default: return OPR_NOUNOPR; |
| 998 | } | 985 | } |
| @@ -1004,10 +991,15 @@ static BinOpr getbinopr (int op) { · 5 unmodified lines | |||
| 1004 | case '+': return OPR_ADD; | 991 | case '+': return OPR_ADD; |
| 1005 | case '-': return OPR_SUB; | 992 | case '-': return OPR_SUB; |
| 1006 | case '*': return OPR_MUL; | 993 | case '*': return OPR_MUL; |
| 1007 | case '/': return OPR_DIV; | ||
| 1008 | case TK_IDIV: return OPR_IDIV; | ||
| 1009 | case '%': return OPR_MOD; | 994 | case '%': return OPR_MOD; |
| 1010 | case '^': return OPR_POW; | 995 | case '^': return OPR_POW; |
| 996 | case '/': return OPR_DIV; | ||
| 997 | case TK_IDIV: return OPR_IDIV; | ||
| 998 | case '&': return OPR_BAND; | ||
| 999 | case '|': return OPR_BOR; | ||
| 1000 | case '~': return OPR_BXOR; | ||
| 1001 | case TK_SHL: return OPR_SHL; | ||
| 1002 | case TK_SHR: return OPR_SHR; | ||
| 1011 | case TK_CONCAT: return OPR_CONCAT; | 1003 | case TK_CONCAT: return OPR_CONCAT; |
| 1012 | case TK_NE: return OPR_NE; | 1004 | case TK_NE: return OPR_NE; |
| 1013 | case TK_EQ: return OPR_EQ; | 1005 | case TK_EQ: return OPR_EQ; |
| @@ -1026,15 +1018,19 @@ static const struct { · 12 unmodified lines | |||
| 1026 | lu_byte left; /* left priority for each binary operator */ | 1018 | lu_byte left; /* left priority for each binary operator */ |
| 1027 | lu_byte right; /* right priority */ | 1019 | lu_byte right; /* right priority */ |
| 1028 | } priority[] = { /* ORDER OPR */ | 1020 | } priority[] = { /* ORDER OPR */ |
| 1029 | {6, 6}, {6, 6}, /* '+' '-' */ | 1021 | {10, 10}, {10, 10}, /* '+' '-' */ |
| 1030 | {7, 7}, {7, 7}, {7, 7}, {7, 7}, /* '*' '/' '//' '%' */ | 1022 | {11, 11}, {11, 11}, /* '*' '%' */ |
| 1031 | {10, 9}, {5, 4}, /* ^, .. (right associative) */ | 1023 | {14, 13}, /* '^' (right associative) */ |
| 1032 | {3, 3}, {3, 3}, {3, 3}, /* ==, <, <= */ | 1024 | {11, 11}, {11, 11}, /* '/' '//' */ |
| 1033 | {3, 3}, {3, 3}, {3, 3}, /* ~=, >, >= */ | 1025 | {6, 6}, {4, 4}, {5, 5}, /* '&' '|' '~' */ |
| 1034 | {2, 2}, {1, 1} /* and, or */ | 1026 | {7, 7}, {7, 7}, /* '<<' '>>' */ |
| 1027 | {9, 8}, /* '..' (right associative) */ | ||
| 1028 | {3, 3}, {3, 3}, {3, 3}, /* ==, <, <= */ | ||
| 1029 | {3, 3}, {3, 3}, {3, 3}, /* ~=, >, >= */ | ||
| 1030 | {2, 2}, {1, 1} /* and, or */ | ||
| 1035 | }; | 1031 | }; |
| 1036 | 1032 | ||
| 1037 | #define UNARY_PRIORITY 8 /* priority for unary operators */ | 1033 | #define UNARY_PRIORITY 12 /* priority for unary operators */ |
| 1038 | 1034 | ||
| 1039 | 1035 | ||
| 1040 | /* | 1036 | /* |
| @@ -1202,7 +1198,7 @@ static void gotostat (LexState *ls, int pc) { · 161 unmodified lines | |||
| 1202 | static void checkrepeated (FuncState *fs, Labellist *ll, TString *label) { | 1198 | static void checkrepeated (FuncState *fs, Labellist *ll, TString *label) { |
| 1203 | int i; | 1199 | int i; |
| 1204 | for (i = fs->bl->firstlabel; i < ll->n; i++) { | 1200 | for (i = fs->bl->firstlabel; i < ll->n; i++) { |
| 1205 | if (luaS_eqstr(label, ll->arr[i].name)) { | 1201 | if (eqstr(label, ll->arr[i].name)) { |
| 1206 | const char *msg = luaO_pushfstring(fs->ls->L, | 1202 | const char *msg = luaO_pushfstring(fs->ls->L, |
| 1207 | "label " LUA_QS " already defined on line %d", | 1203 | "label " LUA_QS " already defined on line %d", |
| 1208 | getstr(label), ll->arr[i].line); | 1204 | getstr(label), ll->arr[i].line); |
| @@ -1627,11 +1623,14 @@ Closure *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff, · 418 unmodified lines | |||
| 1627 | LexState lexstate; | 1623 | LexState lexstate; |
| 1628 | FuncState funcstate; | 1624 | FuncState funcstate; |
| 1629 | Closure *cl = luaF_newLclosure(L, 1); /* create main closure */ | 1625 | Closure *cl = luaF_newLclosure(L, 1); /* create main closure */ |
| 1630 | /* anchor closure (to avoid being collected) */ | 1626 | setclLvalue(L, L->top, cl); /* anchor it (to avoid being collected) */ |
| 1631 | setclLvalue(L, L->top, cl); | 1627 | incr_top(L); |
| 1628 | lexstate.h = luaH_new(L); /* create table for scanner */ | ||
| 1629 | sethvalue(L, L->top, lexstate.h); /* anchor it */ | ||
| 1632 | incr_top(L); | 1630 | incr_top(L); |
| 1633 | funcstate.f = cl->l.p = luaF_newproto(L); | 1631 | funcstate.f = cl->l.p = luaF_newproto(L); |
| 1634 | funcstate.f->source = luaS_new(L, name); /* create and anchor TString */ | 1632 | funcstate.f->source = luaS_new(L, name); /* create and anchor TString */ |
| 1633 | luaC_objbarrier(L, funcstate.f, funcstate.f->source); | ||
| 1635 | lexstate.buff = buff; | 1634 | lexstate.buff = buff; |
| 1636 | lexstate.dyd = dyd; | 1635 | lexstate.dyd = dyd; |
| 1637 | dyd->actvar.n = dyd->gt.n = dyd->label.n = 0; | 1636 | dyd->actvar.n = dyd->gt.n = dyd->label.n = 0; |
| @@ -1640,6 +1639,7 @@ Closure *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff, · 2 unmodified lines | |||
| 1640 | lua_assert(!funcstate.prev && funcstate.nups == 1 && !lexstate.fs); | 1639 | lua_assert(!funcstate.prev && funcstate.nups == 1 && !lexstate.fs); |
| 1641 | /* all scopes should be correctly finished */ | 1640 | /* all scopes should be correctly finished */ |
| 1642 | lua_assert(dyd->actvar.n == 0 && dyd->gt.n == 0 && dyd->label.n == 0); | 1641 | lua_assert(dyd->actvar.n == 0 && dyd->gt.n == 0 && dyd->label.n == 0); |
| 1643 | return cl; /* it's on the stack too */ | 1642 | L->top--; /* remove scanner's table */ |
| 1643 | return cl; /* closure is on the stack, too */ | ||
| 1644 | } | 1644 | } |
| 1645 | 1645 | ||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lparser.h,v 1.71 2013/04/16 18:46:28 roberto Exp $ | 2 | ** $Id: lparser.h,v 1.72 2013/08/30 16:01:37 roberto Exp $ |
| 3 | ** Lua Parser | 3 | ** Lua Parser |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -97,7 +97,6 @@ struct BlockCnt; /* defined in lparser.c */ · 91 unmodified lines | |||
| 97 | /* state needed to generate code for a given function */ | 97 | /* state needed to generate code for a given function */ |
| 98 | typedef struct FuncState { | 98 | typedef struct FuncState { |
| 99 | Proto *f; /* current function header */ | 99 | Proto *f; /* current function header */ |
| 100 | Table *h; /* table to find (and reuse) elements in `k' */ | ||
| 101 | struct FuncState *prev; /* enclosing function */ | 100 | struct FuncState *prev; /* enclosing function */ |
| 102 | struct LexState *ls; /* lexical state */ | 101 | struct LexState *ls; /* lexical state */ |
| 103 | struct BlockCnt *bl; /* chain of current blocks */ | 102 | struct BlockCnt *bl; /* chain of current blocks */ |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lstate.c,v 2.99 2012/10/02 17:40:53 roberto Exp $ | 2 | ** $Id: lstate.c,v 2.121 2014/02/18 13:46:26 roberto Exp $ |
| 3 | ** Global State | 3 | ** Global State |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -30,10 +30,6 @@ · 24 unmodified lines | |||
| 30 | #define LUAI_GCPAUSE 200 /* 200% */ | 30 | #define LUAI_GCPAUSE 200 /* 200% */ |
| 31 | #endif | 31 | #endif |
| 32 | 32 | ||
| 33 | #if !defined(LUAI_GCMAJOR) | ||
| 34 | #define LUAI_GCMAJOR 200 /* 200% */ | ||
| 35 | #endif | ||
| 36 | |||
| 37 | #if !defined(LUAI_GCMUL) | 33 | #if !defined(LUAI_GCMUL) |
| 38 | #define LUAI_GCMUL 200 /* GC runs 'twice the speed' of memory allocation */ | 34 | #define LUAI_GCMUL 200 /* GC runs 'twice the speed' of memory allocation */ |
| 39 | #endif | 35 | #endif |
| @@ -119,6 +115,9 @@ CallInfo *luaE_extendCI (lua_State *L) { · 79 unmodified lines | |||
| 119 | } | 115 | } |
| 120 | 116 | ||
| 121 | 117 | ||
| 118 | /* | ||
| 119 | ** free all CallInfo structures not in use by a thread | ||
| 120 | */ | ||
| 122 | void luaE_freeCI (lua_State *L) { | 121 | void luaE_freeCI (lua_State *L) { |
| 123 | CallInfo *ci = L->ci; | 122 | CallInfo *ci = L->ci; |
| 124 | CallInfo *next = ci->next; | 123 | CallInfo *next = ci->next; |
| @@ -130,6 +129,22 @@ void luaE_freeCI (lua_State *L) { · 5 unmodified lines | |||
| 130 | } | 129 | } |
| 131 | 130 | ||
| 132 | 131 | ||
| 132 | /* | ||
| 133 | ** free half of the CallInfo structures not in use by a thread | ||
| 134 | */ | ||
| 135 | void luaE_shrinkCI (lua_State *L) { | ||
| 136 | CallInfo *ci = L->ci; | ||
| 137 | while (ci->next != NULL) { /* while there is 'next' */ | ||
| 138 | CallInfo *next2 = ci->next->next; /* next's next */ | ||
| 139 | if (next2 == NULL) break; | ||
| 140 | luaM_free(L, ci->next); /* remove next */ | ||
| 141 | ci->next = next2; /* remove 'next' from the list */ | ||
| 142 | next2->previous = ci; | ||
| 143 | ci = next2; | ||
| 144 | } | ||
| 145 | } | ||
| 146 | |||
| 147 | |||
| 133 | static void stack_init (lua_State *L1, lua_State *L) { | 148 | static void stack_init (lua_State *L1, lua_State *L) { |
| 134 | int i; CallInfo *ci; | 149 | int i; CallInfo *ci; |
| 135 | /* initialize stack array */ | 150 | /* initialize stack array */ |
| @@ -163,22 +178,23 @@ static void freestack (lua_State *L) { · 27 unmodified lines | |||
| 163 | ** Create registry table and its predefined values | 178 | ** Create registry table and its predefined values |
| 164 | */ | 179 | */ |
| 165 | static void init_registry (lua_State *L, global_State *g) { | 180 | static void init_registry (lua_State *L, global_State *g) { |
| 166 | TValue mt; | 181 | TValue temp; |
| 167 | /* create registry */ | 182 | /* create registry */ |
| 168 | Table *registry = luaH_new(L); | 183 | Table *registry = luaH_new(L); |
| 169 | sethvalue(L, &g->l_registry, registry); | 184 | sethvalue(L, &g->l_registry, registry); |
| 170 | luaH_resize(L, registry, LUA_RIDX_LAST, 0); | 185 | luaH_resize(L, registry, LUA_RIDX_LAST, 0); |
| 171 | /* registry[LUA_RIDX_MAINTHREAD] = L */ | 186 | /* registry[LUA_RIDX_MAINTHREAD] = L */ |
| 172 | setthvalue(L, &mt, L); | 187 | setthvalue(L, &temp, L); /* temp = L */ |
| 173 | luaH_setint(L, registry, LUA_RIDX_MAINTHREAD, &mt); | 188 | luaH_setint(L, registry, LUA_RIDX_MAINTHREAD, &temp); |
| 174 | /* registry[LUA_RIDX_GLOBALS] = table of globals */ | 189 | /* registry[LUA_RIDX_GLOBALS] = table of globals */ |
| 175 | sethvalue(L, &mt, luaH_new(L)); | 190 | sethvalue(L, &temp, luaH_new(L)); /* temp = new table (global table) */ |
| 176 | luaH_setint(L, registry, LUA_RIDX_GLOBALS, &mt); | 191 | luaH_setint(L, registry, LUA_RIDX_GLOBALS, &temp); |
| 177 | } | 192 | } |
| 178 | 193 | ||
| 179 | 194 | ||
| 180 | /* | 195 | /* |
| 181 | ** open parts of the state that may cause memory-allocation errors | 196 | ** open parts of the state that may cause memory-allocation errors. |
| 197 | ** ('g->version' != NULL flags that the state was completely build) | ||
| 182 | */ | 198 | */ |
| 183 | static void f_luaopen (lua_State *L, void *ud) { | 199 | static void f_luaopen (lua_State *L, void *ud) { |
| 184 | global_State *g = G(L); | 200 | global_State *g = G(L); |
| @@ -190,20 +206,23 @@ static void f_luaopen (lua_State *L, void *ud) { · 5 unmodified lines | |||
| 190 | luaX_init(L); | 206 | luaX_init(L); |
| 191 | /* pre-create memory-error message */ | 207 | /* pre-create memory-error message */ |
| 192 | g->memerrmsg = luaS_newliteral(L, MEMERRMSG); | 208 | g->memerrmsg = luaS_newliteral(L, MEMERRMSG); |
| 193 | luaS_fix(g->memerrmsg); /* it should never be collected */ | 209 | luaC_fix(L, obj2gco(g->memerrmsg)); /* it should never be collected */ |
| 194 | g->gcrunning = 1; /* allow gc */ | 210 | g->gcrunning = 1; /* allow gc */ |
| 211 | g->version = lua_version(NULL); | ||
| 212 | luai_userstateopen(L); | ||
| 195 | } | 213 | } |
| 196 | 214 | ||
| 197 | 215 | ||
| 198 | /* | 216 | /* |
| 199 | ** preinitialize a state with consistent values without allocating | 217 | ** preinitialize a thread with consistent values without allocating |
| 200 | ** any memory (to avoid errors) | 218 | ** any memory (to avoid errors) |
| 201 | */ | 219 | */ |
| 202 | static void preinit_state (lua_State *L, global_State *g) { | 220 | static void preinit_thread (lua_State *L, global_State *g) { |
| 203 | G(L) = g; | 221 | G(L) = g; |
| 204 | L->stack = NULL; | 222 | L->stack = NULL; |
| 205 | L->ci = NULL; | 223 | L->ci = NULL; |
| 206 | L->stacksize = 0; | 224 | L->stacksize = 0; |
| 225 | L->twups = L; /* thread has no upvalues */ | ||
| 207 | L->errorJmp = NULL; | 226 | L->errorJmp = NULL; |
| 208 | L->nCcalls = 0; | 227 | L->nCcalls = 0; |
| 209 | L->hook = NULL; | 228 | L->hook = NULL; |
| @@ -222,6 +241,8 @@ static void close_state (lua_State *L) { · 12 unmodified lines | |||
| 222 | global_State *g = G(L); | 241 | global_State *g = G(L); |
| 223 | luaF_close(L, L->stack); /* close all upvalues for this thread */ | 242 | luaF_close(L, L->stack); /* close all upvalues for this thread */ |
| 224 | luaC_freeallobjects(L); /* collect all objects */ | 243 | luaC_freeallobjects(L); /* collect all objects */ |
| 244 | if (g->version) /* closing a fully built state? */ | ||
| 245 | luai_userstateclose(L); | ||
| 225 | luaM_freearray(L, G(L)->strt.hash, G(L)->strt.size); | 246 | luaM_freearray(L, G(L)->strt.hash, G(L)->strt.size); |
| 226 | luaZ_freebuffer(L, &g->buff); | 247 | luaZ_freebuffer(L, &g->buff); |
| 227 | freestack(L); | 248 | freestack(L); |
| @@ -231,13 +252,20 @@ static void close_state (lua_State *L) { · 3 unmodified lines | |||
| 231 | 252 | ||
| 232 | 253 | ||
| 233 | LUA_API lua_State *lua_newthread (lua_State *L) { | 254 | LUA_API lua_State *lua_newthread (lua_State *L) { |
| 255 | global_State *g = G(L); | ||
| 234 | lua_State *L1; | 256 | lua_State *L1; |
| 235 | lua_lock(L); | 257 | lua_lock(L); |
| 236 | luaC_checkGC(L); | 258 | luaC_checkGC(L); |
| 237 | L1 = &luaC_newobj(L, LUA_TTHREAD, sizeof(LX), NULL, offsetof(LX, l))->th; | 259 | /* create new thread */ |
| 260 | L1 = &cast(LX *, luaM_newobject(L, LUA_TTHREAD, sizeof(LX)))->l; | ||
| 261 | L1->marked = luaC_white(g); | ||
| 262 | L1->tt = LUA_TTHREAD; | ||
| 263 | /* link it on list 'allgc' */ | ||
| 264 | L1->next = g->allgc; | ||
| 265 | g->allgc = obj2gco(L1); | ||
| 238 | setthvalue(L, L->top, L1); | 266 | setthvalue(L, L->top, L1); |
| 239 | api_incr_top(L); | 267 | api_incr_top(L); |
| 240 | preinit_state(L1, G(L)); | 268 | preinit_thread(L1, g); |
| 241 | L1->hookmask = L->hookmask; | 269 | L1->hookmask = L->hookmask; |
| 242 | L1->basehookcount = L->basehookcount; | 270 | L1->basehookcount = L->basehookcount; |
| 243 | L1->hook = L->hook; | 271 | L1->hook = L->hook; |
| @@ -269,36 +297,32 @@ LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) { · 25 unmodified lines | |||
| 269 | g = &l->g; | 297 | g = &l->g; |
| 270 | L->next = NULL; | 298 | L->next = NULL; |
| 271 | L->tt = LUA_TTHREAD; | 299 | L->tt = LUA_TTHREAD; |
| 272 | g->currentwhite = bit2mask(WHITE0BIT, FIXEDBIT); | 300 | g->currentwhite = bitmask(WHITE0BIT); |
| 273 | L->marked = luaC_white(g); | 301 | L->marked = luaC_white(g); |
| 274 | g->gckind = KGC_NORMAL; | 302 | preinit_thread(L, g); |
| 275 | preinit_state(L, g); | ||
| 276 | g->frealloc = f; | 303 | g->frealloc = f; |
| 277 | g->ud = ud; | 304 | g->ud = ud; |
| 278 | g->mainthread = L; | 305 | g->mainthread = L; |
| 279 | g->seed = makeseed(L); | 306 | g->seed = makeseed(L); |
| 280 | g->uvhead.u.l.prev = &g->uvhead; | ||
| 281 | g->uvhead.u.l.next = &g->uvhead; | ||
| 282 | g->gcrunning = 0; /* no GC while building state */ | 307 | g->gcrunning = 0; /* no GC while building state */ |
| 283 | g->GCestimate = 0; | 308 | g->GCestimate = 0; |
| 284 | g->strt.size = 0; | 309 | g->strt.size = g->strt.nuse = 0; |
| 285 | g->strt.nuse = 0; | ||
| 286 | g->strt.hash = NULL; | 310 | g->strt.hash = NULL; |
| 287 | setnilvalue(&g->l_registry); | 311 | setnilvalue(&g->l_registry); |
| 288 | luaZ_initbuffer(L, &g->buff); | 312 | luaZ_initbuffer(L, &g->buff); |
| 289 | g->panic = NULL; | 313 | g->panic = NULL; |
| 290 | g->version = lua_version(NULL); | 314 | g->version = NULL; |
| 291 | g->gcstate = GCSpause; | 315 | g->gcstate = GCSpause; |
| 292 | g->allgc = NULL; | 316 | g->gckind = KGC_NORMAL; |
| 293 | g->finobj = NULL; | 317 | g->allgc = g->finobj = g->tobefnz = g->fixedgc = NULL; |
| 294 | g->tobefnz = NULL; | 318 | g->sweepgc = NULL; |
| 295 | g->sweepgc = g->sweepfin = NULL; | ||
| 296 | g->gray = g->grayagain = NULL; | 319 | g->gray = g->grayagain = NULL; |
| 297 | g->weak = g->ephemeron = g->allweak = NULL; | 320 | g->weak = g->ephemeron = g->allweak = NULL; |
| 321 | g->twups = NULL; | ||
| 298 | g->totalbytes = sizeof(LG); | 322 | g->totalbytes = sizeof(LG); |
| 299 | g->GCdebt = 0; | 323 | g->GCdebt = 0; |
| 324 | g->gcfinnum = 0; | ||
| 300 | g->gcpause = LUAI_GCPAUSE; | 325 | g->gcpause = LUAI_GCPAUSE; |
| 301 | g->gcmajorinc = LUAI_GCMAJOR; | ||
| 302 | g->gcstepmul = LUAI_GCMUL; | 326 | g->gcstepmul = LUAI_GCMUL; |
| 303 | for (i=0; i < LUA_NUMTAGS; i++) g->mt[i] = NULL; | 327 | for (i=0; i < LUA_NUMTAGS; i++) g->mt[i] = NULL; |
| 304 | if (luaD_rawrunprotected(L, f_luaopen, NULL) != LUA_OK) { | 328 | if (luaD_rawrunprotected(L, f_luaopen, NULL) != LUA_OK) { |
| @@ -306,8 +330,6 @@ LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) { · 1 unmodified line | |||
| 306 | close_state(L); | 330 | close_state(L); |
| 307 | L = NULL; | 331 | L = NULL; |
| 308 | } | 332 | } |
| 309 | else | ||
| 310 | luai_userstateopen(L); | ||
| 311 | return L; | 333 | return L; |
| 312 | } | 334 | } |
| 313 | 335 | ||
| @@ -315,7 +337,6 @@ LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) { · 1 unmodified line | |||
| 315 | LUA_API void lua_close (lua_State *L) { | 337 | LUA_API void lua_close (lua_State *L) { |
| 316 | L = G(L)->mainthread; /* only the main thread can be closed */ | 338 | L = G(L)->mainthread; /* only the main thread can be closed */ |
| 317 | lua_lock(L); | 339 | lua_lock(L); |
| 318 | luai_userstateclose(L); | ||
| 319 | close_state(L); | 340 | close_state(L); |
| 320 | } | 341 | } |
| 321 | 342 | ||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lstate.h,v 2.82 2012/07/02 13:37:04 roberto Exp $ | 2 | ** $Id: lstate.h,v 2.102 2014/02/18 13:46:26 roberto Exp $ |
| 3 | ** Global State | 3 | ** Global State |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -16,25 +16,16 @@ · 10 unmodified lines | |||
| 16 | 16 | ||
| 17 | /* | 17 | /* |
| 18 | 18 | ||
| 19 | ** Some notes about garbage-collected objects: All objects in Lua must | 19 | ** Some notes about garbage-collected objects: All objects in Lua must |
| 20 | ** be kept somehow accessible until being freed. | 20 | ** be kept somehow accessible until being freed, so all objects always |
| 21 | ** belong to one (and only one) of these lists, using field 'next' of | ||
| 22 | ** the 'CommonHeader' for the link: | ||
| 21 | ** | 23 | ** |
| 22 | ** Lua keeps most objects linked in list g->allgc. The link uses field | 24 | ** allgc: all objects not marked for finalization; |
| 23 | ** 'next' of the CommonHeader. | 25 | ** finobj: all objects marked for finalization; |
| 24 | ** | 26 | ** tobefnz: all objects ready to be finalized; |
| 25 | ** Strings are kept in several lists headed by the array g->strt.hash. | 27 | ** fixedgc: all objects that are not to be collected (currently |
| 26 | ** | 28 | ** only small strings, such as reserved words). |
| 27 | ** Open upvalues are not subject to independent garbage collection. They | ||
| 28 | ** are collected together with their respective threads. Lua keeps a | ||
| 29 | ** double-linked list with all open upvalues (g->uvhead) so that it can | ||
| 30 | ** mark objects referred by them. (They are always gray, so they must | ||
| 31 | ** be remarked in the atomic step. Usually their contents would be marked | ||
| 32 | ** when traversing the respective threads, but the thread may already be | ||
| 33 | ** dead, while the upvalue is still accessible through closures.) | ||
| 34 | ** | ||
| 35 | ** Objects with finalizers are kept in the list g->finobj. | ||
| 36 | ** | ||
| 37 | ** The list g->tobefnz links all objects being finalized. | ||
| 38 | 29 | ||
| 39 | */ | 30 | */ |
| 40 | 31 | ||
| @@ -53,12 +44,11 @@ struct lua_longjmp; /* defined in ldo.c */ · 12 unmodified lines | |||
| 53 | /* kinds of Garbage Collection */ | 44 | /* kinds of Garbage Collection */ |
| 54 | #define KGC_NORMAL 0 | 45 | #define KGC_NORMAL 0 |
| 55 | #define KGC_EMERGENCY 1 /* gc was forced by an allocation failure */ | 46 | #define KGC_EMERGENCY 1 /* gc was forced by an allocation failure */ |
| 56 | #define KGC_GEN 2 /* generational collection */ | ||
| 57 | 47 | ||
| 58 | 48 | ||
| 59 | typedef struct stringtable { | 49 | typedef struct stringtable { |
| 60 | GCObject **hash; | 50 | TString **hash; |
| 61 | lu_int32 nuse; /* number of elements */ | 51 | int nuse; /* number of elements */ |
| 62 | int size; | 52 | int size; |
| 63 | } stringtable; | 53 | } stringtable; |
| 64 | 54 | ||
| @@ -123,21 +113,20 @@ typedef struct global_State { · 58 unmodified lines | |||
| 123 | lu_byte gcstate; /* state of garbage collector */ | 113 | lu_byte gcstate; /* state of garbage collector */ |
| 124 | lu_byte gckind; /* kind of GC running */ | 114 | lu_byte gckind; /* kind of GC running */ |
| 125 | lu_byte gcrunning; /* true if GC is running */ | 115 | lu_byte gcrunning; /* true if GC is running */ |
| 126 | int sweepstrgc; /* position of sweep in `strt' */ | ||
| 127 | GCObject *allgc; /* list of all collectable objects */ | 116 | GCObject *allgc; /* list of all collectable objects */ |
| 117 | GCObject **sweepgc; /* current position of sweep in list */ | ||
| 128 | GCObject *finobj; /* list of collectable objects with finalizers */ | 118 | GCObject *finobj; /* list of collectable objects with finalizers */ |
| 129 | GCObject **sweepgc; /* current position of sweep in list 'allgc' */ | ||
| 130 | GCObject **sweepfin; /* current position of sweep in list 'finobj' */ | ||
| 131 | GCObject *gray; /* list of gray objects */ | 119 | GCObject *gray; /* list of gray objects */ |
| 132 | GCObject *grayagain; /* list of objects to be traversed atomically */ | 120 | GCObject *grayagain; /* list of objects to be traversed atomically */ |
| 133 | GCObject *weak; /* list of tables with weak values */ | 121 | GCObject *weak; /* list of tables with weak values */ |
| 134 | GCObject *ephemeron; /* list of ephemeron tables (weak keys) */ | 122 | GCObject *ephemeron; /* list of ephemeron tables (weak keys) */ |
| 135 | GCObject *allweak; /* list of all-weak tables */ | 123 | GCObject *allweak; /* list of all-weak tables */ |
| 136 | GCObject *tobefnz; /* list of userdata to be GC */ | 124 | GCObject *tobefnz; /* list of userdata to be GC */ |
| 137 | UpVal uvhead; /* head of double-linked list of all open upvalues */ | 125 | GCObject *fixedgc; /* list of objects not to be collected */ |
| 126 | struct lua_State *twups; /* list of threads with open upvalues */ | ||
| 138 | Mbuffer buff; /* temporary buffer for string concatenation */ | 127 | Mbuffer buff; /* temporary buffer for string concatenation */ |
| 128 | unsigned int gcfinnum; /* number of finalizers to call in each GC step */ | ||
| 139 | int gcpause; /* size of pause between successive GCs */ | 129 | int gcpause; /* size of pause between successive GCs */ |
| 140 | int gcmajorinc; /* pause between major collections (only in gen. mode) */ | ||
| 141 | int gcstepmul; /* GC `granularity' */ | 130 | int gcstepmul; /* GC `granularity' */ |
| 142 | lua_CFunction panic; /* to be called in unprotected errors */ | 131 | lua_CFunction panic; /* to be called in unprotected errors */ |
| 143 | struct lua_State *mainthread; | 132 | struct lua_State *mainthread; |
| @@ -168,8 +157,9 @@ struct lua_State { · 24 unmodified lines | |||
| 168 | int basehookcount; | 157 | int basehookcount; |
| 169 | int hookcount; | 158 | int hookcount; |
| 170 | lua_Hook hook; | 159 | lua_Hook hook; |
| 171 | GCObject *openupval; /* list of open upvalues in this stack */ | 160 | UpVal *openupval; /* list of open upvalues in this stack */ |
| 172 | GCObject *gclist; | 161 | GCObject *gclist; |
| 162 | struct lua_State *twups; /* list of threads with open upvalues */ | ||
| 173 | struct lua_longjmp *errorJmp; /* current error recover point */ | 163 | struct lua_longjmp *errorJmp; /* current error recover point */ |
| 174 | ptrdiff_t errfunc; /* current error handling function (stack index) */ | 164 | ptrdiff_t errfunc; /* current error handling function (stack index) */ |
| 175 | CallInfo base_ci; /* CallInfo for first level (C calling Lua) */ | 165 | CallInfo base_ci; /* CallInfo for first level (C calling Lua) */ |
| @@ -189,7 +179,6 @@ union GCObject { · 13 unmodified lines | |||
| 189 | union Closure cl; | 179 | union Closure cl; |
| 190 | struct Table h; | 180 | struct Table h; |
| 191 | struct Proto p; | 181 | struct Proto p; |
| 192 | struct UpVal uv; | ||
| 193 | struct lua_State th; /* thread */ | 182 | struct lua_State th; /* thread */ |
| 194 | }; | 183 | }; |
| 195 | 184 | ||
| @@ -208,7 +197,6 @@ union GCObject { · 12 unmodified lines | |||
| 208 | check_exp(novariant((o)->gch.tt) == LUA_TFUNCTION, &((o)->cl)) | 197 | check_exp(novariant((o)->gch.tt) == LUA_TFUNCTION, &((o)->cl)) |
| 209 | #define gco2t(o) check_exp((o)->gch.tt == LUA_TTABLE, &((o)->h)) | 198 | #define gco2t(o) check_exp((o)->gch.tt == LUA_TTABLE, &((o)->h)) |
| 210 | #define gco2p(o) check_exp((o)->gch.tt == LUA_TPROTO, &((o)->p)) | 199 | #define gco2p(o) check_exp((o)->gch.tt == LUA_TPROTO, &((o)->p)) |
| 211 | #define gco2uv(o) check_exp((o)->gch.tt == LUA_TUPVAL, &((o)->uv)) | ||
| 212 | #define gco2th(o) check_exp((o)->gch.tt == LUA_TTHREAD, &((o)->th)) | 200 | #define gco2th(o) check_exp((o)->gch.tt == LUA_TTHREAD, &((o)->th)) |
| 213 | 201 | ||
| 214 | /* macro to convert any Lua object into a GCObject */ | 202 | /* macro to convert any Lua object into a GCObject */ |
| @@ -222,6 +210,7 @@ LUAI_FUNC void luaE_setdebt (global_State *g, l_mem debt); · 7 unmodified lines | |||
| 222 | LUAI_FUNC void luaE_freethread (lua_State *L, lua_State *L1); | 210 | LUAI_FUNC void luaE_freethread (lua_State *L, lua_State *L1); |
| 223 | LUAI_FUNC CallInfo *luaE_extendCI (lua_State *L); | 211 | LUAI_FUNC CallInfo *luaE_extendCI (lua_State *L); |
| 224 | LUAI_FUNC void luaE_freeCI (lua_State *L); | 212 | LUAI_FUNC void luaE_freeCI (lua_State *L); |
| 213 | LUAI_FUNC void luaE_shrinkCI (lua_State *L); | ||
| 225 | 214 | ||
| 226 | 215 | ||
| 227 | #endif | 216 | #endif |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lstring.c,v 2.27 2013/06/19 14:27:00 roberto Exp $ | 2 | ** $Id: lstring.c,v 2.38 2014/03/19 18:51:42 roberto Exp $ |
| 3 | ** String table (keeps all strings handled by Lua) | 3 | ** String table (keeps all strings handled by Lua) |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -12,12 +12,15 @@ · 6 unmodified lines | |||
| 12 | 12 | ||
| 13 | #include "lua.h" | 13 | #include "lua.h" |
| 14 | 14 | ||
| 15 | #include "ldebug.h" | ||
| 16 | #include "ldo.h" | ||
| 15 | #include "lmem.h" | 17 | #include "lmem.h" |
| 16 | #include "lobject.h" | 18 | #include "lobject.h" |
| 17 | #include "lstate.h" | 19 | #include "lstate.h" |
| 18 | #include "lstring.h" | 20 | #include "lstring.h" |
| 19 | 21 | ||
| 20 | 22 | ||
| 23 | |||
| 21 | /* | 24 | /* |
| 22 | ** Lua will use at most ~(2^LUAI_HASHLIMIT) bytes from a string to | 25 | ** Lua will use at most ~(2^LUAI_HASHLIMIT) bytes from a string to |
| 23 | ** compute its hash | 26 | ** compute its hash |
| @@ -39,15 +42,6 @@ int luaS_eqlngstr (TString *a, TString *b) { · 15 unmodified lines | |||
| 39 | } | 42 | } |
| 40 | 43 | ||
| 41 | 44 | ||
| 42 | /* | ||
| 43 | ** equality for strings | ||
| 44 | */ | ||
| 45 | int luaS_eqstr (TString *a, TString *b) { | ||
| 46 | return (a->tsv.tt == b->tsv.tt) && | ||
| 47 | (a->tsv.tt == LUA_TSHRSTR ? eqshrstr(a, b) : luaS_eqlngstr(a, b)); | ||
| 48 | } | ||
| 49 | |||
| 50 | |||
| 51 | unsigned int luaS_hash (const char *str, size_t l, unsigned int seed) { | 45 | unsigned int luaS_hash (const char *str, size_t l, unsigned int seed) { |
| 52 | unsigned int h = seed ^ cast(unsigned int, l); | 46 | unsigned int h = seed ^ cast(unsigned int, l); |
| 53 | size_t l1; | 47 | size_t l1; |
| @@ -64,43 +58,41 @@ unsigned int luaS_hash (const char *str, size_t l, unsigned int seed) { · 10 unmodified lines | |||
| 64 | void luaS_resize (lua_State *L, int newsize) { | 58 | void luaS_resize (lua_State *L, int newsize) { |
| 65 | int i; | 59 | int i; |
| 66 | stringtable *tb = &G(L)->strt; | 60 | stringtable *tb = &G(L)->strt; |
| 67 | /* cannot resize while GC is traversing strings */ | 61 | if (newsize > tb->size) { /* grow table if needed */ |
| 68 | luaC_runtilstate(L, ~bitmask(GCSsweepstring)); | 62 | luaM_reallocvector(L, tb->hash, tb->size, newsize, TString *); |
| 69 | if (newsize > tb->size) { | 63 | for (i = tb->size; i < newsize; i++) |
| 70 | luaM_reallocvector(L, tb->hash, tb->size, newsize, GCObject *); | 64 | tb->hash[i] = NULL; |
| 71 | for (i = tb->size; i < newsize; i++) tb->hash[i] = NULL; | ||
| 72 | } | 65 | } |
| 73 | /* rehash */ | 66 | for (i = 0; i < tb->size; i++) { /* rehash */ |
| 74 | for (i=0; i<tb->size; i++) { | 67 | TString *p = tb->hash[i]; |
| 75 | GCObject *p = tb->hash[i]; | ||
| 76 | tb->hash[i] = NULL; | 68 | tb->hash[i] = NULL; |
| 77 | while (p) { /* for each node in the list */ | 69 | while (p) { /* for each node in the list */ |
| 78 | GCObject *next = gch(p)->next; /* save next */ | 70 | TString *hnext = p->tsv.hnext; /* save next */ |
| 79 | unsigned int h = lmod(gco2ts(p)->hash, newsize); /* new position */ | 71 | unsigned int h = lmod(p->tsv.hash, newsize); /* new position */ |
| 80 | gch(p)->next = tb->hash[h]; /* chain it */ | 72 | p->tsv.hnext = tb->hash[h]; /* chain it */ |
| 81 | tb->hash[h] = p; | 73 | tb->hash[h] = p; |
| 82 | resetoldbit(p); /* see MOVE OLD rule */ | 74 | p = hnext; |
| 83 | p = next; | ||
| 84 | } | 75 | } |
| 85 | } | 76 | } |
| 86 | if (newsize < tb->size) { | 77 | if (newsize < tb->size) { /* shrink table if needed */ |
| 87 | /* shrinking slice must be empty */ | 78 | /* vanishing slice should be empty */ |
| 88 | lua_assert(tb->hash[newsize] == NULL && tb->hash[tb->size - 1] == NULL); | 79 | lua_assert(tb->hash[newsize] == NULL && tb->hash[tb->size - 1] == NULL); |
| 89 | luaM_reallocvector(L, tb->hash, tb->size, newsize, GCObject *); | 80 | luaM_reallocvector(L, tb->hash, tb->size, newsize, TString *); |
| 90 | } | 81 | } |
| 91 | tb->size = newsize; | 82 | tb->size = newsize; |
| 92 | } | 83 | } |
| 93 | 84 | ||
| 94 | 85 | ||
| 86 | |||
| 95 | /* | 87 | /* |
| 96 | ** creates a new string object | 88 | ** creates a new string object |
| 97 | */ | 89 | */ |
| 98 | static TString *createstrobj (lua_State *L, const char *str, size_t l, | 90 | static TString *createstrobj (lua_State *L, const char *str, size_t l, |
| 99 | int tag, unsigned int h, GCObject **list) { | 91 | int tag, unsigned int h) { |
| 100 | TString *ts; | 92 | TString *ts; |
| 101 | size_t totalsize; /* total size of TString object */ | 93 | size_t totalsize; /* total size of TString object */ |
| 102 | totalsize = sizeof(TString) + ((l + 1) * sizeof(char)); | 94 | totalsize = sizeof(TString) + ((l + 1) * sizeof(char)); |
| 103 | ts = &luaC_newobj(L, tag, totalsize, list, 0)->ts; | 95 | ts = &luaC_newobj(L, tag, totalsize)->ts; |
| 104 | ts->tsv.len = l; | 96 | ts->tsv.len = l; |
| 105 | ts->tsv.hash = h; | 97 | ts->tsv.hash = h; |
| 106 | ts->tsv.extra = 0; | 98 | ts->tsv.extra = 0; |
| @@ -110,20 +102,13 @@ static TString *createstrobj (lua_State *L, const char *str, size_t l, · 3 unmodified lines | |||
| 110 | } | 102 | } |
| 111 | 103 | ||
| 112 | 104 | ||
| 113 | /* | 105 | LUAI_FUNC void luaS_remove (lua_State *L, TString *ts) { |
| 114 | ** creates a new short string, inserting it into string table | ||
| 115 | */ | ||
| 116 | static TString *newshrstr (lua_State *L, const char *str, size_t l, | ||
| 117 | unsigned int h) { | ||
| 118 | GCObject **list; /* (pointer to) list where it will be inserted */ | ||
| 119 | stringtable *tb = &G(L)->strt; | 106 | stringtable *tb = &G(L)->strt; |
| 120 | TString *s; | 107 | TString **p = &tb->hash[lmod(ts->tsv.hash, tb->size)]; |
| 121 | if (tb->nuse >= cast(lu_int32, tb->size) && tb->size <= MAX_INT/2) | 108 | while (*p != ts) /* find previous element */ |
| 122 | luaS_resize(L, tb->size*2); /* too crowded */ | 109 | p = &(*p)->tsv.hnext; |
| 123 | list = &tb->hash[lmod(h, tb->size)]; | 110 | *p = (*p)->tsv.hnext; /* remove element from its list */ |
| 124 | s = createstrobj(L, str, l, LUA_TSHRSTR, h, list); | 111 | tb->nuse--; |
| 125 | tb->nuse++; | ||
| 126 | return s; | ||
| 127 | } | 112 | } |
| 128 | 113 | ||
| 129 | 114 | ||
| @@ -131,22 +116,28 @@ static TString *newshrstr (lua_State *L, const char *str, size_t l, · 1 unmodified line | |||
| 131 | ** checks whether short string exists and reuses it or creates a new one | 116 | ** checks whether short string exists and reuses it or creates a new one |
| 132 | */ | 117 | */ |
| 133 | static TString *internshrstr (lua_State *L, const char *str, size_t l) { | 118 | static TString *internshrstr (lua_State *L, const char *str, size_t l) { |
| 134 | GCObject *o; | 119 | TString *ts; |
| 135 | global_State *g = G(L); | 120 | global_State *g = G(L); |
| 136 | unsigned int h = luaS_hash(str, l, g->seed); | 121 | unsigned int h = luaS_hash(str, l, g->seed); |
| 137 | for (o = g->strt.hash[lmod(h, g->strt.size)]; | 122 | TString **list = &g->strt.hash[lmod(h, g->strt.size)]; |
| 138 | o != NULL; | 123 | for (ts = *list; ts != NULL; ts = ts->tsv.hnext) { |
| 139 | o = gch(o)->next) { | 124 | if (l == ts->tsv.len && |
| 140 | TString *ts = rawgco2ts(o); | ||
| 141 | if (h == ts->tsv.hash && | ||
| 142 | l == ts->tsv.len && | ||
| 143 | (memcmp(str, getstr(ts), l * sizeof(char)) == 0)) { | 125 | (memcmp(str, getstr(ts), l * sizeof(char)) == 0)) { |
| 144 | if (isdead(G(L), o)) /* string is dead (but was not collected yet)? */ | 126 | /* found! */ |
| 145 | changewhite(o); /* resurrect it */ | 127 | if (isdead(g, obj2gco(ts))) /* dead (but not collected yet)? */ |
| 128 | changewhite(obj2gco(ts)); /* resurrect it */ | ||
| 146 | return ts; | 129 | return ts; |
| 147 | } | 130 | } |
| 148 | } | 131 | } |
| 149 | return newshrstr(L, str, l, h); /* not found; create a new string */ | 132 | if (g->strt.nuse >= g->strt.size && g->strt.size <= MAX_INT/2) { |
| 133 | luaS_resize(L, g->strt.size * 2); | ||
| 134 | list = &g->strt.hash[lmod(h, g->strt.size)]; /* recompute with new size */ | ||
| 135 | } | ||
| 136 | ts = createstrobj(L, str, l, LUA_TSHRSTR, h); | ||
| 137 | ts->tsv.hnext = *list; | ||
| 138 | *list = ts; | ||
| 139 | g->strt.nuse++; | ||
| 140 | return ts; | ||
| 150 | } | 141 | } |
| 151 | 142 | ||
| 152 | 143 | ||
| @@ -159,7 +150,7 @@ TString *luaS_newlstr (lua_State *L, const char *str, size_t l) { · 6 unmodified lines | |||
| 159 | else { | 150 | else { |
| 160 | if (l + 1 > (MAX_SIZE - sizeof(TString))/sizeof(char)) | 151 | if (l + 1 > (MAX_SIZE - sizeof(TString))/sizeof(char)) |
| 161 | luaM_toobig(L); | 152 | luaM_toobig(L); |
| 162 | return createstrobj(L, str, l, LUA_TLNGSTR, G(L)->seed, NULL); | 153 | return createstrobj(L, str, l, LUA_TLNGSTR, G(L)->seed); |
| 163 | } | 154 | } |
| 164 | } | 155 | } |
| 165 | 156 | ||
| @@ -172,14 +163,14 @@ TString *luaS_new (lua_State *L, const char *str) { · 6 unmodified lines | |||
| 172 | } | 163 | } |
| 173 | 164 | ||
| 174 | 165 | ||
| 175 | Udata *luaS_newudata (lua_State *L, size_t s, Table *e) { | 166 | Udata *luaS_newudata (lua_State *L, size_t s) { |
| 176 | Udata *u; | 167 | Udata *u; |
| 177 | if (s > MAX_SIZE - sizeof(Udata)) | 168 | if (s > MAX_SIZE - sizeof(Udata)) |
| 178 | luaM_toobig(L); | 169 | luaM_toobig(L); |
| 179 | u = &luaC_newobj(L, LUA_TUSERDATA, sizeof(Udata) + s, NULL, 0)->u; | 170 | u = &luaC_newobj(L, LUA_TUSERDATA, sizeof(Udata) + s)->u; |
| 180 | u->uv.len = s; | 171 | u->uv.len = s; |
| 181 | u->uv.metatable = NULL; | 172 | u->uv.metatable = NULL; |
| 182 | u->uv.env = e; | 173 | setuservalue(L, u, luaO_nilobject); |
| 183 | return u; | 174 | return u; |
| 184 | } | 175 | } |
| 185 | 176 | ||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lstring.h,v 1.49 2012/02/01 21:57:15 roberto Exp $ | 2 | ** $Id: lstring.h,v 1.54 2014/03/19 18:51:42 roberto Exp $ |
| 3 | ** String table (keep all strings handled by Lua) | 3 | ** String table (keep all strings handled by Lua) |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -19,8 +19,6 @@ · 13 unmodified lines | |||
| 19 | #define luaS_newliteral(L, s) (luaS_newlstr(L, "" s, \ | 19 | #define luaS_newliteral(L, s) (luaS_newlstr(L, "" s, \ |
| 20 | (sizeof(s)/sizeof(char))-1)) | 20 | (sizeof(s)/sizeof(char))-1)) |
| 21 | 21 | ||
| 22 | #define luaS_fix(s) l_setbit((s)->tsv.marked, FIXEDBIT) | ||
| 23 | |||
| 24 | 22 | ||
| 25 | /* | 23 | /* |
| 26 | ** test whether a string is a reserved word | 24 | ** test whether a string is a reserved word |
| @@ -36,9 +34,9 @@ · 9 unmodified lines | |||
| 36 | 34 | ||
| 37 | LUAI_FUNC unsigned int luaS_hash (const char *str, size_t l, unsigned int seed); | 35 | LUAI_FUNC unsigned int luaS_hash (const char *str, size_t l, unsigned int seed); |
| 38 | LUAI_FUNC int luaS_eqlngstr (TString *a, TString *b); | 36 | LUAI_FUNC int luaS_eqlngstr (TString *a, TString *b); |
| 39 | LUAI_FUNC int luaS_eqstr (TString *a, TString *b); | ||
| 40 | LUAI_FUNC void luaS_resize (lua_State *L, int newsize); | 37 | LUAI_FUNC void luaS_resize (lua_State *L, int newsize); |
| 41 | LUAI_FUNC Udata *luaS_newudata (lua_State *L, size_t s, Table *e); | 38 | LUAI_FUNC void luaS_remove (lua_State *L, TString *ts); |
| 39 | LUAI_FUNC Udata *luaS_newudata (lua_State *L, size_t s); | ||
| 42 | LUAI_FUNC TString *luaS_newlstr (lua_State *L, const char *str, size_t l); | 40 | LUAI_FUNC TString *luaS_newlstr (lua_State *L, const char *str, size_t l); |
| 43 | LUAI_FUNC TString *luaS_new (lua_State *L, const char *str); | 41 | LUAI_FUNC TString *luaS_new (lua_State *L, const char *str); |
| 44 | 42 | ||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lstrlib.c,v 1.182 2013/06/20 15:06:51 roberto Exp $ | 2 | ** $Id: lstrlib.c,v 1.189 2014/03/21 14:26:44 roberto Exp $ |
| 3 | ** Standard library for string operations and pattern-matching | 3 | ** Standard library for string operations and pattern-matching |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -116,7 +116,7 @@ static int str_rep (lua_State *L) { · 110 unmodified lines | |||
| 116 | lua_Integer n = luaL_checkinteger(L, 2); | 116 | lua_Integer n = luaL_checkinteger(L, 2); |
| 117 | const char *sep = luaL_optlstring(L, 3, "", &lsep); | 117 | const char *sep = luaL_optlstring(L, 3, "", &lsep); |
| 118 | if (n <= 0) lua_pushliteral(L, ""); | 118 | if (n <= 0) lua_pushliteral(L, ""); |
| 119 | else if (l + lsep < l || l + lsep >= MAXSIZE / n) /* may overflow? */ | 119 | else if (l + lsep < l || l + lsep > MAXSIZE / n) /* may overflow? */ |
| 120 | return luaL_error(L, "resulting string too large"); | 120 | return luaL_error(L, "resulting string too large"); |
| 121 | else { | 121 | else { |
| 122 | size_t totallen = n * l + (n - 1) * lsep; | 122 | size_t totallen = n * l + (n - 1) * lsep; |
| @@ -124,8 +124,9 @@ static int str_rep (lua_State *L) { · 1 unmodified line | |||
| 124 | char *p = luaL_buffinitsize(L, &b, totallen); | 124 | char *p = luaL_buffinitsize(L, &b, totallen); |
| 125 | while (n-- > 1) { /* first n-1 copies (followed by separator) */ | 125 | while (n-- > 1) { /* first n-1 copies (followed by separator) */ |
| 126 | memcpy(p, s, l * sizeof(char)); p += l; | 126 | memcpy(p, s, l * sizeof(char)); p += l; |
| 127 | if (lsep > 0) { /* avoid empty 'memcpy' (may be expensive) */ | 127 | if (lsep > 0) { /* empty 'memcpy' is not that cheap */ |
| 128 | memcpy(p, sep, lsep * sizeof(char)); p += lsep; | 128 | memcpy(p, sep, lsep * sizeof(char)); |
| 129 | p += lsep; | ||
| 129 | } | 130 | } |
| 130 | } | 131 | } |
| 131 | memcpy(p, s, l * sizeof(char)); /* last copy (not followed by separator) */ | 132 | memcpy(p, s, l * sizeof(char)); /* last copy (not followed by separator) */ |
| @@ -178,10 +179,11 @@ static int writer (lua_State *L, const void *b, size_t size, void *B) { · 46 unmodified lines | |||
| 178 | 179 | ||
| 179 | static int str_dump (lua_State *L) { | 180 | static int str_dump (lua_State *L) { |
| 180 | luaL_Buffer b; | 181 | luaL_Buffer b; |
| 182 | int strip = lua_toboolean(L, 2); | ||
| 181 | luaL_checktype(L, 1, LUA_TFUNCTION); | 183 | luaL_checktype(L, 1, LUA_TFUNCTION); |
| 182 | lua_settop(L, 1); | 184 | lua_settop(L, 1); |
| 183 | luaL_buffinit(L,&b); | 185 | luaL_buffinit(L,&b); |
| 184 | if (lua_dump(L, writer, &b) != 0) | 186 | if (lua_dump(L, writer, &b, strip) != 0) |
| 185 | return luaL_error(L, "unable to dump given function"); | 187 | return luaL_error(L, "unable to dump given function"); |
| 186 | luaL_pushresult(&b); | 188 | luaL_pushresult(&b); |
| 187 | return 1; | 189 | return 1; |
| @@ -938,6 +940,217 @@ static int str_format (lua_State *L) { · 750 unmodified lines | |||
| 938 | /* }====================================================== */ | 940 | /* }====================================================== */ |
| 939 | 941 | ||
| 940 | 942 | ||
| 943 | /* | ||
| 944 | ** {====================================================== | ||
| 945 | ** PACK/UNPACK | ||
| 946 | ** ======================================================= | ||
| 947 | */ | ||
| 948 | |||
| 949 | /* maximum size for the binary representation of an integer */ | ||
| 950 | #define MAXINTSIZE 8 | ||
| 951 | |||
| 952 | |||
| 953 | /* number of bits in a character */ | ||
| 954 | #define NB CHAR_BIT | ||
| 955 | |||
| 956 | /* mask for one character (NB ones) */ | ||
| 957 | #define MC (((lua_Integer)1 << NB) - 1) | ||
| 958 | |||
| 959 | /* mask for one character without sign ((NB - 1) ones) */ | ||
| 960 | #define SM (((lua_Integer)1 << (NB - 1)) - 1) | ||
| 961 | |||
| 962 | |||
| 963 | #define SZINT ((int)sizeof(lua_Integer)) | ||
| 964 | |||
| 965 | |||
| 966 | static union { | ||
| 967 | int dummy; | ||
| 968 | char little; /* true iff machine is little endian */ | ||
| 969 | } const nativeendian = {1}; | ||
| 970 | |||
| 971 | |||
| 972 | static int getendian (lua_State *L, int arg) { | ||
| 973 | const char *endian = luaL_optstring(L, arg, | ||
| 974 | (nativeendian.little ? "l" : "b")); | ||
| 975 | if (*endian == 'n') /* native? */ | ||
| 976 | return nativeendian.little; | ||
| 977 | luaL_argcheck(L, *endian == 'l' || *endian == 'b', arg, | ||
| 978 | "endianess must be 'l'/'b'/'n'"); | ||
| 979 | return (*endian == 'l'); | ||
| 980 | } | ||
| 981 | |||
| 982 | |||
| 983 | static int getintsize (lua_State *L, int arg) { | ||
| 984 | int size = luaL_optint(L, arg, 0); | ||
| 985 | if (size == 0) size = SZINT; | ||
| 986 | luaL_argcheck(L, 1 <= size && size <= MAXINTSIZE, arg, | ||
| 987 | "integer size out of valid range"); | ||
| 988 | return size; | ||
| 989 | } | ||
| 990 | |||
| 991 | |||
| 992 | static int packint (char *buff, lua_Integer n, int littleendian, int size) { | ||
| 993 | int i; | ||
| 994 | if (littleendian) { | ||
| 995 | for (i = 0; i < size - 1; i++) { | ||
| 996 | buff[i] = (n & MC); | ||
| 997 | n >>= NB; | ||
| 998 | } | ||
| 999 | } | ||
| 1000 | else { | ||
| 1001 | for (i = size - 1; i > 0; i--) { | ||
| 1002 | buff[i] = (n & MC); | ||
| 1003 | n >>= NB; | ||
| 1004 | } | ||
| 1005 | } | ||
| 1006 | buff[i] = (n & MC); /* last byte */ | ||
| 1007 | /* test for overflow: OK if there are only zeros left in higher bytes, | ||
| 1008 | or if there are only ones left and packed number is negative (signal | ||
| 1009 | bit, the higher bit in last byte, is one) */ | ||
| 1010 | return ((n & ~MC) == 0 || (n | SM) == ~(lua_Integer)0); | ||
| 1011 | } | ||
| 1012 | |||
| 1013 | |||
| 1014 | static int packint_l (lua_State *L) { | ||
| 1015 | char buff[MAXINTSIZE]; | ||
| 1016 | lua_Integer n = luaL_checkinteger(L, 1); | ||
| 1017 | int size = getintsize(L, 2); | ||
| 1018 | int endian = getendian(L, 3); | ||
| 1019 | if (packint(buff, n, endian, size)) | ||
| 1020 | lua_pushlstring(L, buff, size); | ||
| 1021 | else | ||
| 1022 | luaL_error(L, "integer does not fit into given size (%d)", size); | ||
| 1023 | return 1; | ||
| 1024 | } | ||
| 1025 | |||
| 1026 | |||
| 1027 | /* mask to check higher-order byte in a Lua integer */ | ||
| 1028 | #define HIGHERBYTE (MC << (NB * (SZINT - 1))) | ||
| 1029 | |||
| 1030 | /* mask to check higher-order byte + signal bit of next (lower) byte */ | ||
| 1031 | #define HIGHERBYTE1 (HIGHERBYTE | (HIGHERBYTE >> 1)) | ||
| 1032 | |||
| 1033 | static int unpackint (const char *buff, lua_Integer *res, | ||
| 1034 | int littleendian, int size) { | ||
| 1035 | lua_Integer n = 0; | ||
| 1036 | int i; | ||
| 1037 | for (i = 0; i < size; i++) { | ||
| 1038 | if (i >= SZINT) { /* will throw away a byte? */ | ||
| 1039 | /* check for overflow: it is OK to throw away leading zeros for a | ||
| 1040 | positive number, leading ones for a negative number, and a | ||
| 1041 | leading zero byte to allow unsigned integers with a 1 in | ||
| 1042 | its "signal bit" */ | ||
| 1043 | if (!((n & HIGHERBYTE1) == 0 || /* zeros for positive number */ | ||
| 1044 | (n & HIGHERBYTE1) == HIGHERBYTE1 || /* ones for negative number */ | ||
| 1045 | ((n & HIGHERBYTE) == 0 && i == size - 1))) /* leading zero */ | ||
| 1046 | return 0; /* overflow */ | ||
| 1047 | } | ||
| 1048 | n <<= NB; | ||
| 1049 | n |= (lua_Integer)(unsigned char)buff[littleendian ? size - 1 - i : i]; | ||
| 1050 | } | ||
| 1051 | if (size < SZINT) { /* need sign extension? */ | ||
| 1052 | lua_Integer mask = (~(lua_Integer)0) << (size*NB - 1); | ||
| 1053 | if (n & mask) /* negative value? */ | ||
| 1054 | n |= mask; /* signal extension */ | ||
| 1055 | } | ||
| 1056 | *res = n; | ||
| 1057 | return 1; | ||
| 1058 | } | ||
| 1059 | |||
| 1060 | |||
| 1061 | static int unpackint_l (lua_State *L) { | ||
| 1062 | lua_Integer res; | ||
| 1063 | size_t len; | ||
| 1064 | const char *s = luaL_checklstring(L, 1, &len); | ||
| 1065 | lua_Integer pos = posrelat(luaL_optinteger(L, 2, 1), len); | ||
| 1066 | int size = getintsize(L, 3); | ||
| 1067 | int endian = getendian(L, 4); | ||
| 1068 | luaL_argcheck(L, 1 <= pos && (size_t)pos + size - 1 <= len, 1, | ||
| 1069 | "string too short"); | ||
| 1070 | if(unpackint(s + pos - 1, &res, endian, size)) | ||
| 1071 | lua_pushinteger(L, res); | ||
| 1072 | else | ||
| 1073 | luaL_error(L, "result does not fit into a Lua integer"); | ||
| 1074 | return 1; | ||
| 1075 | } | ||
| 1076 | |||
| 1077 | |||
| 1078 | static void correctendianess (lua_State *L, char *b, int size, int endianarg) { | ||
| 1079 | int endian = getendian(L, endianarg); | ||
| 1080 | if (endian != nativeendian.little) { /* not native endianess? */ | ||
| 1081 | int i = 0; | ||
| 1082 | while (i < --size) { | ||
| 1083 | char temp = b[i]; | ||
| 1084 | b[i++] = b[size]; | ||
| 1085 | b[size] = temp; | ||
| 1086 | } | ||
| 1087 | } | ||
| 1088 | } | ||
| 1089 | |||
| 1090 | |||
| 1091 | static int getfloatsize (lua_State *L, int arg) { | ||
| 1092 | const char *size = luaL_optstring(L, arg, "n"); | ||
| 1093 | if (*size == 'n') return sizeof(lua_Number); | ||
| 1094 | luaL_argcheck(L, *size == 'd' || *size == 'f', arg, | ||
| 1095 | "size must be 'f'/'d'/'n'"); | ||
| 1096 | return (*size == 'd' ? sizeof(double) : sizeof(float)); | ||
| 1097 | } | ||
| 1098 | |||
| 1099 | |||
| 1100 | static int packfloat_l (lua_State *L) { | ||
| 1101 | float f; double d; | ||
| 1102 | char *pn; /* pointer to number */ | ||
| 1103 | lua_Number n = luaL_checknumber(L, 1); | ||
| 1104 | int size = getfloatsize(L, 2); | ||
| 1105 | if (size == sizeof(lua_Number)) | ||
| 1106 | pn = (char*)&n; | ||
| 1107 | else if (size == sizeof(float)) { | ||
| 1108 | f = (float)n; | ||
| 1109 | pn = (char*)&f; | ||
| 1110 | } | ||
| 1111 | else { /* native lua_Number may be neither float nor double */ | ||
| 1112 | lua_assert(size == sizeof(double)); | ||
| 1113 | d = (double)n; | ||
| 1114 | pn = (char*)&d; | ||
| 1115 | } | ||
| 1116 | correctendianess(L, pn, size, 3); | ||
| 1117 | lua_pushlstring(L, pn, size); | ||
| 1118 | return 1; | ||
| 1119 | } | ||
| 1120 | |||
| 1121 | |||
| 1122 | static int unpackfloat_l (lua_State *L) { | ||
| 1123 | lua_Number res; | ||
| 1124 | size_t len; | ||
| 1125 | const char *s = luaL_checklstring(L, 1, &len); | ||
| 1126 | lua_Integer pos = posrelat(luaL_optinteger(L, 2, 1), len); | ||
| 1127 | int size = getfloatsize(L, 3); | ||
| 1128 | luaL_argcheck(L, 1 <= pos && (size_t)pos + size - 1 <= len, 1, | ||
| 1129 | "string too short"); | ||
| 1130 | if (size == sizeof(lua_Number)) { | ||
| 1131 | memcpy(&res, s + pos - 1, size); | ||
| 1132 | correctendianess(L, (char*)&res, size, 4); | ||
| 1133 | } | ||
| 1134 | else if (size == sizeof(float)) { | ||
| 1135 | float f; | ||
| 1136 | memcpy(&f, s + pos - 1, size); | ||
| 1137 | correctendianess(L, (char*)&f, size, 4); | ||
| 1138 | res = (lua_Number)f; | ||
| 1139 | } | ||
| 1140 | else { /* native lua_Number may be neither float nor double */ | ||
| 1141 | double d; | ||
| 1142 | lua_assert(size == sizeof(double)); | ||
| 1143 | memcpy(&d, s + pos - 1, size); | ||
| 1144 | correctendianess(L, (char*)&d, size, 4); | ||
| 1145 | res = (lua_Number)d; | ||
| 1146 | } | ||
| 1147 | lua_pushnumber(L, res); | ||
| 1148 | return 1; | ||
| 1149 | } | ||
| 1150 | |||
| 1151 | /* }====================================================== */ | ||
| 1152 | |||
| 1153 | |||
| 941 | static const luaL_Reg strlib[] = { | 1154 | static const luaL_Reg strlib[] = { |
| 942 | {"byte", str_byte}, | 1155 | {"byte", str_byte}, |
| 943 | {"char", str_char}, | 1156 | {"char", str_char}, |
| @@ -953,6 +1166,10 @@ static const luaL_Reg strlib[] = { · 9 unmodified lines | |||
| 953 | {"reverse", str_reverse}, | 1166 | {"reverse", str_reverse}, |
| 954 | {"sub", str_sub}, | 1167 | {"sub", str_sub}, |
| 955 | {"upper", str_upper}, | 1168 | {"upper", str_upper}, |
| 1169 | {"packfloat", packfloat_l}, | ||
| 1170 | {"packint", packint_l}, | ||
| 1171 | {"unpackfloat", unpackfloat_l}, | ||
| 1172 | {"unpackint", unpackint_l}, | ||
| 956 | {NULL, NULL} | 1173 | {NULL, NULL} |
| 957 | }; | 1174 | }; |
| 958 | 1175 | ||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: ltable.c,v 2.78 2013/06/20 15:02:49 roberto Exp $ | 2 | ** $Id: ltable.c,v 2.84 2014/01/27 13:34:32 roberto Exp $ |
| 3 | ** Lua tables (hash) | 3 | ** Lua tables (hash) |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -79,7 +79,7 @@ · 73 unmodified lines | |||
| 79 | 79 | ||
| 80 | static const Node dummynode_ = { | 80 | static const Node dummynode_ = { |
| 81 | {NILCONSTANT}, /* value */ | 81 | {NILCONSTANT}, /* value */ |
| 82 | {{NILCONSTANT, NULL}} /* key */ | 82 | {{NILCONSTANT, 0}} /* key */ |
| 83 | }; | 83 | }; |
| 84 | 84 | ||
| 85 | 85 | ||
| @@ -158,6 +158,7 @@ static int findindex (lua_State *L, Table *t, StkId key) { · 72 unmodified lines | |||
| 158 | if (0 < i && i <= t->sizearray) /* is `key' inside array part? */ | 158 | if (0 < i && i <= t->sizearray) /* is `key' inside array part? */ |
| 159 | return i-1; /* yes; that's the index (corrected to C) */ | 159 | return i-1; /* yes; that's the index (corrected to C) */ |
| 160 | else { | 160 | else { |
| 161 | int nx; | ||
| 161 | Node *n = mainposition(t, key); | 162 | Node *n = mainposition(t, key); |
| 162 | for (;;) { /* check whether `key' is somewhere in the chain */ | 163 | for (;;) { /* check whether `key' is somewhere in the chain */ |
| 163 | /* key may be dead already, but it is ok to use it in `next' */ | 164 | /* key may be dead already, but it is ok to use it in `next' */ |
| @@ -168,9 +169,10 @@ static int findindex (lua_State *L, Table *t, StkId key) { · 4 unmodified lines | |||
| 168 | /* hash elements are numbered after array ones */ | 169 | /* hash elements are numbered after array ones */ |
| 169 | return i + t->sizearray; | 170 | return i + t->sizearray; |
| 170 | } | 171 | } |
| 171 | else n = gnext(n); | 172 | nx = gnext(n); |
| 172 | if (n == NULL) | 173 | if (nx == 0) |
| 173 | luaG_runerror(L, "invalid key to " LUA_QL("next")); /* key not found */ | 174 | luaG_runerror(L, "invalid key to " LUA_QL("next")); /* key not found */ |
| 175 | else n += nx; | ||
| 174 | } | 176 | } |
| 175 | } | 177 | } |
| 176 | } | 178 | } |
| @@ -301,7 +303,7 @@ static void setnodevector (lua_State *L, Table *t, int size) { · 124 unmodified lines | |||
| 301 | t->node = luaM_newvector(L, size, Node); | 303 | t->node = luaM_newvector(L, size, Node); |
| 302 | for (i=0; i<size; i++) { | 304 | for (i=0; i<size; i++) { |
| 303 | Node *n = gnode(t, i); | 305 | Node *n = gnode(t, i); |
| 304 | gnext(n) = NULL; | 306 | gnext(n) = 0; |
| 305 | setnilvalue(gkey(n)); | 307 | setnilvalue(gkey(n)); |
| 306 | setnilvalue(gval(n)); | 308 | setnilvalue(gval(n)); |
| 307 | } | 309 | } |
| @@ -376,7 +378,7 @@ static void rehash (lua_State *L, Table *t, const TValue *ek) { · 68 unmodified lines | |||
| 376 | 378 | ||
| 377 | 379 | ||
| 378 | Table *luaH_new (lua_State *L) { | 380 | Table *luaH_new (lua_State *L) { |
| 379 | Table *t = &luaC_newobj(L, LUA_TTABLE, sizeof(Table), NULL, 0)->h; | 381 | Table *t = &luaC_newobj(L, LUA_TTABLE, sizeof(Table))->h; |
| 380 | t->metatable = NULL; | 382 | t->metatable = NULL; |
| 381 | t->flags = cast_byte(~0); | 383 | t->flags = cast_byte(~0); |
| 382 | t->array = NULL; | 384 | t->array = NULL; |
| @@ -419,7 +421,7 @@ TValue *luaH_newkey (lua_State *L, Table *t, const TValue *key) { · 36 unmodified lines | |||
| 419 | else if (ttisfloat(key)) { | 421 | else if (ttisfloat(key)) { |
| 420 | lua_Number n = fltvalue(key); | 422 | lua_Number n = fltvalue(key); |
| 421 | lua_Integer k; | 423 | lua_Integer k; |
| 422 | if (luai_numisnan(L, n)) | 424 | if (luai_numisnan(n)) |
| 423 | luaG_runerror(L, "table index is NaN"); | 425 | luaG_runerror(L, "table index is NaN"); |
| 424 | if (numisinteger(n, &k)) { /* index is int? */ | 426 | if (numisinteger(n, &k)) { /* index is int? */ |
| 425 | setivalue(&aux, k); | 427 | setivalue(&aux, k); |
| @@ -429,31 +431,37 @@ TValue *luaH_newkey (lua_State *L, Table *t, const TValue *key) { · 3 unmodified lines | |||
| 429 | mp = mainposition(t, key); | 431 | mp = mainposition(t, key); |
| 430 | if (!ttisnil(gval(mp)) || isdummy(mp)) { /* main position is taken? */ | 432 | if (!ttisnil(gval(mp)) || isdummy(mp)) { /* main position is taken? */ |
| 431 | Node *othern; | 433 | Node *othern; |
| 432 | Node *n = getfreepos(t); /* get a free place */ | 434 | Node *f = getfreepos(t); /* get a free place */ |
| 433 | if (n == NULL) { /* cannot find a free place? */ | 435 | if (f == NULL) { /* cannot find a free place? */ |
| 434 | rehash(L, t, key); /* grow table */ | 436 | rehash(L, t, key); /* grow table */ |
| 435 | /* whatever called 'newkey' take care of TM cache and GC barrier */ | 437 | /* whatever called 'newkey' take care of TM cache and GC barrier */ |
| 436 | return luaH_set(L, t, key); /* insert key into grown table */ | 438 | return luaH_set(L, t, key); /* insert key into grown table */ |
| 437 | } | 439 | } |
| 438 | lua_assert(!isdummy(n)); | 440 | lua_assert(!isdummy(f)); |
| 439 | othern = mainposition(t, gkey(mp)); | 441 | othern = mainposition(t, gkey(mp)); |
| 440 | if (othern != mp) { /* is colliding node out of its main position? */ | 442 | if (othern != mp) { /* is colliding node out of its main position? */ |
| 441 | /* yes; move colliding node into free position */ | 443 | /* yes; move colliding node into free position */ |
| 442 | while (gnext(othern) != mp) othern = gnext(othern); /* find previous */ | 444 | while (othern + gnext(othern) != mp) /* find previous */ |
| 443 | gnext(othern) = n; /* redo the chain with `n' in place of `mp' */ | 445 | othern += gnext(othern); |
| 444 | *n = *mp; /* copy colliding node into free pos. (mp->next also goes) */ | 446 | gnext(othern) = f - othern; /* re-chain with 'f' in place of 'mp' */ |
| 445 | gnext(mp) = NULL; /* now `mp' is free */ | 447 | *f = *mp; /* copy colliding node into free pos. (mp->next also goes) */ |
| 448 | if (gnext(mp) != 0) { | ||
| 449 | gnext(f) += mp - f; /* correct 'next' */ | ||
| 450 | gnext(mp) = 0; /* now 'mp' is free */ | ||
| 451 | } | ||
| 446 | setnilvalue(gval(mp)); | 452 | setnilvalue(gval(mp)); |
| 447 | } | 453 | } |
| 448 | else { /* colliding node is in its own main position */ | 454 | else { /* colliding node is in its own main position */ |
| 449 | /* new node will go into free position */ | 455 | /* new node will go into free position */ |
| 450 | gnext(n) = gnext(mp); /* chain new position */ | 456 | if (gnext(mp) != 0) |
| 451 | gnext(mp) = n; | 457 | gnext(f) = (mp + gnext(mp)) - f; /* chain new position */ |
| 452 | mp = n; | 458 | else lua_assert(gnext(f) == 0); |
| 459 | gnext(mp) = f - mp; | ||
| 460 | mp = f; | ||
| 453 | } | 461 | } |
| 454 | } | 462 | } |
| 455 | setobj2t(L, gkey(mp), key); | 463 | setobj2t(L, gkey(mp), key); |
| 456 | luaC_barrierback(L, obj2gco(t), key); | 464 | luaC_barrierback(L, t, key); |
| 457 | lua_assert(ttisnil(gval(mp))); | 465 | lua_assert(ttisnil(gval(mp))); |
| 458 | return gval(mp); | 466 | return gval(mp); |
| 459 | } | 467 | } |
| @@ -468,11 +476,15 @@ const TValue *luaH_getint (Table *t, lua_Integer key) { · 8 unmodified lines | |||
| 468 | return &t->array[key - 1]; | 476 | return &t->array[key - 1]; |
| 469 | else { | 477 | else { |
| 470 | Node *n = hashint(t, key); | 478 | Node *n = hashint(t, key); |
| 471 | do { /* check whether `key' is somewhere in the chain */ | 479 | for (;;) { /* check whether `key' is somewhere in the chain */ |
| 472 | if (ttisinteger(gkey(n)) && ivalue(gkey(n)) == key) | 480 | if (ttisinteger(gkey(n)) && ivalue(gkey(n)) == key) |
| 473 | return gval(n); /* that's it */ | 481 | return gval(n); /* that's it */ |
| 474 | else n = gnext(n); | 482 | else { |
| 475 | } while (n); | 483 | int nx = gnext(n); |
| 484 | if (nx == 0) break; | ||
| 485 | n += nx; | ||
| 486 | } | ||
| 487 | }; | ||
| 476 | return luaO_nilobject; | 488 | return luaO_nilobject; |
| 477 | } | 489 | } |
| 478 | } | 490 | } |
| @@ -484,11 +496,15 @@ const TValue *luaH_getint (Table *t, lua_Integer key) { · 5 unmodified lines | |||
| 484 | const TValue *luaH_getstr (Table *t, TString *key) { | 496 | const TValue *luaH_getstr (Table *t, TString *key) { |
| 485 | Node *n = hashstr(t, key); | 497 | Node *n = hashstr(t, key); |
| 486 | lua_assert(key->tsv.tt == LUA_TSHRSTR); | 498 | lua_assert(key->tsv.tt == LUA_TSHRSTR); |
| 487 | do { /* check whether `key' is somewhere in the chain */ | 499 | for (;;) { /* check whether `key' is somewhere in the chain */ |
| 488 | if (ttisshrstring(gkey(n)) && eqshrstr(rawtsvalue(gkey(n)), key)) | 500 | if (ttisshrstring(gkey(n)) && eqshrstr(rawtsvalue(gkey(n)), key)) |
| 489 | return gval(n); /* that's it */ | 501 | return gval(n); /* that's it */ |
| 490 | else n = gnext(n); | 502 | else { |
| 491 | } while (n); | 503 | int nx = gnext(n); |
| 504 | if (nx == 0) break; | ||
| 505 | n += nx; | ||
| 506 | } | ||
| 507 | }; | ||
| 492 | return luaO_nilobject; | 508 | return luaO_nilobject; |
| 493 | } | 509 | } |
| 494 | 510 | ||
| @@ -509,11 +525,15 @@ const TValue *luaH_get (Table *t, const TValue *key) { · 14 unmodified lines | |||
| 509 | } | 525 | } |
| 510 | default: { | 526 | default: { |
| 511 | Node *n = mainposition(t, key); | 527 | Node *n = mainposition(t, key); |
| 512 | do { /* check whether `key' is somewhere in the chain */ | 528 | for (;;) { /* check whether `key' is somewhere in the chain */ |
| 513 | if (luaV_rawequalobj(gkey(n), key)) | 529 | if (luaV_rawequalobj(gkey(n), key)) |
| 514 | return gval(n); /* that's it */ | 530 | return gval(n); /* that's it */ |
| 515 | else n = gnext(n); | 531 | else { |
| 516 | } while (n); | 532 | int nx = gnext(n); |
| 533 | if (nx == 0) break; | ||
| 534 | n += nx; | ||
| 535 | } | ||
| 536 | }; | ||
| 517 | return luaO_nilobject; | 537 | return luaO_nilobject; |
| 518 | } | 538 | } |
| 519 | } | 539 | } |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: ltable.h,v 2.17 2013/04/26 15:39:25 roberto Exp $ | 2 | ** $Id: ltable.h,v 2.18 2013/08/30 16:01:37 roberto Exp $ |
| 3 | ** Lua tables (hash) | 3 | ** Lua tables (hash) |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -18,6 +18,11 @@ · 12 unmodified lines | |||
| 18 | #define invalidateTMcache(t) ((t)->flags = 0) | 18 | #define invalidateTMcache(t) ((t)->flags = 0) |
| 19 | 19 | ||
| 20 | 20 | ||
| 21 | /* returns the key, given the value of a table entry */ | ||
| 22 | #define keyfromval(v) \ | ||
| 23 | (gkey(cast(Node *, cast(char *, (v)) - offsetof(Node, i_val)))) | ||
| 24 | |||
| 25 | |||
| 21 | LUAI_FUNC const TValue *luaH_getint (Table *t, lua_Integer key); | 26 | LUAI_FUNC const TValue *luaH_getint (Table *t, lua_Integer key); |
| 22 | LUAI_FUNC void luaH_setint (lua_State *L, Table *t, lua_Integer key, | 27 | LUAI_FUNC void luaH_setint (lua_State *L, Table *t, lua_Integer key, |
| 23 | TValue *value); | 28 | TValue *value); |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: ltablib.c,v 1.65 2013/03/07 18:17:24 roberto Exp $ | 2 | ** $Id: ltablib.c,v 1.66 2014/03/21 13:52:33 roberto Exp $ |
| 3 | ** Library for Table Manipulation | 3 | ** Library for Table Manipulation |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -140,7 +140,7 @@ static int unpack (lua_State *L) { · 134 unmodified lines | |||
| 140 | e = luaL_opt(L, luaL_checkint, 3, luaL_len(L, 1)); | 140 | e = luaL_opt(L, luaL_checkint, 3, luaL_len(L, 1)); |
| 141 | if (i > e) return 0; /* empty range */ | 141 | if (i > e) return 0; /* empty range */ |
| 142 | n = e - i + 1; /* number of elements */ | 142 | n = e - i + 1; /* number of elements */ |
| 143 | if (n <= 0 || !lua_checkstack(L, n)) /* n <= 0 means arith. overflow */ | 143 | if (n <= 0 || !lua_checkstack(L, n)) /* n <= 0 means arithmetic overflow */ |
| 144 | return luaL_error(L, "too many results to unpack"); | 144 | return luaL_error(L, "too many results to unpack"); |
| 145 | lua_rawgeti(L, 1, i); /* push arg[i] (avoiding overflow problems) */ | 145 | lua_rawgeti(L, 1, i); /* push arg[i] (avoiding overflow problems) */ |
| 146 | while (i++ < e) /* push arg[i + 1...e] */ | 146 | while (i++ < e) /* push arg[i + 1...e] */ |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: ltm.c,v 2.20 2013/05/06 17:19:11 roberto Exp $ | 2 | ** $Id: ltm.c,v 2.25 2013/12/30 20:47:58 roberto Exp $ |
| 3 | ** Tag methods | 3 | ** Tag methods |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -28,7 +28,7 @@ LUAI_DDEF const char *const luaT_typenames_[LUA_TOTALTAGS] = { · 22 unmodified lines | |||
| 28 | "no value", | 28 | "no value", |
| 29 | "nil", "boolean", udatatypename, "number", | 29 | "nil", "boolean", udatatypename, "number", |
| 30 | "string", "table", "function", udatatypename, "thread", | 30 | "string", "table", "function", udatatypename, "thread", |
| 31 | "proto", "upval" /* these last two cases are used for tests only */ | 31 | "proto" /* this last case is used for tests only */ |
| 32 | }; | 32 | }; |
| 33 | 33 | ||
| 34 | 34 | ||
| @@ -36,14 +36,16 @@ void luaT_init (lua_State *L) { · 1 unmodified line | |||
| 36 | static const char *const luaT_eventname[] = { /* ORDER TM */ | 36 | static const char *const luaT_eventname[] = { /* ORDER TM */ |
| 37 | "__index", "__newindex", | 37 | "__index", "__newindex", |
| 38 | "__gc", "__mode", "__len", "__eq", | 38 | "__gc", "__mode", "__len", "__eq", |
| 39 | "__add", "__sub", "__mul", "__div", "__idiv", "__mod", | 39 | "__add", "__sub", "__mul", "__mod", "__pow", |
| 40 | "__pow", "__unm", "__lt", "__le", | 40 | "__div", "__idiv", |
| 41 | "__band", "__bor", "__bxor", "__shl", "__shr", | ||
| 42 | "__unm", "__bnot", "__lt", "__le", | ||
| 41 | "__concat", "__call" | 43 | "__concat", "__call" |
| 42 | }; | 44 | }; |
| 43 | int i; | 45 | int i; |
| 44 | for (i=0; i<TM_N; i++) { | 46 | for (i=0; i<TM_N; i++) { |
| 45 | G(L)->tmname[i] = luaS_new(L, luaT_eventname[i]); | 47 | G(L)->tmname[i] = luaS_new(L, luaT_eventname[i]); |
| 46 | luaS_fix(G(L)->tmname[i]); /* never collect these names */ | 48 | luaC_fix(L, obj2gco(G(L)->tmname[i])); /* never collect these names */ |
| 47 | } | 49 | } |
| 48 | } | 50 | } |
| 49 | 51 | ||
| @@ -110,12 +112,17 @@ int luaT_callbinTM (lua_State *L, const TValue *p1, const TValue *p2, · 60 unmodified lines | |||
| 110 | void luaT_trybinTM (lua_State *L, const TValue *p1, const TValue *p2, | 112 | void luaT_trybinTM (lua_State *L, const TValue *p1, const TValue *p2, |
| 111 | StkId res, TMS event) { | 113 | StkId res, TMS event) { |
| 112 | if (!luaT_callbinTM(L, p1, p2, res, event)) { | 114 | if (!luaT_callbinTM(L, p1, p2, res, event)) { |
| 113 | if (event == TM_CONCAT) | 115 | switch (event) { |
| 114 | luaG_concaterror(L, p1, p2); | 116 | case TM_CONCAT: |
| 115 | else if (event == TM_IDIV && ttisnumber(p1) && ttisnumber(p2)) | 117 | luaG_concaterror(L, p1, p2); |
| 116 | luaG_tointerror(L, p1, p2); | 118 | case TM_IDIV: case TM_BAND: case TM_BOR: case TM_BXOR: |
| 117 | else | 119 | case TM_SHL: case TM_SHR: case TM_BNOT: |
| 118 | luaG_aritherror(L, p1, p2); | 120 | if (ttisnumber(p1) && ttisnumber(p2)) |
| 121 | luaG_tointerror(L, p1, p2); | ||
| 122 | /* else go through */ | ||
| 123 | default: | ||
| 124 | luaG_aritherror(L, p1, p2); | ||
| 125 | } | ||
| 119 | } | 126 | } |
| 120 | } | 127 | } |
| 121 | 128 | ||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: ltm.h,v 2.16 2013/04/29 16:56:50 roberto Exp $ | 2 | ** $Id: ltm.h,v 2.19 2013/12/30 20:47:58 roberto Exp $ |
| 3 | ** Tag methods | 3 | ** Tag methods |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -13,7 +13,7 @@ · 7 unmodified lines | |||
| 13 | 13 | ||
| 14 | /* | 14 | /* |
| 15 | * WARNING: if you change the order of this enumeration, | 15 | * WARNING: if you change the order of this enumeration, |
| 16 | * grep "ORDER TM" | 16 | * grep "ORDER TM" and "ORDER OP" |
| 17 | */ | 17 | */ |
| 18 | typedef enum { | 18 | typedef enum { |
| 19 | TM_INDEX, | 19 | TM_INDEX, |
| @@ -25,11 +25,17 @@ typedef enum { · 5 unmodified lines | |||
| 25 | TM_ADD, | 25 | TM_ADD, |
| 26 | TM_SUB, | 26 | TM_SUB, |
| 27 | TM_MUL, | 27 | TM_MUL, |
| 28 | TM_DIV, | ||
| 29 | TM_IDIV, | ||
| 30 | TM_MOD, | 28 | TM_MOD, |
| 31 | TM_POW, | 29 | TM_POW, |
| 30 | TM_DIV, | ||
| 31 | TM_IDIV, | ||
| 32 | TM_BAND, | ||
| 33 | TM_BOR, | ||
| 34 | TM_BXOR, | ||
| 35 | TM_SHL, | ||
| 36 | TM_SHR, | ||
| 32 | TM_UNM, | 37 | TM_UNM, |
| 38 | TM_BNOT, | ||
| 33 | TM_LT, | 39 | TM_LT, |
| 34 | TM_LE, | 40 | TM_LE, |
| 35 | TM_CONCAT, | 41 | TM_CONCAT, |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lua.c,v 1.206 2012/09/29 20:07:06 roberto Exp $ | 2 | ** $Id: lua.c,v 1.210 2014/02/26 15:27:56 roberto Exp $ |
| 3 | ** Lua stand-alone interpreter | 3 | ** Lua stand-alone interpreter |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -31,28 +31,38 @@ · 25 unmodified lines | |||
| 31 | #define LUA_MAXINPUT 512 | 31 | #define LUA_MAXINPUT 512 |
| 32 | #endif | 32 | #endif |
| 33 | 33 | ||
| 34 | #if !defined(LUA_INIT) | 34 | #if !defined(LUA_INIT_VAR) |
| 35 | #define LUA_INIT "LUA_INIT" | 35 | #define LUA_INIT_VAR "LUA_INIT" |
| 36 | #endif | 36 | #endif |
| 37 | 37 | ||
| 38 | #define LUA_INITVERSION \ | 38 | #define LUA_INITVARVERSION \ |
| 39 | LUA_INIT "_" LUA_VERSION_MAJOR "_" LUA_VERSION_MINOR | 39 | LUA_INIT_VAR "_" LUA_VERSION_MAJOR "_" LUA_VERSION_MINOR |
| 40 | 40 | ||
| 41 | 41 | ||
| 42 | /* | 42 | /* |
| 43 | ** lua_stdin_is_tty detects whether the standard input is a 'tty' (that | 43 | ** lua_stdin_is_tty detects whether the standard input is a 'tty' (that |
| 44 | ** is, whether we're running lua interactively). | 44 | ** is, whether we're running lua interactively). |
| 45 | */ | 45 | */ |
| 46 | #if defined(LUA_USE_ISATTY) | 46 | #if !defined(lua_stdin_is_tty) /* { */ |
| 47 | |||
| 48 | #if defined(LUA_USE_POSIX) /* { */ | ||
| 49 | |||
| 47 | #include <unistd.h> | 50 | #include <unistd.h> |
| 48 | #define lua_stdin_is_tty() isatty(0) | 51 | #define lua_stdin_is_tty() isatty(0) |
| 49 | #elif defined(LUA_WIN) | 52 | |
| 53 | #elif defined(LUA_WIN) /* }{ */ | ||
| 54 | |||
| 50 | #include <io.h> | 55 | #include <io.h> |
| 51 | #include <stdio.h> | ||
| 52 | #define lua_stdin_is_tty() _isatty(_fileno(stdin)) | 56 | #define lua_stdin_is_tty() _isatty(_fileno(stdin)) |
| 53 | #else | 57 | |
| 58 | #else /* }{ */ | ||
| 59 | |||
| 60 | /* ANSI definition */ | ||
| 54 | #define lua_stdin_is_tty() 1 /* assume stdin is a tty */ | 61 | #define lua_stdin_is_tty() 1 /* assume stdin is a tty */ |
| 55 | #endif | 62 | |
| 63 | #endif /* } */ | ||
| 64 | |||
| 65 | #endif /* } */ | ||
| 56 | 66 | ||
| 57 | 67 | ||
| 58 | /* | 68 | /* |
| @@ -61,9 +71,10 @@ · 2 unmodified lines | |||
| 61 | ** lua_saveline defines how to "save" a read line in a "history". | 71 | ** lua_saveline defines how to "save" a read line in a "history". |
| 62 | ** lua_freeline defines how to free a line read by lua_readline. | 72 | ** lua_freeline defines how to free a line read by lua_readline. |
| 63 | */ | 73 | */ |
| 64 | #if defined(LUA_USE_READLINE) | 74 | #if !defined(lua_readline) /* { */ |
| 75 | |||
| 76 | #if defined(LUA_USE_READLINE) /* { */ | ||
| 65 | 77 | ||
| 66 | #include <stdio.h> | ||
| 67 | #include <readline/readline.h> | 78 | #include <readline/readline.h> |
| 68 | #include <readline/history.h> | 79 | #include <readline/history.h> |
| 69 | #define lua_readline(L,b,p) ((void)L, ((b)=readline(p)) != NULL) | 80 | #define lua_readline(L,b,p) ((void)L, ((b)=readline(p)) != NULL) |
| @@ -72,7 +83,7 @@ · 2 unmodified lines | |||
| 72 | add_history(lua_tostring(L, idx)); /* add it to history */ | 83 | add_history(lua_tostring(L, idx)); /* add it to history */ |
| 73 | #define lua_freeline(L,b) ((void)L, free(b)) | 84 | #define lua_freeline(L,b) ((void)L, free(b)) |
| 74 | 85 | ||
| 75 | #elif !defined(lua_readline) | 86 | #else /* }{ */ |
| 76 | 87 | ||
| 77 | #define lua_readline(L,b,p) \ | 88 | #define lua_readline(L,b,p) \ |
| 78 | ((void)L, fputs(p, stdout), fflush(stdout), /* show prompt */ \ | 89 | ((void)L, fputs(p, stdout), fflush(stdout), /* show prompt */ \ |
| @@ -80,7 +91,9 @@ · 1 unmodified line | |||
| 80 | #define lua_saveline(L,idx) { (void)L; (void)idx; } | 91 | #define lua_saveline(L,idx) { (void)L; (void)idx; } |
| 81 | #define lua_freeline(L,b) { (void)L; (void)b; } | 92 | #define lua_freeline(L,b) { (void)L; (void)b; } |
| 82 | 93 | ||
| 83 | #endif | 94 | #endif /* } */ |
| 95 | |||
| 96 | #endif /* } */ | ||
| 84 | 97 | ||
| 85 | 98 | ||
| 86 | 99 | ||
| @@ -257,20 +270,21 @@ static int incomplete (lua_State *L, int status) { · 170 unmodified lines | |||
| 257 | } | 270 | } |
| 258 | 271 | ||
| 259 | 272 | ||
| 273 | /* prompt the user, read a line, and push it into the Lua stack */ | ||
| 260 | static int pushline (lua_State *L, int firstline) { | 274 | static int pushline (lua_State *L, int firstline) { |
| 261 | char buffer[LUA_MAXINPUT]; | 275 | char buffer[LUA_MAXINPUT]; |
| 262 | char *b = buffer; | 276 | char *b = buffer; |
| 263 | size_t l; | 277 | size_t l; |
| 264 | const char *prmt = get_prompt(L, firstline); | 278 | const char *prmt = get_prompt(L, firstline); |
| 265 | int readstatus = lua_readline(L, b, prmt); | 279 | int readstatus = lua_readline(L, b, prmt); |
| 266 | lua_pop(L, 1); /* remove result from 'get_prompt' */ | ||
| 267 | if (readstatus == 0) | 280 | if (readstatus == 0) |
| 268 | return 0; /* no input */ | 281 | return 0; /* no input (prompt will be popped by caller) */ |
| 282 | lua_pop(L, 1); /* remove prompt */ | ||
| 269 | l = strlen(b); | 283 | l = strlen(b); |
| 270 | if (l > 0 && b[l-1] == '\n') /* line ends with newline? */ | 284 | if (l > 0 && b[l-1] == '\n') /* line ends with newline? */ |
| 271 | b[l-1] = '\0'; /* remove it */ | 285 | b[l-1] = '\0'; /* remove it */ |
| 272 | if (firstline && b[0] == '=') /* first line starts with `=' ? */ | 286 | if (firstline && b[0] == '=') /* for compatibility with 5.2, ... */ |
| 273 | lua_pushfstring(L, "return %s", b+1); /* change it to `return' */ | 287 | lua_pushfstring(L, "return %s", b + 1); /* change '=' to 'return' */ |
| 274 | else | 288 | else |
| 275 | lua_pushstring(L, b); | 289 | lua_pushstring(L, b); |
| 276 | lua_freeline(L, b); | 290 | lua_freeline(L, b); |
| @@ -278,24 +292,48 @@ static int pushline (lua_State *L, int firstline) { · 1 unmodified line | |||
| 278 | } | 292 | } |
| 279 | 293 | ||
| 280 | 294 | ||
| 281 | static int loadline (lua_State *L) { | 295 | /* try to compile line on the stack as 'return <line>'; on return, stack |
| 296 | has either compiled chunk or original line (if compilation failed) */ | ||
| 297 | static int addreturn (lua_State *L) { | ||
| 282 | int status; | 298 | int status; |
| 283 | lua_settop(L, 0); | 299 | size_t len; const char *line; |
| 284 | if (!pushline(L, 1)) | 300 | lua_pushliteral(L, "return "); |
| 285 | return -1; /* no input */ | 301 | lua_pushvalue(L, -2); /* duplicate line */ |
| 302 | lua_concat(L, 2); /* new line is "return ..." */ | ||
| 303 | line = lua_tolstring(L, -1, &len); | ||
| 304 | if ((status = luaL_loadbuffer(L, line, len, "=stdin")) == LUA_OK) | ||
| 305 | lua_remove(L, -3); /* remove original line */ | ||
| 306 | else | ||
| 307 | lua_pop(L, 2); /* remove result from 'luaL_loadbuffer' and new line */ | ||
| 308 | return status; | ||
| 309 | } | ||
| 310 | |||
| 311 | |||
| 312 | /* read multiple lines until a complete line */ | ||
| 313 | static int multiline (lua_State *L) { | ||
| 286 | for (;;) { /* repeat until gets a complete line */ | 314 | for (;;) { /* repeat until gets a complete line */ |
| 287 | size_t l; | 315 | size_t len; |
| 288 | const char *line = lua_tolstring(L, 1, &l); | 316 | const char *line = lua_tolstring(L, 1, &len); /* get what it has */ |
| 289 | status = luaL_loadbuffer(L, line, l, "=stdin"); | 317 | int status = luaL_loadbuffer(L, line, len, "=stdin"); /* try it */ |
| 290 | if (!incomplete(L, status)) break; /* cannot try to add lines? */ | 318 | if (!incomplete(L, status) || !pushline(L, 0)) |
| 291 | if (!pushline(L, 0)) /* no more input? */ | 319 | return status; /* cannot/should not try to add continuation line */ |
| 292 | return -1; | 320 | lua_pushliteral(L, "\n"); /* add newline... */ |
| 293 | lua_pushliteral(L, "\n"); /* add a new line... */ | ||
| 294 | lua_insert(L, -2); /* ...between the two lines */ | 321 | lua_insert(L, -2); /* ...between the two lines */ |
| 295 | lua_concat(L, 3); /* join them */ | 322 | lua_concat(L, 3); /* join them */ |
| 296 | } | 323 | } |
| 324 | } | ||
| 325 | |||
| 326 | |||
| 327 | static int loadline (lua_State *L) { | ||
| 328 | int status; | ||
| 329 | lua_settop(L, 0); | ||
| 330 | if (!pushline(L, 1)) | ||
| 331 | return -1; /* no input */ | ||
| 332 | if ((status = addreturn(L)) != LUA_OK) /* 'return ...' did not work? */ | ||
| 333 | status = multiline(L); /* try as command, maybe with continuation lines */ | ||
| 297 | lua_saveline(L, 1); | 334 | lua_saveline(L, 1); |
| 298 | lua_remove(L, 1); /* remove line */ | 335 | lua_remove(L, 1); /* remove line */ |
| 336 | lua_assert(lua_gettop(L) == 1); | ||
| 299 | return status; | 337 | return status; |
| 300 | } | 338 | } |
| 301 | 339 | ||
| @@ -421,10 +459,10 @@ static int runargs (lua_State *L, char **argv, int n) { · 119 unmodified lines | |||
| 421 | 459 | ||
| 422 | 460 | ||
| 423 | static int handle_luainit (lua_State *L) { | 461 | static int handle_luainit (lua_State *L) { |
| 424 | const char *name = "=" LUA_INITVERSION; | 462 | const char *name = "=" LUA_INITVARVERSION; |
| 425 | const char *init = getenv(name + 1); | 463 | const char *init = getenv(name + 1); |
| 426 | if (init == NULL) { | 464 | if (init == NULL) { |
| 427 | name = "=" LUA_INIT; | 465 | name = "=" LUA_INIT_VAR; |
| 428 | init = getenv(name + 1); /* try alternative name */ | 466 | init = getenv(name + 1); /* try alternative name */ |
| 429 | } | 467 | } |
| 430 | if (init == NULL) return LUA_OK; | 468 | if (init == NULL) return LUA_OK; |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lua.h,v 1.292 2013/07/05 14:29:51 roberto Exp $ | 2 | ** $Id: lua.h,v 1.302 2014/03/20 19:42:35 roberto Exp $ |
| 3 | ** Lua - A Scripting Language | 3 | ** Lua - A Scripting Language |
| 4 | ** Lua.org, PUC-Rio, Brazil (http://www.lua.org) | 4 | ** Lua.org, PUC-Rio, Brazil (http://www.lua.org) |
| 5 | ** See Copyright Notice at the end of this file | 5 | ** See Copyright Notice at the end of this file |
| @@ -19,11 +19,11 @@ · 13 unmodified lines | |||
| 19 | #define LUA_VERSION_MAJOR "5" | 19 | #define LUA_VERSION_MAJOR "5" |
| 20 | #define LUA_VERSION_MINOR "3" | 20 | #define LUA_VERSION_MINOR "3" |
| 21 | #define LUA_VERSION_NUM 503 | 21 | #define LUA_VERSION_NUM 503 |
| 22 | #define LUA_VERSION_RELEASE "0 (work1)" | 22 | #define LUA_VERSION_RELEASE "0 (work2)" |
| 23 | 23 | ||
| 24 | #define LUA_VERSION "Lua " LUA_VERSION_MAJOR "." LUA_VERSION_MINOR | 24 | #define LUA_VERSION "Lua " LUA_VERSION_MAJOR "." LUA_VERSION_MINOR |
| 25 | #define LUA_RELEASE LUA_VERSION "." LUA_VERSION_RELEASE | 25 | #define LUA_RELEASE LUA_VERSION "." LUA_VERSION_RELEASE |
| 26 | #define LUA_COPYRIGHT LUA_RELEASE " Copyright (C) 1994-2013 Lua.org, PUC-Rio" | 26 | #define LUA_COPYRIGHT LUA_RELEASE " Copyright (C) 1994-2014 Lua.org, PUC-Rio" |
| 27 | #define LUA_AUTHORS "R. Ierusalimschy, L. H. de Figueiredo, W. Celes" | 27 | #define LUA_AUTHORS "R. Ierusalimschy, L. H. de Figueiredo, W. Celes" |
| 28 | 28 | ||
| 29 | 29 | ||
| @@ -182,14 +182,20 @@ LUA_API const void *(lua_topointer) (lua_State *L, int idx); · 152 unmodified lines | |||
| 182 | ** Comparison and arithmetic functions | 182 | ** Comparison and arithmetic functions |
| 183 | */ | 183 | */ |
| 184 | 184 | ||
| 185 | #define LUA_OPADD 0 /* ORDER TM */ | 185 | #define LUA_OPADD 0 /* ORDER TM, ORDER OP */ |
| 186 | #define LUA_OPSUB 1 | 186 | #define LUA_OPSUB 1 |
| 187 | #define LUA_OPMUL 2 | 187 | #define LUA_OPMUL 2 |
| 188 | #define LUA_OPDIV 3 | 188 | #define LUA_OPMOD 3 |
| 189 | #define LUA_OPIDIV 4 | 189 | #define LUA_OPPOW 4 |
| 190 | #define LUA_OPMOD 5 | 190 | #define LUA_OPDIV 5 |
| 191 | #define LUA_OPPOW 6 | 191 | #define LUA_OPIDIV 6 |
| 192 | #define LUA_OPUNM 7 | 192 | #define LUA_OPBAND 7 |
| 193 | #define LUA_OPBOR 8 | ||
| 194 | #define LUA_OPBXOR 9 | ||
| 195 | #define LUA_OPSHL 10 | ||
| 196 | #define LUA_OPSHR 11 | ||
| 197 | #define LUA_OPUNM 12 | ||
| 198 | #define LUA_OPBNOT 13 | ||
| 193 | 199 | ||
| 194 | LUA_API void (lua_arith) (lua_State *L, int op); | 200 | LUA_API void (lua_arith) (lua_State *L, int op); |
| 195 | 201 | ||
| @@ -222,12 +228,13 @@ LUA_API int (lua_pushthread) (lua_State *L); · 26 unmodified lines | |||
| 222 | /* | 228 | /* |
| 223 | ** get functions (Lua -> stack) | 229 | ** get functions (Lua -> stack) |
| 224 | */ | 230 | */ |
| 225 | LUA_API void (lua_getglobal) (lua_State *L, const char *var); | 231 | LUA_API int (lua_getglobal) (lua_State *L, const char *var); |
| 226 | LUA_API void (lua_gettable) (lua_State *L, int idx); | 232 | LUA_API int (lua_gettable) (lua_State *L, int idx); |
| 227 | LUA_API void (lua_getfield) (lua_State *L, int idx, const char *k); | 233 | LUA_API int (lua_getfield) (lua_State *L, int idx, const char *k); |
| 228 | LUA_API void (lua_rawget) (lua_State *L, int idx); | 234 | LUA_API int (lua_rawget) (lua_State *L, int idx); |
| 229 | LUA_API void (lua_rawgeti) (lua_State *L, int idx, lua_Integer n); | 235 | LUA_API int (lua_rawgeti) (lua_State *L, int idx, lua_Integer n); |
| 230 | LUA_API void (lua_rawgetp) (lua_State *L, int idx, const void *p); | 236 | LUA_API int (lua_rawgetp) (lua_State *L, int idx, const void *p); |
| 237 | |||
| 231 | LUA_API void (lua_createtable) (lua_State *L, int narr, int nrec); | 238 | LUA_API void (lua_createtable) (lua_State *L, int narr, int nrec); |
| 232 | LUA_API void *(lua_newuserdata) (lua_State *L, size_t sz); | 239 | LUA_API void *(lua_newuserdata) (lua_State *L, size_t sz); |
| 233 | LUA_API int (lua_getmetatable) (lua_State *L, int objindex); | 240 | LUA_API int (lua_getmetatable) (lua_State *L, int objindex); |
| @@ -264,7 +271,7 @@ LUA_API int (lua_load) (lua_State *L, lua_Reader reader, void *dt, · 30 unmodified lines | |||
| 264 | const char *chunkname, | 271 | const char *chunkname, |
| 265 | const char *mode); | 272 | const char *mode); |
| 266 | 273 | ||
| 267 | LUA_API int (lua_dump) (lua_State *L, lua_Writer writer, void *data); | 274 | LUA_API int (lua_dump) (lua_State *L, lua_Writer writer, void *data, int strip); |
| 268 | 275 | ||
| 269 | 276 | ||
| 270 | /* | 277 | /* |
| @@ -288,10 +295,7 @@ LUA_API int (lua_status) (lua_State *L); · 17 unmodified lines | |||
| 288 | #define LUA_GCSTEP 5 | 295 | #define LUA_GCSTEP 5 |
| 289 | #define LUA_GCSETPAUSE 6 | 296 | #define LUA_GCSETPAUSE 6 |
| 290 | #define LUA_GCSETSTEPMUL 7 | 297 | #define LUA_GCSETSTEPMUL 7 |
| 291 | #define LUA_GCSETMAJORINC 8 | ||
| 292 | #define LUA_GCISRUNNING 9 | 298 | #define LUA_GCISRUNNING 9 |
| 293 | #define LUA_GCGEN 10 | ||
| 294 | #define LUA_GCINC 11 | ||
| 295 | 299 | ||
| 296 | LUA_API int (lua_gc) (lua_State *L, int what, int data); | 300 | LUA_API int (lua_gc) (lua_State *L, int what, int data); |
| 297 | 301 | ||
| @@ -394,7 +398,7 @@ LUA_API void *(lua_upvalueid) (lua_State *L, int fidx, int n); · 96 unmodified lines | |||
| 394 | LUA_API void (lua_upvaluejoin) (lua_State *L, int fidx1, int n1, | 398 | LUA_API void (lua_upvaluejoin) (lua_State *L, int fidx1, int n1, |
| 395 | int fidx2, int n2); | 399 | int fidx2, int n2); |
| 396 | 400 | ||
| 397 | LUA_API int (lua_sethook) (lua_State *L, lua_Hook func, int mask, int count); | 401 | LUA_API void (lua_sethook) (lua_State *L, lua_Hook func, int mask, int count); |
| 398 | LUA_API lua_Hook (lua_gethook) (lua_State *L); | 402 | LUA_API lua_Hook (lua_gethook) (lua_State *L); |
| 399 | LUA_API int (lua_gethookmask) (lua_State *L); | 403 | LUA_API int (lua_gethookmask) (lua_State *L); |
| 400 | LUA_API int (lua_gethookcount) (lua_State *L); | 404 | LUA_API int (lua_gethookcount) (lua_State *L); |
| @@ -422,7 +426,7 @@ struct lua_Debug { · 21 unmodified lines | |||
| 422 | 426 | ||
| 423 | 427 | ||
| 424 | /****************************************************************************** | 428 | /****************************************************************************** |
| 425 | * Copyright (C) 1994-2013 Lua.org, PUC-Rio. | 429 | * Copyright (C) 1994-2014 Lua.org, PUC-Rio. |
| 426 | * | 430 | * |
| 427 | * Permission is hereby granted, free of charge, to any person obtaining | 431 | * Permission is hereby granted, free of charge, to any person obtaining |
| 428 | * a copy of this software and associated documentation files (the | 432 | * a copy of this software and associated documentation files (the |
| @@ -202,7 +202,7 @@ int main(int argc, char* argv[]) · 201 unmodified lines | |||
| 202 | return EXIT_SUCCESS; | 202 | return EXIT_SUCCESS; |
| 203 | } | 203 | } |
| 204 | 204 | ||
| 205 | #define nvalue(x) 0 | 205 | #define nvalue(x) ((lua_Number)0) |
| 206 | #define ttypenv(x) ttnov(x) | 206 | #define ttypenv(x) ttnov(x) |
| 207 | /* | 207 | /* |
| 208 | ** $Id: print.c,v 1.69 2013/07/04 01:03:46 lhf Exp $ | 208 | ** $Id: print.c,v 1.69 2013/07/04 01:03:46 lhf Exp $ |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: luaconf.h,v 1.185 2013/06/25 19:04:40 roberto Exp $ | 2 | ** $Id: luaconf.h,v 1.193 2014/03/21 14:27:16 roberto Exp $ |
| 3 | ** Configuration file for Lua | 3 | ** Configuration file for Lua |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -19,6 +19,24 @@ · 13 unmodified lines | |||
| 19 | */ | 19 | */ |
| 20 | 20 | ||
| 21 | 21 | ||
| 22 | /* | ||
| 23 | ** =================================================================== | ||
| 24 | @@ LUA_INT_INT / LUA_INT_LONG / LUA_INT_LONGLONG defines size for | ||
| 25 | @* Lua integers; | ||
| 26 | @@ LUA_REAL_FLOAT / LUA_REAL_DOUBLE / LUA_REAL_LONGDOUBLE defines size for | ||
| 27 | @* Lua floats. | ||
| 28 | ** | ||
| 29 | ** These definitions set the numeric types for Lua. Lua should work | ||
| 30 | ** fine with 32-bit or 64-bit integers mixed with 32-bit or 64-bit | ||
| 31 | ** floats. The usual configurations are 64-bit integers and floats (the | ||
| 32 | ** default) and 32-bit integers and floats (Small Lua, for restricted | ||
| 33 | ** hardware). | ||
| 34 | ** ===================================================================== | ||
| 35 | */ | ||
| 36 | #define LUA_INT_LONGLONG | ||
| 37 | #define LUA_REAL_DOUBLE | ||
| 38 | |||
| 39 | |||
| 22 | /* | 40 | /* |
| 23 | @@ LUA_ANSI controls the use of non-ansi features. | 41 | @@ LUA_ANSI controls the use of non-ansi features. |
| 24 | ** CHANGE it (define it) if you want Lua to avoid the use of any | 42 | ** CHANGE it (define it) if you want Lua to avoid the use of any |
| @@ -41,24 +59,28 @@ · 16 unmodified lines | |||
| 41 | 59 | ||
| 42 | 60 | ||
| 43 | #if defined(LUA_USE_LINUX) | 61 | #if defined(LUA_USE_LINUX) |
| 62 | #define LUA_USE_C99 | ||
| 44 | #define LUA_USE_POSIX | 63 | #define LUA_USE_POSIX |
| 45 | #define LUA_USE_DLOPEN /* needs an extra library: -ldl */ | 64 | #define LUA_USE_DLOPEN /* needs an extra library: -ldl */ |
| 46 | #define LUA_USE_READLINE /* needs some extra libraries */ | 65 | #define LUA_USE_READLINE /* needs some extra libraries */ |
| 47 | #define LUA_USE_STRTODHEX /* assume 'strtod' handles hex formats */ | ||
| 48 | #define LUA_USE_AFORMAT /* assume 'printf' handles 'aA' specifiers */ | ||
| 49 | #define LUA_USE_LONGLONG /* assume support for long long */ | ||
| 50 | #endif | 66 | #endif |
| 51 | 67 | ||
| 52 | #if defined(LUA_USE_MACOSX) | 68 | #if defined(LUA_USE_MACOSX) |
| 69 | #define LUA_USE_C99 | ||
| 53 | #define LUA_USE_POSIX | 70 | #define LUA_USE_POSIX |
| 54 | #define LUA_USE_DLOPEN /* does not need -ldl */ | 71 | #define LUA_USE_DLOPEN /* does not need -ldl */ |
| 55 | #define LUA_USE_READLINE /* needs an extra library: -lreadline */ | 72 | #define LUA_USE_READLINE /* needs an extra library: -lreadline */ |
| 56 | #define LUA_USE_STRTODHEX /* assume 'strtod' handles hex formats */ | ||
| 57 | #define LUA_USE_AFORMAT /* assume 'printf' handles 'aA' specifiers */ | ||
| 58 | #define LUA_USE_LONGLONG /* assume support for long long */ | ||
| 59 | #endif | 73 | #endif |
| 60 | 74 | ||
| 61 | 75 | ||
| 76 | /* | ||
| 77 | @@ LUA_USE_C99 includes all functionality from C 99. | ||
| 78 | ** CHANGE it (define it) if your system is compatible. | ||
| 79 | */ | ||
| 80 | #if defined(LUA_USE_C99) | ||
| 81 | #define LUA_USE_AFORMAT /* assume 'printf' handles 'aA' specifiers */ | ||
| 82 | #endif | ||
| 83 | |||
| 62 | 84 | ||
| 63 | /* | 85 | /* |
| 64 | @@ LUA_USE_POSIX includes all functionality listed as X/Open System | 86 | @@ LUA_USE_POSIX includes all functionality listed as X/Open System |
| @@ -66,11 +88,6 @@ · 1 unmodified line | |||
| 66 | ** CHANGE it (define it) if your system is XSI compatible. | 88 | ** CHANGE it (define it) if your system is XSI compatible. |
| 67 | */ | 89 | */ |
| 68 | #if defined(LUA_USE_POSIX) | 90 | #if defined(LUA_USE_POSIX) |
| 69 | #define LUA_USE_MKSTEMP | ||
| 70 | #define LUA_USE_ISATTY | ||
| 71 | #define LUA_USE_POPEN | ||
| 72 | #define LUA_USE_ULONGJMP | ||
| 73 | #define LUA_USE_GMTIME_R | ||
| 74 | #endif | 91 | #endif |
| 75 | 92 | ||
| 76 | 93 | ||
| @@ -93,7 +110,8 @@ · 16 unmodified lines | |||
| 93 | #define LUA_CDIR "!\\" | 110 | #define LUA_CDIR "!\\" |
| 94 | #define LUA_PATH_DEFAULT \ | 111 | #define LUA_PATH_DEFAULT \ |
| 95 | LUA_LDIR"?.lua;" LUA_LDIR"?\\init.lua;" \ | 112 | LUA_LDIR"?.lua;" LUA_LDIR"?\\init.lua;" \ |
| 96 | LUA_CDIR"?.lua;" LUA_CDIR"?\\init.lua;" ".\\?.lua" | 113 | LUA_CDIR"?.lua;" LUA_CDIR"?\\init.lua;" \ |
| 114 | ".\\?.lua;" ".\\?\\init.lua" | ||
| 97 | #define LUA_CPATH_DEFAULT \ | 115 | #define LUA_CPATH_DEFAULT \ |
| 98 | LUA_CDIR"?.dll;" LUA_CDIR"loadall.dll;" ".\\?.dll" | 116 | LUA_CDIR"?.dll;" LUA_CDIR"loadall.dll;" ".\\?.dll" |
| 99 | 117 | ||
| @@ -105,7 +123,8 @@ · 5 unmodified lines | |||
| 105 | #define LUA_CDIR LUA_ROOT "lib/lua/" LUA_VDIR | 123 | #define LUA_CDIR LUA_ROOT "lib/lua/" LUA_VDIR |
| 106 | #define LUA_PATH_DEFAULT \ | 124 | #define LUA_PATH_DEFAULT \ |
| 107 | LUA_LDIR"?.lua;" LUA_LDIR"?/init.lua;" \ | 125 | LUA_LDIR"?.lua;" LUA_LDIR"?/init.lua;" \ |
| 108 | LUA_CDIR"?.lua;" LUA_CDIR"?/init.lua;" "./?.lua" | 126 | LUA_CDIR"?.lua;" LUA_CDIR"?/init.lua;" \ |
| 127 | "./?.lua;" "./?/init.lua" | ||
| 109 | #define LUA_CPATH_DEFAULT \ | 128 | #define LUA_CPATH_DEFAULT \ |
| 110 | LUA_CDIR"?.so;" LUA_CDIR"loadall.so;" "./?.so" | 129 | LUA_CDIR"?.so;" LUA_CDIR"loadall.so;" "./?.so" |
| 111 | #endif /* } */ | 130 | #endif /* } */ |
| @@ -246,6 +265,11 @@ · 134 unmodified lines | |||
| 246 | */ | 265 | */ |
| 247 | #if defined(LUA_COMPAT_ALL) /* { */ | 266 | #if defined(LUA_COMPAT_ALL) /* { */ |
| 248 | 267 | ||
| 268 | /* | ||
| 269 | @@ LUA_COMPAT_BITLIB controls the presence of library 'bit32'. | ||
| 270 | */ | ||
| 271 | #define LUA_COMPAT_BITLIB | ||
| 272 | |||
| 249 | /* | 273 | /* |
| 250 | @@ LUA_COMPAT_UNPACK controls the presence of global 'unpack'. | 274 | @@ LUA_COMPAT_UNPACK controls the presence of global 'unpack'. |
| 251 | ** You can replace it with 'table.unpack'. | 275 | ** You can replace it with 'table.unpack'. |
| @@ -350,7 +374,7 @@ · 98 unmodified lines | |||
| 350 | /* | 374 | /* |
| 351 | @@ LUAI_MAXSTACK limits the size of the Lua stack. | 375 | @@ LUAI_MAXSTACK limits the size of the Lua stack. |
| 352 | ** CHANGE it if you need a different limit. This limit is arbitrary; | 376 | ** CHANGE it if you need a different limit. This limit is arbitrary; |
| 353 | ** its only purpose is to stop Lua to consume unlimited stack | 377 | ** its only purpose is to stop Lua from consuming unlimited stack |
| 354 | ** space (and to reserve some numbers for pseudo-indices). | 378 | ** space (and to reserve some numbers for pseudo-indices). |
| 355 | */ | 379 | */ |
| 356 | #if LUAI_BITSINT >= 32 | 380 | #if LUAI_BITSINT >= 32 |
| @@ -372,26 +396,14 @@ · 15 unmodified lines | |||
| 372 | #define LUAL_BUFFERSIZE BUFSIZ | 396 | #define LUAL_BUFFERSIZE BUFSIZ |
| 373 | 397 | ||
| 374 | 398 | ||
| 375 | |||
| 376 | |||
| 377 | /* | 399 | /* |
| 378 | ** {================================================================== | 400 | ** {================================================================== |
| 379 | ** The following definitions set the numeric types for Lua. | 401 | ** Configuration for Numbers. |
| 380 | ** Lua should work fine with 32-bit or 64-bit integers mixed with | 402 | ** Change these definitions if no predefined LUA_REAL_* / LUA_INT_* |
| 381 | ** 32-bit or 64-bit floats. The usual configurations are 64-bit | 403 | ** satisfy your needs. |
| 382 | ** integers and floats (the default) and 32-bit integers and floats. | ||
| 383 | ** =================================================================== | 404 | ** =================================================================== |
| 384 | */ | 405 | */ |
| 385 | 406 | ||
| 386 | /* | ||
| 387 | @@ LUA_INTSIZE defines size for Lua integer: 1=int, 2=long, 3=long long | ||
| 388 | @@ LUA_FLOATSIZE defines size for Lua float: 1=float, 2=double, 3=long double | ||
| 389 | ** Default is long long + double | ||
| 390 | */ | ||
| 391 | #define LUA_INTSIZE 3 | ||
| 392 | #define LUA_FLOATSIZE 2 | ||
| 393 | |||
| 394 | |||
| 395 | /* | 407 | /* |
| 396 | @@ LUA_NUMBER is the floating-point type used by Lua. | 408 | @@ LUA_NUMBER is the floating-point type used by Lua. |
| 397 | ** | 409 | ** |
| @@ -401,14 +413,14 @@ · 3 unmodified lines | |||
| 401 | @@ LUA_NUMBER_FRMLEN is the length modifier for writing floats. | 413 | @@ LUA_NUMBER_FRMLEN is the length modifier for writing floats. |
| 402 | @@ LUA_NUMBER_SCAN is the format for reading floats. | 414 | @@ LUA_NUMBER_SCAN is the format for reading floats. |
| 403 | @@ LUA_NUMBER_FMT is the format for writing floats. | 415 | @@ LUA_NUMBER_FMT is the format for writing floats. |
| 404 | @@ lua_number2str converts a floats to a string. | 416 | @@ lua_number2str converts a float to a string. |
| 405 | ** | 417 | ** |
| 406 | @@ l_mathop allows the addition of an 'l' or 'f' to all math operations | 418 | @@ l_mathop allows the addition of an 'l' or 'f' to all math operations |
| 407 | ** | 419 | ** |
| 408 | @@ lua_str2number converts a decimal numeric string to a number. | 420 | @@ lua_str2number converts a decimal numeric string to a number. |
| 409 | */ | 421 | */ |
| 410 | 422 | ||
| 411 | #if LUA_FLOATSIZE == 1 /* { single float */ | 423 | #if defined(LUA_REAL_FLOAT) /* { single float */ |
| 412 | 424 | ||
| 413 | #define LUA_NUMBER float | 425 | #define LUA_NUMBER float |
| 414 | 426 | ||
| @@ -423,7 +435,7 @@ · 8 unmodified lines | |||
| 423 | #define lua_str2number(s,p) strtof((s), (p)) | 435 | #define lua_str2number(s,p) strtof((s), (p)) |
| 424 | 436 | ||
| 425 | 437 | ||
| 426 | #elif LUA_FLOATSIZE == 3 /* }{ long double */ | 438 | #elif defined(LUA_REAL_LONGDOUBLE) /* }{ long double */ |
| 427 | 439 | ||
| 428 | #define LUA_NUMBER long double | 440 | #define LUA_NUMBER long double |
| 429 | 441 | ||
| @@ -437,7 +449,7 @@ · 7 unmodified lines | |||
| 437 | 449 | ||
| 438 | #define lua_str2number(s,p) strtold((s), (p)) | 450 | #define lua_str2number(s,p) strtold((s), (p)) |
| 439 | 451 | ||
| 440 | #else /* }{ default: double */ | 452 | #elif defined(LUA_REAL_DOUBLE) /* }{ double */ |
| 441 | 453 | ||
| 442 | #define LUA_NUMBER double | 454 | #define LUA_NUMBER double |
| 443 | 455 | ||
| @@ -451,7 +463,11 @@ · 7 unmodified lines | |||
| 451 | 463 | ||
| 452 | #define lua_str2number(s,p) strtod((s), (p)) | 464 | #define lua_str2number(s,p) strtod((s), (p)) |
| 453 | 465 | ||
| 454 | #endif /* } */ | 466 | #else /* }{ */ |
| 467 | |||
| 468 | #error "numeric real type not defined" | ||
| 469 | |||
| 470 | #endif /* } */ | ||
| 455 | 471 | ||
| 456 | 472 | ||
| 457 | #if defined(LUA_ANSI) | 473 | #if defined(LUA_ANSI) |
| @@ -481,8 +497,8 @@ · 23 unmodified lines | |||
| 481 | /* the following operations need the math library */ | 497 | /* the following operations need the math library */ |
| 482 | #if defined(lobject_c) || defined(lvm_c) | 498 | #if defined(lobject_c) || defined(lvm_c) |
| 483 | #include <math.h> | 499 | #include <math.h> |
| 484 | #define luai_nummod(L,a,b) ((a) - l_floor((a)/(b))*(b)) | 500 | #define luai_nummod(L,a,b) ((void)L, (a) - l_floor((a)/(b))*(b)) |
| 485 | #define luai_numpow(L,a,b) (l_mathop(pow)(a,b)) | 501 | #define luai_numpow(L,a,b) ((void)L, l_mathop(pow)(a,b)) |
| 486 | #endif | 502 | #endif |
| 487 | 503 | ||
| 488 | /* these are quite standard operations */ | 504 | /* these are quite standard operations */ |
| @@ -493,12 +509,19 @@ · 4 unmodified lines | |||
| 493 | #define luai_numdiv(L,a,b) ((a)/(b)) | 509 | #define luai_numdiv(L,a,b) ((a)/(b)) |
| 494 | #define luai_numunm(L,a) (-(a)) | 510 | #define luai_numunm(L,a) (-(a)) |
| 495 | #define luai_numeq(a,b) ((a)==(b)) | 511 | #define luai_numeq(a,b) ((a)==(b)) |
| 496 | #define luai_numlt(L,a,b) ((a)<(b)) | 512 | #define luai_numlt(a,b) ((a)<(b)) |
| 497 | #define luai_numle(L,a,b) ((a)<=(b)) | 513 | #define luai_numle(a,b) ((a)<=(b)) |
| 498 | #define luai_numisnan(L,a) (!luai_numeq((a), (a))) | 514 | #define luai_numisnan(a) (!luai_numeq((a), (a))) |
| 499 | #endif | 515 | #endif |
| 500 | 516 | ||
| 501 | 517 | ||
| 518 | /* | ||
| 519 | ** The following macro checks whether an operation is not safe to be | ||
| 520 | ** performed by the constant folder. It should result in zero only if | ||
| 521 | ** the operation is safe. | ||
| 522 | */ | ||
| 523 | #define luai_numinvalidop(op,a,b) 0 | ||
| 524 | |||
| 502 | 525 | ||
| 503 | /* | 526 | /* |
| 504 | @@ LUA_INTEGER is the integer type used by Lua. | 527 | @@ LUA_INTEGER is the integer type used by Lua. |
| @@ -511,22 +534,31 @@ · 6 unmodified lines | |||
| 511 | @@ lua_integer2str converts an integer to a string. | 534 | @@ lua_integer2str converts an integer to a string. |
| 512 | */ | 535 | */ |
| 513 | 536 | ||
| 514 | #if LUA_INTSIZE == 1 /* { int */ | 537 | #if defined(LUA_INT_INT) /* { int */ |
| 515 | 538 | ||
| 516 | #define LUA_INTEGER int | 539 | #define LUA_INTEGER int |
| 517 | #define LUA_INTEGER_FRMLEN "" | 540 | #define LUA_INTEGER_FRMLEN "" |
| 518 | 541 | ||
| 519 | #elif LUA_INTSIZE == 2 /* }{ long */ | 542 | #elif defined(LUA_INT_LONG) /* }{ long */ |
| 520 | 543 | ||
| 521 | #define LUA_INTEGER long | 544 | #define LUA_INTEGER long |
| 522 | #define LUA_INTEGER_FRMLEN "l" | 545 | #define LUA_INTEGER_FRMLEN "l" |
| 523 | 546 | ||
| 524 | #else /* }{ default: long long */ | 547 | #elif defined(LUA_INT_LONGLONG) /* }{ long long */ |
| 525 | 548 | ||
| 549 | #if defined(_WIN32) | ||
| 550 | #define LUA_INTEGER __int64 | ||
| 551 | #define LUA_INTEGER_FRMLEN "I64" | ||
| 552 | #else | ||
| 526 | #define LUA_INTEGER long long | 553 | #define LUA_INTEGER long long |
| 527 | #define LUA_INTEGER_FRMLEN "ll" | 554 | #define LUA_INTEGER_FRMLEN "ll" |
| 555 | #endif | ||
| 528 | 556 | ||
| 529 | #endif /* } */ | 557 | #else /* }{ */ |
| 558 | |||
| 559 | #error "numeric integer type not defined" | ||
| 560 | |||
| 561 | #endif /* } */ | ||
| 530 | 562 | ||
| 531 | 563 | ||
| 532 | #define LUA_INTEGER_SCAN "%" LUA_INTEGER_FRMLEN "d" | 564 | #define LUA_INTEGER_SCAN "%" LUA_INTEGER_FRMLEN "d" |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lualib.h,v 1.43 2011/12/08 12:11:37 roberto Exp $ | 2 | ** $Id: lualib.h,v 1.44 2014/02/06 17:32:33 roberto Exp $ |
| 3 | ** Lua standard libraries | 3 | ** Lua standard libraries |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -29,6 +29,9 @@ LUAMOD_API int (luaopen_os) (lua_State *L); · 23 unmodified lines | |||
| 29 | #define LUA_STRLIBNAME "string" | 29 | #define LUA_STRLIBNAME "string" |
| 30 | LUAMOD_API int (luaopen_string) (lua_State *L); | 30 | LUAMOD_API int (luaopen_string) (lua_State *L); |
| 31 | 31 | ||
| 32 | #define LUA_UTF8LIBNAME "utf8" | ||
| 33 | LUAMOD_API int (luaopen_utf8) (lua_State *L); | ||
| 34 | |||
| 32 | #define LUA_BITLIBNAME "bit32" | 35 | #define LUA_BITLIBNAME "bit32" |
| 33 | LUAMOD_API int (luaopen_bit32) (lua_State *L); | 36 | LUAMOD_API int (luaopen_bit32) (lua_State *L); |
| 34 | 37 | ||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lundump.c,v 2.23 2013/04/26 18:48:35 roberto Exp $ | 2 | ** $Id: lundump.c,v 2.34 2014/03/11 18:56:27 roberto Exp $ |
| 3 | ** load precompiled Lua chunks | 3 | ** load precompiled Lua chunks |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -20,249 +20,247 @@ · 14 unmodified lines | |||
| 20 | #include "lundump.h" | 20 | #include "lundump.h" |
| 21 | #include "lzio.h" | 21 | #include "lzio.h" |
| 22 | 22 | ||
| 23 | |||
| 24 | #if !defined(luai_verifycode) | ||
| 25 | #define luai_verifycode(L,b,f) /* empty */ | ||
| 26 | #endif | ||
| 27 | |||
| 28 | |||
| 23 | typedef struct { | 29 | typedef struct { |
| 24 | lua_State* L; | 30 | lua_State *L; |
| 25 | ZIO* Z; | 31 | ZIO *Z; |
| 26 | Mbuffer* b; | 32 | Mbuffer *b; |
| 27 | const char* name; | 33 | const char *name; |
| 28 | } LoadState; | 34 | } LoadState; |
| 29 | 35 | ||
| 30 | static l_noret error(LoadState* S, const char* why) | 36 | |
| 31 | { | 37 | static l_noret error(LoadState *S, const char *why) { |
| 32 | luaO_pushfstring(S->L,"%s: %s precompiled chunk",S->name,why); | 38 | luaO_pushfstring(S->L, "%s: %s precompiled chunk", S->name, why); |
| 33 | luaD_throw(S->L,LUA_ERRSYNTAX); | 39 | luaD_throw(S->L, LUA_ERRSYNTAX); |
| 34 | } | 40 | } |
| 35 | 41 | ||
| 36 | #define LoadMem(S,b,n,size) LoadBlock(S,b,(n)*(size)) | ||
| 37 | #define LoadByte(S) (lu_byte)LoadChar(S) | ||
| 38 | #define LoadVar(S,x) LoadMem(S,&x,1,sizeof(x)) | ||
| 39 | #define LoadVector(S,b,n,size) LoadMem(S,b,n,size) | ||
| 40 | 42 | ||
| 41 | #if !defined(luai_verifycode) | 43 | /* |
| 42 | #define luai_verifycode(L,b,f) /* empty */ | 44 | ** All high-level loads go through LoadVector; you can change it to |
| 43 | #endif | 45 | ** adapt to the endianess of the input |
| 46 | */ | ||
| 47 | #define LoadVector(S,b,n) LoadBlock(S,b,(n)*sizeof((b)[0])) | ||
| 44 | 48 | ||
| 45 | static void LoadBlock(LoadState* S, void* b, size_t size) | 49 | static void LoadBlock (LoadState *S, void *b, size_t size) { |
| 46 | { | 50 | if (luaZ_read(S->Z, b, size) != 0) |
| 47 | if (luaZ_read(S->Z,b,size)!=0) error(S,"truncated"); | 51 | error(S, "truncated"); |
| 48 | } | 52 | } |
| 49 | 53 | ||
| 50 | static int LoadChar(LoadState* S) | 54 | |
| 51 | { | 55 | #define LoadVar(S,x) LoadVector(S,&x,1) |
| 52 | char x; | 56 | |
| 53 | LoadVar(S,x); | 57 | |
| 54 | return x; | 58 | static lu_byte LoadByte (LoadState *S) { |
| 59 | lu_byte x; | ||
| 60 | LoadVar(S, x); | ||
| 61 | return x; | ||
| 55 | } | 62 | } |
| 56 | 63 | ||
| 57 | static int LoadInt(LoadState* S) | 64 | |
| 58 | { | 65 | static int LoadInt (LoadState *S) { |
| 59 | int x; | 66 | int x; |
| 60 | LoadVar(S,x); | 67 | LoadVar(S, x); |
| 61 | if (x<0) error(S,"corrupted"); | 68 | return x; |
| 62 | return x; | ||
| 63 | } | 69 | } |
| 64 | 70 | ||
| 65 | static lua_Number LoadNumber(LoadState* S) | 71 | |
| 66 | { | 72 | static lua_Number LoadNumber (LoadState *S) { |
| 67 | lua_Number x; | 73 | lua_Number x; |
| 68 | LoadVar(S,x); | 74 | LoadVar(S, x); |
| 69 | return x; | 75 | return x; |
| 70 | } | 76 | } |
| 71 | 77 | ||
| 72 | static lua_Integer LoadInteger(LoadState* S) | 78 | |
| 73 | { | 79 | static lua_Integer LoadInteger (LoadState *S) { |
| 74 | lua_Integer x; | 80 | lua_Integer x; |
| 75 | LoadVar(S,x); | 81 | LoadVar(S, x); |
| 76 | return x; | 82 | return x; |
| 77 | } | 83 | } |
| 78 | 84 | ||
| 79 | static TString* LoadString(LoadState* S) | 85 | |
| 80 | { | 86 | static TString *LoadString (LoadState *S) { |
| 81 | size_t size; | 87 | size_t size = LoadByte(S); |
| 82 | LoadVar(S,size); | 88 | if (size == 0xFF) |
| 83 | if (size==0) | 89 | LoadVar(S, size); |
| 84 | return NULL; | 90 | if (size == 0) |
| 85 | else | 91 | return NULL; |
| 86 | { | 92 | else { |
| 87 | char* s=luaZ_openspace(S->L,S->b,size); | 93 | char *s = luaZ_openspace(S->L, S->b, --size); |
| 88 | LoadBlock(S,s,size*sizeof(char)); | 94 | LoadVector(S, s, size); |
| 89 | return luaS_newlstr(S->L,s,size-1); /* remove trailing '\0' */ | 95 | return luaS_newlstr(S->L, s, size); |
| 90 | } | 96 | } |
| 91 | } | 97 | } |
| 92 | 98 | ||
| 93 | static void LoadCode(LoadState* S, Proto* f) | 99 | |
| 94 | { | 100 | static void LoadCode (LoadState *S, Proto *f) { |
| 95 | int n=LoadInt(S); | 101 | int n = LoadInt(S); |
| 96 | f->code=luaM_newvector(S->L,n,Instruction); | 102 | f->code = luaM_newvector(S->L, n, Instruction); |
| 97 | f->sizecode=n; | 103 | f->sizecode = n; |
| 98 | LoadVector(S,f->code,n,sizeof(Instruction)); | 104 | LoadVector(S, f->code, n); |
| 99 | } | 105 | } |
| 100 | 106 | ||
| 101 | static void LoadFunction(LoadState* S, Proto* f); | 107 | |
| 102 | 108 | static void LoadFunction(LoadState *S, Proto *f); | |
| 103 | static void LoadConstants(LoadState* S, Proto* f) | 109 | |
| 104 | { | 110 | |
| 105 | int i,n; | 111 | static void LoadConstants (LoadState *S, Proto *f) { |
| 106 | n=LoadInt(S); | 112 | int i, n; |
| 107 | f->k=luaM_newvector(S->L,n,TValue); | 113 | n = LoadInt(S); |
| 108 | f->sizek=n; | 114 | f->k = luaM_newvector(S->L, n, TValue); |
| 109 | for (i=0; i<n; i++) setnilvalue(&f->k[i]); | 115 | f->sizek = n; |
| 110 | for (i=0; i<n; i++) | 116 | for (i = 0; i < n; i++) |
| 111 | { | 117 | setnilvalue(&f->k[i]); |
| 112 | TValue* o=&f->k[i]; | 118 | for (i = 0; i < n; i++) { |
| 113 | int t=LoadChar(S); | 119 | TValue *o = &f->k[i]; |
| 114 | switch (t) | 120 | int t = LoadByte(S); |
| 115 | { | 121 | switch (t) { |
| 116 | case LUA_TNIL: | 122 | case LUA_TNIL: |
| 117 | setnilvalue(o); | 123 | setnilvalue(o); |
| 118 | break; | 124 | break; |
| 119 | case LUA_TBOOLEAN: | 125 | case LUA_TBOOLEAN: |
| 120 | setbvalue(o,LoadChar(S)); | 126 | setbvalue(o, LoadByte(S)); |
| 121 | break; | 127 | break; |
| 122 | case LUA_TNUMFLT: | 128 | case LUA_TNUMFLT: |
| 123 | setnvalue(o,LoadNumber(S)); | 129 | setnvalue(o, LoadNumber(S)); |
| 124 | break; | 130 | break; |
| 125 | case LUA_TNUMINT: | 131 | case LUA_TNUMINT: |
| 126 | setivalue(o,LoadInteger(S)); | 132 | setivalue(o, LoadInteger(S)); |
| 127 | break; | 133 | break; |
| 128 | case LUA_TSHRSTR: case LUA_TLNGSTR: | 134 | case LUA_TSHRSTR: |
| 129 | setsvalue2n(S->L,o,LoadString(S)); | 135 | case LUA_TLNGSTR: |
| 130 | break; | 136 | setsvalue2n(S->L, o, LoadString(S)); |
| 131 | default: lua_assert(0); | 137 | break; |
| 138 | default: | ||
| 139 | lua_assert(0); | ||
| 140 | } | ||
| 141 | } | ||
| 142 | n = LoadInt(S); | ||
| 143 | f->p = luaM_newvector(S->L, n, Proto *); | ||
| 144 | f->sizep = n; | ||
| 145 | for (i = 0; i < n; i++) | ||
| 146 | f->p[i] = NULL; | ||
| 147 | for (i = 0; i < n; i++) { | ||
| 148 | f->p[i] = luaF_newproto(S->L); | ||
| 149 | LoadFunction(S, f->p[i]); | ||
| 132 | } | 150 | } |
| 133 | } | ||
| 134 | n=LoadInt(S); | ||
| 135 | f->p=luaM_newvector(S->L,n,Proto*); | ||
| 136 | f->sizep=n; | ||
| 137 | for (i=0; i<n; i++) f->p[i]=NULL; | ||
| 138 | for (i=0; i<n; i++) | ||
| 139 | { | ||
| 140 | f->p[i]=luaF_newproto(S->L); | ||
| 141 | LoadFunction(S,f->p[i]); | ||
| 142 | } | ||
| 143 | } | 151 | } |
| 144 | 152 | ||
| 145 | static void LoadUpvalues(LoadState* S, Proto* f) | 153 | |
| 146 | { | 154 | static void LoadUpvalues (LoadState *S, Proto *f) { |
| 147 | int i,n; | 155 | int i, n; |
| 148 | n=LoadInt(S); | 156 | n = LoadInt(S); |
| 149 | f->upvalues=luaM_newvector(S->L,n,Upvaldesc); | 157 | f->upvalues = luaM_newvector(S->L, n, Upvaldesc); |
| 150 | f->sizeupvalues=n; | 158 | f->sizeupvalues = n; |
| 151 | for (i=0; i<n; i++) f->upvalues[i].name=NULL; | 159 | for (i = 0; i < n; i++) |
| 152 | for (i=0; i<n; i++) | 160 | f->upvalues[i].name = NULL; |
| 153 | { | 161 | for (i = 0; i < n; i++) { |
| 154 | f->upvalues[i].instack=LoadByte(S); | 162 | f->upvalues[i].instack = LoadByte(S); |
| 155 | f->upvalues[i].idx=LoadByte(S); | 163 | f->upvalues[i].idx = LoadByte(S); |
| 156 | } | 164 | } |
| 157 | } | 165 | } |
| 158 | 166 | ||
| 159 | static void LoadDebug(LoadState* S, Proto* f) | 167 | |
| 160 | { | 168 | static void LoadDebug (LoadState *S, Proto *f) { |
| 161 | int i,n; | 169 | int i, n; |
| 162 | f->source=LoadString(S); | 170 | f->source = LoadString(S); |
| 163 | n=LoadInt(S); | 171 | n = LoadInt(S); |
| 164 | f->lineinfo=luaM_newvector(S->L,n,int); | 172 | f->lineinfo = luaM_newvector(S->L, n, int); |
| 165 | f->sizelineinfo=n; | 173 | f->sizelineinfo = n; |
| 166 | LoadVector(S,f->lineinfo,n,sizeof(int)); | 174 | LoadVector(S, f->lineinfo, n); |
| 167 | n=LoadInt(S); | 175 | n = LoadInt(S); |
| 168 | f->locvars=luaM_newvector(S->L,n,LocVar); | 176 | f->locvars = luaM_newvector(S->L, n, LocVar); |
| 169 | f->sizelocvars=n; | 177 | f->sizelocvars = n; |
| 170 | for (i=0; i<n; i++) f->locvars[i].varname=NULL; | 178 | for (i = 0; i < n; i++) |
| 171 | for (i=0; i<n; i++) | 179 | f->locvars[i].varname = NULL; |
| 172 | { | 180 | for (i = 0; i < n; i++) { |
| 173 | f->locvars[i].varname=LoadString(S); | 181 | f->locvars[i].varname = LoadString(S); |
| 174 | f->locvars[i].startpc=LoadInt(S); | 182 | f->locvars[i].startpc = LoadInt(S); |
| 175 | f->locvars[i].endpc=LoadInt(S); | 183 | f->locvars[i].endpc = LoadInt(S); |
| 176 | } | 184 | } |
| 177 | n=LoadInt(S); | 185 | n = LoadInt(S); |
| 178 | for (i=0; i<n; i++) f->upvalues[i].name=LoadString(S); | 186 | for (i = 0; i < n; i++) |
| 187 | f->upvalues[i].name = LoadString(S); | ||
| 179 | } | 188 | } |
| 180 | 189 | ||
| 181 | static void LoadFunction(LoadState* S, Proto* f) | 190 | |
| 182 | { | 191 | static void LoadFunction (LoadState *S, Proto *f) { |
| 183 | f->linedefined=LoadInt(S); | 192 | f->linedefined = LoadInt(S); |
| 184 | f->lastlinedefined=LoadInt(S); | 193 | f->lastlinedefined = LoadInt(S); |
| 185 | f->numparams=LoadByte(S); | 194 | f->numparams = LoadByte(S); |
| 186 | f->is_vararg=LoadByte(S); | 195 | f->is_vararg = LoadByte(S); |
| 187 | f->maxstacksize=LoadByte(S); | 196 | f->maxstacksize = LoadByte(S); |
| 188 | LoadCode(S,f); | 197 | LoadCode(S, f); |
| 189 | LoadConstants(S,f); | 198 | LoadConstants(S, f); |
| 190 | LoadUpvalues(S,f); | 199 | LoadUpvalues(S, f); |
| 191 | LoadDebug(S,f); | 200 | LoadDebug(S, f); |
| 192 | } | 201 | } |
| 193 | 202 | ||
| 194 | /* the code below must be consistent with the code in luaU_header */ | 203 | |
| 195 | #define N0 LUAC_HEADERSIZE | 204 | static void checkliteral (LoadState *S, const char *s, const char *msg) { |
| 196 | #define N1 (sizeof(LUA_SIGNATURE)-sizeof(char)) | 205 | char buff[sizeof(LUA_SIGNATURE) + sizeof(LUAC_DATA)]; /* larger than both */ |
| 197 | #define N2 N1+2 | 206 | int len = strlen(s); |
| 198 | #define N3 N2+6 | 207 | LoadVector(S, buff, len); |
| 199 | 208 | if (memcmp(s, buff, len) != 0) | |
| 200 | static void LoadHeader(LoadState* S) | 209 | error(S, msg); |
| 201 | { | ||
| 202 | lu_byte h[LUAC_HEADERSIZE]; | ||
| 203 | lu_byte s[LUAC_HEADERSIZE]; | ||
| 204 | luaU_header(h); | ||
| 205 | memcpy(s,h,sizeof(char)); /* first char already read */ | ||
| 206 | LoadBlock(S,s+sizeof(char),LUAC_HEADERSIZE-sizeof(char)); | ||
| 207 | if (memcmp(h,s,N0)==0) return; | ||
| 208 | if (memcmp(h,s,N1)!=0) error(S,"not a"); | ||
| 209 | if (memcmp(h,s,N2)!=0) error(S,"version mismatch in"); | ||
| 210 | if (memcmp(h,s,N3)!=0) error(S,"incompatible"); else error(S,"corrupted"); | ||
| 211 | } | 210 | } |
| 212 | 211 | ||
| 213 | /* | 212 | |
| 214 | ** load precompiled chunk | 213 | static void fchecksize (LoadState *S, size_t size, const char *tname) { |
| 215 | */ | 214 | if (LoadByte(S) != size) |
| 216 | Closure* luaU_undump (lua_State* L, ZIO* Z, Mbuffer* buff, const char* name) | 215 | error(S, luaO_pushfstring(S->L, "%s size mismatch in", tname)); |
| 217 | { | 216 | } |
| 218 | LoadState S; | 217 | |
| 219 | Closure* cl; | 218 | |
| 220 | if (*name=='@' || *name=='=') | 219 | #define checksize(S,t) fchecksize(S,sizeof(t),#t) |
| 221 | S.name=name+1; | 220 | |
| 222 | else if (*name==LUA_SIGNATURE[0]) | 221 | static void checkHeader (LoadState *S) { |
| 223 | S.name="binary string"; | 222 | checkliteral(S, LUA_SIGNATURE + 1, "not a"); /* 1st char already checked */ |
| 224 | else | 223 | if (LoadByte(S) != LUAC_VERSION) |
| 225 | S.name=name; | 224 | error(S, "version mismatch in"); |
| 226 | S.L=L; | 225 | if (LoadByte(S) != LUAC_FORMAT) |
| 227 | S.Z=Z; | 226 | error(S, "format mismatch in"); |
| 228 | S.b=buff; | 227 | checkliteral(S, LUAC_DATA, "corrupted"); |
| 229 | LoadHeader(&S); | 228 | checksize(S, int); |
| 230 | cl=luaF_newLclosure(L,1); | 229 | checksize(S, size_t); |
| 231 | setclLvalue(L,L->top,cl); incr_top(L); | 230 | checksize(S, Instruction); |
| 232 | cl->l.p=luaF_newproto(L); | 231 | checksize(S, lua_Integer); |
| 233 | LoadFunction(&S,cl->l.p); | 232 | checksize(S, lua_Number); |
| 234 | if (cl->l.p->sizeupvalues != 1) | 233 | if (LoadInteger(S) != LUAC_INT) |
| 235 | { | 234 | error(S, "endianess mismatch in"); |
| 236 | Proto* p=cl->l.p; | 235 | if (LoadNumber(S) != LUAC_NUM) |
| 237 | cl=luaF_newLclosure(L,cl->l.p->sizeupvalues); | 236 | error(S, "float format mismatch in"); |
| 238 | cl->l.p=p; | ||
| 239 | setclLvalue(L,L->top-1,cl); | ||
| 240 | } | ||
| 241 | luai_verifycode(L,buff,cl->l.p); | ||
| 242 | return cl; | ||
| 243 | } | 237 | } |
| 244 | 238 | ||
| 245 | #define MYINT(s) (s[0]-'0') | ||
| 246 | #define VERSION MYINT(LUA_VERSION_MAJOR)*16+MYINT(LUA_VERSION_MINOR) | ||
| 247 | #define FORMAT 0 /* this is the official format */ | ||
| 248 | 239 | ||
| 249 | /* | 240 | /* |
| 250 | * make header for precompiled chunks | 241 | ** load precompiled chunk |
| 251 | * if you change the code below be sure to update LoadHeader and FORMAT above | ||
| 252 | * and LUAC_HEADERSIZE in lundump.h | ||
| 253 | */ | 242 | */ |
| 254 | void luaU_header (lu_byte* h) | 243 | Closure *luaU_undump(lua_State *L, ZIO *Z, Mbuffer *buff, |
| 255 | { | 244 | const char *name) { |
| 256 | int x=1; | 245 | LoadState S; |
| 257 | memcpy(h,LUA_SIGNATURE,sizeof(LUA_SIGNATURE)-sizeof(char)); | 246 | Closure *cl; |
| 258 | h+=sizeof(LUA_SIGNATURE)-sizeof(char); | 247 | if (*name == '@' || *name == '=') |
| 259 | *h++=cast_byte(VERSION); | 248 | S.name = name + 1; |
| 260 | *h++=cast_byte(FORMAT); | 249 | else if (*name == LUA_SIGNATURE[0]) |
| 261 | *h++=cast_byte(*(char*)&x); /* endianness */ | 250 | S.name = "binary string"; |
| 262 | *h++=cast_byte(sizeof(int)); | 251 | else |
| 263 | *h++=cast_byte(sizeof(size_t)); | 252 | S.name = name; |
| 264 | *h++=cast_byte(sizeof(Instruction)); | 253 | S.L = L; |
| 265 | *h++=cast_byte(sizeof(lua_Number)); | 254 | S.Z = Z; |
| 266 | *h++=cast_byte(((lua_Number)0.5)==0); /* is lua_Number integral? */ | 255 | S.b = buff; |
| 267 | memcpy(h,LUAC_TAIL,sizeof(LUAC_TAIL)-sizeof(char)); | 256 | checkHeader(&S); |
| 257 | cl = luaF_newLclosure(L, LoadByte(&S)); | ||
| 258 | setclLvalue(L, L->top, cl); | ||
| 259 | incr_top(L); | ||
| 260 | cl->l.p = luaF_newproto(L); | ||
| 261 | LoadFunction(&S, cl->l.p); | ||
| 262 | lua_assert(cl->l.nupvalues == cl->l.p->sizeupvalues); | ||
| 263 | luai_verifycode(L, buff, cl->l.p); | ||
| 264 | return cl; | ||
| 268 | } | 265 | } |
| 266 | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lundump.h,v 1.39 2012/05/08 13:53:33 roberto Exp $ | 2 | ** $Id: lundump.h,v 1.42 2014/03/11 14:22:54 roberto Exp $ |
| 3 | ** load precompiled Lua chunks | 3 | ** load precompiled Lua chunks |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -7,22 +7,27 @@ · 1 unmodified line | |||
| 7 | #ifndef lundump_h | 7 | #ifndef lundump_h |
| 8 | #define lundump_h | 8 | #define lundump_h |
| 9 | 9 | ||
| 10 | #include "llimits.h" | ||
| 10 | #include "lobject.h" | 11 | #include "lobject.h" |
| 11 | #include "lzio.h" | 12 | #include "lzio.h" |
| 12 | 13 | ||
| 13 | /* load one chunk; from lundump.c */ | ||
| 14 | LUAI_FUNC Closure* luaU_undump (lua_State* L, ZIO* Z, Mbuffer* buff, const char* name); | ||
| 15 | 14 | ||
| 16 | /* make header; from lundump.c */ | 15 | /* data to catch conversion errors */ |
| 17 | LUAI_FUNC void luaU_header (lu_byte* h); | 16 | #define LUAC_DATA "\x19\x93\r\n\x1a\n" |
| 18 | 17 | ||
| 19 | /* dump one chunk; from ldump.c */ | 18 | #define LUAC_INT cast_integer(0xABCD) |
| 20 | LUAI_FUNC int luaU_dump (lua_State* L, const Proto* f, lua_Writer w, void* data, int strip); | 19 | #define LUAC_NUM cast_num(370.5) |
| 21 | 20 | ||
| 22 | /* data to catch conversion errors */ | 21 | #define MYINT(s) (s[0]-'0') |
| 23 | #define LUAC_TAIL "\x19\x93\r\n\x1a\n" | 22 | #define LUAC_VERSION (MYINT(LUA_VERSION_MAJOR)*16+MYINT(LUA_VERSION_MINOR)) |
| 23 | #define LUAC_FORMAT 0 /* this is the official format */ | ||
| 24 | 24 | ||
| 25 | /* size in bytes of header of binary files */ | 25 | /* load one chunk; from lundump.c */ |
| 26 | #define LUAC_HEADERSIZE (sizeof(LUA_SIGNATURE)-sizeof(char)+2+6+sizeof(LUAC_TAIL)-sizeof(char)) | 26 | LUAI_FUNC Closure* luaU_undump (lua_State* L, ZIO* Z, Mbuffer* buff, |
| 27 | const char* name); | ||
| 28 | |||
| 29 | /* dump one chunk; from ldump.c */ | ||
| 30 | LUAI_FUNC int luaU_dump (lua_State* L, const Proto* f, lua_Writer w, | ||
| 31 | void* data, int strip); | ||
| 27 | 32 | ||
| 28 | #endif | 33 | #endif |
| @@ -0,0 +1,240 @@ | |||
| 1 | /* | ||
| 2 | ** $Id: lutf8lib.c,v 1.4 2014/03/20 19:36:02 roberto Exp $ | ||
| 3 | ** Standard library for UTF-8 manipulation | ||
| 4 | ** See Copyright Notice in lua.h | ||
| 5 | */ | ||
| 6 | |||
| 7 | |||
| 8 | #include <assert.h> | ||
| 9 | #include <stdlib.h> | ||
| 10 | #include <string.h> | ||
| 11 | |||
| 12 | #define lutf8lib_c | ||
| 13 | #define LUA_LIB | ||
| 14 | |||
| 15 | #include "lua.h" | ||
| 16 | |||
| 17 | #include "lauxlib.h" | ||
| 18 | #include "lualib.h" | ||
| 19 | |||
| 20 | #define MAXUNICODE 0x10FFFF | ||
| 21 | |||
| 22 | #define iscont(p) ((*(p) & 0xC0) == 0x80) | ||
| 23 | |||
| 24 | |||
| 25 | /* from strlib */ | ||
| 26 | /* translate a relative string position: negative means back from end */ | ||
| 27 | static lua_Integer u_posrelat (lua_Integer pos, size_t len) { | ||
| 28 | if (pos >= 0) return pos; | ||
| 29 | else if (0u - (size_t)pos > len) return 0; | ||
| 30 | else return (lua_Integer)len + pos + 1; | ||
| 31 | } | ||
| 32 | |||
| 33 | |||
| 34 | /* | ||
| 35 | ** Decode an UTF-8 sequence, returning NULL if byte sequence is invalid. | ||
| 36 | */ | ||
| 37 | static const char *utf8_decode (const char *o, int *val) { | ||
| 38 | static unsigned int limits[] = {0xFF, 0x7F, 0x7FF, 0xFFFF}; | ||
| 39 | const unsigned char *s = (const unsigned char *)o; | ||
| 40 | unsigned int c = s[0]; | ||
| 41 | unsigned int res = 0; /* final result */ | ||
| 42 | if (c < 0x80) /* ascii? */ | ||
| 43 | res = c; | ||
| 44 | else { | ||
| 45 | int count = 0; /* to count number of continuation bytes */ | ||
| 46 | while (c & 0x40) { /* still have continuation bytes? */ | ||
| 47 | int cc = s[++count]; /* read next byte */ | ||
| 48 | if ((cc & 0xC0) != 0x80) /* not a continuation byte? */ | ||
| 49 | return NULL; /* invalid byte sequence */ | ||
| 50 | res = (res << 6) | (cc & 0x3F); /* add lower 6 bits from cont. byte */ | ||
| 51 | c <<= 1; /* to test next bit */ | ||
| 52 | } | ||
| 53 | res |= ((c & 0x7F) << (count * 5)); /* add first byte */ | ||
| 54 | if (count > 3 || res > MAXUNICODE || res <= limits[count]) | ||
| 55 | return NULL; /* invalid byte sequence */ | ||
| 56 | s += count; /* skip continuation bytes read */ | ||
| 57 | } | ||
| 58 | if (val) *val = res; | ||
| 59 | return (const char *)s + 1; /* +1 to include first byte */ | ||
| 60 | } | ||
| 61 | |||
| 62 | |||
| 63 | /* | ||
| 64 | ** utf8len(s, [i]) --> number of codepoints in 's' after 'i'; | ||
| 65 | ** nil if 's' not well formed | ||
| 66 | */ | ||
| 67 | static int utflen (lua_State *L) { | ||
| 68 | int n = 0; | ||
| 69 | const char *ends; | ||
| 70 | size_t len; | ||
| 71 | const char *s = luaL_checklstring(L, 1, &len); | ||
| 72 | lua_Integer posi = u_posrelat(luaL_optinteger(L, 2, 1), 1); | ||
| 73 | luaL_argcheck(L, 1 <= posi && posi <= (lua_Integer)len, 1, | ||
| 74 | "initial position out of string"); | ||
| 75 | ends = s + len; | ||
| 76 | s += posi - 1; | ||
| 77 | while (s < ends && (s = utf8_decode(s, NULL)) != NULL) | ||
| 78 | n++; | ||
| 79 | if (s == ends) | ||
| 80 | lua_pushinteger(L, n); | ||
| 81 | else | ||
| 82 | lua_pushnil(L); | ||
| 83 | return 1; | ||
| 84 | } | ||
| 85 | |||
| 86 | |||
| 87 | /* | ||
| 88 | ** codepoint(s, [i, [j]]) -> returns codepoints for all characters | ||
| 89 | ** between i and j | ||
| 90 | */ | ||
| 91 | static int codepoint (lua_State *L) { | ||
| 92 | size_t len; | ||
| 93 | const char *s = luaL_checklstring(L, 1, &len); | ||
| 94 | lua_Integer posi = u_posrelat(luaL_optinteger(L, 2, 1), len); | ||
| 95 | lua_Integer pose = u_posrelat(luaL_optinteger(L, 3, posi), len); | ||
| 96 | int n; | ||
| 97 | const char *se; | ||
| 98 | luaL_argcheck(L, posi >= 1, 2, "out of range"); | ||
| 99 | luaL_argcheck(L, pose <= (lua_Integer)len, 3, "out of range"); | ||
| 100 | if (posi > pose) return 0; /* empty interval; return no values */ | ||
| 101 | n = (int)(pose - posi + 1); | ||
| 102 | if (posi + n <= pose) /* (lua_Integer -> int) overflow? */ | ||
| 103 | return luaL_error(L, "string slice too long"); | ||
| 104 | luaL_checkstack(L, n, "string slice too long"); | ||
| 105 | n = 0; | ||
| 106 | se = s + pose; | ||
| 107 | for (s += posi - 1; s < se;) { | ||
| 108 | int code; | ||
| 109 | s = utf8_decode(s, &code); | ||
| 110 | if (s == NULL) | ||
| 111 | return luaL_error(L, "invalid UTF-8 code"); | ||
| 112 | lua_pushinteger(L, code); | ||
| 113 | n++; | ||
| 114 | } | ||
| 115 | return n; | ||
| 116 | } | ||
| 117 | |||
| 118 | |||
| 119 | static void pushutfchar (lua_State *L, int arg) { | ||
| 120 | int code = luaL_checkint(L, arg); | ||
| 121 | luaL_argcheck(L, 0 <= code && code <= MAXUNICODE, arg, "value out of range"); | ||
| 122 | lua_pushfstring(L, "%U", code); | ||
| 123 | } | ||
| 124 | |||
| 125 | |||
| 126 | /* | ||
| 127 | ** utfchar(n1, n2, ...) -> char(n1)..char(n2)... | ||
| 128 | */ | ||
| 129 | static int utfchar (lua_State *L) { | ||
| 130 | int n = lua_gettop(L); /* number of arguments */ | ||
| 131 | if (n == 1) /* optimize common case of single char */ | ||
| 132 | pushutfchar(L, 1); | ||
| 133 | else { | ||
| 134 | int i; | ||
| 135 | luaL_Buffer b; | ||
| 136 | luaL_buffinit(L, &b); | ||
| 137 | for (i = 1; i <= n; i++) { | ||
| 138 | pushutfchar(L, i); | ||
| 139 | luaL_addvalue(&b); | ||
| 140 | } | ||
| 141 | luaL_pushresult(&b); | ||
| 142 | } | ||
| 143 | return 1; | ||
| 144 | } | ||
| 145 | |||
| 146 | |||
| 147 | /* | ||
| 148 | ** offset(s, n, [i]) -> index where n-th character *after* | ||
| 149 | ** position 'i' starts; 0 means character at 'i'. | ||
| 150 | */ | ||
| 151 | static int byteoffset (lua_State *L) { | ||
| 152 | size_t len; | ||
| 153 | const char *s = luaL_checklstring(L, 1, &len); | ||
| 154 | int n = luaL_checkint(L, 2); | ||
| 155 | lua_Integer posi = u_posrelat(luaL_optinteger(L, 3, 1), len) - 1; | ||
| 156 | luaL_argcheck(L, 0 <= posi && posi <= (lua_Integer)len, 3, | ||
| 157 | "position out of range"); | ||
| 158 | if (n == 0) { | ||
| 159 | /* find beginning of current byte sequence */ | ||
| 160 | while (posi > 0 && iscont(s + posi)) posi--; | ||
| 161 | } | ||
| 162 | else if (n < 0) { | ||
| 163 | while (n < 0 && posi > 0) { /* move back */ | ||
| 164 | do { /* find beginning of previous character */ | ||
| 165 | posi--; | ||
| 166 | } while (posi > 0 && iscont(s + posi)); | ||
| 167 | n++; | ||
| 168 | } | ||
| 169 | } | ||
| 170 | else { | ||
| 171 | n--; /* do not move for 1st character */ | ||
| 172 | while (n > 0 && posi < (lua_Integer)len) { | ||
| 173 | do { /* find beginning of next character */ | ||
| 174 | posi++; | ||
| 175 | } while (iscont(s + posi)); /* ('\0' is not continuation) */ | ||
| 176 | n--; | ||
| 177 | } | ||
| 178 | } | ||
| 179 | if (n == 0) | ||
| 180 | lua_pushinteger(L, posi + 1); | ||
| 181 | else | ||
| 182 | lua_pushnil(L); /* no such position */ | ||
| 183 | return 1; | ||
| 184 | } | ||
| 185 | |||
| 186 | |||
| 187 | static int iter_aux (lua_State *L) { | ||
| 188 | size_t len; | ||
| 189 | const char *s = luaL_checklstring(L, 1, &len); | ||
| 190 | int n = lua_tointeger(L, 2) - 1; | ||
| 191 | if (n < 0) /* first iteration? */ | ||
| 192 | n = 0; /* start from here */ | ||
| 193 | else if (n < (lua_Integer)len) { | ||
| 194 | n++; /* skip current byte */ | ||
| 195 | while (iscont(s + n)) n++; /* and its continuations */ | ||
| 196 | } | ||
| 197 | if (n >= (lua_Integer)len) | ||
| 198 | return 0; /* no more codepoints */ | ||
| 199 | else { | ||
| 200 | int code; | ||
| 201 | const char *next = utf8_decode(s + n, &code); | ||
| 202 | if (next == NULL || iscont(next)) | ||
| 203 | return luaL_error(L, "invalid UTF-8 code"); | ||
| 204 | lua_pushinteger(L, n + 1); | ||
| 205 | lua_pushinteger(L, code); | ||
| 206 | return 2; | ||
| 207 | } | ||
| 208 | } | ||
| 209 | |||
| 210 | |||
| 211 | static int iter_codes (lua_State *L) { | ||
| 212 | luaL_checkstring(L, 1); | ||
| 213 | lua_pushcfunction(L, iter_aux); | ||
| 214 | lua_pushvalue(L, 1); | ||
| 215 | lua_pushinteger(L, 0); | ||
| 216 | return 3; | ||
| 217 | } | ||
| 218 | |||
| 219 | |||
| 220 | /* pattern to match a single UTF-8 character */ | ||
| 221 | #define UTF8PATT "[\0-\x7F\xC2-\xF4][\x80-\xBF]*" | ||
| 222 | |||
| 223 | |||
| 224 | static struct luaL_Reg funcs[] = { | ||
| 225 | {"offset", byteoffset}, | ||
| 226 | {"codepoint", codepoint}, | ||
| 227 | {"char", utfchar}, | ||
| 228 | {"len", utflen}, | ||
| 229 | {"codes", iter_codes}, | ||
| 230 | {NULL, NULL} | ||
| 231 | }; | ||
| 232 | |||
| 233 | |||
| 234 | int luaopen_utf8 (lua_State *L) { | ||
| 235 | luaL_newlib(L, funcs); | ||
| 236 | lua_pushliteral(L, UTF8PATT); | ||
| 237 | lua_setfield(L, -2, "charpatt"); | ||
| 238 | return 1; | ||
| 239 | } | ||
| 240 | |||
| @@ -1,10 +1,11 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lvm.c,v 2.175 2013/06/20 15:02:49 roberto Exp $ | 2 | ** $Id: lvm.c,v 2.190 2014/03/15 12:29:48 roberto Exp $ |
| 3 | ** Lua virtual machine | 3 | ** Lua virtual machine |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| 6 | 6 | ||
| 7 | 7 | ||
| 8 | #include <limits.h> | ||
| 8 | #include <stdio.h> | 9 | #include <stdio.h> |
| 9 | #include <stdlib.h> | 10 | #include <stdlib.h> |
| 10 | #include <string.h> | 11 | #include <string.h> |
| @@ -29,7 +30,7 @@ · 18 unmodified lines | |||
| 29 | 30 | ||
| 30 | 31 | ||
| 31 | /* limit for table tag-method chains (to avoid loops) */ | 32 | /* limit for table tag-method chains (to avoid loops) */ |
| 32 | #define MAXTAGLOOP 100 | 33 | #define MAXTAGLOOP 2000 |
| 33 | 34 | ||
| 34 | 35 | ||
| 35 | /* maximum length of the conversion of a number to a string */ | 36 | /* maximum length of the conversion of a number to a string */ |
| @@ -52,17 +53,9 @@ int luaV_tostring (lua_State *L, StkId obj) { · 16 unmodified lines | |||
| 52 | return 0; | 53 | return 0; |
| 53 | else { | 54 | else { |
| 54 | char buff[MAXNUMBER2STR]; | 55 | char buff[MAXNUMBER2STR]; |
| 55 | size_t len; | 56 | size_t len = (ttisinteger(obj)) |
| 56 | if (ttisinteger(obj)) | 57 | ? lua_integer2str(buff, ivalue(obj)) |
| 57 | len = lua_integer2str(buff, ivalue(obj)); | 58 | : lua_number2str(buff, fltvalue(obj)); |
| 58 | else { | ||
| 59 | len = lua_number2str(buff, fltvalue(obj)); | ||
| 60 | if (strspn(buff, "-0123456789") == len) { /* look like an integer? */ | ||
| 61 | buff[len++] = '.'; /* add a '.0' */ | ||
| 62 | buff[len++] = '0'; | ||
| 63 | buff[len] = '\0'; | ||
| 64 | } | ||
| 65 | } | ||
| 66 | setsvalue2s(L, obj, luaS_newlstr(L, buff, len)); | 59 | setsvalue2s(L, obj, luaS_newlstr(L, buff, len)); |
| 67 | return 1; | 60 | return 1; |
| 68 | } | 61 | } |
| @@ -73,7 +66,7 @@ int luaV_tostring (lua_State *L, StkId obj) { · 4 unmodified lines | |||
| 73 | ** Check whether a float number is within the range of a lua_Integer. | 66 | ** Check whether a float number is within the range of a lua_Integer. |
| 74 | ** (The comparisons are tricky because of rounding, which can or | 67 | ** (The comparisons are tricky because of rounding, which can or |
| 75 | ** not occur depending on the relative sizes of floats and integers.) | 68 | ** not occur depending on the relative sizes of floats and integers.) |
| 76 | ** This function is called only when 'n' has an integer value. | 69 | ** This function should be called only when 'n' has an integral value. |
| 77 | */ | 70 | */ |
| 78 | int luaV_numtointeger (lua_Number n, lua_Integer *p) { | 71 | int luaV_numtointeger (lua_Number n, lua_Integer *p) { |
| 79 | if (cast_num(MIN_INTEGER) <= n && n < (MAX_INTEGER + cast_num(1))) { | 72 | if (cast_num(MIN_INTEGER) <= n && n < (MAX_INTEGER + cast_num(1))) { |
| @@ -121,7 +114,7 @@ void luaV_gettable (lua_State *L, const TValue *t, TValue *key, StkId val) { · 41 unmodified lines | |||
| 121 | } | 114 | } |
| 122 | t = tm; /* else repeat with 'tm' */ | 115 | t = tm; /* else repeat with 'tm' */ |
| 123 | } | 116 | } |
| 124 | luaG_runerror(L, "loop in gettable"); | 117 | luaG_runerror(L, "gettable chain too long; possible loop"); |
| 125 | } | 118 | } |
| 126 | 119 | ||
| 127 | 120 | ||
| @@ -145,7 +138,7 @@ void luaV_settable (lua_State *L, const TValue *t, TValue *key, StkId val) { · 17 unmodified lines | |||
| 145 | /* no metamethod and (now) there is an entry with given key */ | 138 | /* no metamethod and (now) there is an entry with given key */ |
| 146 | setobj2t(L, oldval, val); /* assign new value to that entry */ | 139 | setobj2t(L, oldval, val); /* assign new value to that entry */ |
| 147 | invalidateTMcache(h); | 140 | invalidateTMcache(h); |
| 148 | luaC_barrierback(L, obj2gco(h), val); | 141 | luaC_barrierback(L, h, val); |
| 149 | return; | 142 | return; |
| 150 | } | 143 | } |
| 151 | /* else will try the metamethod */ | 144 | /* else will try the metamethod */ |
| @@ -160,7 +153,7 @@ void luaV_settable (lua_State *L, const TValue *t, TValue *key, StkId val) { · 8 unmodified lines | |||
| 160 | } | 153 | } |
| 161 | t = tm; /* else repeat with 'tm' */ | 154 | t = tm; /* else repeat with 'tm' */ |
| 162 | } | 155 | } |
| 163 | luaG_runerror(L, "loop in settable"); | 156 | luaG_runerror(L, "settable chain too long; possible loop"); |
| 164 | } | 157 | } |
| 165 | 158 | ||
| 166 | 159 | ||
| @@ -192,7 +185,7 @@ int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r) { · 25 unmodified lines | |||
| 192 | if (ttisinteger(l) && ttisinteger(r)) | 185 | if (ttisinteger(l) && ttisinteger(r)) |
| 193 | return (ivalue(l) < ivalue(r)); | 186 | return (ivalue(l) < ivalue(r)); |
| 194 | else if (tonumber(l, &nl) && tonumber(r, &nr)) | 187 | else if (tonumber(l, &nl) && tonumber(r, &nr)) |
| 195 | return luai_numlt(L, nl, nr); | 188 | return luai_numlt(nl, nr); |
| 196 | else if (ttisstring(l) && ttisstring(r)) | 189 | else if (ttisstring(l) && ttisstring(r)) |
| 197 | return l_strcmp(rawtsvalue(l), rawtsvalue(r)) < 0; | 190 | return l_strcmp(rawtsvalue(l), rawtsvalue(r)) < 0; |
| 198 | else if ((res = luaT_callorderTM(L, l, r, TM_LT)) < 0) | 191 | else if ((res = luaT_callorderTM(L, l, r, TM_LT)) < 0) |
| @@ -207,7 +200,7 @@ int luaV_lessequal (lua_State *L, const TValue *l, const TValue *r) { · 8 unmodified lines | |||
| 207 | if (ttisinteger(l) && ttisinteger(r)) | 200 | if (ttisinteger(l) && ttisinteger(r)) |
| 208 | return (ivalue(l) <= ivalue(r)); | 201 | return (ivalue(l) <= ivalue(r)); |
| 209 | else if (tonumber(l, &nl) && tonumber(r, &nr)) | 202 | else if (tonumber(l, &nl) && tonumber(r, &nr)) |
| 210 | return luai_numle(L, nl, nr); | 203 | return luai_numle(nl, nr); |
| 211 | else if (ttisstring(l) && ttisstring(r)) | 204 | else if (ttisstring(l) && ttisstring(r)) |
| 212 | return l_strcmp(rawtsvalue(l), rawtsvalue(r)) <= 0; | 205 | return l_strcmp(rawtsvalue(l), rawtsvalue(r)) <= 0; |
| 213 | else if ((res = luaT_callorderTM(L, l, r, TM_LE)) >= 0) /* first try `le' */ | 206 | else if ((res = luaT_callorderTM(L, l, r, TM_LE)) >= 0) /* first try `le' */ |
| @@ -229,7 +222,7 @@ int luaV_equalobj (lua_State *L, const TValue *t1, const TValue *t2) { · 15 unmodified lines | |||
| 229 | else { /* two numbers with different variants */ | 222 | else { /* two numbers with different variants */ |
| 230 | lua_Number n1, n2; | 223 | lua_Number n1, n2; |
| 231 | lua_assert(ttisnumber(t1) && ttisnumber(t2)); | 224 | lua_assert(ttisnumber(t1) && ttisnumber(t2)); |
| 232 | (void)tonumber(t1, &n1); (void)tonumber(t2, &n2); | 225 | cast_void(tonumber(t1, &n1)); cast_void(tonumber(t2, &n2)); |
| 233 | return luai_numeq(n1, n2); | 226 | return luai_numeq(n1, n2); |
| 234 | } | 227 | } |
| 235 | } | 228 | } |
| @@ -272,7 +265,7 @@ void luaV_concat (lua_State *L, int total) { · 36 unmodified lines | |||
| 272 | if (!(ttisstring(top-2) || ttisnumber(top-2)) || !tostring(L, top-1)) | 265 | if (!(ttisstring(top-2) || ttisnumber(top-2)) || !tostring(L, top-1)) |
| 273 | luaT_trybinTM(L, top-2, top-1, top-2, TM_CONCAT); | 266 | luaT_trybinTM(L, top-2, top-1, top-2, TM_CONCAT); |
| 274 | else if (tsvalue(top-1)->len == 0) /* second operand is empty? */ | 267 | else if (tsvalue(top-1)->len == 0) /* second operand is empty? */ |
| 275 | (void)tostring(L, top - 2); /* result is first operand */ | 268 | cast_void(tostring(L, top - 2)); /* result is first operand */ |
| 276 | else if (ttisstring(top-2) && tsvalue(top-2)->len == 0) { | 269 | else if (ttisstring(top-2) && tsvalue(top-2)->len == 0) { |
| 277 | setobjs2s(L, top - 2, top - 1); /* result is second op. */ | 270 | setobjs2s(L, top - 2, top - 1); /* result is second op. */ |
| 278 | } | 271 | } |
| @@ -333,8 +326,7 @@ lua_Integer luaV_div (lua_State *L, lua_Integer x, lua_Integer y) { · 54 unmodified lines | |||
| 333 | if (cast_unsigned(y) + 1 <= 1U) { /* special cases: -1 or 0 */ | 326 | if (cast_unsigned(y) + 1 <= 1U) { /* special cases: -1 or 0 */ |
| 334 | if (y == 0) | 327 | if (y == 0) |
| 335 | luaG_runerror(L, "attempt to divide by zero"); | 328 | luaG_runerror(L, "attempt to divide by zero"); |
| 336 | else /* -1 */ | 329 | return intop(-, 0, x); /* y==-1; avoid overflow with 0x80000...//-1 */ |
| 337 | return -x; /* avoid overflow with 0x80000... */ | ||
| 338 | } | 330 | } |
| 339 | else { | 331 | else { |
| 340 | lua_Integer d = x / y; /* perform division */ | 332 | lua_Integer d = x / y; /* perform division */ |
| @@ -350,8 +342,7 @@ lua_Integer luaV_mod (lua_State *L, lua_Integer x, lua_Integer y) { · 9 unmodified lines | |||
| 350 | if (cast_unsigned(y) + 1 <= 1U) { /* special cases: -1 or 0 */ | 342 | if (cast_unsigned(y) + 1 <= 1U) { /* special cases: -1 or 0 */ |
| 351 | if (y == 0) | 343 | if (y == 0) |
| 352 | luaG_runerror(L, "attempt to perform 'n%%0'"); | 344 | luaG_runerror(L, "attempt to perform 'n%%0'"); |
| 353 | else /* -1 */ | 345 | return 0; /* y==-1; avoid overflow with 0x80000...%-1 */ |
| 354 | return 0; /* avoid overflow with 0x80000... */ | ||
| 355 | } | 346 | } |
| 356 | else { | 347 | else { |
| 357 | lua_Integer r = x % y; | 348 | lua_Integer r = x % y; |
| @@ -363,16 +354,36 @@ lua_Integer luaV_mod (lua_State *L, lua_Integer x, lua_Integer y) { · 5 unmodified lines | |||
| 363 | } | 354 | } |
| 364 | 355 | ||
| 365 | 356 | ||
| 366 | lua_Integer luaV_pow (lua_Integer x, lua_Integer y) { | 357 | lua_Integer luaV_pow (lua_State *L, lua_Integer x, lua_Integer y) { |
| 367 | lua_Integer r = 1; | 358 | if (y <= 0) { /* special cases: 0 or negative exponent */ |
| 368 | lua_assert(y >= 0); | 359 | if (y < 0) |
| 369 | if (y == 0) return r; | 360 | luaG_runerror(L, "integer exponentiation with negative exponent"); |
| 370 | for (; y > 1; y >>= 1) { | 361 | return 1; /* x^0 == 1 */ |
| 371 | if (y & 1) r = intop(*, r, x); | 362 | } |
| 372 | x = intop(*, x, x); | 363 | else { |
| 364 | lua_Integer r = 1; | ||
| 365 | for (; y > 1; y >>= 1) { | ||
| 366 | if (y & 1) r = intop(*, r, x); | ||
| 367 | x = intop(*, x, x); | ||
| 368 | } | ||
| 369 | r = intop(*, r, x); | ||
| 370 | return r; | ||
| 371 | } | ||
| 372 | } | ||
| 373 | |||
| 374 | |||
| 375 | /* number of bits in an integer */ | ||
| 376 | #define NBITS cast_int(sizeof(lua_Integer) * CHAR_BIT) | ||
| 377 | |||
| 378 | LUAI_FUNC lua_Integer luaV_shiftl (lua_Integer x, lua_Integer y) { | ||
| 379 | if (y < 0) { /* shift right? */ | ||
| 380 | if (y <= -NBITS) return 0; | ||
| 381 | else return cast_integer(cast_unsigned(x) >> (-y)); | ||
| 382 | } | ||
| 383 | else { /* shift left */ | ||
| 384 | if (y >= NBITS) return 0; | ||
| 385 | else return x << y; | ||
| 373 | } | 386 | } |
| 374 | r = intop(*, r, x); | ||
| 375 | return r; | ||
| 376 | } | 387 | } |
| 377 | 388 | ||
| 378 | 389 | ||
| @@ -399,9 +410,9 @@ static Closure *getcached (Proto *p, UpVal **encup, StkId base) { · 20 unmodified lines | |||
| 399 | 410 | ||
| 400 | /* | 411 | /* |
| 401 | ** create a new Lua closure, push it in the stack, and initialize | 412 | ** create a new Lua closure, push it in the stack, and initialize |
| 402 | ** its upvalues. Note that the call to 'luaC_barrierproto' must come | 413 | ** its upvalues. Note that the closure is not cached if prototype is |
| 403 | ** before the assignment to 'p->cache', as the function needs the | 414 | ** already black (which means that 'cache' was already cleared by the |
| 404 | ** original value of that field. | 415 | ** GC). |
| 405 | */ | 416 | */ |
| 406 | static void pushclosure (lua_State *L, Proto *p, UpVal **encup, StkId base, | 417 | static void pushclosure (lua_State *L, Proto *p, UpVal **encup, StkId base, |
| 407 | StkId ra) { | 418 | StkId ra) { |
| @@ -416,9 +427,11 @@ static void pushclosure (lua_State *L, Proto *p, UpVal **encup, StkId base, · 8 unmodified lines | |||
| 416 | ncl->l.upvals[i] = luaF_findupval(L, base + uv[i].idx); | 427 | ncl->l.upvals[i] = luaF_findupval(L, base + uv[i].idx); |
| 417 | else /* get upvalue from enclosing function */ | 428 | else /* get upvalue from enclosing function */ |
| 418 | ncl->l.upvals[i] = encup[uv[i].idx]; | 429 | ncl->l.upvals[i] = encup[uv[i].idx]; |
| 430 | ncl->l.upvals[i]->refcount++; | ||
| 431 | /* new closure is white, so we do not need a barrier here */ | ||
| 419 | } | 432 | } |
| 420 | luaC_barrierproto(L, p, ncl); | 433 | if (!isblack(obj2gco(p))) /* cache will not break GC invariant? */ |
| 421 | p->cache = ncl; /* save it on cache for reuse */ | 434 | p->cache = ncl; /* save it on cache for reuse */ |
| 422 | } | 435 | } |
| 423 | 436 | ||
| 424 | 437 | ||
| @@ -432,7 +445,9 @@ void luaV_finishOp (lua_State *L) { · 7 unmodified lines | |||
| 432 | OpCode op = GET_OPCODE(inst); | 445 | OpCode op = GET_OPCODE(inst); |
| 433 | switch (op) { /* finish its execution */ | 446 | switch (op) { /* finish its execution */ |
| 434 | case OP_ADD: case OP_SUB: case OP_MUL: case OP_DIV: case OP_IDIV: | 447 | case OP_ADD: case OP_SUB: case OP_MUL: case OP_DIV: case OP_IDIV: |
| 435 | case OP_MOD: case OP_POW: case OP_UNM: case OP_LEN: | 448 | case OP_BAND: case OP_BOR: case OP_BXOR: case OP_SHL: case OP_SHR: |
| 449 | case OP_MOD: case OP_POW: | ||
| 450 | case OP_UNM: case OP_BNOT: case OP_LEN: | ||
| 436 | case OP_GETTABUP: case OP_GETTABLE: case OP_SELF: { | 451 | case OP_GETTABUP: case OP_GETTABLE: case OP_SELF: { |
| 437 | setobjs2s(L, base + GETARG_A(inst), --L->top); | 452 | setobjs2s(L, base + GETARG_A(inst), --L->top); |
| 438 | break; | 453 | break; |
| @@ -590,7 +605,7 @@ void luaV_execute (lua_State *L) { · 151 unmodified lines | |||
| 590 | vmcase(OP_SETUPVAL, | 605 | vmcase(OP_SETUPVAL, |
| 591 | UpVal *uv = cl->upvals[GETARG_B(i)]; | 606 | UpVal *uv = cl->upvals[GETARG_B(i)]; |
| 592 | setobj(L, uv->v, ra); | 607 | setobj(L, uv->v, ra); |
| 593 | luaC_barrier(L, uv, ra); | 608 | luaC_upvalbarrier(L, uv); |
| 594 | ) | 609 | ) |
| 595 | vmcase(OP_SETTABLE, | 610 | vmcase(OP_SETTABLE, |
| 596 | Protect(luaV_settable(L, ra, RKB(i), RKC(i))); | 611 | Protect(luaV_settable(L, ra, RKB(i), RKC(i))); |
| @@ -666,6 +681,51 @@ void luaV_execute (lua_State *L) { · 69 unmodified lines | |||
| 666 | } | 681 | } |
| 667 | else { Protect(luaT_trybinTM(L, rb, rc, ra, TM_IDIV)); } | 682 | else { Protect(luaT_trybinTM(L, rb, rc, ra, TM_IDIV)); } |
| 668 | ) | 683 | ) |
| 684 | vmcase(OP_BAND, | ||
| 685 | TValue *rb = RKB(i); | ||
| 686 | TValue *rc = RKC(i); | ||
| 687 | lua_Integer ib; lua_Integer ic; | ||
| 688 | if (tointeger(rb, &ib) && tointeger(rc, &ic)) { | ||
| 689 | setivalue(ra, intop(&, ib, ic)); | ||
| 690 | } | ||
| 691 | else { Protect(luaT_trybinTM(L, rb, rc, ra, TM_BAND)); } | ||
| 692 | ) | ||
| 693 | vmcase(OP_BOR, | ||
| 694 | TValue *rb = RKB(i); | ||
| 695 | TValue *rc = RKC(i); | ||
| 696 | lua_Integer ib; lua_Integer ic; | ||
| 697 | if (tointeger(rb, &ib) && tointeger(rc, &ic)) { | ||
| 698 | setivalue(ra, intop(|, ib, ic)); | ||
| 699 | } | ||
| 700 | else { Protect(luaT_trybinTM(L, rb, rc, ra, TM_BOR)); } | ||
| 701 | ) | ||
| 702 | vmcase(OP_BXOR, | ||
| 703 | TValue *rb = RKB(i); | ||
| 704 | TValue *rc = RKC(i); | ||
| 705 | lua_Integer ib; lua_Integer ic; | ||
| 706 | if (tointeger(rb, &ib) && tointeger(rc, &ic)) { | ||
| 707 | setivalue(ra, intop(^, ib, ic)); | ||
| 708 | } | ||
| 709 | else { Protect(luaT_trybinTM(L, rb, rc, ra, TM_BXOR)); } | ||
| 710 | ) | ||
| 711 | vmcase(OP_SHL, | ||
| 712 | TValue *rb = RKB(i); | ||
| 713 | TValue *rc = RKC(i); | ||
| 714 | lua_Integer ib; lua_Integer ic; | ||
| 715 | if (tointeger(rb, &ib) && tointeger(rc, &ic)) { | ||
| 716 | setivalue(ra, luaV_shiftl(ib, ic)); | ||
| 717 | } | ||
| 718 | else { Protect(luaT_trybinTM(L, rb, rc, ra, TM_SHL)); } | ||
| 719 | ) | ||
| 720 | vmcase(OP_SHR, | ||
| 721 | TValue *rb = RKB(i); | ||
| 722 | TValue *rc = RKC(i); | ||
| 723 | lua_Integer ib; lua_Integer ic; | ||
| 724 | if (tointeger(rb, &ib) && tointeger(rc, &ic)) { | ||
| 725 | setivalue(ra, luaV_shiftl(ib, -ic)); | ||
| 726 | } | ||
| 727 | else { Protect(luaT_trybinTM(L, rb, rc, ra, TM_SHR)); } | ||
| 728 | ) | ||
| 669 | vmcase(OP_MOD, | 729 | vmcase(OP_MOD, |
| 670 | TValue *rb = RKB(i); | 730 | TValue *rb = RKB(i); |
| 671 | TValue *rc = RKC(i); | 731 | TValue *rc = RKC(i); |
| @@ -683,11 +743,9 @@ void luaV_execute (lua_State *L) { · 11 unmodified lines | |||
| 683 | TValue *rb = RKB(i); | 743 | TValue *rb = RKB(i); |
| 684 | TValue *rc = RKC(i); | 744 | TValue *rc = RKC(i); |
| 685 | lua_Number nb; lua_Number nc; | 745 | lua_Number nb; lua_Number nc; |
| 686 | lua_Integer ic; | 746 | if (ttisinteger(rb) && ttisinteger(rc)) { |
| 687 | if (ttisinteger(rb) && ttisinteger(rc) && | 747 | lua_Integer ib = ivalue(rb); lua_Integer ic = ivalue(rc); |
| 688 | (ic = ivalue(rc)) >= 0) { | 748 | setivalue(ra, luaV_pow(L, ib, ic)); |
| 689 | lua_Integer ib = ivalue(rb); | ||
| 690 | setivalue(ra, luaV_pow(ib, ic)); | ||
| 691 | } | 749 | } |
| 692 | else if (tonumber(rb, &nb) && tonumber(rc, &nc)) { | 750 | else if (tonumber(rb, &nb) && tonumber(rc, &nc)) { |
| 693 | setnvalue(ra, luai_numpow(L, nb, nc)); | 751 | setnvalue(ra, luai_numpow(L, nb, nc)); |
| @@ -699,7 +757,7 @@ void luaV_execute (lua_State *L) { · 5 unmodified lines | |||
| 699 | lua_Number nb; | 757 | lua_Number nb; |
| 700 | if (ttisinteger(rb)) { | 758 | if (ttisinteger(rb)) { |
| 701 | lua_Integer ib = ivalue(rb); | 759 | lua_Integer ib = ivalue(rb); |
| 702 | setivalue(ra, -ib); | 760 | setivalue(ra, intop(-, 0, ib)); |
| 703 | } | 761 | } |
| 704 | else if (tonumber(rb, &nb)) { | 762 | else if (tonumber(rb, &nb)) { |
| 705 | setnvalue(ra, luai_numunm(L, nb)); | 763 | setnvalue(ra, luai_numunm(L, nb)); |
| @@ -708,6 +766,16 @@ void luaV_execute (lua_State *L) { · 2 unmodified lines | |||
| 708 | Protect(luaT_trybinTM(L, rb, rb, ra, TM_UNM)); | 766 | Protect(luaT_trybinTM(L, rb, rb, ra, TM_UNM)); |
| 709 | } | 767 | } |
| 710 | ) | 768 | ) |
| 769 | vmcase(OP_BNOT, | ||
| 770 | TValue *rb = RB(i); | ||
| 771 | lua_Integer ib; | ||
| 772 | if (tointeger(rb, &ib)) { | ||
| 773 | setivalue(ra, intop(^, cast_integer(-1), ib)); | ||
| 774 | } | ||
| 775 | else { | ||
| 776 | Protect(luaT_trybinTM(L, rb, rb, ra, TM_BNOT)); | ||
| 777 | } | ||
| 778 | ) | ||
| 711 | vmcase(OP_NOT, | 779 | vmcase(OP_NOT, |
| 712 | TValue *rb = RB(i); | 780 | TValue *rb = RB(i); |
| 713 | int res = l_isfalse(rb); /* next assignment may change this value */ | 781 | int res = l_isfalse(rb); /* next assignment may change this value */ |
| @@ -831,7 +899,7 @@ void luaV_execute (lua_State *L) { · 117 unmodified lines | |||
| 831 | } | 899 | } |
| 832 | ) | 900 | ) |
| 833 | vmcase(OP_FORLOOP, | 901 | vmcase(OP_FORLOOP, |
| 834 | if (ttisinteger(ra)) { /* integer count? */ | 902 | if (ttisinteger(ra)) { /* integer loop? */ |
| 835 | lua_Integer step = ivalue(ra + 2); | 903 | lua_Integer step = ivalue(ra + 2); |
| 836 | lua_Integer idx = ivalue(ra) + step; /* increment index */ | 904 | lua_Integer idx = ivalue(ra) + step; /* increment index */ |
| 837 | lua_Integer limit = ivalue(ra + 1); | 905 | lua_Integer limit = ivalue(ra + 1); |
| @@ -841,12 +909,12 @@ void luaV_execute (lua_State *L) { · 3 unmodified lines | |||
| 841 | setivalue(ra + 3, idx); /* ...and external index */ | 909 | setivalue(ra + 3, idx); /* ...and external index */ |
| 842 | } | 910 | } |
| 843 | } | 911 | } |
| 844 | else { /* floating count */ | 912 | else { /* floating loop */ |
| 845 | lua_Number step = fltvalue(ra + 2); | 913 | lua_Number step = fltvalue(ra + 2); |
| 846 | lua_Number idx = luai_numadd(L, fltvalue(ra), step); /* inc. index */ | 914 | lua_Number idx = luai_numadd(L, fltvalue(ra), step); /* inc. index */ |
| 847 | lua_Number limit = fltvalue(ra + 1); | 915 | lua_Number limit = fltvalue(ra + 1); |
| 848 | if (luai_numlt(L, 0, step) ? luai_numle(L, idx, limit) | 916 | if (luai_numlt(0, step) ? luai_numle(idx, limit) |
| 849 | : luai_numle(L, limit, idx)) { | 917 | : luai_numle(limit, idx)) { |
| 850 | ci->u.l.savedpc += GETARG_sBx(i); /* jump back */ | 918 | ci->u.l.savedpc += GETARG_sBx(i); /* jump back */ |
| 851 | setnvalue(ra, idx); /* update internal index... */ | 919 | setnvalue(ra, idx); /* update internal index... */ |
| 852 | setnvalue(ra + 3, idx); /* ...and external index */ | 920 | setnvalue(ra + 3, idx); /* ...and external index */ |
| @@ -857,10 +925,11 @@ void luaV_execute (lua_State *L) { · 4 unmodified lines | |||
| 857 | TValue *init = ra; | 925 | TValue *init = ra; |
| 858 | TValue *plimit = ra + 1; | 926 | TValue *plimit = ra + 1; |
| 859 | TValue *pstep = ra + 2; | 927 | TValue *pstep = ra + 2; |
| 860 | if (ttisinteger(ra) && ttisinteger(ra + 1) && ttisinteger(ra + 2)) { | 928 | if (ttisinteger(init) && ttisinteger(plimit) && ttisinteger(pstep)) { |
| 861 | setivalue(ra, ivalue(ra) - ivalue(pstep)); | 929 | /* all values are integer */ |
| 930 | setivalue(init, ivalue(init) - ivalue(pstep)); | ||
| 862 | } | 931 | } |
| 863 | else { /* try with floats */ | 932 | else { /* try making all values floats */ |
| 864 | lua_Number ninit; lua_Number nlimit; lua_Number nstep; | 933 | lua_Number ninit; lua_Number nlimit; lua_Number nstep; |
| 865 | if (!tonumber(plimit, &nlimit)) | 934 | if (!tonumber(plimit, &nlimit)) |
| 866 | luaG_runerror(L, LUA_QL("for") " limit must be a number"); | 935 | luaG_runerror(L, LUA_QL("for") " limit must be a number"); |
| @@ -870,7 +939,7 @@ void luaV_execute (lua_State *L) { · 3 unmodified lines | |||
| 870 | setnvalue(pstep, nstep); | 939 | setnvalue(pstep, nstep); |
| 871 | if (!tonumber(init, &ninit)) | 940 | if (!tonumber(init, &ninit)) |
| 872 | luaG_runerror(L, LUA_QL("for") " initial value must be a number"); | 941 | luaG_runerror(L, LUA_QL("for") " initial value must be a number"); |
| 873 | setnvalue(ra, luai_numsub(L, ninit, nstep)); | 942 | setnvalue(init, luai_numsub(L, ninit, nstep)); |
| 874 | } | 943 | } |
| 875 | ci->u.l.savedpc += GETARG_sBx(i); | 944 | ci->u.l.savedpc += GETARG_sBx(i); |
| 876 | ) | 945 | ) |
| @@ -912,7 +981,7 @@ void luaV_execute (lua_State *L) { · 35 unmodified lines | |||
| 912 | for (; n > 0; n--) { | 981 | for (; n > 0; n--) { |
| 913 | TValue *val = ra+n; | 982 | TValue *val = ra+n; |
| 914 | luaH_setint(L, h, last--, val); | 983 | luaH_setint(L, h, last--, val); |
| 915 | luaC_barrierback(L, obj2gco(h), val); | 984 | luaC_barrierback(L, h, val); |
| 916 | } | 985 | } |
| 917 | L->top = ci->top; /* correct top (in case of previous open call) */ | 986 | L->top = ci->top; /* correct top (in case of previous open call) */ |
| 918 | ) | 987 | ) |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lvm.h,v 2.23 2013/05/02 12:31:26 roberto Exp $ | 2 | ** $Id: lvm.h,v 2.25 2013/12/30 20:47:58 roberto Exp $ |
| 3 | ** Lua virtual machine | 3 | ** Lua virtual machine |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -43,7 +43,8 @@ LUAI_FUNC void luaV_execute (lua_State *L); · 37 unmodified lines | |||
| 43 | LUAI_FUNC void luaV_concat (lua_State *L, int total); | 43 | LUAI_FUNC void luaV_concat (lua_State *L, int total); |
| 44 | LUAI_FUNC lua_Integer luaV_div (lua_State *L, lua_Integer x, lua_Integer y); | 44 | LUAI_FUNC lua_Integer luaV_div (lua_State *L, lua_Integer x, lua_Integer y); |
| 45 | LUAI_FUNC lua_Integer luaV_mod (lua_State *L, lua_Integer x, lua_Integer y); | 45 | LUAI_FUNC lua_Integer luaV_mod (lua_State *L, lua_Integer x, lua_Integer y); |
| 46 | LUAI_FUNC lua_Integer luaV_pow (lua_Integer x, lua_Integer y); | 46 | LUAI_FUNC lua_Integer luaV_pow (lua_State *L, lua_Integer x, lua_Integer y); |
| 47 | LUAI_FUNC lua_Integer luaV_shiftl (lua_Integer x, lua_Integer y); | ||
| 47 | LUAI_FUNC void luaV_objlen (lua_State *L, StkId ra, const TValue *rb); | 48 | LUAI_FUNC void luaV_objlen (lua_State *L, StkId ra, const TValue *rb); |
| 48 | 49 | ||
| 49 | #endif | 50 | #endif |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lzio.h,v 1.27 2013/06/07 14:51:10 roberto Exp $ | 2 | ** $Id: lzio.h,v 1.28 2014/01/31 15:14:22 roberto Exp $ |
| 3 | ** Buffered streams | 3 | ** Buffered streams |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -32,6 +32,7 @@ typedef struct Mbuffer { · 26 unmodified lines | |||
| 32 | #define luaZ_sizebuffer(buff) ((buff)->buffsize) | 32 | #define luaZ_sizebuffer(buff) ((buff)->buffsize) |
| 33 | #define luaZ_bufflen(buff) ((buff)->n) | 33 | #define luaZ_bufflen(buff) ((buff)->n) |
| 34 | 34 | ||
| 35 | #define luaZ_buffremove(buff,i) ((buff)->n -= (i)) | ||
| 35 | #define luaZ_resetbuffer(buff) ((buff)->n = 0) | 36 | #define luaZ_resetbuffer(buff) ((buff)->n = 0) |
| 36 | 37 | ||
| 37 | 38 | ||